全体の流れ
- openssl で作るのは大変なので certtool を用いる
- Ubuntu 20.04 の openssl
1.1.1f
、certtool3.6.13
にて確認。 - nginx は
1.11
を用いた。(1.11は 2017年リリース)
certtool
-
ca.key
、ca.crt
を作成 -
server.key
、server.crt
を作成
nginx
- certool で作った
ca.crt
、server.crt
、server.key
を用いる。
Windows
- ブラウザに
ca.crt
をインポートしておくことで、「このサイトは安全ではありません」の表示をスキップできる。
実際の作業
certtool
certtoolを使えるようにする
apt install -y gnutls-bin
make_mycerts.sh
#!/bin/sh
set -eu
CMD="certtool --sec-param High"
CA() {
dns_name=$1
ip_address=$2
$CMD --generate-privkey > ca.key
cat << EOL >> ca.info
cn = CA $dns_name - $ip_address
ca
cert_signing_key
expiration_date = "2100-01-01 09:00:00"
dns_name = $dns_name
ip_address = $ip_address
EOL
$CMD \
--generate-self-signed \
--load-privkey ca.key \
--template ca.info \
--outfile ca.crt
}
WWW() {
dns_name=$1
ip_address=$2
$CMD --generate-privkey > server.key
cat << EOL >> server.info
cn = www $dns_name - $ip_address
tls_www_server
encryption_key
signing_key
expiration_date = "2100-01-01 09:00:00"
dns_name = $dns_name
ip_address = $ip_address
EOL
$CMD \
--generate-certificate \
--load-privkey server.key \
--load-ca-certificate ca.crt \
--load-ca-privkey ca.key \
--template server.info \
--outfile server.crt
}
# クライント証明書を作成 (必須ではない)
CLIENT() {
ou=$1
$CMD --generate-privkey > client-01.key
cat << EOL >> client.info
ou = $ou
tls_www_client
encryption_key
signing_key
expiration_date = "2100-01-01 09:00:00"
EOL
$CMD \
--generate-certificate \
--load-privkey $ou.key \
--load-ca-certificate ca.crt \
--load-ca-privkey ca.key \
--template client.info \
--outfile $ou.crt
$CMD \
--load-ca-certificate ca.crt \
--load-certificate $ou.crt \
--load-privkey $ou.key \
--to-p12 --outder --outfile $ou.p12 \
--p12-name $ou \
--empty-password
}
main.sh
#!/bin/sh
set -eu
. ./make_mycerts.sh
DOMAIN="dev.example.com"
GLOBAL_IP="111.111.111.111"
mkdir -p $DOMAIN && cd $DOMAIN
CA $DOMAIN $GLOBAL_IP
WWW $DOMAIN $GLOBAL_IP
CLIENT "client-01"
-
client-01.p12
をインポートすると、ca.crt
の内容が信頼済みルート証明機関
に入る。
nginx 1.11
./nginx/ore-ssl.conf
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443 ssl;
server_name dev.example.com;
ssl_certificate /etc/ssl/mycerts/server.crt;
ssl_certificate_key /etc/ssl/mycerts/server.key;
ssl_client_certificate /etc/ssl/mycerts/ca.crt;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers ALL:!aNULL:!EXP:!MD5:!RC4:!LOW:+HIGH:+MEDIUM;
ssl_ciphers 'DES-CBC3-SHA';
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
docker run -it --rm \
-v $(pwd)/mycerts/:/etc/ssl/mycerts/ \
-v $(pwd)/nginx/ore-ssl.conf:/etc/nginx/conf.d/ore-ssl.conf \
-p 80:80 \
-p 443:443 \
nginx:1.11
ブラウザで証明書エラーを出さない方法
- IE : 従来の Subject CN値を使う。(server.crt)
- Chrome : サブジェクト代替名 を使う。
DNS Name=xxx.example.com
IP Address=192.168.xx.xx
- Firefox : Firefoxに ca.crt をインポートする。
ca.crtをコマンドプロンプトから取り込みたい場合 (vista以降)
管理者権限で実行
certutil -addstore ROOT ca.crt
おまけ
openssl コマンドで同じようなことをする場合
おまけ
# CA
openssl genrsa -out ca.key 3072
openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj '/CN=CA 2020'
# server
openssl genrsa -out server.key 3072
openssl req -new -key server.key -out server.csr -subj '/CN=dev.example.com'
openssl x509 -req -days 36500 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
# (xpでは不要) nginx 1.12 では ssl_dhparam 指定しないと DHE暗号が使えない
# http://nginx.org/en/CHANGES-1.12
# openssl dhparam -out dhparam.pem 4096
(略)
# クライアント証明書の p12キー
cat client-01.key client-01.crt ca.crt \
| openssl pkcs12 -export -out client-01.p12 -name "client-01" -passin pass: -passout pass:
XPで TLS1.2を(無理やり)有効にする
使用されている暗号を確認
Windows XP IE6 ( ssl_ciphers 'DES-CBC3-SHA';
)
Windows 10 IE11
Firefox
Chrome
-
ssl_ciphers 'DES-CBC3-SHA';
に制限した場合の表示
openssl 1.0.2h と 1.1.0 以降 3DES が無効化された
openssl 1.0.2h や 1.1.0 以降で再度有効化するには
ビルド時に enable-weak-ssl-ciphers
フラグが必要。
nginx 1.11 と 1.12の違い
- XPでは nginx
1.12
を使うと見れなかった。-
dh_param
の設定をしても見れなかった。 - docker で1.11を動かす場合、
nginx:1.11-alpine
を指定。
-
- XPは TLS 1.0 までしか対応していないため注意。
-
openssl ciphers -v 'DES-CBC3-SHA'
が以下なのが原因と思われる。
Error in cipher list
139762468738368:error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:../ssl/ssl_lib.c:2558:
(参考)XPでも見れる場合
$ openssl ciphers -v 'DES-CBC3-SHA'
DES-CBC3-SHA SSLv3 Kx=RSA Au=RSA Enc=3DES(168) Mac=SHA1
- nginx を
enable-weak-ssl-ciphers
フラグをつけてビルドする必要がある。
nginx
cd nginx-1.12.2
./configure --with-openssl \
--with-http_ssl_module \
--with-openssl-opt='enable-weak-ssl-ciphers'
make
sudo make install
curl で接続テスト
- CentOS6 の curlで確認しました。 (Ubuntu 20.04のものでは
rsa_3des_sha
が省かれている) - curl だと ssl_ciphers は
ECDHE-RSA-AES256-GCM-SHA384
が使われる。DES-CBC3-SHAの動作テストなので以下のようにNSSCipherSuite名で指定。
curl \
-v \
--insecure \
--tlsv1 --ciphers rsa_3des_sha \
--cert ./client-01.crt \
--key ./client-01.key \
--cacert ./ca.crt \
https://dev.example.com
nginx のTCPロードバランサー
configureスクリプトに--with-stream を付与してビルドする必要があります。