使用環境がiOS13になったら、自前メールサーバにPOP over SSLで接続できなくなった
症状
「サーバの識別情報を検証できません。」「"...."の識別情報をメールで確認できません。」
SSLの証明書に対するポリシーが変わっていたのが原因。
詳しくは公式サイト参照. 自己証明書でなくて、ちゃんとした証明書を取れば問題ないのだろうが、しばらくの間でも自己証明書の更新でしのぐ。ポイントは、CA証明書のSAN(subjectAltName)という項目にIP/DNSとextendedKeyUsageという項目を適切につけて、SHA2を使え、ということらしい。
SSL証明書の更新
SSLの鍵作成/証明書作成関係のコマンドは、数年に1回調べて叩いて、そのたび忘れる。また、忘れると思う。
Google検索するといくつかのサイトが見つかが、今回主に参考にしたのは下記。
- OpenSSLコマンドの備忘録
- [OpenSSLでX.509 v3の証明書を作成する] (https://qiita.com/SRsawaguchi/items/f4dc743198e1246fff64)
- [証明書に x509v3 拡張属性を追加する] (https://access.redhat.com/ja/solutions/2586691)
- オレだよオレオレ認証局で証明書つくる
- iPhone/iPad等iOSに自己署名オレオレCA証明書からサーバー/クライアント証明書を署名しインストールする
OpenSSLの確認/インストール。
十分信頼できるバージョンのOpenssl実装がインストールされていればこの作業はスキップできるだろう。ちょっと自前サーバーの環境の事情により、opensslのバージョンアップから始める。事情により、Libresslを使うことにする。
% wget https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.9.2.tar.gz
% tar xvf libressl-2.9.2.tar.gz
% cd libressl-2.9.2
% ./configure --prefix=/usr/local/depot/libressl-2.9.2 --with-openssldir=/usr/local/depot/libressl-2.9.2/openssl LDFLAGS=-Wl,-rpath,/usr/local/depot/libressl-2.9.2/lib
% make
% make check
% su -c "make install"
インストール後、
(linux)% ldd /usr/local/depot/libressl-2.9.2/bin/openssl
(macOS)% otool -L /usr/local/depot/libressl-2.9.2/bin/openssl
などの方法で、読み込まれるライブラリ(libssl.{so,dylib}
, libcrypto.{so,dylib}
)のパスが所望のものか確認する。
設定ファイルをアップデート
/usr/local/depot/libressl-2.9.2/openssl/openssl.cnf
openssl
コマンドを叩くごとに、地域名や組織名などをn回入力するのは手間なので、それらのデフォルト値を設定する。
countryName_default
stateOrProvinceName_default
localityName_default
0.organizationName_default
organizationalUnitName_default
-
commonName_default,emailAddress_default
これらのパラメータをそれぞれの_default
がつかないパラメータ定義にあるプロンプト文を参考に設定しておく。また、(実際のIPアドレス、FQDNに合わせて適宜修正のうえ)下記を追記する。下記例のsan_attr_ca
というセクション名は、あとのopenssl
の実行時オプションと整合性がとれていればなんでもよい。
[ san_attr_ca ]
basicConstraints=critical,CA:true,pathlen:1
keyUsage=digitalSignature,keyCertSign,cRLSign
extendedKeyUsage=serverAuth,clientAuth,codeSigning,emailProtection
subjectAltName=IP:000.000.000.000,DNS:samplehost.sampledomain.sampleTLD
以下はroot
で、/usr/local/depot/libressl-2.9.2/openssl/certs
以下で作業した。
'x509v3-mod.cnf'の作成。
/usr/local/depot/libressl-2.9.2/openssl/x509v3.cnf
を参考に。
[ x509v3_san_attr ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage=serverAuth,clientAuth,emailProtection
subjectAltName=IP:000.000.000.000,DNS:samplehost.sampledomain.sampleTLD
鍵/証明書群を作成
今後、作業手順を毎回思い出す手間を省くため,今回作業手順をMakefile
で記述。今後は% make
と叩けば、あとはプロンプトに従って答えるのみ。自己認証局名(下記例だとsamplehostname
)や、作成される署名済みキーのbasename(下記例ではpop3s
)は適宜修正して使用する。作成される暗号化されていない秘密鍵に関しては取り扱い注意。
OPENSSL=/usr/local/depot/libressl-2.9.2/bin/openssl
KEYBITS=4096
SERIALNO=0
CA_HOSTNAME=samplehostname
CA_EXTSEC=san_attr_ca
EXTCNF=x509v3-mod.cnf
EXTCNFSEC=x509v3_san_attr
SERVICE_NAME=pop3s
EXPIREDAYS=824
#.PHONY: usage
#.SUFFIXES: .key .csr .crt .pem
#.PRECIOUS: %.key %.csr %.crt %.pem
all: $(SERVICE_NAME).pem $(CA_HOSTNAME)_ca_certs.cer
$(CA_HOSTNAME)_ca.key:
umask 077 ; $(OPENSSL) genrsa -des3 -out $@ $(KEYBITS)
$(CA_HOSTNAME)_ca.csr: $(CA_HOSTNAME)_ca.key
umask 077 ; $(OPENSSL) req -utf8 -new -key $(@:.csr=.key) -sha256 -out $@
$(CA_HOSTNAME)_ca.crt: $(CA_HOSTNAME)_ca.key $(CA_HOSTNAME)_ca.csr
umask 077 ; $(OPENSSL) req -utf8 -x509 -new -key $(@:.crt=.key) -in $(@:.crt=.csr) -out $@ -set_serial $(SERIALNO) -days $(EXPIREDAYS) -sha256 -extensions $(CA_EXTSEC) -nodes
openssl x509 -text -in $@
$(CA_HOSTNAME)_ca_certs.pem: $(CA_HOSTNAME)_ca.key $(CA_HOSTNAME)_ca.crt
umask 077 ; cat $^ > $@
$(CA_HOSTNAME)_ca_certs.cer:
umask 077 ; $(OPENSSL) x509 -outform der -in $(@:.cer=.pem) -out $@
openssl x509 -text -in $@
$(SERVICE_NAME).key:
umask 077 ; $(OPENSSL) genrsa -des3 -out $(@:.key=.enc.key) $(KEYBITS) ; $(OPENSSL) rsa -in $(@:.key=.enc.key) -out $@
$(SERVICE_NAME).csr: $(SERVICE_NAME).key
umask 077 ; $(OPENSSL) req -new -key $(@:.csr=.key) -sha256 -out $@
$(SERVICE_NAME).crt: $(SERVICE_NAME).csr $(CA_HOSTNAME)_ca_certs.pem $(CA_HOSTNAME)_ca.key $(EXTCNF)
umask 077 ; $(OPENSSL) x509 -req -CA $(CA_HOSTNAME)_ca_certs.pem -CAkey $(CA_HOSTNAME)_ca.key -CAcreateserial -CAserial $(CA_HOSTNAME)_ca.srl -in $(@:.crt=.csr) -out $@ -days $(EXPIREDAYS) -sha256 -extfile $(EXTCNF) -extensions $(EXTCNFSEC)
openssl x509 -text -in $@ -inform der
$(SERVICE_NAME).pem: $(SERVICE_NAME).key $(SERVICE_NAME).crt
umask 077 ; cat $^ > $@
いくつか作成されるファイルのうち、以下で使用するのは、
- 自己認証局の証明書(上記例だと samplehost_ca_certs.cer)
- サービス用の署名済み鍵(上記例だと、pop3s.pem)
サーバー側の作業
上記で作成したサービス用の署名済みの鍵(上記例だと、pop3s.pem)を適切なところに置く。これはpop3s/imapsサーバーの仕様/設定によるだろう。
iOS端末側の設定
- なんらかの安全な手段で、iOSの端末に自己認証局の証明書(上記例だと samplehost_ca_certs.cer)を端末に送る。(メール添付/クラウド経由/webサーバ経由...)をダウンロードする。
- 「設定」アプリ → 「プロファイルがダウンロードされました」→ 「インストール」... と進み、種々の警告メッセージを読んで、リスクを理解してインストールする。
- 「設定」アプリ → 「一般」→「情報」→ 「証明書信頼設定」→ 「ルート証明書を全面的に信頼する」の欄で該当するものを種々の警告メッセージを読んで、リスクを理解したうえで有効にする。
最後に
サーバー管理者以外設定できないですね。ユーザーとしては、まっとうなサーバーを使う以外にないですね。