外出先からOpenVPNで自宅サーバに接続しようとしたのですが、「TLS handshake failed.」というエラーのせいで1時間くらい浪費したのでその解決法をメモしておきます。
状況の整理
クライアント(接続する側)のログには「TLS handshake failed.」というエラーが表示され、サーバー側で詳しく調べるとそのエラーの前に「CRL has expired.」というエラーが表示されていました。 (もしかしたら、クライアント側にも表示されていたのかもしれません)
とにかく、TLS handshake failed.という言い方は曖昧で、本質はCRL has expired.なのでこっちを解決していきます。
CRLとは
さっさと解決したいという方は飛ばしていただいて構わないのですが、CRLとはCertificate Revocation Listの略で、証明書失効リストという意味です。CA(認証局)はCRLを通じて不正だと判明した証明書や秘密鍵が漏れた証明書などを永久または一時的に無効とします。
私はVPNにおいてはオレオレ証明書を使っていたので、CAは自サーバーになりますから、このCRLも自分で発行する必要があります。というか、OpenVPNの初期設定時にやってましたね。みなさんもきっとやっているはずです。
で、このCRLは作りっぱなしでいいというわけではなく、有効期限があります。確かに古いCRLをいつまでも使うのはよくありませんからね。
最も普通な方法でやると、有効期限は30日ですので、30日が経過するとCRLの有効期限切れ、すなわち「CRL has expired.」です。
しかし、それならもっと前からエラーが出ていたのではと思うかもしれません。 その通りです。本来そうあるべきなのですが、どうやらOpenVPN2.3系ではこのエラーが出ないそうで、2.4系で修正されたので、久々に使ったら「CRL has expired.」というエラーにハマったわけです。
解決
有効期限切れとなっていたCRLを再生成してみましょう。以下は私の環境での操作です。適宜修正してください。
cd /etc/openvpn/easyrsa3
./easyrsa gen-crl
cp /etc/openvpn/easyrsa3/pki/crl.pem /etc/openvpn/
chmod o+r /etc/openvpn/crl.pem
これによって、有効期限が30日のCRLを生成し、適用できます。私はこの後、念の為次のように再起動しました。
systemctl restart openvpn
これによって、無事、旅行先から安全に接続できました。
最後までお読みいただきありがとうございました。