DHCP & DNS - ether42/bootable-usb GitHub Wiki

LXC

The LXC requires an interface on every LAN for which it must serve DHCP & DNS:

lxc.network.0.type = veth
lxc.network.0.name = service
lxc.network.0.link = service
lxc.network.0.hwaddr = 02:00:0a:00:65:fd

lxc.network.1.type = veth
lxc.network.1.name = administrative
lxc.network.1.link = administrative
lxc.network.1.hwaddr = 02:00:0a:00:66:fd

lxc.network.2.type = veth
lxc.network.2.name = client
lxc.network.2.link = client
lxc.network.2.hwaddr = 02:00:0a:00:64:fd

For the sake of simplicity, the MAC address encodes the IPv4 address, for example to translate 10.0.100.253 into a MAC address' tail:

printf '%02x ' 10 0 100 253
0a 00 64 fd

Ensure the MAC address' 0x02 bit is set to signal it's user-defined.

Setup

On the rootfs:

apt-get install --no-install-recommends isc-dhcp-server bind9
systemctl disable isc-dhcp-server
systemctl disable bind9 # more exist but they are disabled by default

You may also want to install isc-dhcp-common for the man pages.

Of course, since the LXC host the DHCP service, it has to use static IP addresses.

/etc/network/interfaces.d/service:

auto service
iface service inet static
  address 10.0.101.253
  netmask 255.255.255.0
  gateway 10.0.101.254

/etc/network/interfaces.d/administrative:

auto administrative
iface administrative inet static
  address 10.0.102.253
  netmask 255.255.255.0

/etc/network/interfaces.d/client:

auto client
iface client inet static
  address 10.0.100.253
  netmask 255.255.255.0

/etc/resolv.conf:

nameserver 127.0.0.1
search lorn.space

DHCP

The interfaces on which the DHCP server should listen are setup in /etc/default/isc-dhcp-server:

INTERFACESv4="client service administrative"

A simple configuration should look like:

default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
authoritative;

option domain-search "lorn.space";

include "/etc/dhcp/client";
include "/etc/dhcp/service";
include "/etc/dhcp/administrative";

And the corresponding service subnet file would look like:

subnet 10.0.101.0 netmask 255.255.255.0 {
  option routers 10.0.101.254;
  option subnet-mask 255.255.255.0;
  option domain-name-servers 10.0.101.253;
  host gw-01-service {
    hardware ethernet 02:00:0a:00:65:fe;
    fixed-address 10.0.101.254;
  }
  host ap-01-service {
    hardware ethernet 02:00:0a:00:65:0a;
    fixed-address 10.0.101.10;
  }
}

The administrative gateway should not allow forwarding so there is no need for the routers options on this subnet.

The client subnet should be the only one to declare a pool.

The rootfs' /etc/dhcp/dhclient.conf should be modified as follow:

send host-name = gethostname();
request subnet-mask, broadcast-address;

interface "service" {
  request
    routers,
    domain-name-servers, domain-search;
}

The rationale behind that being most of the LXC are considered as services and as such, should prefer the service interface to communicate. Also, multiple gateways aren't easily handled out of the box, so it's better to only setup one to avoid some RTNETLINK errors (and this is the reason why /etc/network/interfaces should only have one of them).

DNS

FIXME: the 10.in-addr.arpa should be edited to provide PTR.

Split-horizon facility is provided by Bind's zones to only setup one DNS server (but care should be taken as this not the most recommended setup).

/etc/bind/named.conf:

options {
  directory "/var/cache/bind";
  // rfc 1035
  auth-nxdomain no;
  // secure by default
  allow-transfer { none; };
  recursion no;
  minimal-responses yes;
  // minimal-any yes;
  // disable information leak through chaos
  version none;
  hostname none;
  server-id none;
  // listen
  listen-on { any; };
  listen-on-v6 { any; };
  // dnssec, default dnssec-validation auto;
  dnssec-enable yes;
  dnssec-validation yes;
  // log all queries
  querylog yes;
};

view "local" {
  match-clients { localhost; localnets; };
  // allow recursion locally
  recursion yes;

  // forward to google and don't try to resolve
  forwarders {
    8.8.8.8;
    8.8.4.4;
  };
  forward only;

  // authoritative for localhost and broadcast (rfc 1912)
  include "/etc/bind/named.conf.default-zones";
  // rfc 1918 zones to avoid forwarding
  include "/etc/bind/zones.rfc1918";

  //
  zone "client.lorn.space" { type master; file "/etc/bind/db.client.lorn.space"; };
  zone "service.lorn.space" { type master; file "/etc/bind/db.service.lorn.space"; };
  zone "administrative.lorn.space" { type master; file "/etc/bind/db.administrative.lorn.space"; };
  zone "lorn.space" { type master; file "/etc/bind/db.lorn.space"; };
};

view "external" {
  match-clients { any; };

  //
  zone "lorn.space" { type master; file "/etc/bind/db.lorn.space"; };
};

db.lorn.space would look like as follow:

$TTL 3600
@ IN SOA dns.lorn.space. root.lorn.space. (
  2017070501
  14400
  3600
  604800
  300
)

@ IN A 109.190.107.125
@ IN NS dns.lorn.space.
dns IN A 109.190.107.125
www IN A 109.190.107.125

Use named-checkconf and named-checkzone to verify the configuration files.

⚠️ **GitHub.com Fallback** ⚠️