Linux / IPtables PrivX Router
=============================

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

# Requirements

The linux iptables 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 IPtables and/or IP6tables support and respective control
  tools 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 iptables / ip6tables rules
  and chains.

# Overview

PrivX controls the linux iptables PrivX router by executing iptables and/or
ip6tables commands over SSH.

The iptables rules PrivX manages are added to custom iptables chains. The router
setup script creates these custom chains and the jump rules to them from the
standard chains, and enables IPv4 / IPv6 forwarding.

The default custom chains and their usage:
* "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_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:
  * -s {remote access client IP range} -j PRIVX_FORWARD_TARGET
  * -d {remote access client IP range} -j PRIVX_FORWARD_CLIENT
* nat table "PREROUTING" chain:
  * -s {remote access client IP range} -j PRIVX_NAT_PREROUTING
* nat table "POSTROUTING" chain:
  * -s {remote access client IP range} -j PRIVX_NAT_POSTROUTING

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 iptables 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
iptables 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 iptables
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 /usr/sbin/iptables, /usr/sbin/ip6tables 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/iptables, /usr/sbin/ip6tables, /sbin/sysctl

## Installing Setup Script And Environment File

1. Create directory structure under /opt/privx
   # mkdir -p /opt/privx/scripts /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.

## 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 iptables 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 iptables router the configuration looks like following:
  [
      {
        "type": "linux-iptables",
        "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.
