8
19
2018
UPnP/OpenHome Music Server の自作(その6)
APU2C4をルータとして機能させる(応用編:NAT)
前回は、APU2C4のオーディオ専用ネットワーク側(“eth1”)とLAN側(“eth0”)のネットワークとの間で、IPルーティングによる相互通信を行う設定を行い、実際にテスト環境で検証した結果を照会したが、如何だっただろうか.
IPルーティングを行うには、DHCPなどでIPアドレスがコロコロ変わるような環境では非現実的であることが理解できたであろうか.固定IPアドレスで運用する場合にはこれで十分なのだが、やはりもう少し柔軟な運用をしたいところだ.
…と言う訳でDHCPによるダイナミックなIPアドレスを使いつつ、オーディオ専用ネットワークとの間で相互通信する方法を検討してみることにしよう.前々回紹介した、NAT(Network Address Translation)という手法を思い出して欲しい.このNATは2つの異なるネットワークの間で、IPヘッダの中のIPアドレス情報を書き換えて相互に通信させる方法だ.
この場合、お互いのネットワークの境界を飛び越えられるのはNATを設定した特定のネットワーク機器のみで、設定されていないその他の機器から送出されるパケットは一切超えられないので、LAN側のノイジーなパケットデータがNATルータを飛び越えて、オーディオ専用ネットワーク側に流れ出ることはない.勿論、オーディオ専用ネットワーク側からの無関係なパケットもLAN側には流れ出ない.
今回想定するNAT実験環境
今回のNATルーティングでは、テスト用のPC1(192.168.10.101)をLAN側のネットワークから IPアドレス(192.168.100.51) を使ってアクセスできるようにする.LAN側のネットワーク機器からテスト用のPC1にアクセスする際は、このNAT変換用のアドレスを使ってアクセスすることになる.同じネットワークの一員であるので、LAN側のネットワーク機器はPC1への面倒なルーティング設定を行う必要がないのである.
ファイアウォール機能の有効化
最初にCentOS7をインストールした際に、標準で組み込まれているファイアウォール機能を外して構築してきた.これは、Linuxサーバ初心者にとってはファイアウォール機能を正しく実装するのは至難の技だからだ.Linuxサーバをきちんと運用するにはこのファイアウォール機能が必須の設定なのだが、今回の様な家庭内のプライベートなネットワーク環境では殆ど必要のない機能だ.
必要のない機能とは言う物の、実はNATやNAPT環境を実装するにはこのファイアウォール機能(正確にはnetfilterというカーネル内の転送機能)を働かせて、きちんと設定する必要がある.Linuxサーバ初心者にとっては鬼門的な存在のファイアウォール機能なのだが、とりあえず内容を完全に理解できなくとも、見よう見まねで挑戦してみて欲しい.
CentOS 7(RedHat Enterprise Linux 7)系列からOSの管理コマンド体系が大きく変わってしまったことは前の記事で述べたが、ファイアウォール関係の設定方法も大きく変わってしまっている.以前は、iptablesという機能によってファイアウォール機能を実装しており、ファイアウォールの管理方法もiptablesの設定ファイルを直接弄るという方法だった.
CentOS 7系列からは、iptablesは完全に裏方に廻り、firewalldという別な機能でファイアウォール機能を管理するようになり、管理の仕方が根本から変わってしまった.新しい管理方法に変わってから数年経ったので、この新しい管理方法も大部普及してきたようだ.ネットを漁ればfirewalld関連の記事が沢山見つかるので、まだ不意慣れだという方々はこの際に新しい管理方法に移行してみることをお薦めする.
無効化していたfirewalldを復活させる
先ずはCentOS 7 インストール直後に無効かしていた “firewalld” サービスを復活させる必要がある.無効化するときのコマンドは “systemctl disabled firewalld” だったが、有効化は “systemctl enabled firewalld” である.
“firewalld” サービスを自動起動するように設定したところで、”firewalld” サービスを手動で起動しておく.この時点で、デフォルトのファイアウォール設定が有効になるので、ssh(TCP/22)以外のサービスが受け付けられなくなるので、NFSやMinimServerなどは事前に止めておくことを推奨する.
“firewalld” では対象とするネットワークの範疇をゾーン(zone)という概念でカテゴライズしている.このゾーンはデフォルトで下記に示す9つが定義されており、初期の状態では、”public” というゾーンに全てのネットワークインタフェースが属している.
・”block” : 外部から入ってきた全ての(inbound)トラフィックを破棄する
outboundパケットに対する応答は許可する
・”drop” : 外部から入ってきた全ての(inbound)トラフィックを破棄する
outboundパケットに対する応答も破棄する
・”public” : ssh(TCP/22)とdhcpv6-client のみ通信が許可されている
・”external” : ssh(TCP/22)のみ通信が許可されている.
NAPT(IP Masquerade)機能が設定されている.
・”internal” : ssh(TCP/22)、dhcpv6-client、samba-client、mdns、ipp-clientが
許可されている.
・”home” : “internal” と同じ内容
・”work” : ssh(TCP/22)、dhcpv6-client、ipp-clientが許可されている.
・”dmz” : ssh(TCP/22)のみが許可されている.
・”trusted” : 全てのパケットが許可されている.
[root@jukebox ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
[root@jukebox ~]# systemctl enable firewalld
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.
[root@jukebox ~]# systemctl start firewalld
[root@jukebox ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2018-08-19 17:29:00 JST; 1min 25s ago
Docs: man:firewalld(1)
Main PID: 1635 (firewalld)
CGroup: /system.slice/firewalld.service
└─1635 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
Aug 19 17:28:58 jukebox systemd[1]: Starting firewalld - dynamic firewall daemon...
Aug 19 17:29:00 jukebox systemd[1]: Started firewalld - dynamic firewall daemon.
[root@jukebox ~]#
“firewalld”サービスを起動した状態で、デフォルトのゾーン設定状態と9種類のゾーンの設定内容を確認しておく.
[root@jukebox ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1 eth2 <== 3つのインタフェースが全て "public" ゾーンに設定
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@jukebox ~]# firewall-cmd --list-all-zones <== 各ゾーンの内容を表示
block
target: %%REJECT%%
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
dmz
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
drop
target: DROP
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
external
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
home
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh mdns samba-client dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
internal
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh mdns samba-client dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1 eth2
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
trusted
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
work
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@jukebox ~]#
[root@jukebox ~]# firewall-cmd --set-default-zone=trusted <== デフォルトゾーンの変更
success
[root@jukebox ~]# firewall-cmd --get-default-zone
trusted
[root@jukebox ~]# firewall-cmd --get-active-zones
trusted
interfaces: eth0 eth1 eth2
[root@jukebox ~]#
この状態では、3つのNICとも全て “public” ゾーンに組み入れられているので、ssh(TCP/22)とdhcpv6-clientしか通信が許可されていない.この状態では NFSやMinimServerなどの通信が完全に遮断されてしまうので、とりあえずファイアウォールとしての機能を停止する必要がある.勿論、通常のサーバ用途ではきちんとファイアウォール機能を実装しなければならないが、今回は家庭内の閉じた環境だけでの使用なので、ファイアウォールとしての機能は停止させておく.
ファイアウォールとしての機能が働かないようにするには、現在の”public” ゾーンから”trusted” に変更すれば、”firewalld” サービスを止めていた時と同じ状態になる.ファイアウォール設定コマンド”firewall-cmd” でを用いてゾーンを変更してみよう.この後のNAPTルータの設定で、一部ゾーンを変更するかもしれないが、とりあえず今回は全て “trusted” ゾーンで設定することにする.
[root@jukebox ~]# firewall-cmd --zone=trusted --change-interface=eth0
The interface is under control of NetworkManager, setting zone to 'trusted'.
success
[root@jukebox ~]# firewall-cmd --zone=trusted --change-interface=eth1
The interface is under control of NetworkManager, setting zone to 'trusted'.
success
[root@jukebox ~]# firewall-cmd --zone=trusted --change-interface=eth2
The interface is under control of NetworkManager, setting zone to 'trusted'.
success
[root@jukebox ~]# firewall-cmd --reload <== 設定変更を即座に反映させる
success
NATの実装
これまでのIPルーティング方式をNATに変えるメリットは何かと問われると、実は手間暇の割には音質的な優位性はないというのが実情だろうか.強いて挙げるとすれば、LAN側の各機器からオーディオ専用ネットワーク上に置かれた機器を、あたかも自分と同じネットワークに居るように見せ掛けることができることだろうか.
ネットワークオーディオ機器は物理的に別なネットワークに存在するので、LAN側のノイズの影響を受けることも無く、また、LAN側の各機器からはネットワークオーディオ機器が同じネットワークに属していることになるので、IPルーティングの時のようにオーディオネットワークに関するルーティング設定など全く気にしなくて良い.
NATは送信元のIPアドレス書き換え(Source NAT) と戻りパケットの宛先IPアドレス書き換え(Destination NAT)という2回のIPアドレス書き換えが行われる.これを “firewalld” の機能で実装するには、次のコマンドを設定すれば良い.コマンドの個々のパラメータの説明は難しいので、内容を理解できなくてもとりあえずおまじないだと思って設定して欲しい.
テスト用のPCのIPアドレスは192.168.10.101、APU2C4の “eth0” に付加する別名 IPアドレスは192.168.100.51とする.”eth0″自体にはDHCPでIPアドレスが割り当てられており、それとは異なるNAT変換のアドレス(192.168.100.51)をエイリアス(別名)IPとして設定する.”eth0″の実体アドレス192.168.100.xxx はルータ自体の機能として使用しているので、NAT変換専用の別なIPアドレスを”eth0″に設定しておく必要がある.
・送信時の送信元のIPアドレス書き換え
firewall-cmd –permanent –direct –add-rule ipv4 nat POSTROUTING_direct 0 -s 192.168.10.101 -j SNAT –to 192.168.100.51
・戻り時の宛先IPアドレス書き換え
firewall-cmd –permanent –direct –add-rule ipv4 nat PREROUTING_direct 0 -d 192.168.100.51 -j DNAT –to 192.168.10.101
・”eth0″に別名でIPアドレスを付加する
nmcli connection modify eth0 +ipv4.addresses “192.168.100.51/24”
上記コマンドを設定したら、”eth0″に付けた別名IPアドレスを有効化するため、ネットワークを再起動する.これでテストPC(192.168.10.101)がLAN側の各機器に対して、自分があたかも192.168.100.51 のIPアドレスを持っている機器であるかのように振る舞うことができるようになる.
[root@jukebox ~]# firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING_direct 0 -s 192.168.10.101 -j SNAT --to 192.168.100.51
success
[root@jukebox ~]# firewall-cmd --permanent --direct --add-rule ipv4 nat PREROUTING_direct 0 -d 192.168.100.51 -j DNAT --to 192.168.10.101
success
[root@jukebox ~]# nmcli connection modify eth0 +ipv4.addresses 192.168.100.51/24
[root@jukebox ~]# firewall-cmd --reload
[root@jukebox ~]# systemctl restart network
[root@jukebox ~]# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0d:b9:47:1c:18 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.167/24 brd 192.168.100.255 scope global noprefixroute dynamic eth0
valid_lft 86388sec preferred_lft 86388sec
inet 192.168.100.51/24 brd 192.168.100.255 scope global secondary noprefixroute eth0
valid_lft forever preferred_lft forever
3: eth1: mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0d:b9:47:1c:19 brd ff:ff:ff:ff:ff:ff
inet 192.168.10.254/24 brd 192.168.10.255 scope global noprefixroute eth1
valid_lft forever preferred_lft forever
4: eth2: mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether 00:0d:b9:47:1c:1a brd ff:ff:ff:ff:ff:ff
inet 192.168.20.254/24 brd 192.168.20.255 scope global noprefixroute eth2
valid_lft forever preferred_lft forever
[root@jukebox ~]# nmcli device show eth0
GENERAL.DEVICE: eth0
GENERAL.TYPE: ethernet
GENERAL.HWADDR: 00:0D:B9:47:1C:18
GENERAL.MTU: 1500
GENERAL.STATE: 100 (connected)
GENERAL.CONNECTION: eth0
GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1
WIRED-PROPERTIES.CARRIER: on
IP4.ADDRESS[1]: 192.168.100.51/24
IP4.ADDRESS[2]: 192.168.100.167/24
IP4.GATEWAY: 192.168.100.254
IP4.ROUTE[1]: dst = 0.0.0.0/0, nh = 192.168.100.254, mt = 100
IP4.ROUTE[2]: dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[3]: dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.DNS[1]: 192.168.100.11
IP4.DNS[2]: 192.168.100.20
IP4.DOMAIN[1]: home.yoko
IP6.GATEWAY: --
IP6.DNS[1]: 2404:1a8:7f01:a::3
IP6.DNS[2]: 2404:1a8:7f01:b::3
[root@jukebox ~]#
NATが機能しているかどうか確認してみよう
先ずは、iMacから NAT変換用のIPアドレス(192.168.100.51) にpingを打ってみる.
iMac27:~ yasuaki$ ping 192.168.100.51
PING 192.168.100.51 (192.168.100.51): 56 data bytes
64 bytes from 192.168.100.51: icmp_seq=0 ttl=63 time=1.014 ms
64 bytes from 192.168.100.51: icmp_seq=1 ttl=63 time=0.714 ms
64 bytes from 192.168.100.51: icmp_seq=2 ttl=63 time=0.798 ms
^C
--- 192.168.100.51 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.714/0.842/1.014/0.126 ms
iMac27:~ yasuaki$
これだけでは、APU2C4の “eth0” が応答しているのか、テストPC自体が応答しているのか判らないので、テストPCのネットワークケーブルを抜いた状態で再度pingを打ってみる.
iMac27:~ yasuaki$ ping 192.168.100.51
PING 192.168.100.51 (192.168.100.51): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
^C
--- 192.168.100.51 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss
iMac27:~ yasuaki$
確かにテストPCからのping応答のようだ.念のため、テストPC上でWEBサーバを動かして、それをiMacから”http://192.168.100.51/index.html” でアクセスしてみる.同じように、LAN内に立てられている”smokeping”サーバ “smokeping” に対して、テストPCからアクセスして、httpのアクセスログの接続記録から、どのIPアドレスからアクセスされていたかを確認する.
テストPC上にWEBサーバを立ち上げる(Mac OS Xの “Web Sharing”をON)
iMacのWEBブラウザからテストPCのNAT変換アドレス(192.168.100.51)にアクセス
LAN内の”smokeping”サーバにテストPCからアクセスして、httpアクセスログを確認
NAT環境下でもSynology NAS(192.168.100.20)に問題無くアクセスできることを確認
上記のテスト結果から確かにきちんとNAT変換されていることが確認できる.勿論NAT変換されていても、きちんとNFSサーバにアクセス可能だ.
またまた長くなってしまったので、NAPTの説明は次回と言うことで...