Ein AWS-Problem, bei dem ich regelmäßig um Hilfe gebeten werde, klingt in der ersten Beschreibung meist so:

Ich habe hier was installiert (z.B. eine EC2 Instanz mit WebServer, eine RDS, ein ECS Cluster, oder …). Aber leider kann ich es nicht erreichen. Was ist der Grund?

Natürlich ist dieses Fehlerbild ziemlich allgemein und es gibt eine ganze Reihe möglicher Ursachen. Meist lässt sich das Problem dennoch recht schnell eingrenzen und dann auch beheben, wenn man ein Grundverständnis der beteiligten AWS-Dienste und -Ressourcen hat. Ich arbeite in solchen Fällen eine innere Checkliste ab, die die wichtigsten an einer TCP/IP-Verbindung beteiligten Infrastrukturkomponenten in AWS durchgeht.

Diese „Checkliste“ schreibe ich nun explizit auf, um dieser Fehlerklasse den Nimbus des Magischen zu nehmen. (Ein Kollege schrieb mir kürzlich: „Irgendwie ist das [AWS] alles ziemlich gruselig“).

Mein Vorgehen hat vermutlich viele Lücken, insofern bin ich für Verbesserungsvorschläge oder Alternativen dankbar.

Meine Checkliste:

  • Funktioniert die Namensauflösung?
  • Ist das Ziel adressierbar?
  • Gibt es eine Netzwerk-Route von der Quelle zum Ziel?
  • Gibt es eine Network-ACL, die gegen die Verbindung spricht?
  • Gibt eine Security Group, die die Verbindung erlaubt?
  • Lauscht der Dienst überhaupt auf dem/einem öffentlichen Interface?

Die Reihenfolge, in der ich die Punkte bearbeite, hängt in der Regel davon ab, welche Ursache ich vermute – ich arbeite dabei also wesentlich weniger systematisch, als ich mir selbst gerne vormachen würde.

Hier nun Erläuterungen zu den einzelnen Punkten im Detail:

Namensauflösung

Wenn die Zielressource über einen DNS Namen adressiert wird, probiere ich, ob sich dieser auflösen lässt. Das mache ich z.B. mit dem Kommandozeilen-Tool dig. Je nachdem, was in der Umgebung zur Verfügung steht, tut es aber auch oft ein einfaches ping zum ersten Validieren. Umgebung ist dabei auch ein wichtiges Stichwort, denn Namensauflösung ist durchaus abhängig davon, wo sie statt findet.

Im AWS-Kontext tritt dabei vor allem der „split-horizon“ an der AWS- bzw. VPC-Grenze auf: Der gleiche Domainname kann innerhalb von AWS zu einer privaten 10er IP-Adresse und außerhalb zu einer öffentlichen IP aufgelöst werden. Das kann besonders bei den default EC2-DNS-Namen verwirrend sein, die dem Muster ec2-public-ipv4-address.region.compute.amazonaws.com folgen. Der DNS-Name mit der öffentlichen IP muss nicht zur öffentlichen IP aufgelöst werden. Das Ganze ist dabei ein Feature zum (kosten-)effizienten Routen (AWS Dokumentation).

Am Ende dieses Checks sollte man also zuversichtlich sein, dass der Name in der richtigen Umgebung zur erwarteten IP auflöst.

Ist das Ziel adressierbar?

Damit eine direkte Verbindung zum Zielsystem aufgebaut werden kann, muss dessen IP-Adresse bekannt sein und im Adressraum des Quellsystems liegen. Konkret bedeutet das: Soll die Verbindung aus dem (oder „über“ das) Internet stattfinden, muss die Ziel-IP eine öffentliche sein und keine aus dem für private Netze reserviertem Raum (Häufig 10.*.*.*, es gibt aber weitere private Adressen).

Bei RDS heißt die Option zum Zuweisen einer öffentlichen Adresse „Publicly Accessible“. Bei EC2-Instanzen muss dafür eine öffentliche oder „elastic IP“ zugewiesen sein. Default-Werte dafür ergeben sich daraus, ob das Subnetz „öffentlich“ oder „privat“ ist.

