Jetson Nano Jetpack 4.2 firewall broken - possible kernel compilation issue missing iptables modules

This is a fresh copy of ubuntu on my nVidia Jetson Nano, and I am trying to add the following rule to block network access for user 1001.

sudo iptables -A OUTPUT ! -o lo -m owner --uid-owner 1001 -j DROP

I get the following error:

iptables: No chain/target/match by that name.

Here is what I tried that works(YES) and does not work(NOT)

  1. YES - Remove the match criteria and replace with some other condition like source or target
  2. YES - On another similar installation on raspberry pi
  3. NOT - Change chain or target to INPUT or ACCEPT etc…
  4. NOT - Use a different user
  5. NOT - Try using user names instead of user ID
  6. NOT - Try a different match like --gid-owner
  7. NOT - Flushing the tables, restarting the PC etc
  8. NOT - Removed the ! -o lo from the command above

This is beyond me, I really have tried a lot of things and read through a number of posts with the same error - most of the times they are trying to do something complex - yet this is simple and works on my similar raspberry pi install.

After research it seems the match extension is somehow broken. But I am not sure how to check. This seems specific to this build of Ubuntu.

EDIT: See below - some standard ubuntu config files I am looking for are also missing from this install, like boot/config-

I completely cleaned and reinstalled the jetpack on the nano and this was the first command I ran - and it still did not work :(

There seems to be some kind of broader issue with how the kernel is compiled and iptables extensions here.

Any thoughts on this, can someone else test this and see if it works for them?

It seems like the one thing you haven’t tried is removing the exclamation mark from your command - try

sudo iptables -A OUTPUT -o lo -m owner --uid-owner 1001 -j DROP

Note that you’re doing this against the loopback interface (lo) where your Nano is likely connected via Ethernet (eth0) unless you’ve added wi-fi.

HTH,
Simon

Hi,
I have tried that - #8 above. Removed the interface as well and also tried using eth0. I have isolated the error to the match extension thus far. Removing everything else in the command does not help.

PS. Just to be doubly sure, I also just typed your command again and it gave me the same error.

Looks like this issue has been there for long time. I just tried it in rel-28.2 (TX2) and it also cannot work. I will file an internal issue for it.

Thank you, a broken firewall seems to be a very critical security issue to me - I am surprised nobody else noticed this.

I am continuing to investigate this in the meantime. Here is more that I found:

  1. The config file in boot does not exist: running the command ``` grep CONFIG_NETFILTER_XT_MATCH /boot/config-$(uname -r) ``` gives the error ``` grep: /boot/config-4.9.140-tegra: No such file or directory ```
  2. The module ipt_owner is not there in the kernel. Running ``` sudo modinfo ipt_owner ``` gives the error ``` modinfo: ERROR: Module ipt_owner not found. ```

    and trying to load it with

    sudo modprobe ipt_owner
    

    gives the error

    modprobe: FATAL: Module ipt_owner not found in directory /lib/modules/4.9.140-tegra
    

    Which gives me a sense of where the module is supposed to be found.

  3. Hopefully this helps whoever is looking into this. Would love to see a resolution here on how to get the firewall working properly.

I think most embedded developers are focused primarily on getting something out the door with security as an afterthought. I am surprised but not suprised nobody bothered to try a ufw enable. Thank you looking into this and thank you for caring about security.

Please enable NETFILTER_XT_MATCH_OWNER in the defconfig as below.

diff --git a/arch/arm64/configs/tegra_defconfig b/arch/arm64/configs/tegra_defconfig
index 53f712a..2d3541a 100644
--- a/arch/arm64/configs/tegra_defconfig
+++ b/arch/arm64/configs/tegra_defconfig
@@ -167,6 +167,7 @@ CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m

Hey, this does not appear to work on Jetson Nano. I could not find any file called tegra_defconfig anywhere, or a folder with path arch/arm64/config or variations thereof anywhere on the system. Tried various combinations of

sudo find / -name <substring> | grep <substring>

to locate some kind of a combination of file/folders you mentioned but none exist. Searching the internet did not help. The closest things I could find are:

/usr/src/linux-headers-4.9.140-tegra-ubuntu18.04_aarch64/kernel-4.9/tools/perf/arch/arm64
/usr/src/linux-headers-4.9.140-tegra-ubuntu18.04_aarch64/kernel-4.9/arch/arm64
/usr/src/linux-headers-4.9.140-tegra-linux_x86_64/kernel-4.9/tools/perf/arch/arm64
/usr/src/linux-headers-4.9.140-tegra-linux_x86_64/kernel-4.9/arch/arm64

But that did not help as the config folders do not exist there.

Please download the kernel source from our download center and follow the L4T document guide to rebuild the kernel.

FYI, defconfigs are all part of full kernel source (dev headers do not include this). A better config is if you take your current working and running system without modifications and save a copy of “/proc/config.gz”. Other than CONFIG_LOCALVERSION this is an exact match to the current running system. You do not have that guarantee with any defconfig.

I don’t have enough expertise to easily follow the instructions and recompile the kernel without enormous time spent. Is this something that is expected to be fixed in the future? Would like to know to plan accordingly.

I don’t think this would take you too much effort… Please just download the kernel source and follow the guide in L4T document.

Usually you’ll have to wait 4~6 months for next release.

So, I’ve rebuilt the kernel on my host following the documentation. Here is a paste from my host terminal showing the kernel folder:

(/usr/bin/aarch64-linux-gnu-) [username@hostname] -- [~/Dev/nano/jetpack/Linux_for_Tegra/kernel]
 $ ls -la
total 295828
drwxr-xr-x 3 username username      4096 May 22 14:01 .
drwxr-xr-x 8 username username      4096 May 22 13:07 ..
drwxr-xr-x 3 username username      4096 May 22 13:45 dtb
-rwxr-xr-x 1 username username    856213 Mar 13 00:45 dtc
-rw-r--r-- 1 username username  34441224 May 22 13:43 Image
-rw-r--r-- 1 username username  17893905 Mar 13 00:46 kernel_headers.tbz2
-rw-r--r-- 1 username username 249713112 May 22 14:00 kernel_supplements.tbz2
-rw-r--r-- 1 username username     18385 Mar 13 00:45 LICENSE
-rw-r--r-- 1 username username     17992 Mar 13 00:45 LICENSE.dtc
-rwxr-xr-x 1 username username      3443 Mar 13 00:45 nv-enable-hard-coded-kernel-boot-display-mode.sh

My question is: now that i’ve built the kernel, modules and, copied new files into the dtb folder, how might I got about packaging an image for flashing that can be written directly to an sd card of any size? I assume there is documentation, but i’m not currently finding it. A link would be very helpful.

Edit: so I found create-jetson-nano-sd-card-image.sh and I’m guessing that’s the script I need. The only thing I am missing now is a revision id for my board. I would guess 100 (dtb=“a01”) rather than 200 (dtb="a02), but I’m not entirely sure which I am supposed to use for dev nano.

Edit: so I looked underneath the module. It ends with -A02. I’m going to try flashing with that.

Edit: it flashed, booted, same issue with stock image where it hangs at unattended upgrades but it got past it. Logged in. Image expanded to size of the card without issue on first boot. Apt-get appears to work. Will continue to update here and see if the firewall works. I haven’t tried ufw enable yet but will after updates finish.

So everything works, but strangely, ufw has to be started twice to do anything.

This is from a ssh session:

test@custom-nano:~$ uname -a
Linux custom-nano 4.9.140+ #1 SMP PREEMPT Wed May 22 13:38:55 GMT 2019 aarch64 aarch64 aarch64 GNU/Linux
test@custom-nano:~$ sudo ufw enable
[sudo] password for test: 
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
ERROR: problem running ufw-init
ip6tables-restore: line 142 failed

Problem running '/etc/ufw/before6.rules'

test@custom-nano:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
test@custom-nano:~$ exit
logout
Connection to test-nano closed.
[username@hostname] -- [~] 
 $ ssh test@test-nano
(it hangs here trying to connect)

So I sucessfully cut myself off and the firewall works. Any ideas why I have to start it twice?

Edit: the enable does survive a reboot so all works, apart from that one error starting it the manually the first time.

that’s great @mdegans.

Are you able to use iptables extensions and filter by user?

Tbh, I am not very experienced with iptables. I usually use the ufw frontend and allow specific hosts to specific services. I didn’t know it was possible to restrict to users (at least outside of say, “match group foo etc…” in /etc/ssh/sshd_config, if that’s what you mean).

If you tell me what to run to test, I can do that.

Edit: Found it in your OP. Will try that later for a new user. Neat. I didn’t know that was possible.

It just werks.

block@custom-nano:~$ ping google.com
PING google.com ({local google ip here}) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
^C

Note: this doesnt’ seem to block incoming connections via ssh to the user, which makes sense since sshd only runs as root (without a lot of hacking).