らくがきちょう

なんとなく ~所属組織/団体とは無関係であり、個人の見解です~

Apache や Nginx に SSL/TLS 設定をする

今回は Amazon LinuxCentOSApache や Nginx をインストールし、SSL/TLS サーバ証明書を設定する手順をメモしておきます。 尚、SELinux や firewalld は無効化されている前提です。

証明書の用意

証明書を保存するディレクトリを作成しておきます。

mkdir -p /etc/letsencrypt/certificates/

ディレクトリを作成したら、このディレクトリに Let's Encrypt から発行された証明書 (.crt ファイル) と秘密鍵 (.key ファイル) をコピーしておきます。 証明書と秘密鍵パーミッションとオーナーを変更しておきます。

chmod 600 /etc/letsencrypt/certificates/*
chown root:root /etc/letsencrypt/certificates/*

Apache のインストール

ここでは Apache をインストールします。

標準リポジトリからインストール

AWSCentOS の標準リポジトリから yum でインストールします。

yum -y install httpd mod_ssl

証明書の設定

デフォルトで SSL/TLS 関連の設定は /etc/httpd/conf.d/ssl.conf に定義があります。 このファイルを以下のように修正します。

変更前

SSLCertificateFileSSLCertificateKeyFile の定義部分を探します。

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

変更後

これを以下のように、Let's Encrypt で取得した証明書を参照するように書き換えます。

SSLCertificateFile /etc/letsencrypt/certificates/example.com.crt
SSLCertificateKeyFile /etc/letsencrypt/certificates/example.com.key

起動&自動起動の設定

これで設定は完了で Apache の起動&自動起動設定を実施します。

systemctl enable httpd
systemctl start httpd

これで Apache のインストールは完了です。

Nginx のインストール

ここでは Nginx をインストールします。

Nginx 公式リポジトリからインストール

Nginx 公式の Mainline リポジトリからインストールします。 下記を実行し、Nginx 公式リポジトリを追加します。

cat << EOF > /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
EOF

yum で Nginx をインストールします。

yum -y install nginx

証明書の設定

Nginx の設定ファイルは /etc/nginx/conf.d/default.conf に存在します。 このファイルに SSL/TLS 設定を追加しても良いのですが、今回は別ファイルを用意します。 以下のように設定します。

cat << EOF > /etc/nginx/conf.d/https.conf
server {
    listen              443 ssl http2;
    server_name         www.example.com;
    ssl_certificate     /etc/letsencrypt/certificates/example.com.crt;
    ssl_certificate_key /etc/letsencrypt/certificates/example.com.key;
    ssl_protocols       TLSv1.1 TLSv1.2;
    ssl_ciphers         'ECDH !aNULL !eNULL !SSLv2 !SSLv3';

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
EOF

起動&自動起動の設定

これで設定は完了で Nginx の起動&自動起動設定を実施します。

systemctl enable nginx
systemctl start nginx

これで Nginx のインストールは完了です。

OpenSSL での接続テスト

OpenSSL を使って CLI から HTTPS 接続をテストするには以下のように実行します。

openssl s_client -connect www.example.com:443 -showcerts < /dev/null

実行例は以下の通りです。

# openssl s_client -connect www.google.com:443 -showcerts < /dev/null
CONNECTED(00000004)
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
   i:C = US, O = Google Trust Services, CN = GTS CA 1O1
-----BEGIN CERTIFICATE-----
MIIEwDCCA6igAwIBAgIRAITFhItHl+5WCAAAAAAXx6gwDQYJKoZIhvcNAQELBQAw
QjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczET
MBEGA1UEAxMKR1RTIENBIDFPMTAeFw0xOTEwMDMxNzE0MDdaFw0xOTEyMjYxNzE0
MDdaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH
Ew1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgTExDMRcwFQYDVQQDEw53
d3cuZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKOwUK22spMj
TuquPnf22ztMOF1HDGvi5kkuPpkvRQiyGZqpqmFR0Pke60mB7tayG4cb5uvBZ6n8
jVrHGuUixCWjggJUMIICUDAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYB
BQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU9AWZ0osJwSfXST/+HKjEIhKo
PT4wHwYDVR0jBBgwFoAUmNH4bhDrz5vsYJ8YkBug630J/SswZAYIKwYBBQUHAQEE
WDBWMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHMxbzEwKwYI
KwYBBQUHMAKGH2h0dHA6Ly9wa2kuZ29vZy9nc3IyL0dUUzFPMS5jcnQwGQYDVR0R
BBIwEIIOd3d3Lmdvb2dsZS5jb20wIQYDVR0gBBowGDAIBgZngQwBAgIwDAYKKwYB
BAHWeQIFAzAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLnBraS5nb29nL0dU
UzFPMS5jcmwwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdwBj8tvN6DvMLM8LcoQn
V2szpI1hd4+9daY4scdoVEvYjQAAAW2S1EW1AAAEAwBIMEYCIQCuYA0RQtvnYx8k
WSQRk4cdQP7F2ohtOXFxa2nnX3tj3wIhAOImFU6vxngmuhGQ8+rzeekgPOLhhaLw
ozqfx+4HJt1VAHUAdH7agzGtMxCRIZzOJU9CcMK//V5CIAjGNzV55hB7zFYAAAFt
ktRF3wAABAMARjBEAiBzvswHoLBaDJRyCbXK4T0Jqrw2LXOkPXaqbLSGjBa6kQIg
YxBL5oYoOWeGdCnMlaYn3jz8xvZ5MJvTWFiRIuUMx4kwDQYJKoZIhvcNAQELBQAD
ggEBAKobaqzX6fGEb3sFMqKSyeLxN2VPpR6dHpXaRdDiCbUlLHU++d1xkl3idCMA
L+ijpzuKe3GTsMySelJE/YbVgGb6dCFisZzB42HS0922gLWzkNAV8AbJO50O00FC
O1GWBxWkFOo31VWVS33CGYt6f2LmYNl2OfPsGIteme9j95dq/tAeAOsZ79dNFfCK
dljfzM9/HxJu/frXC60PKx8MGkm49D2hP4tew5OxpZvdEqu5q9Yeam9WIN05cWTB
LyJxktrHqeTyqgPwViq5gYTRitFt1JW/4ZLaOO4LARTNgtTdGNHQcuMNfHWqAp5f
gM/VHrkxReg13XSmNJpAFXf3Z58=
-----END CERTIFICATE-----
 1 s:C = US, O = Google Trust Services, CN = GTS CA 1O1
   i:OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
-----BEGIN CERTIFICATE-----
MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw
HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs
U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy
MTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg
U2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnv
UA0Qk28FgICfKqC9EksC4T2fWBYk/jCfC3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRr
mBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++Ac
xGNhr59qM/9il71I2dN8FGfcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmK
FsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7X
rJfoucBZEqFJJSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNV
HQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1Ud
EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8G
A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkwJzAl
BggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzAp
MCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0g
BDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9y
ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAGoA+Nnn78y6pRjd9XlQWNa7H
TgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoN
FvhsO9tvBCOIazpswWC9aJ9xju4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrz
mqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wW
IRdAvKLWZu/axBVbzYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZ
USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==
-----END CERTIFICATE-----
---
Server certificate
subject=C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com

issuer=C = US, O = Google Trust Services, CN = GTS CA 1O1

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2632 bytes and written 402 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
DONE

参考

デフォルトの /etc/httpd/conf.d/ssl.conf

# grep -v -e '^\s*#' -e '^\s*$' /etc/httpd/conf.d/ssl.conf
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache         shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout  300
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

デフォルトの /etc/nginx/conf.d/default.conf

# grep -v -e '^\s*#' -e '^\s*$' /etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}