curl をresolveオプションで名前解決して疎通する

12月 9, 2023AmazonLinux_CentOS,AWS,ELB,Network

概要

  • インフラ構築時や一時的なテスト環境に対し、DNSにレコードが未だ登録されていない状況下で、curl コマンドで疎通確認を行いたい場合があります。その様なケースでは、クライアントの /etc/hosts を編集する方法もありますが、私はcurl コマンドに resolveオプションで付けて確認を行っています。本日は、curl をresolveオプションで名前解決して疎通する方法の紹介となります。
  • このシチュエーションを詳しく説明すると、テスト環境に対し本番環境と同じリクエストを投げたい場合や、通信経路にリバースプロキシやCDN がある構成で直接疎通確認を行う場合、SNI (Server Name Indication)を使用して複数の証明書が登録されている環境で証明書のテストをする場合などが考えられます。
  • 今回の記事では、ALB のHTTPS リスナーにACM で発行された証明書を追加し、DNSにはレコード登録せず、curl コマンドの resolveオプションを使用して動作確認を行います。

 

準備

  • テスト用の ALB (Application Load Balancer) を準備し、HTTPS のリスナーを作成します。ACMで発行された証明書 (仮にexample-a.sub1.examplename.com とします) を割り当てます。
  • ALB には、固定レスポンス 200 を返すアクションを設定しま
  • Route 53 に、DNSレコード (example-a.sub1.examplename.com) を設定し、ALB のDNS名を登録します。

 

  • 次に、SNIを利用して、HTTPS のリスナーに、ACMで発行された2枚目の証明書 (仮にexample-b.sub1.examplename.com とします) を割り当てます。
  • こちらは、DNSレコードの設定を行いません。

 


普通に curl を打ってみる

  • ALBにACMの証明書を割り当て、かつDNSレコードを登録したアドレス (example-a.sub1.examplename.com) に対して、curl コマンドを打ちます。コマンドは以下となります。
curl -v https://example-a.sub1.examplename.com
  • 名前解決は成功しています。TLSハンドシェイクが行われ、サーバー証明書の SAN(subjectAltName)のチェックを行った結果、ホスト名とコモンネームが一致するメッセージが表示されています。
    • subjectAltName: host “example-a.sub1.examplename.com" matched cert’s “example-a.sub1.examplename.com
niikawa@niikawa1:~$ curl -vv https://example-a.sub1.examplename.com/
* Trying 52.69.143.53...
* TCP_NODELAY set
* Connected to example-a.sub1.examplename.com (52.69.143.53) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
* TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=example-a.sub1.examplename.com
* start date: Jan 16 00:00:00 2024 GMT
* expire date: Feb 13 23:59:59 2025 GMT
* subjectAltName: host "example-a.sub1.examplename.com" matched cert's "example-a.sub1.examplename.com"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M03
* 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
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* Using Stream ID: 1 (easy handle 0x562699e57620)
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
> GET / HTTP/2
> Host: example-a.sub1.examplename.com
> User-Agent: curl/7.58.0
> Accept: */*
>
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
< HTTP/2 200
< server: awselb/2.0
< date: Tue, 23 Jan 2024 13:09:28 GMT
< content-type: text/plain; charset=utf-8
< content-length: 0
<
* Connection #0 to host example-a.sub1.examplename.com left intact

 

curl をresolveオプションで打ってみる

  • ALBにACMの証明書を割り当てたが、DNSレコードを登録していないアドレス (example-b.sub1.examplename.com) に対し、curl コマンドを打ちます。準備として、digコマンドでALB のIPアドレスを確認します。
niikawa@niikawa1:~$ dig niikawa-alb1-1234567890.ap-northeast-1.elb.amazonaws.com +short
52.69.143.53
52.69.143.54
  • 次に、resolveオプションを指定してcurl コマンドを打ちます。resolveオプションは、「ホスト名:ポート番号:IPアドレス」の様に指定します。コマンドは、以下となります。
curl -vv --header 'Host:example-b.sub1.examplename.com' --resolve example-b.sub1.examplename.com:443:52.69.143.53 https://example-b.sub1.examplename.com/
  • 名前解決は成功しています。TLSハンドシェイクが行われ、サーバー証明書の SAN(subjectAltName)のチェックを行った結果、ホスト名とコモンネームが一致するメッセージが表示されています。
    • subjectAltName: host “example-b.sub1.examplename.com" matched cert’s “example-b.sub1.examplename.com
niikawa@niikawa1:~$ curl -vv --header 'Host:example-b.sub1.examplename.com' --resolve example-b.sub1.examplename.com:443:52.69.143.53 https://example-b.sub1.examplename.com/
* Added example-b.sub1.examplename.com:443:52.69.143.53 to DNS cache
* Hostname example-b.sub1.examplename.com was found in DNS cache
* Trying 52.69.143.53...
* TCP_NODELAY set
* Connected to example-b.sub1.examplename.com (52.69.143.53) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
* TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=example-b.sub1.examplename.com
* start date: Jan 16 00:00:00 2024 GMT
* expire date: Feb 13 23:59:59 2025 GMT
* subjectAltName: host "example-b.sub1.examplename.com" matched cert's "example-b.sub1.examplename.com"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M03
* 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
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* Using Stream ID: 1 (easy handle 0x55de1b557620)
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
> GET / HTTP/2
> Host:example-b.sub1.examplename.com
> User-Agent: curl/7.58.0
> Accept: */*
>
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
< HTTP/2 200
< server: awselb/2.0
< date: Tue, 23 Jan 2024 13:03:35 GMT
< content-type: text/plain; charset=utf-8
< content-length: 0
<
* Connection #0 to host example-b.sub1.examplename.com left intact
niikawa@niikawa1:~$

 

補足

  • curl に kオプションを指定すると、SAN(subjectAltName)のチェックは行われず、ホスト名とコモンネームの一致は確認しません。