# How to create a VPN server with Hetzner

## Introduction <a href="#introduction" id="introduction"></a>

Having a personal VPN server can prove to be beneficial in many scenarios: having a [static IP address](https://nordvpn.com/blog/what-is-static-ip/), accessing geo-restricted information online, or simply learning the basics of networking. In addition, you can use a single VPN server between several individuals to have IP-restricted access to certain resources, for example, important documents.

[Hetzner](https://www.hetzner.com/) is a large data center operator that offers a wide range of reliable and affordable cloud services, such as cloud servers, dedicated servers, and cloud storage. When used in conjunction with Meshnet and its [traffic routing feature](https://meshnet.nordvpn.com/features/routing-traffic-in-meshnet), Hetzner’s servers can be turned into VPN servers in just a few minutes.

This article goes over the process of deploying a virtual machine (VM) in the cloud using Hetzner and configuring it as a VPN server with the use of [Meshnet](https://nordvpn.com/meshnet/).

{% hint style="info" %}
**Note**

While setting up your own VPN server enhances your online privacy, it may not provide the same level of protection as connecting to a standard VPN server offered by NordVPN. NordVPN follows a [strict no-logs policy](https://nordvpn.com/features/strict-no-logs-policy/), which is crucial for ensuring your online activities remain confidential.
{% endhint %}

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

Before you start, make sure that you have an active [Hetzner account](https://accounts.hetzner.com/signUp). During registration, you are required to provide your billing details.

### Generate an SSH key (optional) <a href="#generate-an-ssh-key-optional" id="generate-an-ssh-key-optional"></a>

When creating your VPN server, you will need to choose an [SSH authentication method](https://nordvpn.com/cybersecurity/glossary/secure-shell/). It is recommended to use SSH key authentication for a more secure connection between your devices. If you intend to use SSH keys, proceed with the instructions below to generate an SSH key pair on your device:

1. Open **PowerShell** (on Windows) or **Terminal** (on macOS and Linux).
2. Execute the following command, where `</path/key-name>` is the desired path and the filename for the SSH key pair:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">ssh-keygen -f &#x3C;/path/key-name>
   </code></pre>

   \
   **Example**

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">ssh-keygen -f C:\Users\secretmeerkat/.ssh/hetzner-vpn
   </code></pre>

   \
   This command generates private and public SSH keys at the specified directory.
3. Display the contents of the public SSH key file by entering the `cat` command followed by the path to the file, as shown:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">cat &#x3C;/path/key-name>
   </code></pre>

   \
   **Example**

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">cat C:\Users\secretmeerkat/.ssh/hetzner-vpn
   </code></pre>

   &#x20;
4. Select and copy the command line output to your clipboard. The copied content will be required when configuring SSH access to the VM.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FjVg0zu6NvaTvzFuncqnS%2Fhetzner_ssh_key_cat.png?alt=media&#x26;token=e92523f9-07c3-4a23-afe9-b5ddf268d271" alt="Content of the SSH public key visible in the terminal window."><figcaption></figcaption></figure></div>

Your SSH key pair is now created and ready for use.

## Create a VM instance on Hetzner <a href="#create-a-vm-instance-on-hetzner" id="create-a-vm-instance-on-hetzner"></a>

With the prerequisites taken care of, you can start working on creating your VPN server on Hetzner.

### Create a new project <a href="#create-a-new-project" id="create-a-new-project"></a>

Hetzner allows you to group servers and other related resources into [projects](https://docs.hetzner.com/cloud/general/faq/#what-are-projects-and-how-can-i-use-them). With projects, you can share the resources with your peers and assign different roles for all users involved. For convenient management, it is recommended to create a new project for your VPN server by taking these steps:

1. On your [Hetzner Cloud console](https://console.hetzner.cloud/projects), select **New project**.
2. Enter a custom name for your project.
3. Click **Add project**.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FFDyiHy2Z21VXPrSJgGE4%2Fhetzner_project_name.png?alt=media&#x26;token=6c1d2af6-9e46-4d41-b2fc-59673827c3e2" alt="Adding a new project called &#x27;VPN servers&#x27; in Hetzner." width="423"><figcaption></figcaption></figure></div>

A new panel for your project should appear on your Hetzner dashboard.

### Import your SSH key (optional) <a href="#import-your-ssh-key-optional" id="import-your-ssh-key-optional"></a>

If you want to use SSH key authentication to connect to your cloud VM, you can import the SSH key to the Hetzner project.

1. On your Hetzner Cloud console, click your newly created project.
2. From the menu on the left, select **Security**.
3. On the **SSH keys** page, click **Add SSH key**.
4. In the new dialog, in the **SSH key** field, paste the content of your public SSH key file.
5. In the **Name** field, enter a custom name for this specific SSH key or leave the automatically generated one.
6. Select **Add SSH key**.\
   \
   ![Adding the generated SSH key to the Hetzner project.](https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FvG6B1s53jYsFx9Wv2rqs%2Fhetzner_ssh_key_add.png?alt=media\&token=082eaef0-a3d0-44a7-99c0-8cd6ee36d865)

You should now see an entry for your key on the SSH keys page.

<div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FBnW5ghRMGNNDhu8Rao46%2Fhetzner_ssh_key_added.png?alt=media&#x26;token=a11d9525-fa9a-414e-b422-5d2e78e8e825" alt="New entry for the added SSH key."><figcaption></figcaption></figure></div>

### Configure the VM <a href="#configure-the-vm" id="configure-the-vm"></a>

With the project created, you can proceed to configure your cloud VPN server.

1. On your Hetzner Cloud console, under your new project, select **Create server**.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FOt9jLyCyyqnOgCJDQDtt%2Fhetnzer_vm_create_server.png?alt=media&#x26;token=f1e1b870-b271-4943-be03-ee68c3897f5c" alt="Clicking &#x27;Create server&#x27; on the Hetzner Cloud console."><figcaption></figcaption></figure></div>

2. On the **Create a server** page, select your preferred location, operating system (OS) image, such as Ubuntu 22.04, and server type for your VPN server.

3. In the **Networking** section, make sure that **Public IPv4** is selected. Optionally, you can choose to enable **Private networks** and configure the network to allow multiple cloud servers to interact with one another.

4. If you choose to use SSH key authentication, under **SSH keys**, select your imported SSH key.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2Frh5bFWuaU8imgQkRHg6G%2Fhetzner_vm_ssh.png?alt=media&#x26;token=a48d4259-5b57-4e03-8629-bd1c208a5a04" alt="Selecting the imported SSH key." width="375"><figcaption></figcaption></figure></div>

5. Under **Name**, enter a custom name for your VPN server.

6. Double-check all of your settings and click **Create & buy now**.

Within a few minutes, your cloud server should be deployed and active.

<div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2F0DR4qnfBONShzGLqkTFm%2Fhetzner_vm_deployed.png?alt=media&#x26;token=279dd15d-2979-4552-833d-4e453a871f97" alt="Entry for the created cloud VM."><figcaption></figcaption></figure></div>

## Access your VM instance <a href="#access-your-vm-instance" id="access-your-vm-instance"></a>

Once the cloud server is created, you can connect to it over SSH. Depending on the SSH authentication method you chose, the ways to connect to the VM are slightly different.

{% tabs %}
{% tab title="SSH key authentication" %}

1. Locate the public IP address of your VM. It can be found in the **Servers** section of your Hetzner Cloud project.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FIoVQ9tHk0L8vAwUKqqWR%2Fhetzner_vm_public_ip.png?alt=media&#x26;token=dec39a1a-d769-411d-8f8f-7878677e03d2" alt="Copying the public IP address of the cloud VM."><figcaption></figcaption></figure></div>

2. Open **PowerShell** (on Windows) or **Terminal** (on macOS and Linux).

3. Run the `ssh -i </path/to/private/key> root@<server>` command, where:
   * `</path/to/private/key>` is the location of your private SSH key file.
   * `<server>` is the external IP address of your cloud VM.\
     \
     **Example**

     <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">ssh -i C:\Users\secretmeerkat/.ssh/hetzner-vpn root@135.181.201.210
     </code></pre>

     &#x20;

4. When establishing a connection to the server for the first time, the SSH client asks you to review and confirm the host key's fingerprint. To proceed with the connection, type `yes` in response to the prompt.

You should now be successfully connected to your cloud VM instance.
{% endtab %}

{% tab title="SSH password authentication" %}

1. Locate the public IP address of your VM. It can be found in the **Servers** section of your Hetzner Cloud project.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FIoVQ9tHk0L8vAwUKqqWR%2Fhetzner_vm_public_ip.png?alt=media&#x26;token=dec39a1a-d769-411d-8f8f-7878677e03d2" alt="Copying the public IP address of the cloud VM."><figcaption></figcaption></figure></div>

2. Open **PowerShell** (on Windows) or **Terminal** (on macOS and Linux).

3. Run the `ssh root@<server>` command, replacing `<server>` with the VM’s public IP address.\
   \
   **Example**

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">ssh root@135.181.201.210
   </code></pre>

   &#x20;

4. When establishing a connection to the server for the first time, the SSH client asks you to review and confirm the host key's fingerprint. To proceed with the connection, type `yes` in response to the prompt.

5. Enter the password you received from Hetzner via email.\
   \
   ![SSH password received via email from Hetzner.](https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FBgDkRymwbKuSnQgJ0WuS%2Fhetzner_ssh_pass_email.png?alt=media\&token=2e57ff26-05b0-4126-bb7c-7966b57c23cd)

You should now be successfully connected to your cloud VM instance.
{% endtab %}
{% endtabs %}

## Install NordVPN on the VM <a href="#install-nordvpn-on-the-vm" id="install-nordvpn-on-the-vm"></a>

To set up NordVPN on your cloud VM, follow these steps:

1. Download and execute the NordVPN installation script by running this command:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">sh &#x3C;(wget -qO - https://downloads.nordcdn.com/apps/linux/install.sh)
   </code></pre>

   &#x20;
2. Log in to your NordVPN account.

### Log in to NordVPN <a href="#log-in-to-nordvpn" id="log-in-to-nordvpn"></a>

You can log in to your NordVPN account without the use of a graphical user interface (GUI) in two ways:

* By running the `nordvpn login` command with the `--token` flag
* By running the `nordvpn login` command with the `--callback` flag

Instructions for both methods are outlined below.

<details>

<summary>Log in using a token</summary>

1. On any device, log in to your [Nord Account](https://my.ndaccount.com/) dashboard and select the **Meshnet (by NordVPN)** card.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FxpqHfJyxPLb25uHSZ74I%2Fucp_meshnet_card.png?alt=media&#x26;token=c9bc9798-bc96-4dfc-8ac7-8a3cf1b4538a" alt="&#x22;Meshnet (by NordVPN)&#x22; card highlighted."><figcaption></figcaption></figure></div>

2. Under **Advanced settings**, select **Get access token**.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FJn3YfCSN2rokFjnMJAzS%2Fucp_get_token.png?alt=media&#x26;token=9f657403-0eff-47af-8da3-4a4837db5d4b" alt="Clicking the &#x27;Set up NordVPN manually&#x27; button."><figcaption></figcaption></figure></div>

3. Enter the verification code sent to your email address.

4. Under **Access token**, click **Generate new token**.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2F2rdjIz6B8KD69EpvERV2%2Fucp_generate_token.png?alt=media&#x26;token=ca21fa64-1669-4786-945f-d2af2fec5cdb" alt="Clicking &#x27;Generate new token&#x27;."><figcaption></figcaption></figure></div>

5. In the dialog that appears, choose either a token that expires in 30 days or one that never expires, and then select **Generate token**.<br>

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FM44Zi3LCVbbovfM5sCra%2Fucp_generate_new.png?alt=media&#x26;token=c06d9740-1a21-4acd-8246-fc81208576bb" alt="Selecting the token expiry option." width="563"><figcaption></figcaption></figure></div>

6. Select **Copy and close**.

7. On your VM, enter the `nordvpn login --token` command along with the copied token:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">nordvpn login --token &#x3C;your_token>
   </code></pre>

   \
   **Example**

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">nordvpn login --token 3fe460cefb8dcf1478c92e45908cec9f9bdbadf7a456a6dfb35dc2c58ee39d5b
   </code></pre>

You should now see a welcome message.

</details>

<details>

<summary>Log in using a URL</summary>

1. Run the following command:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">nordvpn login
   </code></pre>

2. Open the provided link on any device in your browser.

3. Complete the login procedure.

4. Right-click the **Continue** button and select **Copy link address**.

5. Run the following command, replacing `<URL>` with the previously copied link address:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">nordvpn login --callback "&#x3C;URL>"
   </code></pre>

   \
   **Example**

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">nordvpn login --callback "nordvpn://login?action=login&#x26;exchange_token=MGFlY2E1NmE4YjM2NDM4NjUzN2VjOWIzYWM3ZTU3ZDliNDdiNzRjZTMwMjE5YjkzZTNhNTI3ZWZlOTIwMGJlOQ%3D%3D&#x26;status=done"
   </code></pre>

You should now see a welcome message.

</details>

{% hint style="success" %}
**Tip**

To preserve your token when logging out of the NordVPN app, use the `nordvpn logout --persist-token` command. Otherwise, your token will be revoked.&#x20;
{% endhint %}

{% hint style="info" %}
**Note**

If you encounter the error message “Whoops! Permission denied accessing /run/nordvpn/nordvpnd.sock,” enter `sudo usermod -aG nordvpn $USER`. Then, reboot your instance and log back in.
{% endhint %}

## Enable Meshnet <a href="#enable-meshnet" id="enable-meshnet"></a>

On your instance, [enable Meshnet](https://meshnet.nordvpn.com/getting-started/how-to-start-using-meshnet/using-meshnet-on-linux) by typing this command:

{% code overflow="wrap" %}

```bash
nordvpn set meshnet on
```

{% endcode %}

To view the Nord name and Meshnet IP address of your instance, enter the following command.

{% code overflow="wrap" %}

```bash
nordvpn meshnet peer list
```

{% endcode %}

<figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FGGJl3lr8E4cvWp5XhUhW%2Fhetzner_route_peers.png?alt=media&#x26;token=9c1120d2-5ce5-43a6-8b32-69cded88907c" alt="Nord name and Meshnet IP address of the VM."><figcaption></figcaption></figure>

You will also see all of your Meshnet peer devices with their [corresponding permissions](https://meshnet.nordvpn.com/features/explaining-permissions).

### Grant the traffic routing permission

To begin using the VPN server, you need to grant the traffic routing permission for each peer device that you want to have access to the server. Enable this permission from the server machine using the following command:

{% code overflow="wrap" %}

```bash
nordvpn meshnet peer routing allow <device>
```

{% endcode %}

**Example**

{% code overflow="wrap" %}

```bash
nordvpn meshnet peer routing allow secret.meerkat-everest.nord
```

{% endcode %}

For more information, see the [Traffic routing permissions](https://meshnet.nordvpn.com/features/explaining-permissions/traffic-routing-permissions#changing-permissions) page.

## Start using your VPN server <a href="#start-using-your-vpn-server" id="start-using-your-vpn-server"></a>

To start using your new cloud VM as a VPN server, you need to start routing internet traffic from a client device through the VM.

1. On your client device, open NordVPN and log in to your account.
2. Start routing traffic through the linked host device.\
   \
   **Example**

   <div align="left"><figure><picture><source srcset="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FvmAmC9a83uH4uZuXDN8l%2Fwin_route_example_dark.png?alt=media&#x26;token=de1ac2af-b0a1-4209-8235-a342f6da08d1" media="(prefers-color-scheme: dark)"><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FiZP58xTDFMJXiqV11aNQ%2Fwin_route_example.png?alt=media&#x26;token=4b843885-6558-49f5-958e-698765a6250c" alt="Selecting a traffic routing host device under the &#x22;Devices&#x22; tab." width="348"></picture><figcaption></figcaption></figure></div>

For specific instructions, see the [Routing traffic in Meshnet](https://meshnet.nordvpn.com/features/routing-traffic-in-meshnet#see-also) article.

[Your IP address](https://nordvpn.com/what-is-my-ip/) should now be the same as the virtual machine’s. This way, your real public IP address is protected, and the websites you visit will see the location of your VPN server instead of your actual device.

<div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FN8cZdVyWnQJhmI8se3f1%2Fhetzner_route_connected.png?alt=media&#x26;token=fbca92c5-f861-4c91-856e-a5bfb8fd0a9f" alt="Checking the new IP address after connecting to the VPN server."><figcaption></figcaption></figure></div>