Die globale Adressierbarkeit ist natürlich nicht immer wünschenswert. Wenn die Verbindung zwischen zwei Punkten innerhalb eines VPC (oder zwischen zwei mittels Peering verbundenen VPCs) stattfinden soll, reicht die private Adresse.

Häufig existiert auch eine extern adressierbare Schnittstelle wie ein Loadbalancer oder ein „Jump Host“, von dem aus die eigentlichen Ziele dann nur privat adressierbar sind.

Ein Mischfall sind Server, die nicht aus dem Internet adressierbar sein sollen, selbst aber Verbindungen „nach draußen“ initiieren können sollen. In diesem Fall reicht eine private Adresse, es braucht aber NAT.

Gibt es eine Route?

Um das Routing in AWS zu verstehen, ist es notwendig, etwas auszuholen. Mit Hilfe des Dienstes VPC (Virtual Private Cloud) kann man sehr flexibel die Struktur seinen Netzwerkes definieren. Die wichtigsten Bestandteile sind dabei:

Die Tabelle eines Netzes, das aus dem Internet erreichbar ist, sieht dabei dann z.B. so aus:

Destination Target
172.31.0.0/16 local
0.0.0.0/0 igw-XXXXXXXX

Es gibt also eine Route für die lokalen Adressen und eine Route für alles andere zum Internet-Gateway. Meiner Erfahrung nach fehlt häufig die zweite Zeile in der Tabelle, also das Routing zum Internet-Gateway für alle nicht lokalen Adressen.

Verhindert die Network ACL den Zugriff?

„Network access control lists“ (ACLs) sind eine optionale Sicherheitsschicht in VPCs bei Amazon. Es handelt sich um Firewalls auf Subnetzebene. Sie erlauben es, eingehenden und ausgehenden Netzwerkverkehr mit „allow“- und „deny“-Regeln zu filtern.

Ich erwähne sie hier nur der Vollständigkeit halber. Da sie per default „offen“ konfiguriert sind, sind sie kein typisches Problem bei ersten Schritten in AWS. In komplexeren, besser abgesicherten Setups lohnt sich aber ein genauerer Blick.

Security Groups

Ein wesentlich häufigerer Grund für Verbindungsprobleme sind meiner Erfahrung nach fehlerhafte Security Groups (SG). Auch SGs sind Firewalls, sie operieren aber auf Instanzebene, sind also ein oder mehreren EC2- oder RDS- (oder …) Instanzen zugeordnet.

Security Groups enthalten eine Liste von Regeln, die Verbindungen zulassen. Dabei bezieht sich jede Regel auf einen Port oder Port Range und eine Quelle. Die Quelle wird hier entweder über eine feste IP, einen IP-Range (CIDR notation) oder eine Referenz auf eine andere Security Group definiert.

Grade diese letzte Möglichkeit ist beim ersten Kontakt mit Security Groups nicht offensichtlich, aber notwendig für typische Setups. Ein solches ist, z.B. den Zugriff auf einen HTTP-Port von einem Amazon Loadbalancer (ELB) aus zuzulassen:

Port Source
8080 sg-XXXX

Dabei ist die Security Group sg-XXXX dem Loadbalancer zugewiesen.

Lokale Probleme

Zu guter Letzt kann es sein, dass das Problem überhaupt nichts mit AWS zu tun hat. Einige Server lauschen per Default aus Sicherheitsgründen nur „lokal“, also auf dem Loopback-Device. Sie müssen dann explizit konfiguriert werden, auf anderen Interfaces zu lauschen. Häufig geschieht das durch Zuweisen der Bind-Adresse 0.0.0.0.

Eine andere lokale Fehlerquelle sind lokale Firewalls. Es lohnt sich also, einen Blick in iptables, firewalld oder Entsprechungen zu werfen.

Das war’s auch schon. Ich hoffe, meine Checkliste nützt dem ein oder der anderen.