Skip to content

Instantly share code, notes, and snippets.

@EricSeastrand
Last active December 11, 2023 23:48
Show Gist options
  • Save EricSeastrand/b21b2e045756f719a31b951256234dec to your computer and use it in GitHub Desktop.
Save EricSeastrand/b21b2e045756f719a31b951256234dec to your computer and use it in GitHub Desktop.
Making a Debian router

Set WAN DHCP client Set LAN static IP and subnet

cat /etc/network/interfaces 
source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# DHCP config for ens4 (WAN)
auto ens4
iface ens4 inet dhcp


# Static config for ens5 (LAN)
auto ens5
iface ens5 inet static
	address 10.40.0.1
	netmask 255.255.254.0
#	gateway 192.168.1.1
#	dns-nameservers 1.1.1.1

ip link set ens4 up ip link set ens5 up

apt update && apt install nftables -y sudo systemctl enable nftables sudo systemctl restart networking

And add to /etc/sysctl.conf echo 1 > /proc/sys/net/ipv4/ip_forward

#!/usr/sbin/nft -f
flush ruleset

define DEV_PRIVATE = ens5
define DEV_WORLD = ens4
define NET_PRIVATE = 10.40.0.0/23

table ip global {

    chain inbound_world {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        # However, it also lets probes discover this host is alive.
        # This sample accepts them within a certain rate limit:
        #
        # icmp type echo-request limit rate 5/second accept

        # allow SSH connections from some well-known internet host
        # ip saddr 81.209.165.42 tcp dport ssh accept
    }

    chain inbound_private {
        # accepting ping (icmp-echo-request) for diagnostic purposes.
        icmp type echo-request limit rate 5/second accept

        # allow DHCP, DNS and SSH from the private network
        ip protocol . th dport vmap { tcp . 22 : accept, udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept}
    }

    chain inbound {
        type filter hook input priority 0; policy drop;

        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # allow loopback traffic, anything else jump to chain for further evaluation
        iifname vmap { lo : accept, $DEV_WORLD : jump inbound_world, $DEV_PRIVATE : jump inbound_private }

        # the rest is dropped by the above policy
    }

    chain forward {
        type filter hook forward priority 0; policy drop;

        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # connections from the internal net to the internet or to other
        # internal nets are allowed
        iifname $DEV_PRIVATE accept

        # the rest is dropped by the above policy
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;

        # masquerade private IP addresses
        ip saddr $NET_PRIVATE oifname $DEV_WORLD masquerade
    }
}

DHCPD

apt install kea-dhcp4-server -y mv kea-dhcp4.conf kea-dhcp4.sample.conf && vim kea-dhcp4.conf

# /etc/kea/kea-dhcp4.conf
{
# DHCPv4 configuration starts on the next line
"Dhcp4": {

# Set up global values that apply to leases
    "valid-lifetime": 1296000,
    "renew-timer": 864000,
    "rebind-timer": 864000,

# Set up reclaimation for expired leases and leases affinity
    "expired-leases-processing": {
        "reclaim-timer-wait-time": 10,
        "flush-reclaimed-timer-wait-time": 25,
        "hold-reclaimed-time": 3600,
        "max-reclaim-leases": 100,
        "max-reclaim-time": 250,
        "unwarned-reclaim-cycles": 5
    },

# Set up the interfaces to be used by the server.
    "interfaces-config": {
        "interfaces": [ "enp5s0" ]
    },

# Specify the type of lease database
    "lease-database": {
        "type": "memfile",
        "persist": true,
        "name": "/home/_kea/dhcp4.leases",
        "lfc-interval": 3600
    },
  
# Specify the subnets from which we will be leasing addresses.
    "subnet4": [
        {
            "subnet": "10.40.0.0/23",
            "pools": [
                {
                     "pool": "10.40.0.100 - 10.40.1.250"
                }
            ],
            "option-data": [
                {
                    # For each IPv4 subnet you most likely need to specify
                    # at least one router.
                    "name": "routers",
                    "data": "10.40.0.1"
                },
                {
                    # For each IPv4 subnet you most likely need to specify
                    # at least one router.
                    "name": "domain-name",
                    "data": "home.arpa"
                },
                {
                    # For each IPv4 subnet you most likely need to specify
                    # at least one router.
                    "name": "domain-name-servers",
                    "data": "1.1.1.1, 8.8.8.8"
                }
            ],
            "reservations": [
                {
                    # Use this section to specify the target board's fixed 
                    # IP address
                    # Substitute the target board MAC address
                    "client-id": "00:1b:41:0a:00:3d",
                    # Set the static IP address for the target board
                    "ip-address": "10.40.0.5",
                    "hostname": "david-nas"
                 }
            ]
        }
    ]
# DHCPv4 configuration ends with the next line
}

}

