Connect Two Servers Through the WireGuard Tunnel, Step by Step

Two servers talking through the tunnel, step by step

Two servers talking through the tunnel, step by step

This tutorial connects two of your servers so one of them uses a service on the other (a database, a cache, an API) through the encrypted tunnel, by the same host name it uses today. Do the steps in order; each one ends with what you should see.

Where: Servers › My Servers › your server › System › Security › WireGuard Network and Firewall, plus a root shell on each server

The example used on this page

Server A

The application server, the one that connects. After step 01 its private address is, for example, 10.10.0.7.

Server B

The server with the service, here MySQL on port 3306, reached today as db.example.com. After step 01 its private address is, for example, 10.10.0.8.

Use your own addresses: each server shows its private Address on its WireGuard Network tab.

01 · Turn WireGuard on, on both servers

  1. Open server A › Security › WireGuard Network and click Setup WireGuard (Enable WireGuard when it was set up before).
  2. Open server B and do the same.
  3. Write down the Address each tab shows: A = 10.10.0.7, B = 10.10.0.8 in this example.

What you should see: Status running on both tabs, each with its own Address and Public key.

02 · Link the two servers

  1. On server A's WireGuard Network tab, under Set up WireGuard between this server and:, tick server B.
  2. Click Save Links. The link works both ways: B gets A as a peer too, you do not tick anything on B.

What you should see: on both tabs, the other server in the tunnels table, with a Last handshake of a few seconds. Then, in a root shell on A:

ping -c1 10.10.0.8

One reply from B's private address.

03 · Make the service on B listen on the tunnel

The service must accept connections on B's private address. MySQL listening on every address (bind-address = 0.0.0.0) already does. A service bound to 127.0.0.1 only does not: set it to B's private address and restart it. On B:

ss -Hltn | grep 3306

What you should see: 0.0.0.0:3306 or 10.10.0.8:3306. Only 127.0.0.1:3306 means the service is not listening on the tunnel yet.

04 · Open the port on B, only for A's private address

  1. Open server B › Security › Firewall and click + Add Rule.
  2. Action: Allow. Type: IP / range + port.
  3. IP Address or Range: A's private address, 10.10.0.7. Port: 3306. Protocol: TCP. Comment: mysql from A through the tunnel.
  4. Click Add Rule.

Allow only the private address. The service stays closed to the internet, and A reaches it through the tunnel.

What you should see: a new Allow row in the rule list, port 3306/tcp from 10.10.0.7, with your comment.

05 · Point the name into the tunnel on A (/etc/hosts)

Your application keeps connecting to db.example.com. One line in /etc/hosts on A makes that name resolve to B's private address, so every connection to it goes through the tunnel. Nothing changes in the application's settings, and a TLS certificate issued for the name still matches. In a root shell on A:

vi /etc/hosts

Add this line at the end and save:

10.10.0.8 db.example.com
10.10.0.8

B's private address, from its WireGuard Network tab.

db.example.com

The exact name your application uses for B. Several names of the same server go on the same line, separated by spaces.

Put the line only on the server that connects (A). B keeps resolving its own name as before.

getent hosts db.example.com

What you should see: 10.10.0.8 db.example.com.

06 · Check the whole connection

On A:

nc -zv -w3 db.example.com 3306

What you should see: Connection to db.example.com (10.10.0.8) 3306 port [tcp/mysql] succeeded!

On B, while the application is connected:

ss -Htn state established "( sport = :3306 )"

What you should see: connections from 10.10.0.7, A's private address, and none from A's public address.

More services, more servers

  • Another service on B: repeat steps 03 and 04 for its port. The /etc/hosts line from step 05 already covers every service of that name.
  • A third server: turn WireGuard on (step 01), tick it on the server that must reach it (step 02), then steps 03 to 06 for it.
  • Both directions: when B also connects to a service on A, do steps 03 to 06 the other way round: the port on A for B's private address, and A's name in B's /etc/hosts.

Your laptop or phone in the same network: Add a laptop or phone. How the network works: WireGuard network.

Security section