2

I have a dedicated server running Proxmox and a VM inside Proxmox running Debian 7 (Wheezy).

As I only have one IP address, I'm using iptables to forward ports to the VM.

My /etc/network/interfaces:

# The loopback network interface auto lo iface lo inet loopback # For routing auto vmbr1 iface vmbr1 inet manual post-up /etc/pve/kvm-networking.sh bridge_ports dummy0 bridge_stp off bridge_fd 0 # vmbr0: Bridging. Make sure to use only MAC adresses that were assigned to you. auto vmbr0 iface vmbr0 inet static address 91.121.<redacted> netmask 255.255.255.0 network 91.121.<redacted>.0 broadcast 91.121.<redacted>.255 gateway 91.121.<redacted>.254 bridge_ports eth0 bridge_stp off bridge_fd 0 iface vmbr0 inet6 static address 2001:41D0:1:A790::1 netmask 64 post-up /sbin/ip -f inet6 route add 2001:41D0:1:A7ff:ff:ff:ff:ff dev vmbr0 post-up /sbin/ip -f inet6 route add default via 2001:41D0:1:A7ff:ff:ff:ff:ff pre-down /sbin/ip -f inet6 route del default via 2001:41D0:1:A7ff:ff:ff:ff:ff pre-down /sbin/ip -f inet6 route del 2001:41D0:1:A7ff:ff:ff:ff:ff dev vmbr0 auto vmbr2 iface vmbr2 inet static address 10.21.21.254 netmask 255.255.255.0 bridge_ports none bridge_stp off bridge_fd 0 pre-up echo 1 > /proc/sys/net/ipv4/ip_forward pre-up iptables-restore < /etc/iptables.rules 

The iptable rule looks like so (along with more ports, but they all look the same more or less):

-A PREROUTING -i vmbr0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.21.21.4:80 -A POSTROUTING -s 10.21.21.0/24 -o vmbr0 -j MASQUERADE 

There is a site running using Node.js, proxied by Nginx all running inside the VM.

My Nginx configuration is:

upstream node { server 127.0.0.1:4567; } server { listen 80; server_name myDomain.co.uk; location / { proxy_pass http://node; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_redirect off; proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } } 

When pinging my domain, it works fine:

PING myDomain.co.uk (my.ip.address) 56(84) bytes of data. 64 bytes from myHostName.eu (my.ip.address): icmp_req=1 ttl=64 time=0.282 ms 64 bytes from myHostName.eu (my.ip.address): icmp_req=2 ttl=64 time=0.275 ms 64 bytes from myHostName.eu (my.ip.address): icmp_req=3 ttl=64 time=0.284 ms 64 bytes from myHostName.eu (my.ip.address): icmp_req=4 ttl=64 time=0.339 ms 

However when trying cURL, it refuses to connect.

curl --verbose myDomain.co.uk * About to connect() to myDomain.co.uk port 80 (#0) * Trying my.ip.address... * Connection refused * couldn't connect to host * Closing connection #0 curl: (7) couldn't connect to host 

Edit:

I've changed the rules to (as per @FrederikNielsen's advice):

-A PREROUTING -d my.ip.address/32 -p tcp -m multiport --dports 80 -j DNAT --to-destination 10.21.21.4 -A POSTROUTING -s 10.21.21.0/24 -o vmbr0 -j MASQUERADE -A POSTROUTING -s 10.21.21.0/24 -d 10.21.21.4/32 -p tcp -m multiport --dports 80 -j SNAT --to-source my.ip.address 

But still no luck. The error has changed to:

* About to connect() to myDomain.co.uk port 80 (#0) * Trying my.ip.address... * Connection timed out * couldn't connect to host * Closing connection #0 curl: (7) couldn't connect to host 
4
  • Is this for a corporate setting, or home network? Commented Mar 30, 2015 at 13:23
  • It's a dedicated server with a hosting company. Mainly for personal usage. Commented Mar 30, 2015 at 13:24
  • Can you check that port 80 is open? Issue: netstat -anp | grep :80 & lsof -i4 | grep :80 I mean...It says connection refused which usually means either nginx has not started, thus not listening on port 80. Or you have something preventing you from opening port 80, like SELinux. Go and change your SELinux=disabled and restart nginx to see if it spawns port 80? Commented Mar 30, 2015 at 13:56
  • Port 80 is open, I'm able to access my site from a browser. tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2145/nginx I just can't access it internally via the public IP. Commented Mar 30, 2015 at 13:57

1 Answer 1

3

You are going to do some hairpin NAT'ing.

This question has a pretty good accepted answer that explains how to do it.

Another solution could be to use split-horizon DNS setup, but this involves a bit more setup than hairpin NAT'ing.

Update:

-A PREROUTING -d externalIP/32 -p tcp -m multiport --dports 80 -j DNAT --to-destination 10.21.21.4 -A POSTROUTING -s 10.21.21.0/24 -o vmbr0 -j MASQUERADE -A POSTROUTING -s 10.21.21.0/24 -d 10.21.21.4/32 -p tcp -m multiport --dports 80 -j MASQUERADE 

Update #2:

-A PREROUTING -d externalIP -p tcp --dport 80 -j DNAT --to-destination 10.21.21.4 -A POSTROUTING -s 10.21.21.0/24 -d 10.21.21.4 -p tcp --dport 80 -j SNAT --to-source routerInternalIP 
11
  • I've changed the rule to -A PREROUTING -d externalip -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.21.21.4 and added -A POSTROUTING -s 10.21.21.0/24 -d 10.21.21.4/32 -p tcp -m tcp --dport 80 -j SNAT --to-source externalip, however it's just timing out now. Commented Mar 30, 2015 at 15:05
  • Try setting it up exactly as in the linked question, just with changed IPs and ports and then see what happens. It should work Commented Mar 30, 2015 at 15:10
  • I've tried it, still getting timeouts. I've edited the current rules into the OP. Commented Mar 30, 2015 at 15:34
  • @BenFortune - I updated my answer, try those lines. Commented Mar 30, 2015 at 15:43
  • Doesn't work with either MASQUERADE or SNAT. Commented Mar 30, 2015 at 15:46

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.