CentOS7のNginxをTLS1.3に対応させてyumでインストールする

CentOS7のNginxをTLS1.3に対応させてyumでインストールする サーバー

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で簡単に管理できる。

というわけで、以下の手順で行っていきます。

  1. 現在のNginxのバージョンをチェック
  2. 作業用の仮想環境作成
  3. 必要パッケージのインストール
  4. CentOS 7用のNginxのPRMパッケージとOpenSSL 1.1.1をゲット
  5. RPMパッケージをOpenSSL 1.1.1に対応させてリビルド
  6. 自作リポジトリを作成してRPMパッケージを設置
  7. 自作リポジトリからyumでNginxをインストール(又はアップデート)
  8. Nginxの設定(TLS 1.3有効化や暗号スイート等の設定)
  9. 動作確認

現在のNginxのバージョンをチェック

TLS 1.3に対応させたいサーバにSSHで接続します。
そして以下のコマンドで現在のNginxのバージョンを確認しておいてください。

# 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です。)

以下の手順でサクッと仮想環境を作成します。

  1. VirtualBoxのインストール
  2. VirtualBoxの「新規」→「仮想マシンの作成」でウィザードに従ってCentOS 7のMinimal ISOから最小インストール
  3. 仮想マシンの「ネットワーク」の設定で、標準のNATの他にホストオンリーアダプターも追加して有効化
  4. 「ip addr」でIPアドレスを確認してSSHでログイン
  5. 「yum update」でアップデートして最新にする。

※詳しい手順は以下のページで解説していますのでご利用ください。

必要パッケージのインストール(作業用サーバ)

作業用サーバが完成したら、作業に必要な基本的なパッケージをインストールします。

# yum -y install redhat-lsb-core zlib-devel pcre-devel pcre2-devel gcc epel-release

epelリポジトリのenabledを0に変更

