The Parsec Relay Server - An On-Prem High Performance Relay Server

The Parsec Relay Server as part of the Parsec for Teams Enterprise license. It's a solution when you need more control over you network infrastructure and want to ensure connections will always be successful. It can be used as a way to route all Parsec traffic through one public IP address and as a solution for managing strict firewall/NAT settings. If you'd prefer to avoid the Parsec Relay Server, this provides all Parsec networking requirements. 

The Parsec Relay Server is an on-prem high performance relay (HPR) server. It is a lightweight server program that allows efficient relaying of many simultaneous Parsec connections through a single IP address / port configuration. It can be used to assist with NAT traversal as either an on-premises relay for large LAN deployments of Parsec, or as a general purpose WAN relay server.

Pre-Requisites
1) Provision a virtual or physical server with the following minimum specs in your DMZ (or VLAN of choice):
Relay Server machine specs:
2 cores
4GB RAM
1gbps+ NIC
Supported Operating Systems:
Ubuntu 18.04
Ubuntu 20.04
RHEL 7
RHEL 8
CentOS 7
CentOS 8
Note:
Ubuntu needs no firewall configuration by default, as it's default configuration blocks no traffic.
RHEL and CentOS will need the relay's public and private ports opened in their firewalls (or their firewalls disabled).
 
2) In your enterprise (hardware) firewall:
Configure the server with a public IP and port (static NAT).
Example: [public-ip]:[UDP port] <-> [relay-LAN-IP]:[UDP port]
Architecture Diagram

gateway_connection_flows.png

Installation

1) Copy the download URL for the relay server from the Teams Global App Settings page. The .tar.gz contains the Relay Server files and the Readme.

2) SSH into the Linux machine that you'll use for the relay server and download and extract the tar ball, then copy the `parsechpr` and `parsechpr.service` files to the relevant directories:

ssh <user>@<LAN-IP>
wget <relay download URL>
tar -xf <relay.tar.gz>
cd parsechpr1.0
sudo cp parsechpr /bin sudo cp parsechpr.service /etc/systemd/system

3) Use your text editor of choice to modify `ExecStart` under [Service] in parsechpr.service to point to the Public IP address, public (WAN interface) port and internal (LAN interface) port. 

sudo nano /etc/systemd/system/parsechpr.service

Example: `ExecStart=/bin/parsechpr 1.2.3.4 5000 4900`

Syntax: ExecStart=/bin/parsechpr [Public IP Address] [WAN/public interface port] [LAN/Internal interface port]

Save: CTRL + X to close, CTRL + Y to confirm modify, Enter to overwrite

4) Run the service:

sudo systemctl start parsechpr
sudo systemctl enable parsechpr
5) Enter the relay's private (LAN) IP and private port in the "Relay Host IP Addresses" field of the Teams Global App Settings page: gateway_IP.PNG
Usage

Confirm that the relay service is running:

service parsechpr status

The Relay Server will bind to all interfaces with both [public_port] and [private_port]. The [public_address]:[public_port] will be communicated to peers that need to route through the Relay Server and must be accessible from the WAN. Use UDP ports for the private and public port. [private_port] may be configured for additional security. Using a [private_port] ensures that relay requests can only be originated on the [private_port] specified, and any relay requests attempting to be originated on [public_port] will be dropped. If [public_port] is the same as [private_port], only a single port will be used.

As an alternative to configuring the relay for all hosts globally via the Teams Global App Settings page, the relay server address may be manually specified in the configuration file via app_stun_address:

app_stun_address = 10.1.2.20@4900 # Use a local address if possible

An '@' character must be used to delimit the IP address and port. Up to 10 address@port
pairs may be configured, separated by commas:

app_stun_address = 10.1.2.20@23050,10.1.2.21@23051,.... NOTE: this is a different format than in the Application Configuration page on the admin panel. Please read this article to know the format to use on the config page.

If more than one relay server is available, Parsec will choose a relay server at random on each connection attempt. If an attempt fails because the relay address could not be reached, Parsec will blacklist that address for 10 minutes and only consider the remaining addresses.

