2025/05/31 全面改定
「Ubuntu20.04 UFWを使ってルーターを作る」で構築したサーバーに、本記事の2ページ目に残した過去記事の通りの設定を加えていたのだが、もうすぐ4年が経とうとするこのタイミングで、手持ちの携帯端末からのIPv6接続でタイムアウトが発生した。
このサイト自体が更改のタイミングを迎えているので、このタイミングでルーターの設定を少し改善しようとしていて、OSのアップグレードと設定変更を加えたあたりで「設定の誤り」が顕在化したのではないかと思う。
CopilotさんとGeminiさんの力を借りて、きっちり設定し直そうじゃないの。
環境
環境は以下の通り。ルーターのOSは24.04にしてしまっているけれど、20.04でも問題なく動くと思う。
名称 | OS | NIC | IPv4※ | IPv6※ | 備考 |
---|---|---|---|---|---|
CaRouter | 不明 | - | 192.168.0.1 | 2001:db8::1 | キャリアから貸与されたルーター |
MyRouter | Ubuntu 24.04 | ens160 ens192 ppp0 | 192.168.0.11 192.168.9.1 203.0.113.88 | 2001:db8::11 fd01:db8::9:1 <利用不可> | |
WebSV | Ubuntu 20.04 | ens160 ens192 | 192.168.0.77 192.168.9.77 | 2001:db8::77 fd01:db8::9:77 |
※書き分けるためだけの架空アドレス
設計
実際には、全て同じ物理線に乗っているのだけれど、概念的にはこんな感じ。
<internet> <internet>
IPv4 IPv6
│ │
┌─┴───────┴─┐
│PPPoE MyRouter │
│ Bridge 宛のみ通過│
│ CaRouter │
└─┬───────┬─┘
│ …─┼──────┬─────────┬─…
┌─┴───────┴─┐ ┌─┴─────┐ │
│ ppp0 ens160│ │ens160 │ <各種端末>
│ MyRouter │ │ WebSV │
│ ens192├──┤ens192 │
└───────────┘ └───────┘
- インターネットからのパケットはMyRouterが受信。
- IPv4ならppp0で受信。V6プラスのPPPoE接続ではIPv6が使えない。
- IPv6ならens160で受信。CaRouterはMyRouter宛てパケットのみを通過させ、他は遮断する設定にしている。
- MyRouterはWebSVに向けてNAT。
- この時、IPv4・IPv6共にサービス公開専用のセグメントに転送(ens192)。
- WebSVはコンテンツを生成して送信。
- インターネットからの要求は、サービス公開専用のセグメントで送信(ens192)。
- イントラネットからの要求は、ホームラボのセグメントで送信(ens160)。
サービス公開専用のセグメントを作ったことで管理は複雑化したが、代わりにインターネットに向けて安定的にサービスが提供できるようになった。
(セグメントを作る前はタイムアウトしたり、コンテンツの送信開始までに数秒かかったりする、とてもストレスフルな状況だった)
キャリアルーターの設定
キャリアから貸与されているルーターにログインし、公開したいIPv6アドレス宛のパケットを通過させるように設定する。
IPv6の基本的な思想は、デバイス同士が互いに直接通信することのようでだけれど、今回はルーターだけを公開して振り分ける。
IPv4と同じ方式(NAT)を採って、サーバーを直接インターネットに晒さないことで、少しでも安全にしたいという思い。
IPv6セキュリティのレベル
全部遮断する方向で設定。
設定項目 | 設定値 | 備考 |
---|---|---|
IPv6ファイアウォール機能 | 有効 | 有効にすることで外部からのアクセスを遮断。 |
IPv6セキュリティのレベル | 高度 | ファイアウォールを有効にしてもフレッツ網内からのアクセスは可能。 高度に設定することで網内からのアクセスも遮断できる。 |
セキュリティレベルは一時期話題になっていたなぁ。
開けておいても攻撃のターゲットになる端末が見つかるはずはない、とか、5分ごとにIPアドレスが変わるから大丈夫、とか。確かにIPアドレスの範囲は広大。また、Windowsには「一時 IPv6 アドレス」があって、アクセス先で確かめると、それが記録されている。
だけれども、念のためガチガチの設定にしている。
IPv6パケットフィルタ設定(IPoE)
ここで、MyRouterへのパケットだけ通過させるようにフィルタを設定していく。
設定項目 | 設定値 | 備考 |
---|---|---|
エントリ番号 | 今回は1 | 登録しているルール数、順番で変わる。 |
フィルタ種別 | 許可 | |
通信方向 | IPoE->LAN | |
プロトコル | 全て指定 | |
TCPフラグ | - | プロトコルの指定により操作不可 |
送信元IPv6プレフィックス/プレフィックス長 | 全て指定 | |
宛先IPv6プレフィックス/プレフィックス長 | 2001:db8::11 / 128 | 今回は[RouterSV]のアドレスのみ開放。 |
送信元ポート | - | プロトコルの指定により操作不可 |
宛先ポート | - | プロトコルの指定により操作不可 |
ICMPv6タイプ | - | プロトコルの指定により操作不可 |
ICMPv6コード | - | プロトコルの指定により操作不可 |
エントリを追加したら、有効にチェックマークを付けて設定ボタンを押す。
ルーターの設定
仮想PCなので、仮想NICがボタン1つで追加できるから、NICを2つにしておく。
ネットワーク設定
IPv4だけを公開していた時とは大きく変わっている。
- CaRouterからパケットを受け取るため、固定IPアドレスを追加している。
- このサーバー自体がインターネットに接続する場合は、デフォルトゲートウェイとしてCaRouterを使うようにPBR(Policy Based Routing)を設定。
ppp0接続が完了すると、優先度が高いデフォルトゲートウェイになるため。 - ens192を追加し、サービス公開用セグメントのIPアドレスを手動で設定。
/etc/netplan/00-installer-config.yaml
network:
ethernets:
ens160:
addresses:
- 192.168.0.11/24
- 2001:db8::11/64
routes:
- to: default
via: 192.168.0.1
table: 100
- to: default
via: 2001:db8::1
routing-policy:
- from: 192.168.0.11/32
table: 100
nameservers:
addresses:
- 192.168.0.1
- 2001:db8::1
search:
- myhome.local
optional: true
ens192:
dhcp4: false
dhcp6: false
accept-ra: false
addresses:
- 192.168.9.1/24
- fd01:db8::9:1/64
optional: true
version: 2
※先日作ったルーターにIPv6の設定を追加している。
設定変更したら、以下のコマンドで反映させる。
$ sudo netplan apply
続いて、ppp0がオンラインであることのチェックをやめる。
$ sudo systemctl edit systemd-networkd-wait-online.servic
[Service]
ExecStart=
ExecStart=/lib/systemd/systemd-networkd-wait-online --ignore=ppp0
※空行も含めて書く必要があるとのこと。
問題なければ再起動して、設定前に自動構成されていたデフォルトルート等をきれいにしておくと良いように思う。
UFWによる転送設定(outbound)
ローカルからインターネットに出るための設定をしていく。
IP Masquerade
[WebSV]からインターネットにアクセスできるように、IP Masqueradeする。/etc/ufw/before6.rules
…
# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT
# NAT rules
*nat
:POSTROUTING ACCEPT [0:0]
-F
-A POSTROUTING -s fd01:db8::/64 -o ens160 -j MASQUERADE
COMMIT
※赤文字部分を追加。
POSTROUTINGの[0:0]指定は省略することができ、その場合は、カウンターが0クリアされない。
設定を反映させて確認する。
$ sudo ufw reload
$ sudo ip6tables -t nat --list-rules
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -s fd01:db8::/64 -o ens160 -j MASQUERADE
転送許可
カーネルパラメーターを転送可能にしても、それだけではパケットは転送されない。
一般にはデフォルトの転送ポリシーをACCEPTにして転送させるようだけれども、以前の設定を踏襲してポリシーはDROPのままとして、転送ルールを追加してみた。
具体的には、[WebSV]から外に出るものを許可する(135,137:139,445を除く)。
$ sudo ufw route deny in on ens192 out on ens160 to ::/0 port 135,137:139,445 proto tcp
$ sudo ufw route deny in on ens192 out on ens160 to ::/0 port 135,137:139,445 proto udp
$ sudo ufw route allow in on ens192 out on ens160 to ::/0
$ sudo ip6tables -t filter --list-rules ufw6-user-forward
-N ufw6-user-forward
-A ufw6-user-forward -i ens192 -o ens160 -p tcp -m multiport --dports 135,137:139,445 -j DROP
-A ufw6-user-forward -i ens192 -o ens160 -p udp -m multiport --dports 135,137:139,445 -j DROP
-A ufw6-user-forward -i ens192 -o ens160 -j ACCEPT
※順序が重要。delete→insertするか、/etc/ufw/user.rulesの中を並べ替えてreloadするか、どうにかしてそろえる。
外部から送られてくるパケットのうち、接続済み、または、接続済みセッションに関連するものについては通過を許可したい。
確認してみたところ、その設定は標準で入っていた。
$ sudo ip6tables --list-rules ufw6-before-forward
-N ufw6-before-forward
-A ufw6-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw6-before-forward -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A ufw6-before-forward -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A ufw6-before-forward -p icmp -m icmp --icmp-type 12 -j ACCEPT
-A ufw6-before-forward -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A ufw6-before-forward -j ufw-user-forward
ここまでの設定で、インターネットへのアクセスができるルーターとして動作する。
UFWによる転送設定(inbound)
インターネットにサービス公開するための設定をしていく。
NAT
[RouterSV]のところに到着したパケットの宛先を[WebSV]に書き換える。/etc/ufw/before6.rules
…
# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT
# NAT rules
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-F
-A PREROUTING -d 2001:db8::11/128 -p tcp -m tcp --dport 80 -j DNAT --to-destination fd01:db8::9:77
-A PREROUTING -d 2001:db8::11/128 -p tcp -m tcp --dport 443 -j DNAT --to-destination fd01:db8::9:77
-A POSTROUTING -s fd01:db8::/64 -o ens160 -j MASQUERADE
COMMIT
※赤文字部分を追記。
IPv4のルーターを作ったときには、PPP0に届いたパケットをDNATしていた。
IPv6でもens160に届いたパケットを、[WebSV]にDNATする。
設定を反映させる。
$ sudo ufw reload
$ sudo ip6tables -t nat --list-rules
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A PREROUTING -d 2001:db8::11/128 -p tcp -m tcp --dport 80 -j DNAT --to-destination fd01:db8::9:77
-A PREROUTING -d 2001:db8::11/128 -p tcp -m tcp --dport 443 -j DNAT --to-destination fd01:db8::9:77
-A POSTROUTING -s fd01:db8::/64 -o ens160 -j MASQUERADE
転送許可
宛先を[WebSV]に書き換えても、転送のデフォルトポリシーはDROPのため、ブロックされる。
そこで、ens160に到着したパケットの[WebSV]への転送を許可する。
$ sudo ufw route allow in on ens160 out on ens192 to fd01:db8::9:77 port 80 proto tcp
$ sudo ufw route allow in on ens160 out on ens192 to fd01:db8::9:77 port 443 proto tcp
$ sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW 192.168.0.0/24 # SSH
135,137:139,445/udp on ens160 DENY FWD Anywhere on ppp0
135,137:139,445/tcp on ens160 DENY FWD Anywhere on ppp0
Anywhere on ens160 ALLOW FWD Anywhere on ppp0
192.168.0.77 80/tcp on ens160 ALLOW FWD Anywhere on ppp0
192.168.0.77 443/tcp on ens160 ALLOW FWD Anywhere on ppp0
135,137:139,445/tcp (v6) on ens160 DENY FWD Anywhere (v6) on ens192
135,137:139,445/udp (v6) on ens160 DENY FWD Anywhere (v6) on ens192
Anywhere (v6) on ens160 ALLOW FWD Anywhere (v6) on ens192
fd01:db8::9:77 80/tcp on ens192 ALLOW FWD Anywhere (v6) on ens160
fd01:db8::9:77 443/tcp on ens192 ALLOW FWD Anywhere (v6) on ens160
Webサーバーの設定
こちらもやはり、IPv4だけを公開していた時とは大きく変わっている。
- イントラネットからパケットを受け取るため、固定IPアドレスを追加している。
- ens192を追加し、サービス公開用セグメントのIPアドレスを手動で設定。
加えて、ens192から送信するパケットを確実にMyRouter向けるため、PBRを設定している。
/etc/netplan/00-installer-config.yaml
network:
ethernets:
ens160:
addresses:
- 192.168.0.77/24
- 2001:db8::77/64
routes:
- to: default
via: 192.168.0.1
- to: default
via: 2001:db8::1
nameservers:
addresses:
- 192.168.0.1
- 2001:db8::1
search:
- myhome.local
ens192:
dhcp4: false
dhcp6: false
accept-ra: false
addresses:
- 192.168.9.77/24
- fd01:db8::9:77/64
routes:
- to: default
via: 192.168.9.1
table: 100
- to: default
via: fd01:db8::9:1
table: 100
routing-policy:
- from: 192.168.9.0/24
table: 100
- from: fd01:db8::/64
table: 100
version: 2
設定変更したら、以下のコマンドで反映させる。
$ sudo netplan apply
これで[WebSV]のサービスを[MyRouter]でしっかりと保護しつつ、Webサービスのみをインターネットに公開できるようになった。
さいごに
ルーターのアップグレードをしたのが今月の初め、ルーティングの見直しを思い立ったのが先週。
通勤途中に気になったことがあって当サイトを見に行ったら、タイムアウトした。
調べようと思ったらtcpdumpにWireShark、概略は分かっているような気がするものの、中身を分析するには知識が足らない。
そんなときには生成AI。
コマンドのパラメーターを教えてもらったり、各種出力結果をそのまま貼り付けて解説してもらったりして、何が起きているのかがすぐに分かる。
最終的に設定結果を確かめるタイミングでも、かなり頼りになる。
でも、設定のアドバイスは外れたりもするんだよなー、そこは人間が判断するしかない。
思い込みができてしまうと払拭するのが大変なので、最初からやり直したりも。
とかなんとか紆余曲折しながらゴールにたどり着いた。
さてさて、こうして記事をまとめながら思っていることは、「全然Webを検索しなかった」ってこと。
過去記事、Copilot、ターミナル、テスト端末、過去記事、Gemini、ターミナル、テスト端末…って感じでどうにかなる。
自分に読解力さえあれば、もっと活用が進みそうな気がする。知識は活用を加速する効果がある程度、かな。
いずれにしても、ちょっと不安に思っていた設定がきれいになったのが嬉しい。
誰にも見られないページをメンテナンスするのは少し寂しいような気もするけれど。
コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他