Ubuntu20.04とRaspberry PiでIPsecゲートウェイの簡易VPN構築 - 2.StrongSwan VPN接続確認

# 前提と準備

## Linuxサーバー構築の記事
- [Sambaでファイルサーバー構築(CentOS 8.1・openSUSE 15.1・Ubuntu 20.04)](https://qiita.com/kazumi75kitty/items/4298795029ba9f67b9d2)
- [LinuxでApache2.4＋PHP7.4をソースコンパイル - 1.Apache導入](https://qiita.com/kazumi75kitty/items/daaf8ff8feb50ad04f41) /[【Raspberry Pi】](https://qiita.com/kazumi75kitty/items/67686eccaaec73251458)
- [LinuxでApache2.4＋PHP7.4をソースコンパイル - 2.PHP導入](https://qiita.com/kazumi75kitty/items/fca116b1b387fe56c93c) /[【Raspberry Pi】](https://qiita.com/kazumi75kitty/items/50f1a447f6ebc2ee2b61)
- [LinuxでApache2.4＋PHP7.4をソースコンパイル - 3.MySQL導入](https://qiita.com/kazumi75kitty/items/76807c637c096618a0e1)/[【Raspberry Pi】](https://qiita.com/kazumi75kitty/items/4212dacc45944f27ca94)
- [LinuxでApache2.4＋PHP7.4 - 4.セキュリティ(chownとfirewalld)](https://qiita.com/kazumi75kitty/items/8ad51806ac50bd04b644)
- [LinuxでIPsecゲートウェイをVPN構築 - 1.StrongSwan導入](https://qiita.com/kazumi75kitty/items/60941f00ae91c4d9f555) /[【Ubuntu 20.04＋Raspberry Pi】](https://qiita.com/kazumi75kitty/items/08259681247a6c2ebd0d)
- [LinuxでIPsecゲートウェイをVPN構築 - 2.VPNへの接続確認](https://qiita.com/kazumi75kitty/items/f5a33abda9f8edd5c47f) /【Ubuntu 20.04＋Raspberry Pi：この記事】

[前回はStrongSwanのソースコンパイルによるIPsec-VPN環境の構築](https://qiita.com/kazumi75kitty/items/08259681247a6c2ebd0d)を行いましたが、今回はVPNに実際に接続できるか確認しましょう！(˶ ･ᴗ･ )੭⚐⚑

## 環境
- IPsecプログラム：StrongSwan 5.9.0(ソースコンパイル)
- IPsec交渉受信側：Raspberry Pi 3B+ / Raspberry Pi OS(2020/08版)(armhf(v7)、32bit)
- IPsec交渉発信側：Hyper-V(第2世代)のx64仮想機 / Ubuntu 20.04(x86_64)
- VPNに接続するクライアントとサーバーを別途用意(私はここではUbuntuとCentOSのWebサーバーを用意しました)

## 前提
- OSは最小限のインストール。また、最新の状態でOSをアップデートしていること
- ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
- IPsecゲートウェイは、ファイアウォールはufwを使う(ラズパイのRaspberry Pi OSでは、firewalldについて、IPv6周りの連動が糞だったので、Debian系標準のufwを使用することにしました)

## サーバー条件
### IPアドレスとネットワーク構築図
- IPsec交渉受信側ゲートウェイ(下の図の左、Raspberry Pi)：
 - インターネット側(eth0)：192.168.1.22
 - VPN領域側(eth1)：192.168.2.1

- IPsec交渉発信側ゲートウェイ(下の図の右、Ubuntu 20.04)：
 - インターネット側(eth0)：192.168.1.18
 - VPN領域側(eth1)：192.168.5.1

- ネットワークセグメント：
 - インターネット接続可能：192.168.1.0/24
 - Raspberry Pi(図の左の交渉受信側)セキュアセグメント：192.168.2.0/24
 - Ubuntu 20.04(図の右の「CentOS 8」と記載されている交渉発信側)セキュアセグメント：192.168.5.0/24

- VPNに接続する端末：
 - クライアント(Ubuntu 20.04)：192.168.2.2(192.168.2.0/24に属する)
 - Linux Webサーバー(CentOS 8.1)：192.168.5.2(192.168.5.0/24に属する)

- IPsec領域関連：
 - トンネリング区間：192.168.1.22 ～ 192.168.1.18間
 - VPN連携：192.168.2.0/24 ～ 192.168.5.0/24をVPN接続
![IPsecゲートウェイ以内のVPNに接続する図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/ab00d528-1b8b-c477-8d33-b945fca95532.png)
※ 図の左上の「openSUSE」は**Raspberry Pi OS**に、右上の「Linuxルーター CentOS 8」は**Ubuntu 20.04**に読み替えてください。

ここでは、**192.168.2.2のUbuntuクライアントが、192.168.5.2のLinux WebサーバーにVPN接続できるかを試します**。なおVPNに接続しているサーバーとクライアントともに、VPNの範囲のみ接続して、インターネットには接続しないこととします。

### パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年9月時点)
- zlib-1.2.11.tar.gz
- strongswan-5.9.0.tar.gz

それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。

ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。

# 作業手順
## VPNにサーバーとクライアントを接続する
### VPN領域内のIPアドレス割り振り
前回ではeth1はあくまでもネットワークアダプタを追加しただけであって、まだIPアドレスは割り振られていません。ラズパイの場合(Raspberry Pi OS)は/etc/dhcpcd.confを手動で追加するしかなかったんです。。もちろんdhcpcd.confにはデフォルトゲートウェイもDNSサーバーも指定があるので、複数指定するとネットワークの順位が混乱するので、新設したeth1には、IPアドレスのみを記載。

参照記事：

- [RasberryPi(stretch) で複数の NIC について static route を設定する](https://surre.jp/posts/2018/06/15/post/)


```RaspberryPiOS(2020.08)
# vi /etc/dhcpcd.conf
```

```conf:/etc/dhcpcd.conf(RaspberryPiOS)
[以下のインターフェースの情報を最終行に追記]
#interface eth1
interface eth1
static ip_address=192.168.2.1/24
noipv6
```

```RaspberryPiOS(2020.08)
# reboot

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [最初からあるネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.22/24 brd 192.168.1.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 [最初からあるネットワークアダプタのIPv6アドレス] scope global dynamic noprefixroute
       valid_lft 14373sec preferred_lft 12573sec
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [増設ネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.1/24 brd 192.168.5.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 [増設ネットワークアダプタのIPv6アドレス] scope link noprefixroute
       valid_lft forever preferred_lft forever

# ip route
default via 192.168.1.1 dev eth0 proto static metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.22 metric 100
192.168.2.0/24 dev eth1 proto kernel scope link src 192.168.2.1 metric 101
```

IPアドレスの設定ファイルってディストリビューション依存しすぎていて、慣れないと大変です٩(.› ‹.♡)۶
eth1にIPアドレスを設定しました。もちろんルーティングにも192.168.2.0/24も認識されました。

その一方で、Hyper-VのUbuntuだとSSHではなくGUI画面で設定できるから、そこにアドレスとネットマスクだけを指定して設定を保存するだけでOKです٩(.› ‹.♡)۶
![secgw01_Ubuntuでのeth1追加方法.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/1597301c-c928-22ae-a889-0c4cbb516373.png)


```Ubuntu20.04(Hyper-V/x64)
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [最初からあるネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.18/24 brd 192.168.1.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 [最初からあるネットワークアダプタのIPv6アドレス] scope global temporary dynamic
       valid_lft 14043sec preferred_lft 12243sec
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [増設ネットワークアダプタのMACアドレス] brd ff:ff:ff:ff:ff:ff
    inet 192.168.5.1/24 brd 192.168.5.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 [増設ネットワークアダプタのIPv6アドレス] scope link noprefixroute
       valid_lft forever preferred_lft forever

# ip route
default via 192.168.1.1 dev eth0 proto static metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.18 metric 100
192.168.5.0/24 dev eth1 proto kernel scope link src 192.168.5.1 metric 101
```

### VPN領域内のネットワークにサーバーとクライアントをLANケーブル接続する
これは言うまでもないですね。サーバーとクライアントをLANケーブルでつないで、IPアドレスを手動で設定します(DHCPサーバーがVPN領域内にないので、手動設定するしかないです)

「サーバー条件」を参照しての通り、下の図のようなLANケーブル接続でIPアドレスを割り振っていきます。もちろん仮想マシンの場合は仮想スイッチを割り当てるだけでOKです。

- Ubuntuクライアントをラズパイに接続(192.168.2.0/24)。IPアドレスを192.168.2.2に設定
- Linux WebサーバーをHyper-V仮想機に接続(192.168.5.0/24)。IPアドレスを192.168.5.2に設定
![IPsecゲートウェイ以内のVPNに接続する図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/ab00d528-1b8b-c477-8d33-b945fca95532.png)
※ 図の左上の「openSUSE」は**Raspberry Pi OS**に、右上の「Linuxルーター CentOS 8」は**Ubuntu 20.04**に読み替えてください。

## VPNのネットワーク接続動作確認
### Pingはこの時点で通っている

![IPアドレスが適切なだけでもPingは通る](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/330a6ca3-ef99-8527-9232-5526e25089d4.png)
画面上はCentOS＋openSUSEのものですが、今回のUbuntuを使うケースでも、クライアント(192.168.2.2)から対向のVPN領域にあるWebサーバー(192.168.5.2)に通るか確認したら、あっさり通っていました( ´థ౪థ)

やはりUbuntuのIPsecゲートウェイのケースでも、Webがその時点でVPN領域越しに見られるというわけじゃないみたいです。

![この時点ではIPsec-VPN越しサーバーのwgetは不可](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/4d6e6f46-bcd6-95c4-ced6-f1882423750e.png)
もちろんwgetでも「No route」となってしまうはずです

### ufwの転送許可

IPsecでトンネリングしたパケットも、IPsecゲートウェイのufwでまた転送許可のルールを追加しなければならないので、VPNにあるサーバーとクライアントが通信するポートを開放した。ここでは、クライアントが192.168.2.2、サーバーが192.168.5.2なので、192.168.2.0/24 → 192.168.5.0/24宛ての転送許可をルールに加えるが、ufwの場合はrouteを指定する必要がある。

Webサーバーが使うポートは、Webである80・443・8080・8443なので、当然以下のコマンドを入力すればVPN越しにIPsecゲートウェイが転送してくれるはず。

```
[192.168.2.0/24 → 192.168.5.0/24 HTTP 許可]
# ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 80 proto tcp
[192.168.2.0/24 → 192.168.5.0/24 HTTPS 許可]
# ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 443 proto tcp
[192.168.2.0/24 → 192.168.5.0/24 ポート8080 許可]
# ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 8080 proto tcp
[192.168.2.0/24 → 192.168.5.0/24 ポート8443 許可]
# ufw route allow from 192.168.2.0/24 to 192.168.5.0/24 port 8443 proto tcp

[確認するには]
# ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 30303/tcp                  ALLOW IN    192.168.1.0/24
…(中略)…
[10] 192.168.5.0/24 80/tcp      ALLOW FWD   192.168.2.0/24
[11] 192.168.5.0/24 443/tcp     ALLOW FWD   192.168.2.0/24
[12] 192.168.5.0/24 8080/tcp    ALLOW FWD   192.168.2.0/24
[13] 192.168.5.0/24 8443/tcp    ALLOW FWD   192.168.2.0/24
…(中略)…
```

参照：

- [ufw 再入門](https://blog.n-z.jp/blog/2018-02-25-ufw.html)

Hyper-V仮想マシンのCentOS 8.1ではfirewalldとdirectの相性が悪い(具体的には、たぶんnftablesとの登録がうまくいっていないみたい)ために、[転送ルールをfirewalldに登録してもうまく転送できない問題が発生](https://qiita.com/kazumi75kitty/items/f5a33abda9f8edd5c47f#firewalld%E3%81%AE%E8%BB%A2%E9%80%81%E8%A8%B1%E5%8F%AF%E3%82%92%E3%81%99%E3%82%8B%E3%81%8Ccentos-81%E3%81%AEnftables%E3%81%AE%E9%80%A3%E5%8B%95%E3%81%AB%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%A6%E6%96%AD%E5%BF%B5)していたが、Ubuntu20.04とRaspberry Pi OS(2020/08版)のufwではまだそういう問題が発生していなく、今後Debian系のOSはnftablesを推奨するので、早期にnftablesと転送ルールの問題が解決しなければ、CentOSの二の舞になるかもしれませんが…

#### nftables関連でいろいろ参考させていただきました！( ´ •̥  ̫ •̥ ` )- ̗̀ ♡  ̖́-
- [centOS8でDockerコンテナから名前解決ができない話をnftコマンドで解決する](https://qiita.com/DaichiSasak1/items/11687a3c613c8811350c)
- [netfilterとfirewalldとiptablesとnftablesの関係](https://qiita.com/bashaway/items/e405d59d92670fbc5341)
- [Linuxにおける新たなパケットフィルタリングツール「nftables」入門 - さくらのナレッジ](https://knowledge.sakura.ad.jp/22636/)


### Webサーバーにアクセスできるか確認
IPsecゲートウェイの両方で転送を許可できたら、VPN越しにクライアントからVPN内のサーバーにアクセスできるかやってみました。

![サーバーアクセス成功](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/3f69cc6a-7b78-8302-1f28-87847f212d8e.jpeg)

この成功画面では、CentOS＋openSUSEの場合での画面ですが、実際Ubuntuでもうまくいっています！！

## セキュリティ確認
### IPsecゲートウェイをまたぐパケットは暗号化されている？？
やはり、Ubuntuの場合でも、下の画面みたいにパケットがIPsecトンネルでは暗号化を確認しています(˶ ･ᴗ･ )੭♡♡

![パケットがIPsec暗号化されている！](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/a5cf3ca4-8191-9e9e-13aa-866416158e3b.png)

わかりやすくHTTP(ポート80)で「QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ…」をHTTPSで暗号化させずにクライアントでサーバーからページをアクセスしてみたけど、IPsecゲートウェイ間のトンネリングでそれを拾ってみてみると、暗号化されていました！！


# まとめ
StrongSwanでRaspberry Pi OSとHyper-V仮想マシンのUbuntu 20.04でも、IPsecゲートウェイの構築を行い、IPsec-VPNとしての用途を満たすことは確認した。やはりセキュリティ対策についてもCentOSの場合ともやはり変わらないことはわかったが…今後はnftablesのufwやfirewalldとの相性の課題もまだあるみたいだし…⸝⸝ᵕ ᵕ⸝⸝