The Relay Server acts as a phony STUN server that exposes itself as the peer's address rather than the true public IP. This will cause Parsec to route all WAN traffic through the Relay Server instead of using its normal NAT traversal routines.

Details

The Relay Server lightly inspects packets sent to both its [public_port] and [private_port]. It maintains a ~128MB static lookup table used to pair two Parsec peers at connection time.

For the purpose of this document, the Parsec peer using the Relay Server will be labeled "P1" and the peer attempting to connect to P1 will be labeled "P2".

  1. P1 configures itself to use the Relay Server by setting "app_stun_address" in the configuration file.
  2. P2 initiates a connection to P1, then the two peers exchange an unguessable 8 byte pairing key via Parsec's secure websocket.
  3. P1 makes a STUN Binding Request to the Relay Server via the secure [private_port]: a. The Relay Server uses the pairing key included in the STUN Binding Request to originate the pairing request by creating an entry in the internal lookup tables. b. The HPR returns the [public_address]:[public_port] to P1 as its WAN candidate.
  4. P1 sends its WAN candidate, now the Relay Server's [public_address]:[public_port], to P2.
  5. P2 sends a STUN Binding Request to the Relay Server which includes the pairing key.
  6. If the pairing key sent from P2 matches P1's key in the lookup table, the peers become paired and UDP traffic begins to flow via the Relay Server.
  7. All STUN protocol packets continue to be integrity checked via a private key never sent over the wire (see WebRTC). Packets that arrive to the Parsec app that do not pass the integrity check are dropped.
  8. All other BUD/SCTP packets that may arrive are fully encrypted via AES128-GCM. Packets that fail decryption or the GCM authentication check are dropped.
  9. All entries in the internal lookup tables are invalidated after 2 minutes of no traffic.
Troubleshooting

Verifying UDP connectivity using Netcat

You can use netcat to check if you can reach the Secure Relay using UDP. Netcat is included in most Linux distros as well as in MacOS. Is also available for windows here: https://nmap.org/download.html

In order to test the connectivity, run netcat in the Relay to listen for UDP connection in the public port, on our example 5000, with the following command:

nc -u -l 5000

On the client side, run the following command to connect to the Relay via its public IP and port, in our example: 1.2.3.4:5000 with the following command:

nc -u 1.2.3.4:5000

As this is UDP, both commands won’t show an error even if the connection can’t be established. In order to test connectivity, just type something on the client side and press enter. If the connectivity is working, you should see the text you typed in the client appearing on the Relay. 

You can run the same test from the internal host to the Relay, using the internal port in the Relay command (4900) and using the internal ip:internal port of the relay (10.1.2.20:4900) when connecting from the Host. 

Verifying configuration on premise Parsec host / Teams Admin Dashboard:

Verify that app_stun_address is pointed to the LAN/Private IP address of the relay and the LAN/Private port you specified when configuring the parsechpr.service on the Linux machine running the relay. If you modify this value, save the file (if done via config.txt) then restart Parsec from the system tray.

Verify that from the on premise Parsec host you can ping the LAN interface / IP address of the Linux machine running the relay.  

Verify that the Parsec host has general https internet connectivity (443).

Verify configuration on the firewall:

Confirm you are allowing inbound + outbound UDP traffic on the WAN interface of your firewall to and from the same [public port] you specified on the parsechpr.service. You must not use port translation. If you have set [Public Port] to 5000, then you must open UDP port 5000 on the WAN interface and it must forward directly to port 5000 (and LAN IP address) of the Linux machine running the relay.

Confirm your UDP inbound + outbound firewall rule at a minimum accepts traffic from your remote clients public IP address, but for testing purposes we recommend allowing traffic from all public addresses 0.0.0.0/0

Confirm you are not blocking traffic by application type on the Public port specified.

Verify configuration on the Linux parsechpr service host:

Verify the service is running:

sudo service parsechpr status

Verify the inbuilt (or otherwise) software firewall on the machine is not blocking UDP on the public or private ports you specified.

Verify  you can ping the on premise Parsec host via LAN.

General troubleshooting:

Make sure the client IS NOT connected to the on premise network via VPN, make sure the client device does have general internet connectivity, make sure the client (sitting at the users home) is the device initiating the connection to the on premise host.