TLSv 1.3 に対応している curl を Mac にササッとインストールしてみた

--tlsv1.3 を使いたいあなたに。

コンバンハ、千葉(幸)です。

Mac プリインストールの curl で--tlsv1.3オプションを使おうとしたところ、以下のメッセージが表示されました。

かなしいメッセージ

curl https://cafe.classmethod.jp/ --tlsv1.3
curl: (4) LibreSSL was built without TLS 1.3 support

curl: (4) LibreSSL was built without TLS 1.3 support

TLS 1.3 で確認を取りたい用途があったため、新たに curl をインストールして対応しました。

対応自体はすんなり終わったのですが、せっかくなのでメモを残しておきます。

先にまとめ

ひと昔は大変そうだったが、今だったらbrew install curlを実行するだけでOK。

インストール前の状態

Mac の情報はこちら。

% sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H114

zsh を使用しています。

% echo $SHELL
/bin/zsh

もともとインストールされていた curl はこちら。

% curl --version
curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2
Release-Date: 2019-03-27
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets

パスは以下です。

% which curl
/usr/bin/curl

curl の実行

--tlsv1.3を指定しても正常に実行されないのは先述の通りです。

curl https://cafe.classmethod.jp/ --tlsv1.3
curl: (4) LibreSSL was built without TLS 1.3 support

以下エントリと同じように、 TLSv 1.3 に対応した 弊社カフェサイト に接続を試みると、 TLSv 1.2 でコネクションしています。

