CentOS6.xでAmazon EFSとの通信経路をTLS暗号化した時のメモ

CentOS6.xでAmazon EFSとの通信経路をTLS暗号化してNFSマウントする機会があったのでその時のメモです。

## 注意
ここで述べている内容は個人のテスト環境でNFSマウントした時の手順であり、実際の商用環境などで性能や動作を保証するものではありません。

## 前提

CentOS6.xにstunnelパッケージがインストールされて**いない**こと。
今回stunnelはCentOS6.x標準のパッケージより新しいものをコンパイルして/usr/local/bin/stunnelとしてインストールするため既存のstunnelパッケージがインストールされていると正常に動作しない可能性があります。

## 依存パッケージ

amazon-efs-utilsをインストールには以下のパッケージに依存しますが、CentOS6.xで提供されているパッケージはバージョンを満たしていないためamazon-efs-utilsツールを導入することができません。

| パッケージ | 必須バージョン | CentOS6.x |
| ---------- | -------------- | --------- |
| openssl | 1.0.2 以降 | 1.0.1 |
| python | 3 以降 | 2.6.6 |
| stunnel | 4.56 以降 | 4.29 |

CentOSのパッケージをyumアップデートしてもバージョンは変わりませんし
opensslのようなパッケージをコンパイルしてOSのライブラリを上書きしてしまうと、opensslを参照している他のパッケージが正常に動作しなくなる可能性があります。

そこでバージョン条件を満たすパッケージを/opt配下にコンパイル・インストールし、EFSマウントヘルパーだけが/opt配下のファイルを参照するようにします。

| パッケージ    | 参照するopensslライブラリ |
| ------------- | ------------------------- |
| Apacheなど    | OS標準のopenssl1.0.1e     |
| aws-efs-utils | /opt配下のopenssl1.1.1k   |

## 構築

#### yumリポジトリの変更

CentOS6のリポジトリは2020/11/30でサポートが終了したためVaultを参照するようにします。

```
# sed -i -e "s/^mirrorlist=http:\/\/mirrorlist.centos.org/#mirrorlist=http:\/\/mirrorlist.centos.org/g" /etc/yum.repos.d/CentOS-Base.repo
# sed -i -e "s/^#baseurl=http:\/\/mirror.centos.org/baseurl=http:\/\/vault.centos.org/g" /etc/yum.repos.d/CentOS-Base.repo
```

#### nssアップデート

以降の手順のcurlやgitなどでエラーが出る場合はnssパッケージをアップデートしてください。

```
# yum -y update nss
```

諸事情によりパッケージのアップデートを行えない場合は、CentOS6.xとは別のホストで以下のソースをダウロードしてCentOS6.xの/opt/srcに配置してください。
※以下は記事作成時点での最新です。

- https://www.openssl.org/source/openssl-1.1.1k.tar.gz
- https://www.stunnel.org/downloads/stunnel-5.59.tar.gz
- https://www.python.org/ftp/python/3.9.5/Python-3.9.5.tgz
- https://github.com/aws/efs-utils/archive/refs/heads/master.zip

#### コンパイルに必要なパッケージのインストール

```
# yum -y install gcc git make nks-utils rpm-build zlib-devel
```

#### opensslのインストール

sharedライブラリは作成せずアーカイブのみ作成します。

```
# mkdir -p /opt/src
# cd /opt/src
# curl -O https://www.openssl.org/source/openssl-1.1.1k.tar.gz
# tar xzf openssl-1.1.1k.tar.gz
# cd openssl-1.1.1k
# ./config -fPIC --prefix=/opt/openssl --openssldir=/opt/openssl no-shared
# make
# make install
```

#### stunnelのインストール

stunnelが参照するopensslは 4.でインストールしたライブラリをスタティックリンクします。

```
# cd /opt/src
# curl -O https://www.stunnel.org/downloads/stunnel-5.59.tar.gz
# tar xzf stunnel-5.59.tar.gz
# cd stunnel-5.59
# ./configure --prefix=/opt/stunnel --with-ssl=/opt/openssl --enable-static
# make
# mkdir -p /opt/stunnel/etc/stunnel /opt/stunnel/var/run/stunnel
# touch /opt/stunnel/etc/stunnel/stunnel.pem
# make install
# ln -s /opt/stunnel/bin/stunnel /usr/local/bin/stunnel
```

