インストール
# yum install mod_ssl
自己署名証明書
SAN 項目を追加した設定ファイルを作成。
# cd /etc/pki/tls/ # cp openssl.cnf openssl-san.cnf
openssl.cnf と openssl-san.cnf の差分
--- openssl.cnf +++ openssl-san.cnf @@ -104,7 +104,7 @@ #################################################################### [ req ] default_bits = 2048 -default_md = sha1 +default_md = sha256 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes @@ -222,6 +222,11 @@ basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName=@alt_names + +[ alt_names ] +DNS.1=takeash.net +DNS.2=*.takeash.net [ v3_ca ]
- 証明書フォルダへ移動
# cd certs/
- サーバー用秘密鍵作成 (server.key)
# openssl genrsa -aes128 2048 > server.key
- パスフレーズ削除
httpd 再起動時にパスフレーズが要求されないようにするため。# openssl rsa -in server.key -out server.key
-
サーバー用自己署名証明書作成 (server.crt)
# openssl req -utf8 -new -key server.key -x509 -days 3650 -out server.crt -set_serial 0 \ -subj '/C=JP/ST=Tokyo/L=Chuo-ku/O=TakeAsh.net/CN=takeash.net' -extensions v3_req -config ../openssl-san.cnf
-
サブジェクト例 (TakeAsh.net)
項目 用途 サンプル C 国名コード JP ST 都道府県 Tokyo L 区市町村 Chuo-ku O 組織名 TakeAsh.net CN コモンネーム(ドメイン名) takeash.net 証明書確認
「X509v3 extensions - X509v3 Subject Alternative Name」項目が存在すれば SAN が含まれている。# openssl x509 -in server.crt -text ... X509v3 Subject Alternative Name: DNS:takeash.net, DNS:*.takeash.net ...
-
/etc/httpd/conf.d/ssl.conf (抜粋)
SSLCertificateFile /etc/pki/tls/certs/server.crt SSLCertificateKeyFile /etc/pki/tls/certs/server.key DocumentRoot "/var/www/html" SSLProtocol all -SSLv2 -SSLv3
-
httpd 再起動
- CentOS 6
# service httpd restart
- CentOS 7
# systemctl restart httpd
- CentOS 6
-
動作テスト
Certbot
-
Certbot 使用前準備
- ホスト名が正引きできること。(ワイルドカード不可)
- バーチャルホストのサーバ名と要求するドメイン名のどれかが一致すること。
- インターネットから https でアクセス可能になっていること。
- https ポート解放
# firewall-cmd --permanent --add-service=https
- CertBot は Apache が稼働しているサーバ上で実行する。
Certbot インストール (EPEL リポジトリ)
# yum install python-certbot-apache
証明書取得
取得に成功すると「/etc/letsencrypt/live/<ドメイン1>/」に証明書が作成される。# certbot certonly --apache \ -m <メールアドレス> --agree-tos \ -d <ドメイン1> [-d <ドメイン2> ...]
/etc/httpd/conf.d/ssl.conf (抜粋)
Listen 443 https SSLEngine on SSLCertificateFile /etc/letsencrypt/live/<ドメイン1>/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/<ドメイン1>/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/<ドメイン1>/chain.pem
/etc/httpd/conf.d/VirtualHosts.conf (抜粋)
バーチャルホスト毎に SSL 設定が必要。<VirtualHost *:80 *:443> ServerName vh1.<ドメイン1> DocumentRoot /var/www/vh1-html/ SSLEngine on SSLCertificateFile /etc/letsencrypt/live/<ドメイン1>/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/<ドメイン1>/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/<ドメイン1>/chain.pem <Directory "/var/www/vh1-html"> AllowOverride All </Directory> </VirtualHost>
自動更新スクリプト /etc/cron.monthly/certbot.sh
#!/bin/bash /bin/certbot renew
Certbot (ワイルドカード, 手動)
Certbot インストール (EPEL リポジトリ)
# yum -y install yum-utils # yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional # yum install certbot-apache
証明書取得(手動)
途中HTTPへのテキストファイルの配置とDNSへのTXTレコードの追加を指示されるので、追加してからEnterを押して先へ進む。
取得に成功すると「/etc/letsencrypt/live/<ドメイン>/」に証明書が作成される。# certbot certonly --manual \ --server https://acme-v02.api.letsencrypt.org/directory \ -d "*.example.com" -d example.com
/etc/httpd/conf.d/ssl.conf (抜粋)
Listen 443 https SSLEngine on SSLCertificateFile /etc/letsencrypt/live/<ドメイン>/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/<ドメイン>/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/<ドメイン>/chain.pem
/etc/httpd/conf.d/VirtualHosts.conf (抜粋)
バーチャルホスト毎に SSL 設定が必要。<VirtualHost *:80 *:443> ServerName vh1.<ドメイン1> DocumentRoot /var/www/vh1-html/ SSLEngine on SSLCertificateFile /etc/letsencrypt/live/<ドメイン1>/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/<ドメイン1>/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/<ドメイン1>/chain.pem <Directory "/var/www/vh1-html"> AllowOverride All </Directory> </VirtualHost>
apache 再起動
CentOS 7# systemctl restart httpd
証明書更新
「--manual」で取得した場合は「renew」による自動更新ができないので、既存の証明書を削除し同名で取得し直す。# certbot delete
Certbot (ワイルドカード, 自動)
Certbot, DNS Plugin インストール (EPEL リポジトリ)
# yum -y install yum-utils # yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional # yum install certbot-apache python2-certbot-dns-rfc2136
BIND 用認証キーの作成
Kcertbot-key.+165+43987.key, Kcertbot-key.+165+43987.private の2つのファイルが作成される。# cd /etc/named/ # dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST certbot-key
認証ファイル /etc/named/certbot_rfc2136.ini , ファイルモード 600
# Target DNS server dns_rfc2136_server = 127.0.0.1 # Target DNS port dns_rfc2136_port = 53 # TSIG key name dns_rfc2136_name = certbot-key. # TSIG key secret dns_rfc2136_secret = <Kcertbot-key.+165+43987.key のハッシュ値> # TSIG key algorithm dns_rfc2136_algorithm = HMAC-SHA512
/etc/named.conf に追加
key "certbot-key." { algorithm hmac-sha512; secret "<Kcertbot-key.+165+43987.key のハッシュ値>"; }; view "internal" { match-clients { localhost; localnets; }; match-destinations { localhost; localnets; }; recursion yes; zone "." IN { type hint; file "named.ca"; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; include "/etc/named/<ドメイン>.lan.zone"; }; view "external" { match-clients { any; }; match-destinations { any; }; recursion no; include "/etc/named/<ドメイン>.wan.zone"; include "/etc/named/_acme-challenge.<ドメイン>.wan.zone"; };
/etc/named/<ドメイン>.lan.zone
zone "<ドメイン>" { type master; file "<ドメイン>.lan.db"; update-policy { grant certbot-key. name _acme-challenge.<ドメイン>. txt; }; };
/etc/named/<ドメイン>.wan.zone
zone "<ドメイン>" { type master; file "<ドメイン>.wan.db"; allow-query { any; }; update-policy { grant certbot-key. name _acme-challenge.<ドメイン>. txt; }; };
/etc/named/_acme-challenge.<ドメイン>.wan.zone
zone "_acme-challenge.<ドメイン>" { type master; file "_acme-challenge.<ドメイン>.wan.db"; allow-query { any; }; update-policy { grant certbot-key. name _acme-challenge.<ドメイン>. txt; }; };
/var/named/<ドメイン>.wan.db
$TTL 86400 @ IN SOA ns1.<ドメイン>. root.<ドメイン>. ( 2018090500 ; Serial 28800 ; Refresh 14400 ; Retry 2592000 ; Expire 86400 ; Minimum ) IN NS ns1.<ドメイン>. IN MX 10 mail.<ドメイン>. @ IN A <グローバル IP アドレス> ns1 IN A <グローバル IP アドレス> www IN A <グローバル IP アドレス> mail IN A <グローバル IP アドレス> _acme-challenge IN NS ns1.<ドメイン>. * IN A <グローバル IP アドレス> <ドメイン>. IN TXT "v=spf1 a mx ~all"
/var/named/_acme-challenge.<ドメイン>.wan.db
$TTL 86400 @ IN SOA ns1.<ドメイン>. root.<ドメイン>. ( 2018090500 ; Serial 1h ; Refresh 15m ; Retry 30d ; Expire 1h ; Minimum ) IN NS ns1.<ドメイン>.
<ドメイン>.jnl: create: permission denied
(/var/named/data/named.run) 対策# chmod 770 /var/named/ # setsebool -P named_write_master_zones 1
証明書取得
# certbot certonly \ --dns-rfc2136 \ --dns-rfc2136-credentials /etc/named/certbot_rfc2136.ini \ -d "*.<ドメイン>" -d <ドメイン>
/etc/letsencrypt/renewal-hooks/deploy/restartServices.sh
#!/bin/bash LANG=en_us.UTF-8 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin services="httpd postfix dovecot" if [ $(id -u) != 0 ]; then echo "This command requires root previlege." 1>&2 exit 1 fi for service in ${services}; do echo "restart ${service}" systemctl restart ${service} || exit $? done exit 0
サービス登録
# systemctl start certbot-renew # systemctl enable certbot-renew # systemctl status certbot-renew
動作確認
証明書の内容をテキスト出力
# openssl x509 -text -in /etc/letsencrypt/live/<ドメイン>/cert.pem
証明書の有効期限を表示
getExpireDate.sh
#!/bin/bash
CommonName=example.net
NotAfter=`openssl x509 -noout -dates -in /etc/letsencrypt/live/${CommonName}/fullchain.pem | \
grep notAfter | \
sed -e "s/notAfter=//" | \
date -f - --iso-8601`
echo ${NotAfter}
SSL 接続確認
$ openssl s_client -connect <ホスト>:443
設定失敗
CONNECTED(00000003)
140139752064912:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:794:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 289 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1535884386
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
設定成功
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = *.<ドメイン1>
verify return:1
---
Certificate chain
0 s:/CN=*.<ドメイン1>
i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGETCCBPmgAwIBAgISA3VBvI0cSyzAQGtpIaQKQRZxMA0GCSqGSIb3DQEBCwUA
...
リンク
-
Let's Encrypt Free SSL/TLS Certificates
- CertbotとBINDの組み合わせでLet's Encryptのワイルドカード証明書を取得・更新する
- OpenSSL CSR with Alternative Names one-line - End Point Blog
- SAN対応 x.509 証明書を取得するためのCSRを作成する - Qiita
- subjectAltNameでバーチャルホスト - Kung Noi Blog
- Webサーバー間通信内容暗号化(Apache+mod_SSL) - CentOSで自宅サーバー構築
- SSL Server Test (Powered by Qualys SSL Labs)
-
ssl certificate - how to add subject alernative name to ssl certs? - Stack Overflow
- keytool -certreq -ext SAN=dns:example.com,ip:192.168.0.1
- keytool(ja) / keytool(en)