Skip to content

Instantly share code, notes, and snippets.

@bronson
Last active November 23, 2016 01:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bronson/8902bd9e5e85fbd286d3 to your computer and use it in GitHub Desktop.
Save bronson/8902bd9e5e85fbd286d3 to your computer and use it in GitHub Desktop.
Centos 7 default iptables config

So, why does libvirt set its rules up like this?

Since the default policy is ACCEPT, and all rules are ACCEPT, that means that all traffic coming into the host is accepted. So why bother allowing DNS and BOOTP (DHCP) traffic? Answer: because libvirt wants to ensure that, even if the INPUT chain has a different policy, all guests (traffic originating on the virbr0 interface) will receive DNS and DHCP service from the host.

Chain INPUT (policy ACCEPT 380 packets, 37990 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  virbr0 any     anywhere             anywhere             udp dpt:domain
    0     0 ACCEPT     tcp  --  virbr0 any     anywhere             anywhere             tcp dpt:domain
    0     0 ACCEPT     udp  --  virbr0 any     anywhere             anywhere             udp dpt:bootps
    0     0 ACCEPT     tcp  --  virbr0 any     anywhere             anywhere             tcp dpt:bootps

Rule 2 allows any outgoing guest traffic to be forwarded. Rule 1 then works with rule 2 so incoming packets that are a part of an established (outgoing) connection are passed as well.

Rule 3 ensures that all guests can talk to each other.

All other traffic to and from guests is dropped with an ICMP rejection so you find out immediately that something went wrong, you're not just blackholed.

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  any    virbr0  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  virbr0 any     192.168.122.0/24     anywhere            
    0     0 ACCEPT     all  --  virbr0 virbr0  anywhere             anywhere            
    0     0 REJECT     all  --  any    virbr0  anywhere             anywhere             reject-with icmp-port-unreachable
    0     0 REJECT     all  --  virbr0 any     anywhere             anywhere             reject-with icmp-port-unreachable

Finally, DHCP packets originating on the host are explicitly allowed to be sent to guests.

Why isn't DNS explicitly enabled? If input and output policies are DENY, DHCP will still work, and DNS requests will still arrive, but replies will be dropped. This seems asymmetric.

Chain OUTPUT (policy ACCEPT 333 packets, 38232 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  any    virbr0  anywhere             anywhere             udp dpt:bootpc

NATing

Prerouting is used to mangle the destination so that the packet can be routed to a different location.

Chain PREROUTING (policy ACCEPT 333 packets, 22179 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Definitely nothing in INPUT and OUTPUT, since they only affect packets originated or terminated by the host.

Chain INPUT (policy ACCEPT 333 packets, 22179 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 23 packets, 1708 bytes)
 pkts bytes target     prot opt in     out     source               destination         

But postrouting has some action.

Multicast packets originating on a guest get dumped out to the internet unmasqueraded.

Broadcasts from guests also get dumped onto the host's interface. That seems odd to me since there's no way for replies to reach the guest. What's the benefit to allowing this?

TCP and UDP packets originating on a guest and leaving the network will be masqueraded. (not if they're destined for the host of course because then they'll transit the non-nat INPUT chain). The source port will be replaced with a host-specified port between 1024 and 65535. Because the guest doesn't have a routable IP address, the host needs to mangle the source address. (why does it need to do this in POSTROUTING? theoretically, couldn't it be done in the FORWARD chain?)

I'm guessing they have separate tcp, udp, and all masq targets so they can have separate byte counters? Otherwise, I don't see any difference between these rules.

Chain POSTROUTING (policy ACCEPT 23 packets, 1708 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   261 RETURN     all  --  *      *       192.168.122.0/24     224.0.0.0/24        
    0     0 RETURN     all  --  *      *       192.168.122.0/24     255.255.255.255     
    4   240 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
  258 18901 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
    0     0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24    

Mangling

Chain POSTROUTING (policy ACCEPT 213 packets, 28840 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 CHECKSUM   udp  --  any    virbr0  anywhere             anywhere             udp dpt:bootpc CHECKSUM fill

Nothing interesting here. I'm guessing this rule just fixes some lazy DHCP software that doesn't bother checksumming?

Chain INPUT (policy ACCEPT 380 packets, 37990 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- virbr0 any anywhere anywhere udp dpt:domain
0 0 ACCEPT tcp -- virbr0 any anywhere anywhere tcp dpt:domain
0 0 ACCEPT udp -- virbr0 any anywhere anywhere udp dpt:bootps
0 0 ACCEPT tcp -- virbr0 any anywhere anywhere tcp dpt:bootps
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any virbr0 anywhere 192.168.122.0/24 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- virbr0 any 192.168.122.0/24 anywhere
0 0 ACCEPT all -- virbr0 virbr0 anywhere anywhere
0 0 REJECT all -- any virbr0 anywhere anywhere reject-with icmp-port-unreachable
0 0 REJECT all -- virbr0 any anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT 333 packets, 38232 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- any virbr0 anywhere anywhere udp dpt:bootpc
Chain PREROUTING (policy ACCEPT 333 packets, 22179 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 333 packets, 22179 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 23 packets, 1708 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 23 packets, 1708 bytes)
pkts bytes target prot opt in out source destination
2 261 RETURN all -- * * 192.168.122.0/24 224.0.0.0/24
0 0 RETURN all -- * * 192.168.122.0/24 255.255.255.255
4 240 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
258 18901 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
[root@ex ~]# iptables -L -v -t mangle
Chain PREROUTING (policy ACCEPT 245 packets, 29743 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 240 packets, 28835 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 195 packets, 24658 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 213 packets, 28840 bytes)
pkts bytes target prot opt in out source destination
0 0 CHECKSUM udp -- any virbr0 anywhere anywhere udp dpt:bootpc CHECKSUM fill
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment