1つのプログラムをwlan1
インターフェイスにバインドする必要があります。他のすべてのプログラムは、デフォルトでwlan0
を使用する必要があります。
このため、専用のネットワーク名前空間を構成しました。
ip netns add wlan1_ns
ip link add vwlan1a type veth peer name vwlan1b
ip link set vwlan1a netns wlan1_ns
ip addr add 10.200.1.1/24 dev vwlan1b
ip link set vwlan1b up
ip netns exec wlan1_ns ip addr add 10.200.1.2/24 dev vwlan1a
ip netns exec wlan1_ns ip link set vwlan1a up
ip netns exec wlan1_ns ip link set lo up
ip netns exec wlan1_ns ip route add default via 10.200.1.1
iptables -t nat -A POSTROUTING -s 10.200.1.0/255.255.255.0 -o wlan1 -j MASQUERADE
iptables -A FORWARD -i wlan1 -o vwlan1b -j ACCEPT
iptables -A FORWARD -o wlan1 -i vwlan1b -j ACCEPT
これを行った後、ドメイン名の解決が新しい名前空間で機能することを期待していますが、明らかにそうではありません、なぜですか?:
$ Sudo ip netns exec wlan1_ns ping -v google.com
ping: socket: Permission denied, attempting raw socket...
ping: socket: Permission denied, attempting raw socket...
ping: google.com: Temporary failure in name resolution
...ルート名前空間にいる間、ホストの解決は正常に機能します(wlan1
はインターネットに接続されていないため、パケット損失が発生しますが、気にしないでください)。
# ping google.com
PING google.com (216.58.212.238) 56(84) bytes of data.
^C
--- google.com ping statistics ---
122 packets transmitted, 0 received, 100% packet loss, time 125718ms
ドメイン名の代わりにIPでping/curlを使用すると、リクエストが正しく送信されます。なぜ解決がうまくいかないのか、私はアイデアを使い果たしました。私はこれをRaspberryPi3、Raspbian、カーネル4.9で行っています。私がすでに調査したものを以下に見つけてください。
nsswitch.confファイル:
$ cat /etc/nsswitch.conf | grep Host
hosts: files mdns4_minimal [NOTFOUND=return] dns
ルート名前空間のresolvconf応答:
$ resolvconf -l
# resolv.conf from lo.dnsmasq
nameserver 127.0.0.1
# resolv.conf from wlan1
# resolv.conf for wlan1
domain coova.org
nameserver <<ANONYMIZED DNS IP>>
nameserver <<ANONYMIZED DNS IP>>
名前空間のresolvconf:
$ ip netns exec wlan1_ns resolvconf -l
# resolv.conf from lo.dnsmasq
nameserver 127.0.0.1
# resolv.conf from wlan1
# resolv.conf for wlan1
domain coova.org
nameserver <<ANONYMIZED DNS IP>>
nameserver <<ANONYMIZED DNS IP>>
ルート名前空間のiptables
$ Sudo iptables -v --list
Chain INPUT (policy ACCEPT 641 packets, 63289 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 171 packets, 90385 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- wlan1 vwlan1b anywhere anywhere
32 1816 ACCEPT all -- vwlan1b wlan1 anywhere anywhere
Chain OUTPUT (policy ACCEPT 802 packets, 91050 bytes)
pkts bytes target prot opt in out source destination
私の名前空間のiptables:
$ Sudo ip netns exec wlan1_ns iptables -v --list
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
到達可能なdnsmasqIPを指すようにresolvconfを構成しました。
pi@raspberrypi:~ $ Sudo sh -c "echo nameserver 172.24.1.1 | resolvconf -a lo.dnsmasq"
Too few arguments.
Too few arguments.
pi@raspberrypi:~ $ resolvconf -l
# resolv.conf from lo.dnsmasq
nameserver 172.24.1.1
# resolv.conf from wlan1
# resolv.conf for wlan1
domain coova.org
nameserver <<ANONYMIZED _IP>>
nameserver <<ANONYMIZED _IP>>
IPが到達可能であることを証明するために、Dig
はドメイン名を正しく解決します。
pi@raspberrypi:~ $ Sudo sh -c "ip netns exec wlan1_ns Dig +short @172.24.1.1 google.com"
172.217.17.142
... ping
にはまだ問題があります:
pi@raspberrypi:~ $ Sudo sh -c "ip netns exec wlan1_ns ping -v google.com"
ping: socket: Permission denied, attempting raw socket...
ping: socket: Permission denied, attempting raw socket...
ping: google.com: Temporary failure in name resolution
ネットワーク名前空間は、リゾルバーとしてdnsmasqを実行しているように見えるループバックインターフェイスも分離します。これが、名前空間がドメイン名の解決に失敗する理由です。名前空間がインターネットに接続されている場合は、resolv.confのネームサーバーを名前空間からアクセスできるネームサーバーに変更することで、これを簡単にテストできます。 as Google Public DNS 。
dnsmasqをリゾルバーとして使用するには、名前空間から到達できるアドレスをリッスンするように構成し、それに応じてresolv.confを変更する必要があります。