OpenStack上でLinuxルーター作る時の知見とか

ども。
昨夜は17時から飲み始め、22時前には潰れるという最高な週末でした、
P山です。

週末にかけて、OpenStackでOpenVPNのスループット取ろうと思って、
VPNルーターを作った際にハマった知見をご紹介します。

構成図

スクリーンショット 2015-04-05 18.26.27

ネットワーク

  • 仮想インターネット 210.252.100.0/24
  • SiteA-Internal 192.168.0.0/24
  • SiteB-Internal 172.16.0.0/24

ホスト

  • SiteA-vpn-host 210.252.100.2 / 192.168.0.7
  • SiteB-vpn-host 210.252.100.101 / 172.16.0.5
  • SiteB-host 172.16.0.8

やりたかったこと

SiteA-vpn-hostとSiteB-vpn-hostを仮想Internet上でVPNセッションを結び、
それぞれのサイトにhostを設置して、SiteA-hostとSiteB-host間の通信のスループットを取ろうと思っていました。

#
SiteA-host => SiteA-vpn-host <== VPN ==> SiteB-vpn-host <= SiteB-host
#
&#91;/shell&#93;

この時に、VPNセッションを結んで、SiteA-vpn-hostとSiteB-vpn-hostはVPNトンネル通して正常にtapに割り振られたIPでやりとりすることは出来ました。

しかし、ルーティングを正しく設定したとしても、SiteB-hostから送信したパケットが、SiteA-vpn-hostに到達しませんでした。


<h1>切り分け</h1>
上記から問題はSiteB-vpn-hostのルーターとしての機能に問題があると判断しました。


# sysctl -p
net.ipv4.ip_forward = 1

ルーティング設定は正常に行われています。

切り分けをわかりやすくするため、SiteB-hostからSiteA-vpn-hostへの通信を、SiteB-vpn-hostを経由するルーティングへと変更します。

SiteB-hostのルーティング設定

[root@siteb-host ~]# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         172.16.0.254    0.0.0.0         UG        0 0          0 eth0
10.8.0.0        172.16.0.5      255.255.255.0   UG        0 0          0 eth0
172.16.0.0      0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.0.0     172.16.0.5      255.255.255.0   UG        0 0          0 eth0
210.252.100.0   172.16.0.5      255.255.255.0   UG        0 0          0 eth0 #このレコードを追加

この時点でSiteB-hostからSite-A-vpn-hostへpingを打つと、

[root@siteb-host ~]# ping 210.252.100.2
PING 210.252.100.2 (210.252.100.2) 56(84) bytes of data.
^C
--- 210.252.100.2 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 2999ms

疎通がありません。

SiteB-vpn-host上でのtcpdump
仮想インターネット側

[root@siteb-vpn-host log]# tcpdump icmp -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:07:07.007524 IP host-172-16-0-8.openstacklocal > 210.252.100.2: ICMP echo request, id 916, seq 120, length 64
10:07:08.007539 IP host-172-16-0-8.openstacklocal > 210.252.100.2: ICMP echo request, id 916, seq 121, length 64
10:07:09.007531 IP host-172-16-0-8.openstacklocal > 210.252.100.2: ICMP echo request, id 916, seq 122, length 64

SiteA-vpn-host(210.252.100.2)に対して確かにパケットを送信しています。

SiteA-vpn-host上でのtcpdump

[root@sitea-vpn-host ccd]# tcpdump icmp -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

少なくとも、SiteB-vpn-hostはSiteB-hostからのパケットをSiteA-vpn-hostに送っていますが、
SiteA-vpn-hostに到達していないことから、通信経路がこのパケットの送信を許可していないことがわかります。

このことから仮説として、OpenStackのネットワークは自身が管理していないサブネットをFromIPかDestIPに持つパケットの送信を許可していないのではないかと思えます。

仮説の検証として、SiteB-vpn-hostのインターネット向けの通信をIPマスカレードしてみます。

$ systemctl start firewalld
$ firewall-cmd --zone=external --change-interface=eth0
$ firewall-cmd --zone=internal --change-interface=eth1

再度tcpdumpを取ると、

SiteB-vpn-host上でのtcpdump
仮想インターネット側

[root@siteb-vpn-host log]# tcpdump icmp -i eth0 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:22:24.591477 IP 210.252.100.101 > 210.252.100.2: ICMP echo request, id 921, seq 109, length 64
10:22:24.591778 IP 210.252.100.2 > 210.252.100.101: ICMP echo reply, id 921, seq 109, length 64
10:22:25.592018 IP 210.252.100.101 > 210.252.100.2: ICMP echo request, id 921, seq 110, length 64
10:22:25.592292 IP 210.252.100.2 > 210.252.100.101: ICMP echo reply, id 921, seq 110, length 64

先ほどと状況が変わり、SiteA-vpn-host(210.252.100.2)からパケットが戻ってくるようになりました。

SiteA-vpn-host上でのtcpdump

[root@sitea-vpn-host ccd]# tcpdump icmp -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:21:40.592578 IP 210.252.100.101 > 210.252.100.2: ICMP echo request, id 921, seq 65, length 64
10:21:40.592623 IP 210.252.100.2 > 210.252.100.101: ICMP echo reply, id 921, seq 65, length 64
10:21:41.592974 IP 210.252.100.101 > 210.252.100.2: ICMP echo request, id 921, seq 66, length 64
10:21:41.593021 IP 210.252.100.2 > 210.252.100.101: ICMP echo reply, id 921, seq 66, length 64

こちらも問題なくパケットが到達するようになりました。
ただやはり、FromIP 210.252.100.2 DestIp 172.16.0.8のパケットがSiteB-Intを通過できない問題が残るので、
何か設定がないかドキュメント読み込んでみます。

まとめ

OpenStackのNWはL3までパケットを見ているっぽくて、異なるNWセグメントのパケットを通すことが出来ないっぽい。