How to setup port forwarding after enabling openvpn droplet

Posted November 13, 2020 1.5k views

I set up an OpenVPN droplet using this one-click droplet:

Is it possible to port forward my devices that are connected? If so, how would I go about doing it?

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

1 answer

The openvpn server configuration will depends on the configuration of your prospective vpn client and its service/program which you would like to have an access to (through forwarded port).

Let’s go through an example which may give you some tips on how to configure port forwarding. Let’s assume that our vpn client is a linux machine, and we would like to ssh it from the internet, addressing your openvpn/pihole droplet.

1. The things to do on prospective vpn client.

We need to find out what IP address and port sshd (ssh daemon) listens on.

sudo netstat -tulpn | grep -i -e sshd -e address
Proto Local Address Foreign Address State PID/Program name tcp 0* LISTEN 1548/sshd

Local Address indicates that sshd listens on port 22 on each network interface with IP address assigned to it. So, we are lucky because sshd service will be immediately available on virtual vpn interface when it is up. It would be a bit more complicated if sshd listened on particular network interface only. It would demand changing sshd configuration or changing our approach to openvpn configuration.

The port that sshd listens on has to be open in firewall’s settings on vpn client. Let’s assume we use iptables to configure firewall on our vpn client. So, we are adding an appropriate rule:

sudo iptables --table filter --insert INPUT 1 --protocol tcp --dport 22 --jump ACCEPT

We need to save iptables ruleset to a file, to recreate firewall settings after rebooting. For example:

sudo sh -c "iptables-save > /etc/iptables.rules"

2. Things to do on openvpn/pihole droplet.
We have to provide a static IP address to our vpn client to configure port forwarding efficiently. We will do that with config file put in openvpn client configuration directory (ccd) on droplet. First, we need to enable ccd configuration in openvpn server settings. Open configuration file /etc/openvpn/server/server.conf in your favourite editor, and add a directive that specify a location of openvpn client config directory:

client-config-dir /etc/openvpn/ccd

Then, create this directory:

mkdir /etc/openvpn/ccd

We are going to assign particular IP address to a vpn client due to its certificate common name (CN). So, we need to find out what is CN of a certificate of our prospective vpn client. A certificate is placed in VPN Client configuration file that has been created during deploying openvpn/pihole droplet. It is located in root’s home directory /root/client.ovpn on the droplet. You will copy it to your vpn client device, and use it to establish vpn connection to your droplet. But now, open this file in your fovourite editor and copy certificate content from it (it is a section between the lines BEGIN CERTIFICATE and END CERTIFICATE):


Paste copied content into online decoder, e.g. you can try here. It will reveal certificate’s CN (common name). In our case, CN will be client.
To configure static IP address for our vpn client, open a new file /etc/openvpn/ccd/client in your text editor, add below content to it, and then save the file. Note that a filename is CN from the certificate.


Thanks to that, openvpn server will assign IP to a client that uses certificate with CN=client. The IP address and mask (subnet) correspond to the settings in /etc/openvpn/server/server.conf. There are some directives in config file, defining network topology (subnet) and particular subnet:

... topology subnet server ...

Finally, we have a static IP configured for our vpn client. Now, we can redirect a traffic to its particular port (port forwarding). We cannot forward port TCP 22 because we ssh openvpn/pihole droplet through this port. So, let’s forward any other one, e.g. TCP 1818. First, we have to open it in droplet’s firewall settings. There are some iptables rules predefined on openvpn/pihole droplet. To list ruleset of INPUT chain, run below command.

iptables --table filter --list INPUT --line-numbers
Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED 2 ACCEPT udp -- anywhere anywhere udp dpt:openvpn 3 DROP udp -- anywhere anywhere 4 DROP tcp -- anywhere anywhere tcp dpt:ssh recent: UPDATE seconds: 60 hit_count: 6 name: SSH side: source mask: 5 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh recent: SET name: SSH side: source mask: 6 DROP tcp -- anywhere anywhere

The last rule in this chain DROPs all TCP packets that do not match previous rules. So, we need to insert our rule before that one:

iptables --table filter --insert INPUT 6 --protocol tcp --dport 1818 --jump ACCEPT

The traffic to our client has to be forwarded, so let’s check how FORWARD chain looks like:

iptables --table filter --list FORWARD --line-numbers
Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED 2 ACCEPT all -- anywhere 3 DROP all -- anywhere anywhere

We need to allow forwarding to our vpn client but again, we need to insert our rule before the rule dropping all packets (no. 3).

iptables --table filter --insert FORWARD 3 --protocol tcp --destination --jump ACCEPT

Now, we are going to add a rule to redirect input traffic from port 1818 to our client’s IP (, to port 22 (ssh).

iptables --table nat --append PREROUTING --protocol tcp --dport 1818  --jump DNAT --to-destination

The ssh traffic to our vpn client is redirected now, thanks to DNAT rule (Destination Network Address Translation) added to PREROUTING chain in nat table. But we need to configure traffic from our vpn client as well. To ensure that the remote station, sshing our vpn client, gets correct response, we need to modify the packets outgoing from our vpn client. The source address of our vpn client has to be replaced with public IP address of openvpn/pihole droplet, as it is the gateway/server that remote workstation actually communicate with. Such kind of address manipulation is called SNAT (Source Network Address Translation or masquerade), and it is done in POSTROUTING chain of nat table. Let’s take a look at that chain:

iptables --table nat --list POSTROUTING --line-numbers
Chain POSTROUTING (policy ACCEPT) num target prot opt source destination 1 SNAT all -- ! to:

There is an appropriate rule already preconfigured. It has been created during openvpn/pihole droplet deployment. This rule replaces source address in packets outdoing from the subnet to destinations not belonging to this subnet. A new source address, that is put into packets, is our openvpn/pihole droplet’s public IP (in this example:

It seems that iptables configuration is done. To preserve iptables settings, and load them automatically during system booting we need to save them. There is an iptables ruleset file on the droplet that we can use for that purpose. To save iptables ruleset, run below command.

sh -c "iptables-save > /etc/iptables/rules.v4"

Now, you can restart droplet and test if iptables settings are automatically applied.

shutdown -r now
iptables --table filter --list --line-numbers
iptables --table nat --list --line-numbers

If everythig is OK, you can try to connect your vpn client to openvpn/pihole droplet, using configuration file copied to vpn client from droplet root’s home directory (/root/client.ovpn). Then, test if port forwarding works.

Let me know how if it helps, pls.

Submit an Answer