オフィスへのリモートVPN接続には長らくCisco Systems社のASA5505を使用していましたが、電源トラブルにより起動不可となってしまいました。
ただ機器としてかなり古いモデルであり、またコストをかけてリプレースする気も失せていたので、オープンソースVPNサーバのOpenVPNを導入することにしました。
元々Cisco ASAを利用する前(もう15年近く前になりますが)は実はOpenVPNを使っていたので再び古巣に戻ってきたという感覚です。
Contents
想定する構成
上記のような構成です。リモートLANは自宅やモバイルルータ環境下のネットワークという想定です。
モバイルPCやスマホにインストールされたOpenVPNクライアントツールからインターネット経由でOpenVPNサーバにアクセスし、サーバ⇔クライアント間で仮想的なVPN LAN(緑色のエリア)を形成し、VPN LAN越しにローカルLANのリソース(Webサーバやファイルサーバ等)にアクセスできるようにします。
この構成ではVPN ServerはローカルLANとVPN LANを中継するルータとして機能するため「ルータ方式」と呼ばれます。クライアントにローカルLANのIPを直接割り振る「ブリッジ方式」という実装方法もありますが、ここではその方式については触れません。
VPNクライアントを論理的に別のネットワークに分けることで、ネットワーク単位での制御が容易になるため、個人的にはルータモードをオススメします。
事前準備
IPリソースの確認
以下、本記事では下記のIPリソースを使用するものとします。
219.xx.xx.xx
- OpenVPNサーバ:192.168.11.148
- Web/Fileサーバ:192.168.11.147
- D/G:192.168.11.254
- モバイルPC:172.24.11.100
- OpenVPNサーバ兼D/G:8.20.0.1
- OpenVPNクライアント:8.20.0.2
ルータのポート転送設定
前項の図に記載した通り、クライアントPCからのインターネット越しの接続要求(UDP:1194番)をOpenVPNサーバに届けるためにポート転送の設定をインターネットアクセスルータに設定する必要があります。
一般家庭のインターネットアクセスルータにもポート転送の設定はあると思いますが、それに関してはそれぞれの機器のマニュアルを参照してください。
ポイントとして、
- ルータのグローバルIPアドレスに届いたUDP:1194番の通信を、
- OpenVPNサーバのプライベートIPのUDP:1194番に転送する。
という設定がなされればOKです。
ちなみに当方の環境で使っているCisco 1812J(IOS v12.x)の場合はグローバルコンフィグモードにて
ip nat inside source static udp 192.168.11.148 1194 interface Dialer1 1194
とすればOKです(Dialer1インタフェースにてPPPoE接続を行っている場合)。
VPNネットワークへのスタティックルーティング設定
VPNクライアントがローカルLAN内のリソースにアクセスした際、接続先のノード(Webサーバ等)からの「戻りパケット」を、正しくVPNクライアントに返してあげるために、スタティックルーティングを切ってあげる必要があります。
個別のノードにルーティングテーブルを設定するのではなく、D/G(デフォルトゲートウェイ)であるルータに設定してあげるのが効率的です。以下はCisco 1812Jに設定する場合のコマンドです。
ip route 8.20.0.0 255.255.255.0 192.168.11.148
8.20.0.0/24ネットワークへの通信は、192.168.11.148(OpenVPNサーバ)に転送する、という設定になります。
OpenVPNのインストールと設定
前置きが長くなりましたが、ここからが実装です。等環境ではCentOS7.9へのインストールになります。
パッケージのインストール
まず初めにEPELリポジトリをインストール後、OpenVPNと付随するパッケージをインストールします。
yum install epel-release
yum install openvpn easy-rsa net-tools bridge-utils
認証局および各種証明書の作成
PKIの初期化
cd /usr/share/easy-rsa/3
./easyrsa init-pki
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /usr/share/easy-rsa/3/pki
認証局の作成
./easyrsa build-ca Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017 #任意のパスフレーズを設定 Enter New CA Key Passphrase:<パスフレーズ> Re-Enter New CA Key Passphrase:<パスフレーズ(確認)> Generating RSA private key, 2048 bit long modulus .....................+++ ................+++ e is 65537 (0x10001) You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- #任意のCA名称を設定 Common Name (eg: your user, host, or server name) [Easy-RSA CA]:OpenVPN-CA CA creation complete and you may now import and sign cert requests. Your new CA certificate file for publishing is at: /usr/share/easy-rsa/3/pki/ca.crt
次にサーバ証明を作成しますが、デフォルトのままだと有効期限が1年(365days)となってしまうため、varsファイルを新規に作成して有効期限を延長します。
vi vars set_var EASYRSA_CERT_EXPIRE 36500 #有効期限を100年(36500days)
サーバ証明書作成
./easyrsa build-server-full vpnsrv nopass Note: using Easy-RSA configuration from: /usr/share/easy-rsa/3.0.8/vars Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017 Generating a 2048 bit RSA private key ..................+++ ........................+++ writing new private key to '/usr/share/easy-rsa/3/pki/easy-rsa-3693.MzWtsR/tmp.0ddHG3' ----- Using configuration from /usr/share/easy-rsa/3/pki/easy-rsa-3693.MzWtsR/tmp.OwxTxY Enter pass phrase for /usr/share/easy-rsa/3/pki/private/ca.key:<認証局作成の際に設定したパスフレーズ> Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows commonName :ASN.1 12:'vpnsrv' Certificate is to be certified until Jan 27 05:55:48 2123 GMT (36500 days) Write out database with 1 new entries Data Base Updated
クライアント証明書作成 ※クライアントごとに作成が必要です。
./easyrsa build-client-full openvpnclient nopass Note: using Easy-RSA configuration from: /usr/share/easy-rsa/3.0.8/vars Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017 Generating a 2048 bit RSA private key ....+++ ..............................................................+++ writing new private key to '/usr/share/easy-rsa/3/pki/easy-rsa-3807.YgbGaX/tmp.vfLaSq' ----- Using configuration from /usr/share/easy-rsa/3/pki/easy-rsa-3807.YgbGaX/tmp.uwO4Yu Enter pass phrase for /usr/share/easy-rsa/3/pki/private/ca.key:<認証局作成の際に設定したパスフレーズ> Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows commonName :ASN.1 12:'openvpnclient' Certificate is to be certified until Jan 27 05:58:18 2123 GMT (36500 days) Write out database with 1 new entries Data Base Updated
dhパラメータ生成
./easyrsa gen-dh
Note: using Easy-RSA configuration from: /usr/share/easy-rsa/3.0.8/vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
......................................................................+..........+.......................................................+...........+.........................+.......................................................................++*++*
DH parameters of size 2048 created at /usr/share/easy-rsa/3/pki/dh.pem
TLS-Auth キー作成
openvpn --genkey --secret ./pki/ta.key
作成した各種証明書等を/etc/openvpn/server/配下にコピー
cp -pR /usr/share/easy-rsa/3/pki/{issued,private,ca.crt,dh.pem,ta.key} /etc/openvpn/server/
OpenVPNサーバ設定
始めに、OpenVPNサーバがルータとして機能するためにパケットフォワーディングを有効にします。
vi /etc/sysctl.d/10-ipv4_forward.conf #以下の内容を記述し新規保存。 net.ipv4.ip_forward = 1 #設定を反映 sysctl --system
サンプル設定ファイルをコピーし、編集します。
cp /usr/share/doc/openvpn-2.4.12/sample/sample-config-files/server.conf /etc/openvpn/server/ vi /etc/openvpn/server/server.conf #リスンポート(必要に応じて変更) port 1194 #プロトコル(必要に応じて変更) ;proto tcp proto udp #コピーした各種証明書ファイル名 ca ca.crt cert issued/vpnsrv.crt key private/vpnsrv.key #コピーしたDHファイル名 dh dh.pem #VPNネットワーク #ローカルおよびリモートネットワークと重複しなければ何でもOK server 8.20.0.0 255.255.255.0 #ローカルネットワーク #⇒VPNクライアントに通知するルーティングテーブル push "route 192.168.11.0 255.255.255.0" #キープアライブ(10秒毎に生存確認, 120秒無応答でダウンと判断) keepalive 10 120 #コピーしたTLS-Authキーファイル名 tls-auth ta.key #圧縮通信を有効化 comp-lzo #persistオプション有効化 persist-key persist-tun #ログ出力先 status /var/log/openvpn-status.log log /var/log/openvpn.log log-append /var/log/openvpn.log #ログレベル verb 3
サーバ起動、自動起動有効化
systemctl start openvpn-server@server
systemctl enable openvpn-server@server
OpenVPNクライアントの設定
クライアントアプリのインストール
OpenVPNクライアントアプリは、Windows, Android, iPhone等各種OSに対応しています。
Windowsアプリケーションはここから入手・インストール可能です。(OpenVPN公式)
Androidアプリはここ(Playストア)
iPhoneアプリはここ(Appストア)
.opvnファイルの作成
OpenVPNクライアントの設定は、各種証明書および各種接続定義が記載された.opvnファイルを読み込ませるのが従来の方法ですが、これだとファイル数が最低でも5ファイル必要で、スマートフォン等にわざわざ転送して読み込ませるのが面倒な上に、スマートフォンのファイル管理ツールによっては5ファイルを同時にOpenVPNアプリに読み込ませることができないという可能性もあります。
そこで、各種証明書情報を.ovpnファイルに記述してしまうことで、設定ファイルを1つだけにすることが可能で、このほうが運用は楽です。
以下、1つの.ovpnファイルにまとめた例です。
client dev tun #グローバルIPアドレス remote 219.xx.xx.xx 1194 resolv-retry infinite nobind persist-key persist-tun #以下のCA証明書、クライアント証明書、クライアントキーについては #キーの内容を直接記載(※後述)するため、ここではコメントアウトします。 #ca ca.crt #cert openvpnclient.crt #key openvpnclient.key remote-cert-tls server #TLS-Authキー内容も直接記載(※後述)するため、ここではコメントアウト。 #tls-auth ta.key 1 #代わりに以下の2項目を有効にします。 tls-client key-direction 1 cipher AES-256-CBC comp-lzo verb 3 #以下、<ca> ~ </ca>タグ内にはCA証明書(ca.crt)のうち #「--BEGIN CERTIFICATE--」から「--END CERTIFICATE--」の内容を貼り付けます。 <ca> -----BEGIN CERTIFICATE----- MIIDRzCCAi+gAwIBAgIJANTQQgwHVmihMA0GCSqGSIb3DQEBCwUAMBwxGjAYBgNV BAMMEVlnZ2RyYXNpbGwtVlBOLUNBMB4XDTIzMDIwODA3MTYxNVoXDTMzMDIwNTA3 <~中略~> F/LqffJKU3OlE+9O2WOueZjRiFQcEp+V0kfvIOyVTlHaACEPcZ8bMqaH8/dthEbg /r3GamN4ZlXdQoEz/jGLftx7ZR3xTfZxzoG7Xz30fIot3yG+K4nTdcQaU7KF8cF4 jxz+Bl5RhXkYsehLI9pzFYtI0jVEntn3Uj3M -----END CERTIFICATE----- </ca> #以下、<cert> ~ </cert>タグ内にはクライアント証明書(openvpnclient.crt)のうち #「--BEGIN CERTIFICATE--」から「--END CERTIFICATE--」の内容を貼り付けます。 <cert> -----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIQU3rnxEvsiYs2a7rnJqnJBzANBgkqhkiG9w0BAQsFADAc MRowGAYDVQQDDBFZZ2dkcmFzaWxsLVZQTi1DQTAgFw0yMzAyMDkwMjIzMDBaGA8y <~中略~> poBKrPgP+t1J5gwY1Nl/TaS4pkCSoQOjD9e/aA0uyjFUy3VfdZv2iuRCcrm41hMi GqWrbNSvAAf1vBGLlQLYeDO2EQmY9oMYOOmGavUka2WkKa0Y90XF8oHrs575HZ+E fQ== -----END CERTIFICATE----- </cert> #以下、<key> ~ </key>タグ内にはクライアントキー(openvpnclient.key)のうち #「--BEGIN CERTIFICATE--」から「--END CERTIFICATE--」の内容を貼り付けます。 <key> -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCvZh5XCx+cOLYR ZAfNwM9hKsJZ6zAS02AEuHB9NWNZdGUwoNl+XfDMhbE5YsSq7MXLe9dUwrt8aCf/ <~中略~> MNQtnEj1da8kfwzi1blR4Dr7ILwnvdwPwsLDI8XbDoiCKFF1DGDNtT2/Frn1amPR ndbknYkpmQ0UJVdjW1LUsuwkZU1E9cgWIPFO/kLm+66Ox8JJlxJ2mZVauGMfHDsS 6hYQ733bnihcknVadx07HaU3 -----END PRIVATE KEY----- </key> #以下、<tls-auth> ~ </tls-auth>タグ内にはTLS-Authキー(ta.key)のうち #「--BEGIN CERTIFICATE--」から「--END OpenVPN Static key V1--」の内容を貼り付けます。 <tls-auth> -----BEGIN OpenVPN Static key V1----- 4c531775972122c4e399c417ea8927b6 479173396c41eb547e5447165bfac9f5 <~中略~> beb34c82b303011948c691dfb0c93b05 ef40db16e7d2cddac6bf7566164fac42 -----END OpenVPN Static key V1----- </tls-auth>
作成したファイルを.ovpnファイル(例:openvpnclient.ovpn)として保存し、PCまたはスマートフォンに転送します。
転送したファイルをOpenVPN Connectをアプリにて以下の画面で読み込ませれば設定は完了です。
.ovpnファイルをインポート後、接続可能になります。
リプレースしてみた感想
一言でいうと「軽い」に尽きます。UDPを使っているということもあり、TCPのコネクションオーバーヘッドが少なく、接続時も接続後の通信もとてもスムーズでした。
CiscoのAnyConnectは接続に5~6秒かかりましたが、OpenVPNだと1秒かかりません。15年以上前にOpenVPNを使ったときはそんなサクサクなイメージはなかったので、明らかに品質が向上したのかなと思います。
専用ハードウェアも必要ないですし、これは今後の主力になりそうです。