2021年12月31日金曜日

NetBSDとRaspberry Pi OS でOpenVPNを使った拠点間L2VPNの構築

自宅と実家をL2VPNで結びたくなったのでOpenVPNで繋ぐことにした。
自宅には前からあるNetBSD/amd64 9.2をOpenVPNのサーバとして使い、実家側にはラズパイを買って設置することにした。値段とか気にせずクリックしたらRaspberry Pi4 ModelB 4GBに必要な機材一式のセットを選んでいた。
試行錯誤して、やっとわかってきた。

・OpenVPNの設定以外にOS側のインターフェイスの設定が必要である。
・NetBSDとRaspberry Pi OSではbridgeインターフェイスの仕様が違う(NetBSDはbridgeインターフェイスにIPアドレスが付与できず、Raspberry Pi OSでは付与できる)
・L2VPNなので同一サブネットを共有するので拠点ごとにIPアドレスがぶつからない様に設計しておく。

いったん実家にもっていく前に自宅で試験環境を作成してやってみた。
構成はこんな感じ。




〇全般の設計
・共有するサブネットは192.168.0.0/24とする。
・サーバ側拠点は192.168.0.1~99、クライアント側拠点は192.168.0.100~254を利用する。
・デフォルトゲートウェイはサーバ側拠点は192.168.0.1、クライアント側拠点は192.168.0.100とする。
・OpenVPNはUDPでVPNを構築する。ポート番号をデフォルトの1194/UDPから(このblogでは)31194/UDPに変える。
・IPv4の事しか考えない。
・サーバ側拠点のグローバルIPアドレスは常時接続の為、滅多に変わらない事から自分で保有しているドメイン空間から切り出してAレコードで登録する。登録するDNSは個人契約のO365のサービスの中にあったので登録する。このblogでは「vpn.example.com」とする。
・今のところサーバ側、クライアント側でProxyArpの設定やFirewallの設定は無くても動いている。

〇NetBSD側(サーバ側)の対応
・クライアントから接続を受けるのでブロードバンドルータの設定を変更し外から31194/UDPがNetBSD側(サーバ側)に転送されるように設定(ポートフォワーディング)する。
・pkginを使い「openvpn-2.5.3」と「easy-rsa-3.0.8」を入れる。
・(メモ)netbsdのifconfigで一時的にIPアドレスを消すのは「ifconfig wm0 inet 192.168.0.3 delete
」という文法

1. インターフェイス側の設定を行う
・物理IF名はwm0のみである。
・wm0はIPアドレスを与えないため、「/etc/ifconfig.wm0」を作成し中身は「up」のみ記載。
・tap0インターフェイスが必要で、IPアドレスも付与するので「/etc/ifconfig.tap0」に下記の内容を記述する(「The NetBSD Guide」の「24.6. Setting up a network bridge device」にあるExample 24.10にドンピシャの設定が書いてあった。このtap0の設定の中でbridgeも設定してしまえば確かにブリッジの設定前にtap-IFが出来ていない依存関係が解決されるや
)。
---
create
inet 192.168.0.3 netmask 255.255.255.0
up
!ifconfig bridge0 create
!brconfig bridge0 add $int add wm0 up
---

・bridgeインターフェイスも必要だがtapの設定中で作成しているので不要
・「/etc/rc.conf」にはインターフェイスの設定は特に記載しない。
・ここで試しに再起動してみて、外部からsshなど出来るか、ネットワークインターフェイスやブリッジインターフェイスの状態、ルーティングテーブルの状態を確認すると区切りは良いでしょう。

tcpdumpでインターフェイスを指定してキャプチャして動作をみるとかも切り分けに良いかと。

ifconfig:
・wm0,bridge0,tap0はUPになっているか
・wm0,tap0は「PROMISC」が入っているか(netbsdのNW-IFはbridge-IFに参加すると自動でプロミスキャスモードになる)
・IPv4アドレスは、wm0のみに設定されているか
netstat -rn:
・defaultを含め、出力先IFがtap0になっているか(普通は物理IF(今回だとwm0)だが、今回はVPNの関係でtap0が出力先IFになる)。
brconfig bridge0:
・Interfacesにtap0とwm0が存在するか
・Address cacheに色々なMACアドレスが乗ってきているか。


2. OpenVPNのTLSの設定
証明書のくだりは全て下記のサイトに書いている通りに実施
VPNサーバー構築(OpenVPN) - CentOSで自宅サーバー構築 (centossrv.com)

3. OpenVPNの設定ファイル
・設定ファイル「server.conf」を「/usr/pkg/etc/openvpn」に設置。
・設定ファイルの中身は下記。動作のログはもともとこのサーバがsyslog.conf側で「*.info」を特定ファイルに書き出しているので、そっちに吐かれている
---
port 31194
proto udp
dev tap0
ca pki/ca.crt
cert pki/issued/server.crt
dh pki/dh.pem
server-bridge
keepalive 10 120
cipher AES-256-CBC
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
verb 3
explicit-exit-notify 1
---

4. openvpnの起動設定
・起動ファイルのコピー「cp -p /usr/pkg/share/examples/rc.d/openvpn /etc/rc.d/」
・自動起動の設定「/etc/rc.conf」に「openvpn=YES」を追記する。
・この状態でrootにて「/etc/rc.d/openvpn start」としてログに「openvpn[2711]: Initialization Sequence Completed」が出ていれば待ち受け出来ている。
・プロセスなどをpsコマンドで見ておくと「/usr/pkg/sbin/openvpn --cd /usr/pkg/etc/openvpn --daemon --config server.conf」というプロセスが見える。
・sockstatでプロセス名でgrepをかければ「nobody   openvpn    2711   7 udp6   *.31194               *.*」が見える
・最後に再起動してみて、プロセスの状態やログが目的の通りであれば設定完了。

Raspberry Pi OS側(クライアント側)の対応
・必要なソフトのインストール
apt-get install openvpn
apt-get install tcpdump
apt-get install bridge-utils
・あると便利なツール
apt-get install locate
apt-get install emacs
・クライアントから最初のUDPを送るのでブロードバンドルータの設定は不要。
・(メモ)Raspberry Pi OSのifconfigで一時的にIPアドレスを消すのは「ifconfig eth0 0.0.0.0
」(この文法、気持ち悪い...)という文法
・なお私は
Raspberry Pi OSを含めLinux系のシステム管理は良く分からないのでググって適当にやっています。


1.
インターフェイス側の設定を行う
・eth0は、IPアドレスをつけずにUPだけさせる。
・「/etc/dhcpcd.conf」に下記を記述
---
interface eth0
static ip_address=0.0.0.0/0
---
・bridgeインターフェイスをbr0という名前で作成し、tapインターフェイスはtap0という名前で作成し、br0のブリッジにeth0とtap0を参加させる。
・「
/etc/network/interfaces」に下記を記述する。
---
auto br0
iface br0 inet static
    address 192.168.0.103
    netmask 255.255.255.0
    network 192.168.0.0
    broadcast 192.168.0.255
    gateway 192.168.0.101
    dns-nameserver 192.168.0.101
    bridge-ports eth0 tap0
    bridge_stp off
    bridge_maxwait 0
    bridge_fd      0
    pre-up ip tuntap add dev tap0 mode tap user root
    pre-up ip link set tap0 up
    post-down ip link set tap0 down
    post-down ip tuntap del dev tap0 mode tap
---
・ここで試しに再起動してみて、外部からsshなど出来るか、ネットワークインターフェイスやブリッジインターフェイスの状態、ルーティングテーブルの状態を確認すると区切りは良いでしょう。
tcpdumpでインターフェイスを指定してキャプチャして動作をみるとかも切り分けに良いかと。

ifconfig:
・eth0,br0,tap0はUPになっているか
・IPv4アドレスは、br0のみに設定されているか
netstat -rn:
・出力先IFがbr0になっているか
brctl show br0:
・Interfacesにtap0にeth0が存在するか

2. OpenVPNのTLSの設定
証明書のくだりは全て下記のサイトに書いている通りに実施
VPNサーバー構築(OpenVPN) - CentOSで自宅サーバー構築 (centossrv.com)

3. OpenVPNの設定ファイル
・設定ファイル「client.conf」を「/etc/openvpn/client」に設置。
・設定ファイルのシンボリックリンク「cd /etc/openvpn/」、「ln -s /etc/openvpn/client/client.conf ./」(自動起動時に何も考えないと/etc/openvpn/client.confを見に行くため)
・設定ファイルの中身は下記。
---
client
dev tap0
proto udp
remote vpn.example.com 31194
resolv-retry infinite
nobind
user nobody
group nogroup
ca client/ca.crt
cert client/client-A.crt
key client/client-A.key
remote-cert-tls server
tls-auth client/ta.key 1
cipher AES-256-CBC
verb 3
---

4. openvpnの起動設定
・お試しの起動を行うにはcd /etc/openvpn/」で降りて、「sudo openvpn --config client.conf」を実行。標準出力(画面)に「Initialization Sequence Completed」」が出ていれば接続できるはずなので、pingなどで疎通を確認。起動してから確立まで20秒ぐらいかかることもある。
・うまく行かない場合はtcpdumpでIFごとにパケットの状態を確認する。
・自動起動の設定「systemctl enable openvpn@client」を入力し、再起動をして動作確認
・クライアント側の再起動時、トンネル確立後、クライアント側のなんかのパケットを契機に(arp?)サーバ側からもパケットが送れるようになるので、アドホックにclontabに「@reboot sleep 10; ping -c 192.168.0.1 > /dev/null」を記述

〇状況
OpenVPNを使った拠点間L2VPNの構築が出来たが肝心のDLNAがだいたいうまく出来るがまれにできない時がある。
拠点間のRTT(作業用PCとNetBSD間のpingで計測)で50ms~70msでCATV会社提供のUSB-HDDに入れている地デジ番組やCATV番組をDLNAで視聴することや、CATV会社のDLNAをIOデータのNASにムーブしているものを視聴することができた。
オミクロン株が落ち着いたら実家にもっていって確認しよう。


〇参考サイト(感謝)
・OpenVPN本家:Ethernet Bridging
 ここにインターフェイスの設定はOpenVPNの設定の外で必要よと書いてあり気が付く。
・NetBSD本家: The NetBSD Guideの24.6. Setting up a network bridge device
   bridgeの設定方法などを確認 
・QiitaのKohei MATSUSHITA さんの記事: OpenVPNで拠点間L2接続
  構成図があったので、これをみてIFとIPアドレスの付与について気づきになった。
・CentOSで自宅サーバー構築: VPNサーバー構築(OpenVPN)
  TLSの設定は、内容を理解せずにこの記事を見よう見まねで設定。
・ある異邦人の技術メモ:自宅と実家をOpenVPNでつなぐ!