EC2 ohne Internetzugang im eigenen VPC – Internet Gateway und Route Table korrekt einrichten

Du hast ein eigenes VPC erstellt, eine EC2-Instanz in einem öffentlichen Subnetz gestartet – und ping google.com läuft ins Leere. Kein Timeout-Fehler, keine Fehlermeldung, einfach nichts. Dieses Problem tritt fast immer auf, wenn ein Custom VPC ohne Internet Gateway oder mit einer unvollständigen Route-Table-Konfiguration aufgesetzt wird, weil AWS bei eigenen VPCs bewusst keine Standard-Internetverbindung mitliefert.

TL;DR – EC2 Internetzugang im Custom VPC

SchrittAktionWarum notwendig
1Internet Gateway erstellen und an VPC anhängenOhne IGW gibt es keinen Pfad ins öffentliche Internet
2Route Table aktualisieren (0.0.0.0/0 → IGW)Der Traffic muss explizit über das IGW geroutet werden
3Subnetz mit Route Table verknüpfenEine Route Table ohne Subnetz-Assoziation hat keine Wirkung
4Öffentliche IP oder Elastic IP prüfenOhne öffentliche IP kann das IGW keinen eingehenden Rückpfad aufbauen
5Security Group und Network ACL prüfenFirewall-Regeln können ausgehenden ICMP/TCP-Traffic blockieren

Wie ein Custom VPC und Internetzugang funktionieren

Wenn AWS ein Default-VPC anlegt, werden Internet Gateway, Route Tables und Subnetz-Assoziationen automatisch konfiguriert. Bei einem Custom VPC passiert das nicht – du bekommst ein leeres Netzwerk-Konstrukt ohne jede externe Konnektivität. Das ist kein Bug, sondern bewusstes Design für Isolation.

Damit eine EC2-Instanz in einem öffentlichen Subnetz das Internet erreichen kann, müssen drei unabhängige Bedingungen gleichzeitig erfüllt sein:

  • Ein Internet Gateway (IGW) muss existieren und am VPC hängen.
  • Die Route Table des Subnetzes muss eine Route 0.0.0.0/0 zum IGW enthalten.
  • Die Instanz muss eine öffentliche IPv4-Adresse oder Elastic IP besitzen.

Fehlt auch nur eine dieser drei Bedingungen, kommt kein Paket raus. Security Groups und Network ACLs sind zusätzliche Schichten, die den Traffic danach noch blockieren können.

graph LR EC2["EC2-Instanz
Private IP"] NACL["Network ACL
Subnetz-Ebene"] RT["Route Table
0.0.0.0/0 → IGW"] IGW["Internet Gateway
NAT: privat → öffentlich"] SG["Security Group
Instanz-Ebene"] INET["Öffentliches Internet"] EC2 -->|"ausgehend"| NACL NACL -->|"erlaubt"| RT RT -->|"Default-Route"| IGW IGW -->|"öffentliche IP"| INET INET -->|"Antwort"| SG SG -->|"stateful: erlaubt"| EC2
  1. EC2-Instanz sendet ein Paket an eine externe IP.
  2. Das Paket trifft auf die Network ACL des Subnetzes – erste Filterebene auf Subnetz-Ebene.
  3. Die Route Table entscheidet, wohin das Paket geroutet wird. Ohne 0.0.0.0/0 → IGW wird es verworfen.
  4. Das Internet Gateway übersetzt die private IP der Instanz in ihre öffentliche IP (NAT) und leitet das Paket ins Internet.
  5. Eingehende Antworten durchlaufen die Security Group der Instanz als letzte Filterebene.

Schritt-für-Schritt: EC2 Internetzugang im Custom VPC einrichten

Schritt 1: Vorhandene Konfiguration prüfen

Bevor du etwas änderst, verschaffe dir einen vollständigen Überblick. Die meisten Fehler entstehen dadurch, dass man annimmt, ein IGW sei bereits vorhanden – und dann an der falschen Stelle sucht. Prüfe zuerst, ob dein VPC überhaupt ein Internet Gateway hat.

# VPC-ID ermitteln
aws ec2 describe-vpcs \
  --filters 'Name=isDefault,Values=false' \
  --query 'Vpcs[*].{VpcId:VpcId,CidrBlock:CidrBlock,Name:Tags[?Key==`Name`].Value|[0]}' \
  --output table

# Internet Gateways prüfen – ist eines an dein VPC angehängt?
aws ec2 describe-internet-gateways \
  --filters 'Name=attachment.vpc-id,Values=vpc-0123456789abcdef0' \
  --query 'InternetGateways[*].{IGW_ID:InternetGatewayId,State:Attachments[0].State}' \
  --output table

Gibt die zweite Abfrage eine leere Liste zurück, fehlt das Internet Gateway – dann weiter mit Schritt 2. Gibt es ein IGW mit Status available, liegt das Problem in Route Table oder Security Group.

Schritt 2: Internet Gateway erstellen und am VPC anhängen

Ein IGW existiert zunächst unabhängig von jedem VPC. Erst der Attach-Befehl verbindet beides. Dieser Zwei-Schritt-Prozess ist wichtig – ein erstelltes, aber nicht angehängtes IGW hat keinerlei Wirkung, und die AWS-Konsole zeigt es trotzdem als vorhanden an.

# Internet Gateway erstellen
aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=mein-igw}]' \
  --query 'InternetGateway.InternetGatewayId' \
  --output text

