Linux / nftables PrivX Router
=============================

# Version
PrivX-Router-Linux-Nftables 45.0-55_c3831aacb3

# Requirements

The linux nftables router requirements:
* Router must be placed on the path between the VPN server and the protected 
  targets, and the router must able to forward IPv4 and/or IPv6 packets.
* Kernel must support nftables support and the nft control tool must be
  available.
* SSH server with SSH exec support.
* Any existing firewall solution must be disabled or explicitly configured to
  allow non-interfering coexistence with PrivX router nftables rules and chains.

# Overview

PrivX controls the Linux nftables PrivX router by executing nftables commands
over SSH.

The nftables rules PrivX manages are added to custom nftables chains. The router
setup script creates these custom chains and enables IPv4 / IPv6 forwarding.

The default custom tables and their usage:
* "PRIVX_FILTER": packet filtering for IPv4 traffic
* "PRIVX_NAT": network address translation for IPv4 traffic
* "PRIVX6_FILTER": packet filtering for IPv6 traffic
* "PRIVX6_NAT": network address translation for IPv6 traffic

The default custom chains and their usage:
* "PRIVX_FORWARD": jump rules for forwarding IPv4 traffic
* "PRIVX_FORWARD_TARGET": accept / drop rules for client to target IPv4 traffic
* "PRIVX_FORWARD_CLIENT": accept / drop rules for target to client IPv4 traffic
* "PRIVX_NAT_PREROUTING": destination nat rules for IPv4 traffic
* "PRIVX_NAT_POSTROUTING": source nat rules for IPv4 traffic
* "PRIVX6_FORWARD": jump rules for forwarding IPv6 traffic
* "PRIVX6_FORWARD_TARGET": accept / drop rules for client to target IPv6 traffic
* "PRIVX6_FORWARD_CLIENT": accept / drop rules for target to client IPv6 traffic
* "PRIVX6_NAT_PREROUTING": destination nat rules for IPv6 traffic
* "PRIVX6_NAT_POSTROUTING": source nat rules for IPv6 traffic

Jump rules:
* "FORWARD" chain:
  * ip saddr {remote access client IP range} counter jump PRIVX_FORWARD_TARGET
  * ip daddr {remote access client IP range} counter jump PRIVX_FORWARD_CLIENT

The remote access client IP range is defined the environment file's variables
RAC_IP_POOL and RAC6_IP_POOL. Either IP range can be left empty in which case
custom chains and jump rules are not created for the respective IP version. The
names of the custom chain's can also be modified by editing the environment
file.

When a new network access session is created or removed, PrivX connects to the
router via SSH and executes the commands to add/remove the nftables rules. These
commands always read the environment file to resolve the custom chain names.

It is expected that any other firewall solution or application managing the
nftables rules in the system does not interfere with rules installed in the
custom chains or with the jump rules from the standard chains to the custom
chains.

Note that for example the default configuration of firewalld does not allow
traffic from remote access client IP range to targets, thus meaning the nftables
rules added by PrivX do not have any effect. We recommend disabling firewalld or
configuring it explicitly to allow all traffic from remote access client IP
range to all targets, thereby leaving the access control for such traffic to
PrivX.

# Setting Up The Router

## Creating Dedicated User

It is recommended to create a user account dedicated for controlling the router
and to give that user the minimum required privileges via sudo:

1. Create a normal user account
   # adduser privx

2. Grant access to /sbin/nftables and /sbin/sysctl by
   adding the following line to sudo configuration in /etc/sudoers or
   /etc/sudoers.d/privx-router:
   %privx   ALL = NOPASSWD: /usr/sbin/nft, /sbin/sysctl

## Installing Setup Script And Environment File

1. Create directory structure under /opt/privx
   # mkdir -p /opt/privx/scripts /opt/privx/etc
   # chown privx:privx /opt/privx/etc

2. Copy scripts/setup.sh
   # cp scripts/setup.sh /opt/privx/scripts/
   # chown privx:privx /opt/privx/scripts/setup.sh
   # chmod 0755 /opt/privx/scripts/setup.sh

3. Copy etc/privx-router.env and edit the file to match your environment
   # cp etc/privx-router.env /opt/privx/etc/
   edit /opt/privx/etc/privx-router.env 
   # chown privx:privx /opt/privx/etc/privx-router.env
   # chmod 0444 /opt/privx/etc/privx-router.env

   Refer to the comments in privx-router.env for more information about the
   environment variables.

4. Create files for ruleset and lockfile
   # touch /opt/privx/etc/nftables.lock
   # chown privx:privx /opt/privx/etc/nftables.lock
   # chmod 0644 /opt/privx/etc/nftables.lock
   # touch /opt/privx/etc/nftables.rules
   # chown privx:privx /opt/privx/etc/nftables.rules
   # chmod 0644 /opt/privx/etc/nftables.rules

## Executing Setup Script On Boot

The setup.sh needs to be executed when the router is booted.

One way to achieve this is to use the sample systemd service file in
systemd/privx-router.service. To install it:

1. Copy privx-router.service
   # cp systemd/privx-router.service /etc/systemd/system/
   # chown root:root /etc/systemd/system/privx-router.service
   # chmod 0755 /etc/systemd/system/privx-router.service

2. Reload systemd service files
   # systemctl daemon-reload

3. Start privx-router service
   # systemctl start privx-router

4. Enable privx-router service to run automatically at boot
   # systemctl enable privx-router

# Deploying Router As a Host To PrivX

It is recommended to create a dedicated role to PrivX for controlling access to
the router. This role must be configured as a role granting access to the
router's host account in PrivX configuration. It is recommended that the role is
normally not granted to any PrivX users, but it can be granted to a admin user
if it necessary to debug the router's nftables rules or to perform any manual
maintenance.

Once you have created a dedicated role, please refer to PrivX documentation for
supported SSH authentication methods and instructions for deploying the router
as a host to PrivX:
  https://privx.docs.ssh.com/docs/authenticating-to-hosts/supported-authentication-methods

# Configuring Network Access Manager

The routers are configured to PrivX Network Access Manager via the the settings
UI. The configuration is entered as an array of json objects.

For Linux nftables router the configuration looks like following:
  [
      {
        "type": "linux-nftables",
        "client_ip_pool": [
            "10.0.0.0/8"
        ],
        "username": "privx",
        "hostname": "10.10.2.22",
        "max_concurrent_ssh_exec_requests": 1
    }
  ]

The client_ip_pool must match the RAC_IP_POOL and RAC6_IP_POOL defined in the
environment file. Username and hostname are used when connecting to the router
using SSH. Hostname can contain an optional port number and an optional extender
prefix. Optional parameter max_concurrent_ssh_exec_requests can be used for
setting the SSH exec worker pool size. By default the size is 1.

