CentOS 7のNginxをTLS 1.3に対応させたいが、ソースからビルド等せずに出来るだけ簡単にyumでTLS 1.3対応済みのNginxをインストール(又はアップデート)したい。
そんな要望が多いと思いますのでその方法を解説します。
※動作確認環境(2022/06/06更新)
CentOS 7.9
Nginx 1.22.0
OpenSSL 1.1.1o
現状
OpenSSL 1.1.1が2018年秋に公開されてTLS 1.3に正式対応したが、CentOS 7に標準で入っているOpenSSLのバージョンは1.0.2系なのでそのままではTLS 1.3を利用できない。
CentOS 7のOpenSSL自体を1.1.1に上げてしまうのが手っ取り早く思えるが、そんなことをしたらNginx以外の他のパッケージも巻き込んで非常にややこしいことになる。
それならNginxだけにOpenSSL 1.1.1を対応させるという手もあるが、ソースからビルドするのは手間がかかるし、依存関係の処理や、その後のNginxのアップデートなども面倒だ。
対策案
CentOS 7でパッケージ管理をするならyumでやるのが一番簡単。
それならyumで手軽に管理できるOpenSSL 1.1.1及びTLS 1.3に対応済みのNginxを作って、自作リポジトリを作成してそこに登録してしまえば良い。以降はyumで簡単に管理できる。
というわけで、以下の手順で行っていきます。
- 現在のNginxのバージョンをチェック
- 作業用の仮想環境作成
- 必要パッケージのインストール
- CentOS 7用のNginxのPRMパッケージとOpenSSL 1.1.1をゲット
- RPMパッケージをOpenSSL 1.1.1に対応させてリビルド
- 自作リポジトリを作成してRPMパッケージを設置
- 自作リポジトリからyumでNginxをインストール(又はアップデート)
- Nginxの設定(TLS 1.3有効化や暗号スイート等の設定)
- 動作確認
現在のNginxのバージョンをチェック
TLS 1.3に対応させたいサーバにSSHで接続します。
そして以下のコマンドで現在のNginxのバージョンを確認しておいてください。
1 2 |
# rpm -qa | grep nginx nginx-1.18.0-3.el7.ngx.x86_64 |
「nginx-1.18.0-3.el7.ngx.x86_64」が現在のNginxのバージョンだと確認できました。
これを覚えておきます。
作業用の環境作成
VirtualBoxに作業用CentOS 7の仮想環境を作る。
詳細は省きますが、要点は以下の二つ。
- yumとcurlで外部に接続できる。
- SSHでログインできる。
単に最新のRPMパッケージを取得してリビルドするだけなので余分な機能は不要です。(※VirtualBoxでなくてもyumとcurlとSSHが利用できれば何でもOKです。)
以下の手順でサクッと仮想環境を作成します。
- VirtualBoxのインストール
- VirtualBoxの「新規」→「仮想マシンの作成」でウィザードに従ってCentOS 7のMinimal ISOから最小インストール
- 仮想マシンの「ネットワーク」の設定で、標準のNATの他にホストオンリーアダプターも追加して有効化
- 「ip addr」でIPアドレスを確認してSSHでログイン
- 「yum update」でアップデートして最新にする。
※詳しい手順は以下のページで解説していますのでご利用ください。
必要パッケージのインストール(作業用サーバ)
作業用サーバが完成したら、作業に必要な基本的なパッケージをインストールします。
1 |
# yum -y install redhat-lsb-core zlib-devel pcre-devel pcre2-devel gcc epel-release |
epelリポジトリのenabledを0に変更
1 |
# vi /etc/yum.repos.d/epel.repo |
1 2 3 4 5 6 7 8 |
[epel] name=Extra Packages for Enterprise Linux 7 - $basearch #baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch failovermethod=priority enabled=0 #1から0に変更 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 |
epelから必要なパッケージをインストールします。
1 |
# yum -y --enablerepo=epel install rpm-build zlib-devel pcre-devel perl-devel perl-ExtUtils-Embed GeoIP-devel libxslt-devel gd-devel |
「Development Tools」をグループインストールします。
1 |
# yum -y --enablerepo=epel groupinstall "Development Tools" |
最新のNginxとOpenSSLをゲット(作業用サーバ)
作業用ユーザー作成
まず、作業用のユーザーを作成します。
1 |
# useradd builder |
作業用ユーザーに変更(スイッチ)します。
1 |
# su builder - |
作業用のディレクトリを設定します。
1 2 |
$ cd $ echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros |
NginxとOpenSSLの最新バージョンをチェック
NginxとOpenSSLの公式サイトで最新バージョン(2022/06/06現在)をチェックします。
■Nginx公式サイト
https://nginx.org/packages/centos/7/SRPMS/
※Nginxの最新バージョン(CentOS 7用)「ginx-1.22.0-1.el7.ngx.src.rpm」
【ダウンロードURL】
https://nginx.org/packages/centos/7/SRPMS/nginx-1.22.0-1.el7.ngx.src.rpm
■OpenSSL公式サイト
https://www.openssl.org/source/
※OpenSSL 1.1.1系の最新バージョン「openssl-1.1.1o.tar.gz」
【ダウンロードURL】
https://www.openssl.org/source/openssl-1.1.1o.tar.gz
ダウンロードおよび展開
Nginxのダウンロードおよびインストール
1 2 |
$ curl -L -O https://nginx.org/packages/centos/7/SRPMS/nginx-1.22.0-1.el7.ngx.src.rpm $ rpm -ivh nginx-1.22.0-1.el7.ngx.src.rpm |
OpenSSLのダウンロードおよび展開
1 2 |
$ curl -L -O https://www.openssl.org/source/openssl-1.1.1o.tar.gz $ tar xvfz openssl-1.1.1o.tar.gz |
RPMパッケージをリビルド(作業用サーバ)
RPMパッケージの設定ファイルを編集
「nginx.spec」ファイルを編集して上書き保存します。
1 |
$ vi rpmbuild/SPECS/nginx.spec |
■変更点(1)
opensslの記述がある部分を全てコメントアウトします。
1 2 3 4 5 6 7 8 9 10 11 12 |
...省略... %if (0%{?rhel} == 7) && (0%{?amzn} == 0) %define epoch 1 Epoch: %{epoch} Requires(pre): shadow-utils #Requires: openssl >= 1.0.2 #コメント化して無効にする #BuildRequires: openssl-devel >= 1.0.2 #コメント化して無効にする %define dist .el7 %endif ...省略... |
■変更点(2)※任意で変更
作成されるNginxのバージョンナンバーを確認して必要であれば変更します。
1 2 3 4 5 6 |
...省略... %define base_version 1.22.0 %define base_release 2%{?dist}.ngx #「1%{?dist}.ngx」を「2%{?dist}.ngx」に変更 ...省略... |
■変更点(3)
「 --with-openssl=/home/builder/openssl-1.1.1o」を末尾に追加し、OpenSSL 1.1.1を含めてNginxをリビルドします。
1 2 3 4 5 6 |
...省略... %define BASE_CONFIGURE_ARGS $(echo "--prefix=%{_sysconfdir}/nginx --sbin-path=%{_sbindir}/nginx --modules-path=%{_libdir}/nginx/modules --conf-path=%{_sysconfdir}/nginx/nginx.conf --error-log-path=%{_localstatedir}/log/nginx/error.log --http-log-path=%{_localstatedir}/log/nginx/access.log --pid-path=%{_localstatedir}/run/nginx.pid --lock-path=%{_localstatedir}/run/nginx.lock --http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp --http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp --http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp --http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp --user=%{nginx_user} --group=%{nginx_group} --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-openssl=/home/builder/openssl-1.1.1o") #※"~"内の末尾に「 --with-openssl=/home/builder/openssl-1.1.1o」を追加 ...省略... |
RPMパッケージをリビルド
OpenSSL 1.1.1系を内部に含んだNginxのRPMパッケージをリビルド(再構築)します。
1 |
$ rpmbuild -bb rpmbuild/SPECS/nginx.spec |
結構な時間が掛かりますが、RPMパッケージのリビルド(再構築)が成功すると以下の場所にrpmファイルが作成されます。
「/home/builder/rpmbuild/RPMS/x86_64/nginx-1.22.0-2.el7.ngx.x86_64.rpm」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
...省略... ファイルの処理中: nginx-debuginfo-1.22.0-2.el7.ngx.x86_64 Provides: nginx-debuginfo = 1:1.22.0-2.el7.ngx nginx-debuginfo(x86-64) = 1:1.22.0-2.el7.ngx Requires(rpmlib): rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(CompressedFileNames) <= 3.0.4-1 パッケージに含まれないファイルの検査中: /usr/lib/rpm/check-files /home/builder/rpmbuild/BUILDROOT/nginx-1.22.0-2.el7.ngx.x86_64 書き込み完了: /home/builder/rpmbuild/RPMS/x86_64/nginx-1.22.0-2.el7.ngx.x86_64.rpm 書き込み完了: /home/builder/rpmbuild/RPMS/x86_64/nginx-debuginfo-1.22.0-2.el7.ngx.x86_64.rpm 実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.OpRoZb + umask 022 + cd /home/builder/rpmbuild/BUILD + cd nginx-1.22.0 + /usr/bin/rm -rf /home/builder/rpmbuild/BUILDROOT/nginx-1.22.0-2.el7.ngx.x86_64 + exit 0 [builder@localhost ~]$ |
RPMパッケージをダウンロード
SSHターミナルのSCP機能やSFTP機能等で仮想環境からRPMパッケージ(nginx-1.22.0-2.el7.ngx.x86_64.rpm)をローカルのお好きな場所にダウンロードします。※当方はRLoginを利用しています。
以上で作業用の仮想環境での作業は終了です。
作成した作業用の仮想環境は今後のNginxやOpenSSLのアップデートの際にも使うので、また使えるようにディスクイメージは削除せずに保存しておきましょう。
自作リポジトリを作成(本番環境)
実際にTLS 1.3に対応したNginxを利用するサーバーにSSHで接続します。
まずはじめに、現在利用しているNginxのリポジトリを無効化します。
1 |
# vi /etc/yum.repos.d/nginx.repo |
1 2 3 4 5 |
[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=0 enabled=0 #1を0に変更 |
次に、新しいリポジトリ(orgMyRepo)を作成するのでcreaterepoをインストールします。
1 |
# yum -y install createrepo |
リポジトリ用のPRM配置ディレクトリを作成します。
1 2 |
# mkdir -p /tmp/orgMyRepo # chmod 0757 /tmp/orgMyRepo |
先ほど作成してダウンロードしたTLS 1.3対応済みNginxのRPMファイルをSSHターミナルのSCP機能やSFTP機能等で「/tmp/orgMyRepo」内にアップロードします。
リポジトリを作成します。
1 |
# createrepo /tmp/orgMyRepo |
repoファイルを作成します。
1 |
# vi /etc/yum.repos.d/orgMyRepo.repo |
1 2 3 4 5 |
[orgMyRepo] name=orgMyRepo baseurl=file:///tmp/orgMyRepo gpgcheck=0 enabled=0 |
リポジトリ情報を再読み込みします。
1 |
# yum clean all |
自作リポジトリが完成しました。
yumでNginxをインストール又はアップデート(本番環境)
満を持してNginxをインストールします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# yum --enablerepo=orgMyRepo install nginx 読み込んだプラグイン:fastestmirror, langpacks Determining fastest mirrors * base: ftp.iij.ad.jp * centos-sclo-rh: ftp.iij.ad.jp * centos-sclo-sclo: ftp.iij.ad.jp * extras: ftp.iij.ad.jp * remi-safe: ftp.riken.jp * updates: ftp.iij.ad.jp base | 3.6 kB 00:00:00 centos-sclo-rh | 3.0 kB 00:00:00 centos-sclo-sclo | 3.0 kB 00:00:00 extras | 2.9 kB 00:00:00 mariadb-main | 3.4 kB 00:00:00 mariadb-maxscale | 2.4 kB 00:00:00 mariadb-tools | 2.9 kB 00:00:00 orgMyRepo | 2.9 kB 00:00:00 remi-safe | 3.0 kB 00:00:00 updates | 2.9 kB 00:00:00 virtualmin | 3.6 kB 00:00:00 virtualmin-universal | 3.6 kB 00:00:00 (1/16): base/7/x86_64/group_gz | 153 kB 00:00:00 (2/16): centos-sclo-sclo/x86_64/primary_db | 300 kB 00:00:00 (3/16): extras/7/x86_64/primary_db | 247 kB 00:00:00 (4/16): mariadb-main/7/x86_64/updateinfo | 5.8 kB 00:00:00 (5/16): mariadb-tools/7/x86_64/primary_db | 17 kB 00:00:00 (6/16): base/7/x86_64/primary_db | 6.1 MB 00:00:00 (7/16): centos-sclo-rh/x86_64/primary_db | 3.3 MB 00:00:00 (8/16): mariadb-main/7/x86_64/primary_db | 59 kB 00:00:00 (9/16): orgMyRepo/primary_db | 2.5 kB 00:00:00 (10/16): remi-safe/primary_db | 2.2 MB 00:00:00 (11/16): mariadb-maxscale/7/x86_64/primary_db | 6.9 kB 00:00:00 (12/16): virtualmin/7/x86_64/group_gz | 1.3 kB 00:00:00 (13/16): updates/7/x86_64/primary_db | 16 MB 00:00:00 (14/16): virtualmin-universal/group_gz | 456 B 00:00:00 (15/16): virtualmin/7/x86_64/primary_db | 27 kB 00:00:00 (16/16): virtualmin-universal/primary_db | 26 kB 00:00:00 依存性の解決をしています --> トランザクションの確認を実行しています。 ---> パッケージ nginx.x86_64 1:1.18.0-3.el7.ngx を 更新 ---> パッケージ nginx.x86_64 1:1.22.0-2.el7.ngx を アップデート --> 依存性解決を終了しました。 依存性を解決しました ============================================================================================== Package アーキテクチャー バージョン リポジトリー 容量 ============================================================================================== 更新します: nginx x86_64 1:1.22.0-2.el7.ngx orgMyRepo 3.6 M トランザクションの要約 ============================================================================================== 更新 1 パッケージ 総ダウンロード容量: 3.6 M Is this ok [y/d/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction 更新します : 1:nginx-1.22.0-2.el7.ngx.x86_64 1/2 警告: /etc/nginx/nginx.conf は /etc/nginx/nginx.conf.rpmnew として作成されました。 整理中 : 1:nginx-1.18.0-3.el7.ngx.x86_64 2/2 検証中 : 1:nginx-1.22.0-2.el7.ngx.x86_64 1/2 検証中 : 1:nginx-1.18.0-3.el7.ngx.x86_64 2/2 更新: nginx.x86_64 1:1.22.0-2.el7.ngx 完了しました! |
インストールが完了しました。
Nginxの設定ファイル変更(本番環境)
ssl_protocolsに「TLSv1.3」を追加し、ssl_ciphersの先頭に以下の3つの暗号スイートを追加します。
- TLS-AES-256-GCM-SHA384
- TLS-CHACHA20-POLY1305-SHA256
- TLS-AES-128-GCM-SHA256
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
server { server_name onoredekaiketsu.com; ...省略... listen 150.95.212.180:443 ssl http2 default_server; ssl_protocols TLSv1.2 TLSv1.3; #TLSv1.3を追加 ssl_prefer_server_ciphers on; ssl_ciphers "TLS-AES-256-GCM-SHA384:TLS-CHACHA20-POLY1305-SHA256:TLS-AES-128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"; ssl_certificate /etc/letsencrypt/live/onoredekaiketsu.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/onoredekaiketsu.com/privkey.pem; ssl_dhparam /etc/nginx/ssl/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/onoredekaiketsu.com/fullchain.pem; resolver 8.8.8.8; add_header Strict-Transport-Security 'max-age=31536000; includeSubonoredekaiketsu.coms;'; } |
Nginxを再起動します。
1 2 |
# systemctl restart nginx # systemctl restart php-fpm |
ブラウザで動作確認
全ての変更が終わったのでChromeのデベロッパーツールで動作確認します。
ちゃんとTLS 1.3になってますね。
SSL Server Testも実行してみます。
SSL Test – SSL Server Test (Powered by Qualys SSL Labs)
https://www.ssllabs.com/ssltest/
■SSL Testのスコア
■プロトコルとCipher Suites
問題ありません。
おまけ(NginxやOpenSSLのアップデートが公開された場合)
NginxやOpenSSLのアップデートが公開されたときの作業内容を説明します。
まず、今回利用した作業用仮想環境を立ち上げてSSHでログインし、yum updateを実行して環境を最新にします。
その後のRPMパッケージのリビルド作業は、「su builder -」で作業用ユーザーに変更(スイッチ)するところからは今回と全く同じです。最新バージョンのNginxまたはOpenSSLをダウンロードして設定ファイルを書き換えてリビルドしてください。
リビルドが完了したら新しいRPMファイルをダウンロードし、本番サーバーにSSH接続して「/tmp/orgMyRepo」にその新RPMファイルをアップロードします。
次のステップだけ少々違います。
既にorgMyRepoリポジトリは作成されているので、今回はcreaterepoの「--update」オプションで更新してリポジトリ情報を再読み込みします。
1 2 |
# createrepo --update /tmp/orgMyRepo/ # yum clean all |
あとは通常のyumでアップデートが可能です。
1 |
# yum --enablerepo=orgMyRepo install nginx |
まとめ
CentOS 7用のRPMパッケージをリビルドしてNginxをTLS 1.3に対応させることができました。
Nginxをアップデートする際は、今回作成した作業用の仮想環境でまた同じ処理を行って自作リポジトリにアップするだけ良いので、今後もyumで簡単にパッケージ管理ができてメンテナンスも楽です。
以上で解決です。