異なるFirewall内の二つのプライベートネットワークをSoftEtherVPNで拠点間接続してみた

#概要
職場のプライベートネットワーク(192.168.32.0/24)と自宅のプライベートネットワーク(192.168.1.0/24)をFirewallの設定を変えることなくVPNで拠点間接続した。Firewall３枚を貫通するVPN常時接続（下図の最下段）を構築した。この目的のためには、VPS１つ、プライベートネットワーク内のサーバ２台があれば十分。
![vpn.002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215076/9ba8654b-fb15-ad1f-f572-3bba62eee732.png)

##解決すべきだった課題
沢山あるので、列挙しておきます。

- 職場の組織は大きなネットワークを構成し、セキュリティが厳しく外部（インターネット）と接続できる固定IPの発行を制限している。このFirewallは、事実上NATでhttpとhttpsしか通していない。
- 更に、職場ではこのFirewallの中に更にゆるいFirewallを構築している。
- 職場の組織では某メーカー製のVPN接続を提供しているが、端末にクライアントをインストールしなければならず、当然のことのようにWindowsとMacしかサポートされていない。サーバ間のVPN接続はできない。
- ここでは詳細を述べないが、今回の試行の中途で[組織内のネットワークに接続し、PC端末から、あらゆるリソースにアクセスすることは出来ていた](https://www.lapidem.pw/linux/73/firewall-private-network-vpn/)（いわゆるリモートVPNアクセス）ので、拠点間の接続は必須ではなかったが、自宅のサーバから職場のサーバにアクセスするためにはVPN接続されたPC端末へのログインを経由してから、職場のサーバにログインしなければならず、直接職場のサーバに接続することはできなかった。
- Local Bridgeの設置で、Linuxに固有の問題があることに気付かなかった。ドキュメントを良く読めば書いてあったのですが。。。



###要するに
**PV1 -> FW1->FW2<=>Internet<=>FW3<-PV2**
を
**PV1 <=> FW1<=>FW2<=>Internet<=>FW3<=>PV2**
としたかった訳ですが、SoftEtherVPNとcloudのVPSを使えば**VPNリモートアクセス**で
**PV1<=>FW1<=>FW2<=>VPS<=>Internet**
や
**Internet<=>VPS<=>FW3<=PV2**
は比較的簡単にできますが、PV1とPV2を同時に常時接続したかった訳です。
(PV: private network, FW: Firewall)

##解決策
- Internet側からFirewall内にVPN接続するためには、インターネット上の固定IPが必要です。そこで、VPSをレンタルすれば、インターネット上の固定IPを取得できます。
- 後で分かったのですが、最初にリモートVPN接続を設定した際にBridge接続したLinuxマシンはネットワークIFを一つしか持っていなかったため、(SoftEtherVPNのドキュメントによれば）Linuxの制限によりローカルのネットワークのL2レイヤーのブリッジとして機能が不十分でした。これは、２つのネットワークIFを持つBridgeサーバを設置することで解決しました。
- PV1とPV2を同じネットワークセグメントに設定すれば、リモートVPNアクセスの手法で実現できる（と思われる）が、ネットワークを再構築するのが面倒なのでルーティングする必要がありましたが、これはSoftEtherVPN serverの**仮想L3 スイッチ**を使って解決しました。


#方法
##VPSにVPN serverを立てる
詳細は[こちら](https://www.lapidem.pw/linux/73/firewall-private-network-vpn/)。
- VPS2にVPNサーバをインストールする。
    - VPS2に仮想ハブ vHub3とvHub4を設定する。
    - 仮想ハブvHub3とvHub4にユーザを作成する。

##ネットワークIFを２つ持つVPN bridgeを設置する
- PV1のDebian1にVPNブリッジをインストールする。
    - Debian1は、２つのネットワークインターフェイスを持っている必要があります（enp1s0とenp2s0)。
    - Local Bridge接続をenp2s0に対して行う。
    - 私はNetwork-managerをアンインストール（サーバには不向きです）して、以下の設定をしています。
        - enp2s0にIPを割り当てても良いが、プロトコルスタックの負荷を軽減するために0.0.0.0を割り当てる。
    - VPS2のvHub4にカスケード接続する。

```:/etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

auto enp1s0 
iface enp1s0 inet static
        address 192.168.32.10
        netmask 255.255.255.0
        gateway 192.168.32.100

allow-hotplug enp2s0
iface enp2s0 inet static
        address 0.0.0.0
``` 

- 同様にして、vHub3とDebian2をカスケード接続する。

- VPS2のvHub4に接続して、PV1にリモートVPN接続できることを確認する。
- VPS2のvHub4に接続して、PV2にリモートVPN接続できることを確認する。
- 例えば、ネットワークIFを一つしか持たないUbuntu2をブリッジとしたVPS2のvHub1に接続しても、Ubuntu2にアクセスすることはできません（ただし、Ubuntu1やPV1のgatewayにはアクセスできるので、そからInternetにアクセスすることはできます）。また、L2スイッチにブリッジ接続が不十分のため、後述のL3スイッチを設定しても、L3スイッチに設定した仮想IFを認識できないようです（これがハマった理由）。
- vHub4経由であれば、Debian1のenp1s0にアクセスできるので、PV1の全ネットワークにアクセスできます。

 
##仮想L3 switchを設定する
- VPS2のVPN serverでL3 switchを設定します。
    - 仮想L３スイッチを作ります。
        - vHub3に仮想IFの192.168.1.200/255.255.255.0を設定
        - vHub4に仮想IFの192.168.32.200/255.255.255.0を設定
        - ルーティングは設定する必要はありません。これだけで、192.168.1.0/24と192.168.32.0/24のルーティングが設定されます。
        - PV1側からは、ping192.168.1.200の反応があることを確認します。
        - PV2側からは、ping192.168.32.200の反応があることを確認します。
        - その先のマシンで帰りの経路が設定されていないため、pingの反応はこの段階ではありません。
        

##ルーティングを設定する
PV1とPV2のネットワークセグメント間のルーティングはVPN serverの仮想L3スイッチで行いましたが、帰りの経路を各マシンでも設定する必要があります。

- PV1側では、

```
$ sudo /sbin/route add -net 192.168.1.0/24 gw 192.168.32.200
```

- PV2側では、

```
$ sudo /sbin/route add -net 192.168.32.0/24 gw 192.168.1.200
```
を設定する必要があります。
systemdで設定する方法は、[こちら](https://qiita.com/lapidem/items/da063dd920b156122005)で紹介しました。

#その他
- リモートVPNアクセス等で、もう一つのVPN経路を確保して設定するのが楽です。
- 今回、使ったNICを２つ持つマシンは、[こちら](https://www.lapidem.pw/windows/270/xcy-intel-celeron-j1900-quad-core/)。