% curl -s -v https://cafe.classmethod.jp > /dev/null
*   Trying 99.84.55.24...
* TCP_NODELAY set
* Connected to cafe.classmethod.jp (99.84.55.24) 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):
} [233 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [91 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [4844 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-AES128-GCM-SHA256
---以下略---

せっかくなので TLSv 1.3 で接続して欲しいところです。新しい curl をインストールします。

Homebrew による curl のインストール

以下のサイトを参考にしました。2019年当時はいろいろと試行錯誤が必要だったようですが、2021年現在はお手軽に実現できました。

Homebrew のインストール

Homebrew のインストールがまだの場合は、以下から実施してください。

brew install curl-openssl

上記のサイトを参考に、brew install curl-openssl を行いました。

後から気付いたのですが、(少なくとも現在では)curlcurl-opensslも同じ formulae として扱われるようです。brew install curlでも問題ありません。

Homebrew_Formulae Formerly known as: curl-openssl

今回やりたいこととは直接関係ないログも含まれていますが、実行ログの全量を載せておきます。

折り畳み
% brew install curl-openssl
Updating Homebrew...
==> Downloading https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.6.3_2.yosemite.bottle.tar.gz
########################################################################################################################################### 100.0%
==> Pouring portable-ruby-2.6.3_2.yosemite.bottle.tar.gz
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
acl2                    dnsprobe                heppdt2                 libxau                  node@14                 t-rec
act                     dnsx                    hexo                    libxaw                  notmuch-mutt            taskwarrior-tui
aerc                    docui                   httpx                   libxaw3d                numcpp                  tctl
aida-header             dog                     hy                      libxcb                  oakc                    tendermint
alsa-lib                dotenv-linter           indicators              libxcomposite           ocaml-zarith            terracognita
apidoc                  dotnet                  infracost               libxcursor              oci-cli                 terraform@0.12
arb                     dprint                  inframap                libxdamage              openalpr                terraform@0.13
argo                    driftctl                inja                    libxdmcp                openfst                 terrascan
argocd                  dstask                  ioctl                   libxext                 openjdk@8               tfsec
arrayfire               duckscript              isl@0.18                libxfixes               or-tools                tgenv
arturo                  duf                     isort                   libxfont                ormolu                  thanos
asroute                 easy-rsa                jimtcl                  libxft                  osi                     thrax
athenacli               efm-langserver          jinx                    libxi                   osm                     tm
atkmm@2.28              eksctl                  jpeg-xl                 libxinerama             overdrive               torchvision
attr                    eleventy                jql                     libxkbfile              ox                      trec_eval
aws-console             empty                   json5                   libxml++@4              pandocomatic            tree-sitter
aws-rotate-key          envoy                   jsonnet-bundler         libxml++@5              pangomm@2.42            trunk
bandit                  evernote2md             k3sup                   libxmu                  parallel-hashmap        ugrep
bit-git                 f3d                     kcgi                    libxp                   pdftilecut              usb.ids
blaze                   fennel                  keptn                   libxpm                  pdm                     utf8cpp
bond                    fetch                   khiva                   libxrandr               periscope               util-macros
borgbackup              fizz                    ko                      libxrender              phive                   v2ray
box2d                   fleet-cli               kona                    libxres                 php@7.4                 vc
bpython                 flit                    kondo                   libxscrnsaver           pickle                  vint
bpytop                  flow-cli                ksync                   libxshmfence            pipgrip                 vivid
c7n                     flux                    kube-linter             libxt                   pkger                   volk
cadence                 fnm                     kubecm                  libxtst                 podman                  vsh
cairomm@1.14            folderify               kubevela                libxv                   postgresql@12           vtk@8.2
cargo-audit             font-util               kubie                   libxvmc                 prometheus-cpp          vulture
cargo-edit              foreman                 lab                     libxxf86dga             promtail                wangle
cargo-watch             forge                   ladspa-sdk              libxxf86vm              protoc-gen-go-grpc      wayland
castget                 fpart                   ldpl                    linux-headers           protoc-gen-gogo         wayland-protocols
cbc                     functionalplus          leaf                    localstack              protoc-gen-gogofaster   webify
cdktf                   gallery-dl              libaio                  logcli                  ptpython                wgcf
cfn-flip                gateway-go              libbsd                  logswan                 python@3.9              wownero
cfn-format              gcalcli                 libcap                  loki                    rain                    x86_64-elf-gdb
cgl                     gdu                     libcap-ng               lp_solve                reg                     xbitmaps
chalk-cli               git-hooks-go            libdmx                  lua@5.3                 regipy                  xcb-proto
charge                  git-hound               libdrm                  luajit-openresty        richmd                  xcb-util
chars                   gitlint                 libfontenc              lunchy                  rm-improved             xcb-util-cursor
chart-testing           gitql                   libfs                   lunchy-go               rttr                    xcb-util-image
checkov                 giza                    libfuse                 luv                     ruby@2.7                xcb-util-keysyms
clair                   glab                    libgccjit               magic_enum              rustscan                xcb-util-renderutil
clang-format@8          glibmm@2.64             libhandy                mariadb@10.4            sdns                    xcb-util-wm
clash                   go@1.14                 libice                  markdownlint-cli        server-go               xcbeautify
cli11                   gofumpt                 libirecovery            marked                  shallow-backup          xcinfo
cloudformation-guard    gojq                    libmnl                  massdns                 sheldon                 xdpyinfo
commitizen              golangci-lint           libnetfilter-queue      matplotplusplus         showkey                 xinput
condure                 googletest              libnfnetlink            md4c                    shtools                 xkeyboardconfig
copilot                 gopls                   libnsl                  mermaid-cli             silicon                 xorgproto
cortex                  goredo                  libpciaccess            mesa-glu                simdjson                xorgrgb
counterfeiter           gosec                   libpinyin               mhonarc                 sleef                   xterm
crane                   gost                    libpthread-stubs        microplane              snap                    xtrans
crcany                  gostatic                librttopo               mockery                 solidity                yh
croaring                gping                   libseccomp              muffet                  spack                   yj
croc                    gradle-profiler         libslirp                naabu                   sponge                  ykdl
cubejs-cli              grokj2k                 libsm                   nanorc                  sqlc                    youtube-dlc
cvs-fast-export         gtkmm4                  libtirpc                ncspot                  sqlite-utils            youtubedr
datasette               gulp-cli                libva                   never                   staticcheck             yq@3
dbdeployer              h2spec                  libvdpau                nfpm                    strace                  z.lua
device-mapper           halide                  libvnc                  ngs                     structurizr-cli         zsh-async
diskonaut               hblock                  libx11                  nicotine-plus           subfinder               zsh-you-should-use
==> Updated Formulae
Updated 4902 formulae.
==> Renamed Formulae
elasticsearch@6.8 -> elasticsearch@6             gtk+4 -> gtk4                                    now-cli -> vercel-cli
gst-validate -> gst-devtools                     kibana@6.8 -> kibana@6                           prest -> prestd
==> Deleted Formulae
boost@1.55                   elasticsearch@2.4            kibana@5.6                   rmtrash                      woboq_codebrowser
boost@1.59                   elasticsearch@5.6            llvm@6                       sflowtool                    wpscan
confluent-platform           fmsx                         meson-internal               stlviewer                    xspin
cryptopp                     gobby                        mysql-connector-c++@1.1      tomee-jax-rs                 xu4
curl-openssl                 godep                        ori                          unp64
dtrx                         i386-elf-grub                pgplot                       unrar

==> Downloading https://homebrew.bintray.com/bottles/brotli-1.0.9.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/a382d95787cc2a5742a1d713f939bbc91ca6e097aee7f49f95cc111dca9fa9d7?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/gettext-0.21.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/cdea54f52b7c36ebcb5fe26a1cf736d7cd6fd5f2fd016dd8357a8624ffd6b5f8?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/libunistring-0.9.10.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/ce746662b98d93511b86920011b5cafcd2eecbce4c9c40d8c52a143cdf708456?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/libidn2-2.3.0.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/0908585cca518a83f101b2edc0417a26a4b4fc8b76e393c6f6672de6e595c914?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/libmetalink-0.1.3.catalina.bottle.tar.gz
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/openssl%401.1-1.1.1i.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/066b9f114617872e77fa3d4afee2337daabc2c181d7564fe60a5b26d89d69742?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/libssh2-1.9.0_1.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/2c4dcf8149663f9a133deac5bc42ce308d1ced90227cac391ca30b0ab2d381f9?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/c-ares-1.17.1.catalina.bottle.tar.gz
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/jemalloc-5.2.1_1.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/b1b211e5bead798c236d478dd74310a97a7b59470f607b608c07222648b08bf5?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/libev-4.33.catalina.bottle.tar.gz
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/nghttp2-1.42.0_1.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/ddc63177feae52a5d07ec0f5793a8dcb5a344f0bdd4f4ba0633dacfd8249b0be?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/openldap-2.4.57.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/1fcdd72cf7619ea2c79055357f8e1a600e4758d04f2233160381316bf64b0659?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/rtmpdump-2.4%2B20151223_1.catalina.bottle.tar.gz
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/zstd-1.4.8.catalina.bottle.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/ad897f36994db64c4ec410c1e9324b66dcf4f2175cf7d24c62ec647921b5dc7d?response-content-dispo
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/curl-7.74.0.catalina.bottle.2.tar.gz
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/18e818ff24895ffd9355c34f79dd92aaf220e16d71ffdef6e2a07c0a6ddb4637?response-content-dispo
######################################################################## 100.0%
==> Installing dependencies for curl: brotli, gettext, libunistring, libidn2, libmetalink, openssl@1.1, libssh2, c-ares, jemalloc, libev, nghttp2, openldap, rtmpdump and zstd
==> Installing curl dependency: brotli
==> Pouring brotli-1.0.9.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/brotli/1.0.9: 25 files, 2.3MB
==> Installing curl dependency: gettext
==> Pouring gettext-0.21.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/gettext/0.21: 1,953 files, 19.0MB
==> Installing curl dependency: libunistring
==> Pouring libunistring-0.9.10.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/libunistring/0.9.10: 54 files, 4.4MB
==> Installing curl dependency: libidn2
==> Pouring libidn2-2.3.0.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/libidn2/2.3.0: 70 files, 727.8KB
==> Installing curl dependency: libmetalink
==> Pouring libmetalink-0.1.3.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/libmetalink/0.1.3: 31 files, 182.9KB
==> Installing curl dependency: openssl@1.1
==> Pouring openssl@1.1-1.1.1i.catalina.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

and run
  /usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

==> Summary
🍺  /usr/local/Cellar/openssl@1.1/1.1.1i: 8,067 files, 18.5MB
==> Installing curl dependency: libssh2
==> Pouring libssh2-1.9.0_1.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/libssh2/1.9.0_1: 184 files, 941KB
==> Installing curl dependency: c-ares
==> Pouring c-ares-1.17.1.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/c-ares/1.17.1: 85 files, 672.3KB
==> Installing curl dependency: jemalloc
==> Pouring jemalloc-5.2.1_1.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/jemalloc/5.2.1_1: 16 files, 2MB
==> Installing curl dependency: libev
==> Pouring libev-4.33.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/libev/4.33: 12 files, 454.7KB
==> Installing curl dependency: nghttp2
==> Pouring nghttp2-1.42.0_1.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/nghttp2/1.42.0_1: 24 files, 2.8MB
==> Installing curl dependency: openldap
==> Pouring openldap-2.4.57.catalina.bottle.tar.gz
==> Caveats
openldap is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have openldap first in your PATH run:
  echo 'export PATH="/usr/local/opt/openldap/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/openldap/sbin:$PATH"' >> ~/.zshrc

For compilers to find openldap you may need to set:
  export LDFLAGS="-L/usr/local/opt/openldap/lib"
  export CPPFLAGS="-I/usr/local/opt/openldap/include"

==> Summary
🍺  /usr/local/Cellar/openldap/2.4.57: 329 files, 7.1MB
==> Installing curl dependency: rtmpdump
==> Pouring rtmpdump-2.4+20151223_1.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/rtmpdump/2.4+20151223_1: 20 files, 443.4KB
==> Installing curl dependency: zstd
==> Pouring zstd-1.4.8.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/zstd/1.4.8: 26 files, 3.4MB
==> Installing curl
==> Pouring curl-7.74.0.catalina.bottle.2.tar.gz
==> Caveats
curl is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have curl first in your PATH run:
  echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.zshrc

For compilers to find curl you may need to set:
  export LDFLAGS="-L/usr/local/opt/curl/lib"
  export CPPFLAGS="-I/usr/local/opt/curl/include"


zsh completions have been installed to:
  /usr/local/opt/curl/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/curl/7.74.0: 479 files, 3.7MB
==> `brew cleanup` has not been run in 30 days, running now...
Removing: /Users/username/Library/Caches/Homebrew/jq--1.6.catalina.bottle.1.tar.gz... (420.8KB)
Removing: /Users/username/Library/Caches/Homebrew/oniguruma--6.9.5-rev1.catalina.bottle.tar.gz... (436.8KB)
Removing: /Users/username/Library/Caches/Homebrew/tree--1.8.0.catalina.bottle.tar.gz... (49.5KB)
Removing: /Users/username/Library/Logs/Homebrew/tree... (64B)
Removing: /Users/username/Library/Logs/Homebrew/oniguruma... (64B)
Removing: /Users/username/Library/Logs/Homebrew/jq... (64B)
Pruned 3 symbolic links and 2 directories from /usr/local
==> Caveats
==> openssl@1.1
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

and run
  /usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

==> openldap
openldap is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have openldap first in your PATH run:
  echo 'export PATH="/usr/local/opt/openldap/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/openldap/sbin:$PATH"' >> ~/.zshrc

For compilers to find openldap you may need to set:
  export LDFLAGS="-L/usr/local/opt/openldap/lib"
  export CPPFLAGS="-I/usr/local/opt/openldap/include"

==> curl
curl is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have curl first in your PATH run:
  echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.zshrc

For compilers to find curl you may need to set:
  export LDFLAGS="-L/usr/local/opt/curl/lib"
  export CPPFLAGS="-I/usr/local/opt/curl/include"


zsh completions have been installed to:
  /usr/local/opt/curl/share/zsh/site-functions

実行結果のうち curl に関する部分のみ抽出したものが以下です。

==> curl
curl is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have curl first in your PATH run:
  echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.zshrc

For compilers to find curl you may need to set:
  export LDFLAGS="-L/usr/local/opt/curl/lib"
  export CPPFLAGS="-I/usr/local/opt/curl/include"

ここで確認できるフルパスを指定してバージョンを確認すると以下となっていました。

% /usr/local/opt/curl/bin/curl --version
curl 7.74.0 (x86_64-apple-darwin19.6.0) libcurl/7.74.0 (SecureTransport) OpenSSL/1.1.1i zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.0 libssh2/1.9.0 nghttp2/1.42.0 librtmp/2.3
Release-Date: 2020-12-09
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz Metalink MultiSSL NTLM NTLM_WB SPNEGO SSL TLS-SRP UnixSockets zstd

パスを通す

上記の作業が完了した時点では、 curl は引き続きデフォルトのパスを向いています。

% which curl
/usr/bin/curl

プロファイルに、新規にインストールした curl のパスを通す処理を追加します。

% echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.zshrc

プロファイルに以下が追加されたため、ログインする度にパスの先頭に/usr/local/opt/curl/binが追加されます。

% cat ~/.zshrc | grep PATH
export PATH="/usr/local/opt/curl/bin:$PATH"

ターミナルを開き直すなどしてプロファイルを読みこめば、新しく追加された curl のパスを向いていることが確認できます。

% which curl
/usr/local/opt/curl/bin/curl

念のためバージョン確認をすると、インストール後にフルパスで確認したものと同じであることが分かります。

% curl --version
curl 7.74.0 (x86_64-apple-darwin19.6.0) libcurl/7.74.0 (SecureTransport) OpenSSL/1.1.1i zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.0 libssh2/1.9.0 nghttp2/1.42.0 librtmp/2.3
Release-Date: 2020-12-09
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz Metalink MultiSSL NTLM NTLM_WB SPNEGO SSL TLS-SRP UnixSockets zstd

余談:curl と curl-openssl

従来は別物であったかも知れませんが、現時点では特に違いを考慮する必要はなさそうです。

curlで search しても curl-openssl はヒットせず。

% brew search curl
==> Formulae
awscurl      curl ✔       curlftpfs    curlpp       flickcurl    grpcurl

もちろんcurl-opensslで search しても見つかりません。

% brew search curl-openssl
Error: No formulae or casks found for "curl-openssl".

install を curl で指定しても curl-opennssl で指定しても結果は同じです。

% brew install curl
Warning: curl 7.74.0 is already installed and up-to-date
To reinstall 7.74.0, run `brew reinstall curl`


% brew install curl-openssl
Warning: curl 7.74.0 is already installed and up-to-date
To reinstall 7.74.0, run `brew reinstall curl`

インストール後の curl の実行

再度 Developers.IO CAFE に curl を試みると、 TLSv 1.3 で接続したことを確認できました。

% curl -s -v https://cafe.classmethod.jp > /dev/null
*   Trying 99.84.55.114:443...
* Connected to cafe.classmethod.jp (99.84.55.114) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
} [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):
{ [10 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [4853 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [264 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [36 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [36 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
---以下略---

ちなみにこのエントリが載っているサイトである Developers.IO では、現時点で TLSv 1.3 に対応していません。 curl を行うと TLSv 1.3 からネゴシエーションを行いますが、最終的には TLSv 1.2 で接続を行います。

% curl -s -v https://dev.classmethod.jp > /dev/null
*   Trying 13.114.114.78:443...
* Connected to dev.classmethod.jp (13.114.114.78) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [98 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [4846 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 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 handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
---以下略---

このあたりのおさらいには以下をどうぞ。

最後に少し小ネタをご紹介します。

--tls-max で TLS バージョンの上限を指定

--tls-maxオプションでバージョンの上限を指定できます。

Developers.IO CAFE に TLSv 1.2 で接続してみました。

% curl -s -v --tls-max 1.2 https://cafe.classmethod.jp > /dev/null
*   Trying 99.84.55.28:443...
* Connected to cafe.classmethod.jp (99.84.55.28) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [235 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [91 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [4844 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 handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
---以下略---

--tlsv1.x で TLS バージョンの下限を指定

--tlsv1.xオプションでバージョンの下限を指定できます。

TLSv 1.3 に非対応の Developers.IO に--tlsv1.3を指定して curl を試行すると、ハンドシェイクで失敗します。

% curl -s -v --tlsv1.3 https://dev.classmethod.jp > /dev/null
*   Trying 13.113.72.115:443...
* Connected to dev.classmethod.jp (13.113.72.115) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS alert, handshake failure (552):
{ [2 bytes data]
* error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
* Closing connection 0

楽しい!

終わりに

curl で--tlsv1.3を使いたい、というお話でした。

curl: (4) LibreSSL was built without TLS 1.3 supportで検索すると 2019年ごろのバタバタした記事が多くヒットしたので身構えてしまったのですが、今となってはだいぶ落ち着いているようです。

同じようなケースに直面した方の参考になれば幸いです。

以上、千葉(幸)がお送りしました。