ToDo: Figure out apparmor issues. Had to disable to let dhcpd run. It didn't like kea reading the dhcp leases cache file for whatever reason. Evidently it's a known issue from Google searches.

apt install apparmor-utils
aa-disable /etc/apparmor.d/usr.sbin.kea-dhcp4
systemctl start kea-dhcp4-server

TODO

The End

Sadly, this approach wasn't able to deliver the performance I was after. Using 2.5gbe interfaces, I was hoping for line-rate NAT with a single stream. Here's what I ended up with. Scenario: downloading a file from the internet. Actual setup" client on LAN interface of debian router. WAN of the debian router is plugged into my network as just another client. iperf server host is a truenas scale instance with 10gbe (capable of 10gbps single stream).

admin@david-nas[~]$ iperf3 -c truenas-scale.seas.house -R 
Connecting to host truenas-scale.seas.house, port 5201
Reverse mode, remote host truenas-scale.seas.house is sending
[  5] local 10.40.0.100 port 49272 connected to 10.23.4.21 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   175 MBytes  1.46 Gbits/sec                  
[  5]   1.00-2.00   sec   140 MBytes  1.18 Gbits/sec                  
[  5]   2.00-3.00   sec   142 MBytes  1.19 Gbits/sec                  
[  5]   3.00-4.00   sec   140 MBytes  1.17 Gbits/sec                  
[  5]   4.00-5.00   sec   146 MBytes  1.22 Gbits/sec                  
[  5]   5.00-6.00   sec   139 MBytes  1.16 Gbits/sec                  
[  5]   6.00-7.00   sec   157 MBytes  1.31 Gbits/sec                  
[  5]   7.00-8.00   sec   140 MBytes  1.17 Gbits/sec                  
[  5]   8.00-9.00   sec   155 MBytes  1.30 Gbits/sec                  
[  5]   9.00-10.00  sec   140 MBytes  1.18 Gbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.04  sec  1.44 GBytes  1.23 Gbits/sec  10437             sender
[  5]   0.00-10.00  sec  1.44 GBytes  1.24 Gbits/sec                  receiver

Bumping up to 6 streams nets us 1.83 Gbits/sec. Still not quite the 2.5gbe we are after.

iperf3 -c truenas-scale.seas.house -R -P 6
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.04  sec   416 MBytes   347 Mbits/sec  4579             sender
[  5]   0.00-10.00  sec   414 MBytes   348 Mbits/sec                  receiver
[  7]   0.00-10.04  sec   433 MBytes   362 Mbits/sec  4446             sender
[  7]   0.00-10.00  sec   432 MBytes   363 Mbits/sec                  receiver
[  9]   0.00-10.04  sec   316 MBytes   264 Mbits/sec  3607             sender
[  9]   0.00-10.00  sec   314 MBytes   264 Mbits/sec                  receiver
[ 11]   0.00-10.04  sec   354 MBytes   296 Mbits/sec  4249             sender
[ 11]   0.00-10.00  sec   353 MBytes   296 Mbits/sec                  receiver
[ 13]   0.00-10.04  sec   319 MBytes   267 Mbits/sec  3964             sender
[ 13]   0.00-10.00  sec   318 MBytes   267 Mbits/sec                  receiver
[ 15]   0.00-10.04  sec   349 MBytes   291 Mbits/sec  4450             sender
[ 15]   0.00-10.00  sec   348 MBytes   292 Mbits/sec                  receiver
[SUM]   0.00-10.04  sec  2.13 GBytes  1.83 Gbits/sec  25295             sender
[SUM]   0.00-10.00  sec  2.13 GBytes  1.83 Gbits/sec                  receiver

With 12 streams we're able to finally hit a little over 2 gig.

iperf3 -c truenas-scale.seas.house -R -P 12
[SUM]   0.00-10.03  sec  2.44 GBytes  2.09 Gbits/sec  36266             sender
[SUM]   0.00-10.00  sec  2.43 GBytes  2.09 Gbits/sec                  receiver

This was the most performance I could get out of this setup for NAT resembling the real-world usecase of a soho router.

On the other hand, other scenarios are able to achieve near line-rate 2.5gbe: Regular old upload to the server hits 2.26 - nearly the real-world maximum we can expect after factoring in overhead.

