Setup mini pc with two network cards, ipv6, dhcp and ip forwarding

I got myself a nice litte pc with two network cards. I want to divide my network to my provider and use virtual machines with ipv6 and ipv4. As operating system I use debian in command line only.

I don’t use my original ipv6 addresses in this manual

At first you have to get your “ipv6 präfix delegation” from your internet service provider. You find it in your router configuration. You need a network präfix lower than 64 to get more than one subnet in your environment. My isp got me 1234:1234:1234:1234::/62. 2 Bits of subnets or 4 subnets are allowed to create by myself.

First type in “ip a” to display your network configuration:

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 noprefixroute
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.59/24 brd 192.168.0.255 scope global dynamic enp0s8
       valid_lft 604427sec preferred_lft 604427sec
    inet6 1234:1234:1234:1234:aba1:abcd:abcd:abcd/64 scope global dynamic mngtmpaddr
       valid_lft 1627sec preferred_lft 1627sec
    inet6 fe80::1534:5432:1234:3212/64 scope link
       valid_lft forever preferred_lft forever

With the command “ip -br a” you got a nicer output:

lo               UNKNOWN        127.0.0.1/8 ::1/128
enp0s3           DOWN
enp0s8           UP             192.168.0.59/24 1234:1234:1234:1234:aba1:abcd:abcd:abcd/64 fe80::1534:5432:1234:3212/64

Every ipv6 address starts with “fe” or “fd” are local adresses and are genereated by the system. Do not change them.

Write down the ipv6 address of the card connected to the internet. In my case it’s the enp0s8 with the ipv6 address 1234:1234:1234:1234:aba1:abcd:abcd:abcd/64.

Next you need the gateway to the internet. Use the comman “ip route show”:

default via 192.168.0.1 dev enp0s8

192.168.0.0/24 dev enp0s8 proto kernel scope link src 192.168.0.59

But you need it for ipv6, do “ip -6 route show”:

....
fe80::/64 dev enp0s8 proto kernel metric 256 pref medium
default via fe80::1534:5432:1234:aaa9 dev enp0s8 proto ra metric 1024 expires 1798sec hoplimit 64 pref medium

Now we can set a fixed ipv4 and ipv6 address for our network card to the internet. Edit the networkfile by “nano /etc/network/interfaces” and change everything of your network card to fixed addresses like here. I got the nameserver from https://controld.com/free-dns but you can use yours:

# The primary network interface
allow-hotplug enp0s8

iface enp0s8 inet static
        address 192.168.0.59
        netmask 255.255.255.0
        gateway 192.168.0.1
        dns-nameservers 76.76.2.2 76.76.10.2

iface enp0s8 inet6 static
        address 1234:1234:1234:1234:aba1:abcd:abcd:abcd
        netmask 64
        gateway fe80::1534:5432:1234:aaa9
        autoconf 0
        dns-nameservers 2606:1a40::2 2606:1a40:1::2

I also changed the resolv.conf file “nano /etc/resolv.conf”:

nameserver 76.76.2.2
nameserver 76.76.10.2
nameserver 2606:1a40::2
nameserver 2606:1a40:1::2

Restart your network with “systemctl restart networking” and test your configuration with “dig -6 google.com”:

; <<>> DiG 9.18.19-1~deb12u1-Debian <<>> -6 google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64958
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             126     IN      A       142.250.184.238

;; Query time: 23 msec
;; SERVER: 1234:1234::2#53(2606:1a40::2) (UDP)
;; WHEN: Fri Feb 09 18:55:18 CET 2024
;; MSG SIZE  rcvd: 55

If everything is ok we configure the second card. Since I got four subnets I use the next number 1234:1234:1234:1235::/64 as my sub network. “nano /etc/network/interfaces” and add:

allow-hotplug enp0s3
iface enp0s3 inet static
        address 192.168.1.1
        netmask 255.255.255.0

