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?
    – random
    Mar 30, 2015 at 13:23
  • It's a dedicated server with a hosting company. Mainly for personal usage. 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?
    – Proxy
    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. 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. 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
    – Frederik
    Mar 30, 2015 at 15:10
  • I've tried it, still getting timeouts. I've edited the current rules into the OP. Mar 30, 2015 at 15:34
  • @BenFortune - I updated my answer, try those lines.
    – Frederik
    Mar 30, 2015 at 15:43
  • Doesn't work with either MASQUERADE or SNAT. Mar 30, 2015 at 15:46

Not the answer you're looking for? Browse other questions tagged .