Run python-iptables (iptc) as non-root user

478 Views Asked by At

I am trying to run the python-iptables as a non-root user.

My script is test.py:

import iptc
import os

uid = os.getuid()
print("Real user ID of the current process:", uid)

table = iptc.Table(iptc.Table.FILTER)
print("Table is:".format(table))

I tried:

  1. Giving the capability CAP_NET_ADMIN to /usr/bin/python2.7 (outcome is: $ getcap /usr/bin/python2.7 /usr/bin/python2.7 = cap_net_admin+eip ) and executing /usr/bin/python2.7 ./test.py as described in: Python Scapy sniff without root
  2. Compiling and running with ambient capabilities as defined in: https://gist.github.com/tomix86/32394a43be70c337cbf1e0c0a56cbd8d and executing ./ambient -c '12' /usr/bin/python2.7 ./test.py
  3. I haven't yet tested with python-prctl but I soon plan to as described in: Unable to get CAP_CHOWN and CAP_DAC_OVERRIDE working for regular user

The logs are:

('Real user ID of the current process:', 1000)
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    table = iptc.Table(iptc.Table.FILTER)
  File "/usr/lib64/python2.7/site-packages/iptc/ip4tc.py", line 1566, in __new__
    obj._init(name, autocommit)
  File "/usr/lib64/python2.7/site-packages/iptc/ip4tc.py", line 1582, in _init
    self.refresh()
  File "/usr/lib64/python2.7/site-packages/iptc/ip4tc.py", line 1619, in refresh
    self.strerror()))
iptc.ip4tc.IPTCError: can't initialize filter: Permission denied (you must be root)

My kernel is:

$ uname -r
4.4.224-1.el7.elrepo.x86_64

My python version is:

Python 2.7.5

My python-iptables version is:

python-iptables            0.12.0

I can successfully run "iptables -L" as a non-root user but I cannot successfully run iptc python commands as a non-root user.

Is there any other way to give my python script capabilities or is it related to the iptc code?

Could it be failing because it requires additional capabilities?

2

There are 2 best solutions below

1
Hammad Ali Butt On

run python with sudo or run this python under superuser credentials. Because iptables requires (sudo) superuser credentials.

for example: sudo python test.py

0
NJL On

iptc is not shell'ing out to run iptables - it's loading the c-bindings directly. As the script is calling python underneath, you have to give python these capabilities directly.

Giving capabilities to python system-wide is not a good idea(tm). Making a local-copy of python runnable only by the user, with the additional capabilities of cap_raw/net will do the trick.

njl@mymachine:~/myproject $ which python3
/home/njl/bin/python3

njl@mymachine:~/myproject $ getcap ~/bin/python3
/home/njl/bin/python3 cap_net_admin,cap_net_raw=ep

njl@mymachine:~/myproject $ ls -l ~/bin/python3
-rwx------ 1 njl njl 4703672 Jan  7 21:18 /home/njl/bin/python3
njl@mymachine:~/myproject $ ./demo.py
{'INPUT': [], 'FORWARD': [], 'OUTPUT': []}

Sample Code:

#!/usr/bin/env python3
import iptc

def dump_iptables():
    return iptc.easy.dump_table('filter',ipv6=False)

print(dump_iptables())