Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How do I block a user from accessing the internet under Linux?

I'm trying the following:

iptables -A OUTPUT -p tcp --dport 80,443 -m owner --uid-owner $USERNAME -j DROP

Is that the right syntax or command?

share|improve this question
not being familiar with -m owner you could probably just remove -p tcp --dport 80,443 and prevent ALL tcp/ip access – xenoterracide Apr 5 '10 at 7:54
If you have control over their access point (e.g. router), you could block their computer's physical addresses and whatnot. – iglvzx Nov 15 '11 at 0:11
@iglvzx That would block the whole machine, and not a specific user, which is what it looks like was being asked. – killermist Jun 25 '12 at 3:22

And then I do ssh -D 12345, point my browser to use SOCKS proxy localhost:12345, and on I go on my merry way.

In other words, blacklisting specific ports is not sufficient; you may want to block all network access:

iptables -A OUTPUT -m owner --uid-owner $USERNAME -j DROP

Note that there may be a need to access certain network resources (e.g. local network shares), so you may need to whitelist those (or perhaps whitelist the local network block).

share|improve this answer

This command will only block the user from accessing the World Wide Web, not the entire Internet.

Apart from that it should work, assuming it is run on the same machine $USERNAME is working on.

share|improve this answer
This is correct only for web servers running on standard ports. This is the case for most web servers, but generally a web server can listen on any port. So it's possible for that user to set up a remote web server running on a non-standart port, host a CGI proxy web script there and browse the Internet over it. – geek Feb 15 '10 at 15:20

First of all

iptables is the right command to do the job. But generaly you would use a reasonable amount of commands to set up a complete table. 1 command is one alternation to the table.

To find out the tables already in place and the default policy if no rules are matched use iptables -L. Usualy ine would write a bash script containing all the iptables setting. Where, at first you flush all the chains and then put everything in at once. This is to prevent losing track of what's in and out.

Also, check your init implementation if there are init scripts available to make your changes persistent over power cycles. (Normally your tables are lost after reboot).

Just create a script to include all your iptables commands:

# Flush all chains
iptables -F

#Set defaults policies
iptables -P INPUT DROP
iptables -P FORWARD DROP

# Don't block localhost traffic
iptables -A INPUT -i lo -j ACCEPT
# Don't re-evaluate already accepted connections
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#Allowed incomming tcp ports
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT # SSH
# Add watherver you wish to allow more

See this article for more tips on standard iptable rules.

Now to answer your question

First we needed to make sure you have a basic firewall up and running. Now, you can add your rule to your script to take effect. Please take in account suggestions from the other answers: an user can easily by-pass two blocked ports with a proxy or alternate ports.

Furthermore, your syntax was not correct. --dport can use only one port. You need to use the multi port module or chain multiple rules to do so.

However, blocking all outgoing connections for this user, will cause many applications to fail because they depend on the lo connection located at localhost or (Eg. if you are using KDM/KDE, your system freezes up during login.)

So you need to exclude the lo network interface from your rule. If still you want to allow the user to access only certain services, just create a rule before the DROP rule allowing those ports. I would suggest the following:

# Don't re-evaluate already ACCEPTed connections:
iptables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Allow an outgoing connection, like SSH
iptables -A OUTPUT -p tcp --dport 22 -m owner --uid-owner $USERNAME -j ACCEPT

# Drop anything else that not on localhost
iptables -A OUTPUT ! -o lo -m owner --uid-owner $USERNAME -j DROP
share|improve this answer

You must log in to answer this question.