admin@david-nas[~]$ iperf3 -c truenas-scale.seas.house              
Connecting to host truenas-scale.seas.house, port 5201
[  5] local 10.40.0.100 port 48534 connected to 10.23.4.21 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   272 MBytes  2.28 Gbits/sec    1    626 KBytes       
[  5]   1.00-2.00   sec   271 MBytes  2.27 Gbits/sec    0    638 KBytes       
[  5]   2.00-3.00   sec   270 MBytes  2.27 Gbits/sec    0    649 KBytes       
[  5]   3.00-4.00   sec   270 MBytes  2.26 Gbits/sec    1    632 KBytes       
[  5]   4.00-5.00   sec   270 MBytes  2.26 Gbits/sec    2    556 KBytes       
[  5]   5.00-6.00   sec   270 MBytes  2.26 Gbits/sec    2    624 KBytes       
[  5]   6.00-7.00   sec   270 MBytes  2.26 Gbits/sec    0    643 KBytes       
[  5]   7.00-8.00   sec   271 MBytes  2.28 Gbits/sec    0    649 KBytes       
[  5]   8.00-9.00   sec   268 MBytes  2.24 Gbits/sec    1    619 KBytes       
[  5]   9.00-10.00  sec   271 MBytes  2.27 Gbits/sec    0    660 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  2.64 GBytes  2.27 Gbits/sec    7             sender
[  5]   0.00-10.04  sec  2.64 GBytes  2.26 Gbits/sec                  receiver

Transfers with the router itself are also line-rate capable. So if you wanted to run a single box with a bunch of homelab stuff, plex, hw transcoding, containers, storage, even a full debian desktop with gpu accelerated rendering over remote desktop... It could also be your router. If your internet is <1gbps you'd never notice the nat bottleneck.

admin@david-nas[~]$ iperf3 -c 10.40.0.1
Connecting to host 10.40.0.1, port 5201
[  5] local 10.40.0.100 port 53792 connected to 10.40.0.1 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   273 MBytes  2.29 Gbits/sec    0    584 KBytes       
[  5]   1.00-2.00   sec   271 MBytes  2.27 Gbits/sec    0    649 KBytes       
[  5]   2.00-3.00   sec   271 MBytes  2.28 Gbits/sec    0    693 KBytes       
[  5]   3.00-4.00   sec   270 MBytes  2.26 Gbits/sec    1    580 KBytes       
[  5]   4.00-5.00   sec   271 MBytes  2.28 Gbits/sec    0    588 KBytes       
[  5]   5.00-6.00   sec   271 MBytes  2.27 Gbits/sec    0    645 KBytes       
[  5]   6.00-7.00   sec   270 MBytes  2.27 Gbits/sec    0    645 KBytes       
[  5]   7.00-8.00   sec   271 MBytes  2.28 Gbits/sec    0    645 KBytes       
[  5]   8.00-9.00   sec   270 MBytes  2.26 Gbits/sec    0    645 KBytes       
[  5]   9.00-10.00  sec   271 MBytes  2.28 Gbits/sec    0    645 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  2.65 GBytes  2.27 Gbits/sec    1             sender
[  5]   0.00-10.00  sec  2.64 GBytes  2.27 Gbits/sec                  receiver

As far as system load on the router, it never gets high: load average: 0.08, 0.07, 0.03 is what I observed while running any of these tests. There's no load whatsoever. But there are other clues: When not bottlenecked we get:

admin@david-nas[~]$ iperf3 -c truenas-scale.seas.house -t 0
Router: %Cpu(s):  0.0 us,  0.0 sy,  0.0 ni, 93.6 id,  0.0 wa,  0.0 hi,  6.4 si,  0.0 st

When using many streams to get around the download-direction bottleneck:

admin@david-nas[~]$ iperf3 -c truenas-scale.seas.house -t 0 -R -P 8
Router: %Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 96.4 id,  0.0 wa,  0.0 hi,  3.3 si,  0.0 st 

When bottlenecked:

iperf3 -c truenas-scale.seas.house -t 0 -R 
Router: %Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 97.5 id,  0.0 wa,  0.0 hi,  2.4 si,  0.0 st 

There's more to this that I don't think I'll ever fully understand.

At this point I've seen what I need to see. This started out as an effort to recycle my inlaws' old Dell into something useful. I really wanted to see how nftables can perform. But it's a lot to set up and manage, when I really just need something simple that won't bottleneck a "multi gig" WAN connection. I think I'll just install pfsense and call it a day.

Here's some info about the hardware I tried this on: Dell XPS desktop from 2011ish.

