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
SoftEtherの設定 vpncmd
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
が出現する。
dhcpでアドレスを取得
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 処理を書くことができる。
pppoe 接続時にSoftEtherでVPN接続を起動する
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 の使い方が足りなかったので調査して追記。