openWrt で softether のVPNをルーティングする
openwrt に vpn 拠点間接続をやらせてみる
リモート側のネットワークの設定やマスカレードなどは済んでいる状態。OpenWRTからリモートへ接続する
Host-->openwrt--<SoftEtherVPN>--VPN Server--(office network)--10.193.3.40
細かいことは抜いておいて、相手先のネットワークのサーバーにアクセスできればいい。
openwrt に softether のクライアントを入れる
opkg install softethervpn-client
vpnclient
と vpncmd
が導入される。
インストールするとClientが起動している
localhost で SoftEther のクライアントが起動している。起動を確認しておく。
root@OpenWrt:~# ps auxf | grep softethervpn
root 2116 0.0 0.0 6644 1600 ? S<s 03:48 0:00 /usr/libexec/softethervpn/vpnclient execsvc
root 2119 0.9 0.1 23000 16528 ? S<l 03:48 0:02 \_ /usr/libexec/softethervpn/vpnclient execsvc
このあたりはmacOS/Ubuntu で接続するときと同じ
vpncmd /CLIENT localhost /CMD NicCreate
vpncmd /CLIENT localhost /CMD AccountList
vpncmd /CLIENT localhost /CMD AccountCreate
vpncmd /CLIENT localhost /CMD AccountPasswordSet
vpncmd /CLIENT localhost /CMD AccountConnect ocn
vpncmd /CLIENT localhost /CMD AccountList
コマンド |
設定値 |
NicCreate |
soeth0 |
AccountCreate |
/name:ocn /nic:soeth0 /hub=Vpn /remote=vpn.my-office.jp:443 |
AccountPasswordSet |
パスワード |
上記のとおりにコマンドをいれてもいいが、毎回毎回訊かれるのが面倒。
コマンドの引数を使ってコピペ可能にする。
## 共通化
alias vpncmd='vpncmd /CLIENT localhost /CMD ' # コマンド省略
conn=ocn-tak # 接続名
## 接続作成
vpncmd NicCreate soeth0
vpncmd AccountCreate $conn /SERVER:vpn.ocn.ac.tld:443 /USERNAME:takuya1234 /HUB:USER_HUB /NICNAME:vpn_soeth0
vpncmd /CLIENT localhost /CMD AccountPasswordSet $conn /PASSWORD:mypassword /TYPE:radius
## 接続と確認
vpncmd /CLIENT localhost /CMD AccountConnect $conn
vpncmd /CLIENT localhost /CMD AccountList
vpncmd /CLIENT localhost /CMD AccountStatusGet $conn
## 切断と確認
vpncmd /CLIENT localhost /CMD AccountDisConnect $conn
vpncmd /CLIENT localhost /CMD AccountList
vpncmd /CLIENT localhost /CMD AccountStatusGet $conn
接続すると、Nicの名前に vpn_
がプレフィックスされたインターフェイスが現れる。
今回は、Nic の名前を soeth0
としたので、 vpn_soeth0
が出現する。
openwrt の場合、udhcp を使えばいいので、それ用のスクリプトを用意する。
アドレス取得時に、最低限のルーティングを行うのだが
最初は動作確認のために、ルーティングは書かずにアドレスだけもらっておく。
ルーティングは動作確認後に後で追記する。
etc/config/custom/softether/dhcp.sh(ルーティングなし)
#!/usr/bin/env bash
setup_interface() {
echo "udhcpc: ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}"
ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
# info
echo router=${router}
}
case "$1" in
deconfig)
ifconfig "$interface" 0.0.0.0
;;
renew)
setup_interface update
;;
bound)
setup_interface ifup
;;
esac
udhcp でアドレス取得
これで、IPアドレスが取得される。
udhcpc -i vpn_soeth0 -s /etc/config/custom/softether/dhcp.sh
ルーティング
仮想Hub経由してルータに接続する。
ping 10.35.225.254
ルータに接続できたら、GWとして、ルーティングを入れてやる。
ip route add 10.193.3.0/24 via 10.35.225.254 dev vpn_soeth0
ルーティングテーブル追加の確認。pingで接続を確認する。
ping 10.193.3.40
これで、OpenWRTから、リモート側のPCまで到達できた。
VPN接続を共有する(マスカレード)
OpenWRTにルータらしく、NATとマスカレードをして、ローカル側にVPN接続を共有させる。
要は、マスカレードとフォワーディングを入れてやる。
VPN_IF=vpn_soeth0
iptables -I FORWARD -o $VPN_IF -j ACCEPT
iptables -t nat -A POSTROUTING -o $VPN_IF -j MASQUERADE
共有を確認する
192.168.1.100 から 10.193.3.40へ接続を確認する
takuya@work $ ssh 192.168.1.100
takuya@192.168.1.100 $ ping 10.193.3.40
パケットが応答されたので、接続できた。
設定を永続化する。
最後に、udhcp の起動スクリプトに、これらのルーティングを書き加える。
etc/config/custom/softether/dhcp.sh(ルーティング追加)
#!/usr/bin/env bash
setup_interface() {
echo "udhcpc: ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}"
ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
### 追加
# routing
ip route add 10.193.3.0/24 via ${router} dev ${interface}
# masquerade
iptables -I FORWARD -o ${interface} -j ACCEPT
iptables -t nat -A POSTROUTING -o ${interface} -j MASQUERADE
}
case "$1" in
deconfig)
ifconfig "$interface" 0.0.0.0
;;
renew)
setup_interface update
;;
bound)
setup_interface ifup
;;
esac
動作チェックする。
## iptables を初期化して
service firewall restart
## ip を解放してルーティング・テーブルをリセット
ifconfig vpn_soeth0 0.0.0.0
## softether を切断
vpncmd /CLIENT localhost /CMD AccountDisConnect ocn
## softethre を接続
vpncmd /CLIENT localhost /CMD AccountConnect ocn
## dhcp 取得とルーティング設定
udhcpc -i vpn_soeth0 -s /etc/config/custom/softether/dhcp.sh
接続を切断して、再接続し、dhcp を再取得、udhcが指定スクリプトを動かす。
udhcp が取得後に、指定スクリプトを実行して、ipアドレス設定とルーティングを設定コマンドを流してくれる。
この一連の流れをコマンド化
/etc/config/custom/softether/start-my-softether-connection.sh
vpncmd /CLIENT localhost /CMD AccountDisConnect ocn
vpncmd /CLIENT localhost /CMD AccountConnect ocn
udhcpc -i vpn_soeth0 -s /etc/config/custom/softether/dhcp.sh
udhcpc の接続をrenew/releaseする
udhcpc は常駐させるモードと常駐させないモードが有る。
udhcpc -S -C -i $VPN_IF -s $UDHCP_SCRIPT # プロセスが常駐する
udhcpc -q -S -C -i $VPN_IF -s $UDHCP_SCRIPT # 実行したら終わり。プロセスは常駐しない。
プロセスを常駐している場合、シグナルで、renew/releaseが可能になる。
## dhcp を renew する
pkill -USR1 -f "udhcpc -S -C -i $VPN_IF -s $UDHCP_SCRIPT"
## dhcp を release する
pkill -USR2 -f "udhcpc -S -C -i $VPN_IF -s $UDHCP_SCRIPT"
それぞれ、終了後にスクリプト実行して、ルーティングなどの処理を追加することができる。
割当解放(リリース)した場合は /bin/sh $UDHCP_SCRIPT deconfig
が呼ばれ、割当更新(renew)した場合は、/bin/sh $UDHCP_SCRIPT renew
がそれぞれの引数(deconfig , renew, bound
)をつけて実行される。
この引数を使ってdhcp割当・解放・更新のスクリプトを書くことができる。
スクリプト例
# router, interface ip の変数はudhcpcから渡される
function cleanup_interface(){
## ルーティング解放・IP割当解除などの処理
nft del table my_vpn
ip route del ${DEST_NET} via ${router} dev ${interface}
ifconfig $interface 0.0.0.0
}
function setup_interface (){
## IP割当処理、ルーティング作成などの処理
ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
ip route add ${DEST_NET} via ${router} dev ${interface}
nft add table my_vpn
}
case "$1" in
deconfig)
cleanup_interface
;;
renew)
setup_interface update
;;
bound)
setup_interface ifup
;;
esac
常駐している場合にシグナルを受け取って片付けのdeconf 処理を書くことができる。
ppooe 接続時にスクリプトを動かすには、hotplug.d を使えばいいので、hotplug で実行するスクリプトを作る。
PPPoEが起動したら、間髪入れず、SoftEther を接続しに行くようにする。
/etc/hotplug.d/iface/99-softether
#!/usr/bin/env bash
## PPPoE接続後に、 スクリプトを実行する
## iface の変化後に、TARGET_INTERFACEで検出して任意のフックが可能
## main
function main(){
TARGET_INTERFACE=pppoe-XXX
TARGET_DEVICE=eth1
###
[ "$ACTION" = "ifup" -a "$INTERFACE" = "$TARGET_INTERFACE" ] && {
# log sample
logger "iface $TARGET_INTERFACE / $TARGET_DEVICE up detected, do hotplug actions."
sleep 10;
/etc/config/custom/softether/start-my-softether-connection.sh
}
}
main
最後の最後に、再接続チェック
ネットワークを再起動して、pppoe接続後にsoftether がちゃんと接続されて、ルーティングとマスカレードされることを確認する。
root#openWrt $ service network restart
注意点
実験用openWrt ルータはx86/ext4 で動作しているので、パッケージを容量気にせずに入れている。
bash / iproute2 / iptables-full など割と大きめのパッケージを入れて、そのへんのubuntu とおなじような動作しているので、容量がシビアなwrt だとこの方法だとうまくイカないかもしれない。
2023-08-29 追記
接続コマンドと作成コマンドをダイアログではなくコマンド引数で与えるようにメモを更新。
2023-08-30 追記
udhcpc の使い方が足りなかったので調査して追記。
参考資料