inxi -Fxz
System:
  Kernel: 6.1.0-9-amd64 arch: x86_64 bits: 64 compiler: gcc v: 12.2.0 Console: pty pts/2
    Distro: Debian GNU/Linux 12 (bookworm)
Machine:
  Type: Desktop System: Dell product: XPS 8500 v: N/A serial: <filter>
  Mobo: Dell model: 0NW73C v: A00 serial: <filter> UEFI: Dell v: A09 date: 09/05/2012
CPU:
  Info: quad core model: Intel Core i7-3770 bits: 64 type: MT MCP arch: Ivy Bridge rev: 9 cache:
    L1: 256 KiB L2: 1024 KiB L3: 8 MiB
  Speed (MHz): avg: 1775 high: 3000 min/max: 1600/3900 cores: 1: 1600 2: 1600 3: 3000 4: 1600
    5: 1600 6: 1600 7: 1600 8: 1600 bogomips: 54271
  Flags: avx ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx
Graphics:
  Device-1: AMD Pitcairn XT [Radeon HD 7870 GHz Edition] driver: radeon v: kernel arch: GCN-1
    bus-ID: 01:00.0 temp: 32.0 C
  Display: x11 server: X.org v: 1.21.1.7 with: Xwayland v: 22.1.9 driver: X: loaded: radeon
    unloaded: fbdev,modesetting,vesa dri: radeonsi gpu: radeon tty: 232x96
  API: OpenGL Message: GL data unavailable in console for root.
Audio:
  Device-1: AMD Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series]
    driver: snd_hda_intel v: kernel bus-ID: 01:00.1
  API: ALSA v: k6.1.0-9-amd64 status: kernel-api
  Server-1: PipeWire v: 0.3.65 status: n/a (root, process)
  Server-2: PulseAudio v: 16.1 status: off (using pipewire-pulse)
Network:
  Device-1: Qualcomm Atheros AR9485 Wireless Network Adapter vendor: Dell driver: ath9k v: kernel
    bus-ID: 02:00.0
  IF: wlp2s0 state: down mac: <filter>
  Device-2: Intel Ethernet I225-V driver: igc v: kernel port: N/A bus-ID: 03:00.0
  IF: enp3s0 state: up speed: 2500 Mbps duplex: full mac: <filter>
  Device-3: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet vendor: Dell driver: r8169
    v: kernel port: d000 bus-ID: 04:00.0
  IF: enp4s0 state: up speed: 1000 Mbps duplex: full mac: <filter>
  Device-4: Intel Ethernet I225-V driver: igc v: kernel port: N/A bus-ID: 05:00.0
  IF: enp5s0 state: up speed: 2500 Mbps duplex: full mac: <filter>
Bluetooth:
  Device-1: Qualcomm Atheros Bluetooth USB Host Controller type: USB driver: btusb v: 0.8
    bus-ID: 1-1.5:3
  Report: hciconfig ID: hci0 rfk-id: 0 state: up address: <filter> bt-v: 2.1 lmp-v: 4.0
Drives:
  Local Storage: total: 29.82 GiB used: 10.73 GiB (36.0%)
  ID-1: /dev/sda vendor: Samsung model: SSD PM830 mSATA 32GB size: 29.82 GiB
Partition:
  ID-1: / size: 28.89 GiB used: 10.72 GiB (37.1%) fs: ext4 dev: /dev/sda2
  ID-2: /boot/efi size: 299.4 MiB used: 5.8 MiB (1.9%) fs: vfat dev: /dev/sda1
Swap:
  Alert: No swap data was found.
Sensors:
  System Temperatures: cpu: 29.0 C mobo: N/A gpu: radeon temp: 32.0 C
  Fan Speeds (RPM): cpu: 881 mobo: 909
Info:
  Processes: 188 Uptime: 1h 50m Memory: 23.43 GiB used: 833.2 MiB (3.5%) Init: systemd
  target: graphical (5) Compilers: gcc: 12.2.0 Packages: 2509 Shell: Bash v: 5.2.15 inxi: 3.3.26
root@old-dell-white:~# lscpu
Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         36 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  8
  On-line CPU(s) list:   0-7
Vendor ID:               GenuineIntel
  BIOS Vendor ID:        Intel
  Model name:            Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
    BIOS Model name:     Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz Fill By OEM CPU @ 3.4GHz
    BIOS CPU family:     6
    CPU family:          6
    Model:               58
    Thread(s) per core:  2
    Core(s) per socket:  4
    Socket(s):           1
    Stepping:            9
    CPU(s) scaling MHz:  43%
    CPU max MHz:         3900.0000
    CPU min MHz:         1600.0000
    BogoMIPS:            6783.97
    Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop                         _tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm cpuid_fault epb pti ssbd i
                         brs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts md_clear flush_l1d
