ufw

ufw fails to load if kernel does not support IPv6

Bug #2025532 reported by Forza
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
ufw
Opinion
Medium
Unassigned

Bug Description

I am running small VMs based on Alpine Linux with a custom kernel that has IPV6 compiled out.

UFW is failing to load during boot with the following message:

```
 * Starting ufw ...
ip6tables-restore v1.8.9 (nf_tables):
line 2: TABLE_ADD failed (Not supported): table filter
line 2: CHAIN_ADD failed (No such file or directory): chain INPUT
line 2: CHAIN_UPDATE failed (No such file or directory): chain INPUT
line 3: TABLE_ADD failed (Not supported): table filter
line 3: CHAIN_ADD failed (No such file or directory): chain FORWARD
line 3: CHAIN_UPDATE failed (No such file or directory): chain FORWARD
line 4: TABLE_ADD failed (Not supported): table filter
line 4: CHAIN_ADD failed (No such file or directory): chain OUTPUT
line 4: CHAIN_UPDATE failed (No such file or directory): chain OUTPUT
line 5: TABLE_ADD failed (Not supported): table filter
line 5: RULE_APPEND failed (No such file or directory): rule in chain INPUT
line 6: TABLE_ADD failed (Not supported): table filter
line 6: RULE_APPEND failed (No such file or directory): rule in chain OUTPUT

Problem loading ipv6 (skipping)
 * Failed to start ufw.
 [ !! ]
 * ERROR: ufw failed to start
 * Starting dropbear ...
 [ ok ]
 * Starting QEMU Guest Agent ...
 [ ok ]
 * Starting busybox watchdog ...
 [ ok ]
```

Upon examining the code I found the culprit is the following test in `/var/lib/ufw-init-functions`:
https://git.launchpad.net/ufw/tree/src/ufw-init-functions?h=debian/master#n142

```
if ip6tables -L INPUT -n >/dev/null 2>&1; then
                # IPv6 support disabled but available in the kernel, so
                # default DROP and accept all on loopback
                delete_chains 6 || error="yes"

                printf "*filter\n"\
":INPUT DROP [0:0]\n"\
":FORWARD DROP [0:0]\n"\
":OUTPUT DROP [0:0]\n"\
"-A INPUT -i lo -j ACCEPT\n"\
"-A OUTPUT -o lo -j ACCEPT\n"\
"COMMIT\n" | ip6tables-restore || error="yes"

                if [ "$error" = "yes" ]; then
                    out="${out}\nProblem loading ipv6 (skipping)"
                fi
            fi
```
The test uses ip6tables to determine if IPV6 is enabled in the kernel. But on this system, `ip6tables` does not return an error code, which makes the script wrongly try to load the DROP rules with `ip6tables-restore`

Example:
```
### No IPv6 support is available:

bc-ssh:~# ll /proc/net/tc*
-r--r--r-- 1 root root 0 Jul 1 14:52 /proc/net/tcp
(no tcp6 file)

bc-ssh:~# ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:94:E0:81
          inet addr:192.168.0.222 Bcast:192.168.0.255 Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
          RX packets:374 errors:0 dropped:2 overruns:0 frame:0
          TX packets:109 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:42958 (41.9 KiB) TX bytes:15419 (15.0 KiB)

lo Link encap:Local Loopback
          inet addr:127.0.0.1 Mask:255.0.0.0
          UP LOOPBACK RUNNING MTU:65536 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

## ip6tables will emit error codes
bc-ssh:~# ip6tables && echo true
ip6tables v1.8.9 (nf_tables): no command specified
Try `ip6tables -h' or 'ip6tables --help' for more information.

## however no error code when listing rules:
bc-ssh:~# ip6tables -L INPUT -n && echo true
Chain INPUT (policy ACCEPT)
target prot opt source destination
true
```
ip6tables v1.8.9 (nf_tables)
ufw 0.36.2
kernel 6.3.10

Instead of relying on `ip6tables` it might be better to use some other method to determine the ipv6 support, or simply give a warning instead of failing to load the init.d service?

For example by using `sysctl` or files in `/sys/`?

Tags: ipv6
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Thanks for the bug report. Sorry I just saw this now.

Changed in ufw:
status: New → Triaged
importance: Undecided → Medium
Revision history for this message
stacktrust (stacktrust) wrote :

Attached patch tested successfully with UFW on a kernel without IPv6 support, detected via 'cat /proc/net/if_inet6'.

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Thanks for the patch.

I'm uncomfortable applying as is because (AIUI) /proc/net/if_inet6 won't exist on kernels where ipv6 is compiled as a module but isn't loaded yet. ufw starts very in boot before network interfaces are up and I suspect if this patch were applied there might be times when ufw is started, would detect /proc/net/if_inet6 isn't there, would fail to put the rules in place, only to have the ipv6 module loaded after when interfaces come up. On a system like yours where you've removed ipv6 support and you know it, this is fine but it wouldn't be good for ufw in general.

I can say that ufw operates fine when the kernel is booted with ipv6.disable=1. It seems like you perhaps left out too much of your custom kernel? Or, left too much in since 'ip6tables -L INPUT -n' is showing that the input chain is available?

I've made this change to ufw to give a better diagnostic for this situation: https://git.launchpad.net/ufw/commit/?id=a024e6824c777518ad463abde4cdfc00ee3a4e20

I'm going to close this for now since ufw is designed to be run on general purpose systems with more or less standard kernel config and so as it stands, this falls outside of the project's scope. I suggest that you continue to patch ufw for your needs or explore your kernel config.

Thanks again for your report.

Changed in ufw:
status: Triaged → Opinion
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.