KVM on Ubuntu: Port forwarding to a guest VM

Ben picture Ben · Dec 8, 2012 · Viewed 11.5k times · Source

I installed kvm and set several guests on a server using vmbuilder. Here is the following configuration :

server host1 (xxx.xxx.xxx.xxx) ->  guest vm1 (192.168.122.203)
                               ->  guest vm2 (192.168.122.204)

Where xxx.xxx.xxx.xxx is the fix IP address of host1.

I would like to connect to vm1 using the following command:

ssh username@host1 -p 2222

I tried to do it by adding the following rule in iptables:

sudo iptables --table nat --append PREROUTING --protocol tcp --destination xxx.xxx.xxx.xxx --destination-port 2222 --jump DNAT --to-destination 192.168.122.203:22

But I got a timeout when I'm running:

ssh username@host1 -p 2222

Here are my iptables rules:

sudo iptables -nL -v --line-numbers -t nat
Chain PREROUTING (policy ACCEPT 32446 packets, 3695K bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        7   420 DNAT       tcp  --  *      *       0.0.0.0/0            xxx.xxx.xxx.xxx        tcp dpt:2222 to:192.168.122.203:22

Chain INPUT (policy ACCEPT 8961 packets, 968K bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 350 packets, 23485 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 357 packets, 23905 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1      151  9060 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
2       99  7524 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
3        3   252 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24



sudo iptables -nL -v --line-numbers 
Chain INPUT (policy ACCEPT 14 packets, 1147 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1      454 30229 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
2        0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
3        0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:67
4        0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:67

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     589K 2304M ACCEPT     all  --  *      virbr0  0.0.0.0/0            192.168.122.0/24     state RELATED,ESTABLISHED
2     403K   24M ACCEPT     all  --  virbr0 *       192.168.122.0/24     0.0.0.0/0           
3        0     0 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0            0.0.0.0/0           
4        1    60 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
5        0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT 4 packets, 480 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Any advices will be appreciate.

Answer

Ben picture Ben · Dec 11, 2012

OK, I found the answer:

I added those 2 rules to the nat table:

$sudo iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.122.203:22
$sudo iptables -t nat -A POSTROUTING -p tcp --dport 22 -d 192.168.122.203 -j SNAT --to 192.168.122.1

Then I deleted the rule 4 et 5 of the chain FORWARD of the table filter

$sudo iptables -nL -v --line-numbers -t filter

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
(...)        
4        7   420 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
5        0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

$sudo iptables -D FORWARD 5 -t filter
$sudo iptables -D FORWARD 4 -t filter

And now I connect to vm1 by doing:

$ssh user1@host -p 2222
user1@vm1:~$