無料サーバー証明書の導入
無料のサーバー証明書がLet's Encryptから発行できるので試してみました。ただし、固定グローバルIPアドレスのサーバーは用意できないので、外部公開はダイナミックDNSサービスを使用します。
CentOS7のインストール
以前の記事を参考に設定します。今回もインストールメディアは、CentOS7(7.7.1908)を使用します。
インストール設定は、以下のとおりです。
- インストール時に使用する言語 : 日本語
- 日付と時刻 : アジア/東京 タイムゾーン
- キーボード : 日本語
- 言語サポート : 日本語(日本)
- インストールソース : ローカルメディア
- ソフトウェアの選択 : 最小限のインストール
- インストール先 : パーティションを自動構成
- KDUMP : 有効
- ネットワークとホスト名 : 未設定
- SECURITY PROFILE : 未設定
- ユーザーの作成 : ユーザーを作成(管理者権限は付与しない)
OSインストール後の設定
OSインストール後の設定は、以下のとおりです。
SELinuxとFirewallを無効に設定
# setenforce 0 # vi /etc/sysconfig/selinux SELINUX=disabled # systemctl stop firewalld # systemctl disable firewalld
システム設定の変更
システム設定を変更します。
CTRL-ALT-DELでの再起動を抑止します。 # systemctl mask ctrl-alt-del.target Created symlink from /etc/systemd/system/ctrl-alt-del.target to /dev/null. 連続でCTRL-ALT-DELを押し続けた時の再起動を抑止します。 # vi /etc/systemd/system.conf [Manager] CtrlAltDelBurstAction=none 抑止設定を反映させます。 # systemctl daemon-reexec messagesログを確認しながら、CTRL-ALT-DELキーを連続で押し続けて、再起動が発生しないことを確認します。 ※systemdのバージョンが223以降でないと抑止設定は反映されません。 # tail -f /var/log/messages
ネットワーク設定
IPアドレスなどを設定します。
ホスト名とIPアドレスを設定します。 # nmtui ※プロンプトのホスト名は、再ログイン時に更新されます。 pingで外部との疎通を確認します。 # ping www.yahoo.co.jp
パッケージの追加とシステムの更新
外部との接続が確認できたので、パッケージの追加とシステムの更新をおこないます。
必要と思うパッケージをインストールします。 # yum install bash-completion net-tools システムを更新します。 # yum update ※kernelも最新のバージョンに更新します。
不要なログ出力を抑止
/var/log/messages
に出力するログを減らすように修正します。
不要な設定をコメントアウトします。 # vi /usr/lib/systemd/system/firstboot-graphical.service #SysVStartPriority=99
CentOS7のmdadm-4.1-4
には不具合があるので、CentOS8のmdadm4-1.13
を参考に設定ファイルを修正します。
設定ファイルを修正します。 # vi /usr/lib/systemd/system/mdcheck_start.timer #OnCalendar=Sun *-*-1..7 1:00:00 OnCalendar=Sun *-*-1,2,3,4,5,6,7 1:00:00 # vi /usr/lib/systemd/system/mdcheck_start.service #Environment= MDADM_CHECK_DURATION="6 hours" Environment="MDADM_CHECK_DURATION=6 hours" # vi /usr/lib/systemd/system/mdcheck_continue.service #Environment= MDADM_CHECK_DURATION="6 hours" Environment="MDADM_CHECK_DURATION=6 hours"
使用しないパッケージを削除して、ログ出力を減らします。
指紋認証デーモンの削除 # yum remove fprintd
Webサーバーのセットアップ
Webサーバー(Apache 2.4)をインストールします。
インストール可能なパッケージグループを確認します。 # yum grouplist 環境構築に必要なパッケージをインストールします。 # yum groupinstall "Server with GUI" # yum groupinstall "Basic Web Server" Webサービスを開始します。 # systemctl enable httpd # systemctl start httpd
システムの再起動
起動モードを変更して、再起動します。
デフォルトの起動モードをGUIに変更して、再起動します。 # systemctl set-default graphical.target # reboot
GUI環境の設定
GUI環境の設定は、以下のとおりです。
- 言語 : 日本語
- 入力 : 日本語(かな漢字)
- 位置情報サービス : オン
- オンラインアカウント : スキップ
Firefoxでhttp://localhost/
にアクセスして、Webサービスが稼働していることを確認します。
ポートフォワード設定
ルーターにポートフォワード設定を追加して、外部からWebサーバーにアクセスできるようにします。
ポートフォワード設定方法は、ルーターの機種によって異なるので割愛しますが、設定内容は以下のとおりです。
転送先IPアドレス | プロトコル | ポート範囲 |
---|---|---|
Webサーバーに設定したIPアドレス | TCP | 80 - 80 |
Webサーバーに設定したIPアドレス | TCP | 443 - 443 |
ダイナミックDNSサービスの設定とアクセス確認
ダイナミックDNSサービスは、無料で使用できるMyDNS.JPを選びました。
ダイナミックDNSサービスの初期登録
手順の詳細は割愛しますが、以下の作業をおこないました。
- 新規利用なので、ユーザー登録をおこないます。
- ルーターWAN側に割り当てられているグローバルIPアドレスを、取得したドメイン名に登録します。
グローバルIPアドレスは、MyDNS.JPサイトのトップページ(赤枠部分)から確認できます。
ドメイン情報を登録します。
Webサーバーの設定変更
ダイナミックDNSサービスで設定したホスト名をhttpd.conf
に設定します。
ホスト名を設定します。 # vi /etc/httpd/conf/httpd.conf ServerName www.xxxxx.mydns.jp 設定ファイルを再読み込みします。 # systemctl reload httpd
外部からのアクセス確認
スマホ(キャリア回線)から、取得したホスト名にHTTPおよびHTTPSでアクセスできることを確認します。
HTTPでアクセスできることを確認します。
HTTPSでアクセスできることを確認します。ただし、正しいサーバー証明書がインストールされていないので、警告が表示されます。
ダイナミックDNSサービスへのIPアドレス自動登録
フリーソフトのDiCEを使用して、ダイナミックDNSサービスにIPアドレスを自動登録するように設定します。
DiCEのインストール
ダウンロードしたDiCEを展開します。 # tar xvzf ./diced01914.tar.gz # cp ./DiCE/ /opt/ -r # rm ./DiCE -rf DiCEを動作させるのに必要な32bitパッケージをインストールします。 # yum install libstdc++ # yum install libstdc++.i686 DiCEの日本語文字化け対策にnkfパッケージをインストールします。 # yum install epel-release # yum install nkf
IPアドレスの検出方法と更新間隔の設定
# /opt/DiCE/diced | nkf -uw =-=-=- DiCE DynamicDNS Client -=-=-= Version 0.19 for Japanese Copyright(c) 2001 sarad :setup IPアドレスの検出方法を指定してください (0) 自動検出 (1) ローカルのネットワークアダプタから検出 (2) 外部のスクリプトから検出 <現在:0> (N)変更しない (P)戻る >2 ------------------------------------------------- スクリプトのURLを入力してください <現在:> (N)変更しない (P)戻る >http://info.ddo.jp/remote_addr.php ------------------------------------------------- プライベートIPアドレスも検出対象ですか? (Y/N) <現在:いいえ> (P)戻る >n ------------------------------------------------- IPアドレスの検出をテストしますか? (Y/N) (P)戻る >y 検出IPアドレス>xxx.xxx.xxx.249 ------------------------------------------------- IPアドレスの検出をテストしますか? (Y/N) (P)戻る >n ------------------------------------------------- IPアドレスをチェックする間隔を指定してください(分) 設定可能範囲は5分以上です <現在:10> (N)変更しない (P)戻る >n ================================================= DNSサーバーの負荷を軽減するために頻繁なDNS更新を防ぐ必要があります 前回の更新から一定時間DNS更新処理を行わないように保護時間を設定して ください(分) 設定可能範囲は10分から1440分です <現在:60> (N)変更しない (P)戻る >20 ================================================= 設定を保存しますか? (Y/N) (P)戻る >y 設定を保存しました ================================================= :
続いて、使用するダイナミックDNSサービスと更新間隔を設定します。
:add 新しくイベントを追加します DynamicDNSサービス名を入力してください "?"で対応しているサービスを一覧表示します (P)戻る >MyDNS.JP ------------------------------------------------- << MyDNS.JP >> URL: http://www.mydns.jp/ *** 情報 *** ドメイン名、ホスト名についてはマスターID(ユーザー名)にて管理されています。 IPアドレスはサーバー側で自動検出します。 (これらは入力しても無視されます) ================================================= ドメイン名を入力してください "?"でドメイン一覧を表示します (P)戻る >xxxxx.mydns.jp ※マスターIDにて管理されているので、入力しても無視されます。 ================================================= ホスト名を入力してください (P)戻る >www ※マスターIDにて管理されているので、入力しても無視されます。 ================================================= ログインユーザ名を入力してください (P)戻る >mydnsxxxxxx ================================================= ログインパスワードを入力してください (P)戻る >xxxxxxxxxxx ================================================= 登録するIPアドレスを入力してください 空白にすると現在のIPアドレスを自動検出します (P)戻る > ================================================= このイベントに題名を付けてください (P)戻る >Update_MyDNS.JP ================================================= このイベントを実行するスケジュールを設定します ------------------------------------------------- 実行する頻度を指定してください (番号入力) (0)1回のみ (1)1日1回 (2)1週間に1回 (3)1ヵ月に1回 (4)その他の周期 (5)IPアドレス変化時 (6)起動時 (P)戻る >5 ------------------------------------------------- IPアドレスがあまり変化しない環境の場合、更新せずに一定期間を過ぎると アカウントを削除されてしまうことがあります IPアドレスの変化が無い時に実行する間隔を指定してください (0)7日毎 (1)14日毎 (2)21日毎 (3)28日毎 (4)35日毎 (5)56日毎 (6)84日毎 (P)戻る >1 ================================================= ================================================= このイベントを有効にしますか? (Y/N) (イベントの有効/無効は"EN/DIS"コマンドで切替えられます) >y ================================================= イベントを保存しますか? (Y/N) >y イベント"Update_MyDNS.JP"を保存しました ================================================= :
更新イベントを実行して、正常に動作することを確認します。
:ex 0 + xx/xx xx:xx にUpdate_MyDNS.JPが実行されました IPアドレスを更新しました :exit #
DiCEをサービスとして登録
DiCEをサービスとして登録します。設定ファイルについては、こちらを参考にしました。
DiCEのサービス用設定ファイルを作成します。 # vi /usr/lib/systemd/system/dice.service [Unit] Description=The DiCE Server After=network.target remote-fs.target nss-lookup.target [Service] Type=simple ExecStart=/opt/DiCE/diced -s -l ExecReload=/bin/kill -HUP ${MAINPID} ExecStop=/bin/kill ${MAINPID} PrivateTmp=true [Install] WantedBy=multi-user.target 設定ファイルの再読み込みをおこないます。 # systemctl daemon-reload システム起動時に自動起動するように設定します。 # systemctl enable dice.service サービスを開始します。 # systemctl start dice.service
サーバー証明書の導入
Let's Encrpytからサーバー証明書を発行します。手順については、こちらを参考にしました。
必要なパッケージのインストール
サーバー証明書の発行に必要なパッケージをインストールします。
EPELリポジトリを追加して、必要なパッケージをインストールします。 # yum install epel-release # yum install certbot python-certbot-apache
サーバー証明書の発行
DocumentRootのパスは、デフォルトの/var/www/html/
とします。
certbot
コマンドについては、こちらを参照してください。
ドメイン名とホスト名用のサーバー証明書を作成します。 # certbot certonly --webroot -w /var/www/html/ -d xxxxx.mydns.jp -d www.xxxxx.mydns.jp \ --agree-tos -m (連絡先メールアドレス) Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: n ※初回のみ表示 Obtaining a new certificate Performing the following challenges: http-01 challenge for xxxxx.mydns.jp http-01 challenge for www.xxxxx.mydns.jp Using the webroot path /var/www/html for all unmatched domains. Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/xxxxx.mydns.jp/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/xxxxx.mydns.jp/privkey.pem Your cert will expire on 2020-xx-xx. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le #
発行されたサーバー証明書を確認します。
# ls -l /etc/letsencrypt/live/xxxxx.mydns.jp/ 合計 4 -rw-r--r-- 1 root root 692 xx月 xx xx:xx README lrwxrwxrwx 1 root root 41 xx月 xx xx:xx cert.pem -> ../../archive/xxxxx.mydns.jp/cert1.pem lrwxrwxrwx 1 root root 42 xx月 xx xx:xx chain.pem -> ../../archive/xxxxx.mydns.jp/chain1.pem lrwxrwxrwx 1 root root 46 xx月 xx xx:xx fullchain.pem -> ../../archive/xxxxx.mydns.jp/fullchain1.pem lrwxrwxrwx 1 root root 44 xx月 xx xx:Xx privkey.pem -> ../../archive/xxxxx.mydns.jp/privkey1.pem
SSL設定の変更
発行されたサーバー証明書を使用するように設定を変更します。
# vi /etc/httpd/conf.d/ssl.conf デフォルトの設定を変更します。 SSLCertificateFile /etc/letsencrypt/live/xxxxx.mydns.jp/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/xxxxx.mydns.jp/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/xxxxx.mydns.jp/chain.pem
設定ファイルを再読み込みします。
# systemctl reload httpd
外部からのHTTPSアクセスの確認
警告が表示されないので、サーバー証明書に問題がないことが確認できます。
サーバー証明書の更新
Let’s Encryptから発行したサーバー証明書の有効期限が90日なので、定期的に更新をおこなうようにスケジュールを設定します。
サーバー証明書の更新テスト
スケジュールを設定する前に、--dry-run
オプションを指定して、サーバー証明書の更新に問題がないかテストします。
# certbot renew --dry-run (省略) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: ※テスト成功 /etc/letsencrypt/live/xxxxx.mydns.jp/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (省略)
更新テストに問題がないことが確認できました。
更新スクリプトの設定
サーバー証明書の更新は、certbot
パッケージのスクリプトを使用して更新スケジュールを設定します。
certbotパッケージの内容を確認します。 # rpm -ql certbot (省略) /usr/lib/systemd/system/certbot-renew.service /usr/lib/systemd/system/certbot-renew.timer (省略)
certbot-renew.timer
の内容を確認します。
# cat /usr/lib/systemd/system/certbot-renew.timer [Unit] Description=This is the timer to set the schedule for automated renewals [Timer] OnCalendar=*-*-* 00/12:00:00 RandomizedDelaySec=12hours Persistent=true [Install] WantedBy=timers.target 0時と12時に実行(最大12時間のランダムな遅延)するよう設定されています。
certbot-renew.service
の内容を確認します。
# cat /usr/lib/systemd/system/certbot-renew.service [Unit] Description=This service automatically renews any certbot certificates found [Service] EnvironmentFile=/etc/sysconfig/certbot Type=oneshot ExecStart=/usr/bin/certbot renew --noninteractive --no-random-sleep-on-renew $PRE_HOOK $POST_HOOK $RENEW_HOOK $DEPLOY_HOOK $CERTBOT_ARGS ExecStartに設定したコマンドを一度だけ実行(Type=oneshot)するように設定されています。
サーバー証明書の更新が成功した時の動作を/etc/sysconfig/certbot
に設定します。こちらを参考にしました。
# vi /etc/sysconfig/certbot サーバー証明書の更新が成功した時に実行するコマンドを設定します。 DEPLOY_HOOK="--post-hook 'systemctl reload httpd'"
更新スケジュールの設定
更新スケジュールを設定します。
有効なsystemdタイマー(スケジュール)を確認します。 # systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES x 2020-xx-xx 00:00:00 JST 6h left x 2020-xx-xx 00:48:21 JST 16h ago unbound-anchor.timer unbound-anchor.service x 2020-xx-xx 01:03:10 JST 7h left x 2020-xx-xx 01:03:10 JST 16h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service 2 timers listed. Pass --all to see loaded but inactive timers, too. システム起動時にcertbot-renew.timerが起動するように設定します。 # systemctl enable certbot-renew.timer Created symlink from /etc/systemd/system/timers.target.wants/certbot-renew.timer to /usr/lib/systemd/system/certbot-renew.timer. certbot-renew.timerを開始します。 # systemctl start certbot-renew.timer certbot-renew.timerがスケジュールに登録されたことを確認します。 # systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES X 2020-xx-xx 00:00:00 JST 6h left X 2020-xx-xx 00:48:21 JST 17h ago unbound-anchor.timer unbound-anchor.service X 2020-xx-xx 01:03:10 JST 7h left X 2020-xx-xx 01:03:10 JST 16h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service X 2020-xx-xx xx:xx:xx JST 12h left n/a n/a certbot-renew.timer certbot-renew.service 3 timers listed. Pass --all to see loaded but inactive timers, too.
スケジュールの実行と確認
スケジュールから呼び出すサービスを手動実行して、サーバー証明書を更新します。
サーバー証明書の有効期限まで30日以上残っていると更新されないので、一時的に更新を強制する設定にします。
# vi /etc/sysconfig/certbot CERTBOT_ARGS="--force-renewal"
実行前に、現在のサーバー証明書の有効期間を確認しておきます。
certbot-renew.timer
が呼び出すcertbot-renew.service
サービスを手動で実行します。
# systemctl start certbot-renew.service 実行後、ログを確認します。 # tail /var/log/messages -n 30 (省略) xxx x xx:xx:xx xxxxx systemd: Starting This service automatically renews any certbot certificates found... xxx x xx:xx:xx xxxxx certbot: Saving debug log to /var/log/letsencrypt/letsencrypt.log xxx x xx:xx:xx xxxxx certbot: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xxx x xx:xx:xx xxxxx certbot: Processing /etc/letsencrypt/renewal/xxxxx.mydns.jp.conf xxx x xx:xx:xx xxxxx certbot: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xxx x xx:xx:xx xxxxx certbot: Plugins selected: Authenticator webroot, Installer None xxx x xx:xx:xx xxxxx certbot: Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org xxx x xx:xx:xx xxxxx certbot: Renewing an existing certificate xxx x xx:xx:xx xxxxx certbot: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xxx x xx:xx:xx xxxxx certbot: new certificate deployed without reload, fullchain is xxx x xx:xx:xx xxxxx certbot: /etc/letsencrypt/live/xxxxx.mydns.jp/fullchain.pem xxx x xx:xx:xx xxxxx certbot: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xxx x xx:xx:xx xxxxx certbot: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xxx x xx:xx:xx xxxxx certbot: Congratulations, all renewals succeeded. The following certs have been renewed: xxx x xx:xx:xx xxxxx certbot: /etc/letsencrypt/live/xxxxx.mydns.jp/fullchain.pem (success) xxx x xx:xx:xx xxxxx certbot: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xxx x xx:xx:xx xxxxx certbot: Running post-hook command: systemctl reload httpd xxx x xx:xx:xx xxxxx systemd: Reloading The Apache HTTP Server. xxx x xx:xx:xx xxxxx systemd: Reloaded The Apache HTTP Server. xxx x xx:xx:xx xxxxx systemd: Started This service automatically renews any certbot certificates found. 問題なく完了できたことが確認できます。
一時的な設定変更を元に戻します。
# vi /etc/sysconfig/certbot CERTBOT_ARGS=""
サーバー証明書が更新されたことを確認します。
常時SSL化(HTTPSへのリダイレクト)
サーバー証明書が利用できるようになったので、こちらを参考にして、HTTPSにリダイレクトするように設定します。
httpd.conf
の末尾に、以下のように追記して、設定ファイルを再読み込みします。
# vi /etc/httpd/conf/httpd.conf RewriteEngine on RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # systemctl reload httpd
サイトにアクセスして、リダイレクトが成功していることを確認します。