How to block incoming/outgoing network access for a single user using iptables?

Why this post?

Hmm… Every SysAdmin, who love to play with Linux iptables must know, how iptables deal networking for a single user. You need to dig more on Linux iptables to get this option. Yeah, it’s possible!! Linux iptables has a special module to deal with this operation. This iptables module is called “owner” (ipt_owner).

Before starting, you must have the basics of iptables.. Please read the post added below to get a clear intro on Linux iptables:

What is iptables in Linux?

We can call, it’s the basics of Firewall for Linux. Iptables is a rule based firewall system and it is normally pre-installed on a Unix operating system which is controlling the incoming and outgoing packets. By-default the iptables is running without any rules, we can create, add, edit rules into it. Read More……

The module owner

This iptables module will attempt to match various characteristics of the packet creator, for locally generated packets. Not the point, it can only manage outgoing network access for a single user.

If someone ask you about “How you block all connections to a port for a process running under a user on the server?” or “How to block all incoming connections for a particular user?” by using iptables, you can answer “It Won’t Possible.” (Using, the by-default ipt_owner module)

This option is valid in the OUTPUT and POSTROUTING chains.

See the dmesg warning when I try to add it on INPUT chain 🙂

[1389305.755721] nf_conntrack version 0.5.0 (65536 buckets, 262144 max)
[1389719.919415] x_tables: ip_tables: owner match: used from hooks INPUT, but only valid from OUTPUT/POSTROUTING

How To Block Outgoing Network Access For a Single User Using Iptables?

This option in iptables is very useful, if you want to block outgoing network activities for a particular user account on your Linux server/system. Here you can use owner module to match user and block all outgoing traffic for that user.

Scenario 1:

Consider this scenario, if you want to block all outgoing connections from a user “crybit” on the server, we can simply create an OUTPUT chain rule to do so.

See the rules and examples pasted below:

Syntax

iptables -A OUTPUT -o ethX -m owner --uid-owner {user name} -j DROP

I am guessing you are familiar with the commonly using iptables switches. Here, we have to use the following switches to define owner details.

-m owner : To define owner with the help of –uid-owner
–uid-owner {user name} : Matches if the packet was created by a process with the given effective username.

You can use any jump (j) option like, DROP, REJECT etc as you wish…

It also support the following switches:

--gid-owner (groupid)    : Matches if the packet was created by a process with the given effective group id.
--pid-owner (process id) : Matches if the packet was created by a process with the given process id.
--sid-owner (session id) : Matches if the packet was created by a process in the given session group.
--cmd-owner (name)       : Matches if the packet was created by a process with the given command name. [Not supported in latest iptables]

Example:

Test user is “crybit

Checking the user has network activities..

[root@connect ~]# su - crybit

[crybit@connect ~]$ ping -c2 goo.gl
PING goo.gl (172.217.6.14) 56(84) bytes of data.
64 bytes from ord38s01-in-f14.1e100.net (172.217.6.14): icmp_seq=1 ttl=57 time=8.55 ms
64 bytes from ord38s01-in-f14.1e100.net (172.217.6.14): icmp_seq=2 ttl=57 time=8.60 ms

--- goo.gl ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 8.554/8.581/8.608/0.027 ms

[crybit@connect ~]$ dig +short goo.gl
172.217.6.14

Yup, everything is okay!!

Now we are going to block outgoing network access for the user “crybit

Checking active ethernet link

Use "ip a" command

eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:16:3c:10:46:bf brd ff:ff:ff:ff:ff:ff

You can use eth0 here.

iptables -A OUTPUT -o eth0 -m owner --uid-owner crybit -j DROP

Try again, now you can’t ping or dig as the user “crybit.”

[crybit@connect ~]$ ping -c2 goo.gl
ping: goo.gl: Name or service not known

[crybit@connect ~]$ dig +short goo.gl
^C[crybit@connect ~]$

That’s it!!

Scenario 2:

You can also block out going network activity for system defined users. Consider this scenario, if you want to block all outgoing network connections for Apache user. This can block someone downloading code into your server using wget or any other tools.

Check the user name for Apache server and add it to the rule using “-m owner –uid-owner” switch.

Don’t forget to allow email ports, 25,143,110 so that emails can work properly.

iptables --append OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Create a new chain to deal this task.

iptables --new-chain for_apache_user

Use new chain to process packets generated by apache user.

iptables -A OUTPUT -m owner --uid-owner apache -j for_apache_user

Define email ports to allow connections:

iptables -A chk_apache_user -p tcp --syn -d 127.0.0.1 --dport 143 -j RETURN
iptables -A chk_apache_user -p tcp --syn -d 127.0.0.1 --dport 110 -j RETURN
iptables -A chk_apache_user -p tcp --syn -d 127.0.0.1 --dport 25  -j RETURN

Reject everything else and stop the network activity for the user Apache:

iptables -A for_apache_user -j REJECT

Try it and let me know if you have any suggestions.

Post navigation

Arunlal A

Senior System Developer at Zeta. Linux lover. Traveller. Let's connect! Whether you're a seasoned DevOps pro or just starting your journey, I'm always eager to engage with like-minded individuals. Follow my blog for regular updates, connect on social media, and let's embark on this DevOps adventure together! Happy coding and deploying!

Leave a Reply

Your email address will not be published. Required fields are marked *