# DHCP with NAT on proxmox

In 
Published 2021-08-29

# proxmox on dedicated server

It happened so, that i wanted to experiment with virtualization using proxmox on rented dedicated server, with only one ipv4 address. I stumbled on a problem where i couldn't access the internet in virtual machines. Becaaauuuuse server doesn't have the DHCP. So as a proud self-respecting amateur, It took me days to sort it out how to fix it 🤡

In the end, It was solved by setting up Dnsmasq DHCP sever and using NAT config


# setting up server for NAT

Go to the left menu > server's hostname > system > network , you will be see that you have only one network device, which is eth0. of course won't be enough to make your internet work on virtual machines. That's what we need NAT for.

Let's see this eth0 device and the create the Linux Bridge to assign VM's private adresses

eth0 network device with CIDR and Default Gateway configured
eth0 network device with CIDR and Default Gateway configured

Creating Linux Bridge and assigning it private ipv4 with subnet

click okay and then apply your configuration
click okay and then apply your configuration

you need ifupdown2 to reload network configuration (500) error is fixed by running this command:

sudo apt install ifupdown2

Editing /etc/network/interfaces on hypervisor | You better be careful 🤠

you will see something like this, for vmbr0

nano /etc/network/interfaces
auto vmbr0
iface vmbr0 inet static
        address 10.10.10.1/24
        bridge-ports none
        bridge-stp off
        bridge-fd 0

replace it with this:

/etc/network/interfaces
auto vmbr0
iface vmbr0 inet static
        address 10.10.10.1/24
        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.10.10.1/24' -o eth0 -j MASQUERADE
        post-down iptables -t nat -D POSTROUTING -s '10.10.10.1/24' -o eth0 -j MASQUERADE
  1. vmbr0 - linux bridge with private ip;
  2. eth0 - default physical network device;
  3. address 10.10.10.1 - subnet for our vmbr0 linux bridge;
  4. post-up/post-down iptables - forwarding private ip's to public one on the eth0 network device

# installing and configuring dnsmasq

Right now we're finished with configuring the network files for our hypervisor. The next thing to do, will be installing lightweight and, to be honest, really easy dhcp server to configure, compated to isc-dhcp-server

Installing dnsmasq:

apt install dnsmasq

Editing dnsmasq config file:

nano /etc/dnsmasq.conf
interface=vmbr0
listen-address= 10.10.10.1
dhcp-range=interface:vmbr1,10.10.10.3,10.10.10.254,255.255.255.0,12h
dhcp-option=interface:vmbr1,3,10.10.10.1
dhcp-option=interface:vmbr1,6,10.10.10.1

and restarting the dhcp server service with:

service dnsmasq restart

You will have access to the internet in virtual machines now. But dnsmasq will assign only random private ip's to the vm's.

You can assign private ip to the vm, by adding following line to the dnsmasq config:

nano /etc/dnsmasq.conf
dhcp-host=macaddress,10.10.10.44
  1. dhcp-host - option in dnsmasq config to add static ip to vm
  2. macaddress - MAC address of our virtual machine
  3. 10.10.10.44 - private ip which i want to be assignet to vm

MAC address of vm is located in proxmox settings
MAC address of vm is located in proxmox settings

In my case right now, i want my vm with D2:BD:EB:29:C0:6E MAC address to be assigned 10.10.10.66 private ip

My config will look like following way:

/etc/dnsmasq.conf
interface=vmbr0
listen-address= 10.10.10.1
dhcp-range=interface:vmbr0,10.10.10.3,10.10.10.254,255.255.255.0,12h
dhcp-option=interface:vmbr0,3,10.10.10.1
dhcp-option=interface:vmbr0,6,10.10.10.1
dhcp-host=76:2A:15:A2:B0:6E,10.10.10.66

# Forwarding ports to public ip

You can either do it manually or using my simple .sh script

# Using script:

:::code source="../../static/files/iptables-pf.sh" :::

iptables-pf.sh
iptables-pf.sh

# Manually:

iptables -t nat -A PREROUTING --dst 94.26.248.124 -p tcp --dport 80 -j DNAT --to-destination 10.10.10.66
iptables -I FORWARD 1 -i eth0 -o vmbr0 -d 10.10.10.66 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -t nat -A POSTROUTING --dst 10.10.10.66 -p tcp --dport 80 -j SNAT --to-source 94.26.248.124
  1. 94.26.248.124 - my public ip (no worries, it's was a test server anyway!)
  2. 80 - port you want to open. https port in my case
  3. 10.10.10.66 - private ip i want to forward from
  4. vmbr0 - name our linux bridge device

# Troubleshoot

Problem:

I was setting up Mail Server on the "Instance 100" with 10.10.10.22 private ip. After I deleted it, I couldn't create another VM with the same static ip, and i also couldn't forward any port that was used on previous VM

Solution:

Problem is that our DHCP Server thinks that VM with 10.10.10.22 IP address is still running and up. So it doesn't let you use it on another machine and forward same ports that were on machine before deleting it.

This could be solved by going to /var/lib/misc/ directory and cleaning dnsmasq.leases file

How dnsmasq.leases looks in my case
How dnsmasq.leases looks in my case


It's Done! you can create your VM's now, and they will have access to the internet without or with static private ip to route ports