Background: I haven't done anything with iptables in a few years... I have Fedora 16 running in a VM on VMWare, with my firewall (TomatoUSB) port forwarding to the VM.

VM is at 192.168.1.155. I know that the packets are making it to the VM...

Based on this illustration to see how the packets are supposed to go, I would expect the packets to come out of nat-PREROUTING and either go to mangle-INPUT or mangle-FORWARD unless the kernel is dropping them for some other reason.

This question appears to be off-topic. The users who voted to close gave this specific reason:

"Questions describing a problem that can't be reproduced and seemingly went away on its own (or went away when a typo was fixed) are off-topic as they are unlikely to help future readers." – Braiam, jasonwryan, Ramesh, Anthon, garethTheRed

2 Answers
2

I had two interfaces, eth0 (192.168.99.x) and eth1 (192.168.1.x). They were there for legacy reasons, I was lazy when I wanted a new VM and copied my previous one. Anyway, I simply disabled eth0 and everything worked.

I checked some of the rp_filter settings in /etc/sysctl.conf but that didn't fix it (but made me think it was a weird IF issue). The settings are documented in /usr/share/doc/kernel-doc-x.x.x/Documentation/networking/ip-sysctl.txt in the kernel-doc package.

So it works now, and I will leave this here for the search engines to find and maybe this will help somebody else some day.

I know this is a bit late, however ... Does the host know it is responsible that IP? Here's a schema I put at the top of the rules files I create. You can find similar flow-charts elsewhere, but having it in ASCII (wouldn't want to call it art ;)) can be quite useful on the terminal.

For the most part I know this from heart, but hey, doesn't hurt to have a reference if forgetfulness strikes.

Routing can happen either using the routing table ("kernel routing" in the above flowchart) or using netfilter. Now if - and that's the most likely scenario in your case - you didn't set up the routing table accordingly, the kernel would not know where the packet has to go and eventually drop it. Btw: in such cases it's useful to create a custom chain that will LOG and then DROP or add the rules in that order. This way you'll see what rules were hit. Also useful is iptables-save -c which will prepend the packet and byte counters to each rule line similar to how it appends it for the chains (format [packets:bytes]).

For ports forwarded to a VM via DNAT I have the following recipe (will explain below):

Mind that you may want to alter the order to fit the rules with your own. Also, if the OUTPUT chain doesn't have ACCEPT as its default policy, make sure that you add an output rule, although for all practical purposes this should be catered by having an RELATED,ESTABLISHED state rule. You can also refine the interfaces to match or match by wildcard. For example I gave the bridges of my virtual guests all the prefix _ (an underscore) and can therefore match -i _+ and -o _+. Similarly for several network cards (eth0, eth1) you'd match with -i eth+.

So what happens here is that:

a DNAT rule is inserted which takes input on (host) port $INPORT for TCP and "routes" it to $CONTIP:$VMPORT, i.e. the IP of the container and the port in the container. Yep, they could differ. If they don't it's alright to leave out the destination part (i.e. just ``$CONTIP`).

three rules to mask traffic that's from the subnet of the virtual guests but not going to another virtual guest.

an INPUT rule to allow incoming packets on the public IP (no interface given, but could be!) to port $INPORT through. I think this rule isn't strictly needed, at least not if you tie it to the public interface.

a rule to forward traffic to $INPORT for the virtual guest subnet ($VMNET)

a rule to forward traffic to $INPORT on the public IP ($MAINIP)

Last but not least the value for sysctl (/proc/sys/net/ipv4/ip_forward) should be:

# cat /proc/sys/net/ipv4/ip_forward
1

to make your host a router.

If it's not use echo 1 to write to the above "file" in the procfs or better yet use sysctl -w net.ipv4.ip_forward=1 as root.