IPv6
IPv6 implementation on Koozali SME Server
Some notes on how we can implement IPv6 on Koozali SME Server
This is a massive task and needs careful consideration and a lot of work.
Initial bug: https://bugs.koozali.org/show_bug.cgi?id=6393
Feel free to add notes and comments.
Commentary
As IPv4 address availability has decreased, the world is slowly starting to use IPv6.
A fundamental block to adoption of IPv6 has been the lack of backwards compatibility. Yes, you could go full IPv6 only, assuming all your devices can handle it, but as most of the world still runs IPv4 you have to manage that.
Essentially every service and app has to be written to allow for both IPv4 AND IPv6. aka 'Dual Stack'.
That means duplicating a lot of work, and due to the nature of IPv6 - it was not designed to handle NAT, and every device is meant to have a routable public IP - this means added complexity and security considerations. That makes it more difficult for Koozali in Server/Gateway mode.
Carriers have found it easier to use CGNAT - double NAT - than deal with the issue of rolling out IPv6.
Some countries have rolled IPv6 out, some are in the process, and many have not at all.
Even where IPv6 has been rolled out, not all ISPs offer it.
IPv6 has been around for 25 years and is still a very long way from widespread adoption. It may well be another 25 years before the world is fully IPv6, and IPv4 will still exist for a long time come thereafter.
List of areas to be considered
Config entries
There are a couple of instances where a key is already used:
config show IPv6
We should use this as the basis for IPv6 settings.
IP addresses
I have no IPv6 from my provider so set up a 6to4 tunnel account with Hurricane:
You can set up a free account and obtain a /64block
The following testing was done with a server in server only mode as this is the easier scenario.
My server is behind a Mikrotik router. I first set up the Mikrotik to handle the IPv6. Then I worked on the server.
The server will pick up an IPv6 address automatically from the tunnel via the router. It will need further configuration for SME to handle the tunnel instead of the router. However, this is sufficient for basic testing.
Remember that IPv6 address are public facing. I have not done any work on firewalling.
Some other brief thoughts:
- Tunneled 6to4
- Native IPv6 block from ISP
- DHCP/DNS in Koozali
- Routed using public IP and private address space?
Enable networking
IPv6 currently disabled.
Get your Gateway IP "Server IPv6 Address:" and set it here:
IPv6=service status=enabled Gateway=2001:470:79c1:5ff::1
This seems to get it started:
mkdir -p /etc/e-smith/templates-custom/etc/sysctl.conf nano /etc/e-smith/templates-custom/etc/sysctl.conf/net.ipv6
{ if ( ($IPv6{status} || 'disabled') ne "enabled" ) { $OUT .= "# IPv6 is disabled\n"; $OUT .= "net.ipv6.conf.all.disable_ipv6 = 1\n"; $OUT .= "net.ipv6.conf.default.disable_ipv6 = 1\n"; } else { $OUT .= "# IPv6 is enabled\n"; $OUT .= "net.ipv6.conf.all.disable_ipv6 = 0\n"; $OUT .= "net.ipv6.conf.default.disable_ipv6 = 0\n"; } }
mkdir -p /etc/e-smith/templates-custom/etc/sysconfig/network-scripts/ifcfg-ethX nano /etc/e-smith/templates-custom/etc/sysconfig/network-scripts/ifcfg-ethX/60IPV6
{ if ($IPv6{'status'} eq "enabled") { $OUT .= "IPV6INIT=yes"; $OUT .= "IPV6_AUTOCONF=yes"; $OUT .= "IPV6_DEFROUTE=yes"; $OUT .= "IPV6_PEERROUTES=yes"; $OUT .= "IPV6_FAILURE_FATAL=yes"; $OUT .= "DNS0=2001:4860:4860::8888"; # Google DNS - you may want to change them!! $OUT .= "IPV6_PRIVACY=no"; } else { return "IPV6INIT=no"; }
mkdir -p /etc/e-smith/templates-custom/etc/sysconfig/network-scripts/route-ethX nano /etc/e-smith/templates-custom/etc/sysconfig/network-scripts/route-ethX/08Gateway
{ return "" unless (defined $GatewayIP && ( ($SystemMode eq 'serveronly' && $InternalInterface{Name} eq $THIS_DEVICE ) || ($ExternalInterface{Name} eq $THIS_DEVICE) )); $OUT .= "$GatewayIP dev $THIS_DEVICE\n"; $OUT .= "default via $GatewayIP dev $THIS_DEVICE\n"; if ($IPv6{'status'} eq "enabled") { $OUT .= "$IPv6{'Gateway' dev $THIS_DEVICE\n"; $OUT .= "default via $IPv6{'Gateway'} dev $THIS_DEVICE\n"; } }
signal-event post-upgrade;signal-event reboot.
You should get an automatic IP assigned from your Hurricane pool.
ip addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether ca:94:35:c2:d6:e1 brd ff:ff:ff:ff:ff:ff inet 192.168.10.212/24 brd 192.168.10.255 scope global eth0 valid_lft forever preferred_lft forever inet6 2001:470:79c1:5ff:c894:35ff:fec2:d6e1/64 scope global mngtmpaddr dynamic valid_lft 2591951sec preferred_lft 604751sec inet6 fe80::c894:35ff:fec2:d6e1/64 scope link valid_lft forever preferred_lft forever
Try a ping6
ping6 ipv6.google.com PING ipv6.google.com(mad06s10-in-x0e.1e100.net (2a00:1450:4003:808::200e)) 56 data bytes 64 bytes from mad06s10-in-x0e.1e100.net (2a00:1450:4003:808::200e): icmp_seq=1 ttl=117 time=56.2 ms 64 bytes from mad06s10-in-x0e.1e100.net (2a00:1450:4003:808::200e): icmp_seq=2 ttl=117 time=55.5 ms
See the bug for some more templates that we might be able to use.
Firewall
ip6tables
Server/Gateway
Routing
DNS/DHCPD
DNS (PiHole in a docker container?)
Services
List of other affected services and vague efforts to get IPv6 running for them.
httpd
smbd
mysql (already listens for tcp6/3313)
ntpd (already listens on udp6/123)
sshd as below
ldap as below
=====SSH===== (bad hack here so careful as this may open your server up to remote access)
mkdir /etc/e-smith/templates-custom/etc/ssh/sshd_config nano /etc/e-smith/templates-custom/etc/ssh/sshd_config/15ListenAddress
{ my $access = $sshd{'access'} || 'private'; my $address = ($access eq "public") ? "0.0.0.0" : "$LocalIP"; # Not sure how we allow for 'Local IP only' with IPv6 # Possibly limit it to the local subnet? if ($IPv6{status} eq "enabled") { $OUT .= "ListenAddress ::\n"; $OUT .= "ListenAddress $address\n"; } else { $OUT .= "ListenAddress $address\n"; } }
signal-event remoteaccess-update
Then try:
ssh root@2001:470:1f13:3ff:2a9:b700:fe99:792c
LDAP
mkdir -p /etc/e-smith/templates-custom/etc/sysconfig/slapd nano /etc/e-smith/templates-custom/etc/sysconfig/slapd/40OPTIONS
Add this code:
{ { # Any custom options #SLAPD_OPTIONS=" -4 -d { $ldap{LogLevel} || 256 } -s 0 " my $slapdOptions = "#Test"; my $logLevel = $ldap{LogLevel} || 256; if ($IPv6{'status'} eq "enabled") { $slapdOptions = "SLAPD_OPTIONS=\"-d $logLevel -s 0\" " ; } else { $slapdOptions = "SLAPD_OPTIONS=\"-4 -d $logLevel -s 0\" " ; } $OUT .= "# Any custom options\n"; $OUT .= "$slapdOptions\n"; }
Edited the unit file /usr/lib/systemd/system/ldap.service to comment out the Environment line and just leave the config file
#Environment="SLAPD_URLS=ldap:/// ldaps:/// ldapi:///" "SLAPD_OPTIONS=-4 -d 256 -s 0" EnvironmentFile=/etc/sysconfig/slapd
systemctl daemon-reload systemctl restart ldap.service
However, /usr/sbin/cpu is not IPv6 aware and is unmaintained.
We can bypass this and force IPv4 by editing:
/etc/cpu-system.conf
Modify the template and change localhost to 127.0.0.1
[LDAP] LDAP_HOST = 127.0.0.1 LDAP_PORT = 389
Other notes
Use in a web browser
https://[2001:470:1f13:3ff:2a9:b700:fe99:792c]
Ping
ping6 2001:470:1f13:3ff:2a9:b700:fe99:792c