Here's the problem: you're allowing access to some ports of your server based on source IPs. This is common practise, even if it's not 100% secure (since source IPs can be spoofed in certain situations). However what if you've no fixed source IP address(es) (which is common practise too) that you can feed into
iptables
rules? You can register a domain name at a
dynamic DNS provider (eg. dyndns.org) and have your client (a DSL router or a client app on your PC) automatically update the IP of that domain name, whenever your client's internet connection get's up. But still,
iptables
does not allow use of domain names in firewall rules (and it's good so
). Here's where my script comes into play. It allows you to specify a list of domain names and destinations (host+port) for which the script will automatically generate permitting
iptables
rules.
The script is self-documented: take a look at the comments at the start of the script to learn how it can be set up. Don't forget to configure
cron
to execute the script periodically so
iptables
rules are updated regularily as the clients' IPs change.
Comments
dynamic address rules update
Would you
Dynamic firewall rules for iptables
2009, February 22 - 17:46 — müzso
Re: Would you
Hard Coded eth0
I recomend that you allow for non hard coded eth?
I will modify the code to allow this if you would like me to send it back?
Re: Hard Coded eth0
/etc
).Bugfix for my dynamic firewall rules script
This got fixed in v1.2.
iptables DNAT and SNAT
Could be this script modified to manage DNAT and SNAT (POSTROUTING and PREROUTING rules), with dynamic ips?
Thanks
Re: iptables DNAT and SNAT
Will this accept a port-range (rather than single port)
First, would it be easier to simply hard-code the dynamic DNS entries in a iptables script file, and re-run the file (flushing/resetting the rules) every X minutes? Or is there a reason this wouldn't work?
Second, I'm curious about how to open multiple ports...
The current example shows:
"dynamic2.address.example.com;22"
Could it open multiple ports by using a port-range, for example:
"dynamic2.address.example.com;0:1023"
Or is there any way to simply remove the second parameter for complete access by that host?
"dynamic2.address.example.com"
Re: Will this accept a port-range (rather than single port)
It'd be definitely easier. Whether it works as expected ... it depends. Under certain circumstances it might work. But that method would rely on the system-wide DNS resolver to return an up-to-date DNS response for the given domain name. Since if you specify a domain name in your
iptables
command, it'll use the DNS servers as given in your/etc/resolv.conf
file (supposing you use the simple file based DNS resolver).In case of DynDNS, the SOA DNS servers for the dyndns.org domain (eg. ns1.dyndns.org) return a TTL of 60 seconds. If your DNS forwarder honors that, then you should have no problem, since your iptables command will always get an up-to-date IP address for the given domain name. However if your DNS server does not honor the TTLs returned by the ns*.dyndns.org servers (or if you use another dynamic DNS provider that uses a significantly larger TTL), then it will not work well, since your
iptables
script will get a cached IP address that might not be up-to-date.And there's another issue: DNS server failure. I've already experienced that dyndns.org name servers can fail sometimes. During the development of this script I've experienced multiple DNS reponse failures from the ns*.dyndns.org servers (probably due to high load). My script can query multiple DNS servers in case one fails. If you specify all dyndns.org DNS servers in your rule, then the script will query each until it gets an IP address from one of them. It is quite unlikely that all ns*.dyndns.org servers fail at the same time so that should be enough. There're five dyndns.org DNS servers (ns1.dyndns.org, ..., ns5.dyndns.org).
The current version does not support port ranges (of course this enhancement might be added later). You can add multiple ports only by listing them one by one.
Eg.: "dynamic2.address.example.com;0,1,2,3,4,5,6,...,1023"
Of course in the above example the "..." should be replaced with all the ports in the range. It'd make quite a long line and I'm not even sure it'd work. I've never tested any rule strings that long. Theoretically it should, but who knows (there might be some secret buffer limitation that I cannot recall right now).
No. The second parameter is compulsory. I could remove this limitation of course. I did not think that somebody would ever require all ports to be opened for a given client address. Of course there're cases (dumb protocols like Oracle's SQL*Net) when you've no choice.
NAT table
Can you please let me know what changes are required to support NAT table ?
Warm Regards
Supratik
Re: NAT table
Re: NAT table
/sbin/iptables -t nat -A POSTROUTING -d 216.239.61.104 -o eth0 -j SNAT --to-source $PUBLICIP [216.239.61.104 is the ip of google.com]
The problem is that, IP address for google.com changes after a certain period of time. Can you please tell me what changes
I have to make in the "dynamic_address_rules-1.3.sh " file for the same ?.
Re: NAT table
My script currently supports generation of iptables rules only for incoming connections. The goal was to create rules for incoming connections from remote hosts with a dynamic IP address. You'd like to use it for outgoing connections to remote hosts with a dynamic IP address. It's certainly feasible, but requires quite some changes to the script. I could modify it to support such use cases out of the box, but ...
The google.com (or www.google.com) address is not a dynamic domain name! Multiple IPs are assigned to it, but the IP set is fairly constant. However for each DNS query a different IP address is returned in a round-robin fashion. I assume this is your problem. You've to create iptables rules for all the IPs of the google.com domain. Or you could add google.com to your
/etc/hosts
file with one of the addresses (to restrict all IP connections going to "google.com" to a single IP) and in this case you'd have to add only a single rule to your iptables list. I'd not suggest the latter approach, but it's certainly an option.Currently my script does not support generation of iptables rules for all IPs of a multi-IP domain name. In such cases it takes the last IP retrieved from the DNS lookup answer. Later on I might create an option to support rule generation for all IPs of multi-IP domain names.
Re: NAT table
#!/bin/bash
IPT=/sbin/iptables
DIG=/usr/bin/dig
IFACE=eth0
TABLE=nat
CHAIN=google_rules
HOSTNAMES=(
"google.com"
)
if ! test -x ${IPT}; then
echo "${IPT} is not executable" >&2
exit 1
fi
if ! test -x ${DIG}; then
echo "${DIG} is not executable" >&2
exit 2
fi
if $IPT -t ${TABLE} -n -L ${CHAIN} > /dev/null 2>&1; then
$IPT -t ${TABLE} -F ${CHAIN}
else
$IPT -t ${TABLE} -N ${CHAIN}
$IPT -t ${TABLE} -I POSTROUTING -o ${IFACE} -j ${CHAIN}
fi
for record in "${HOSTNAMES[@]}"; do
for ip in $(${DIG} +noall +answer ${record} | awk '/[ \n\t][0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?$/{print $NF}'); do
$IPT -t ${TABLE} -A ${CHAIN} -d ${ip} -j ACCEPT
done
done
$IPT -t ${TABLE} -A ${CHAIN} -j RETURN
Put it in a script and execute it regularly (eg. every 5-10 minutes).
If you need these rules only for access to the HTTP port of google.com, then you might change the POSTROUTING rule to this:
$IPT -t ${TABLE} -I POSTROUTING -o ${IFACE} -p TCP --dport 80 -j ${CHAIN}
Enterprise connection profiling
I am looking for configuration which enables the laptop to identify the network i.e.
1.Office LAN
2. VPN and
3. Home(Internet)
When connected to them respectively it should open and block certain ports based on the connectivity.
For example i need to enable SSH/VNC while i am on office network and block it once i am over the internet.
Please let me know if i can get any help with this.
Re: Enterprise connection profiling
I'm not a networking expert, but automatic (and secure/dependable) identification of a network seems to be a tough challenge. There might be already standardized protocols and mechanisms for this, but I don't know of any (and even if there're, chances are that most networking devies -switches/routers- do not support them). Detecting the VPN connection (vs. the "plain" connections) is easier, since it'll probably use a different interface (i.e. /dev/* device file), but telling a connection to the office LAN from a connection to the home router is difficult. You could use some simplification, eg. if your PC can connect to a specific port of a specific IP address (and/or talk to some service with verifiable results), then we say it's connected to the office network. You could use similiar "identification" on your home network as well (eg. you could verify the MAC address of the home router that your PC connects to and base the decision -whether you're connected to the home LAN or not- on that).
As for the automation of all this ... there must be some entry points for the NIC's connect/disconnect events that you can use/hijack. I'd guess that probably some udev events are fired when you put the RJ45 plug into your computer's network port (or pull the plug), so you might be able to write custom udev rules to execute some shell script upon these events. And you could write these shell scripts so they detect (based on the previously outlined ideas) the network you're connecting to and pull up (or tear down) some firewall rules based on the given network.
I know these are some very general ideas, but that's all I have right now. Unfortunately I've not done this myself so I cannot provide you with a specific implementation.
P.S.: or you could just try to Google for a solution. There might be free or commercial software (with a GUI and easy setup) that could do what you're aiming for.