Amazon EFSでマウントヘルパーを使用せずに転送中のデータを暗号化する

2018.07.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon Elastic File System (EFS) は、転送時の暗号化をサポートしています。

[新機能] Amazon EFS が通信経路での TLS 暗号化をサポートしました

Amazon EFS マウントヘルパー amazon-efs-utils をインストール後、

$ sudo mount -t efs -o tls fs-12345678:/ /mnt/efs

というようにマウント時に -o tls オプションを追加するだけで、アプリケーションの変更なしに Amazon EFS との通信が暗号化されます。

この暗号処理の裏では stunnel が活躍しています。

stunnel でローカルのあるポートからAmazon EFS の TLS 通信用ポート 2049 と TLS 1.2 で接続し、クライアントは localhost:port をマウントしています。

マウントヘルパーを使用せずに転送中のデータの暗号化を有効にする

今回は、マウントヘルパー amazon-efs-utils の処理を理解するために、ヘルパーを使わずに、各コマンドを直接叩いて通信を暗号化します。

詳細は、ドキュメントAWS Documentation » Amazon Elastic File System (EFS) » User Guide » Security » Encrypting Data and Metadata in EFS の "How Encrypting in Transit Works " のセクションをご確認ください。

1. stunnel のインストール

stunnel をインストールします。Amazon Linux 1/2 の場合は yum でインストール可能です。

$ sudo yum install -y stunnel
$ stunnel -version
stunnel 4.56 on x86_64-koji-linux-gnu platform
Compiled/running with OpenSSL 1.0.2k-fips  26 Jan 2017
Threading:PTHREAD Sockets:POLL,IPv6 SSL:ENGINE,OCSP,FIPS Auth:LIBWRAP

Global options:
debug                  = daemon.notice
pid                    = /var/run/stunnel.pid
RNDbytes               = 64
RNDfile                = /dev/urandom
RNDoverwrite           = yes

Service-level options:
ciphers                = FIPS (with "fips = yes")
ciphers                = ALL:!SSLv2:!aNULL:!EXP:!LOW:-MEDIUM:RC4:+HIGH (with "fips = no")
curve                  = prime256v1
sessionCacheSize       = 1000
sessionCacheTimeout    = 300 seconds
sslVersion             = TLSv1 (with "fips = yes")
sslVersion             = TLSv1 for client, all for server (with "fips = no")
stack                  = 65536 bytes
TIMEOUTbusy            = 300 seconds
TIMEOUTclose           = 60 seconds
TIMEOUTconnect         = 10 seconds
TIMEOUTidle            = 43200 seconds
verify                 = none

2. stunnel を実行し、TLS を使用して、ポート 2049 で Amazon EFS ファイルシステムに接続

次に stunnel を利用して Amazon EFS の 2049 ポートに TLS で接続します。

stunnel のオプションがややこしそうです。

amazon-efs-utils パッケージで TLS マウントした状態で stunnel のプロセスを確認すると、 /var/run/efs/ 以下に stunnel 用の設定ファイルを出力し、stunnel 起動時にその設定ファイルを読み込んでいることがわかります。

$ ps aux -www | grep stunnel
root      3332  0.0  0.7 116604  7548 ?        Ssl  18:40   0:00 stunnel /var/run/efs/stunnel-config.fs-12345678.home.ec2-user.mnt.20399

$ cat /var/run/efs/stunnel-config.fs-12345678.home.ec2-user.mnt.20399
foreground = yes
fips = no
socket = l:SO_REUSEADDR=yes
socket = a:SO_BINDTODEVICE=lo
[efs]
checkHost = fs-12345678.efs.eu-central-1.amazonaws.com
OCSPaia = yes
accept = 127.0.0.1:20399
TIMEOUTbusy = 20
connect = fs-12345678.efs.eu-central-1.amazonaws.com:2049
libwrap = no
CAfile = /etc/pki/tls/certs/ca-bundle.crt
sslVersion = TLSv1.2
verify = 2
client = yes

今回は、この設定ファイルを流用し、必要なところだけ書き換えます。

stunnel-sample.config

oreground = yes
fips = no
socket = l:SO_REUSEADDR=yes
socket = a:SO_BINDTODEVICE=lo
[efs]
checkHost = fs-12345678.efs.eu-central-1.amazonaws.com
OCSPaia = yes
accept = 127.0.0.1:20399
TIMEOUTbusy = 20
connect = fs-12345678.efs.eu-central-1.amazonaws.com:2049
libwrap = no
CAfile = /etc/pki/tls/certs/ca-bundle.crt
sslVersion = TLSv1.2
verify = 2
client = yes
  • checkHost(証明書チェックに利用するホスト名)
  • connect

