古いアプリケーションサーバで、SSL/TLS証明書の有効期限切れに急遽対応することになった。
いくつかハマリどころがあったので対処方法を公開する。
問題点
期限切れ証明書はDigiCertが発行したもの。
この機会に Let's Encrypt の無料証明書に差し替えたいというのがお客様からの要望だが、ここでひとつ問題があった。
それは、Pythonで書かれた公式ACMEクライアントのcertbot
が CentOS 6 以降にしか対応していないことだ。
# 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
を変更する。他のセクションも同様。
[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
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 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から参照するようにすれば完了だ。