自己署名証明書
~オレオレ証明書を作る~

2020/1/4


経緯

webブラウザでサンプルページを表示すると、「保護されていない通信」と表示される。
webサーバへのアクセスは実験室に限定しているのでとくに問題はないが、ちょっとおもしろくない。

保護されていない通信 保護されていない通信

どうするか?

どうするか?
  1. このまま見ないふりをする
    根本的な解決でない。
    常時SSL化の流れがあり、近い将来httpを全面的に否定するような流れにでもなるとも限らない。
  2. 「保護されていない通信」と表示しないブラウザを使う
    きっと古いブラウザだと思う。
    ある日突然「保護されていない通信」と表示するかもしない。
  3. 自己署名証明書を作ってみる
    自己署名証明書(オレオレ証明書)を信用するか否かが問題だ。
    アクセス時に警告が出るので、使い勝手に問題があるかもしれない。できれば、なにも言わずにアクセスしてほしい。
  4. 専用の認証局を試す
    webserver以外に認証局(ルートCA)が必要でちょっと手間がかかる。
    証明書を必要とするwebserverが複数あるなら認証局を用意するのがよさそう。
    webserver1台なら、webserverに自己認証局を同居させるか? 自己署名証明書で足りるのでは?
  5. 外部団体(認証サービス)に証明書の発行をお願いする
    外部団体にはベリサイン社、グローバルサイン社、シマンテック社などがあり、有償で証明書を発行している。
    このwebserverは外部からアクセスするつもりはない。外部団体に証明書をお願いするには、「外部団体がこのwebserverにアクセスできる」(実在性の確認)ことが前提になるので、却下。
証明書は、「このサーバは安全です」(「証明書を申請したサーバに一致します」)と外部団体(第三者認証局)が保証するので安心して通信できるわけだが、 自己署名証明書(オレオレ証明書)では「このサーバは安全です」と言っているのはサーバ自身なので、簡単には信用できない。
・サーバの設置者を信用し
・そのサーバが発行した自己署名証明書(オレオレ証明書)を信用し
・現在接続しているサーバが正しいものであると思い込む
であるなら自己署名証明書(オレオレ証明書)を使うことができよう。

apache(https設定)

mod_sslをインストールすると/etc/httpd/conf.d/ssl.confができる。
dnf -y install mod_ssl
/etc/httpd/conf.d/ssl.confを修正する。
修正前修正後

#DocumentRoot "/var/www/html"
#ServerName www.example.com:443
#を削除, ServerNameを修正
DocumentRoot "/var/www/html"
ServerName webserver.takahashi.lab:443

#SSLProtocol all -SSLv3
#を削除, プロトコルはTLS1.3のみを許可 (-allで全て不許可した後、TLS1.3を許可)
#SSLProtocol -all +TLS1.3
#「SSLProtocol: Illegal protocol 'TLS1.3'」のときは #を削除
SSLProtocol all -SSLv3

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
#PEMでエンコードした証明書
SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt

SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
#秘密鍵
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key

<FilesMatch "\.(cgi|shtml|phtml|php)$">>
SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
#cgi,php他は使わないのですべてコメントアウト
#<FilesMatch "\.(cgi|shtml|phtml|php)$">>
# SSLOptions +StdEnvVars
#</FilesMatch>
#<Directory "/var/www/cgi-bin">
# SSLOptions +StdEnvVars
#</Directory>

http://..../はhttps://..../として取り扱いたいので、rewrite.confをつくる。
#/etc/httpd/conf.d/rewrite.confをつくる
<ifModule mod_rewrite.c>
      RewriteEngine On
      LogLevel alert rewrite:trace3
      RewriteCond %{HTTPS} off
      RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</ifModule>

/etc/httpd/以下設定を修正した後、設定事項を確認する。
apache configtest

自己署名証明書をつくる

