VPN接続をCisco ASA5505からOpenVPNに移行したお話

Linux

 

オフィスへのリモートVPN接続には長らくCisco Systems社のASA5505を使用していましたが、電源トラブルにより起動不可となってしまいました。

ただ機器としてかなり古いモデルであり、またコストをかけてリプレースする気も失せていたので、オープンソースVPNサーバのOpenVPNを導入することにしました。

元々Cisco ASAを利用する前(もう15年近く前になりますが)は実はOpenVPNを使っていたので再び古巣に戻ってきたという感覚です。

 

想定する構成

OpenVPN Network

上記のような構成です。リモートLANは自宅やモバイルルータ環境下のネットワークという想定です。

モバイルPCやスマホにインストールされたOpenVPNクライアントツールからインターネット経由でOpenVPNサーバにアクセスし、サーバ⇔クライアント間で仮想的なVPN LAN(緑色のエリア)を形成し、VPN LAN越しにローカルLANのリソース(Webサーバやファイルサーバ等)にアクセスできるようにします。

この構成ではVPN ServerはローカルLANとVPN LANを中継するルータとして機能するため「ルータ方式」と呼ばれます。クライアントにローカルLANのIPを直接割り振る「ブリッジ方式」という実装方法もありますが、ここではその方式については触れません。

VPNクライアントを論理的に別のネットワークに分けることで、ネットワーク単位での制御が容易になるため、個人的にはルータモードをオススメします。

 

事前準備

IPリソースの確認

以下、本記事では下記のIPリソースを使用するものとします。

グローバルIP

219.xx.xx.xx

ローカルネットワーク(192.168.11.0/24)
  • OpenVPNサーバ:192.168.11.148
  • Web/Fileサーバ:192.168.11.147
  • D/G:192.168.11.254
リモートネットワーク(172.24.11.0/24)
  • モバイルPC:172.24.11.100
VPNネットワーク(8.20.0.0/24)
  • OpenVPNサーバ兼D/G:8.20.0.1
  • OpenVPNクライアント:8.20.0.2

 

ルータのポート転送設定

前項の図に記載した通り、クライアントPCからのインターネット越しの接続要求(UDP:1194番)をOpenVPNサーバに届けるためにポート転送の設定をインターネットアクセスルータに設定する必要があります。

一般家庭のインターネットアクセスルータにもポート転送の設定はあると思いますが、それに関してはそれぞれの機器のマニュアルを参照してください。

ポイントとして、

  1. ルータのグローバルIPアドレスに届いたUDP:1194番の通信を、
  2. 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接続を行っている場合)。

Cisco 1812J でのポート転送 – IOS 12.4(24)T1-

 

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を使ったときはそんなサクサクなイメージはなかったので、明らかに品質が向上したのかなと思います。

専用ハードウェアも必要ないですし、これは今後の主力になりそうです。