iface enp0s3 inet6 static
        address 1234:1234:1234:1235::1
        netmask 64
        autoconf 0

Do a “systemctl restart networking” and check with “ip a” if everything is in place.

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 noprefixroute
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:76:d8:d5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet6 1234:1234:1234:1235::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::1534:5432:6666:7777/64 scope link
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.59/24 brd 192.168.0.255 scope global dynamic enp0s8
       valid_lft 604427sec preferred_lft 604427sec
    inet6 1234:1234:1234:1234:aba1:abcd:abcd:abcd/64 scope global dynamic mngtmpaddr
       valid_lft 1627sec preferred_lft 1627sec
    inet6 fe80::1534:5432:1234:3212/64 scope link
       valid_lft forever preferred_lft forever

Now we need a DHCP Server for the clients: “apt install isc-dhcp-server”. Ignore any error message.

Do “nano /etc/default/isc-dhcp-server” to let the dhcp only run on your internal network card and not on the internet card:

INTERFACESv4="enp0s3"
INTERFACESv6="enp0s3"

Edit the ipv4 settings: “nano /etc/dhcp/dhcpd.conf”

option domain-name "local";
option domain-name-servers 76.76.2.2,76.76.10.2;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
authoritative;
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.10 192.168.1.200;
  option routers 192.168.1.1;
}

Edit the ipv6 settings: “nano /etc/dhcp/dhcpd6.conf”

default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
allow leasequery;
option dhcp6.name-servers 2606:1a40::2,2606:1a40:1::2;
option dhcp6.domain-search "local";
#option dhcp6.preference 255;
option dhcp6.info-refresh-time 21600;

subnet6 1234:1234:1234:1235::/64 {
        range6 1234:1234:1234:1235::2 1234:1234:1234:1235:ffff:ffff:ffff:ffff;
}

Then restart the service with “systemctl restart isc-dhcp-server”. If you got a error, do “systemctl status isc-dhcp-server”

…
Feb 09 19:35:55 idefix dhcpd[1840]: than a configuration issue please read the section on submitting
…

and do with the number in the bracets: “journalctl _PID=1840”. Now you get detailed informations about the error.

Now activate IP forwarding by “nano /etc/sysctl.conf” and uncomment:

net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

Load the new settings: “sysctl –load /etc/sysctl.conf”

Install iptables with persistent tool: “apt install iptables iptables-persistent”. And “nano /etc/iptables/rules.v4” and “nano /etc/iptables/rules.v6”:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -j MASQUERADE
COMMIT

Load the iptables with: “iptables-restore < /etc/iptables/rules.v4” and “ip6tables-restore < /etc/iptables/rules.v6”

At least you need to install radvd service to anounce the clients the ipv6 gateway. “apt install radvd”. Do a “nano /etc/radvd.conf”:

interface enp0s3
{
        AdvSendAdvert on;
        prefix 1234:1234:1234:1235::/64
        {
        };
        route fe80::1534:5432:6666:7777/64
        {
        };
};

More infos you can find here https://man.archlinux.org/man/radvd.conf.5.en

Do a “systemctl restart radvd”.

“nano /etc/hosts”:

127.0.0.1       localhost
192.168.1.1     asterix.local   asterix

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
1234:1234:1234:1235::1  asterix.local asterix

“systemctl restart networking”

For the clients you have to edit “nano /etc/network/interfaces”:

allow-hotplug enp0s3
iface enp0s3 inet dhcp
iface enp0s3 inet6 dhcp

FINISHED!

To assign fixed addresses via dhcp you have to edit.

“nano /etc/dhcp/dhcpd.conf”:

host gamepc {
        option host-name "gamepc.local";
        hardware ethernet DD:12:34:AB:CC:DE;
        fixed-address 192.168.1.100;
}

“nano /etc/dhcp/dhcpd6.conf”:

host gamepc {
        hardware ethernet DD:12:34:AB:CC:DE;
        fixed-address6 1234:1234:1234:1235::100;
}