1

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!

Chev_603
  • 133
  • 6
  • Okay, bunch of data we can work with, now try to explain what would you like to accomplish. – Michal Sokolowski Jun 11 '15 at 06:04
  • It's not completely clear from the question what you want to achieve. What exactly is the IP config of `venet0` and `venet1`? What is `$VPN_SN`? Are the forwarding prerequisites met - `/proc/sys/net/ipv4/ip_forward`? Did you run `tcpdump` or `tshark` on the machine to see what is happenning to the packets in flight? – Josip Rodin Jun 11 '15 at 10:01
  • Ok I edited the OP to try to better explain. $VPN_SN is the vpn subnet. $EXT_IP is the server's external (public and incoming) interface. – Chev_603 Jun 11 '15 at 15:27
  • @Chev_603 where did you start that netcat listener? – Josip Rodin Jun 11 '15 at 20:13
  • @Chev_603 when you start the client, `nc 1.2.3.4 15555`, from the Internet, run `tshark -n -i venet0` on the server and see what, if anything, is going through – Josip Rodin Jun 11 '15 at 20:17
  • @Chev_603 also, did you make sure that `iptables -A FORWARD -j REJECT` is the last rule in that chain, below the rule allowing 15555 to be forwarded? – Josip Rodin Jun 11 '15 at 20:18
  • note also that this sounds like a duplicate of http://superuser.com/questions/519268/allow-local-connection-to-client-running-openvpn – Josip Rodin Jun 11 '15 at 20:19
  • Thanks so much for the help guys. So I set the nc listener to the vpn client's ip, and also tried setting it to server public ip, and also on just any or '0.0.0.0'. And yes the FORWARD -j REJECT is the last in that chain. This is what tcpdump on the server showed: 06:42:34.759793 IP 2.3.4.5:38367 > 1.2.3.4:8080: Flags [S], seq 3010944766, win 14600, options [mss 1460,sackOK,TS val 827885552 ecr 0,nop,wscale 8], length 0 5 packets captured 6 packets received by filter 0 packets dropped by kernel And on the remote end I get a connection timeout error. – Chev_603 Jun 12 '15 at 10:46
  • Changing the forward/nat rules to port 8080 in the example above. Also, if I am forwarding packets on a specific port, do I also need an INPUT rules for that port on the router(server) end..? – Chev_603 Jun 12 '15 at 10:52
  • I confirmed using tshark that the packets are not making it to the client. On the server, I see this retransmission warning: 5 6 69.896185 2.3.4.5 -> 1.2.3.4 TCP 76 [TCP Retransmission] 40077 > 8080 [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=828280494 TSecr=0 WS=256 – Chev_603 Jun 12 '15 at 11:10
  • @Chev_603 OK, so you're only seeing the first, SYN packet. When you run `iptables -n -L FORWARD -v | egrep 'pkts|8080'` do you see an increasing number in the pkts/ column after you try connecting? Likewise, run `iptables -n -t nat -L PREROUTING | egrep 'pkts|8080'` and see if the numbers increase. When you find the one that sits idle at 0, you'll identify which part of the system is stopping the connection. – Josip Rodin Jun 12 '15 at 12:13
  • Also, you should not start a listener on the server itself, because the whole point of PREROUTING is to avoid packets coming into INPUT, and instead to redirect them through FORWARD. – Josip Rodin Jun 12 '15 at 12:14
  • Thanks, that is a really useful trick. I ended up figuring it out. The reason I placed the listener on the server at one point was to see if the packets were even making it that far. – Chev_603 Jun 21 '15 at 20:28

2 Answers2

2

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!
Chev_603
  • 133
  • 6
0

I'm using also OpenVPN on a OpenVZ server. I tried your script but I cant access my raspberry pi at home via the public server address :(.

I can connect to my raspi (connected via OpenVPN to my server) from my server trough the tun0 address 10.8.0.2:8080.

But when I want to connect to the raspi trough the server address its not possible

this is my iptables -L output:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere             udp dpt:openvpn
ACCEPT     all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             10.8.0.2             tcp dpt:http-alt state NEW
ACCEPT     all  --  anywhere             10.8.0.2             state RELATED,ESTABLISHED
ACCEPT     all  --  10.8.0.2             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             10.8.0.2             tcp dpt:http-alt state NEW
ACCEPT     all  --  anywhere             10.8.0.2             state RELATED,ESTABLISHED
ACCEPT     all  --  10.8.0.2             anywhere             state RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination