Proxmox and using NAT with a Virtual Machine

    So I finally decided to make the jump to virtualization. Sure the performance is 1-3% slower then running on raw hardware, but the features gained from this way outweigh the cons. Now I can do backups on the fly, snapshots, quickly move resources around machines, and its all free thanks to Proxmox! Proxmox is a Linux Debian based distro that utilizes a custom kernel with support for OpenVZ and KVM. I’l go more into depth on Proxmox later, but for now here is my situation.

I have a friend who needed a KVM VPS Unit with a Install of Debian linux, but the thing is they only wanted it for SSH. Now, due to the fact I only have 13 WAN IP’s for my entire network, I was not about to give away one just for a SSH unit. So this is where using NAT with my Proxmox Server’s WAN IP comes in handy.

Now there are probably better ways of doing this, but here is how I do it. I create a new network bridge (I will use vmbr2 in my example) that is not linked to any interfaces, so its for the host and between VM’s only. I also don’t care to set up DHCP for it because I am only using this for NAT, and its best to keep everything static so its easier to create the NAT rules. So, start up a root console. You will need it.

So here is a visual guide of what I am doing. For this example 55.44.33.22 is my WAN IP.

VM Machine ———————– Proxmox Host Server ——————— World Wide Web
10.99.0.1:22          10.99.0.1:22 NAT to 55.44.33.22:1022              55.44.33.22:1022

So what this does is it makes it so if you ssh to 55.44.33.22 on port 1022, it will NAT through the Proxmox host, and then connect to 10.99.0.1, the static IP you set on the VM.

So to do this open up /etc/network/interfaces on the proxmox server and add the following code to create a new interface:

[code]auto vmbr2
iface vmbr2 inet static
    address 10.99.0.254
    netmask 255.255.255.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
[/code]

Don’t close out of editing yet!!! What this does is creates the virtual interface that we will put on VM’s that need to NAT out. For my example I will use 10.99.0.0/24 as my network range, but you can use whatever you want. OK, now add this after the code you just entered:

[code]
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s ‘10.99.0.0/24’ -o vmbr0 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s ‘10.99.0.0/24’ -o vmbr0 -j MASQUERADE
    post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp –dport 1022 -j DNAT –to 10.99.0.1:22
    post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp –dport 1022 -j DNAT –to 10.99.0.1:22
[/code]

what this code does is it enables IP_forwarding for NAT to work, allows your network range to be used in NAT, then it defines what ports forward to where, and on what interface. Wel also have all of the post-downs so the rules are removed if you take the interface offline.

So lets break down the post-up code so you can see how to add your own ports

[code]post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp –dport 1022 -j DNAT –to 10.99.0.1:22[/code]

In this line there are 3 main things to keep a eye on. vmbr0, 1022, and 10.99.0.1:22. The vmbr0 part defines your WAN Interface. Whatever is defined here is what interface it will NAT to, so make sure this is set to the interface that is facing the web. Next is the 1022. This is the port that you want to use to connect to the inside port. And last is 10.99.0.1:22. This is the static IP of the VM machine, and the port that you want forwarded.

So in the end, you should have the following code in /etc/network/interfaces

[code]auto vmbr2
iface vmbr2 inet static
    address 10.99.0.254
    netmask 255.255.255.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s ‘10.99.0.0/24’ -o vmbr0 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s ‘10.99.0.0/24’ -o vmbr0 -j MASQUERADE
    post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp –dport 1022 -j DNAT –to 10.99.0.1:22
    post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp –dport 1022 -j DNAT –to 10.99.0.1:22
[/code]

and you should have a VM with a static IP of 10.99.0.1, on the interface vmbr2. If you do all of this, then SSH from that VM should be accessible from your WAN IP on port 1022.

If you need help with this, or have ideas for other posts please feel free to share with me.

Citation:
http://help.ovh.co.uk/Proxmox

24 thoughts on “Proxmox and using NAT with a Virtual Machine

  1. Tadas

    Hello,
    I am doing something wrong, because i can’t access. maybe you could help me ? send me and email if you can. thanks.

    Reply
  2. Norman

    Very useful tutorial. How would you port forward requests to a web server (80) and mysql server (3306) on a VM that contains multiple websites?

    Reply
  3. amilkar

    Hi, nice tutorial. I have a long time googling becasuse I have a problem to reach a port on VM behind a firewall and I don’o found nothing.

    I really appreciate if you can help me. I have 2 NIC, eth1 external ip=172.19.2.1 gw 172.19.1.1 and eth0 internal ip=192.168.10.1/24. I made nat to reach outside from proxmox base, but I cant reach from internet (behind 172.19.0.0) to any port in VM.

    I build a ws 2008 with smtp server on prt 25. I can sent email, but I cant receive, because the VM is not reachable.

    I give my email if you want contact me.

    Thanks

    Reply
  4. Attila

    Hi there. I have heard about proxmox not long ago and I am planning to switch to their system however I have hard finding guide about setting up my network with one interface but with two different network. One for public ip vms and one for nat ip…How would you accomplish this. I can either make bridge or nat work but not both the same time. I have two public ip-s that I can use and plus one for the public vm.

    I hope u can help.

    Reply
  5. Ralf

    Hello,

    you write ” you should have a VM with a static IP of 10.99.0.1, on the interface vmbr2.” Could you please show the /etc/network/interfaces for the VM to obtain these settings. Thank you very much!

    Ralf

    Reply
    1. Chris B - Admin Post author

      Hello,

      For this, you would just set a static IP in the VM, and have its network interface set to vmbr2.

      So in the VM, /etc/network/interfaces would look like.
      auto eth0
      iface eth0 inet static
      address 10.99.0.1
      netmask 255.255.255.0
      gateway 10.99.0.254

      Reply
      1. Taras Kozlov

        Thank you for the great manual. It was really very helpful! However, I would like to add two notes here that might be helpful for someone new to Proxmox (and server administration in general) as myself.

        First one, I was only able to provide VM with internet access by adding dns-nameservers to eth0 config. So, the final content of /etc/network/interfaces in guest machine looks like:

        auto eth0
        iface eth0 inet static
        address 10.99.0.1
        netmask 255.255.255.0
        gateway 10.99.0.254
        dns-nameservers 8.8.8.8 8.8.4.4

        And the second one is the problem that I can’t find the solution yet: ping from guest to host works perfectly, but ping from host to VM doesn’t, i.e. I can’t reach 10.99.0.1 from the PVE machine.

        Reply
        1. Chris B - Admin Post author

          You will need to define a static route on the proxmox box so it knows where to route the traffic. For example if the VM is on vmbr1, you would run
          ip route add *IP-of-VM* dev vmbr1
          on the proxmox host.

          Reply
  6. Chris

    Would this work in a cluster? Lets say I have a vm on cluster 1 then another vm on cluster 2. Could behind the nat they be linked together?

    The clusters currently have 2 nics, one for wan and one for lan on separate switches.

    Reply
    1. Chris B - Admin Post author

      What do you mean by linked together? If you wanted them to communicate with each other over a specified port, then it is possible to use this method. If you want to forward all ports, like they are on the same network, it would be better to throw both VMs on a VLAN together that is tagged on your LAN link.

      Reply
  7. Ivan

    Where did you get your understanding of proxmox vm networking from? Something is not right in my case but I’m not sure how to troubleshoot

    Reply
  8. Adolfo

    Thank you for the tutorial, It really helped me!

    But I have a question. If I want to have 2 VMs with ssh, should I add to the same port or in different port?

    Thank you for your answer!

    Reply
  9. ANNE

    How do you create a virtual machine with NAT mode? I choose the network mode for NAT ,but there is not a virtual network interface card in server. Then I change the /etc/network/interfaces like you told us, but it does not work either. So can you help me with my problem?

    Reply
  10. Chet

    What’s up, the whole thing is going nicely here and ofcourse every one is sharing information, that’s really fine, keep up writing.

    Reply
  11. Martin

    It’s a shame you have to use the console to add NAT rules manually. In these days when every cheap router includes NAT configuration page, why Proxmox does not offer anything like that?

    I wanted to use Proxmox to allow my colleagues to quickly bring up some small LXC virtual machines for experiments and development environments, and usually they want to have their site with public access. For example, setting up a web server on a VM port 80 and then allowing to access it on any free port available on the public IP, as long as the developer knows which port was dedicated to his VM.

    But I don’t want to give all developers access to the Proxmox node console because it is too easy to mess up things there. Just a simple “Add NAT to my VM” web form and accompanying script to modify the NAT rules and refresh iptable configuration should do the job. Maybe we could develop it ourselves as a custom Proxmox extension? Or maybe somebody has already done that?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *