Ubuntu remote desktop without public IP with ZeroTier & TigerVNC
Tags: linux, vpn, vnc, networking
Published: 2020-07-09 14:38:45

**Aim**: Connect machines in virtual network and be able to use remote desktop without public IP.

## 1. ZeroTier VPN ##

* **Create [ZeroTier](https://my.zerotier.com) account**, go to *Networks*, then hit **Create a Network** button.

* Set your network as private and __select *destination* subnet__ you want to use for it, for example: `192.168.0.0/24`.

* **Install ZeroTier on all machines** that you want to use as described on their [website](https://www.zerotier.com/download/):

```bash
$ curl -s 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/doc/contact%40zerotier.com.gpg' | gpg --import && \
if z=$(curl -s 'https://install.zerotier.com/' | gpg); then echo "$z" | sudo bash; fi
```

* At the end of install **you will see your member ID**. Edit your network on ZeroTier website, go to *Members* section and **Manually Add Member** by entering ID and hitting *+ Add New Member*.

* **Set auth** field to newly added machine, and manually **enter IP number** in your network subnet, for example: `192.168.0.1`. You can also add name and description that will help you to organize your machines.

* Next, **join the network** on the machine where you have installed ZeroTier. It's enough to do it once – **ZeroTier will start it on every system boot**:

```bash
$ sudo zerotier-cli join <network_id>
```

* **Check if machine is online** in ZeroTier panel and if you can ping other computers after adding them.

## 2. VPN local domains (optional) ##

* **If you want to use subdomains** for managing different services on your VPN machines (like Apache virtual hosts etc.) you can **add DNS «A» records** for VPN machines. This way you will be able to reach computers not only by IP numer but also by subdomain name like `vpn1.mydomain.com`. Here is an example: 

```
vpn1 A 192.168.0.1
vpn2 A 192.168.0.2
vpn3 A 192.168.0.3
```

* Remeber that **this subdomains will be available only from within your VPN subnet**.

## 3. TigerVNC server ##

* **Install TigerVNC server** from the repository and **set your VNC password**:
```bash
$ sudo apt install tigervnc-standalone-server tigervnc-xorg-extension tigervnc-viewer
$ vncpassword
```

* **Edit X startup scripts** in `~/.vnc/xstartup`. Here's a working example for Ubuntu Mate:
```bash
#!/bin/sh
unset DBUS_SESSION_BUS_ADDRESS
export XKL_XMODMAP_DISABLE=1
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
vncconfig -iconic &
mate-session &
```

* To **create a service** that can be easily managed, create a new file `vnc.service` in `/etc/systemd/system` dir with following contents:

```
[Unit]
Description=TigerVNC
After=network.target
StartLimitIntervalSec=0

[Service]
Type=forking
Restart=always
RestartSec=3
User=your-user-name
WorkingDirectory=/home/your-user-name
ExecStartPre=/usr/bin/tigervncserver -kill :1
ExecStart=/usr/bin/tigervncserver :1 -name your-session-name -localhost no -geometry 1366x768 -depth 16
ExecStop=/usr/bin/tigervncserver -kill :1

[Install]
WantedBy=multi-user.target
```

* Replace all occurrences of `your-user-name` with your user name and `your-session-name` with the name you like. Change screen geometry to which will be best for you on the client machine.

* **Enable new service** and **start the server**:

```bash
$ sudo systemctl daemon-reload
$ sudo systemctl enable vnc
$ sudo systemctl start vnc
```

* **If there are problems** you can debug by disabling service and **manually start the server** by direct ExecStart command to see what happens:

```bash
$ tigervncserver -kill :1
$ tigervncserver :1 -name your-session-name -localhost no -geometry 1366x768 -depth 16
```

* To connect to the server you can install `tigervnc-viewer` or `remmina` with VNC plugin on client machine:

```bash
$ sudo apt install tigervnc-viewer
$ vncviewer
```

* After connecting to the server you can hit F8 key to see available options.

## 4. SSH Tunnel

* To make VNC connection secure you can **create SSH tunnel**:

```bash
$ ssh -L 5901:localhost:5901 192.168.0.1 -p 22
```

* Now you can connect to VNC server by typing `localhost:1` in TigerVNC.