#### python3のインストール

```
# cd /opt/src
# curl -O https://www.python.org/ftp/python/3.9.5/Python-3.9.5.tgz
# tar xzf Python-3.9.5.tgz
# cd Python-3.9.5
# ./configure --prefix=/opt/python
# make
# make install
```

#### EFSマウントヘルパー(aws-efs-utils)のインストール

aws-efs-utilsは依存関係を無視してインストールします。

```
# cd /opt/src

# git clone https://github.com/aws/efs-utils
# cd efs-utils

※別ホストでソースをダウンロードした場合は下記手順で展開してください。
# unzip master.zip
# cd efs-utils-master

# make rpm
# rpm -ivh --nodeps build/amazon-efs-utils*rpm
```

#### EFSマウントヘルパー(aws-efs-utils)の変更

aws-efs-utilsが今回インストールした/opt/python/bin/python3を参照するように変更します。

```
# sed -i -e 's/\/usr\/bin\/env python3/\/opt\/python\/bin\/python3/' /usr/bin/amazon-efs-mount-watchdog
# sed -i -e 's/\/usr\/bin\/env python3/\/opt\/python\/bin\/python3/' /sbin/mount.efs
```

#### aws-efs-utilsによってstunnelのコンフィグファイルに"libwrap=no"が出力されないようにmount.efsを変更します。

```
# sed -i -e 's/CENTOS8/CENTOS/g' -e 's/CentOS Linux release 8/CentOS release/' /sbin/mount.efs
```

## 設定

#### efs-utils.confの設定

- リージョン設定

下記は東京リージョンのEFSをマウントする場合です。

```
# sed -i -e 's/^#region = us-east-1/region = ap-northeast-1/' /etc/amazon/efs/efs-utils.conf
```

- ホスト証明書チェックを無効化します。

```
# sed -i -e 's/stunnel_check_cert_hostname = true/stunnel_check_cert_hostname = false/' /etc/amazon/efs/efs-utils.conf
```

#### EFSマウント設定

- /etc/fstabにEFSのマウントエントリを追加します。

```
fs-XXXXXXXX:/             /mnt/efs   efs     tls,_netdev     0 0
```

- CentOS6.xがVPNなどで接続されたオンプレサーバーの場合/etc/hostsでEFSマウントターゲットを指定します。

```
(EFSマウントターゲットのIP) fs-XXXXXXXX.efs.ap-northeast-1.amazonaws.com
```

## 動作確認

#### EFSのマウント

```
# mkdir /mnt/efs
# mount /mnt/efs
```

####  EFSのマウント確認

```
# df /mnt/efs
127.0.0.1:/               8.0E   59M  8.0E    1% /mnt/efs
```

CentOS6.xからstunnelを介してEFSにTLSv1.2で接続されていることが確認で出来ます。

```
# ps -ef | grep stunnel | grep -v grep
root      1105     1  0 05:46 ?        00:00:00 /usr/local/bin/stunnel /var/run/efs/stunnel-config.fs-17d778a3.mnt.efs.20116

# cat /var/run/efs/stunnel-config.fs-17d778a3.mnt.efs.20116
fips = no

foreground = yes
socket = l:SO_REUSEADDR=yes
socket = a:SO_BINDTODEVICE=lo
[efs]
client = yes
accept = 127.0.0.1:20116
connect = fs-17d778a3.efs.us-east-1.amazonaws.com:2049
sslVersion = TLSv1.2
renegotiation = no
TIMEOUTbusy = 20
TIMEOUTclose = 0
TIMEOUTidle = 70
delay = yes
verify = 2
CAfile = /etc/amazon/efs/efs-utils.crt
cert = /var/run/efs/fs-17d778a3.mnt.efs.20116+/certificate.pem
key = /etc/amazon/efs/privateKey.pem
```