を対応する EFS のエンドポイントに変更します。

accept のローカルのポート(サンプルでは 20399)を適宜変更します。

この設定ファイルを利用して stunnel を root 権限で起動します。

$ sudo stunnel stunnel-sample.config
2018.07.26 16:19:37 LOG5[ui]: stunnel 5.48 on x86_64-pc-linux-gnu platform
2018.07.26 16:19:37 LOG5[ui]: Compiled/running with OpenSSL 1.0.2k-fips  26 Jan 2017
2018.07.26 16:19:37 LOG5[ui]: Threading:PTHREAD Sockets:POLL,IPv6 TLS:ENGINE,FIPS,OCSP,PSK,SNI Auth:LIBWRAP
2018.07.26 16:19:37 LOG5[ui]: Reading configuration from file /home/ec2-user/stunnel-sample.config
2018.07.26 16:19:37 LOG5[ui]: UTF-8 byte order mark not detected
2018.07.26 16:19:37 LOG5[ui]: FIPS mode disabled
2018.07.26 16:19:37 LOG5[ui]: Configuration successful

3. NFS クライアントを使用して、最初のステップで書き留めたポート port に、localhost:port をマウント

最後に mount コマンドでマウントします。

stunnel 版マウント

$ sudo mount -t nfs4 \
  -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20399 \
  127.0.0.1:/ \
  /mnt/efs
$

オプション(-o)に、stunnel でローカルバインドしたポートを指定(,port=20399)します。

また Amazon EFS のエンドポイントではなく、127.0.0.1 を指定します。

このオプションでマウントしたときの stunnel のログを確認します。

$ sudo stunnel stunnel-sample.config
...
2018.07.26 16:19:45 LOG5[0]: Service [efs] accepted connection from 127.0.0.1:51972
2018.07.26 16:19:45 LOG5[0]: s_connect: connected 172.31.25.244:2049
2018.07.26 16:19:45 LOG5[0]: Service [efs] connected remote server from 172.31.16.61:35998
2018.07.26 16:19:45 LOG5[0]: OCSP: Connecting the AIA responder "http://o.ss2.us/"
2018.07.26 16:19:45 LOG5[0]: s_connect: connected 52.85.182.204:80
2018.07.26 16:19:45 LOG5[0]: OCSP: Certificate accepted
2018.07.26 16:19:45 LOG5[0]: OCSP: Connecting the AIA responder "http://ocsp.rootg2.amazontrust.com"
2018.07.26 16:19:45 LOG5[0]: s_connect: connected 52.85.182.118:80
2018.07.26 16:19:45 LOG5[0]: OCSP: Certificate accepted
2018.07.26 16:19:45 LOG5[0]: OCSP: Connecting the AIA responder "http://ocsp.rootca1.amazontrust.com"
2018.07.26 16:19:45 LOG5[0]: s_connect: connected 52.85.182.50:80
2018.07.26 16:19:45 LOG5[0]: OCSP: Certificate accepted
2018.07.26 16:19:45 LOG5[0]: OCSP: Connecting the AIA responder "http://ocsp.sca1b.amazontrust.com"
2018.07.26 16:19:45 LOG5[0]: s_connect: connected 52.85.182.167:80
2018.07.26 16:19:45 LOG5[0]: OCSP: Certificate accepted
2018.07.26 16:19:45 LOG5[0]: Certificate accepted at depth=0: CN=*.efs.eu-central-1.amazonaws.com

正常に接続できています。

非 stunnel 版

比較のために、stunnel を使わない場合のマウントオプションも記載します。

$ sudo mount -t nfs4 \
  -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport \
  fs-12345678.efs.eu-central-1.amazonaws.com:/ \
  /mnt/efs
$

ポートはオプション指定せず、Amazon EFS のエンドポイント(fs-12345678.efs.eu-central-1.amazonaws.com)を利用してマウントします。

マウントヘルパーのメリット

マウントヘルパー(amazon-efs-utils)を使うと

  • ローカルのポートを自動で割り振る
  • stunnel のプロセスを監視
  • ログ出力
  • オプションを細かく指定しなくてもいい感じでマウント

など、特別な理由がない限りは使わない手はありません。

最後に

今回はマウントヘルパー(amazon-efs-utils)を使わずに、 Amazon EFS に対して通信を暗号化してマウントしました。

ヘルパーがどのように動いているのか把握することで、システムをより安定にしたり、システム障害時のスムーズな問題切り分けが可能になります。

よりよい Amazon EFS ライフを!

参考