IBM Cloud: VPCで透過的ファイアーウォールを作る方法(1)

# 1 はじめに

例えばあるサーバーにアクセスする時には、利用者に特に意識させることなく強制的にファイアーウォールなどの通過させるなどの透過的な環境を作成したいことがある。例えば、以下の図のような環境がある時に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/c6b2cc84-712e-5f90-46a0-0fb6b6f61f8d.png)

直接端末から`10.4.0.19`のサーバーにアクセスさせるのではなく、これをVNF(Virtual Network Function)として構成されたアプライアンスを必ず通すことでより高度なセキュリティーチェックをしたいケースなどが挙げられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/8d473b67-8389-ec3d-a0aa-c503a22c872e.png)

今回はこのような構成をする際のIBM Cloud VPCの構成を検証する。ただし、VNFを用意するのは大変だし、VNFそのものの設定に説明の多くを割くのは本稿の目的ではないため、VNFの代替として単純にforward機能だけを持つLinuxで代替する。


# 2. 擬似VNFの準備

##2-1. `Allow IP Spoofing`を有効化する
IP Spoofingを有効にしておかないと、自分宛以外のパケットを送信できないため。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/139beada-bf11-7f42-ecb3-83319a5fa2a2.png)

## 2-2. IP Forwardの有効化

```txt:/etc/sysctl.conf
# Per CCE-80157-1: Set net.ipv4.ip_forward = 0 in /etc/sysctl.conf
net.ipv4.ip_forward = 1
```

```
[root@transfw1 ~]# sysctl -p
```

# 3. Custom Route(Ingress)の作成

Direct Link越しでアクセスされてきたパケットのうち、10.4.0.0/24宛のパケットは、VNFに転送するように構成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/1ec1eec7-5d05-faf4-a351-d9c7b4029644.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/6c042019-ce2d-7b80-e00e-2c6438bb2a66.png)


# 4. Custom Route(Egress)の作成

Direct Link越しの端末(192.168.50.0/24)への戻りのパケットが、VNFに転送されるように構成する。
これがなかったら、サーバーハVNFを経由せずに直接端末にパケットを戻す（要件的にそれで問題ないのであれば、この設定は不要）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/bec1a82a-6496-4d29-28af-bacf89492d33.png)

このCustom Routeは10.4.0.0/24というsubnet上のサーバーに対してのみ適用されれば良いので、専用のcustom routeを作れば良いだろう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/90a545a4-c4dc-4a8e-ce3b-6d0163bb679e.png)


# 5. テスト

192.168.50.223の端末（今回はAIXを利用）からアクセスする。

```shell:pingに成功
bash-4.3# ifconfig en1
en1: flags=1e084863,814c0<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD(ACTIVE),LARGESEND,CHAIN>
        inet 192.168.50.223 netmask 0xffffff00 broadcast 192.168.50.255
         tcp_sendspace 262144 tcp_recvspace 262144 rfc1323 1

bash-4.3# ping 10.4.0.19
PING 10.4.0.19 (10.4.0.19): 56 data bytes
64 bytes from 10.4.0.19: icmp_seq=0 ttl=54 time=1 ms
64 bytes from 10.4.0.19: icmp_seq=1 ttl=54 time=1 ms
64 bytes from 10.4.0.19: icmp_seq=2 ttl=54 time=1 ms
64 bytes from 10.4.0.19: icmp_seq=3 ttl=54 time=1 ms
```

10.4.0.19宛のパケットとその戻りのパケットが２つずつ確認できる。

- 192.168.50.223 > 10.4.0.19 (端末 -> 擬似VNF）
- 192.168.50.223 > 10.4.0.19 (擬似VNF -> サーバー）
- 10.4.0.19 > 192.168.50.223 (サーバー -> 擬似VNF）
- 10.4.0.19 > 192.168.50.223 (擬似VNF -> 端末）

```shell:擬似VNFを経由するパケット
[root@transfw1 ~]# tcpdump -i any icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
05:38:30.148263 IP 192.168.50.223 > 10.4.0.19: ICMP echo request, id 362, seq 5, length 64
05:38:30.148286 IP 192.168.50.223 > 10.4.0.19: ICMP echo request, id 362, seq 5, length 64
05:38:30.148577 IP 10.4.0.19 > 192.168.50.223: ICMP echo reply, id 362, seq 5, length 64
05:38:30.148583 IP 10.4.0.19 > 192.168.50.223: ICMP echo reply, id 362, seq 5, length 64
05:38:31.148244 IP 192.168.50.223 > 10.4.0.19: ICMP echo request, id 362, seq 6, length 64
05:38:31.148268 IP 192.168.50.223 > 10.4.0.19: ICMP echo request, id 362, seq 6, length 64
05:38:31.148640 IP 10.4.0.19 > 192.168.50.223: ICMP echo reply, id 362, seq 6, length 64
05:38:31.148645 IP 10.4.0.19 > 192.168.50.223: ICMP echo reply, id 362, seq 6, length 64
05:38:32.148364 IP 192.168.50.223 > 10.4.0.19: ICMP echo request, id 362, seq 7, length 64
05:38:32.148382 IP 192.168.50.223 > 10.4.0.19: ICMP echo request, id 362, seq 7, length 64
05:38:32.148778 IP 10.4.0.19 > 192.168.50.223: ICMP echo reply, id 362, seq 7, length 64
05:38:32.148784 IP 10.4.0.19 > 192.168.50.223: ICMP echo reply, id 362, seq 7, length 64
```