それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

OpenVPNでeasy-rsaを使ったCA構築でTLS接続をする

ここまで、次のことを試しました。

  • OpenVPNの起動と接続・コマンドから
  • OpenVPNの固定鍵(共有鍵)の作成と仕様
  • OpenVPNで設定ファイルを利用して接続する

TLSを使う。

TLSを使うことにします。UDP/TLSの場合、http3/HTTPSと同じ通信方式なのでパケットフィルタリングで落とされる可能性も低めです。 今どきの暗号化接続はTLSでしょう。

TLS接続のファイルたち

TLSの場合は、いっぱいファイルが出てきます。

証明書を作成するのに、CA作成、クライアント鍵作成、クライアント署名リクエストの作成、署名済み証明書作成、などたくさん手順が必要です。

サーバー証明書(署名済みの公開鍵)を作成するために、CAも秘密鍵・公開鍵のペアを使うので、たくさん手順が必要です。

その他にも 安全な鍵交換のための dh ファイルも出てきます。

そういうわけで、いくつもファイルを作る必要があります。

  • CA
  • サーバー
    • 証明書(公開鍵+CA署名)
  • クライアント
    • 証明書(公開鍵+CA署名)
  • dh

CAの役割や証明書についてはIPA基本情報の教科書でも出てくるものなので、特に触れませんが。

dh もDiffie-Hellman鍵交換 などでググると出てきます。

OpenVPNとeasy-rsa

OpenVPNの記事を見ていると、よくCAの話が出てきますが、CA自体はOpenSSLで作るので、すべてがOpenVPNの話題ではありません。

CAの作成とPKIつまり署名リクエストと署名、証明書作成は openssl の使い方の話になります。詳しくは openssl クックブックを見たほうが速いと思います

これらの手順を簡単にしてくれるのがeasy-rsa です。

どんな方法でもいいので、先のCAと証明書を作れば使えるようになります。*1

easy-rsa

オレオレ認証局のCAを立ち上げて、証明書を作成するのを簡単にしてくれるパッケージです。

今回は easy-rsa自己署名証明書オレオレ証明書)を使います。が、debian では、更に簡易化されたものがありました。easy-rsa と一緒にインストールされます。

Ubunt/Debianの場合

make-cadir というコマンドがあります。easy-rsa と一緒にインストールされます。便利です。

証明書を作るためのディレクトリを作成する。

make-cadir my-easy-rsa/

インストールすると、次のように、コマンド一式がコピーされます。

基本的な手順

make-cadir をしたあとは、コマンドを順番に実行するだけです。

source vars
./build-ca
./build-key-server  server
./build-dh
./build-key client

これでぱぱっと作れます。 試したのはDebian 9 の頃だったのでeasy-rsa コマンドが少し古いです。

easy-rsa のNEWバージョン

最近のeasy-rsa だと次のようになります。

make-cadir my-easy-rsa/
source vars
./easyrsa init-pki
./easyrsa build-ca  nopass
./easyrsa build-server-fuill server nopass
 ./easyrsa build-client-full client nopass
./easyrsa gen-dh

鍵ファイル一式が作れました。

takuya@:my-easy-rsa$ find -type f -name '*key' -o -name '*crt' -o -name '*dh*'
./pki/dh.pem
./pki/issued/client.crt
./pki/issued/server.crt
./pki/ca.crt
./pki/private/server.key
./pki/private/ca.key
./pki/private/client.key

サーバーの起動

これを使って、サーバーを起動します。

sudo openvpn \
  --dev tun1 \
  --ifconfig 10.9.8.1 10.9.8.2 \
  --tls-server \
  --dh    /home/takuya/openvpn/my-easy-rsa/pki/dh.pem  \
  --ca    /home/takuya/openvpn/my-easy-rsa/pki/ca.crt \
  --cert  /home/takuya/openvpn/my-easy-rsa/pki/issued/server.crt \
  --key   /home/takuya/openvpn/my-easy-rsa/pki/private/server.key  \
  --verb 6

クライアントの起動

クライアントに必要なファイルをコピーしてきて、起動します。

sudo openvpn \
  --dev tun1 \
  --remote 192.168.1.1
  --ifconfig 10.9.8.2 10.9.8.1 \
  --tls-client \
  --dh    ./pki/dh.pem  \
  --ca    ./pki/ca.crt \
  --cert  ./pki/issued/client.crt \
  --key   ./pki/private/client.key  \
  --verb 6

あとは ping を打って確認します。

ping 10.9.8.1

ちなみに、verb6 にしておくと、サーバー側、クライアント側でpingごとにログが流れていくので、非常にわかりやすいと思います。

tls-auth の追加

tls-auth を追加すれば、UDPのハンドシェイクが安全になります。追加しておきます。

openvpn --genkey --secret ta.key

クライアント側・サーバー側の双方に、tls-auth を追加します。

ファイルをコピーして共有します。

それぞれ、--tls-auth とパスを起動オプションに追加します。

サーバー側の起動

sudo openvpn \
  --dev tun1 \
  --ifconfig 10.9.8.1 10.9.8.2 \
  --tls-server \
  --dh    /home/takuya/openvpn/my-easy-rsa/pki/dh.pem  \
  --ca    /home/takuya/openvpn/my-easy-rsa/pki/ca.crt \
  --cert  /home/takuya/openvpn/my-easy-rsa/pki/issued/server.crt \
  --key   /home/takuya/openvpn/my-easy-rsa/pki/private/server.key  \
  --tls-auth /home/takuya/openvpn/ta.key  \
  --verb 6

クライアント側

sudo openvpn \
  --dev tun1 \
  --remote 192.168.1.1
  --ifconfig 10.9.8.2 10.9.8.1 \
  --tls-client \
  --dh    ./pki/dh.pem  \
  --ca    ./pki/ca.crt \
  --cert  ./pki/issued/client.crt \
  --key   ./pki/private/client.key  \
  --tls-auth  ./ta.key  \
  --verb 6

クライアントにサーバー証明書のverifyをいれる

ここままでも繋がりますが、クライアントの接続ログを見るとサーバー側の証明書をverify してないぞとメッセージで言われてます。

Tue Feb 18 05:07:12 2020 WARNING: No server certificate verification method has been enabled.  See http://openvpn.net/howto.html#mitm for more info.

サーバーの証明書は build-server-full serverと指定したので名前がserverになってます。なので次のようにクライアント起動オプションに追加します。

--remote-cert-tls server

安全なcipher を使う

サーバー側を起動すると、次のようにメッセージが出てくるので aes-256-cbc を使います。

WARNING: INSECURE cipher with block size less than 128 bit (64 bit).  This allows attacks like SWEET32.  Mitigate by using a --cipher with a larger block size (e.g. AES-256-CBC).

サーバー側に足しておきます。

--tls-server \ 
--ciper aes-256-cbc

クライアントにも入れておきます。

--tls-client \ 
--ciper aes-256-cbc

ここまでで

TLS接続を実現することが出来ました。

*1: 厳密には証明書の形式があって云々