Help us understand the problem. What is going on with this article?

MacにTLS1.3とHTTP/2で通信可能なcurlをインストールした手順

More than 1 year has passed since last update.

Mac標準のcurlはLibreSSLとリンクしているが、現在手元にインストールされているバージョンだとTLS1.3を指定して通信することはできない。

$ /usr/bin/curl --version
curl 7.54.0 (x86_64-apple-darwin18.0) libcurl/7.54.0 LibreSSL/2.6.5 zlib/1.2.11 nghttp2/1.24.1
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets HTTPS-proxy

$ /usr/bin/curl https://www.instart.com --tlsv1.3 --http2
curl: (4) LibreSSL was built without TLS 1.3 support

TLS1.3に対応しているOpenSSL1.1を使用したcurlをインストールすることで、TLS1.3通信が可能になるのだけど、インストールに苦戦したのでメモしておく。

Macの場合、curlはbrew install curlまたはbrew install curl-opensslでインストールできるが、これでインストールしたcurlはTLS1.3に未対応のOpenSSL1.0系にリンクしてしまう。この時--tlsv1.3オプションを指定してもエラーにならないが無視されてしまい、TLS1.2などで接続されてしまう。

OpenSSL 1.1はbrew install opensslではなくbrew install openssl@1.1でインストールできるが、/usr/local/opt/openssl@1.1という別ディレクトリーにインストールされることもあり、この後curlをインストールしても1.0の方が使用されてしまう。また、他のbrewでインストールしたライブラリーが1.0系を参照していることもあり、1.0をアンインストールしてもうまくいかなかった。openssl@1.11.0と同一ディレクトリーに上書きできるなら解決しそうな気もするのだけど、できるのだろうか?

仕方ないのでcurlのソースをダウンロードしてビルドするが、下記のように、1.1側を参照させるような環境変数設定をがんばって行っても、なぜか1.0とリンクしてしまう。

$ export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
$ export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
$ export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
$ ./configure --with-nghttp2=/usr/local/opt/nghttp2 --with-brotli --without-darwinssl --with-ssl="/usr/local/opt/openssl@1.1" CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" CFLAGS="-I/usr/local/opt/openssl@1.1/include"

config.logを見ると、checking for OpenSSL headers versionの結果が1.0.2になってしまうことがわかった。バージョン確認がどのように行われているかを調べたところ、#include <openssl/crypto.h>して定数OPENSSL_VERSION_NUMBERの値をチェックしている。

ここで、なぜかCPPFLAGSで指定したディレクトリーではなく、-I/opt/local/includeが追加されており、-isystemより-Iが優先されるため、1.0系が入っている/opt/local/include/openssl/cypto.hの方が優先で参照されてしまっていた。

gcc -E -isystem /usr/local/opt/openssl@1.1/include -I /opt/local/include  -I/usr/local/Cellar/openssl@1.1/1.1.1c/include    conftest.c

configureの20703行目あたりでzlibライブラリーの場所を確認するために実行したpkg-configコマンドの戻り値が-Iを使っていることが判明したため、-isystemに置き換えたところ、無事1.1.1cとリンクしてTLS1.3通信が可能になった。

#      CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags-only-I zlib`"
      CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" 
$ /usr/local/bin/curl --version
curl 7.65.3 (x86_64-apple-darwin18.7.0) libcurl/7.65.3 OpenSSL/1.1.1c zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 nghttp2/1.39.1 librtmp/2.3
Release-Date: 2019-07-19
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS brotli HTTP2 HTTPS-proxy IDN IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets

$ /usr/local/bin/curl -v https://www.instart.com -o/dev/null --tlsv1.3 --http2
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 159.180.93.29:443...
* TCP_NODELAY set
* Connected to www.instart.com (159.180.93.29) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2820 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [264 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=Palo Alto; O=Instart Logic, Inc.; OU=IT Department; CN=*.instart.com
*  start date: Jan 21 00:00:00 2019 GMT
*  expire date: Jan 29 12:00:00 2020 GMT
*  subjectAltName: host "www.instart.com" matched cert's "*.instart.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
*  SSL certificate verify ok.
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* 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
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x7fea5500b600)
} [5 bytes data]
> GET / HTTP/2
> Host: www.instart.com
> User-Agent: curl/7.65.3
> Accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [289 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [273 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
} [5 bytes data]
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0< HTTP/2 200
< content-type: text/html; charset=UTF-8
< content-length: 77762
< x-type: default
< accept-ranges: bytes
< x-pingback: https://instart.wpengine.com/xmlrpc.php
< cache-control: max-age=600, must-revalidate
< x-pass-why:
< vary: Accept-Encoding
< vary: Accept-Encoding
< vary: Accept-Encoding,Cookie
< x-cacheable: SHORT
< x-cache-group: normal
< link: <https://instart.wpengine.com/wp-json/>; rel="https://api.w.org/"
< server: nginx
< wpe-backend: apache
< date: Wed, 24 Jul 2019 01:30:21 GMT
< x-cache: HIT: 26
< x-instart-request-id: 5606122923514061747:UXT01-CPVNPPRY16:1563931821:0
<
{ [15820 bytes data]
100 77762  100 77762    0     0  36714      0  0:00:02  0:00:02 --:--:-- 36714
* Connection #0 to host www.instart.com left intact

疲れすぎたのでissueを書こうとしたけどKNOWN BUSに似たようなのがあった。
https://curl.haxx.se/docs/knownbugs.html#configure_finding_libs_in_wrong

twk
Auth0社でSolutions Engineerをしています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away