Virtualization features: 
  Virtualization:        VT-x
Caches (sum of all):     
  L1d:                   128 KiB (4 instances)
  L1i:                   128 KiB (4 instances)
  L2:                    1 MiB (4 instances)
  L3:                    8 MiB (1 instance)
NUMA:                    
  NUMA node(s):          1
  NUMA node0 CPU(s):     0-7
Vulnerabilities:         
  Itlb multihit:         KVM: Mitigation: VMX disabled
  L1tf:                  Mitigation; PTE Inversion; VMX conditional cache flushes, SMT vulnerable
  Mds:                   Mitigation; Clear CPU buffers; SMT vulnerable
  Meltdown:              Mitigation; PTI
  Mmio stale data:       Unknown: No mitigations
  Retbleed:              Not affected
  Spec store bypass:     Mitigation; Speculative Store Bypass disabled via prctl
  Spectre v1:            Mitigation; usercopy/swapgs barriers and __user pointer sanitization
  Spectre v2:            Mitigation; Retpolines, IBPB conditional, IBRS_FW, STIBP conditional, RSB filling, PBRSB-eIBRS Not affected
  Srbds:                 Vulnerable: No microcode
  Tsx async abort:       Not affected
root@old-dell-white:~# dmidecode -t memory
# dmidecode 3.4
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.

Handle 0x002A, DMI type 16, 23 bytes
Physical Memory Array
        Location: System Board Or Motherboard
        Use: System Memory
        Error Correction Type: None
        Maximum Capacity: 32 GB
        Error Information Handle: Not Provided
        Number Of Devices: 4

Handle 0x002C, DMI type 17, 34 bytes
Memory Device
        Array Handle: 0x002A
        Error Information Handle: Not Provided
        Total Width: 64 bits
        Data Width: 64 bits
        Size: 8 GB
        Form Factor: DIMM
        Set: None
        Locator: DIMM3
        Bank Locator: BANK 0
        Type: DDR3
        Type Detail: Synchronous
        Speed: 1600 MT/s
        Manufacturer: Micron
        Serial Number: DE9A77BD
        Asset Tag: 9876543210
        Part Number: 16JTF1G64AZ-1G6D1 
        Rank: 2
        Configured Memory Speed: 1600 MT/s

Handle 0x002E, DMI type 17, 34 bytes
Memory Device
        Array Handle: 0x002A
        Error Information Handle: Not Provided
        Total Width: 64 bits
        Data Width: 64 bits
        Size: 8 GB
        Form Factor: DIMM
        Set: None
        Locator: DIMM1
        Bank Locator: BANK 1
        Type: DDR3
        Type Detail: Synchronous
        Speed: 1600 MT/s
        Manufacturer: Micron
        Serial Number: DE9A77B0
        Asset Tag: 9876543210
        Part Number: 16JTF1G64AZ-1G6D1 
        Rank: 2
        Configured Memory Speed: 1600 MT/s

Handle 0x0030, DMI type 17, 34 bytes
Memory Device
        Array Handle: 0x002A
        Error Information Handle: Not Provided
        Total Width: Unknown
        Data Width: Unknown
        Size: No Module Installed
        Form Factor: DIMM
        Set: None
        Locator:        
        Bank Locator:        
        Type: Unknown
        Type Detail: None

Handle 0x0031, DMI type 17, 34 bytes
Memory Device
        Array Handle: 0x002A
        Error Information Handle: Not Provided
        Total Width: 64 bits
        Data Width: 64 bits
        Size: 8 GB
        Form Factor: DIMM
        Set: None
        Locator: DIMM2
        Bank Locator: BANK 3
        Type: DDR3
        Type Detail: Synchronous
        Speed: 1600 MT/s
        Manufacturer: Micron
        Serial Number: DE9A77B1
        Asset Tag: 9876543210
        Part Number: 16JTF1G64AZ-1G6D1 
        Rank: 2
        Configured Memory Speed: 1600 MT/s

Pfsense?

Well, looks like Pfsense can't hit line speed either on this hardware. Single stream performance in a download scenario manages just 1.5gbps. With 6 streams we can max out the 2.5gbe interface, but that's not what I'm after. Worse yet, pfsense lacks compatible fan control for this antique Dell XPS PC, so the fans run full tilt the entire time creating tons of noise and sucking up dust.

The quest for a true 2.5gbps router continues.

DNSMASQ

You probably want something like it. So you can cache DNS requests, and so LAN hosts get listed in DNS.

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