# Ausgabe: igw-0abc123def456789a

# IGW an VPC anhängen
aws ec2 attach-internet-gateway \
  --internet-gateway-id igw-0abc123def456789a \
  --vpc-id vpc-0123456789abcdef0

Kein Output bedeutet Erfolg. Prüfe danach erneut mit describe-internet-gateways, ob der Status auf available steht.

Schritt 3: Route Table des öffentlichen Subnetzes aktualisieren

Das IGW hängt jetzt am VPC – aber der Traffic findet es noch nicht, weil die Route Table nichts davon weiß. Du musst eine explizite Default-Route hinzufügen. Zuerst die Route Table des betroffenen Subnetzes identifizieren, dann die Route eintragen.

# Route Tables im VPC auflisten und Subnetz-Assoziationen prüfen
aws ec2 describe-route-tables \
  --filters 'Name=vpc-id,Values=vpc-0123456789abcdef0' \
  --query 'RouteTables[*].{RT_ID:RouteTableId,Subnets:Associations[*].SubnetId,Routes:Routes[*].DestinationCidrBlock}' \
  --output table

# Default-Route zum IGW hinzufügen
aws ec2 create-route \
  --route-table-id rtb-0abc123def456789a \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id igw-0abc123def456789a

Wenn die Route bereits existiert (z. B. mit einem anderen Gateway), schlägt create-route fehl. In diesem Fall replace-route verwenden:

aws ec2 replace-route \
  --route-table-id rtb-0abc123def456789a \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id igw-0abc123def456789a

Schritt 4: Subnetz mit der Route Table verknüpfen

Eine Route Table mit korrekten Routen, aber ohne Subnetz-Assoziation, hat keine Wirkung auf Instanzen in diesem Subnetz. Das ist ein häufiger Fallstrick: Man sieht die Route im AWS-Konsole und denkt, alles ist korrekt – aber das Subnetz nutzt noch die Haupt-Route-Table des VPC, die keine IGW-Route enthält.

# Subnetz-ID ermitteln
aws ec2 describe-subnets \
  --filters 'Name=vpc-id,Values=vpc-0123456789abcdef0' \
  --query 'Subnets[*].{SubnetId:SubnetId,CidrBlock:CidrBlock,AZ:AvailabilityZone}' \
  --output table

# Subnetz mit Route Table verknüpfen
aws ec2 associate-route-table \
  --route-table-id rtb-0abc123def456789a \
  --subnet-id subnet-0abc123def456789a

Schritt 5: Öffentliche IP der EC2-Instanz sicherstellen

Das IGW kann nur Pakete weiterleiten, wenn die Instanz eine öffentliche IP hat – es führt eine 1:1-NAT zwischen privater und öffentlicher IP durch. Ohne öffentliche IP gibt es schlicht keine Adresse, an die Antwortpakete zurückgesendet werden könnten.

# Öffentliche IP der Instanz prüfen
aws ec2 describe-instances \
  --instance-ids i-0abc123def456789a \
  --query 'Reservations[*].Instances[*].{InstanceId:InstanceId,PrivateIP:PrivateIpAddress,PublicIP:PublicIpAddress,State:State.Name}' \
  --output table

Zeigt PublicIP None, hat die Instanz keine öffentliche IP. Du hast zwei Optionen:

  • Elastic IP zuweisen (empfohlen für Produktionsumgebungen – die IP bleibt beim Stop/Start erhalten):
# Elastic IP allozieren
aws ec2 allocate-address \
  --domain vpc \
  --query 'AllocationId' \
  --output text

# Ausgabe: eipalloc-0abc123def456789a

# Elastic IP der Instanz zuweisen
aws ec2 associate-address \
  --instance-id i-0abc123def456789a \
  --allocation-id eipalloc-0abc123def456789a
  • Auto-Assign Public IP im Subnetz aktivieren (für neue Instanzen):
