I am trying to redirect a certain port range in a linux host to one of its guest VMs. I would like for this redirection to apply to all the host's interfaces, including localhost. I was able to do:

iptables -I FORWARD -m state -d --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport 8000:8500 -j DNAT --to

Where 8000:8500 is the range I am interested in forwarding and is the guest's IP. This works as long as I am trying to connect from another machine, i.e. not the VM host. But I would also like to be able to forward traffic that originates inside the VM host.

Hope that is clear, sorry if I mangled the terminology.


Apparently performing DNAT for loopback traffic is not possible — e.g., see this question, or this debian-user discussion. Using REDIRECT works because traffic stays on the loopback interface, but forwarding the traffic to another machine does not work.

You could use a userspace program to forward TCP connections — e.g., xinetd with the following configuration will forward port 8000 to your VM:

service forward_8000
        type                    = UNLISTED
        port                    = 8000
        socket_type             = stream
        wait                    = no
        user                    = root
        redirect                = 8000

However, it is not possible to redirect a range of ports this way — every port needs a separate service definition.

  • Thank you. I found rinetd which is slightly easier to setup than xinetd for this amount of ports. I am awarding you the bounty since you provided as close to an authoritative answer as I am likely to get. take care. – samwise May 15 '13 at 19:44

Local packets will not enter the PREROUTING chain. I believe you will need to use the OUTPUT chain in the NAT table to do that:

iptables -t nat -I OUTPUT -p tcp --dport 8000:8500 -j DNAT --to

You will possibly also need to add a rule to the filter chain that allows these outbound and their related packets:

iptables -I OUTPUT -m state -d --state NEW,RELATED,ESTABLISHED -j ACCEPT
  • That does not seem to work. I get the same result, i.e., telnet localhost 8000 is unable to connect (I have something running on VM on port 8000) – samwise May 10 '13 at 22:45
  • You may also need to add a rule to allow the packets out. (The counterpart of your FORWARD rule.) I recommend you check your packets with tcpdump so you see what's actually happening. – Janoszen May 10 '13 at 22:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.