CentOS 5でLet's Encryptするには

古いアプリケーションサーバで、SSL/TLS証明書の有効期限切れに急遽対応することになった。
いくつかハマリどころがあったので対処方法を公開する。

# 問題点
期限切れ証明書はDigiCertが発行したもの。
この機会に **Let's Encrypt** の無料証明書に差し替えたいというのがお客様からの要望だが、ここでひとつ問題があった。
それは、Pythonで書かれた公式ACMEクライアントの`certbot`が **CentOS 6** 以降にしか対応していないことだ。

```shell-session:お客様の環境
# cat /etc/redhat-release 
CentOS release 5.11 (Final)
```

お客様のサーバは **CentOS 5** なので、今回は`dehydrated`で証明書を取得することにした。
`dehydrated`は、ACMEプロトコルを`bash`、`openssl`、`curl`、`sed`、`grep`で実装する非公式のACMEエージェントだ。

# EPELリポジトリを追加するまで
`dehydrated`は、`git`を用いたサービスのひとつである **GitHub** で配布しているので、まず`git`を導入する必要がある。
`git`はyumの標準リポジトリにないので、EPELリポジトリを追加するところから始めよう。

## yum.repo の修正

**CentOS 5** は **EOL**（サポート終了）なので、yumが参照できなくなっている。
http://mirror.centos.org/centos/5.11/readme によると、
CentOS 5.11の最新リリース版は http://vault.centos.org/5.11/ から入手できるとのことなので、yumのBaseリポジトリを変更する。

`mirrorlist`をコメントアウトし、`baseurl`を変更する。他のセクションも同様。

```config:/etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://vault.centos.org/5.11/os/$basearch/
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
```

````shell-session:EPELリポジトリを追加
yum -y install epel-release
```

ところが見つからないと怒られる。

```shell-session:エラーメッセージ
http://vault.centos.org/5.11/os/x86_64/RPMS/epel-release-5-4.noarch.rpm: [Errno 14] HTTP Error 404: Not Found
Trying other mirror.
```

たしかに同名のファイルは無いようで、Fedora Archiveからwgetを試みるも・・・

```:Fedora&nbsp;Archive
wget https://archives.fedoraproject.org/pub/archive/epel/5Server/x86_64/epel-release-5-4.noarch.rpm
```

```shell-session:エラーメッセージ
OpenSSL: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
```

`--secure-protocol=TLSv1_2`は`Invalid value`になるし、`--no-check-certificate`を付けても変わらない。
`openssl`のバージョンが古いことが影響しているようだ。

```shell-session
# openssl version
OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008
```

## TLS 1.0 無効化への対処

TLS 1.0には様々な脆弱性が指摘されていて、インターネット界隈ではTLS 1.0廃止の動きが広がっている。
今日ではTLS 1.0を受け付けないサイトが多い。

どちらにせよ、`dehydrated`を動かすには **OpenSSL** と **cURL** は新しくしておいた方が良く、
https://qiita.com/kuwas_h/items/a1f1dcefaf79d913b3ef
の通りにリビルドし、バージョンアップした。

```shell-session
# openssl version
OpenSSL 1.0.2n  7 Dec 2017
```

`wget`で`--secure-protocol=TLSv1_2`を指定するためには、少なくとも`wget`のバージョンを1.16以上にする必要があるそうなので、`wget`もソースコードからリビルドする。

```
# wget -V
GNU Wget 1.11.4 Red Hat modified

cd /usr/local/src
wget http://ftp.gnu.org/gnu/wget/wget-1.16.tar.gz
tar zxvf wget-1.16.tar.gz
cd wget-1.16
./configure --prefix=/usr --with-ssl=openssl
make install

# wget -V
GNU Wget 1.16 built on linux-gnu.
```

TLSv1_2を指定してダウンロード成功。EPELリポジトリが有効になる。

```
wget --secure-protocol=TLSv1_2 --no-check-certificate https://archives.fedoraproject.org/pub/archive/epel/5Server/x86_64/epel-release-5-4.noarch.rpm
rpm -ivh epel-release-5-4.noarch.rpm
```

# Gitのインストールまで
EPELリポジトリから`git`をインストール。

```
yum install --enablerepo=epel git
```

キーを取り込むか聞かれるので "y" を応答。

```
Importing GPG key 0x217521F6 "Fedora EPEL <epel@fedoraproject.org>" from /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL
Is this ok [y/N]: y
```

試しにここで`git clone`してみると、**GitHub** でもTLS 1.0/1.1のアクセスを禁止しているのでエラーになる。 

```
git clone https://github.com/lukas2511/dehydrated
Cloning into 'dehydrated'...
error: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version while accessing https://github.com/lukas2511/dehydrated/info/refs?service=git-upload-pack
fatal: HTTP request failed
```

gitのバージョンが古いので `git config --global http.sslVersion "tlsv1.2"` も効かないようだ。
ソースコードから最新バージョンでリビルドしよう。

```
# git version
git version 1.8.2.3

cd /usr/local/src
wget --no-check-certificate https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.9.5.tar.gz
tar zxvf git-2.9.5.tar.gz
cd git-2.9.5
./configure --prefix=/usr
make prefix=/usr all
make prefix=/usr install

# git version
git version 2.9.5
```

# dehydratedの導入と設定

改めて`git clone`し、HTTPによるドメイン認証の設定を行う。

```shell
cd /opt
git clone https://github.com/lukas2511/dehydrated
cd dehydrated
cp docs/examples/config config
echo "ドメイン名" > domains.txt
mkdir /var/www/dehydrated   # ワンタイムトークンの作成場所（デフォルト通り）
```

`http://ドメイン名/.well-known/acme-challenge/` にアクセスできるようにする。
（常時SSLのためポート443のみで運用しているお客様には、ポート80を開けていただくよう手配しよう）

```apache:/etc/httpd/conf.d/acme-challenge.conf
Alias /.well-known/acme-challenge /var/www/dehydrated
<Directory "/var/www/dehydrated/.well-known/acme-challenge">
    order allow,deny
    allow from all
</Directory>
```

## 証明書の取得

```
./dehydrated -c --accept-terms
```

`/opt/dehydrated/certs/ドメイン名`の下に証明書がダウンロードされるので、Apache HTTPDから参照するようにすれば完了だ。