Ursprünglich veröffentlicht im August 2021. Aktualisiert im Mai 2025.
Kurzantwort: Um curl zu verwenden, öffnen Sie ein Terminal und geben Sie curl ein, gefolgt von der URL, die Sie anfragen möchten – zum Beispiel curl https://www.fastly.com/. Dies sendet eine HTTP-Anfrage und gibt die Antwort direkt auf Ihrem Bildschirm aus.
Fazit:
Verwenden Sie
curl -svo /dev/null, um Verbindungsdetails, TLS-Handshakes, Anfrage-Header und Antwort-Header zu prüfen, ohne von einem Antworttext abgelenkt zu werden.Verwenden Sie
-H "host: ...", um zu testen, wie ein Server auf verschiedene Host-Header reagiert.Verwenden Sie
--resolve, um DNS zu überbrücken und Anfragen an eine bestimmte IP-Adresse zu senden.Verwenden Sie
--connect-to, um Verbindungen umzuleiten und dabei den ursprünglichen Hostnamen der Anfrage zu erhalten.Durch die Kombination dieser Optionen lassen sich Probleme mit Routing, DNS, TLS und Origin-Servern leichter beheben.
Kennen Sie das Gefühl, dass es manchmal nur um ein einziges Thema geht? Als Sales Engineer unterstütze ich unsere Kunden bei der Erstellung und Bereitstellung von Systemen, und vergangene Woche ging es dabei definitiv hauptsächlich um ein Thema.
Ich wurde mit etwas konfrontiert, das ich bisher für einen Nischenanwendungsfall gehalten hatte: Ich musste ein bestimmtes Tool (cURL) auf eine bestimmte Art und Weise nutzen, um die Reaktion eines Origin-Servers zu testen (z. B. ob eine Anwendung als Antwort eine ungewöhnliche Fehlermeldung zurückgibt). Und dieses Thema verfolgte mich immer weiter! Ich erklärte den Prozess einigen Kollegen, die damit noch nicht so vertraut waren, sowie einigen Kunden, die Fehler bei ihren Bereitstellungen beheben wollten. Und dabei entstand die Idee für diesen Blogpost. Legen wir doch am besten gleich los.
Ein kurzer cURL-Überblick
Client URL (auch als cURL oder curl bekannt) wurde im Jahr 1997 von Daniel Stenberg veröffentlicht, der das Projekt seitdem fleißig betreut. Ursprünglich wurde dieses Tool entwickelt, um den Abruf von Wechselkursen für IRC-Nutzer zu automatisieren. Inzwischen wird es aber für sämtliche URL-Abrufe verwendet. Seit Stenberg das Projekt ins Leben rief, hat er es ständig weiterentwickelt und neue Funktionen hinzugefügt, sodass es inzwischen zu einem Grundpfeiler für andere Projekte geworden ist. Absolut großartig.
Bei Curl handelt es sich um ein Kommandozeilen-Tool, mit dem Sie HTTP-Requests an eine URL senden und das Ergebnis empfangen können. Standardmäßig sendet curl eine HTTP-GET-Anfrage, wodurch es sich zum Testen von Websites, APIs und Origin-Servern eignet. Bei Betriebssystemen wie macOS und vielen Linux-Distributionen ist es bereits standardmäßig enthalten. Und da ein Großteil des Internets auf HTTP ausgerichtet ist, ist es ein großartiges Tool, um Webseiten, APIs oder alles andere mit einer HTTP-Schnittstelle anzusteuern.
Zu Demozwecken verwenden wir curl, um das Browserverhalten beim Anfordern einer Webseite zu simulieren. So behalten wir die vollständige Kontrolle über die Anfrage, was die Fehlersuche erheblich erleichtert.
Nachfolgend finden Sie einen einfachen curl-Befehl, den ich mit dem Terminalprogramm auf meinem MacBook ausgeführt habe. Mit diesem Befehl wird die Fastly-Website aufgerufen und der vollständige HTML-Code angezeigt. Der Output ist zwar etwas unübersichtlich, aber um die Bereinigung kümmern wir uns später.
$ curl https://www.fastly.com/Gängige cURL-Flags für die Fehlerbehebung
-s: Silent-Modus-v: Ausführliche Ausgabe mit Anfrage- und Antwortdetails-o: Ausgabe in eine Datei schreiben-I: Nur Antwort-Header zurückgeben-H: Einen benutzerdefinierten HTTP-Header hinzufügen--resolve: DNS-Auflösung für einen Hostnamen überbrücken--connect-to: Verbindung zu einem anderen Host oder einer anderen IP-Adresse herstellen
Die eigentliche Stärke von curl besteht darin, dass man Requests mit Flags manipulieren kann. Indem man zum Beispiel -I hinzufügt, werden als Antwort nur die Header vom Remote-Server ausgegeben und nicht die Inhalte.
Ich verwende bei fast allen curls als Flags -svo, wobei „s“ für „silent mode“, „v“ für „verbose“ und „o“ für „writing to a file“ steht. Diese setze ich auf /dev/null.
Der vollständige curl Befehl lautet also curl -svo /dev/null https://www.fastly.com. So kann ich mich auf die genauen Requests konzentrieren, ohne von einer unübersichtlichen Antwort abgelenkt zu werden. Die Header sind mit praktischen kleinen Flags versehen, die anzeigen, ob sie gesendet oder empfangen wurden, und der SSL-Handshake wird vor der Hauptanfrage angezeigt.
Nachfolgend sehen Sie den schriftlichen Befehl ($), die Verbindung und den SSL-Handshake (*), die Anfrage (>) und die Antwort (<).
$ curl -svo /dev/null https://www.fastly.com/
* Trying 199.232.77.57...
* TCP_NODELAY set
* Connected to www.fastly.com (199.232.77.57) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [228 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [102 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2828 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [300 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Fastly, Inc.; CN=www.fastly.com
* start date: Mar 3 21:56:03 2021 GMT
* expire date: Apr 4 21:56:03 2022 GMT
* subjectAltName: host "www.fastly.com" matched cert's "www.fastly.com"
* issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fe1f980aa00)
> GET / HTTP/2
> Host: www.fastly.com
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200
< alt-svc: h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
< etag: "5c770df920f8c90e4c4532c32aea6ec3"
< content-type: text/html
< accept-ranges: bytes
< date: Mon, 09 Aug 2021 15:38:35 GMT
< x-served-by: cache-pwk4963-PWK
< x-cache: HIT
< x-cache-hits: 2
< x-timer: S1628523515.208976,VS0,VE0
< vary: Accept-Encoding
< x-xss-protection: 1; mode=block
< x-frame-options: DENY
< x-content-type-options: nosniff
< cache-control: max-age=0, private, must-revalidate
< server: Artisanal bits
< strict-transport-security: max-age=31536000
< content-length: 777219
<
{ [1113 bytes data]
* Connection #0 to host www.fastly.com left intact
* Closing connection 0Wie cURL die URL und den SSL-Namen verwendet
Das obige Szenario zeigt eine Situation, in der der SSL-Zertifikatname, der Host Header und der DNS-Name alle den Wert www.fastly.com haben. Manchmal braucht es eben nicht mehr! Ab hier wollen wir diese Elemente allerdings getrennt betrachten, um verschiedene Aspekte für unterschiedliche Fehlersuchziele untersuchen zu können.
So, wie wir https://www.fastly.com/ aktuell nutzen, wird die angefragte URL angezeigt. Der in der URL verwendete Hostname (z. B. www.fastly.com) wird von curl als Wert genutzt, um den Namen des SSL-Zertifikats anzufragen und zu verifizieren. Dies ist wichtig, um zu überprüfen, ob Ihr TLS wie gewünscht funktioniert und ob Ihre Website mit dem von Ihnen erwarteten Zertifikat sicher ist. Hier ein Beispiel:
$ curl -svo /dev/null https://www.fastly.com/
* Trying 199.232.77.57...
* TCP_NODELAY set
* Connected to www.fastly.com (199.232.77.57) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [228 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [102 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2828 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [300 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Fastly, Inc.; CN=www.fastly.com
* start date: Mar 3 21:56:03 2021 GMT
* expire date: Apr 4 21:56:03 2022 GMT
* subjectAltName: host "www.fastly.com" matched cert's "www.fastly.com"
* issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
* SSL certificate verify ok.
--->{Truncated for readability}<---
So geben Sie einen Pfad in cURL an
Die beiden anderen Dinge, die bei der Original-URL verbleiben, sind das Schema (z. B. HTTP oder HTTPS) und der Pfad zu der angefragten Ressource. Ich betrachte die URL als das Ziel, und alles andere ist nur die Art und Weise, wie oder wo wir sie anfragen.
Die URL definiert außerdem das Schema (z. B. HTTP gegenüber HTTPS) und den Pfad zu der angefragten Ressource.
Um einen Pfad in curl anzugeben, fügen Sie ihn direkt in die URL ein: curl https://www.fastly.com/blog/
Damit wird die Ressource `/blog/` angefordert, während derselbe Host, dieselbe Zertifikatsvalidierung und dasselbe Routing-Verhalten beibehalten werden.
So legen Sie cURL-Host-Header fest
HTTP-Header ermöglichen Clients, zusätzliche Informationen mit einer Anfrage zu senden. In curl können Header mithilfe des Flags `-H` oder `--header` hinzugefügt werden. Einer der nützlichsten Header für die Fehlerbehebung ist der Host-Header, der einem Webserver mitteilt, welchen Hostnamen Sie anfordern. Ein typischer Webserver kann mehrere Websites mit unterschiedlichen Domainnamen wie blog.example.com oder docs.example.com hosten. Auch wenn sich diese Websites auf demselben System befinden, können der Quellcode bzw. der URL-Pfad unterschiedlich sein.
Wenn wir den Host-Header ändern wollen, können wir diese Änderung in curl durch die ausdrückliche Definition des Headers übergeben. Header können entweder mit --header oder mit den kürzeren -H-Flags gekennzeichnet sein. Der Wert steht dabei zwischen Anführungszeichen und der Name des Headers wird definiert. Der curl Befehl sieht folgendermaßen aus:
$ curl -svo /dev/null https://www.fastly.com/ -H “host: blog.fastly.com”Mit diesem Request können wir den Host von blog.fastly.com abfragen, indem wir das Zertifikat und die Location von www.fastly.com verwenden. Dies ist besonders dann nützlich, wenn wir die Unterschiede in der Apex zweier Domains überprüfen möchten, z. B. fastly.com gegen www.fastly.com. Im Folgenden können wir sehen, dass ein korrekter 301-Redirect zu www stattfindet.
$ curl -svo /dev/null https://www.fastly.com/ -H "host: fastly.com"
* Trying 199.232.77.57...
* TCP_NODELAY set
* Connected to www.fastly.com (199.232.77.57) port 443 (#0)
--->{Truncated for readability}<---
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fa15480aa00)
> GET / HTTP/2
> Host: fastly.com
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 301
< retry-after: 0
< accept-ranges: bytes
< date: Mon, 09 Aug 2021 16:26:07 GMT
< x-served-by: cache-pwk4938-PWK
< x-cache: HIT
< x-cache-hits: 0
< cache-control: max-age=0, private, must-revalidate
< server: Artisanal bits
< strict-transport-security: max-age=31536000
< location: https://www.fastly.com/
< content-length: 0
<
{ [0 bytes data]
* Connection #0 to host www.fastly.com left intact
* Closing connection 0
So verwenden Sie cURL --resolve zum Überbrücken von DNS
Von allen Flags in curl ist --resolve wahrscheinlich das am meisten unterschätzte. Diese Technik ist besonders nützlich für die Fehlerbehebung beim Request Routing. Durch das Überschreiben der DNS-Auflösung können Sie testen, wie ein bestimmter Origin reagiert, bevor Sie den öffentlichen DNS aktualisieren, ein neues Deployment überprüfen oder Probleme innerhalb einer Kette von Proxys und Loadbalancern isolieren. Beachten Sie, dass Sie ganz am Anfang jeder oben gezeigten curl Trying X.X.X.X als IP-Adresse sehen, die den Domainnamen aus dem DNS auflöst. Manchmal ist der DNS-Name aber nicht das eigentliche Ziel, das Sie ansteuern möchten. Möglicherweise handelt es sich dabei um ein anfängliches Deployment, und wir testen, ob der Service korrekt aufgelöst wird, bevor wir den DNS ändern, um diese Änderung zu veröffentlichen. Vielleicht gibt es aber auch eine Kette von Reverse-Proxys, bei der der öffentliche DNS nur den Anfang der Kette auflöst, wir aber wissen wollen, wie der Origin-Server selbst reagiert.
Um diese Probleme zu umgehen, können wir den Domainnamen für curl selbst auflösen und jede beliebige IP-Adresse angeben. Hierfür sind folgende beiden Schritte notwendig:
1. Sofern Sie die IP-Adresse nicht bereits kennen, müssen Sie möglicherweise eine DNS-Auflösung des Hosts durchführen, um diese zu erhalten. Ich verwende am liebsten Dig, ein weiteres Standardprogramm, das diese DNS-Abfrage über die Kommandozeile durchführt.
$ dig www.fastly.com +short
prod.www-fastly-com.map.fastly.net.
151.101.185.572. Als Nächstes können wir die IP-Adresse zuweisen, die von curl beim HTTP Request verwendet werden soll, indem wir die Option --resolve zusammen mit dem zu ersetzenden Domainnamen, dem Port und der zu verwendenden IP einsetzen. Das Ganze sieht dann wie folgt aus:
$ curl -svo /dev/null https://www.fastly.com/ -H "host: fastly.com" --resolve www.fastly.com:443:151.101.185.57
* Added www.fastly.com:443:151.101.185.57 to DNS cache
* Hostname www.fastly.com was found in DNS cache
* Trying 151.101.185.57...
* TCP_NODELAY set
* Connected to www.fastly.com (151.101.185.57) port 443 (#0)
--->{Truncated for readability}<---
Connect-to-Alternative
Als Alternative zur obigen Funktion „Resolve“ können wir auch --connect-to verwenden und entweder eine IP-Adresse oder einen Host übermitteln, mit denen eine Verbindung hergestellt werden soll. Dies ist zwar einfacher, aber bei der Verwendung eines Hosts ist die Genauigkeit nicht ganz so hoch. „Connect-to“ führt eine DNS-Auflösung für Sie durch. Sie müssen sich dann allerdings darauf verlassen, dass die DNS-Auflösung die richtige IP-Adresse nutzt. Dies ist kein Problem, wenn Sie definitiv wissen, dass es eine 1:1-Zuordnung von Host zu IP gibt. Manchmal haben Sie aber mehrere A-Einträge und möchten alle IP-Adressen ausprobieren, oder der Host verfügt über ein DNS-basiertes Loadbalancing, sodass verschiedene Locations oder Versuche zu unterschiedlichen Ergebnissen führen können. Indem Sie die Funktion --resolve oder --connect-to mit einer IP-Adresse nutzen, können Sie explizit sein. Wenn Sie diese curl also zum Beispiel mit Ihren Kollegen teilen, sind Ihre jeweiligen Ergebnisse mit höherer Wahrscheinlichkeit vergleichbar.
Ein weiterer Vorteil der Verwendung von „connect-to“ ist, dass Sie die explizite Angabe des Domainnamens, für den Sie einen DNS wie bei „resolve“ definieren möchten, sowie des Ports überspringen können. Sie sehen also zum Beispiel ::151.101.185.57 oder Sie könnten ::target.host.fastly.com verwenden.
$ curl -svo /dev/null https://www.fastly.com/ -H "host: fastly.com" --connect-to ::151.101.185.57
* Connecting to hostname: 151.101.185.57
* Trying 151.101.185.57...
* TCP_NODELAY set
* Connected to 151.101.185.57 (151.101.185.57) port 443 (#0)
--->{Truncated for readability}<---cURL-Flags, Header und Routing im Zusammenspiel
Es ist erwähnenswert, dass es viele Techniken zur Durchführung von HTTP-Requests gibt. Curl bietet verschiedene Methoden, die alle ihre Vor- und Nachteile haben, und jeder Entwickler hat scheinbar seinen eigenen Favoriten. Meiner ist der, den ich Ihnen soeben gezeigt habe.
Zusammenfassend lässt sich sagen, dass curl zum Senden von HTTP-GET-Anfragen, zum Prüfen von Anfrage- und Antwort-Headern, zum Manipulieren von Host-Headern und zum Überbrücken der DNS-Auflösung verwendet werden kann. Durch die Kombination von Flags wie `-s`, `-v`, `-H`, `--resolve` und `--connect-to` können Sie genau bestimmen, wohin eine Anfrage gesendet wird, wie sie geroutet wird, welches TLS-Zertifikat präsentiert wird und wie ein Server antwortet. Dies erleichtert die Fehlersuche und erspart Ihnen hoffentlich unzählige Stunden Frust. Probieren Sie es doch einfach mal selbst!
Das folgende Snippet zeigt den vollständigen Code, der zur leichteren Orientierung farbig markiert ist:


