ЁЯПл The SchoolтА║ЁЯЪк NATтА║ЁЯЪк рдзрдбрд╛ 01 тАФ NAT рдХрд╛: рд╢рд╛рд│реЗрдЪреЗ рдлрд╛рдЯрдХ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯЪк рдзрдбрд╛ 01 тАФ NAT рдХрд╛: рд╢рд╛рд│реЗрдЪреЗ рдлрд╛рдЯрдХ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 8 рдкреИрдХреА рдзрдбрд╛ 01 ┬╖ рдкреБрдвреЗ: lesson-02-how-pat-works


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рд╣рд╛ рд╕рдВрдкреВрд░реНрдг рдХреЛрд░реНрд╕ рдПрдХрдЪ рдкреНрд░рд╢реНрди рд╕реЛрдбрд╡рддреЛ: private subnet рдордзреАрд▓ servers рдирд╛ internet рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрд╛рдпрдЪреЗ рдЕрд╕рддреЗ (updates, package downloads, partner APIs), рдкрдг internet рд▓рд╛ рддреНрдпрд╛рдВрдЪреНрдпрд╛рдкрд░реНрдпрдВрдд рдХрдзреАрд╣реА рдкреЛрд╣реЛрдЪрддрд╛ рдпреЗрддрд╛ рдХрд╛рдорд╛ рдирдпреЗ. рдпрд╛рдЪреЗ рдЙрддреНрддрд░ рдореНрд╣рдгрдЬреЗ рдЕрд╕реЗ рдлрд╛рдЯрдХ рдЬреЗ рдлреЗрд▒реНрдпрд╛рдВрдирд╛ рдмрд╛рд╣реЗрд░ рдЬрд╛рдК рджреЗрддреЗ рдЖрдгрд┐ рдЙрддреНрддрд░рд╛рдВрдирд╛ рдкрд░рдд рдпреЗрдК рджреЗрддреЗ, рдмрд╛рдХреА рдХрд╛рд╣реАрд╣реА рдирд╛рд╣реА: NAT (Network Address Translation). рд╕рдВрдкреВрд░реНрдг рдХреЛрд░реНрд╕рднрд░ рддреБрдореНрд╣реА рд╡рд╛рдкрд░рдгрд╛рд░ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдЦрд▒реНрдпрд╛ files:

ЁЯОТ рд╕реБрд░реВ рдХрд░рдгреНрдпрд╛рдЖрдзреА: рддреБрдореНрд╣рд╛рд▓рд╛ рдлрдХреНрдд Python 3 рд▓рд╛рдЧрддреЗ, рдмрд╛рдХреА рдХрд╛рд╣реА рдирд╛рд╣реА тАФ AWS account рдирдХреЛ, pip install рдирдХреЛ. gateway.py рд╣реЗ рд╢рд┐рдХрд╡рдгреНрдпрд╛рд╕рд╛рдареАрдЪреЗ model рдЖрд╣реЗ, router рдирд╛рд╣реА: рддреЗ AWS NAT gateway documentation рдордзреАрд▓ рдЖрдХрдбреЗ рдкрд╛рд│рддреЗ (рдкреНрд░рддреНрдпреЗрдХ IP рд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ destination рд╕рд╛рдареА 55,000 connections, 350-second idle timeout), рдкрдг рдЦрд░реЗ packets рд╣рд▓рд╡рдд рдирд╛рд╣реА. рддреНрдпрд╛рддрд▓реНрдпрд╛ рдХрд┐рдорддреА рдЙрджрд╛рд╣рд░рдг рдХрд┐рдорддреА рдЖрд╣реЗрдд (us-east-1) тАФ рдиреЗрд╣рдореА AWS pricing page рддрдкрд╛рд╕рд╛. рдЦрд▒реНрдпрд╛ account рд╡рд░ рдЕрд╢реА рдЦреВрдг рдЕрд╕рд▓реЗрд▓реНрдпрд╛ commands рдирд╛ AWS CLI рдЖрдгрд┐ credentials рд▓рд╛рдЧрддрд╛рдд, рдЖрдгрд┐ NAT gateway рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЕрд╕реЗрдкрд░реНрдпрдВрдд рджрд░ рддрд╛рд╕рд╛рд▓рд╛ рдкреИрд╕реЗ рд▓рд╛рдЧрддрд╛рдд.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рдПрдХрд╛ рд╢рд╛рд│реЗрд▓рд╛ рдПрдХ private wing рдЖрд╣реЗ ЁЯПл. рдЖрддрд▓реНрдпрд╛ рдЦреЛрд▓реНрдпрд╛рдВрдордзреНрдпреЗ private рдмрд╛рдХ рдХреНрд░рдорд╛рдВрдХ рдЖрд╣реЗрдд тАФ "рдЦреЛрд▓реА 48 рдордзреАрд▓ рдмрд╛рдХ 25". рд╢рд╛рд│реЗрдмрд╛рд╣реЗрд░ рдпрд╛ рдХреНрд░рдорд╛рдВрдХрд╛рдВрдирд╛ рдХрд╛рд╣реАрдЪ рдЕрд░реНрде рдирд╛рд╣реА. рдЧрд╛рд╡рд╛рддрд▓реЗ рджреБрдХрд╛рди "рдмрд╛рдХ 25" рд▓рд╛ рдкрддреНрд░ рдкрд╛рдард╡реВ рд╢рдХрдд рдирд╛рд╣реА.

рдореНрд╣рдгреВрди рдмрд╛рд╣реЗрд░ рдЬрд╛рдгрд╛рд░реА рдкреНрд░рддреНрдпреЗрдХ рдлреЗрд░реА рд╢рд╛рд│реЗрдЪреНрдпрд╛ рдлрд╛рдЯрдХрд╛рддреВрди рдЬрд╛рддреЗ ЁЯЪк. рдлрд╛рдЯрдХрд╛рд╡рд░ рдПрдХ рд░рдЦрд╡рд╛рд▓рджрд╛рд░ рдЙрднрд╛ рдЕрд╕рддреЛ, рддреНрдпрд╛рдЪреНрдпрд╛рдХрдбреЗ рдПрдХ рдиреЛрдВрджрд╡рд╣реА рдЕрд╕рддреЗ ЁЯУТ:

рдмрд╛рд╣реЗрд░ рдЬрд╛рдгреЗ: рд╣реЛ. рдЙрддреНрддрд░реЗ рдкрд░рдд рдпреЗрдгреЗ: рд╣реЛ. рдЕрдиреЛрд│рдЦреА рд▓реЛрдХрд╛рдВрдиреА рдЖрдд рдпреЗрдгреЗ: рдХрдзреАрдЪ рдирд╛рд╣реА. рд╣реЗрдЪ NAT.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    desk["ЁЯкС private desk<br/>10.20.48.25:50001"]
    gate["ЁЯЪк NAT gateway<br/>public IP 13.232.10.20<br/>ЁЯУТ register"]
    pypi["ЁЯМР pypi.org<br/>151.101.0.223:443"]
    stranger["ЁЯХ╡я╕П stranger<br/>198.51.100.9"]
    desk -->|"1 trip out"| gate
    gate -->|"2 leaves as 13.232.10.20:1024"| pypi
    pypi -->|"3 answer back тЖТ row found"| gate
    gate -->|"4 handed to the desk"| desk
    stranger -.->|"5 knocks тЖТ no row"| drop["ЁЯЪл dropped"]

ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/nat/lesson-diagrams.html#l01

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдХрд╛рд░рдг databases, app servers рдЖрдгрд┐ batch jobs рдпрд╛рдВрдЪреА рдЬрд╛рдЧрд╛ private subnets рдордзреНрдпреЗрдЪ рдЖрд╣реЗ: internet рд╡рд░рдЪреНрдпрд╛ рдХреЛрдгрд╛рд▓рд╛рд╣реА рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╢реА connection рдЙрдШрдбрддрд╛ рдпреЗрдК рдирдпреЗ. рдкрдг рддреНрдпрд╛рдЪ servers рдирд╛ OS patches рдЖрдгрд╛рд╡реЗ рд▓рд╛рдЧрддрд╛рдд, pypi.org рдХрд┐рдВрд╡рд╛ npm рд╡рд░реВрди packages рдШреНрдпрд╛рд╡реЗ рд▓рд╛рдЧрддрд╛рдд, рдЖрдгрд┐ payment рдХрд┐рдВрд╡рд╛ SMS APIs call рдХрд░рд╛рд╡реНрдпрд╛ рд▓рд╛рдЧрддрд╛рдд. "рдлрдХреНрдд updates download рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА" рддреНрдпрд╛рдВрдирд╛ public IPs рджреЗрдКрди public subnet рдордзреНрдпреЗ рдареЗрд╡рд▓реЗ рддрд░ рджрд╛рд░ рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдиреА рдЙрдШрдбрддреЗ. NAT рддреЗ рдлрдХреНрдд рдПрдХрд╛рдЪ рдмрд╛рдЬреВрдиреЗ рдЙрдШрдбрддреЛ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

nat/demo.py рдордзреАрд▓ why() рдПрдХ public IP рдЕрд╕рд▓реЗрд▓реЗ рдПрдХ рдлрд╛рдЯрдХ рддрдпрд╛рд░ рдХрд░рддреЗ, NatGateway.send() рдиреЗ рдПрдХрд╛ рдмрд╛рдХрд╛рд▓рд╛ pypi.org рдХрдбреЗ рдмрд╛рд╣реЗрд░ рдкрд╛рдард╡рддреЗ, рдЖрдгрд┐ рдордЧ NatGateway.reply() рдиреЗ рдПрдХрд╛ рдЕрдиреЛрд│рдЦреА рдорд╛рдгрд╕рд╛рд▓рд╛ рдареЛрдард╛рд╡реВ рджреЗрддреЗ. nat/gateway.py рдордзреНрдпреЗ send() рд╣реЗ self.table (рдиреЛрдВрджрд╡рд╣реА) рдордзреНрдпреЗ рдПрдХ рдУрд│ рд▓рд┐рд╣рд┐рддреЗ рдЖрдгрд┐ public address рд╡ port рдкрд░рдд рджреЗрддреЗ; reply() рддреА рдУрд│ рд╢реЛрдзрддреЗ рдЖрдгрд┐ private рдмрд╛рдХ рдкрд░рдд рджреЗрддреЗ, рдХрд┐рдВрд╡рд╛ drop рдореЛрдЬреВрди None рдкрд░рдд рджреЗрддреЗ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 nat/demo.py why
python3 - <<'EOF'
import sys; sys.path.insert(0, "nat"); from gateway import NatGateway
PYPI = ("151.101.0.223", 443, "tcp")
STRANGER = ("198.51.100.9", 443, "tcp")
g = NatGateway("nat-a", ["13.232.10.20"])
ip, port = g.send(("10.20.48.25", 50001), PYPI)
print("the desk leaves as:", ip, port)
print("pypi answers:", g.reply(ip, port, PYPI))
print("stranger on the same port:", g.reply(ip, port, STRANGER))
print("stranger on port 8080:", g.reply(ip, 8080, STRANGER))
print("rows:", len(g.table), "dropped:", g.dropped)
EOF
python3 nat/test_nat.py

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

why рд╣реЗ app 10.20.48.25:50001 тЖТ pypi.org leaves as 13.232.10.20:1024 рдЖрдгрд┐ a stranger knocks on 13.232.10.20:2222 тЖТ dropped тАФ nobody inside asked рдЫрд╛рдкрддреЗ. рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:

the desk leaves as: 13.232.10.20 1024
pypi answers: ('10.20.48.25', 50001)
stranger on the same port: None
stranger on port 8080: None
rows: 1 dropped: 2

рддрд┐рд╕рд░реА рдУрд│ рдкрд╛рд╣рд╛: рдЕрдиреЛрд│рдЦреА рдорд╛рдгрд╕рд╛рдиреЗ рдмрд╛рдХ рд╡рд╛рдкрд░рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рддреНрдпрд╛рдЪ port рд╡рд░ рдареЛрдард╛рд╡рд▓реЗ, рдЖрдгрд┐ рддрд░реАрд╣реА рддреЛ drop рдЭрд╛рд▓рд╛. рдиреЛрдВрджрд╡рд╣реАрддреАрд▓ рдУрд│ рд╕рд╛рдВрдЧрддреЗ "port 1024, pypi.org рд╕рд╛рдареА". рдЗрддрд░ рдХреЛрдгрд╛рдХрдбреВрди рдЖрд▓реЗрд▓реЗ рдЙрддреНрддрд░ рдЬреБрд│рдд рдирд╛рд╣реА. Tests 8/8 passed рдиреЗ рд╕рдВрдкрддрд╛рдд.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

рдлрд╛рдЯрдХрд╛рдорд╛рдЧрдЪрд╛ рдмрд╛рдХ рдмрд╛рд╣реЗрд░ рдЬрд╛рдКрди рдЖрдкрд▓реЗ рдЙрддреНрддрд░ рдкрд░рдд рдорд┐рд│рд╡реВ рд╢рдХрддреЛ тАФ рдЖрдгрд┐ рдЕрдиреЛрд│рдЦреА рдорд╛рдгреВрд╕ рдЖрддрд▓реНрдпрд╛ рджрд┐рд╢реЗрдиреЗ рд╕рдВрд╡рд╛рдж рд╕реБрд░реВ рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА, рд╡рд╛рдкрд░рд╛рдд рдЕрд╕рд▓реЗрд▓рд╛ port рдЕрдВрджрд╛рдЬрд╛рдиреЗ рдУрд│рдЦрд▓рд╛ рддрд░реАрд╕реБрджреНрдзрд╛ рдирд╛рд╣реА.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд

рдЦрд▒реНрдпрд╛ account рд╡рд░ (AWS CLI рдЖрдгрд┐ credentials рд▓рд╛рдЧрддрд╛рдд; NAT gateway рддрдпрд╛рд░ рдЭрд╛рд▓реНрдпрд╛рдЪреНрдпрд╛ рдХреНрд╖рдгрд╛рдкрд╛рд╕реВрди рджрд░ рддрд╛рд╕рд╛рд▓рд╛ bill рд▓рд╛рдЧрддреЗ):

aws ec2 allocate-address --domain vpc                        # the gate's fixed address тЖТ eipalloc-тАж
aws ec2 create-nat-gateway --subnet-id subnet-public-a --allocation-id eipalloc-0abc --connectivity-type public
aws ec2 create-route --route-table-id rtb-private-a --destination-cidr-block 0.0.0.0/0 --nat-gateway-id nat-0abc
aws ec2 describe-nat-gateways --query 'NatGateways[].[NatGatewayId,State,SubnetId,ConnectivityType]' --output table

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: "internet рд▓рд╛ рд╕реЗрд╡рд╛ рди рджреЗрдгрд╛рд▒реНрдпрд╛ рд╕рдЧрд│реНрдпрд╛рд╕рд╛рдареА private subnets, рдЖрдгрд┐ egress NAT рдордзреВрди" рд╣реАрдЪ AWS network рдЪреА default рд░рдЪрдирд╛ рдЖрд╣реЗ. рдкреБрдврдЪреЗ рд╕рд╛рдд рдзрдбреЗ рддреЗ рдлрд╛рдЯрдХ рдиреАрдЯ рдЪрд╛рд▓рд╡рдгреНрдпрд╛рдмрджреНрджрд▓ рдЖрд╣реЗрдд: рддреЗ рдХрд╕реЗ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рддреЗ, рддреЗ рдХреБрдареЗ рдареЗрд╡рд╛рдпрдЪреЗ, рддреНрдпрд╛рдЪрд╛ рдЦрд░реНрдЪ рдХрд┐рддреА рдЖрдгрд┐ рддреЗ рдХрд╕реЗ рдмрд┐рдШрдбрддреЗ.

тПня╕П рдкреБрдвреЗ

рдПрдХ рдлрд╛рдЯрдХ, рдПрдХ public address, рд╢реЗрдХрдбреЛ рдмрд╛рдХ. рдЙрддреНрддрд░ рдХреЛрдгрддреНрдпрд╛ рдмрд╛рдХрд╛рдЪреЗ рдЖрд╣реЗ рд╣реЗ рд░рдЦрд╡рд╛рд▓рджрд╛рд░рд╛рд▓рд╛ рдХрд╕реЗ рдХрд│рддреЗ? рдлрд╛рдЯрдХ рдХрд╕реЗ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рддреЗ (PAT) тАФ рдиреЛрдВрджрд╡рд╣реА, рдУрд│-рдУрд│ рдХрд░реВрди.

git checkout lesson-02-how-pat-works

ЁЯЪк Lesson 01 тАФ Why NAT: the school gate

ЁЯУН You are here: Lesson 01 of 8 ┬╖ Next: lesson-02-how-pat-works


ЁЯУж What's in this branch

The one problem this whole course solves: servers in a private subnet need to reach the internet (updates, package downloads, partner APIs), but the internet must never be able to reach them. The answer is a gate that lets trips go out and answers come back, and nothing else: NAT (Network Address Translation). Real files you will use all the way through:

ЁЯОТ Before you start: you need Python 3 and nothing else тАФ no AWS account, no pip install. gateway.py is a teaching model, not a router: it follows the numbers in the AWS NAT gateway documentation (55,000 connections per destination per IP, a 350-second idle timeout), but it does not move real packets. Prices in it are example prices (us-east-1) тАФ always check the AWS pricing page. Commands marked on a real account need the AWS CLI and credentials, and a NAT gateway costs money every hour it exists.

ЁЯзТ Explain like I'm 5

A school has a private wing ЁЯПл. The rooms inside have private desk numbers тАФ "desk 25 in room 48". Those numbers mean nothing outside the school. A shop in town cannot post a letter to "desk 25".

So every trip out goes through the school gate ЁЯЪк. At the gate stands a guard with a register book ЁЯУТ:

