Openvpn – Port Forwarding through OpenVPN to Client on OpenVZ

openvpnopenvzport-forwarding

Edit: Okay I will try to make this more clear. What I am trying to achieve is simply a port forward, through my OpenVZ hosted openvpn server, to a service running on a client. There are a few different services I'd like to forward, like a web server, or a bittorent client. For the sake of argument, let's say I just want to establish a functional netcat connection with this topology:

internet —>[–>server(1.2.3.4:15555)]-nat-/->openvpn-server(10.8.0.1)–\ -> client running a webserver (10.8.0.6:15555)

or ….

(inet) —>|(public ip)-nat-through-openvpn-server–|->to-client-\ 10.8.0.6(destination)

Where inet represents any host on the internet, 1.2.3.4 represents my server's public IP, and 10.8.0.6 represents the ovpn client that will be hosting the server, which I'd like reachable from behind the VPN, at the address/port 1.2.3.4:15555

Here is my ifconfig:

lo        Link encap:Local Loopback  
      inet addr:127.0.0.1  Mask:255.0.0.0
      UP LOOPBACK RUNNING  MTU:16436  Metric:1
      RX packets:1037374 errors:0 dropped:0 overruns:0 frame:0
      TX packets:1037374 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:141887598 (141.8 MB)  TX bytes:141887598 (141.8 MB)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
      UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
      RX packets:1746329 errors:0 dropped:0 overruns:0 frame:0
      TX packets:3193026 errors:0 dropped:117 overruns:0 carrier:0
      collisions:0 txqueuelen:100 
      RX bytes:104945794 (104.9 MB)  TX bytes:4356609743 (4.3 GB)

venet0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet addr:127.0.0.2  P-t-P:127.0.0.2  Bcast:0.0.0.0  Mask:255.255.255.255
      UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
      RX packets:43166195 errors:0 dropped:0 overruns:0 frame:0
      TX packets:44728488 errors:0 dropped:11647 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:34214141842 (34.2 GB)  TX bytes:43166888251 (43.1 GB)

venet0:0  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet addr:1.2.3.4  P-t-P:1.2.3.4  Bcast:1.2.3.4  Mask:255.255.255.255
      UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1

venet0:1  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet addr:1.2.3.5  P-t-P:1.2.3.5  Bcast:1.2.3.5  Mask:255.255.255.255
      UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1

So I'd like for hosts on the internet to be able to reach a netcat listener (or webserver) at the server's public IP address, NAT'd through the openvpn server, to an openvpn client.

I asked this question last night and deleted it because I thought I had figured out the answer, but it turns out I had not..
If this appears to be a duplicate question than I apologize. I have searched and have attempted to follow recommendations found in other threads on this topic.The situtation is that I have an Ubuntu Minimal vps. It is an OpenVZ container. It is primarily being used as a openvpn server. The network topology is p2p. I am trying to forward a port to a client (say 10.8.0.6, p2p 10.8.0.5) through the server's public IP (example 1.2.3.4) so that a certain service (let's say apache) is reachable from the VPN address 1.2.3.4.

I know that because the server is an OpenVZ container, certain iptables workarounds need to be used, like for openvpn:

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s $VPN_SN -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING  -s $VPN_SN -o venet0 -j SNAT --to-source $OUTIP

That works fine. I also can redirect traffic destined to the server from one port to another :

iptables -A INPUT -i venet0 -d $EXTIP -p tcp --dport 80 -m state --state NEW -j ACCEPT
$IPT -t nat -A PREROUTING -p tcp -d $EXTIP --dport 80 -j REDIRECT --to-port 9001
iptables -A INPUT -i venet0 -p tcp --dport 9001 -j ACCEPT

That also works, although I would prefer to not have the destination port (9001) open to the world, but I could not get it to work otherwise. What I cannot get to work at all is forwarding traffic destined to the server's public IP ($EXT_IP in the example above) on a certain port to one of the VPN clients. I have tried doing this a few different ways. (I am also wondering if the point-to-point topology is complicating this?) I tried using rules such as described in another thread:

$IPT -A INPUT -p tcp -d $OUTIP --dport 15555 -j ACCEPT
$IPT -A FORWARD -i venet0 -p tcp --dport 15555 -j ACCEPT
$IPT -t nat -A PREROUTING -i venet0 -p tcp -m tcp --dport 15555 -j DNAT --to-destination 10.8.0.6:15555

(OUTIP means outgoing IP address, or venet0:1's address. VPN traffic is routed through venet0:0 to venet0:1)

Next I set up a netcat listener: nc -l 0.0.0.0 -p 15555

And used this site to test the connection, which finally showed some progress:

invalid connection to [10.8.0.6] from (UNKNOWN) [66.240.174.69] 55814

Now at least I know that the traffic is being forwarded, which is a start. So I thought maybe I need to add a postrouting rule so that the traffic knows where to be sent back to

$IPT -A POSTROUTING -t nat -p tcp -d 10.8.0.6 --dport 15555 -j SNAT --to-source $OUT_IP:15555

I got the same result. I am so frusterated by how many hours I've spent trying to forward one dang port to a client. I would seriously appreciate some help!

Best Answer

I finally got this to work. Turns out the packets were not being forwarded past the server. I ended up needing these rules below. I wrote this little script to enable/disable the port forwarding rule.

## Port Forwarding to Client ##
fwd_EN="false" # Change to 'true' to enable
ext_if="venet0" # 
int_if="tun0" # 
int_ip="10.9.0.6" # client to forward to
int_PRT="15555"

if [[ $fwd_EN == "true" ]]; then

echo Warning: Port Forwarding enabled

$IPT -t nat -A PREROUTING -p tcp -i $ext_if --dport $int_PRT -j DNAT --to-dest $int_ip:$int_PRT
$IPT -A FORWARD -p tcp -i $ext_if -o $int_if -d $int_ip --dport $int_PRT -m state --state NEW -j ACCEPT
$IPT -A FORWARD -i $ext_if -o $int_if -d $int_ip -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $int_if -s $int_ip -o $ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT

else echo Info: Port Forwarding Disabled

fi

Now I can set up a nc listener on the client and from a remote host, run nc 1.2.3.4 15555 and the connection works!

anon@vpnclient:~$ nc -l -v -p 15555
Listening on [0.0.0.0] (family 0, port 15555)
Connection from [x.x.x.x] port 15555 [tcp/*] accepted (family 2, sport 58939)
Can you see me?
yes, I can!
Related Topic