1. watawuwu

    Posted

    watawuwu
Changes in title
+RustでAlpineからHTTPS
Changes in tags
Changes in body
Source | HTML | Preview

目的

x86_64-unknown-linux-muslでビルドしたバイナリを使って、DockerコンテナのAlpineからHTTPS通信をしたい!

HTTPS通信と書いていますが、想定しているユースケースはhyperを使った通信処理です。
gothamなど多くのWebFrameworkがhyperを使用しているため、WebServerを作る場合のTipsでもあります。

Ubuntuでビルドして、Ubuntuで起動するなら簡単ですが、muslを使ってBuildし
Alpineで起動するとハマりどころが多いのでメモっておきます。

前提

軽量なDockerイメージにするため、Compile OSとRuntime OSを分けます。

環境

  • Compile OS: ubuntu16.04
  • Runtime OS: alpine3.7
  • Rust: v1.23
  • Target: rust-opensslx86_64-unknown-linux-musl
  • SSL Lib: OpenSSL(openssl-rust)
  • サンプルソース
    • makeで実行

設定

Compile時の設定

OpenSSLを静的リンクするために以下の設定を行います。

  • OpenSSLをmusl-libcを使ってコンパイルし、Staticなlibraryを用意
  • 静的リンクするためのビルド設定を環境変数に設定
    • OPENSSL_STATIC=1
    • 必要に応じてOPENSSL_プリフィックスで始まる環境変数の設定

具体的にはこちらのDockerfileが参考となります。

Runtime時の設定

Linuxディストリビューションによって証明書のパスが違うため、証明書のパスを設定する必要があります。
Alpineで実行する際には以下の設定をします。

$ apk add --no-cache ca-certificates && update-ca-certificates
$ export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
$ export SSL_CERT_DIR=/etc/ssl/certs

他の方法として、Alpine以外のLinuxディストリビューションでも動作させたい場合、openssl-probeを使うことで証明書のパスをRuntime時に解決できます

[dependencies]
openssl-probe = "0.1"

init_ssl_cert_env_vars()を実行する。

extern crate openssl_probe;

fn main() {
    openssl_probe::init_ssl_cert_env_vars();
    //... your code
}

Docker

上記で紹介したイメージを利用しMultiStageでbuildすると、軽量なDockerイメージを作成できます。

FROM ekidd/rust-musl-builder:stable AS rust-builder
ADD . .
RUN cargo build --release --target x86_64-unknown-linux-musl

FROM alpine:3.7
COPY --from=rust-builder /home/rust/src/target/x86_64-unknown-linux-musl/release/{bin} /usr/local/bin
RUN apk add --no-cache ca-certificates && update-ca-certificates
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
ENV SSL_CERT_DIR=/etc/ssl/certs
CMD ["{bin}"]

サンプルソースでは13Mと軽量なDockerイメージを作ることができました。

備考

証明書が発見できない場合は以下の様なエラーが発生します。

The OpenSSL library reported an error: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed:s3_clnt.c:1269