1. watawuwu

    Posted

    watawuwu
Changes in title
+RustでAlpineからHTTPS
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,86 @@
+## 目的
+`x86_64-unknown-linux-musl`でビルドしたバイナリを使って、DockerコンテナのAlpineからHTTPS通信をしたい!
+
+HTTPS通信と書いていますが、想定しているユースケースは`hyper`を使った通信処理です。
+[gotham](https://github.com/gotham-rs/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)
+ - [rust-openssl](https://github.com/sfackler/rust-openssl)
+- [サンプルソース](https://github.com/watawuwu/sample-rust-alpine-https)
+ - `make`で実行
+
+## 設定
+
+### Compile時の設定
+OpenSSLを静的リンクするために以下の設定を行います。
+
+- OpenSSLを`musl-libc`を使ってコンパイルし、Staticなlibraryを用意
+- 静的リンクするためのビルド設定を環境変数に設定
+ - `OPENSSL_STATIC=1`
+ - 必要に応じて`OPENSSL_`プリフィックスで始まる環境変数の設定
+
+具体的には[こちら](https://github.com/emk/rust-musl-builder/blob/master/Dockerfile#L62-L96)の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](https://crates.io/crates/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
+上記で紹介した[イメージ](https://hub.docker.com/r/ekidd/rust-musl-builder/)を利用し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}"]
+```
+
+[サンプルソース](https://github.com/watawuwu/sample-rust-alpine-https)では13Mと軽量なDockerイメージを作ることができました。
+
+## 備考
+証明書が発見できない場合は以下の様なエラーが発生します。
+
+```
+The OpenSSL library reported an error: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed:s3_clnt.c:1269
+```