我が家ではeo光のインターネット回線を利用しており,ONUはeo-RT100を使用しているのですが,LAN内からグローバルIPv4アドレスにアクセスするとポート転送が動作しないという問題がありました.
つまりブラウザがv4を選ぶかv6を選ぶかによってランダムにルーターの管理画面が表示される状況に.
そこでIPv4はルーティングを行い,IPv6はブリッジを行うルーター(ブルーターと言うらしい)を作成し,v4パケットをサーバーのローカルIPに転送することで解決を図ります.
前提
必要な物
- NIC2個
- 適当なサーバー(省電力の物が望ましい)
- (要るなら)L2スイッチ
- ebtablesが利用できるディストリ
ルーターとして新たに常時稼働の製品を増やす事になるため,市販のルーターに負けないぐらい省電力なサーバーが望ましいです.
というわけで…
HP t630を購入して役割を失っていたWyse 3040に再度役立ってもらう事に.
ルーターとして動作させて計測した所,電源ラインでtyp. 1A,max 1.5Aといった感じですので安心してつけっぱなしにできます.
NICは内蔵1つしかないのでメルカリで買った激安USB3.0ドングルを追加してます.実測800Mbpsぐらい出てるのでまあ困らないです.
なお,Linuxを利用しますが古い目のディストリの方がいいかもしれません.
というのも,最近のディストリではnftablesへの移行が進められており,ArchではebtablesがすでにAUR行きになっています.
なので今回はUbuntu 20.04を利用します.やUbuntu神
適当にUbuntuセットアップ
インストーラーに従ってすすめるだけですが,MMCに対応していないのか?パーティショニングがちょっと変でした.
なのでCtrl+Alt+F2で仮想コンソールに入ってcgdiskで設定しました.WyseのEFIはcgdiskでMMCに作ったESPを普通に認識してくれます.
インストール後,正常に起動する事が確認できたら,いつもの儀式を行います.
|
|
これでps ax
がだいぶエレガントになります.
Ubuntu Server Coreみたいなバリアントが欲しいです…
必要なパッケージを入れる
apt install isc-dhcp-server firewalld ebtables
もしかしたらまだあるかも
ネットワーク設定
netplanが消えているのでいつもどおりsystemd-networkdを利用します.
私の設定はこんな感じ
/etc/systemd/network/enp1s0.network
[Match]
Name=enp1s0
[Network]
Bridge=br-home
Address=192.168.1.15/24
Gateway=192.168.1.1
DNS=1.1.1.1
/etc/systemd/network/enx.network
[Match]
Name=enx*
[Network]
Bridge=br-home
/etc/systemd/network/br-home.netdev
[NetDev]
Name=br-home
Kind=bridge
[Bridge]
# 重要:無いと一部のv6パケットが破棄される
MulticastSnooping=false
/etc/systemd/network/br-home.network
[Match]
Name=br-home
[Network]
IPv6AcceptRA=false
Address=10.1.10.1/24
[Route]
Gateway=10.1.10.1
Destination=10.1.10.0/24
NIC2つともブリッジしてええのかと思うかもしれませんが,ebtablesによって分離するため問題ありません.
ただし,設定するまでネットに繋がらなくなるため先にDHCPでパッケージを入れてからこの設定を流し込むのがおすすめ.
|
|
ブルーターへ
|
|
ebtables-legacyに変更
|
|
firewalldはiptablesの保存ツールになってもらいます笑
パケット転送の設定
IPv4でルーティングが行えるようになったので転送の設定を行います.
とはいえ,eo光のような環境ではグローバルv4アドレスが変わるのでpermanentな設定にするのは適切ではありません.
そこでランタイムルールに設定し,1時間毎に再設定するようにします.
シェルスクリプトを作成
/usr/local/bin/natloopback.sh
|
|
|
|
systemdユニットを作成 /etc/systemd/system/natloopback.service
[Unit]
Description=nat loopback
RefuseManualStart=no
RefuseManualStop=yes
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/natloopback.sh
/etc/systemd/system/natloopback.timer
[Unit]
Description=Run natloopback hourly
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
|
|
|
|
で正常そうなログが出ていたらOK.
DHCPサーバー
正直書くまでも無くねと思いますが…
/etc/dhcp/dhcpd.conf
# 最初の方
option domain-name "internal.haru3.me";
option domain-name-servers 192.168.1.1, 1.1.1.1;
# 省略
# This is a very basic subnet declaration.
#コメントアウト&変更
subnet 10.1.10.0 netmask 255.255.255.0 {
range 10.1.10.50 10.1.10.200;
option routers 10.1.10.1;
}
/etc/default/isc-dhcp-server
INTERFACESv4="br-home"
|
|
ここまでできてたらbr-homeに接続した機器に適当なIPが振られて通信できるはず.
Overlayfs (Optional)
ルーターは電源ブチ切りしても壊れてはいけないのでシステムをroでマウントし,ログ等はoverlayfsに乗るようにします.
Ubuntuだとoverlayrootという便利ツールが標準装備ですのでちょっと設定変えるだけでOK.
/etc/overlayroot.local.conf
overlayroot="tmpfs"
再起動すると反映されます.
おわりに
このブルーターはPocket WiFiをWANとした環境でも使えるはずなので簡易NASがついにIPv6対応できそうです.
しかしネットにこの手の情報少なすぎませんか?みんなLinuxでIPv6扱わないのかな.
nftablesオンリーになったらいよいよ打つ手が無くなりそうなのですが…
まあ適当なエンプラルーター用意するほうが全てにおいて良さそうな気もしなくないですが.
2022/7/7追記
環境によってはIPv6パケットがフィルタに邪魔される場合があります.
私の場合,/etc/sysctl.conf
を下記のようにしました.
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.bridge.bridge-nf-call-ip6tables = 0