iptables --gid-owner works only for user's main group - firewall

I am trying to disable access to IP 1.2.3.4 for all users except for members of group "neta". This is a new group which I created only for this matter.
iptables -I OUTPUT -o eth0 -p tcp -d 1.2.3.4 -m owner ! --gid-owner neta -j REJECT
This disables access to 1.2.3.4 for all users, even if they are member of group "neta".
I have an user xx and he is a member of groups xx (main group) and neta. If I change the rule to:
iptables -I OUTPUT -o eth0 -p tcp -d 1.2.3.4 -m owner \! --gid-owner xx -j REJECT
everyone except user xx is not able to access 1.2.3.4.
I added root to this group xx:
usermod -a -G xx root
but root was still not able to access this IP.If I add main user's group (root, xx) to the rule everything works as expected.
I tried spliting it in two rules just to be sure (and log rejected):
iptables -A OUTPUT -o eth0 -p tcp -d 1.2.3.4 -m owner --gid-owner neta -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -d 1.2.3.4 -m limit --limit 2/s --limit-burst 10 -j LOG
iptables -A OUTPUT -o eth0 -p tcp -d 1.2.3.4 -j REJECT
but there is no difference. Everything is being rejected.
There are no other iptables rules.
root#vm1:~# iptables -nvL
Chain INPUT (policy ACCEPT 19 packets, 1420 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 10 packets, 1720 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * eth0 0.0.0.0/0 1.2.3.4 owner GID match 1001
0 0 LOG tcp -- * eth0 0.0.0.0/0 1.2.3.4 limit: avg 2/sec burst 10 LOG flags 0 level 4
0 0 REJECT tcp -- * eth0 0.0.0.0/0 1.2.3.4 reject-with icmp-port-unreachable
I want to be able to (dis)allow access to this IP by adding/removing users from this "neta" group instead of adding iptables rules for every user.

Ok, to be honest I know to little about linux and iptables to be sure about my theory, but since I wanted to do the same for a VPN here we go.
I assume that the match is done using the process from which the packets originate from and that a linux process doesn't get all groups of a user assigned but instead a process runs with one uid and one gid.
That means that you have to execute the command explicitly using this specific group, or else the command/process is executed using the default group of the user.
Writing this I had an idea to see whether there is such possibility.
I restricted access to a certain IP range using the group VPN. This never worked. Now I tested with the following command and it works:
sg vpn -c "ssh user#10.15.1.1"
So I hope my theory was correct.

Old post, but chiming in since I have run into this exact problem in Ubuntu 16.04.3 LTS server.
Ubuntu's implementation of iptables extensions through netfilter examines the owner of the current network packet, and queries only the primary group id of that user. It doesn't dig deeper and get all the group memberships. Only the primary group is compared to the --gid-owner value. It doesn't look any further.
What the OP was trying to accomplish would work if he/she changed the primary/default user group of all relevant usernames to "neta". Those users would then be captured by the rule.

To use a supplementary group you need to add the --suppl-groups flag to your iptables command
From man page:
--suppl-groups
Causes group(s) specified with --gid-owner to be also checked in the supplementary groups of a process.

Related

Linux: how to get network stats on tcp (ie excluding udp)?

I've been using /sys/class/net/eno1/statistics/rx_bytes and tx_bytes to gather stats on my network interface. The trouble is, that network has a device (a Silicon Dust HDHOMERUN HDTV tuner) which constantly streams UDP packets at a very high rate that I don't want to monitor. I'd like to remove that traffic from the monitor - perhaps by only looking at TCP packets.
Is there any way to separate out the TCP and UDP stats?
netstat -st gives some info but it's somewhat cryptic - just how big is a 'segment'? The MTU? The man page is silent on that.
$ netstat -st | grep 'segments received'
25449056 segments received
1683 bad segments received
$ netstat -st | grep 'segments sent out'
37860139 segments sent out
Based on this answer from serverfault. If you are using iptables you can add a rule to each of the INPUT and OUTPUT chains which will count every packet which carries TCP in the payload. It is possible that you will need to invoke every iptables command with sudo.
Create the rules:
# Match all TCP-carrying packets incoming on 'eno1' iface
iptables -I INPUT -i eno1 -p tcp
# Match all TCP-carrying packets outgoing through 'eno1' iface
iptables -I OUTPUT -o eno1 -p tcp
Afterwards, you can use iptables -nvxL INPUT or OUTPUT to be presented with the number of bytes processed by the rule:
Chain INPUT (policy ACCEPT 9387 packets, 7868103 bytes)
pkts bytes target prot opt in out source destination
10582 9874623 tcp -- eno1 * 0.0.0.0/0 0.0.0.0/0
In case you already have other rules defined it might be handy to create a separate chain entirely. This is also described in the answer i referenced, though you also want the -i and -o options in the in/out chains respectively. These allow you to filter on a single interface (use -i for INPUT and -o for OUTPUT).
iptables -N count_in # create custom chain named 'count_in'
iptables -A count_in -j RETURN # append RETURN action to chain 'count_in'
iptables -I INPUT -j count_in # insert chain at the top of chain INPUT
iptables -I count_in 1 -i eno1 -p tcp # insert rule that matches all tcp packets on eno1
# and has no action (does nothing)
iptables -nvxL count_in # list chain 'count_in' rules
I am not sure whether the "bytes" counter includes the IP header, or just the TCP segment bytes but it is still probably the closest metric to what you want to measure (TCP-only rx/tx bytes).
Additionally keep in mind that oftentimes rules defined with iptables are not actually saved and will get deleted on a system reboot. To enable them persistently on every reboot you may use the iptables-save and iptables-restore commands. To learn their usage you should probably look in your Linux distro's documentation as well as iptables manual.
Finally, AFAIK iptables is considered legacy by now and it is being slowly replaced by nftables. I myself still have iptables installed in my system by default. If you want to switch/are already using nftables, then you need to translate above commands to the syntax supported by the nft command. There is a utility called iptables-translate available which may help with this. It's purpose is to translate old iptables commands to equivalent nft commands. I mention this mostly for the sake of completeness, you should be just fine using iptables for your particular task if you have it installed.
You can use iptraf-ng.
Install with:
sudo apt install iptraf-ng
This will give you statistics per protocol (IPv4/IPv6/TCP/UDP/ICMP/...) on a specific interface:
sudo iptraf-ng -d eth0
You can also use this to have details per ports:
sudo iptraf-ng -s eth0

How to delete/unblock my server IP in iptables on Ubuntu?

My first server blocked my second server IP and I haven't access now.
Command iptables -L -n | grep xx.xxx.xxx.xx
give me result like:
ACCEPT all -- xx.xxx.xxx.xx 0.0.0.0/0
REJECT all -- xx.xxx.xxx.xx 0.0.0.0/0 reject-with icmp-port-unreachable
The xx.xxx.xxx.xx is the same IP and it is my server IP.
I have two rules like ACCEPT AND REJECT for this IP.
How can I give access to my server IP from iptables and prevent blocking my IP ?
Many thanks for help.
To recreate your issue
iptables -A INPUT -s 10.64.7.109 -j ACCEPT
iptables -A INPUT -s 10.64.7.109 -j REJECT
iptables -P INPUT DROP
but that will not block 10.64.7.109 and the first rule hit will be the accept
you are only sharing the output that specifically has the IP you are interested in so i can not see what rules above these 2 would be blocking it.
you can allow this IP by inserting a rule in position 1 which will resolve your issue but without seeing all your rules I can not say it is the most appropriate way to resolve the issue.
iptables -I INPUT 1 -s 10.64.7.109 -j ACCEPT

Creating firewall rules using iptables

Is there any way to construct a firewall rule using "iptables" which filters packets on both input and output? I've only been able to find rules like the following which allow you to designate it as applying to packet source (INPUT) or destination (OUTPUT).
iptables -A INPUT -i eth1 -p tcp -s 192.168.1.0/24 --dport 80 -j DROP.
It would make sense though that I should be able to filter packets coming from and going to specific places so that I could end up with a fw table like the following:
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 172.152.4.0/24 92.3.0.0/16
Any suggestions?
Thanks!
Yes and no.
No because: iptables works by defining how to treat packets based on their categorization into chains (INPUT, OUTPUT, FORWARD, ...) first and only then also on specific characteristics (source or destination address, protocol type, source or destination port, etc). You can never define an iptable rule that does not apply to a specific chain.
INPUT, OUTPUT, and FORWARD are the default chains of the iptables system. INPUT addresses everything with destination localhost (i.e. that is addressed to your network device); OUTPUT applies to everything with source localhost (i.e. that comes from your computer).
Yes because: You can define custom chains. You can do that like so
sudo iptables -N MYCHAIN
then you can send packets from both the INPUT and the OUTPUT (and if you like the FORWARD) chain to MYCHAIN, for instance all the TCP packages from INPUT:
sudo iptables -A INPUT -p tcp -j MYCHAIN
or all the packages from OUTPUT
sudo iptables -A OUTPUT -j MYCHAIN
and then you can define any rule you want for mychain, including
sudo iptables -A MYCHAIN -s 172.152.4.0/24 -d 92.3.0.0/16 -j ACCEPT
which should be more or less the rule you wanted
However, one might argue that it does indeed make sense to keep INPUT and OUTPUT chains seperate. Most users will want to apply much stricter rules on INPUT and FORWARD than on OUTPUT. Also, iptables can be used for routing in which case it makes a fundamental difference if you have an incoming or an outgoing package.

IPTABLES How to block 8.8.8.8

I am creating a script that allows you to block, IP, port, certain IP's and ports, and DNS servers. It basically gets a name and blocks certain addresses for that person.
Problem is, I am stuck at blocking 8.8.8.8 . No matter what I have tried, I cannot seem to block it!
Here is what I have tried so far:
iptables -A OUTPUT -p tcp -d 8.8.8.8 --destination-port 53 -j DROP
iptables -A OUTPUT -p udp -d 8.8.8.8 --destination-port 53 -j DROP
iptables -A OUTPUT -p -s 8.8.8.8 -j DROP
And even
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j DROP
Pinging any other site doesn't work, while pinging 8.8.8.8 still works...
My Policies are all set to ALLOW. Should I change them?
I am kinda new to this, apologies if this all seems queer . Thanks!
You're trying to block a SOURCE address in the OUTPUT chain. 8.8.8.8 would be a DESTINATION in the output chain. The SOURCE of a packet in the output chain is generally the machine you're running these rules on... Try these:
-A INPUT -s 8.8.8.8 -j DROP
-A OUTPUT -d 8.8.8.8 -j DROP
rule #1 will drop any packets coming IN to your system which originated on google's public DNS. rule #2 will drop any packets LEAVING your system destined for the same.
As for ping, remember that ping uses the ICMP protocol. You're trying to block UDP only. Also remember that DNS requests CAN use TCP if the request or response would need more than 1 udp packet.

Iptables or something to redirect IP in gateway (GNU/Linux)

Im writing a bash scripting to account traffic in my network server:
WAN:eth1 -> GNU/Linux Server:eth0 -> Users
The GNU/Linux server uses squid, bind, QoS, mysql, lighttpd.
After an IP exceed the established quota a new QoS rule is applied for that IP (user) too exist one "flag" to decide when is restored the IP counter to Zero.
Some IPs and subnets work without quotas, other gruop of ips/subnets work with new QoS after quota is exceeded, and now I wanna work with a third group with redirection after quota is exceeded.
When an IP exceed the established quota all http traffic must be redirected to host (lighttpd runing on GNU/Linux ) and DROP all other traffic generated for that IP. In webserver exist a webpage with: "You exceed your daily quote of traffic, please wait "x" hours or call to your provider to purchase an extra navigation package" or something like that.
Is possible using a chain, or how can I do that?.
The most topics that I found in Internet, are related to block all and create a new chain to let out to Internet (not work for me). And other redirect only IP by IP, but how can I create something that a "chain" and attach the IPs to must me redirected to can after restore that IPs easly?
Thanks for help and sorry for my poor English :S.
Are you looking for something like this?
iptables -t nat -A PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -I INPUT 1 -i lo -s 192.168.100.66 -j ACCEPT
iptables -I INPUT 2 -i eth1 -d 192.168.100.66 -j DROP
This will redirect packets from 192.168.100.66 on port 80 to the local webserver on the loopback interface, allow that conversation, then reject all other packets being routed to 192.168.100.66 on the WAN interface.
To restore the connection back to normal you will want to delete those firewall entries:
iptables -t nat -D PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -D INPUT -i lo -s 192.168.100.66 -j ACCEPT
iptables -D INPUT -i eth1 -d 192.168.100.66 -j DROP
Note that iptables itself (well, the xtables-addons extension set providing quota2) can already do the quota matching magic and you can (re)set the values through procfs, combined with REDIRECT as #resmon6 says:
-t nat -s user1addr -m quota2 --name user1 ! --quota 0 -j REDIRECT...
-t nat -s user2addr -m quota2 --name user2 ! --quota 0 -j REDIRECT...
The syntax is a arguably a little odd right now (0 is the initial value only and is independent from the runtime quota test involving the negational !. Noticing this just now, a patch may make it in to unroll this confusing syntax in the future).

Resources