12

Is it at all possible to execute the iptables --list … command without being root?

Running it as non-root prints this:

$ iptables --list
iptables v1.4.21: can't initialize iptables table `filter': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.

If you must be root to list iptables, what is the reasoning behind that?  Is there a security concern with viewing the rules?  Is there a resource or service used by iptables --list that requires root access?

Obviously, modifying iptables firewall rules requires privileges.  I am asking about viewing them.


Instead of being root, is there a capability that could permit listing the rules?  Does iptables use netlink to interface with the kernel?  Because netlink(7) mentions that

Only processes with an effective UID of 0 or the CAP_NET_ADMIN capability may send or listen to a netlink multicast group.

Maybe that does not apply to iptables.

I am not sure whether this is the right way of doing it, but adding a capability to iptables does not let me list the rules, either:

bash-4.1$ echo $UID
2000
bash-4.1$ getcap /sbin/iptables-multi-1.4.7
/sbin/iptables-multi-1.4.7 = cap_net_admin+ep
bash-4.1$ /sbin/iptables-multi-1.4.7 main --list
FATAL: Could not load /lib/modules/3.10.0-514.21.1.el7.x86_64/modules.dep: No such file or directory
iptables v1.4.7: can't initialize iptables table `filter': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded. 

Here are some relevant questions:

Both provide workarounds, in my opinion, and do not discuss the fundamental reason behind the restriction.

3
  • Do those linked questions really include a workaround though? I see suggestions to just use root and/or to use sudo, but both of those would allow the users to also modify rules no?
    – jesse_b
    Commented Aug 10, 2017 at 1:15
  • As a workaround they suggest to wrap sudo iptables in a script or call iptables in a cron job by root. I thought of these as workarounds to fall back to the privileged user in a different way.
    – Hakan Baba
    Commented Aug 10, 2017 at 1:19
  • 1
    Yea, but your question has me thinking there is a good use case for more granular iptables permissions. The first thing I thought when I read this was low tier support personnel could need the ability to view firewall rules as part of initial troubleshooting on an incident but have no access to modify them. If you gave them sudo permissions you would be giving them way more than just view iptables. Even as one person suggested giving them permission to sudo a script could be problematic but that sounds like the closest thing so far.
    – jesse_b
    Commented Aug 10, 2017 at 1:23

4 Answers 4

14

It appears iptables needs both CAP_NET_RAW and CAP_NET_ADMIN to be able to read the tables. I tried

$ cp /usr/sbin/iptables ~/iptables  # note, it may be a symbolic link
$ sudo setcap CAP_NET_RAW,CAP_NET_ADMIN+ep  ~/iptables
$ ~/iptables  -nvL

and it was ok.

3
  • 2
    The true answer, for a huge class of problems Commented Jan 6, 2019 at 15:37
  • 1
    As of Linux 5.15 (and Ubuntu 22.04) I can run iptables -nvL with only the CAP_NET_ADMIN capability.
    – mpb
    Commented Jun 25, 2023 at 4:27
  • Ok... but CAP_NET_ADMIN allows "administration of IP firewall", so will allow you to write filter rules, and not just read them (YMMV; I haven't tried it). So this isn't an answer to the question, and is no better than just allowing everyone to run to run iptables without a password in the sudoers file. I think the answer has to be to add specific iptables -nvL/ufw status/etc rules to the sudoers file.
    – EML
    Commented May 31 at 10:43
11

Indeed, iptables uses the netlink interface to communicate with the kernel. It opens a netlink socket to xtables, then issues commands via this socket. Access control is performed when the socket is opened, not for individual commands, so the same permissions are required for listing and modifying rules. The only way to allow a user to list rules but not modify them is to give them a carefully-written setuid (or setcap) executable.

It would be nice if there was an interface to netfilter in /proc, but as far as I know the task of implementing it has never been completed.

1

Here's what I did:

$ cat iptables-list.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    if (setuid(0) != 0)
    {
        perror("setuid");
        return EXIT_FAILURE;
    }
    execl("/sbin/iptables", "iptables", "-L", "-n", NULL);
    perror("execl");
}
$ gcc -Wall -Werror -o iptables-list -s iptables-list.c
$ sudo mv iptables-list /sbin/iptables-list
$ sudo chown 0.0 /sbin/iptables-list
$ sudo chmod 4755 /sbin/iptables-list
$ ls -l /sbin/iptables-list
-rwsr-xr-x 1 root root 5552 Feb 23 08:14 /sbin/iptables-list
$ iptables-list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
...
3
  • 1
    Please note that the original question is for situations without root access: sudo is root access, and setuid bit requires root access too.
    – Samveen
    Commented Apr 5, 2022 at 2:23
  • 2
    @Samveen Indeed, but making a root-owned compiled program that holds the setuid bit and runs just one fixed command is (somewhat) more secure than using an administrator-prepared script with sudo, as it eliminates both the sudo and the shell from the chain, resulting in much less privileged code to run and so reduced potential of weaknesses. This is exactly the original recommended practice for granting a regular user limited access to some administrative function from back when sudo did not exist and/or administrators didn't just assume that shells are bullet-proof.
    – telcoM
    Commented Feb 7 at 5:01
  • on google colab, '!iptables-list' gives: 'execl: Operation not permitted'
    – b.g.
    Commented Feb 22 at 13:41
0

On Ubuntu 20.04.5 LTS Focal, I had to set CAP_DAC_READ_SEARCH, CAP_NET_RAW and CAP_NET_ADMIN capabilities.

If you set only CAP_NET_RAW and CAP_NET_ADMIN, you will see such error:

Fatal: can't open lock file /run/xtables.lock: Permission denied

Let’s see how it works:

$ sudo cp /usr/sbin/ip6tables ~/ip6tables

$ sudo setcap cap_net_admin,cap_net_raw+ep ./ip6tables # not enough caps
$ ./ip6tables -nvL
Fatal: can't open lock file /run/xtables.lock: Permission denied

# CAP_NET_RAW + CAP_NET_ADMIN + CAP_DAC_READ_SEARCH capabilities
$ sudo setcap cap_dac_read_search,cap_net_admin,cap_net_raw+ep ./ip6tables 
$ ./ip6tables -nvL # works fine
Chain INPUT (policy ACCEPT 1813K packets, 4509M bytes)
=== /// ===

Also, please note if you are trying to run a program and executing ip6tables as a child process, then you have to pass required capabilities to such child process.

For Golang, please see this pr and this code

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .