Networking fundamentals · Advanced
Routing between networks: peering, transit, VPN and private DNS
Why it matters
Networking appeared in 56% of the Cloud and Network Engineer job descriptions we read. Once a company has more than one network (several VPCs, an office, a data centre), the work shifts to connecting them: which path each packet takes, what happens when ranges overlap, and how names resolve on each side.
The concept
Longest prefix match. A router picks the most specific route that contains the destination. A /16 beats a /8, and 0.0.0.0/0 (the default route) is used only when nothing else matches.
Ways to connect networks:
VPC peering: a direct, private link between two VPCs. Simple and cheap, but not transitive (A to B and B to C does not give A to C), so a full mesh grows quickly.
Transit gateway (or a hub VNet in Azure): a hub that many VPCs and VPNs attach to, with its own route tables. It scales to many networks and centralises control.
Site-to-site VPN: an encrypted tunnel over the internet to an office or data centre, often with BGP to exchange routes. Dedicated links (AWS Direct Connect, Azure ExpressRoute) give more predictable bandwidth and latency.
Private DNS: private hosted zones and resolver rules so
db.internalresolves correctly from every connected network, including forwarding between the cloud and on-premises DNS.
Non-overlapping ranges are the prerequisite. Routing cannot tell two networks with the same range apart.
Worked example: an app subnet's route table
import ipaddress
# Route table of an app subnet in a hub-and-spoke network (like an AWS route table with a transit gateway).
ROUTES = [
("10.20.0.0/16", "local"), # this VPC
("10.0.0.0/8", "transit-gateway"), # other VPCs and the office, via the hub
("10.30.0.0/16", "peering-to-analytics"), # a direct peering is more specific than the /8
("192.168.0.0/16", "vpn-to-office"),
("0.0.0.0/0", "nat-gateway"), # everything else: the internet, outbound only
]
TABLE = [(ipaddress.ip_network(cidr), target) for cidr, target in ROUTES]
def next_hop(destination: str) -> tuple[str, str]:
ip = ipaddress.ip_address(destination)
matches = [(net, target) for net, target in TABLE if ip in net]
net, target = max(matches, key=lambda m: m[0].prefixlen) # longest prefix wins
return str(net), target
for dest in ["10.20.33.7", "10.30.4.12", "10.45.1.1", "192.168.10.5", "142.250.183.14"]:
net, target = next_hop(dest)
print(f"{dest:15} matches {net:15} -> {target}")$ python3 routes.py
10.20.33.7 matches 10.20.0.0/16 -> local
10.30.4.12 matches 10.30.0.0/16 -> peering-to-analytics
10.45.1.1 matches 10.0.0.0/8 -> transit-gateway
192.168.10.5 matches 192.168.0.0/16 -> vpn-to-office
142.250.183.14 matches 0.0.0.0/0 -> nat-gateway10.30.4.12 matches both 10.0.0.0/8 and 10.30.0.0/16; the /16 is more specific, so traffic to the analytics VPC takes the direct peering instead of the transit gateway. 10.45.1.1 only matches the /8 and goes through the hub. The public address only matches the default route and leaves through the NAT gateway. Cloud route tables use exactly this rule.
Troubleshooting paths
When two networks cannot talk, check both directions: a route from A to B, a route back from B to A, security groups or firewalls on both sides, network ACLs, and DNS on the client side. Asymmetric routing, where the return path differs and a stateful firewall drops it, is a classic cause of "it works one way". Cloud tools such as VPC Reachability Analyzer and flow logs show where packets stop.
Common mistakes
Overlapping CIDRs between VPCs or with the office, discovered only when someone needs to connect them.
Forgetting the return route, or adding it to the wrong route table.
A full mesh of peerings that no one can reason about. Move to a hub once you have more than a few VPCs.
DNS that works in one network only, because resolver rules were not shared.
Interview angle
"How would you connect 20 VPCs and two offices?" (a transit hub with route table segmentation, VPN or dedicated links with BGP, central private DNS, non-overlapping IP plan). "Is VPC peering transitive?" (no). "Two routes match a destination; which wins?" (the longest prefix).
Practice task
Add a route
10.30.8.0/22 -> firewall-inspectionand predict, then check, where10.30.9.1and10.30.4.12go.Draw the route tables on both sides for the analytics peering, including the return routes, and list the security group rules needed for PostgreSQL traffic.