aws ec2 modify-subnet-attribute \
  --subnet-id subnet-0abc123def456789a \
  --map-public-ip-on-launch

Achtung: modify-subnet-attribute wirkt nur auf neu gestartete Instanzen. Bestehende Instanzen ohne öffentliche IP benötigen eine Elastic IP.

Schritt 6: Security Group auf ausgehenden Traffic prüfen

Security Groups sind stateful – wenn ausgehender Traffic erlaubt ist, werden Antwortpakete automatisch zugelassen. Das Problem liegt fast immer bei ausgehenden Regeln, die zu restriktiv gesetzt wurden, oder bei eingehenden ICMP-Regeln, wenn du mit ping testest.

# Security Group der Instanz ermitteln
aws ec2 describe-instances \
  --instance-ids i-0abc123def456789a \
  --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId' \
  --output text

# Ausgehende Regeln der Security Group prüfen
aws ec2 describe-security-groups \
  --group-ids sg-0abc123def456789a \
  --query 'SecurityGroups[*].{Outbound:IpPermissionsEgress}' \
  --output json

Für grundlegende Konnektivitätstests sollte die Security Group ausgehenden Traffic auf Port 80/443 (TCP) und ICMP erlauben. Falls die Egress-Regeln fehlen:

# Ausgehenden HTTPS-Traffic erlauben
aws ec2 authorize-security-group-egress \
  --group-id sg-0abc123def456789a \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# Ausgehenden HTTP-Traffic erlauben
aws ec2 authorize-security-group-egress \
  --group-id sg-0abc123def456789a \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0

# Ausgehenden ICMP-Traffic erlauben (für ping)
aws ec2 authorize-security-group-egress \
  --group-id sg-0abc123def456789a \
  --protocol icmp \
  --port -1 \
  --cidr 0.0.0.0/0

Schritt 7: Network ACL prüfen

Network ACLs sind stateless – Antwortpakete müssen explizit durch eingehende Regeln erlaubt werden. Das ist der Unterschied zu Security Groups, der in der Praxis oft vergessen wird. Wenn ausgehender Traffic funktioniert, aber keine Antwort ankommt, liegt es häufig an einer Network ACL, die eingehende Ephemeral Ports blockiert.

# Network ACL des Subnetzes prüfen
aws ec2 describe-network-acls \
  --filters 'Name=association.subnet-id,Values=subnet-0abc123def456789a' \
  --query 'NetworkAcls[*].{AclId:NetworkAclId,Entries:Entries[*].{Rule:RuleNumber,Protocol:Protocol,Action:RuleAction,CIDR:CidrBlock,Egress:Egress}}' \
  --output table

Die Standard-Network-ACL eines Custom VPC erlaubt allen Traffic (Regel 100: ALLOW ALL). Wenn du eine eigene ACL erstellt hast, stelle sicher, dass sowohl ausgehende als auch eingehende Regeln für die benötigten Ports vorhanden sind – inklusive der Ephemeral-Port-Range für Antwortpakete (typischerweise 1024–65535).

Häufige Fehlerdiagnose: Das stille Fehlschlagen

graph TD S1["Symptom: ping schlägt fehl"] S2["Annahme 1: Security Group blockiert ICMP"] S3["ICMP in SG erlaubt – Problem bleibt"] S4["Annahme 2: DNS-Problem"] S5["curl auf IP schlägt ebenfalls fehl"] S6["Ursache: Subnetz nutzt Haupt-RT
ohne IGW-Route"] S7["Fix: associate-route-table ausführen"] S8["Ping erfolgreich"] S1 --> S2 S2 --> S3 S3 --> S4 S4 --> S5 S5 --> S6 S6 --> S7 S7 --> S8
  1. Symptom: ping google.com antwortet nicht, kein Fehler.
  2. Erste Annahme: Security Group blockiert ICMP – ICMP in der SG erlaubt, Problem bleibt.
  3. Zweite Annahme: DNS funktioniert nicht – curl https://8.8.8.8 schlägt ebenfalls fehl.
  4. Tatsächliche Ursache: Das Subnetz war noch mit der Haupt-Route-Table verknüpft, die keine IGW-Route enthielt. Die neue Route Table mit IGW-Route existierte, war aber nicht mit dem Subnetz assoziiert.
  5. Fix: associate-route-table ausführen – sofortiger Erfolg.

Das Tückische: In der AWS-Konsole sieht man die Route Table mit der korrekten IGW-Route und denkt, alles stimmt. Die Subnetz-Assoziation ist auf einer anderen Tab-Seite versteckt.

IAM-Berechtigungen für diese Operationen

Wenn du diese Schritte als IAM-Benutzer oder über eine Rolle ausführst, benötigst du mindestens die folgenden Berechtigungen. Ohne diese schlagen die CLI-Befehle mit UnauthorizedOperation fehl.

🔽 IAM-Policy anzeigen (Least Privilege für VPC-Netzwerkkonfiguration)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VPCNetworkConfiguration",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeVpcs",
        "ec2:DescribeSubnets",
        "ec2:DescribeRouteTables",
        "ec2:DescribeInternetGateways",
        "ec2:DescribeInstances",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeNetworkAcls",
        "ec2:CreateInternetGateway",
        "ec2:AttachInternetGateway",
        "ec2:CreateRoute",
        "ec2:ReplaceRoute",
        "ec2:AssociateRouteTable",
        "ec2:AllocateAddress",
        "ec2:AssociateAddress",
        "ec2:ModifySubnetAttribute",
        "ec2:AuthorizeSecurityGroupEgress"
      ],
      "Resource": "*"
    }
  ]
}

