ラズベリーパイで透過型FWを作ってみる

興味本意でラズベリーパイで簡易的な透過型FWを作ってみます。
とは言ってもやってみると簡単で、eth0とeth1でブリッジを組んでiptablesでフォワーディング、フィルタリングを行うだけです。
ブリッジ設定は、探せば色々ありますが、[ここ](https://wiki.debian.org/BridgeNetworkConnections)とかも参考にしてます。

#こんな感じで接続
ルータもしくは上位機器<----->eth0 ラズパイ eth1<----->PCやハブなど

#用意するもの
・ラズベリーパイ2(OSはraspbianの4.4系)
・USB　LANアダプター([USB-LAN100R](https://www.planex.co.jp/products/usb-lan100r/spec.shtml)を使用しました)

#作成手順
※予めSSHの設定やapt-get updateなどはされているという前提です。

##必要なものをインストールしたり

```text:コマンド
# iptables-persistentのインストール(サービス名はnetfilter-persistent)
sudo apt-get install iptables-persistent

# netfilter-persistent自動起動有効
sudo update-rc.d netfilter-persistent defaults 

# bridge-utilsのインストール
sudo apt-get install bridge-utils

# dhcpdの自動起動停止(アンインストールでもOK)
sudo update-rc.d dhcpcd disable
```

##ipv6の無効化
ローカルIPで使用するので今回は無効化してます。
以下のファイルを作成し保存、再起動後に有効になります。

```text:/etc/sysctl.d/10-disableipv6.conf
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
```

##ipの設定
dhcpdは使わないので下記ファイルのみでOK

```text:/etc/network/interfaces
# ループバックインターフェイス
auto lo br0
iface lo inet loopback

# ブリッジの設定
iface br0 inet static
       bridge_ports eth0 eth1
       address XXX.XXX.XXX.XXX
       netmask XXX.XXX.XXX.XXX
       broadcast XXX.XXX.XXX.XXX
       gateway XXX.XXX.XXX.XXX
       dns-nameservers XXX.XXX.XXX.XXX

# eth0インターフェイスにはIPを割り当てない
iface eth0 inet static
        address 0.0.0.0

# eth1インターフェイスにはIPを割り当てない
iface eth1 inet static
        address 0.0.0.0
```

##iptablesの設定

この辺の設定は環境による事もあるので参考程度にお願いします。

```text:/etc/iptables/rules.v6
# ipv6は使用しない
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0
COMMIT
```

```text:/etc/iptables/rules.v4
*filter
# 内部からの通信以外は基本遮断
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# ループバックアドレスからの通信を許可
-A INPUT -i lo -j ACCEPT
# 確立している通信は内部への通信を許可
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 確立している通信はフォワーディングを許可
-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# 指定のアドレスからのssh許可設定
-A INPUT -p tcp -m state --state NEW -s XXX.XXX.XXX.XXX --dport 22 -j ACCEPT

# eth1側からeth0側へのTCP通信を許可
-A FORWARD -m physdev --physdev-in eth1 --physdev-is-bridged --physdev-out eth0 -p tcp -j ACCEPT

# eth1側からのNTPの通信を許可
-A FORWARD -m physdev --physdev-in eth1 --physdev-is-bridged --physdev-out eth0 -p udp --dport 123 -j ACCEPT

# eth1側からのDNSの通信を許可
-A FORWARD -m physdev --physdev-in eth1 --physdev-is-bridged --physdev-out eth0 -p udp --dport 53 -j ACCEPT

# DHCPサーバーからのeth1側への通信を許可
-A FORWARD -m physdev --physdev-in eth0 --physdev-is-bridged --physdev-out eth1 -p udp --sport 68 --dport 67 -j ACCEPT
# DHCPクライアントからのeth0側への通信を許可
-A FORWARD -m physdev --physdev-in eth1 --physdev-is-bridged --physdev-out eth0 -p udp --sport 67 --dport 68 -j ACCEPT

# eth1側からのpingリクエストの許可
-A FORWARD -m physdev --physdev-in eth1 --physdev-is-bridged --physdev-out eth0 -p icmp --icmp-type 8 -j ACCEPT
# eth0からのping応答の許可
-A FORWARD -m physdev --physdev-in eth1 --physdev-is-bridged --physdev-out eth0 -p icmp --icmp-type 0 -j ACCEPT

# ログはお好みですが、ログローテートしないと大変だと思います。
-A INPUT -m limit --limit 1/s -j LOG --log-prefix "[iptables input]: " --log-level=warning
-A FORWARD -m limit --limit 1/s -j LOG --log-prefix "[iptables forward]: " --log-level=info

# 残りはログに記録して破棄（しなくても良い）
-A INPUT  -j LOG --log-prefix "[iptables input drop]: " --log-level=warning
-A INPUT  -j DROP
-A FORWARD -j LOG --log-prefix "[iptables forward drop]: " --log-level=warning
-A FORWARD -j DROP
COMMIT
```

最後に再起動すれば完成です。