更新履歴
2023/12/15
firewalldの設定一部修正
2022/11/25
ndppdのパッケージさらに追加。一部修正
2021/10/23
CentOS8向けndppdのパッケージ追加
2020/6/18
2.4 ndppd の修正と 2.5 firewalld の追加。CentOS 8.2でfirewalldのゾーンのマスカレード設定がIPv6を無視するようになってくれたので、IPv6-NATを使わない設定を追加
2020/3/29
便利なポートテストサイトを見つけて動作確認ができたので、ファイアウォールの設定追記。知識が怪しすぎて用語の使い方が酷すぎたのを少し整理。。。
はじめに
CentOS7をIPv4(PPPoE)のブロードバンドルーターとして稼働させていますが、今回はIPv6(IPoE)も使えるようにしたいと思います。タイトルはCentOS7ですが、修正を重ねてCentOS8.2向けの記事になってきてる気がします
firewalldのバージョンによって挙動がコロコロ変わるので、バージョン次第ではこの記事通りの設定ではうまくいかないかもしれません
Linuxの知識もネットワークの知識もセキュリティの知識もない素人なのでつっこみどころがあるのはご容赦ください。この記事を書く3日前にNDPとかIPv6リンクローカルアドレスとかを初めて聞いたくらいのレベルです
IPv4はそのままPPPoEで、IPv6のみIPoEを使うようにします。市販の家庭用のブロードバンドルーターだとPPPoEとIPoEの共存は2台のルーターが必要になることもあるようですが、今回は1台で両方使えるようにします
流行?のIPv4 over IPv6はこの記事では扱いません。
次の記事でやってます → CentOS7でOCNバーチャルコネクト
環境
- 回線:フレッツ光ネクスト
- プロバイダ:OCN
- ひかり電話なし、HGWなし
- 最終確認:CentOS 8.2(firewalldのバックエンドはiptables)
大体こんな環境です。タイトルはCentOS7ですが、最後に確認したのは8.2です。ご了承ください。
雑な図ですが、上図から下図に変更します。IPv4(PPPoE)環境は全く変更せず、IPv6(IPoE)を追加します。IPv6対応サイトにアクセスするときにIPv6(IPoE)でアクセスするようにします。また、自分で建てているサーバーにIPv6(IPoE)でアクセスできるようにします
市販の家庭用IPv6のルーターは、IPv6ブリッジ(パススルー)のものとNDプロキシのものがあるようですが、セキュリティ面を考えブリッジを使わないルーターにします。IPv6環境下でもIPv4のようにWAN側とLAN側でわけ、セキュリティを確保します
基本的にはIPv6対応サイトへのアクセスとIPv6からのアクセスがPPPoEからIPoEに変わるだけで、それ以外については変わらないようにします
手順
以下、WAN側のインターフェイスをenp2s0、LAN側のインターフェイスをbr0としてすすめていきます
また、すでにプロバイダ等との契約が済んでいて、WAN側(enp2s0)にIPv6のグローバルIPが降ってきているものとします
sysctlの設定
まずはIPv6パケット転送を有効にしてルーターとして動作できるようにします
1 |
# vi /etc/sysctl.conf |
1 |
net.ipv6.conf.all.forwarding=1 |
1 |
# sysctl -p |
1行追加し、反映させます
radvdの設定
1 |
# yum install radvd |
LAN内のPCがIPv6アドレスを自動で設定できるようにするためにradvdをインストールします
1 |
# ip a |
WAN側NICのIPv6のグローバルアドレスを確認します
1 2 3 4 5 6 |
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1454 qdisc mq state UP group default qlen 1000 link/ether 80:ee:73:ab:4f:68 brd ff:ff:ff:ff:ff:ff inet6 2400:xxxx:xxxx:xxxx::1:1/64 scope global noprefixroute dynamic valid_lft 2591901sec preferred_lft 604701sec inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link noprefixroute valid_lft forever preferred_lft forever |
inet6のfe80から始まらない方がグローバルアドレスです
1 |
# vi /etc/radvd.conf |
1 2 3 4 5 6 7 8 9 10 11 |
interface br0 { AdvSendAdvert on; AdvLinkMTU 1500; prefix 2400:xxxx:xxxx:xxxx::/64 { AdvOnLink on; AdvAutonomous on; }; }; |
interfaceにはLAN側のインターフェイスを指定します。prefixにはさきほど調べたグローバルアドレスのプレフィックスを入れます
(2400:xxxx:xxxx:xxxx::1:1/64 だったら 2400:xxxx:xxxx:xxxx::/64)
AdvLinkMTUを設定するとLAN内のNICのIPv6のMTUが自動で設定されます。統一したい場合はWAN側のMTUと同じ値をいれてしまいましょう
IPoEなら1500固定でいいと思いますが、Path MTU Discovery Black Holeの回避で1280にしたい方もいるかも。個別に設定したいならAdvLinkMTUオプション削除で
radvd.confのマニュアル – https://linux.die.net/man/5/radvd.conf
1 |
# systemctl start radvd |
これでLAN内のPCにIPv6アドレスが自動で設定されるようになります。30秒ほど待って設定されているか確認します
1 |
# ip a |
1 2 3 4 5 6 |
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:22:cf:ed:04:c3 brd ff:ff:ff:ff:ff:ff inet 192.168.1.1/24 brd 192.168.1.255 scope global noprefixroute br0 valid_lft forever preferred_lft forever inet6 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0/64 scope global noprefixroute dynamic valid_lft 86202sec preferred_lft 14202sec |
LAN側のインターフェイスにも2400:xxxx:xxxx:xxxxからはじまるグローバルIPが設定されたら成功です。xxxx以降の部分はMACアドレスなどから自動で決まるようです
これでLANの端末にはすべて2400:xxxx:xxxx:xxxxから始まるグローバルIPアドレスが自動で振られるようになります
MACアドレスをもとに自動で振られることや、全部がグローバルIPってのはIPv4のときの感覚とはずいぶん違いますね
ルーティングの確認
ルーティングに問題があると通信ができないので確認します
1 |
# ip -6 r |
1 2 |
2400:xxxx:xxxx:xxxx::/64 dev enp2s0 proto ra metric 100 pref medium 2400:xxxx:xxxx:xxxx::/64 dev br0 proto ra metric 425 pref medium |
私の例。2400:xxxx:xxxx:xxxx~のIPアドレスはグローバルアドレスですが、ルーターから見た場合はLANのPCのアドレスということになります。つまり2400:xxxx:xxxx:xxxx~とはLAN側のインターフェイス(br0)で通信しないといけません。
ということはメトリック値はLAN側のインターフェイスの方が低くなければいけません。この私の例の場合、WAN側(enp2s0)がLAN側(br0)より優先されてしまうので、LAN側への通信もWAN側(enp2s0)で行おうとしてしまい、通信に失敗してしまいます
1 2 3 |
# nmcli connection modify enp2s0 ipv6.route-metric 500 # nmcli connection down enp2s0 # nmcli connection up enp2s0 |
もしWAN側のメトリック値がLAN側のメトリック値より低かった場合は、LAN側よりも高くします
1 |
# ip -6 r |
1 2 |
2400:xxxx:xxxx:xxxx::/64 dev br0 proto ra metric 425 pref medium 2400:xxxx:xxxx:xxxx::/64 dev enp2s0 proto ra metric 500 pref medium |
確認。これでLAN側の端末へパケットが流れるようになります
1 2 3 4 5 6 7 8 9 10 11 12 |
C:\WINDOWS\system32>ping -6 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 に ping を送信しています 32 バイトのデータ: 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 からの応答: 時間 <1ms 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 からの応答: 時間 <1ms 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 からの応答: 時間 <1ms 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 からの応答: 時間 <1ms 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 の ping 統計: パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、 ラウンド トリップの概算時間 (ミリ秒): 最小 = 0ms、最大 = 0ms、平均 = 0ms |
LANにある他の端末からPingが通るか確認します。WindowsからPingを試した例です。ルーティングが正しければ、あとはPing拒否の設定をしていなければ通るはずです
LANのPCとルーターが通信できないと、LANのPCがインターネットにつながりません
ndppdの設定
NDプロキシの設定を自動でやってくれるndppdのインストールをします
インストール
パッケージをインストール
いつの間にかEPELリポジトリに追加されていました。EPELリポジトリを有効にしてインストールします
1 |
# dnf install ndppd |
CentOS8用しか用意されていないようなので、CentOS7の場合はソースからインストールします以下のソースからインストールの部分は不要になりましたが、一応残しておきます
ソースからインストールする場合
1 2 3 4 |
# git clone https://github.com/DanielAdolfsson/ndppd # cd ndppd # make # make install |
ndppdを入手し、make&インストールします
1 2 |
# cp ndppd.service /etc/systemd/system/ # vi /etc/systemd/system/ndppd.service |
デーモン用ファイルをコピーして編集します
1 2 3 4 |
[Service] ExecStart=/usr/local/sbin/ndppd -d -p /var/run/ndppd.pid Type=forking PIDFile=/var/run/ndppd.pid |
ndppdのパスを合わせます。PIDファイルの場所も適宜変更します
1 |
# systemctl daemon-reload |
リロードします
設定
1 |
# vi /etc/ndppd.conf |
18 19 20 21 22 23 24 25 26 27 28 29 |
route-ttl 30000 address-ttl 30000 proxy enp2s0 { router no autowire yes promiscuous no rule 2400:xxxx:xxxx:xxxx::/64 { iface br0 autovia yes } } |
proxyにはWAN側デバイスを、ruleには radvd.conf でも使ったプレフィックスを使います。ifaceはなんとなくautoからLAN側のインターフェイスの明記に変えました
ndppd/ndppd.conf-dist at master · DanielAdolfsson/ndppd · GitHub
設定ファイルの説明はこちらを参照してください
1 2 |
# systemctl start ndppd # systemctl enable ndppd |
起動します
firewalldの設定
WAN側のIFをexternalゾーン(マスカレードを有効にしているゾーン)につっこみます。firewalldの設定でつっこむか、networek managerの方で設定するかどちらかで
1 2 |
# firewall-cmd --permanent --zone=external --change-interface=enp2s0 # firewall-cmd --reload |
firewalldの場合
CentOS 8.1(firewalld-0.7.1)以前の場合、ゾーンのマスカレードの設定を有効にすると、IPv4だけでなくIPv6のフォワードとNATの設定もする(してしまう)ので、特に設定しなくても通信できてしまいます
CentOS 8.2(firewalld-0.7.2)以降の場合は本来不要なIPv6のNATをしなくなりました。フォワードの設定は自分で書く必要がある場合があります。
firewalldのバージョン、設定次第では以下が必要です。IPv6での接続確認ができない場合は以下を実行してみてください。
1 2 |
# firewall-cmd --permanent --direct --add-rule ipv6 filter FORWARD 0 -i br0 -o enp2s0 -j ACCEPT # firewall-cmd --reload |
-iの方はLAN側、-oの方はWAN側デバイスを指定します
DNSの設定
使っているDNSサーバーがAレコード(IPv4アドレス)とAAAAレコード(IPv6アドレス)の両方を返すものであれば変更する必要はありません。Aレコードしか返さないものであれば変更する必要があります
例えばGoogle Public DNS(8.8.8.8)を使っている場合であれば変更する必要はありません
1 |
# dig AAAA google.com |
1 2 |
;; ANSWER SECTION: google.com. 299 IN AAAA 2404:6800:4004:81a::200e |
digコマンドでAAAAレコードを調べることができます。このようにAAAAレコードが返ってこなければDNSサーバーの設定を変更する必要があります
DNSサーバーを立てている場合はDNSサーバーの設定を、立てていない場合は /etc/resolv.conf 等PCのDNSの設定を変える必要があります
DNSサーバーへのアクセスもIPv6(IPoE)にしたい場合は使用するDNSサーバーをIPv6のアドレスに変更しましょう
例えばGoogle Public DNSであれば
2001:4860:4860::8888 / 2001:4860:4860::8844
です。これらもAレコードとAAAAレコードの両方が返ってくるので、IPv4にもIPv6にも使えます
接続確認
IPv6動作確認サイトにアクセスします
1 2 |
# systemctl enable radvd # systemctl enable ndppd |
問題なさそうであれば、radvdとndppdを自動起動するようにします
ファイアウォールの設定
IPv6でLAN内のサーバーを外部に公開したい場合、したくない場合の手順を確認します
IPv4のときと同じような感覚で運用できるような気がします
端末 | IF | zone | IPv4アドレス | IPv6アドレス |
ルーター | enp2s0 | external | 2400:xxxx:xxxx:xxxx::1:1 | |
br0 | internal | 192.168.1.1 | 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0 | |
サーバー | eno1 | internal | 192.168.1.10 | 2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas |
たとえばLANにサーバーがあったとします。サーバーでWebサーバー(ポート番号8080)をたて、外部に公開する例を考えてみます。サーバーの8080番ポートはすでにあいてるものとします
ポートフォワード
IPv4の場合であれば、ポートフォワードの設定をして外部に公開しますが、IPv6でも同じような手順で公開できます
1 2 3 |
# firewall-cmd --zone=external --add-forward-port=port=8080:proto=tcp:toaddr=192.168.1.10 --permanent # firewall-cmd --zone=external --add-forward-port=port=8080:proto=tcp:toaddr=2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas --permanent # firewall-cmd --reload |
上がIPv4のポート転送の設定、下がIPv6のポート転送の設定です。IPv4をIPv6のアドレスに変えるだけで手順は同じです。これで
http://IPv4のグローバルアドレス:8080 や、ルーターのWAN側IPv6グローバルIPを使って
http://[2400:xxxx:xxxx:xxxx::1:1]:8080 でアクセスできます
サーバー側のグローバルIPを使って
http://[2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas]:8080
などとアクセスしようとしてもアクセスできません。IPv4のときのようなNATの内側と同じ感覚での運用になると思います
firewalldの説明だとゾーンでのポート転送はipv4限定となってるのですが使えてしまいます(バージョン次第?)
また、NDプロキシがなくてもアクセスできてしまうので、ndppdを起動してなくてもアクセスできてしまいます
通過許可
サーバーのグローバルIPを使って、ポートフォワードを使わすにサーバーにアクセスできるようにすることも可能です
1 |
# firewall-cmd --direct --add-rule ipv6 filter FORWARD 0 -i enp2s0 -o br0 -p tcp -d 2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas --dport 8080 -j ACCEPT |
LAN側のサーバーの8080ポートへのアクセスを通過許可する設定例です
これで、サーバーのグローバルIPを使って
http://[2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas]:8080
でアクセスできるようになります。ndppdを切るとアクセスできなくなります
ドメインを持っている場合は、IPv6のグローバルアドレスを追加すればIPv4とIPv6の両方に対応したWebサーバーになります
もちろんIPv4(またはIPv6)でのみ外部公開する、ということもできます
設定したらテストサイトを使って確認します
IPv6ポートテストサイト
http://www.ipv6scanner.com/cgi-bin/main.py
https://ipv6.chappell-family.com/ipv6tcptest/
参考サイト
コメント