Hinweis: Viele Describe-Aktionen im EC2-Namespace unterstützen keine ressourcenbasierte Einschränkung und erfordern "Resource": "*". Überprüfe die aktuellen Einschränkungen im AWS Service Authorization Reference.

Vollständige Konfiguration verifizieren

Nachdem alle Schritte abgeschlossen sind, eine abschließende Prüfung der gesamten Konfiguration:

# Alle Routen der Route Table prüfen
aws ec2 describe-route-tables \
  --route-table-ids rtb-0abc123def456789a \
  --query 'RouteTables[*].Routes[*].{Destination:DestinationCidrBlock,Target:GatewayId,State:State}' \
  --output table

# Subnetz-Assoziation bestätigen
aws ec2 describe-route-tables \
  --route-table-ids rtb-0abc123def456789a \
  --query 'RouteTables[*].Associations[*].{SubnetId:SubnetId,Main:Main}' \
  --output table

# Öffentliche IP der Instanz bestätigen
aws ec2 describe-instances \
  --instance-ids i-0abc123def456789a \
  --query 'Reservations[*].Instances[*].{PublicIP:PublicIpAddress,State:State.Name}' \
  --output table

Wenn Routes eine Zeile mit 0.0.0.0/0 und dem IGW als Target zeigt, die Subnetz-Assoziation korrekt ist und die Instanz eine öffentliche IP hat – dann sollte ping google.com von der Instanz aus funktionieren.

Nächste Schritte und weiterführende Ressourcen

Mit einem funktionierenden Internet Gateway und korrekter Route Table hast du die Grundlage für ein öffentliches Subnetz gelegt. Für Produktionsumgebungen solltest du zusätzlich folgende Punkte berücksichtigen:

  • NAT Gateway für private Subnetze: Instanzen in privaten Subnetzen benötigen ein NAT Gateway für ausgehenden Internetzugang, ohne selbst öffentlich erreichbar zu sein.
  • VPC Flow Logs aktivieren: Für Troubleshooting auf Netzwerkebene sind Flow Logs unverzichtbar – sie zeigen, ob Pakete akzeptiert oder abgelehnt wurden.
  • Bastion Host oder AWS Systems Manager Session Manager: Direkter SSH-Zugriff über öffentliche IPs ist in Produktionsumgebungen ein Sicherheitsrisiko.

Offizielle Dokumentation: AWS VPC Internet Gateway – Dokumentation

Glossar – Schlüsselbegriffe für EC2 Internetzugang im Custom VPC

BegriffErklärung
Internet Gateway (IGW)Horizontales Skalierungskomponent, das ein VPC mit dem öffentlichen Internet verbindet. Muss explizit erstellt und am VPC angehängt werden.
Route TableRegelsatz, der bestimmt, wohin Netzwerkpakete aus einem Subnetz geroutet werden. Jedes Subnetz ist genau einer Route Table zugeordnet.
Elastic IP (EIP)Statische öffentliche IPv4-Adresse, die einem AWS-Konto zugeordnet ist und einer Instanz zugewiesen werden kann. Bleibt beim Stoppen der Instanz erhalten.
Network ACL (NACL)Zustandslose Firewall auf Subnetz-Ebene. Im Gegensatz zu Security Groups müssen Antwortpakete durch explizite eingehende Regeln erlaubt werden.
Öffentliches SubnetzEin Subnetz, dessen Route Table eine Route zum Internet Gateway enthält. Der Begriff ist eine Konvention – AWS erzwingt keine technische Unterscheidung.

Kommentare

Beliebte Posts aus diesem Blog

EC2 SSH Verbindungs-Timeout: Security Group Inbound-Regeln richtig konfigurieren