Out: yes. Answers back: yes. Strangers walking in: never. That is NAT.

ЁЯЧ║я╕П Diagram

flowchart LR
    desk["ЁЯкС private desk<br/>10.20.48.25:50001"]
    gate["ЁЯЪк NAT gateway<br/>public IP 13.232.10.20<br/>ЁЯУТ register"]
    pypi["ЁЯМР pypi.org<br/>151.101.0.223:443"]
    stranger["ЁЯХ╡я╕П stranger<br/>198.51.100.9"]
    desk -->|"1 trip out"| gate
    gate -->|"2 leaves as 13.232.10.20:1024"| pypi
    pypi -->|"3 answer back тЖТ row found"| gate
    gate -->|"4 handed to the desk"| desk
    stranger -.->|"5 knocks тЖТ no row"| drop["ЁЯЪл dropped"]

ЁЯЧ║я╕П Drawn version + a lab: https://school-edh.pages.dev/nat/lesson-diagrams.html#l01

тЭУ What

ЁЯдФ Why

Because private subnets are where databases, app servers and batch jobs belong: nothing on the internet should be able to open a connection to them. But those same servers still need to fetch OS patches, pull packages from pypi.org or npm, and call payment or SMS APIs. Putting them in a public subnet with public IPs "just to download updates" opens the door both ways. NAT opens it one way only.

ЁЯФз How (in this repo)

why() in nat/demo.py builds one gate with one public IP, sends one desk out to pypi.org with NatGateway.send(), then lets a stranger knock with NatGateway.reply(). In nat/gateway.py, send() writes a row in self.table (the register) and returns the public address and port; reply() looks the row up and returns the private desk, or counts a drop and returns None.

ЁЯзк Try it

python3 nat/demo.py why
python3 - <<'EOF'
import sys; sys.path.insert(0, "nat"); from gateway import NatGateway
PYPI = ("151.101.0.223", 443, "tcp")
STRANGER = ("198.51.100.9", 443, "tcp")
g = NatGateway("nat-a", ["13.232.10.20"])
ip, port = g.send(("10.20.48.25", 50001), PYPI)
print("the desk leaves as:", ip, port)
print("pypi answers:", g.reply(ip, port, PYPI))
print("stranger on the same port:", g.reply(ip, port, STRANGER))
print("stranger on port 8080:", g.reply(ip, 8080, STRANGER))
print("rows:", len(g.table), "dropped:", g.dropped)
EOF
python3 nat/test_nat.py

тЬЕ Verify тАФ what you should see

why prints app 10.20.48.25:50001 тЖТ pypi.org leaves as 13.232.10.20:1024 and a stranger knocks on 13.232.10.20:2222 тЖТ dropped тАФ nobody inside asked. Your snippet prints:

the desk leaves as: 13.232.10.20 1024
pypi answers: ('10.20.48.25', 50001)
stranger on the same port: None
stranger on port 8080: None
rows: 1 dropped: 2

Look at the third line: the stranger knocked on the very port the desk is using, and was still dropped. The register row says "port 1024, for pypi.org". An answer from anyone else does not match. The tests end with 8/8 passed.

ЁЯПБ What you just proved

A desk behind the gate can go out and get its answer back тАФ and a stranger cannot start a conversation in, not even by guessing a port that is in use.

тЪая╕П Common mistakes

ЁЯПн In production

On a real account (needs the AWS CLI and credentials; the NAT gateway bills every hour from the moment it is created):

aws ec2 allocate-address --domain vpc                        # the gate's fixed address тЖТ eipalloc-тАж
aws ec2 create-nat-gateway --subnet-id subnet-public-a --allocation-id eipalloc-0abc --connectivity-type public
aws ec2 create-route --route-table-id rtb-private-a --destination-cidr-block 0.0.0.0/0 --nat-gateway-id nat-0abc
aws ec2 describe-nat-gateways --query 'NatGateways[].[NatGatewayId,State,SubnetId,ConnectivityType]' --output table

ЁЯПн Why this matters in production: "private subnets for everything that does not serve the internet, egress through NAT" is the default AWS network design. The next seven lessons are about running that gate well: how it remembers, where to put it, what it costs and how it breaks.

тПня╕П Next

One gate, one public address, hundreds of desks. How does the guard know which desk an answer belongs to? How the gate remembers (PAT) тАФ the register, row by row.

git checkout lesson-02-how-pat-works
тЖР Course homeall lessonsNext тЖТhow pat works

This page is the lesson's README from the lesson-01-why-nat branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.