Iptables rule wrong if created a rule with protocol 4
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
neutron |
Fix Released
|
Medium
|
Brian Haley |
Bug Description
I followed this document to create security group rule for requirement "Allow ingress Protocol IPIP or 4" and I used "ipip" value
https:/
btw I expected my iptables rule on nova compute is "-A INPUT -s 172.16.2.0/24 -p 4 -j ACCEPT" but the runtime rule in kernel was "-A INPUT -s 172.16.2.0/24 -p ipip -j ACCEPT" and proto number was 94 not 4
// the rules output for one port
Chain neutron-
pkts bytes target prot opt in out source destination
115K 219M RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED /* Direct packets associated with a known session to the RETURN chain. */
0 0 RETURN udp -- * * 0.0.0.0/0 172.16.2.165 udp spt:67 dpt:68
0 0 RETURN udp -- * * 0.0.0.0/0 255.255.255.255 udp spt:67 dpt:68
0 0 RETURN 94 -- * * 172.16.2.0/24 0.0.0.0/0
0 0 RETURN udp -- * * 172.16.2.0/24 0.0.0.0/0 udp dpt:8472
0 0 RETURN tcp -- * * 172.16.2.0/24 0.0.0.0/0 tcp dpt:4240
0 0 RETURN udp -- * * 172.16.2.0/24 0.0.0.0/0 udp multiport dports 30000:32767
1 90 RETURN tcp -- * * 172.16.2.0/24 0.0.0.0/0 tcp dpt:10250
0 0 RETURN tcp -- * * 172.16.2.0/24 0.0.0.0/0 tcp dpt:4245
512 30720 RETURN tcp -- * * 172.16.2.0/24 0.0.0.0/0 tcp multiport dports 30000:32767
0 0 RETURN icmp -- * * 172.16.2.0/24 0.0.0.0/0
0 0 RETURN udp -- * * 172.16.2.0/24 0.0.0.0/0 udp dpt:4789
0 0 RETURN tcp -- * * 172.16.2.0/24 0.0.0.0/0 tcp dpt:4244
2 142 RETURN tcp -- * * 172.16.2.0/24 0.0.0.0/0 tcp dpt:179
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID /* Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack. */
14 2122 neutron-
description: | updated |
description: | updated |
So this is one of those confusing edge cases and I think Linux is conspiring against us. Let me explain.
1) neutron-lib does correctly define the protocol name 'ipip' as 4.
2) The linux kernel uses the same in in.h:
IPPROTO_IPIP = 4
IPPROTO_BEETPH = 94 (?)
3) iptables maps 'ipip' to 94 and 'ipencap' to 4.
# for num in {0..255}; do iptables -A INPUT -p $num; done
# iptables-save | grep -E 'ipip|ipencap'
-A INPUT -p ipencap
-A INPUT -p ipip
4) /etc/protocols does the same as iptables:
grep -E 'ipencap|ipip' /etc/protocols
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
ipip 94 IPIP # IP-within-IP Encapsulation Protocol
5) getprotoby{ name|number} does what /etc/protocols does:
$ getprotobyname ipip
struct protoent: (0x7fbbbcca9c60)
p_name ipip
p_aliases IPIP
p_proto 94
$ getprotobynumber 4
struct protoent: (0x7fc51ad86be0)
p_name ipencap
p_aliases IP-ENCAP
p_proto 4
Neutron actually builds a mapping based on the getprotoby* calls, so in the iptables case it winds-up doing the wrong thing (it's actually more complicated than that, but...)
I'm assuming the value in the DB is actually 4, correct? We just maybe need to do a little trickery when dealing with iptables-save based on #3 above.
As a workaround please use 4, I think that will do the correct thing, right?