前回記事
で,PINE A64+ の性能評価をした結果,特に ANSI-NI 対応であること,Gigabit Ethernet 対応であることから,VPN Server として使うことにしたと書きました.今回はその詳細の備忘録です.
VPN として何を使うか?
なるべく色々なものに対応させたいと思います.ただし,
- MacOS と iOS の対応を考慮すると,L2TP/IPSec への対応
- ANSI-NI で高速化ができること
は必須としておきます.
その上で,VPN プロトコルごとに別のサーバーソフトウェアを設定は避けたいのですが,オープンソースなものでこのような用途に対応できるのは Softether 以外知りません.したがって,まずは Softether VPN Server で L2TP/IPSec への対応を目指すことにします.
事前準備
Softether VPN Server はバイナリパッケージとして導入するのが普通なのではないかと思いますが,残念ながら arm 版は32bit版しかありません.今回のシステムは arm ですが,64bit 環境ですので,ソースコードからコンパイルすることにします.まずはその事前準備から.
Softether の Git サイト
を見ると,
- gcc
- libncurses-dev
- libreadline-dev
- make
- openssl-dev
が必要だと書いてありますが,Ubuntu の場合,openssl-dev の代わりに libssl-dev を指定しないといけません.
$ sudo apt-get install gcc libncurses5-dev libreadline-dev make libssl-dev パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下の追加パッケージがインストールされます: binutils cpp cpp-5 gcc-5 libasan2 libatomic1 libc-dev-bin libc6-dev libcc1-0 libgcc-5-dev libisl15 libitm1 libmpc3 libmpfr4 libreadline6-dev libssl-doc libtinfo-dev libubsan0 linux-libc-dev manpages manpages-dev zlib1g-dev 提案パッケージ: binutils-doc cpp-doc gcc-5-locales gcc-multilib autoconf automake libtool flex bison gdb gcc-doc gcc-5-doc libgcc1-dbg libgomp1-dbg libitm1-dbg libatomic1-dbg libasan2-dbg liblsan0-dbg libtsan0-dbg libubsan0-dbg libcilkrts5-dbg libmpx0-dbg libquadmath0-dbg glibc-doc ncurses-doc readline-doc make-doc man-browser 以下のパッケージが新たにインストールされます: binutils cpp cpp-5 gcc gcc-5 libasan2 libatomic1 libc-dev-bin libc6-dev libcc1-0 libgcc-5-dev libisl15 libitm1 libmpc3 libmpfr4 libncurses5-dev libreadline-dev libreadline6-dev libssl-dev libssl-doc libtinfo-dev libubsan0 linux-libc-dev make manpages manpages-dev zlib1g-dev アップグレード: 0 個、新規インストール: 27 個、削除: 0 個、保留: 0 個。 22.4 MB のアーカイブを取得する必要があります。 この操作後に追加で 90.1 MB のディスク容量が消費されます。 続行しますか? [Y/n] 取得:1 http://ports.ubuntu.com xenial/main arm64 libmpfr4 arm64 3.1.4-1 [173 kB] ....
依存関係でかなりたくさんのパッケージが入ります.
Softether のコンパイルと AES-NI 対応についての注意
次は,Git で Softether のソースコードを取得し,コンパイルする準備をします.
$ cd /usr/local/src $ sudo git clone https://github.com/SoftEtherVPN/SoftEtherVPN.git $ cd SoftEtherVPN $ sudo ./configure
このままだと /usr 以下にいろいろ入るので,Makefile を以下の通り変更して,/usr/local 以下に入る様調整します.
$ sudo vi Makefile ..... INSTALL_BINDIR=/usr/local/bin/ INSTALL_VPNSERVER_DIR=/usr/local/vpn/vpnserver/ INSTALL_VPNBRIDGE_DIR=/usr/local/vpn/vpnbridge/ INSTALL_VPNCLIENT_DIR=/usr/local/vpn/vpnclient/ INSTALL_VPNCMD_DIR=/usr/local/vpn/vpncmd/ .....
なお,2ch(今は 5ch かな?)を見ると,-m64 を削除しないと make できないような記述が見つかるのですが,実際にはやらなくても make できてしまいます(いろいろ WARNING は出るが).
$ sudo make $ sudo make install
ところで,Softether VPN Server はインテルのライブラリを用いて AES-NI を有効化する方法があるようです.
そのためには,Intel の AES-NI ライブラリを利用できる様コンパイルしなければならないのですが,そのソースコードを眺めると,x86 のインラインアセンブラで CPU の種類を判定している部分があります.当然,この部分は arm ではコンパイル不能ですし,私にはどうやって直したら良いのかも分からないので,今回は,Softether でインテルのライブラリを用いた AES-NI の有効化はあきらめました.
ただし,だからと言って,AES-NI の効果がないとは言えないと思っています.
と言うのも,Softether VPN Server は openssl の evp 関数を用いて暗号化を行っている様です(このあたり参照).前回記事を見てもらえるとわかりますが,evp を使う場合は,AES-NI による高速化が行われているみたいなので,結局,openssl のライブラリ経由で AES-NI 対応になるんじゃないかと.ただし,きちんとソースコードを追っかけた訳じゃありません.識者の方おられましたらお教えいただけると有り難いです.
Bridge インターフェースの準備
Softether のコンパイルとインストールが済んだら,次は Bridge インターフェース(br0)の準備を行います.と言うのも,
に説明があるのですが,Softether とLANのインターフェース(今回は eth0)を直接ブリッジしてしまうと,VPN 経由で当該インターフェースにアクセスできなくなってしまうからで,これを避けるため,Linux の仮想ネットワークデバイス(tap_se0)と eth0 を br0 にブリッジさせることにします.なお,もちろん,VPN 経由で eth0 にアクセスできなくて構わないのであればこの節の内容は省力して構わない訳です(セキュリティ的にはこちらの方が望ましいかもしれない).
このためには,まず,ネットワークブリッジの作成等を行うパッケージを導入します.
$ sudo apt-get install bridge-utils
次にブリッジインターフェース(今回は br0)を起動時に作成するよう設定します.
$ vi /etc/network/interfaces.d/br0 auto br0 iface br0 inet static address 192.168.0.10 netmask 255.255.255.0 network 192.168.0.0 broadcast 192.168.0.255 gateway 192.168.0.1 dns-nameservers 192.168.0.1 dns-search hyt.net bridge_ports eth0 bridge_stp off bridge_maxwait 3
なお,今回は固定アドレスとしましたが,
- iface br0 inet static ⇒ iface br0 inet dhcp
のように記せば DHCP による割り当ても可能です(目的から言って固定にするのが普通だと思いますが).
インターフェース eth0 は br0 にブリッジされるので,アドレスの割当は行わないよう,以下の通り設定を変更します.
$ sudo vi /etc/network/interfaces.d/eth0 auto eth0 iface eth0 inet manual
正しく設定できていれば,再起動後,以下の様な感じになるはずです.
$ ifconfig br0 Link encap:Ethernet HWaddr **:**:**:**:**:** inet addr:192.168.0.10 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::****:****:****:****/64 Scope:Link inet6 addr: fd00::****:****:****:****/64 Scope:Global inet6 addr: fd00::****:****:****:****/64 Scope:Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:233 errors:0 dropped:19 overruns:0 frame:0 TX packets:278 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:16575 (16.5 KB) TX bytes:28917 (28.9 KB) eth0 Link encap:Ethernet HWaddr **:**:**:**:**:** UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:234 errors:0 dropped:0 overruns:0 frame:0 TX packets:280 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:20006 (20.0 KB) TX bytes:32977 (32.9 KB) Interrupt:114 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:80 errors:0 dropped:0 overruns:0 frame:0 TX packets:80 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:5920 (5.9 KB) TX bytes:5920 (5.9 KB) $ $ brctl show bridge name bridge id STP enabled interfaces br0 8000.76a705f16524 no eth0
Softether の初期設定と仮想インターフェースのブリッジの設定
正直,Softether の初期設定は,コマンドラインからではなく,GUI 版の「SoftEther VPN サーバー管理マネージャ」を使った方が分かり易いのですが,今回はあえてコマンドラインから設定していくことにします(GUI 設定アプリを導入するのが面倒だった).
まず,vpnserver を起動と終了をテストします.
$ sudo vpnserver start [sudo] password for hyt: The SoftEther VPN Server service has been started. $ sudo vpnserver stop
次に,Softether の DDNS 機能を無効化します.Softether VPN Server はデフォルトで Softether 社が運営する DDNS サーバーを用いるようになっているのですが,今回は Softether のものではなく,ルーターの DynamicDNS 機能を利用するからです.これは,vpnserver の設定ファイルの DDnsClient ディレクティブを無効にすることで行えます.
$ sudo vpnserver stop $ sudo vi /usr/local/vpn/vpnserver/vpn_server.config .... declare DDnsClient^M {^M bool Disabled true^M ..... $ sudo vpnserver start
なお,Softether の設定ファイルは DOS 形式の改行コードを持つことから,vi で編集するときは行末に ^M が表示されますが,そのまま編集していることに注意してください.
次に,vpncmd で Softether の設定を行います.
$ vpncmd vpncmd コマンド - SoftEther VPN Developer Edition コマンドライン管理ユーティリティ SoftEther VPN コマンドライン管理ユーティリティ (vpncmd コマンド) Developer Edition Version 4.23 Build 9647 (Japanese) Compiled 2017/10/19 14:28:18 by yagi at pc37 Copyright (c) SoftEther VPN Project. All Rights Reserved. vpncmd プログラムを使って以下のことができます。 1. VPN Server または VPN Bridge の管理 2. VPN Client の管理 3. VPN Tools コマンドの使用 (証明書作成や通信速度測定) 1 - 3 を選択: 1 接続先の VPN Server または VPN Bridge が動作しているコンピュータの IP アドレスまたはホスト名を指定してください。 'ホスト名:ポート番号' の形式で指定すると、ポート番号も指定できます。 (ポート番号を指定しない場合は 443 が使用されます。) 何も入力せずに Enter を押すと、localhost (このコンピュータ) のポート 443 に接続します。 接続先のホスト名または IP アドレス:(Enterを入力) サーバーに仮想 HUB 管理モードで接続する場合は、仮想 HUB 名を入力してください。 サーバー管理モードで接続する場合は、何も入力せずに Enter を押してください。 接続先の仮想 HUB 名を入力:(Enterを入力) VPN Server "localhost" (ポート 443) に接続しました。 VPN Server 全体の管理権限があります。 VPN Server>
まず,vpnserver のパスワードを設定します.
VPN Server>ServerPasswordSet ******************
次に仮想スイッチ DEFAULT (標準で定義されている)と tap デバイスをブリッジします.
VPN Server>BridgeCreate DEFAULT /DEVICE:se0 /TAP:yes .... VPN Server>BridgeList BridgeList コマンド - ローカルブリッジ接続の一覧の取得 番号|仮想 HUB 名|ブリッジ先 LAN カードまたは tap デバイス名|状態 ----+-----------+------------------------------------------+------ 1 |DEFAULT |se0 |動作中 コマンドは正常に終了しました。 VPN Server>
次に,現時点で有効な VPN 接続方式を確認し,L2TP over IPSEC(事前共有鍵 xxxxxx)のみを有効にします.
VPN Server>IpSecGet IPsecGet コマンド - IPsec VPN サーバー機能の現在の設定の取得 項目 |値 ----------------------------------------------+------- L2TP over IPsec サーバー機能は有効 |いいえ Raw L2TP サーバー機能は有効 |いいえ EtherIP / L2TPv3 over IPsec サーバー機能は有効|いいえ IPsec 事前共有鍵の文字列 |vpn デフォルト仮想 HUB 名 |DEFAULT コマンドは正常に終了しました。 VPN Server>>OpenVpnGet OpenVpnGet コマンド - OpenVPN 互換サーバー機能の現在の設定を取得 項目 |値 ------------------------------+---- OpenVPN 互換サーバー機能が有効|はい UDP ポート番号一覧 |1194 コマンドは正常に終了しました。 VPN Server>SstpGet SstpGet コマンド - Microsoft SSTP VPN 互換サーバー機能の現在の設定を取得 項目 |値 -------------------------------+---- SSTP VPN 互換サーバー機能が有効|はい コマンドは正常に終了しました。 VPN Server>IPsecEnable /L2TP:yes /L2TPRAW:no /ETHERIP:no /PSK:xxxxxx /DEFAULTHUB:DEFAULT IPsecEnable コマンド - IPsec VPN サーバー機能の有効化 / 無効化 コマンドは正常に終了しました。 VPN Server>OpenVpnEnable no OpenVpnEnable コマンド - OpenVPN 互換サーバー機能を有効化 / 無効化 UDP ポート番号の一覧 (標準は 1194 / 複数指定可): 1194 コマンドは正常に終了しました。 VPN Server>SstpEnable no SstpEnable コマンド - Microsoft SSTP VPN 互換サーバー機能を有効化 / 無効化 コマンドは正常に終了しました。 VPN Server>IPsecGet IPsecGet コマンド - IPsec VPN サーバー機能の現在の設定の取得 項目 |値 ----------------------------------------------+-------- L2TP over IPsec サーバー機能は有効 |はい Raw L2TP サーバー機能は有効 |いいえ EtherIP / L2TPv3 over IPsec サーバー機能は有効|いいえ IPsec 事前共有鍵の文字列 |xxxxxx デフォルト仮想 HUB 名 |DEFAULT コマンドは正常に終了しました。 VPN Server>OpenVpnGet OpenVpnGet コマンド - OpenVPN 互換サーバー機能の現在の設定を取得 項目 |値 ------------------------------+------ OpenVPN 互換サーバー機能が有効|いいえ UDP ポート番号一覧 |1194 コマンドは正常に終了しました。 VPN Server>SstpGet SstpGet コマンド - Microsoft SSTP VPN 互換サーバー機能の現在の設定を取得 項目 |値 -------------------------------+------ SSTP VPN 互換サーバー機能が有効|いいえ コマンドは正常に終了しました。 VPN Server>
ここまでで,いったん vpncmd を終了させ,インターフェースの状態を見ると,以下の様になるはずです.
VPN Server>quit $ $ ifconfig br0 Link encap:Ethernet HWaddr **:**:**:**:**:** inet addr:192.168.0.10 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::****:****:****:****/64 Scope:Link inet6 addr: fd00::****:****:****:****/64 Scope:Global inet6 addr: fd00::****:****:****:****/64 Scope:Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:233 errors:0 dropped:19 overruns:0 frame:0 TX packets:278 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:16575 (16.5 KB) TX bytes:28917 (28.9 KB) eth0 Link encap:Ethernet HWaddr **:**:**:**:**:** UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:11711 errors:0 dropped:3 overruns:0 frame:0 TX packets:11347 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1155369 (1.1 MB) TX bytes:1269059 (1.2 MB) Interrupt:114 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:288 errors:0 dropped:0 overruns:0 frame:0 TX packets:288 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:95344 (95.3 KB) TX bytes:95344 (95.3 KB) tap_se0 Link encap:Ethernet HWaddr **:**:**:**:**:** inet6 addr: fe80::****:****:****:****/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:42 errors:0 dropped:0 overruns:0 frame:0 TX packets:111 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:3612 (3.6 KB) TX bytes:9162 (9.1 KB)
最後にブリッジインターフェースである br0 とブリッジします.ただし,この設定は再起動後に消えてしまうことに注意が必要です.
$ sudo brctl addif br0 tap_se0 $ brctl show bridge name bridge id STP enabled interfaces br0 8000.00acff0fb787 no eth0 tap_se0
利用者の作成と仮想スイッチの設定
次は VPN の利用者(今回は vpnuser とします)の作成と仮想スイッチの設定を行います.
$ vpncmd vpncmd コマンド - SoftEther VPN Developer Edition コマンドライン管理ユーティリティ SoftEther VPN コマンドライン管理ユーティリティ (vpncmd コマンド) Developer Edition Version 4.23 Build 9647 (Japanese) Compiled 2017/10/19 14:28:18 by yagi at pc37 Copyright (c) SoftEther VPN Project. All Rights Reserved. vpncmd プログラムを使って以下のことができます。 1. VPN Server または VPN Bridge の管理 2. VPN Client の管理 3. VPN Tools コマンドの使用 (証明書作成や通信速度測定) 1 - 3 を選択: 1 接続先の VPN Server または VPN Bridge が動作しているコンピュータの IP アドレスまたはホスト名を指定してください。 'ホスト名:ポート番号' の形式で指定すると、ポート番号も指定できます。 (ポート番号を指定しない場合は 443 が使用されます。) 何も入力せずに Enter を押すと、localhost (このコンピュータ) のポート 443 に接続します。 接続先のホスト名または IP アドレス:(ENTERを入力) サーバーに仮想 HUB 管理モードで接続する場合は、仮想 HUB 名を入力してください。 サーバー管理モードで接続する場合は、何も入力せずに Enter を押してください。 接続先の仮想 HUB 名を入力: DEFAULT VPN Server "localhost" (ポート 443) に接続しました。 VPN Server 内の仮想 HUB 'DEFAULT' に対する管理権限があります。 VPN Server/DEFAULT>
まずは,仮想スイッチのパスワードを設定します.
VPN Server・DEFAULT>SetHubPassword *****************
次に,利用者として vpnuser を登録します.
VPN Server/DEFAULT>UserCreate vpnuser /GROUP:none /REALNAME:none /NOTE:none VPN Server/DEFAULT>UserPasswordSet vpnuser /PASSWORD:****************
ここまで設定出来たら,ルーターの DynamicDNS の設定や,ポートの解放(今回は L2TP over IPSEC なので,たぶん UDP 500 と 4500)の設定を行い,クライアント(ios, MacOS Windows 等)から接続試験を行います.なお,
- ID: vpnuser
- Password: (設定した vpnuser のパスワード)
- 共有鍵: vpn
です.また,MacOS や iOS の設定や DynamicDNS の設定は本 blog では解説しません.
などをご覧ください.
無事接続できることを確認できたら,次は vpnserver が起動時にサービスとして自動的に起動する様設定を行います.
Softether のサービス化
最近の Linux ディストリビューションだと,systemd を用いてサービス化するのが普通だと思うのですが,Ubuntu 16.04 の場合は昔ながらの init.d 以下にサービスを登録する方法も使えるようです.実際,/etc/init.d 以下をみると,
$ ls /etc/init.d/ README kmod resolvconf alsa-utils mountall-bootclean.sh rsync bootmisc.sh mountall.sh rsyslog checkfs.sh mountdevsubfs.sh sendsigs checkroot-bootclean.sh mountkernfs.sh single checkroot.sh mountnfs-bootclean.sh skeleton console-setup mountnfs.sh ssh cron networking udev dbus ondemand umountfs halt procps umountnfs.sh hostname.sh rc umountroot hwclock.sh rc.local unattended-upgrades keyboard-setup.dpkg-bak rcS urandom killprocs reboot
の様にずらっと見慣れたファイルがありますので,これに習い,今回は /etc/init.d 以下に vpnserver のサービス化ファイルを配置することにしました.
$ sudo vi /etc/init.d/vpnserver #!/bin/sh ### BEGIN INIT INFO # Provides: vpnserver # Required-Start: $local_fs $network # Required-Stop: $local_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: SoftEther VPN Server # Description: Start vpnserver daemon SoftEther VPN Server ### END INIT INFO DAEMON=/usr/local/vpn/vpnserver/vpnserver LOCK=/var/lock/vpnserver . /lib/lsb/init-functions test -x $DAEMON || exit 0 case "$1" in start) sleep 3 log_daemon_msg "Starting SoftEther VPN Server" "vpnserver" $DAEMON start >/dev/null 2>&1 touch $LOCK log_end_msg 0 sleep 3 tap=`/sbin/ifconfig -a| awk '$1 ~ /^tap/ {print $1}'` /sbin/brctl addif br0 tap_se0 ;; stop) log_daemon_msg "Stopping SoftEther VPN Server" "vpnserver" $DAEMON stop >/dev/null 2>&1 rm $LOCK log_end_msg 0 sleep 2 ;; restart) $DAEMON stop sleep 2 $DAEMON start sleep 5 tap=`/sbin/ifconfig -a| awk '$1 ~ /^tap/ {print $1}'` /sbin/brctl addif br0 tap_se0 ;; status) if [ -e $LOCK ] then echo "vpnserver is running." else echo "vpnserver is not running." fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 esac exit 0 $ $ sudo chmod +x /etc/init.d/vpnserver $ sudo update-rc.d vpnserver defaults $ sudo systemctl daemon-reload $ sudo vpnserver stop $ sudo service vpnserver start
なお,途中で sudo systemctl daemon-reload としているのは,service コマンドで起動しようとすると WARNNING が出るからです.どうも ubuntu の場合,init.d 以下にサービス化ファイルを作ったとしても,init ではなく systemd を用いてサービスを起動しているようですね.これを見ると初めから systemd でサービス化する設定ファイルを準備した方が良かったかもしれません.
きちんと全て正常に動くかどうか再起動して試して終了です.
Softether のリージョンロック?
ここまででとりあえず最低限 L2TP/IPSec で接続できる VPN Server ができあがるはずです.Softether 自体は,L2TP/IPSec 以外にも
- Softether
- PPTP
- OpenVPN
- SSTP
- L2TPv3
- EtherIP
など,おおよそ考えうる限りの方式に対応した VPN サーバーとして振る舞えますが,その設定方法については,Softether のマニュアル
を参照してください.また,今回は最低限 L2TP/IPSec サーバとして動くよう設定しただけです.外部に公開されるサービスですので,追加的なファイヤーウォールの設定や監視等も必ず行なわなければならないことにご注意ください.
なお,参考にさせて頂いた記事
を見ると,リージョンロックなる文言があり,何のことかと追ってみると,これは
の通り,RADIUS 認証や固有証明書認証のロックのことらしいです.これを外すかどうかは自己責任とありますが,もちろん今回は見送りとしています.でも,この機能があれば,Windows の Radius と暗号化ありで連携できる可能性が高い訳で,以前の本件についての記事
で暗号化できないのが問題だと書きましたが,これがどうにかできるかもしれないと言うことです.しかしもちろんこんなこと個人レベルでやるようなことではないですし,実験的ならともかく本格的に利用するつもりなら当然 Softether の有料版を使うべきでしょうね.
以上!