Bridged Network Source NAT

Overview

Administrators may desire to provision Kasm sessions that egress out of a specific IP assigned to the host. This might be useful if the network utilizes special policy routes based on source IPs to direct traffic. In this example we will demonstrate how to:

  • Create a custom docker network using the bridge driver.

  • Configure the docker network to egress out of defined interface IP.

  • Configure a Kasm Workspace to always be provisioned on the desired docker network, using the Restrict to Docker Network Workspace Setting

In this model, the Kasm sessions will be given a NATed address inside the docker network pool (e.g 172.19.0.0/16) but when the traffic leaves the docker host it will utilize a specific IP that belongs to one of the hosts interfaces.

../_images/diagram.png

Desired Configuration

Environment

Network Interfaces

Interface

IP(s)

enp0s3

192.168.4.53/24 192.168.4.153/24

enp0s8

192.168.56.103/24

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:be:61:fa brd ff:ff:ff:ff:ff:ff
    inet 192.168.4.53/22 brd 192.168.7.255 scope global noprefixroute dynamic enp0s3
       valid_lft 12112sec preferred_lft 12112sec
    inet 192.168.4.153/24 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::e7be:8f90:49c:ec27/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:b4:47:93 brd ff:ff:ff:ff:ff:ff
    inet 192.168.56.103/24 brd 192.168.56.255 scope global noprefixroute dynamic enp0s8
       valid_lft 506sec preferred_lft 506sec
    inet6 fe80::dbad:e1ea:d353:c4a/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

Docker Network Configuration

Note

The docker network names used in this example are intentionally prefixed with z_ . Due to a quirk docker will choose the default route for the container based on the name of the docker network ordered alphabetically. We name these custom networks accordingly so that they won’t cause interruptions with the Kasm service containers or user workflow.

  1. Create a bridged docker network named z_custom_a

sudo docker network create \
    --driver bridge \
    --attachable \
    --opt "com.docker.network.bridge.name"="z_custom_a" \
    --opt "com.docker.network.bridge.enable_ip_masquerade"="false" \
    z_custom_a
  1. After the network is created, get the auto-generated subnet

sudo docker inspect z_custom_a | grep Subnet
                "Subnet": "172.19.0.0/16",
  1. Update iptables to source nat traffic from the custom docker network to the defined IP

sudo iptables -t nat -A POSTROUTING -s 172.19.0.0/16 ! -o z_custom_a -j SNAT --to-source 192.168.4.153
  1. Create a bridged docker network named z_custom_b.

sudo docker network create \
    --driver bridge \
    --attachable \
    --opt "com.docker.network.bridge.name"="z_custom_b" \
    --opt "com.docker.network.bridge.enable_ip_masquerade"="false" \
    z_custom_b
  1. After the network is created, get the auto-generated subnet

sudo docker inspect z_custom_b | grep Subnet
                "Subnet": "172.20.0.0/16",
  1. Update iptables to source nat traffic from the custom docker network to the defined IP

sudo iptables -t nat -A POSTROUTING -s 172.20.0.0/16 ! -o z_custom_b -j SNAT --to-source 192.168.56.103
  1. The generated briged interfaces can also be observed using ip a

ip a
...
32: z_custom_a: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:5e:07:7a:e6 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global z_custom_a
       valid_lft forever preferred_lft forever
33: z_custom_b: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:f4:a5:a7:ca brd ff:ff:ff:ff:ff:ff
    inet 172.20.0.1/16 brd 172.20.255.255 scope global z_custom_b
       valid_lft forever preferred_lft forever

Kasm Workspace Configuration

  1. Log into the Kasm UI as an administrator.

  2. Select Workspaces -> Workspaces.

  3. Select Edit next to the desired Workspace from the arrow menu.

  4. Check Restrict Image to Docker Network and select the desired network

../_images/restrict_to_network.webp

Restrict Image to Docker Network

Create a new session using the Workspace and verify the configurations. In this example we make a request to a web server that returns our IP

../_images/verification.png

Verification