Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Basic firewall question:

How do I set up the firewall on a system in a LAN so that some ports are only open to connections from the local area network, and not from the outside world?

For instance, I have a box running Scientific Linux 6.1 (a RHEL based distro), and I want its SSH server to only accept connections from localhost or LAN?

Thanks.

share|improve this question

4 Answers 4

up vote 6 down vote accepted

With the kernel's iptables completely empty (iptables -F), this will do what you ask:

# iptables -A INPUT -p tcp --dport 22 -s 192.168.0.0/24 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -s 127.0.0.0/8 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j DROP

This says that all LAN addresses are allowed to talk to TCP port 22, that localhost gets the same consideration (yes, 127.* not just 127.0.0.1), and packets from every other address not matching those first two rules get unceremoniously dropped into the bit bucket. You can use REJECT instead of DROP if you want an active rejection (TCP RST) instead of making TCP port 22 a black hole for packets.

If your LAN doesn't use the 192.168.0.* block, you will naturally need to change the IP and mask on the first line to match your LAN's IP scheme.

These commands may not do what you want if your firewall already has some rules configured. (Say iptables -L as root to find out.) What frequently happens is that one of the existing rules grabs the packets you're trying to filter, so that appending new rules has no effect. While you can use -I instead of -A with the iptables command to splice new rules into the middle of a chain instead of appending them, it's usually better to find out how the chains get populated on system boot and modify that process so your new rules always get installed in the correct order.

On RHEL type systems, the easiest way to modify firewall chains when ordering matters is to edit /etc/sysconfig/iptables. The OS's GUI and TUI firewall tools are rather simplistic, so once you start adding more complex rules like this, it's better to go back to good old config files. Beware, once you start doing this, you risk losing your changes if you ever use the OS's firewall tools to modify the configuration, since it may not know how to deal with handcrafted rules like these.

Add something like this to that file:

-A RH-Firewall-1-INPUT -p tcp --dport 22 -s 192.168.0.0/24 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 22 -s 127.0.0.0/8 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 22 -j DROP

Where you add it is the tricky bit. If you find a line in that file talking about --dport 22, simply replace it with the three lines above. Otherwise, it should probably go before the first existing line ending in -j ACCEPT. Generally, you'll need to acquire some familiarity with the way iptables works, at which point the correct insertion point will be obvious.

Save that file, then say service iptables restart to reload the firewall rules. Be sure to do this while logged into the console, in case you fat-finger the edits! You don't want to lock yourself out of your machine while logged in over SSH.

The similarity to the commands above is no coincidence. Most of this file consists of arguments to the iptables command. The differences relative to the above are that the iptables command is dropped and the INPUT chain name becomes the special RHEL-specific RH-Firewall-1-INPUT chain. (If you care to examine the file in more detail, you'll see earlier in the file where they've essentially renamed the INPUT chain. Why? Couldn't say.)

share|improve this answer

The low-level tool for firewall setup under Linux is iptables. There are also higher-level tools available. I don't know if Scientific Linux has a recommended firewall tool.

According to this web page (I haven't verified that it applies to 6.1), service iptables save will save the current firewall rules, and these saved rules are loaded at boot time. So you need to set up the rules you want through iptables commands (or any other means), then run service iptables save to make your setup persistent.

Scott Pack's blog post is a start for dropping “oddball” packets that aren't usually needed and have a high risk of being part of an attack. Beyond that, you'll want to close all incoming ports, and open only the ones you need. Something like this:

# Accept everything on the loopback interface
iptables -A INPUT -i lo -j ACCEPT
# Accept ICMP
iptables -A INPUT -p icmp --icmp-type any -j ACCEPT
# Drop oddball packets
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -f -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# Accept packets that are part of established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Accept selected incoming connections, e.g. ssh from 10.0.42.x
iptables -A INPUT -p tcp --dport 22 -s 10.0.42.0/24 -j ACCEPT
# Reject incoming connections that aren't explicitly accepted
iptables -A INPUT -j REJECT
share|improve this answer
1  
Gilles, didn't you misread the question a little bit? I understand that the Scientific Linux box is one of the computers on LAN, but not the firewall. –  rozcietrzewiacz Aug 30 '11 at 22:49
    
@Gilles Yes, the box is one of the computers on the LAN. –  hpy Aug 30 '11 at 22:51
    
@rozcietrzewiacz I understand that the firewall is on the same machine as the server. I agree that the question is ambiguous to some extent, but since penyuan only mentioned the OS of one machine, I presume everything is happening on that machine. Otherwise this wouldn't be a unix question, this would be an underspecified network admin question. –  Gilles Aug 30 '11 at 22:52

The preferred way to do it is with iptables. It looks as though that's been adequately covered by others, so, just for completeness, I'll point out an alternative access control method that is available for many daemons on most Linux distros. That access control method is provided by the libwrap library.

To check whether your favourite daemon has libwrap support, try running the following:

ldd `which sshd` | grep libwrap

If you get a non-empty result, such as

libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f84e7b0e000)

then you are definitely good to go.

It's almost a certainty that your sshd daemon does have libwrap support, and so it should consult the /etc/hosts.allow and /etc/hosts.deny files for access control. Assuming your local LAN network is 192.168.100.0/24, you can deny access to sshd to all clients except those on the local host or on the local LAN by putting the following into your /etc/hosts.deny file:

sshd: ALL EXCEPT 127.0.0.0/255.0.0.0, [::1]/128, 192.168.100.0/255.255.255.0

Note that this method does not actually open or close ports, per se. It simply tells daemons that use this method of access control whether to accept or reject connection attempts from clients that match the given pattern(s).

For complete details, check out the man pages, starting with hosts_access(5).

share|improve this answer

If you have your own linux-based firewall, you'd best setup iptables, as others describe here. If not and the firewall is your router, then most probably the default configuration already prevents access from outside, unless you explicitly enable port forwarding (as I recently described in answer to this question).

For additional security above that, you can use a separate subnet for in-LAN connections. To do so, for each computer add a second IP address that would be used only within LAN and not by the router. Let's say the whole LAN is now using 192.168.0.xxx addresses and the router (gateway, firewall) is 192.168.0.1. So add a second address for each computer - for example:

ifconfig eth0:0 192.168.5.1/24

Next, edit sshd configuration to use only this address (so that it would not allow connections coming on 192.168.0.xxx) - edit /etc/ssh/sshd_config and modify ListenAddress to the one of your new subnet (192.168.5.1 in the above example). That's it! If you do not configure the gateway to route that subnet's communication, it should be separated from the outside.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.