前書き
Qiitaをご覧の皆様にとってはごく当然のことでしょうが、IPv6通信はその膨大なアドレス数を活かし、各端末1台1台に直接グローバルIP(グローバルユニキャストアドレス、GUA)を与えます。(※普通の環境なら)
つまり、上流のルーターで適切なファイアウォールを設定しパケットをフィルタリングしない限り、各端末はインターネット側からReachableな状態です。
大抵のルーターではインターネット側からLAN側宛のPort 22,25,80,110,135,137:139,443,445,465,587,993,995,3389,5060,5900あたりの通信は塞ぐ設定になっているのではないかと思います。
某社のHGWは偶に素通しになってることがある気がしますが
しかしこのまま通信すると、通信先には自分の端末の生IPアドレスが記録されることになります。
常識的な設定のネットワークであれば、通常は/64で振り出されたRAを元に、MACアドレスを加えた半固定的なIPと、一時的な乱数生成的な実際の通信用のIPが各端末に設定され(しかも一定時間後に変わる)、後者の方で通信をするので、そんなに(通信相手にMACアドレスを類推され該当MACアドレスを有する機器の脆弱性を突くような攻撃を受けることに)神経質になる必要はないでしょう。
しかし、世の中には私の様な「各端末にGUAを割り当てるとか論外論外!!!!LAN内の端末は全てプライベートIPを使うべし!!!!!!」というプライベートIP勢過激派が一定数存在します(存在しますよね????)。
今回はそんなニッチな需要向けに、「各端末にグローバルIPを振らないけど、インターネットとも通信出来る環境」を作ってみた話です。
前提条件
拙宅は仮想化基盤サーバーに収容した仮想マシンをルーターにしています。
インターネット回線は近頃流行りのマンションに備え付けの無料インターネット回線(1Gbps)です。
IPから類推するにJPNE/JPIX系のIPoE接続な環境で、実効スループットは100〜200Mbpsぐらいでしょうか。
各居室にはIPv4プライベートIPが一つとインターネットからUnReachableなIPv6 GUAが/64で降ってきます。
勿論、ルーターとなっている仮想マシンには適切なファイアウォールを設定していて、仮令同じマンションの部屋からの通信であっても応答しません(の、筈)。
従来はこの/64のアドレスブロックから更に適当なPrefixを付けて/112のアドレスブロックを切り出して、NDP Proxyで上流にルートを広告していました。
今回はNDP Proxyを停止(廃止)して、新たにプライベートIP(IPv6ではユニークローカルアドレス、ULAと言います)オンリーな環境とし、尚且つインターネットとはIPv4と同様に上流ルーターだけが持つIPv6 GUAを使って通信出来る状態を作ります。
要するにIPv6でNAT(IPマスカレード)をします。
ちなみに某社UTMもUTMだけがGUAを持ち、配下にはULAを配布して通信させる様なので、特別トリッキーというわけではない、筈です。
実践
先ずはLAN内に広告するULAのアドレスブロックを決めましょう。
ULAのアドレスブロックはfd00::/8ですが、この内上位40bitをPrefix、更にその後ろ16bitをSubnetとして持ちます。
に寄れば、
厳密にはULA≠プライベートIPアドレスなので、外部のサイトとは重複しないIPアドレスを利用することが求められます。
つまり安易にオレオレPrefixを付けてはいけない、ということです。
自由にして良いのはSubnetの範囲だけ、という風に私は理解しました。
つまり今まで上流から勝手にPrefix付けて/112で切り出していたのも厳密にはアカン様な
上記条件を満たすためRFC4193が制定されており、上記URLから飛べるULA算出プログラムにルーターのMACアドレスを入力して実行するだけで簡単にULAを求めることが出来ます。
ありがたやありがたや。
というわけで仮想ルーターのMACアドレスを入力して得られたULAを元に、仮想ルーターの設定を変更していきます。
先ず仮想ルーターのNDP Proxyを停止します。
sudo systemctl stop ndppd
sudo systemctl disable ndppd
次に /etc/radvd.conf を次のように変更します。
以下、変更箇所または注釈は「 # <- 」の形で図示します。実際の設定の際には省いてください。
interface ethX
{
AdvSendAdvert on;
MinRtrAdvInterval 30;
MaxRtrAdvInterval 100;
AdvDefaultLifetime 120;
AdvManagedFlag off;
AdvOtherConfigFlag on;
prefix fdXX:XXXX:XXXX:XXXX::/64 # <-
{
AdvAutonomous on;
AdvOnLink on;
AdvRouterAddr on;
};
RDNSS fdXX:XXXX:XXXX:XXXX::1 # <-
{
AdvRDNSSPreference 8;
AdvRDNSSOpen off;
AdvRDNSSLifetime 119;
};
};
次に /etc/bind/named.conf.options を次の様に変更します。
options {
directory "/var/cache/bind";
recursion yes;
listen-on port 53 {
localhost;
192.168.XXX.0/2X;
};
listen-on-v6 port 53 {
localhost;
fdXX:XXXX:XXXX:XXXX::1; # <-
};
allow-query {
localhost;
192.168.XXX.0/2X;
fdXX:XXXX:XXXX:XXXX::/64; # <-
};
forwarders {
2606:4700:4700::1111;
2606:4700:4700::1001;
1.1.1.1;
1.0.0.1;
};
dnssec-validation no;
};
forwarders の部分はお好きなDNSサーバーの値に置き換えてください。
ここではCloudFlareのパブリックDNSを指定していますが、通常はDHCPで上流から広告されるDNSサーバーを指定した方が高速な気がします。
次に /etc/kea/kea-dhcp6.conf を次の様に変更します。
{
"Dhcp6": {
"valid-lifetime": 86400,
"renew-timer": 3600,
"rebind-timer": 7200,
"preferred-lifetime": 54000,
"decline-probation-period": 3600,
"interfaces-config": {
"interfaces": ["ethX”]
},
"lease-database": {
"type": "memfile",
"persist": true,
"name": "/var/lib/kea/dhcp6.leases"
},
"option-data": [
{
"name": "dns-servers",
"data": "fdXX:XXXX:XXXX:XXXX::1” # <-
},
{
"name": "domain-search",
"data": “XXXX.XXXX”
}
],
"subnet6": [
{
"subnet": "fdXX:XXXX:XXXX:XXXX::/64", # <-
"pools": [{
"pool": "fdXX:XXXX:XXXX:XXXX::/64" # <-
}],
"id": 1,
"interface": "ethX”
}
]
}
}
次に、 NetplanのLAN側インターフェイスの値を次の様に変更します。
network:
ethernets:
eth0:
accept-ra: false
addresses:
- 192.168.XX.1/24
- fdXX:XXXX:XXXX:XXXX::1/64 # <-
dhcp4: false
dhcp6: false
optional: true
version: 2
次に、 /etc/default/ufw を次の様に変更します。
IPV6=yes
DEFAULT_INPUT_POLICY="DROP"
DEFAULT_OUTPUT_POLICY="ACCEPT"
DEFAULT_FORWARD_POLICY="DROP"
次に、 /etc/ufw/sysctl.conf に次の行を追加します(既に値が存在する場合は変更してください)。
net/ipv6/conf/default/forwarding=1
net/ipv6/conf/all/forwarding=1
net/ipv6/conf/ethX/accept_ra=2 # <- WAN側のインターフェイスを指定してください。
net/ipv6/conf/ethX/accept_ra_pinfo=1 # <- WAN側のインターフェイスを指定してください。
net/ipv6/conf/ethX/autoconf=1 # <- WAN側のインターフェイスを指定してください。
次に、 /etc/ufw/before6.rules の下の方の「COMMIT」の下に以下の様な行を追加します。
# NAT rules
*nat
:POSTROUTING ACCEPT [0:0]
-F
-A POSTROUTING -s fdXX:XXXX:XXXX:XXXX::/64 -o ethX -j MASQUERADE # <- 「ethX」はWAN側のインターフェイスを指定してください。
COMMIT
最後に、UFWに内から外(LAN側インターフェイスからWAN側インターフェイス)へのパケット転送を許可するルールを設定します。
sudo ufw route allow in on ethX out on ethX from ::/0 port 32768:65535 proto udp # <- 「in on ethX」のethXはLAN側、「out on ethX」のethXはWAN側のインターフェイスを設定してください。
sudo ufw route allow in on ethX out on ethX from ::/0 port 32768:65535 proto tcp # <- 「in on ethX」のethXはLAN側、「out on ethX」のethXはWAN側のインターフェイスを設定してください。
以上が終わったら、sudo netplan try をして設定が正しいかどうか確かめます。
問題なければそのままENTERを押せば永続的に適用することが可能になります。
続いて sudo ufw reload を行います。
設定が正しければUFW Reloadedの表示が出ると思います。
続いて sudo systemctl daemon-reload を行った後、ルーターを再起動します。
ついでにDHCPでIPv6を取得していた機器も一旦LANから切断するか、IPv6を一旦オフ -> オンにすることをお勧めします(変更前のIPアドレスを掴み続ける端末があって大変だった……)。
ルーターの再起動が終わって新しいプリフィックスのIPとDNSとデフォルトゲートウェイが振られたのを確認したら、次の様なサイトにアクセスします。
カメが動いたり、実際の自分の端末IPではなくルーターが上流から取得しているGUAが表示されていれば成功です。
ちなみに最近のブラウザはアクセスしようとしているページがIPv4/IPv6デュアルスタックな場合、どちらからも読み込みを行ってデータのロードが速かった方を優先して表示する、という挙動をする様です。
その為、IPv6対応サイトでもIPv4で接続されたり、IPv6で読み込まれたのにリロードするとIPv4になる、といった様な挙動が発生する様です。
また、WindowsではULAのみが振り出される環境下に於いてインターネット上のIPv6のサービスに到達可能な状態であっても、GUAが振られていない場合は「インターネット接続なし」という表示になる様です(Windows10で確認)。
総括
被り難いとは言え、アドレスブロックの移譲を受けていないネットワークに勝手にオレオレPrefixを設定してはいけない(それはそう)。
GUAをルーターのみが持つネットワーク設計とすることにより、NDP Proxyが不要になり、また外から中のULAを直接知ることが出来ないのでセキュリティが向上した(と思う)。
GUAをルーターのみが持つことにより、従前環境では自宅側に居るVMとの通信ルートを起動時にStaticに(/usr/sbin/ip route -A inet6…を叩いて)設定しなくてはならなかったのが不要になった。
マンション備え付けの無料インターネットのプリフィックスが変わった場合(半固定的なIPoEなのでまず変わらないと思うが……)にあちこち書き直さなくてはいけなかった状態が、LAN内はULAを使う様にしたことで不要になった。
GUAに代わってULAを使う様になったため、従前ではIPv6で表示できていたサイトがIPv4になったり、あるいはその逆が発生することがある。
どうもULAしか振られていない場合、SpeedTestはIPv4でのみ稼働する節がある。
ちなみにFast.comはIPv6で接続できてIPv6で計測された。
今回の自宅ネットワーク改定により、特に速度が向上するとかいうことはない。