Skip to content

Instantly share code, notes, and snippets.

@krsna1729
Forked from egernst/workstation-router.md
Created January 31, 2020 23:12
Show Gist options
  • Save krsna1729/8b53bf1cfe1843ecfe82d34a6e33352a to your computer and use it in GitHub Desktop.
Save krsna1729/8b53bf1cfe1843ecfe82d34a6e33352a to your computer and use it in GitHub Desktop.

Physical Setup:

---------------------
| workstation  [enp5s0f0] -- internet
|                  |          ---------------
|              [enp5s0f1] -- |    switch    |
--------------------         |              |
               [lab-nuc-1] --|              |
               [lab-nuc-2] --|--------------|

Software Setup

Workstation Setup

We'll setup a network with subnet 10.0.0.0/24

Setup static IP for the 'extra' interface

Add details for a static configration for enp5s0f1

old way:

$ cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto enp5s0f1
iface enp5s0f1 inet static
  address 10.0.0.1
  gateway 10.0.0.1
  netmask 255.255.255.0
  network 10.0.0.0
  broadcast 10.0.0.255

systemd

Ugh, I should probably use systemd. Next time, checkout this writeup

Setup DHCP server listening on enp5s0f1

isc-dhcp-server seemed to fit the bill for my needs.

sudo apt-get install isc-dhcp-server

Configure isc-dhcp-server to listen on enp5s0f1:

$ cat /etc/default/isc-dhcp-server  | grep INTERFACES
INTERFACESv4="enp5s0f1"
INTERFACESv6="enp5s0f1"

Update the dhcp daemon configuration, /etc/dhcp/dhcpd.conf. Highlights include:

subnet 10.0.0.0 netmask 255.255.255.0 {
option routers                  10.0.0.1;
option subnet-mask              255.255.255.0;
option broadcast-address        10.0.0.255;
range   10.0.0.1   10.0.0.10;
}
authoritative;

Behind proxy? Configure DHCP to provide correct DNS

Above is enough if you aren't behind a corporate proxy. If you aren't so lucky, you'll want to also explicitly set the DNS details. On the workstation (Bionic), DNS resolution is running locally on 127.0.0.53:54 thanks to systemd-resolve. One way to tell this is being resolved locally by viewing output of nslookup:

$ nslookup google.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	google.com
Address: 172.217.6.78
Name:	google.com
Address: 2607:f8b0:4005:80a::200e

Using netstat, I could see "who" is on port 53, and thus who is managing the DNS:

$ sudo netstat -plunt | grep 127.0.0.53
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      909/systemd-resolve 
udp        0      0 127.0.0.53:53           0.0.0.0:*                           909/systemd-resolve 

For systemd-resolve, I can figure out actual servers used if not locally available via status:

$ systemd-resolve --status
Global
...
Link 2 (enp5s0f0)
      Current Scopes: DNS
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no
         DNS Servers: 10.248.2.1
                      10.22.224.196
                      10.3.86.116
          DNS Domain: jf.intel.com

Use these servers/domain in our DHCP configuration (/etc/dhcp/dhcpd.conf):

option domain-name "jf.intel.com";
option domain-name-servers 10.248.2.1, 10.22.244.196, 10.3.86.116;

Once setup, restart dhcpd:

sudo systemctl daemon-reload
sudo systemctl restart isc-dhcp-server

Once you have devices attached, you should see their lease information @ /var/lib/dhcp/dhcpd.leases

Oh, you want network connectivity for your NUCs?

First, enable ipv4 forwarding by uncommenting appropriate line in /etc/sysctl.conf:

$ sudo cat /etc/sysctl.conf | grep ip_forward
net.ipv4.ip_forward=1

Next, setup the following ip table rules:

*nat:
 -A POSTROUTING -o enp5s0f0 -j MASQUERADE

While walking through the post-routing NAT table, for packets going out on enp5s0f0, jump to the NAT Masquerade chain. Maquerade will modify the senders address to be the same as the routers IP (SNAT). Basically, no one "outside" the subnet we created knows the sender's original address, so we'll use the same as the gateway's.

*filter:
 -A FORWARD -i enp5s0f1 -o enp5s0f0 -j ACCEPT

For packets which are being forwarded with source NUC (5s0f1) and destination 5s0f0 (inernet), take action "accept"

*filter:
-A FORWARD -i enp5s0f0 -o enp5s0f1 -m state --state RELATED,ESTABLISHED -j ACCEPT

For packets being forwarded which come from the internet and are destined for the NUC, only forward if we have an established session already.

Oh, you want network connectivity and use a transparent proxy?

On my workstation, I run chameleon socks, which sets up redsocks and a nat table chain, CHAMELEONSOCKS, which will forward non-proxy traffic to a particular port (which redsocks listens on). For more details on it, see gist on chameleonsocks. We want all of our NUC traffic to go through this chain as well, so our transparent proxy is, well, even more transparent! This can be done by adding a jump in our prerouting NAT table to the chameleonsocks chain if the traffic is coming from the NUC facing NIC (5s0f1). This is carried out by the following rule:

*nat
-A PREROUTING -i enp5s0f1 -p tcp -j CHAMELEONSOCKS

NUC Setup

Plug in the ethernet cable.

Boot it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment