今回はちょっとした備忘録代わりです。
Raspberry piをGETしてからというもの、Home GatewayとしてのRaspberryが有能過ぎて、色々と活用してみたい欲に駆られています。
今回はラズパイを使って、VPNサーバを構築したいと思います。実は今までもQNAPのNASサーバを使って、L2TP
via IPsec VPNを構築してはいたんですが、なんだか色々不安定というか、使いづらいというか、元々のサーバスペック(1 core/128Mメモリ)が貧弱という理由もあってか、作動状況がとても不安定になってしまっていたんですよね。
一方ラズパイはあの小さな筐体かつて消費電力で、ハイスペック(4 core/1GBメモリ)ですから、ただのHomekitだけに使うには勿体ないですよね。なので、今回はあのラズパイにVPNサーバ化してしまおうという計画です。
そうすると一気にラズパイがHome Gatewayとしての役割が増してきて、今後の可能性が更に広がるような気がします。
先ずは構成
上記の通り、そんな大した構成ではありません。今までQNAP NASにやらせていたVPNサーバ機能を外だしするだけですね。QNAPでは色々と問題が起きた時に何が起きているのかイマイチ良くわかんなかった(中にSSHで覗けば見れるんでしょうが)のもあって、今回ラズパイを使って、自分で一から作ってしまえばもっと使いやすく(Trouble shooting含めて)なるんじゃないかと期待しています。
ラズパイのセットアップは、割愛します。以下参照してもらえばとりあえずOKだと思います。
https://qiita.com/Halhira/items/1da2ae543217be26988a
導入するのは、以下のHWとSWです。
- SoftEther VPN https://ja.softether.org/
- Raspberry Pi 3 Model B+
我が家はこのラズパイ構成にさらにIKEA Tradfri + Hue用途にも兼用させています
良く知らなかったんですが、FREEのVPNサーバ/クライアントソフトで、Linuxだけじゃなく、Windows/Mac/Solaris/FreeBSDとか色々な環境で動くみたいです。インストールの全体手順はこんな感じです。
- VPNサーバのインストール
- VPNサーバの設定
- ルーターのポート開放
- DDNSの設定
- Firewallの設定
最後のFirewallの設定は、ラズパイを外部に公開するので、ポートを規制しておかないとかなと思って、念のため入れています。前にルーターFWを入れているので、そこまで気にしなくても良いかなとも思いますが、念のため実施しておきます。
VPNサーバのインストール
#適当なVersionのファイルをDL(Linux/ARM32bit)
$wget http://jp.softether-download.com/files/softether/v4.27-9668-beta-2018.05.29-tree/Linux/SoftEther_VPN_Server/32bit_-_ARM_EABI/
# パッケージを解凍
tar zxvf softether-vpnserver-v4.27-9664-beta-2018.04.20-linux-arm_eabi-32bit.tar.gz
# フォルダごとを移動して、make
sudo mv vpnserver /usr/local
cd /usr/local/vpnserver/
sudo make
# 実行権限を付与
sudo chmod 600 *
sudo chmod 700 vpncmd
sudo chmod 700 vpnserver
インストールができているかの確認。
$ sudo ./vpncmd
vpncmd コマンド - SoftEther VPN コマンドライン管理ユーティリティ
SoftEther VPN コマンドライン管理ユーティリティ (vpncmd コマンド)
Version 4.27 Build 9668 (Japanese)
Compiled 2018/05/29 21:51:20 by yagi at pc33
Copyright (c) SoftEther VPN Project. All Rights Reserved.
vpncmd プログラムを使って以下のことができます。
1. VPN Server または VPN Bridge の管理
2. VPN Client の管理
3. VPN Tools コマンドの使用 (証明書作成や通信速度測定)
1 - 3 を選択: 3
VPN Tools を起動しました。HELP と入力すると、使用できるコマンド一覧が表示できます。
VPN Tools>check
Check コマンド - SoftEther VPN の動作が可能かどうかチェックする
---------------------------------------------------
SoftEther VPN 動作環境チェックツール
Copyright (c) SoftEther VPN Project.
All Rights Reserved.
この動作環境チェックツールを実行したシステムがテストに合格した場合は、SoftEther VPN ソフトウェアが動作する可能性が高いです。チェックにはしばらく時間がかかる場合があります。そのままお待ちください...
'カーネル系' のチェック中...
[合格] ○
'メモリ操作系' のチェック中...
[合格] ○
'ANSI / Unicode 文字列処理系' のチェック中...
[合格] ○
'ファイルシステム' のチェック中...
[Unit]
[合格] ○
'スレッド処理システム' のチェック中...
[合格] ○
'ネットワークシステム' のチェック中...
[合格] ○
すべてのチェックに合格しました。このシステム上で SoftEther VPN Server / Bridge が正しく動作する可能性が高いと思われます。
コマンドは正常に終了しました。
VPN Tools>exit
これでVPNサーバ自体はインストール完了ですが、このままだと起動等が使いづらいので、サービス化してしまいましょう。
# サービス起動ファイルの作成 (名前はお好みで)
$ sudo vim /etc/systemd/system/softether-vpn.service
[Unit]
Description=Softether VPN Server Service
After=network.target
[Service]
Type=forking
User=root
ExecStart=/usr/local/vpnserver/vpnserver start
ExecStop=/usr/local/vpnserver/vpnserver stop
Restart=on-abort
WorkingDirectory=/usr/local/vpnserver/
ExecStartPre=/sbin/ip link set dev eth0 promisc on
[Install]
WantedBy=multi-user.target
#実行権限の付与
$ chmod +x /etc/systemd/system/softether-vpn.service
# デーモンの再起動と起動確認
$sudo systemctl daemon-reload
$ sudo systemctl start softether-vpn
$ sudo systemctl status softether-vpn
● softether-vpn.service - Softether VPN Server Service
Loaded: loaded (/etc/systemd/system/softether-vpn.service; disabled; vendor preset: enabled)
Active: active (running) since Fri 2018-09-07 17:21:53 JST; 4s ago
Process: 26300 ExecStart=/usr/local/vpnserver/vpnserver start (code=exited, status=0/SUCCESS)
Process: 26296 ExecStartPre=/sbin/ip link set dev eth0 promisc on (code=exited, status=0/SUCCESS)
Main PID: 26303 (vpnserver)
CGroup: /system.slice/softether-vpn.service
├─26303 /usr/local/vpnserver/vpnserver execsvc
└─26304 /usr/local/vpnserver/vpnserver execsvc
9月 07 17:21:53 raspberrypi systemd[1]: Starting Softether VPN Server Service...
9月 07 17:21:53 raspberrypi vpnserver[26300]: The SoftEther VPN Server service has been started.
9月 07 17:21:53 raspberrypi systemd[1]: Started Softether VPN Server Service.
# 自動起動設定
$ sudo systemctl enable softether-vpn
VPNサーバの設定
このままだと単にVPNサービスが起動しているだけなので、ここからL2TP VPNサーバとしての設定を入れてあげます。私の環境はMac からのsshしかないので、全てCLIで実施していますが、Windows PCの人は、公式管理ツールがあるらしいので、
そちらを使っても良いのでは?
# 設定コマンドを起動
$ sudo ./vpncmd
1. VPN Server または VPN Bridge の管理
2. VPN Client の管理
3. VPN Tools コマンドの使用 (証明書作成や通信速度測定)
1 - 3 を選択: 1
# 仮想ハブを選択。今回は特に複数のハブを使って〜〜とは考えていないので、デフォルトのものを使ってます。
VPN Server>hub default
Hub コマンド - 管理する仮想 HUB の選択
仮想 HUB "DEFAULT" を選択しました。
コマンドは正常に終了しました。
# ユーザの作成
VPN Server/DEFAULT>usercreate
UserCreate コマンド - ユーザーの作成
ユーザー名: hoge
参加するグループ名:
ユーザーの本名:
ユーザーの説明:
コマンドは正常に終了しました。
# ユーザのパスワードの設定
VPN Server/DEFAULT>userpasswordset
UserPasswordSet コマンド - ユーザーの認証方法をパスワード認証に設定しパスワードを設定
ユーザー名: hoge
パスワードを入力してください。キャンセルするには Ctrl+D キーを押してください。
パスワード: ********
確認入力 : ********
コマンドは正常に終了しました。
# L2TPの設定
VPN Server/DEFAULT>ipsecenable
IPsecEnable コマンド - IPsec VPN サーバー機能の有効化 / 無効化
L2TP over IPsec サーバー機能を有効 (yes / no): yes
Raw L2TP サーバー機能を有効 (yes / no): no
EtherIP / L2TPv3 over IPsec サーバー機能を有効 (yes / no): no
IPsec 事前共有鍵の文字列 (9 文字以下を推奨): hogehoge
VPN 接続時に仮想 HUB 名が省略された場合のデフォルト仮想 HUB 名: default
コマンドは正常に終了しました。
# 何のコマンドが良くわからないけど、とりあえず入れておく
VPN Server/DEFAULT>securenatenable
SecureNatEnable コマンド - 仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の有効化
コマンドは正常に終了しました。
ルーターのポート開放設定
詳しくは書きませんが、WAN側からルーターにアクセスしてVPNを貼るためには、ポート開放、ポートフォワーディングをしてあげる必要があります。メーカーによって呼び方は様々ですが、要はWAN側からのアクセスをポート指定でLAN側のラズパイに投げてあげないと、VPNが貼れません。
L2TPの場合、以下のポートを開放してあげる必要があります。
esp プロトコル(プロトコル番号 50)
isakmp/UDP(ポート番号 500)
ipsec-nat-t/UDP(ポート番号 4500)l2tp/UDP(ポート番号 1701) #IPsec有りの場合は不要なので修正しました。
DDNSの設定
これもかなり重要な設定です。DNSとはと言う一般論のネットワーク話になるので、細かくは割愛しますが、、、基本的にフレッツ光とか、一般的なISPは固定グローバルIPなんてくれません。勿論お金を追加で払えばやってくれるとは思いますが、そうでなければ基本的には、グローバルIPがコロコロ変わります。 そうするとどうなるかと言うと、外部から自宅のルーターに接続するIPが変わるので、IP指定なんかでは辿り着けなくなりますね。(接続時点でのIPがわからないので。) 因みにQNAPではmyqnapcloudと言うDDNS(ダイナミックDNS)が無料で付いてくるので、そいつを使うと言うのもありです。 しかし今回はmydnsと言う国産無料DNSを使ってラズパイに設定してみたいと思います。mydnsの登録等は適当にググって貰いたいですが、これは無料の代わりに1週間に一度はIPを更新してあげないとアカウントが勝手に無効にされてしまうので、ラズパイのcrontabに仕込んで勝手にIP自動更新して貰いましょう。 基本的には10分間隔でIPをどしどし更新してもらおうと思います。 更新スクリプトは以下を参考にさせて貰いました。
http://yamamotoplog.blog38.fc2.com/blog-entry-184.html
IP更新期間については、MyDNSが8日間IP通知がない場合にサーバから警告が出てしまうので、このシェルでは7日間(約1000回)のタイミングで強制的にIP通知するようにシェルを改版しています。
# シェルフォルダを作成
$ mkdir -p /opt/scripts/mydns
# シェルの作成
$ vim /opt/scripts/update_mydns_ip.sh
#!/bin/sh
#Id password
ID=mydns494862
PASSWORD=yuAj6Dt37fG
#変数定義
HTTP="http://"
IPV6=${HTTP}${ID}:${PASSWORD}@ipv6.mydns.jp/login.html
IPV4=${HTTP}${ID}:${PASSWORD}@ipv4.mydns.jp/login.html
SCRIPT_DIR=/opt/scripts/mydns
IP_FILE=$SCRIPT_DIR/CURRENT_IP.txt
DATE_FILE=$SCRIPT_DIR/DATE.txt #未更新期間の記録
CURRENT_IP="0.0.0.0"
NEW_IP="0.0.0.0"
DATE=0
UPDATE_LOG=$SCRIPT_DIR/UPDATE.log
#前回のIP
if [ -f $IP_FILE ] ; then
CURRENT_IP=`cat $IP_FILE`
fi
#今回のIP
# curl ifconfig.co
# curl inet-ip.info
NEW_IP=`curl inet-ip.info`
#未更新期間の取得
if [ -f $DATE_FILE ] ; then
DATE=`cat $DATE_FILE`
fi
if [ $CURRENT_IP = $NEW_IP ] ; then
#未更新期間が7日以上であれば、強制的にIP通知
if [ $DATE -ge 1000] ; then
wget -q -O $SCRIPT_DIR/`date +%Y%m%d_%H%M%S`_ipv6.txt $IPV6
if [ $? = 0 ] ; then
sleep 3;
wget -q -O $SCRIPT_DIR/`date +%Y%m%d_%H%M%S`_ipv4.txt $IPV4
if [ $? = 0 ] ; then
#更新
echo $NEW_IP > $IP_FILE
echo 0 > $DATE_FILE
echo [`date +%Y%m%d_%H%M%S`] update $CURRENT_IP to $NEW_IP >> $UPDATE_LOG
fi
fi
else
#未更新期間を1つ追加
echo $((DATE += 1)) > $DATE_FILE
fi
#IPが違うのであれば、更新
else
wget -q -O $SCRIPT_DIR/`date +%Y%m%d_%H%M%S`_ipv6.txt $IPV6
if [ $? = 0 ] ; then
sleep 3;
wget -q -O $SCRIPT_DIR/`date +%Y%m%d_%H%M%S`_ipv4.txt $IPV4
if [ $? = 0 ] ; then
#更新
echo $NEW_IP > $IP_FILE
echo 0 > $DATE_FILE
echo [`date +%Y%m%d_%H%M%S`] update $CURRENT_IP to $NEW_IP >> $UPDATE_LOG
fi
fi
fi
# 実行権限の付与
$ chmod +x /opt/scripts/update_mydns_ip.sh
# crontabに記述
$ crontab -e
0,10,20,30,40,50 * * * * /opt/scripts/update_mydns_ip.sh 2>> /var/log/mydns_error.log
Firewallの設定
通常Debianだと、iptablesとかを使うらしいんですが、ワタシは仕事でCentOSの方が良く使っているので、firewalldを使うことにしました。こっちの方が馴染みがあるので・・・
# firewalldのインストール、自動起動化
$ sudo apt-get install firewalld
$ sudo systemctl enable firewalld
# ポート開放の設定
$ sudo firewall-cmd --add-service=https --zone=public –-permanent
$ sudo firewall-cmd --add-port=50/udp --zone=public –-permanent
$ sudo firewall-cmd --add-port=500/udp --zone=public –-permanent
$ sudo firewall-cmd --add-port=4500/udp --zone=public –-permanent
$ sudo firewall-cmd --add-port=1701/udp --zone=public –-permanent
# 接続インターフェイス名の確認
$ ifconfig
# 確認したインターフェイスをFirewallに紐付ける
$ sudo firewall-cmd --zone=public --change-interface=wlan0
success
# リロードさせて確認
$ sudo firewall-cmd --reload
success
$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: wlan0
sources:
services: ssh dhcpv6-client https
ports: 50/udp 500/udp 4500/udp 1701/udp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
これで全部の設定はおしまいです。
最後の確認
最後にVPNクライアント側から接続を確認します。Windows/Mac/iPhoneそれぞれの設定があると思いますが、基本的には全部一緒です。 ただWindows 10だけ、レジストリを追加でいじらないといけないらしいので注意してください。
https://www.cup.com/staticip/manual/win10_l2tp.html
- VPNタイプ:L2TP via IPsec
- IPアドレス: DDNSのドメイン名
- ユーザー:作成したユーザ名
- パスワード:作成したパスワード
- 事前共有キー:指定した文字列
コメント