Linux - SecurityThis forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a slackware distribution with kernel 2.6. I want to setup up a firewall using iptables. I have read numerous tutorials, some right here on LQ. All are wonderfully informative. However, I think I'd rather someone just give me the "fish". I don't want to spend lots of time learning and experimenting for what I want.
First, how do I know if iptables is running? I see nothing when I `ps ax`. iptables seems to be commented out in my rc.local[*] files. But if I do iptables -L, I see the (default) INPUT,FORWARD,OUTPUT chains which basically ACCEPTs everything.
Where are these config scripts kept? /etc/sysconfig doesn't exist. Some tutorials indicate my iptables config is kept there.
Most importantly, I want to reject all requests except those for ftp (21), ssh (22), http (80), https (440) and smtp (25) on eth1.
I'm not running dns - that is handled by subnet provider. Any suggestions for other services I should let through?
I have a slackware distribution with kernel 2.6. I want to setup up a firewall using iptables. [...] Where are these config scripts kept? /etc/sysconfig doesn't exist. Some tutorials indicate my iptables config is kept there.
On Slackware the convention is to set up an /etc/rc.d/rc.firewall script instead of using a config file.
Quote:
First, how do I know if iptables is running? I see nothing when I `ps ax`. iptables seems to be commented out in my rc.local[*] files. But if I do iptables -L, I see the (default) INPUT,FORWARD,OUTPUT chains which basically ACCEPTs everything.
Iptables doesn't run like a daemon. The iptables binaries are run only when you execute them yourself, such as when you executed that "iptables -L" command, or when each iptables line in your rc.firewall script is run. Iptables allows you to configure the kernel's firewall code, which is called Netfilter. This is done with modules, so you'd wanna use lsmod instead of ps to check things. For example, this is what my Ubuntu (also kernel 2.6) laptop looks like right now:
That said, if your "iptables -L" command provided you with that output, I believe that confirms your Netfilter/iptables setup is properly set.
Quote:
Most importantly, I want to reject all requests except those for ftp (21), ssh (22), http (80), https (440) and smtp (25) on eth1.
I'm not running dns - that is handled by subnet provider. Any suggestions for other services I should let through?
You mean inbound, right? Like, this box is a server and not a client, right?
Quote:
I'm not running dns - that is handled by subnet provider. Any suggestions for other services I should let through?
How would I configure that?
By making the necessary edits to your rc.firewall script and then executing it (or giving it a "reload|restart" parameter if it's designed to work with that). Adding a rule for a service is usually just a matter of doing a copy paste and then a changing a port number.
Since you're asking for suggestions about which services to let through, it now sounds like this is a client and not a server.
win32sux: Thanks for the info. The tutorials I read weren't really clear on these simple lsmod and rc.firewall details. I have no rc.firewall. My `lsmod | grep ipt` returns a bit less than your example:
This machine is a web server, so I guess incoming packets on eth1 are my concern. I also have an eth0 which is an internal lan connection, but I am not concerned about that since it has its own Windows Server firewall. I'm focusing on eth1 which is connected directly to the Internet.
Simon Bridge: Thanks for the link. I will check it out, but there appears to be a lot of stuff in the example and, to be honest, I am more interested in a correct solution for my immediately needs than puzzling my way through more examples. It will be easier for me to figure out how things work if I can see the implementation of MY requirements. A Rosetta Stone, if you will.
There aren't any more modules loaded because you haven't implemented any rules.
The required modules are automatically loaded as rules need them.
Quote:
This machine is a web server, so I guess incoming packets on eth1 are my concern. I also have an eth0 which is an internal lan connection, but I am not concerned about that since it has its own Windows Server firewall. I'm focusing on eth1 which is connected directly to the Internet.
Quote:
So, what should MY rc.firewall script look like?
Here's an example (just a starting point) based on the info you've provided so far:
Code:
#!/bin/sh
IPT="/usr/sbin/iptables"
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT
$IPT -t mangle -P PREROUTING ACCEPT
$IPT -t mangle -P INPUT ACCEPT
$IPT -t mangle -P FORWARD ACCEPT
$IPT -t mangle -P OUTPUT ACCEPT
$IPT -t mangle -P POSTROUTING ACCEPT
$IPT -t raw -P PREROUTING ACCEPT
$IPT -t raw -P OUTPUT ACCEPT
$IPT -F
$IPT -F -t nat
$IPT -F -t mangle
$IPT -F -t raw
$IPT -X
$IPT -X -t nat
$IPT -X -t mangle
$IPT -X -t raw
$IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -p TCP -i eth1 -m multiport --dports 21,22,25,80,443 \
-m state --state NEW -j ACCEPT
$IPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
win32sux: Thanks, now we're getting somewhere. I'm going to try to figure out what you've given me. I'll tahe this one piece at a time:
You're setting the INPUT, FORWARD, OUTPUT chains of the filter table to target DROP (drop packets). The you set the various chains of the nat, mangle and raw chains to accept packets.
Then you -F, flush (i.e. delete all rules) of all tables, after which you -X, delete every non-builtin chain in the tables.
So, doesn't the -F/-X remove all the default targets you just set up using -P? Proably not, but what did you just accomplish with all that?
So, doesn't the -F/-X remove all the default targets you just set up using -P?
Nope. The policies aren't affected by those.
Quote:
Proably not, but what did you just accomplish with all that?
You made sure everything was 100% pristine before your actual rules get executed. On a fresh startup, none of the flushes, deletes, and ACCEPT policies will make any difference, as the box will boot without any iptables configuration at all. But doing this in the script gives you the ability to return your iptables configuration to your original state with minimal effort (you just have to execute /etc/rc.d/rc.firewall) whenever you want. Without those commands, re-executing the script after having played with iptables would yield unpredictable results.
Nikosis: I'll check you your link ASAP; sounds interesting. Right now it's not coming up.
win32sux: Thanks for the explanation on the flushes. The bit about restarting makes sense. Before I fire this baby up, let me see if I understand the rules you created:
> $IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
Add a rule to the INPUT chain of the (default) filter table. Do extended packet matching (-m) using the "state" module. For states RELATED (packet associated with existing connection) or ESTABLISHED (connection has seen packets in both directions), jump (-j) to the ACCEPT target. I.e. accept all INPUT packets for existing connections.
> $IPT -A INPUT -i lo -j ACCEPT
Add a rule to the INPUT chain to accept all packets for the localhost interface
> $IPT -A INPUT -p TCP -i eth1 -m multiport --dports 21,22,25,80,443 \
> -m state --state NEW -j ACCEPT
Add a rule to the INPUT chain to ACCEPT (-j) all new connections (--state NEW) for TCP protocol packets (-p TCP) for interface (-i) eth1
> $IPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
accept all output packets for existing connection
> $IPT -A OUTPUT -o lo -j ACCEPT
accept all output packets for localhost interface
Are these the correct interpretations? My eth0 interface isn't mentioned. That is the one on the internal lan and I don't need any filtering. Should I do the same with eth0 as you've done with lo?
# Set default policy to DROP
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
# Flush old rules
$IPT -F
# Allow packets of established connections
$IPT -A INPUT -i eth0 -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
but, you'll need more rules if you want all of those ports open.
Are these the correct interpretations? My eth0 interface isn't mentioned. That is the one on the internal lan and I don't need any filtering. Should I do the same with eth0 as you've done with lo?
Yeah, I think you've got it down pretty good. Just remember that NEW doesn't mean "new connection", it means more like "initial packet". In this case, the idea being that it's the first packet that starts the handshake (since this is TCP). So you could even specify that you want this match to occur only if the packet is a proper SYN packet, which is something I like to do (see the example below). As for eth0, sorry, I thought that you meant that you didn't want any traffic on that interface. I now understand that you simply wish to allow all traffic on it without any firewalling. So to do that you just need to add one rule to accept inbound connections, and (optionally) one rule to allow outbound connections:
Code:
#!/bin/sh
IPT="/usr/sbin/iptables"
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT
$IPT -t mangle -P PREROUTING ACCEPT
$IPT -t mangle -P INPUT ACCEPT
$IPT -t mangle -P FORWARD ACCEPT
$IPT -t mangle -P OUTPUT ACCEPT
$IPT -t mangle -P POSTROUTING ACCEPT
$IPT -t raw -P PREROUTING ACCEPT
$IPT -t raw -P OUTPUT ACCEPT
$IPT -F
$IPT -F -t nat
$IPT -F -t mangle
$IPT -F -t raw
$IPT -X
$IPT -X -t nat
$IPT -X -t mangle
$IPT -X -t raw
$IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i eth0 -m state --state NEW -j ACCEPT
$IPT -A INPUT -p TCP -i eth1 -m multiport --dports 21,22,25,80,443 \
--syn -m state --state NEW -j ACCEPT
$IPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A OUTPUT -o eth0 -m state --state NEW -j ACCEPT
win32sux: Sorry, got distracted with the holidays. I'm going to fire up what we have come up with right now. I have a lingering question: why did you code the eth0 interface as:
$IPT -A INPUT -i eth0 -m state --state NEW -j ACCEPT
$IPT -A OUTPUT -o eth0 -m state --state NEW -j ACCEPT
instead of:
$IPT -A INPUT -i eth0 -j ACCEPT
$IPT -A OUTPUT -o eth0 -j ACCEPT
win32sux: Sorry, got distracted with the holidays. I'm going to fire up what we have come up with right now. I have a lingering question: why did you code the eth0 interface as:
$IPT -A INPUT -i eth0 -m state --state NEW -j ACCEPT
$IPT -A OUTPUT -o eth0 -m state --state NEW -j ACCEPT
instead of:
$IPT -A INPUT -i eth0 -j ACCEPT
$IPT -A OUTPUT -o eth0 -j ACCEPT
like you did with the lo interface?
Good question. The reason behind it is that I want to allow all packets on the loopback interface - without any care about their state. You could make restrictive rules for the loopback interface if you want, of course. As for the real interfaces, the reason I specify the state is so that I am certain that only packets in those three states (NEW,RELATED,ESTABLISHED) are allowed on them. In other words, there is no reason why packets in state INVALID should be allowed to enter/exit the box - which is what would happen if you use those two last rules you posted.
FYI, here is my iptables -L, does this look right? I am able to ssh to the host. http works and database queries on the local lan work.
iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere state NEW
ACCEPT tcp -- anywhere anywhere multiport dports ftp,ssh,smtp,http,https state NEW
Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere state NEW
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.