webserver上で作業を行う。
ろば電子が詰まつてゐる オレオレ証明書をopensslで作る(詳細版)(https://ozuma.hatenablog.jp/entry/20130511/1368284304) によると、3ステップでよいらしい。
作業手順は
  1. 秘密鍵を生成
  2. CSR Certificate Signing Request生成
  3. 自己署名証明書生成 秘密鍵を使いCSRに電子署名
#ろば電子版
cd /etc/pki/myCA
#秘密鍵生成
openssl genrsa 2048 > server.key

#CSR生成
openssl req -new -key server.key > server.csr
#いろいろ質問がある
#Country Name (2 letter code) [XX]:JP
#State or Province Name (full name) []:HKD
#Locality Name (eg, city) [Default City]:HKDT
#Organization Name (eg, company) [Default Company Ltd]:NITH
#Organizational Unit Name (eg, section) []:Takahashi Lab
#Common Name (eg, your name or your server's hostname) []:webserver.takahashi.lab
#Email Address []:.

#Please enter the following 'extra' attributes
#to be sent with your certificate request
#A challenge password []:
#An optional company name []:

#自己署名証明書生成
openssl x509 -req -signkey server.key < server.csr > server.crt 
#Signature ok
#subject=C = JP, ST = HKD, L = HKDT, O = NITH, OU = Takahashi Lab, CN = webserver.takahashi.lab
#Getting Private key

#/etc/httpd/conf.d/ssl.confで指定したディレクトリに証明をコピー
rm -rf /etc/httpd/conf/ssl.crt/ /etc/httpd/conf/ssl.key
mkdir -p /etc/httpd/conf/ssl.crt/ /etc/httpd/conf/ssl.key
cp server.crt /etc/httpd/conf/ssl.crt/
cp server.key /etc/httpd/conf/ssl.key/

firewall-cmd設定

firewall-cmdでhttpsを許可する。
#firewall-cmdでhttpsを許可する。
firewall-cmd --list-all;#httpsがないことを確認
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
firewall-cmd --list-all;#httpsが追加されたことを確認

https://webserver:443/でアクセスしてみると、「保護されていない通信 webserver」(黒文字)から「保護されていない通信 http://webserver」(赤文字)に変わった。
ブラウザに証明書をインストールしていないので、「NET::ERR_CERT_AUTHORITY_INVALID」が表示される。


保護されていない通信の詳細をみると、「このサイトへの接続は保護されていません」であり、証明書は無効になっている。


証明書の各項目はさきほど設定したとおりであり、証明書の有効期間は30日がデフォルトになっている。


ディベロッパーツールを見ると、NET::ERR_CERT_AUTHORITY_INVALIDに加えて、Subject Alternative Name missingになっている。このままではSAN値がないらしい。


SANを追記する

DNSとlocalhostを指定してみる。有効期間は365日にする。
#CSR生成 オプションをつけて質問を省略
mkdir /etc/pki/myCA; cd /etc/pki/myCA
openssl genrsa 2048 > server.key
openssl req -new -key server.key -subj "/C=JP/ST=HKD/L=HKDT/O=NITH/OU=Takahashi Lab/CN=webserver.takahashi.lab"> server.csr

#SAN値は外部ファイルに記述した
echo "subjectAltName = DNS:webserver.takahashi.lab, IP:192.168.xx.xx, IP:172.0.0.1" > san.txt

# 署名要求を秘密鍵で署名してサーバ証明書を作成する  有効期限は3650日
openssl x509 -days 3650 -req -extfile san.txt -signkey server.key < server.csr > server.crt
rm -rf /etc/httpd/conf/ssl.crt/ /etc/httpd/conf/ssl.key
mkdir -p /etc/httpd/conf/ssl.crt/ /etc/httpd/conf/ssl.key
cp server.crt /etc/httpd/conf/ssl.crt/
cp server.key /etc/httpd/conf/ssl.key/
rm -f /var/www/html/webserver.takahashi.lab.crt
cp server.crt /var/www/html/webserver.takahashi.lab.crt
systemctl restart httpd

webブラウザに証明書をインポート

これでサーバ側の準備ができた。
つぎは、webブラウザに証明書をインポートする。
webブラウザごとに手順が違うので、自己署名証明書(2)以降で個別に検証する。

「証明書の話をすると公開鍵とか秘密鍵とかの話ばかりでよくわからない。」「身近な例に例えるともうすこしわかった気になれると思う。」という方はこちらを参照されるとよいでしょう。印鑑証明を例に、とてもわかりやすく認証局の役割を説明しています。
SEの道標
【図解】よく分かるデジタル証明書(SSL証明書)の仕組み 〜https通信フロー,発行手順,CSR,自己署名(オレオレ)証明書,ルート証明書,中間証明書の必要性や扱いについて〜 (https://milestone-of-se.nesuke.com/sv-advanced/digicert/digital-certification-summary/)



証明書の作り方はこちらのサイトを参照
オレオレ認証局の作り方~SSL証明書を無料で作る方法 on CentOS 5 (https://www.webtech.co.jp/blog/optpix_labs/server/1159/)

httpsの設定とオレオレ証明書(自己署名証明書)の作成 (https://qiita.com/miqpim/items/911aa34e128950ec2d09)

opensslでサーバ証明書とルート証明書を作成するスクリプト (https://qiita.com/masahiro-aoike/items/965bd827dc13894f6664)

オレだよオレオレ認証局で証明書つくる (https://qiita.com/ll_kuma_ll/items/13c962a6a74874af39c6)

kakiro-web CentOS7.2 64bit OpenSSLを使用して自己認証局で署名したSSLクライアント証明書を作成 (https://www.kakiro-web.com/linux/ssl-client.html)

Server World CentOS8 SSL証明書を作成する(自己署名) (https://www.server-world.info/query?os=CentOS_8&p=ssl&f=1)

ろば電子が詰まつてゐる オレオレ証明書をopensslで作る(詳細版)(https://ozuma.hatenablog.jp/entry/20130511/1368284304)

Chromeで使えるオレオレ証明書を作成する方法 (https://qiita.com/t-kuni/items/d3d72f429273cf0ee31e)

Apache/SSL自己証明書の作成とmod sslの設定(http://www.maruko2.com/mw/Apache/SSL%E8%87%AA%E5%B7%B1%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8mod_ssl%E3%81%AE%E8%A8%AD%E5%AE%9A)

OpenSSLでプライベート認証局の構築(ルートCA、中間CA)https://qiita.com/bashaway/items/ac5ece9618a613f37ce5

HTTP/2応用編 TLSv1.3を設定してみた。 - Apache 2.4系でHTTP/2対応サーバを構築してみるテスト。 https://http2.try-and-test.net/tls13_apache_conf.html

Apache2.4 のRequireディレクティブでアクセス制御を行う - 闘うITエンジニアの覚え書き https://www.magata.net/memo/index.php?Apache2.4%20%A4%CERequire%A5%C7%A5%A3%A5%EC%A5%AF%A5%C6%A5%A3%A5%D6%A4%C7%A5%A2%A5%AF%A5%BB%A5%B9%C0%A9%B8%E6%A4%F2%B9%D4%A4%A6