# vi /etc/yum.repos.d/epel.repo
[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から必要なパッケージをインストールします。

# yum -y --enablerepo=epel install rpm-build zlib-devel pcre-devel perl-devel perl-ExtUtils-Embed GeoIP-devel libxslt-devel gd-devel

「Development Tools」をグループインストールします。

# yum -y --enablerepo=epel groupinstall "Development Tools"

最新のNginxとOpenSSLをゲット(作業用サーバ)

作業用ユーザー作成

まず、作業用のユーザーを作成します。

# useradd builder

作業用ユーザーに変更(スイッチ)します。

# su builder -

作業用のディレクトリを設定します。

$ 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のダウンロードおよびインストール

$ 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のダウンロードおよび展開

$ 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」ファイルを編集して上書き保存します。

$ vi rpmbuild/SPECS/nginx.spec

■変更点(1)
opensslの記述がある部分を全てコメントアウトします。

...省略...

 %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のバージョンナンバーを確認して必要であれば変更します。

...省略...

 %define base_version 1.22.0
 %define base_release 2%{?dist}.ngx #「1%{?dist}.ngx」を「2%{?dist}.ngx」に変更

...省略...
「2%{?dist}.ngx」のはじめの数字ですが、一番はじめに調べた現在のNginxのバージョンが「nginx-1.22.0-1.el7.ngx.src.rpm」だったので、リビルド時にこの末尾の数字を1つカウントアップして「2」にすることにより「nginx-1.22.0-2.el7.ngx.src.rpm」というパッケージが新規作成されてパッケージ名の重複を防ぎ、更に新しいバージョンのパッケージとして認識されるのでyumでアップデートが出来るようになります。

■変更点(3)
--with-openssl=/home/builder/openssl-1.1.1o」を末尾に追加し、OpenSSL 1.1.1を含めてNginxをリビルドします。

...省略...

 %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パッケージをリビルド(再構築)します。

$ rpmbuild -bb rpmbuild/SPECS/nginx.spec

結構な時間が掛かりますが、RPMパッケージのリビルド(再構築)が成功すると以下の場所にrpmファイルが作成されます。

/home/builder/rpmbuild/RPMS/x86_64/nginx-1.22.0-2.el7.ngx.x86_64.rpm

...省略...

ファイルの処理中: 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を利用しています。

SSHのSFTP機能でNginxのRPMファイルをダウンロード

以上で作業用の仮想環境での作業は終了です。

作成した作業用の仮想環境は今後のNginxやOpenSSLのアップデートの際にも使うので、また使えるようにディスクイメージは削除せずに保存しておきましょう。

自作リポジトリを作成(本番環境)

実際にTLS 1.3に対応したNginxを利用するサーバーにSSHで接続します。

まずはじめに、現在利用しているNginxのリポジトリを無効化します。

# vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=0 #1を0に変更

次に、新しいリポジトリ(orgMyRepo)を作成するのでcreaterepoをインストールします。

# yum -y install createrepo

リポジトリ用のPRM配置ディレクトリを作成します。

# mkdir -p /tmp/orgMyRepo
# chmod 0757 /tmp/orgMyRepo

先ほど作成してダウンロードしたTLS 1.3対応済みNginxのRPMファイルをSSHターミナルのSCP機能やSFTP機能等で「/tmp/orgMyRepo」内にアップロードします。

SSHのSFTP機能でNginxのRPMファイルをアップロード

リポジトリを作成します。

# createrepo /tmp/orgMyRepo

repoファイルを作成します。

# vi /etc/yum.repos.d/orgMyRepo.repo
[orgMyRepo]
name=orgMyRepo
baseurl=file:///tmp/orgMyRepo
gpgcheck=0
enabled=0

リポジトリ情報を再読み込みします。

# yum clean all

自作リポジトリが完成しました。

yumでNginxをインストール又はアップデート(本番環境)

満を持してNginxをインストールします。

# 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
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を再起動します。

# systemctl restart nginx
# systemctl restart php-fpm

ブラウザで動作確認

全ての変更が終わったのでChromeのデベロッパーツールで動作確認します。

デベロッパーツールでTLS1.3を確認

ちゃんとTLS 1.3になってますね。

SSL Server Testも実行してみます。

SSL Test – SSL Server Test (Powered by Qualys SSL Labs)
https://www.ssllabs.com/ssltest/

SSL LabsのSSL Checkを実行(1)

■SSL Testのスコア

SSL LabsのSSL Checkを実行(2)

■プロトコルとCipher Suites

SSL CheckのプロトコルとCipher Suites

問題ありません。

おまけ(NginxやOpenSSLのアップデートが公開された場合)

NginxやOpenSSLのアップデートが公開されたときの作業内容を説明します。

まず、今回利用した作業用仮想環境を立ち上げてSSHでログインし、yum updateを実行して環境を最新にします。

その後のRPMパッケージのリビルド作業は、「su builder -」で作業用ユーザーに変更(スイッチ)するところからは今回と全く同じです。最新バージョンのNginxまたはOpenSSLをダウンロードして設定ファイルを書き換えてリビルドしてください。

リビルドが完了したら新しいRPMファイルをダウンロードし、本番サーバーにSSH接続して「/tmp/orgMyRepo」にその新RPMファイルをアップロードします。

次のステップだけ少々違います。
既にorgMyRepoリポジトリは作成されているので、今回はcreaterepoの「--update」オプションで更新してリポジトリ情報を再読み込みします。

# createrepo --update /tmp/orgMyRepo/
# yum clean all

あとは通常のyumでアップデートが可能です。

# yum --enablerepo=orgMyRepo install nginx

まとめ

CentOS 7用のRPMパッケージをリビルドしてNginxをTLS 1.3に対応させることができました。

Nginxをアップデートする際は、今回作成した作業用の仮想環境でまた同じ処理を行って自作リポジトリにアップするだけ良いので、今後もyumで簡単にパッケージ管理ができてメンテナンスも楽です。

以上で解決です。

タイトルとURLをコピーしました