ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

Ubuntu では ca-certificates パッケージで CA 証明書をインストールできるぞ

1 行まとめ

Ubuntu ベースの Docker コンテナSSL 接続をするために ca-certificates パッケージをインストールしましょう。

エラー内容

Ubuntu 18.04 (ubuntu:18.04) ベースの Docker コンテナで HTTPS 接続ができなくて npm install に失敗した。

root@068c8e545fca:/# npm install -g carto
npm ERR! Linux 4.9.125-linuxkit
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install" "-g" "carto"
npm ERR! node v8.10.0
npm ERR! npm  v3.5.2
npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY

npm ERR! unable to get local issuer certificate
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /npm-debug.log

見るからに CA 証明書のエラーっぽい。 /npm-debug.log の中身を見ると以下のような感じ。

0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/node', '/usr/bin/npm', 'install', '-g', 'carto' ]
(略)
15 info attempt registry request try #1 at 10:34:44 AM
16 verbose request id 454780186dc942d1
17 http request GET https://registry.npmjs.org/carto
18 info retry will retry, error on last attempt: Error: unable to get local issuer certificate
19 info attempt registry request try #2 at 10:34:54 AM
20 http request GET https://registry.npmjs.org/carto
21 info retry will retry, error on last attempt: Error: unable to get local issuer certificate
22 info attempt registry request try #3 at 10:35:54 AM
23 http request GET https://registry.npmjs.org/carto
24 silly fetchPackageMetaData Error: unable to get local issuer certificate
24 silly fetchPackageMetaData at TLSSocket. (_tls_wrap.js:1105:38)
24 silly fetchPackageMetaData at emitNone (events.js:106:13)
24 silly fetchPackageMetaData at TLSSocket.emit (events.js:208:7)
24 silly fetchPackageMetaData at TLSSocket._finishInit (_tls_wrap.js:639:8)
24 silly fetchPackageMetaData at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)
24 silly fetchPackageMetaData error for carto { Error: unable to get local issuer certificate
24 silly fetchPackageMetaData at TLSSocket. (_tls_wrap.js:1105:38)
24 silly fetchPackageMetaData at emitNone (events.js:106:13)
24 silly fetchPackageMetaData at TLSSocket.emit (events.js:208:7)
24 silly fetchPackageMetaData at TLSSocket._finishInit (_tls_wrap.js:639:8)
24 silly fetchPackageMetaData at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38) code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' }
(略)
30 verbose stack Error: unable to get local issuer certificate
30 verbose stack at TLSSocket. (_tls_wrap.js:1105:38)
30 verbose stack at emitNone (events.js:106:13)
30 verbose stack at TLSSocket.emit (events.js:208:7)
30 verbose stack at TLSSocket._finishInit (_tls_wrap.js:639:8)
30 verbose stack at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)
31 verbose cwd /
32 error Linux 4.9.125-linuxkit
33 error argv "/usr/bin/node" "/usr/bin/npm" "install" "-g" "carto"
34 error node v8.10.0
35 error npm v3.5.2
36 error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
37 error unable to get local issuer certificate
38 error If you need help, you may report this error at:
38 error <https://github.com/npm/npm/issues>
39 verbose exit [ 1, true ]

curl コマンドを試してみるも、当然ながらこちらも CA 証明書のエラー。

root@068c8e545fca:/# curl https://google.com/
curl: (77) error setting certificate verify locations:
  CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs

原因と対応

Ubuntu では基本的な CA 証明書が ca-certificates パッケージで提供されている。 これがインストールされていない状態で npm install コマンドや curl コマンドで HTTPS 通信しようとすると CA 証明書のエラーが発生する。 curl パッケージなどをインストールする際に、デフォルトでは推奨パッケージとして ca-certificates パッケージもインストールされるのでこのエラーには遭遇しづらいが、Docker イメージをビルドする際に apt install -y --no-install-recommends curl という感じで --no-install-recommends オプションを付けていると ca-certificates パッケージがインストールされずに、上記の状態になる。

対策としては、単純に ca-certificates パッケージをインストールすれば良い。