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

The Parsec Gateway Server is available as an add-on to Parsec for Teams. It's a solution when you need more control over you network infrastructure. 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 Gateway Server, this provides all Parsec networking requirements. 

The Parsec Gateway 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 gateway 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):
Gateway 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 gateway'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] <-> [gateway-LAN-IP]:[UDP port]
Installation

Copy the download URL for the gateway server from the Teams App Config. The .tar.gz contains the Gateway Server files and the Readme.

SSH into the Linux machine that you'll use for the gateway 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 <gateway download URL>
tar -xf <gateway.tar.gz>
cd parsechpr1.0
sudo cp parsechpr /bin sudo cp parsechpr.service /etc/systemd/system

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

Run the service:

sudo systemctl start parsechpr
sudo systemctl enable parsechpr
Usage

Confirm that the gateway service is running:

service pasrechpr status

The Gateway 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 Gateway 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.

Beginning with Parsec build 150-48, the STUN server address may be specified in the
configuration file via app_stun_address:

app_stun_address = 192.168.1.150@[private_port] # 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 = 192.168.1.150@23050,192.168.1.151@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 STUN server is available, Parsec will choose a STUN server at random on each connection attempt. If an attempt fails because the STUN address could not be reached, Parsec will blacklist that address for 10 minutes and only consider the remaining addresses.

The Gateway 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 Gateway Server instead of using its normal NAT traversal routines.

Details

The Gateway 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 Gateway Server will be labeled "P1" and the peer attempting to connect to P1 will be labeled "P2".

  1. P1 configures itself to use the Gateway 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 Gateway Server via the secure [private_port]: a. The Gateway 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 Gateway Server's [public_address]:[public_port], to P2.
  5. P2 sends a STUN Binding Request to the Gateway 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 Gateway 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 configuration on premise Parsec host / Teams Admin Dashboard:

Verify that app_stun_address is pointed to the LAN/Private IP address of the gateway and the LAN/Private port you specified when configuring the parsechpr.service on the Linux machine running the gateway. 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 gateway.  

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.

It's still not working:

To aid troubleshooting, we recommend installing a temporary iperf3 server application on the Linux machine, and running a UDP iperf3 speedtest from the remote Parsec client and internal Parsec host. This troubleshooting step will allow you to test network connectivity internally and externally to the Linux host without involving Parsec.