Remove support for ip6tables

The ip6tables frameworks has been deprecated for quite a while now, as
it has been replaced by nftables. On modern distributions, rules added
with ip6tables are just converted to nftables rules and are added to an
ip6tables compatibility table there. This changed the name of the kernel
modules, breaking ip6tables auto-detection (cf. issues #42 and #44).

Unfortunately, due to the way nftables works, these rules can no longer
be relied upon to ensure the CLAT traffic is allowed. This is due to the
fact that in nftables, *all* chains that hook into a packet's path must
return an «accept» verdict in order for the packet to be ultimately
accepted, while it is enough for a single chain to return a «drop»
verdict in order for the packet to be dropped.

That means that the rules that accepts CLAT traffic might be overridden
by a «default drop» rule added to another chain in another table, e.g.,
by firewalld or similar local firewall frameworks. See #23 for an
example of this.

On the other hand, if there is no drop rule anywhere, the rules added by
clatd are superfluous to begin with, as the default kernel behaviour is
to accept the packages.

Therefore just remove support for ip6tables entirely. Users of
firewalld, ufw,  or similar local firewall frameworks will need to make
sure that rules are added in those frameworks that permit the CLAT
traffic, e.g., by using `script-up`, like so for ufw:

```
script-up=ufw route allow in on $clat_dev out on $plat_dev
```

Native support for adding rules to the most common local firewall
frameworks might be added in the future.

Closes #44 (no longer applicable).
This commit is contained in:
Tore Anderson
2025-02-02 09:00:39 +01:00
parent 6342488889
commit 6a582bf1e4
3 changed files with 7 additions and 51 deletions

View File

@@ -23,8 +23,8 @@ install:
installdeps:
# .deb/apt-get based distros
if test -x "$(APT_GET)"; then $(APT_GET) -y install perl-base perl-modules libnet-ip-perl libnet-dns-perl libio-socket-ip-perl iproute2 iptables tayga; fi
if test -x "$(APT_GET)"; then $(APT_GET) -y install perl-base perl-modules libnet-ip-perl libnet-dns-perl libio-socket-ip-perl iproute2 tayga; fi
# .rpm/DNF/YUM-based distros
if test -x "$(DNF_OR_YUM)"; then $(DNF_OR_YUM) -y install perl perl-Net-IP perl-Net-DNS perl-IO-Socket-IP perl-File-Temp iproute iptables; fi
if test -x "$(DNF_OR_YUM)"; then $(DNF_OR_YUM) -y install perl perl-Net-IP perl-Net-DNS perl-IO-Socket-IP perl-File-Temp iproute; fi
# If necessary, try to install the TAYGA .rpm using dnf/yum. It is unfortunately not available in all .rpm based distros (in particular CentOS/RHEL).
if test -x "$(DNF_OR_YUM)" && test ! -x "$(TAYGA)"; then $(DNF_OR_YUM) -y install tayga || echo "ERROR: Failed to install TAYGA using dnf/yum, the package is probably not included in your distro. Try enabling the EPEL repo <URL: https://fedoraproject.org/wiki/EPEL> and try again, or install TAYGA <URL: http://www.litech.org/tayga> directly from source."; exit 1; fi

View File

@@ -232,12 +232,6 @@ encountered will be used.
Path to the B<ip> binary from the iproute2 package available at
L<https://www.kernel.org/pub/linux/utils/net/iproute2>. Required.
=item B<cmd-ip6tables=path> (default: assume in $PATH)
Path to the B<ip6tables> binary from the netfilter package available at
L<http://netfilter.org>. Only required for adding ip6tables rules
(see the B<ip6tables-enable> configuration setting).
=item B<cmd-tayga=path> (default: assume in $PATH)
Path to the B<tayga> binary from the TAYGA package available at
@@ -254,22 +248,11 @@ forwarding.
All sysctls that are modified will be restored to their original values when
B<clatd> is shutting down.
=item B<ip6tables-enable=bool> (default: see below)
Controls whether or not B<clatd> should insert ip6tables rules that permit the
forwarding of IPv6 traffic between the CLAT and PLAT devices. Such forwarding
must be permitted for B<clatd> to work correctly. Any rules added will be
removed when B<clatd> is shutting down.
The default is I<yes> if the ip6tables_filter kernel module is loaded, I<no>
if it is not.
=item B<plat-dev> (default: auto-detect)
Which network device is facing the PLAT (NAT64). By default, this is
auto-detected by performing a route table lookup towards the PLAT prefix.
This setting is used when setting up generating the CLAT IPv6 address, and
when setting up ip6tables rules and Proxy-ND entries.
auto-detected by performing a route table lookup towards the PLAT prefix. This
setting is used when generating the CLAT IPv6 address and Proxy-ND entries.
=item B<plat-prefix> (default: auto-detect)
@@ -441,7 +424,7 @@ SOFTWARE.
=head1 SEE ALSO
ip(8), ip6tables(8), tayga(8), tayga.conf(5)
ip(8), tayga(8), tayga.conf(5)
RFC 6052, RFC 6145, RFC 6146, RFC 6877, RFC 7050, RFC 7335 RFC 7755, RFC 7756,
RFC 7757

31
clatd
View File

@@ -41,10 +41,8 @@ $CFG{"clat-v4-addr"} = "192.0.0.1"; # from RFC 7335
$CFG{"clat-v6-addr"} = undef; # derive from existing SLAAC addr
$CFG{"dns64-servers"} = undef; # use system resolver by default
$CFG{"cmd-ip"} = "ip"; # assume in $PATH
$CFG{"cmd-ip6tables"} = "ip6tables"; # assume in $PATH
$CFG{"cmd-tayga"} = "tayga"; # assume in $PATH
$CFG{"forwarding-enable"} = 1; # enable ipv6 forwarding?
$CFG{"ip6tables-enable"} = undef; # allow clat<->plat traffic?
$CFG{"plat-dev"} = undef; # PLAT-facing device, default detect
$CFG{"plat-prefix"} = undef; # detect using DNS64 by default
$CFG{"plat-fallback-prefix"} = undef; # fallback prefix if no prefix is found
@@ -387,8 +385,8 @@ sub get_plat_prefix {
#
# This function figures out which network interface on the system faces the
# PLAT/NAT64. We need this when generating an IPv6 address for the CLAT, when
# installing Proxy-ND entries, and when setting up ip6tables rules.
# PLAT/NAT64. We need this when generating an IPv6 address for the CLAT and
# when installing Proxy-ND entries.
#
sub get_plat_dev {
d("get_plat_dev(): finding which network dev faces the PLAT");
@@ -596,7 +594,6 @@ my $cleanup_zero_forwarding_sysctl; # zero forwarding sysctl if set
my @cleanup_accept_ra_sysctls; # accept_ra sysctls to be reset to '1'
my $cleanup_zero_proxynd_sysctl; # zero proxy_ndp sysctl if set
my $cleanup_remove_proxynd_entry, # true if having added proxynd entry
my $cleanup_remove_ip6tables_rules; # true if having added ip6tables rules
my @cleanup_restore_v4_defaultroutes; # temporarily replaced defaultroutes
sub cleanup_and_exit {
@@ -637,14 +634,6 @@ sub cleanup_and_exit {
cmd(\&w, cfg("cmd-ip"), qw(-6 neighbour delete proxy), cfg("clat-v6-addr"),
"dev", cfg("plat-dev"));
}
if(defined($cleanup_remove_ip6tables_rules)) {
d("Cleanup: Removing ip6tables rules allowing traffic between the CLAT ",
"and PLAT devices");
cmd(\&w, cfg("cmd-ip6tables"), qw(-D FORWARD -i), cfg("clat-dev"),
"-o", cfg("plat-dev"), qw(-j ACCEPT));
cmd(\&w, cfg("cmd-ip6tables"), qw(-D FORWARD -i), cfg("plat-dev"),
"-o", cfg("clat-dev"), qw(-j ACCEPT));
}
for my $rt (@cleanup_restore_v4_defaultroutes) {
d("Cleanup: Restoring temporarily replaced IPv4 default route");
cmd(\&w, cfg("cmd-ip"), qw(-4 route add), @{$rt});
@@ -763,9 +752,6 @@ p("Device facing the PLAT: ", $CFG{"plat-dev"});
$CFG{"clat-v6-addr"} ||= get_clat_v6_addr();
p("Using CLAT IPv4 address: ", $CFG{"clat-v4-addr"});
p("Using CLAT IPv6 address: ", $CFG{"clat-v6-addr"});
if(!defined($CFG{"ip6tables-enable"})) {
$CFG{"ip6tables-enable"} = -e "/sys/module/ip6table_filter" ? 1 : 0;
}
if(!$CFG{"v4-defaultroute-advmss"} and cfgint("v4-defaultroute-mtu")) {
$CFG{"v4-defaultroute-advmss"} = $CFG{"v4-defaultroute-mtu"} - 40;
}
@@ -850,19 +836,6 @@ if(cfgbool("forwarding-enable")) {
}
}
#
# Add ip6tables rules permitting traffic between the PLAT and the CLAT
#
if(cfgbool("ip6tables-enable")) {
p("Adding ip6tables rules allowing traffic between the CLAT ",
"and PLAT devices");
cmd(\&w, cfg("cmd-ip6tables"), qw(-I FORWARD -i), cfg("clat-dev"),
"-o", cfg("plat-dev"), qw(-j ACCEPT));
cmd(\&w, cfg("cmd-ip6tables"), qw(-I FORWARD -i), cfg("plat-dev"),
"-o", cfg("clat-dev"), qw(-j ACCEPT));
$cleanup_remove_ip6tables_rules = 1;
}
#
# Enable ND proxy for the CLAT's IPv6 address on the interface facing the PLAT
#