Jump to content
bogdi19

Linux security part 2

Recommended Posts

Firewalls with iptables and ipchains

Your network's first barrier against unwanted infiltrators is your firewall. You do have a firewall in place, right? If you think you don't need one, monitor your incoming network traffic some time: you might be amazed by the attention you're receiving. For instance, one of our home computers has never run a publicly accessible service, but it's hit 10-150 times per day by Web, FTP, and SSH connection requests from unfamiliar hosts. Some of these could be legitimate, perhaps web crawlers creating an index; but when the hits are coming from dialup12345.nowhere.aq in faraway Antarctica, it's more likely that some script kiddie is probing your ports. (Or the latest Windows worm is trying in vain to break in.)

Linux has a wonderful firewall built right into the kernel, so you have no excuse to be without one. As a superuser, you can configure this firewall with interfaces called ipchains and iptables. ipchains models a stateless packet filter. Each packet reaching the firewall is evaluated against a set of rules. Stateless means that the decision to accept, reject, or forward a packet is not influenced by previous packets.

iptables, in contrast, is stateful: the firewall can make decisions based on previous packets. Consider this firewall rule: "Drop a response packet if its associated request came from server.example.com." iptables can manage this because it can associate requests with responses, but ipchains cannot. Overall, iptables is significantly more powerful, and can express complex rules more simply, than ipchains.

ipchains is found in kernel Versions 2.2 and up, while iptables requires kernel Version 2.4 or higher.[1] The two cannot be used together: one or the other is chosen when the kernel is compiled.

[1] Kernel 2.0 has another interface called ipfwadm, but it's so old we won't cover it.

A few caveats before you use the recipes in this chapter:

We're definitely not providing a complete course in firewall security. ipchains and iptables can implement complex configurations, and we're just scratching the surface. Our goal, as usual, is to present useful recipes.

The recipes work individually, but not necessarily when combined. You must think carefully when mixing and matching firewall rules, to make sure you aren't passing or blocking traffic unintentionally. Assume all rules are flushed at the beginning of each recipe, using iptables -F or ipchains -F as appropriate. [Recipe 2.17]

The recipes do not set default policies (-P option) for the chains. The default policy specifies what to do with an otherwise unhandled packet. You should choose intelligent defaults consistent with your site security policy. One example for iptables is:

# iptables -P INPUT DROP

# iptables -P OUTPUT ACCEPT

# iptables -P FORWARD DROP

and for ipchains:

# ipchains -P input DENY

# ipchains -P output ACCEPT

# ipchains -P forward DENY

These permit outgoing traffic but drop incoming or forwarded packets.

The official site for iptables is netfilter/iptables project homepage - The netfilter.org project, where you can also find the Linux 2.4 Packet Filtering Howto at Linux 2.4 Packet Filtering HOWTO. Another nice iptables article is at http://www.samag.com/documents/s=1769/sam0112a/0112a.htm.

Our Firewall Philosophy

In designing a set of firewall rules for a Linux host, there are several different models we could follow. They correspond to different positions or functions of the host in your network.

Single computer

The host has a single network interface, and the firewall's purpose is to protect that host from the outside world. The principle distinction here is "this host" versus "everything else." One example is a home computer connected to a cable modem.

Multi-homed host

The host has multiple network interfaces connected to different networks, but is not acting as a router. In other words, it has an address on each of its connected networks, but it does not forward traffic across itself, nor interconnect those networks for other hosts. Such a host is called multi-homed and may be directly connected to various networks. In this case, firewall rules must distinguish among the different interfaces, addresses, and networks to which the host/router is attached, perhaps implementing different security policies on different networks. For example, the host might be connected to the Internet on one side, and a trusted private network on the other.

Router

The host has multiple network interfaces and is configured as a router. That is, the kernel's " IP forwarding" flag is on, and the host will forward packets between its connected networks as directed by its routing table. In this case, firewall rules not only must control what traffic may reach the host, but also might restrict what traffic can cross the host (as router), bound for other hosts.

For this chapter, we decided to take the first approach?single computer?as our model. The other models are also valid and common, but they require a more detailed understanding of topics beyond the scope of this book, such as IP routing, routing protocols (RIP, OSPF, etc.), address translation (NAT/NAPT), etc.

We also assume your single computer has source address verification turned on, to prevent remote hosts from pretending to be local. [Recipe 2.1] Therefore we don't address such spoofing directly in the firewall rules.

Enabling Source Address Verification

2.1.1 Problem

You want to prevent remote hosts from spoofing incoming packets as if they had come from your local machine.

2.1.2 Solution

Turn on source address verification in the kernel. Place the following code into a system boot file (i.e., linked into the /etc/rc.d hierarchy) that executes before any network devices are enabled:

#!/bin/sh

echo -n "Enabling source address verification..."

echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter

echo "done"

Or, to perform the same task after network devices are enabled:

#!/bin/sh

CONF_DIR=/proc/sys/net/ipv4/conf

CONF_FILE=rp_filter

if [ -e ${CONF_DIR}/all/${CONF_FILE} ]; then

echo -n "Setting up IP spoofing protection..."

for f in ${CONF_DIR}/*/${CONF_FILE}; do

echo 1 > $f

done

echo "done"

fi

A quicker method may be to add this line to /etc/sysctl.conf:

net.ipv4.conf.all.rp_filter = 1

and run sysctl to reread the configuration immediately:

# sysctl -p

2.1.3 Discussion

Source address verification is a kernel-level feature that drops packets that appear to come from your internal network, but do not. Enabling this feature should be your first network-related security task. If your kernel does not support it, you can set up the same effect using firewall rules, but it takes more work. [Recipe 2.2]

2.1.4 See Also

sysctl(8). Source address verification is explained in the IPCHAINS-HOWTO at http://www.linux.org/docs/ldp/howto/IPCHAINS-HOWTO-5.html#ss5.7.

Blocking Spoofed Addresses

2.2.1 Problem

You want to prevent remote hosts from pretending to be local to your network.

2.2.2 Solution

For a single machine, to prevent remote hosts from pretending to be that machine, use the following:

For iptables:

# iptables -A INPUT -i external_interface -s your_IP_address -j REJECT

For ipchains:

# ipchains -A input -i external_interface -s your_IP_address -j REJECT

If you have a Linux machine acting as a firewall for your internal network (say, 192.168.0.*) with two network interfaces, one internal and one external, and you want to prevent remote machines from spoofing internal IP addresses to the external interface, use the following:

For iptables:

# iptables -A INPUT -i external_interface -s 192.168.0.0/24 -j REJECT

Drop Versus Reject

The Linux firewall can refuse packets in two manners. iptables calls them DROP and REJECT, while ipchains uses the terminology DENY and REJECT. DROP (or DENY) simply swallows the packet, never to be seen again, and emits no response. REJECT, in contrast, responds to the packet with a friendly message back to the sender, something like "Hello, I have rejected your packet."

DROP and REJECT have pros and cons. In general, REJECT is more compliant with standards: hosts are supposed to send rejection notices. Used within your network, rejects make things easier to debug if problems occur. DROP gives a bit more security, but it's hard to say how much, and it increases the risk of other network-related problems for you. A DROP policy makes it appear to peers that your host is turned off or temporarily unreachable due to network problems. Attempts to connect to TCP services will take a long time to fail, as clients will receive no explicit rejection (TCP "reset" message), and will keep trying to connect. This may have unexpected consequences beyond the blocking the service. For example, some services automatically attempt to use the IDENT protocol (RFC 1413) to identify their clients. If you DROP incoming IDENT connections, some of your outgoing protocol sessions may be mysteriously slow to start up, as the remote server times out attempting to identify you.

On the other hand, REJECT can leave you open to denial of service attacks, with you as the unwitting patsy. Suppose a Hostile Third Party sends you packets with a forged source address from a victim site, V. In response, you reject the packets, returning them not to the Hostile Third Party, but to victim V, owner of the source address. Voilà?you are unintentionally flooding V with rejections. If you're a large site with hundreds or thousands of hosts, you might choose DROP to prevent them from being abused in such a manner. But if you're a home user, you're probably less likely to be targeted for this sort of attack, and perhaps REJECT is fine. To further complicate matters, the Linux kernel has features like ICMP rate-limiting that mitigate some of these concerns. We'll avoid religious arguments and simply say, "Choose the solution best for your situation."

In this chapter, we stick with REJECT for simplicity, but you may feel free to tailor the recipes more to your liking with DROP or DENY. Also note that iptables supports a variety of rejection messages: "Hello, my port is unreachable," "Bummer, that network is not accessible," "Sorry I'm not here right now, but leave a message at the beep," and so forth. (OK, we're kidding about one of those.) See the ?reject-with option.

For ipchains:

# ipchains -A input -i external_interface -s 192.168.0.0/24 -j REJECT

2.2.3 Discussion

For a single machine, simply enable source address verification in the kernel. [Recipe 2.1]

2.2.4 See Also

iptables(8), ipchains(8).

Blocking All Network Traffic

2.3.1 Problem

You want to block all network traffic by firewall.

2.3.2 Solution

For iptables:

# iptables -F

# iptables -A INPUT -j REJECT

# iptables -A OUTPUT -j REJECT

# iptables -A FORWARD -j REJECT

For ipchains:

# ipchains -F

# ipchains -A input -j REJECT

# ipchains -A output -j REJECT

# ipchains -A forward -j REJECT

2.3.3 Discussion

You could also stop your network device altogether with ifconfig [Recipe 3.2] or even unplug your network cable. It all depends on what level of control you need.

The target REJECT sends an error packet in response to the incoming packet. You can tailor iptables's error packet using the option ?reject-with. Alternatively, you can specify the targets DROP (iptables) and DENY (ipchains) that simply absorb the packet and produce no response. See Drop Versus Reject.

2.3.4 See Also

iptables(8), ipchains(8).

Rules in a chain are evaluated in sequential order.

Blocking Incoming Traffic

2.4.1 Problem

You want to block all incoming network traffic, except from your system itself. Do not affect outgoing traffic.

2.4.2 Solution

For iptables:

# iptables -F INPUT

# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT

# iptables -A INPUT -j REJECT

For ipchains:

# ipchains -F input

# ipchains -A input -i lo -j ACCEPT

# ipchains -A input -p tcp --syn -j REJECT

# ipchains -A input -p udp --dport 0:1023 -j REJECT

2.4.3 Discussion

The iptables recipe takes advantage of statefulness, permitting incoming packets only if they are part of established outgoing connections. All other incoming packets are rejected.

The ipchains recipe accepts all packets from yourself. The source can be either your actual IP address or the loopback address, 127.0.0.1; in either case, the traffic is delivered via the loopback interface, lo. We then reject TCP packets that initiate connections (?syn) and all UDP packets on privileged ports. This recipe has a disadvantage, however, which is that you have to list the UDP port numbers. If you run other UDP services on nonprivileged ports (1024 and up), you'll have to modify the port list. But even so there's a catch: some outgoing services allocate a randomly numbered, nonprivileged port for return packets, and you don't want to block it.

Don't simply drop all input packets, e.g.:

# ipchains -F input

# ipchains -A input -j REJECT

as this will block responses returning from your legitimate outgoing connections.

iptables also supports the ?syn flag to process TCP packets:

# iptables -A INPUT -p tcp --syn -j REJECT

As with ipchains, this rule blocks TCP/IP packets used to initiate connections. They have their SYN bit set but the ACK and FIN bits unset.

If you block all incoming traffic, you will block ICMP messages required by Internet standards (RFCs); see http://rfc.net/rfc792.html and ICMP Packet Filtering v1.2.

2.4.4 See Also

iptables(8), ipchains(8).

Blocking Outgoing Traffic

2.5.1 Problem

Drop all outgoing network traffic. If possible, do not affect incoming traffic.

2.5.2 Solution

For iptables:

# iptables -F OUTPUT

# iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT

# iptables -A OUTPUT -j REJECT

For ipchains:

# ipchains -F output

# ipchains -A output -p tcp ! --syn -j ACCEPT

# ipchains -A output -j REJECT

Depending on your shell, you might need to escape the exclamation point.

2.5.3 Discussion

This recipe takes advantage of iptables's statefulness. iptables can tell the difference between outgoing traffic initiated from the local machine and outgoing traffic in response to established incoming connections. The latter is permitted, but the former is not.

ipchains is stateless but can recognize (and reject) packets with the SYN bit set and the ACK and FIN bits cleared, thereby permitting established and incoming TCP connections to function. However, this technique is insufficient for UDP exchanges: you really need a stateful firewall for that.

2.5.4 See Also

iptables(8), ipchains(8).

Blocking Incoming Service Requests

2.6.1 Problem

You want to block connections to a particular network service, for example, HTTP.

2.6.2 Solution

To block all incoming HTTP traffic:

For iptables:

# iptables -A INPUT -p tcp --dport www -j REJECT

For ipchains:

# ipchains -A input -p tcp --dport www -j REJECT

To block incoming HTTP traffic but permit local HTTP traffic:

For iptables:

# iptables -A INPUT -p tcp -i lo --dport www -j ACCEPT

# iptables -A INPUT -p tcp --dport www -j REJECT

For ipchains:

# ipchains -A input -p tcp -i lo --dport www -j ACCEPT

# ipchains -A input -p tcp --dport www -j REJECT

2.6.3 Discussion

You can also block access at other levels such as TCP-wrappers. [Recipe 3.9][Recipe 3.11]

2.6.4 See Also

iptables(8), ipchains(8).

Blocking Access from a Remote Host

2.7.1 Problem

You want to block incoming traffic from a particular host.

2.7.2 Solution

To block all access by that host:

For iptables:

# iptables -A INPUT -s remote_IP_address -j REJECT

For ipchains:

# ipchains -A input -s remote_IP_address -j REJECT

To block requests for one particular service, say, the SMTP mail service:

For iptables:

# iptables -A INPUT -p tcp -s remote_IP_address --dport smtp -j REJECT

For ipchains:

# ipchains -A input -p tcp -s remote_IP_address --dport smtp -j REJECT

To admit some hosts but block all others:

For iptables :

# iptables -A INPUT -s IP_address_1 [-p protocol --dport service] -j ACCEPT

# iptables -A INPUT -s IP_address_2 [-p protocol --dport service] -j ACCEPT

# iptables -A INPUT -s IP_address_3 [-p protocol --dport service] -j ACCEPT

# iptables -A INPUT [-p protocol --dport service] -j REJECT

For ipchains:

# ipchains -A input -s IP_address_1 [-p protocol --dport service] -j ACCEPT

# ipchains -A input -s IP_address_2 [-p protocol --dport service] -j ACCEPT

# ipchains -A input -s IP_address_3 [-p protocol --dport service] -j ACCEPT

# ipchains -A input [-p protocol --dport service] -j REJECT

2.7.3 Discussion

You can also block access at other levels such as TCP-wrappers. [Recipe 3.9][Recipe 3.11]

2.7.4 See Also

iptables(8), ipchains(8).

Blocking Access to a Remote Host

2.8.1 Problem

You want to block outgoing traffic to a particular host.

2.8.2 Solution

To block all access:

For iptables:

# iptables -A OUTPUT -d remote_IP_address -j REJECT

For ipchains:

# ipchains -A output -d remote_IP_address -j REJECT

To block a particular service, such as a remote web site:

For iptables:

# iptables -A OUTPUT -p tcp -d remote_IP_address --dport www -j REJECT

For ipchains:

# ipchains -A output -p tcp -d remote_IP_address --dport www -j REJECT

2.8.3 Discussion

Perhaps you've discovered that a particular web site has malicious content on it, such as a trojan horse. This recipe will prevent all of your users from accessing that site. (We don't consider "redirector" web sites, such as Hide IP and Anonymous Web Browsing Software — Anonymizer, which would get around this restriction.)

2.8.4 See Also

iptables(8), ipchains(8).

Blocking Outgoing Access to All Web Servers on a Network

2.9.1 Problem

You want to prevent outgoing access to a network, e.g., all web servers at yahoo.com.

2.9.2 Solution

Figure out how to specify the yahoo.com network, e.g., 64.58.76.0/24, and reject web access:

For iptables:

# iptables -A OUTPUT -p tcp -d 64.58.76.0/24 --dport www -j REJECT

For ipchains:

# ipchains -A output -p tcp -d 64.58.76.0/24 --dport www -j REJECT

2.9.3 Discussion

Here the network is specified using Classless InterDomain Routing (CIDR) mask format, a.b.c.d/N, where N is the number of bits in the netmask. In this case, N=24, so the first 24 bits are the network portion of the address.

2.9.4 See Also

iptables(8), ipchains(8).

You can supply hostnames instead of IP addresses in your firewall rules. If DNS reports multiple IP addresses for that hostname, a separate rule will be created for each IP address. For example, Yahoo! România has (at this writing) 11 IP addresses:

$ host Yahoo! România

Yahoo! România is an alias for akadns.net.

akadns.net has address 216.109.125.68

akadns.net has address 64.58.76.227

...

So you could block access to Yahoo, for example, and view the results by:

iptables:

# iptables -A OUTPUT -d Yahoo! România -j REJECT

# iptables -L OUTPUT

ipchains:

# ipchains -A output -d Yahoo! România -j REJECT

# ipchains -L output

Security experts recommend that you use only IP addresses in your rules, not hostnames, since an attacker could poison your DNS and circumvent rules defined for hostnames. However, the hostnames are relevant only at the moment you run iptables or ipchains to define a rule, as the program looks up the underlying IP addresses immediately and stores them in the rule. So you could conceivably use hostnames for convenience when defining your rules, then check the results (via the output of iptables-save or ipchains-save [Recipe 2.19]) to confirm the IP addresses.

Blocking Remote Access, but Permitting Local

2.10.1 Problem

You want only local users to access a TCP service; remote requests should be denied.

2.10.2 Solution

Permit connections via the loopback interface and reject all others.

For iptables :

# iptables -A INPUT -p tcp -i lo --dport service -j ACCEPT

# iptables -A INPUT -p tcp --dport service -j REJECT

For ipchains:

# ipchains -A input -p tcp -i lo --dport service -j ACCEPT

# ipchains -A input -p tcp --dport service -j REJECT

Alternatively, you can single out your local IP address specifically:

For iptables:

# iptables -A INPUT -p tcp ! -s your_IP_address --dport service -j REJECT

For ipchains:

# ipchains -A input -p tcp ! -s your_IP_address --dport service -j REJECT

Depending on your shell, you might need to escape the exclamation point.

2.10.3 Discussion

The local IP address can be a network specification, of course, such as a.b.c.d/N.

You can permit an unrelated set of machines to access the service but reject everyone else, like so:

For iptables:

# iptables -A INPUT -p tcp -s IP_address_1 --dport service -j ACCEPT

# iptables -A INPUT -p tcp -s IP_address_2 --dport service -j ACCEPT

# iptables -A INPUT -p tcp -s IP_address_3 --dport service -j ACCEPT

# iptables -P INPUT -j REJECT

For ipchains:

# ipchains -A input -p tcp -s IP_address_1 --dport service -j ACCEPT

# ipchains -A input -p tcp -s IP_address_2 --dport service -j ACCEPT

# ipchains -A input -p tcp -s IP_address_3 --dport service -j ACCEPT

# ipchains -P input -j REJECT

2.10.4 See Also

iptables(8), ipchains(8). Chapter 3 covers diverse, non-firewall approaches to block incoming service requests.

Controlling Access by MAC Address

2.11.1 Problem

You want only a particular machine, identified by its MAC address, to access your system.

2.11.2 Solution

# iptables -F INPUT

# iptables -A INPUT -i lo -j ACCEPT

# iptables -A INPUT -m mac --mac-source 12:34:56:89:90:ab -j ACCEPT

# iptables -A INPUT -j REJECT

ipchains does not support this feature.

2.11.3 Discussion

This technique works only within your local subnet. If you receive a packets from a machine outside your subnet, it will contain your gateway's MAC address, not that of the original source machine.

MAC addresses can be spoofed. Suppose you have a machine called mackie whose MAC address is trusted by your firewall. If an intruder discovers this fact, and mackie is down, the intruder could spoof mackie's MAC address and your firewall would be none the wiser. On the other hand, if mackie is up during the spoofing, its kernel will start screaming (via syslog) about duplicate MAC addresses.

Note that our recipe permits local connections from your own host; these arrive via the loopback interface.

2.11.4 See Also

iptables(8), ipchains(8).

Permitting SSH Access Only

2.12.1 Problem

You want to permit incoming SSH access but no other incoming access. Allow local connections to all services, however.

2.12.2 Solution

For iptables:

# iptables -F INPUT

# iptables -A INPUT -p tcp --dport ssh -j ACCEPT

# iptables -A INPUT -i lo -j ACCEPT

# iptables -A INPUT -j REJECT

For ipchains:

# ipchains -F input

# ipchains -A input -p tcp --dport ssh -j ACCEPT

# ipchains -A input -i lo -j ACCEPT

# ipchains -A input -j REJECT

2.12.3 Discussion

A common setup is to permit access to a remote machine only by SSH. If you want this access limited to certain hosts or networks, list them by IP address as follows:

For iptables :

# iptables -A INPUT -p tcp -s 128.220.13.4 --dport ssh -j ACCEPT

# iptables -A INPUT -p tcp -s 71.54.121.19 --dport ssh -j ACCEPT

# iptables -A INPUT -p tcp -s 152.16.91.0/24 --dport ssh -j ACCEPT

# iptables -A INPUT -j REJECT

For ipchains:

# ipchains -A input -p tcp -s 128.220.13.4 --dport ssh -j ACCEPT

# ipchains -A input -p tcp -s 71.54.121.19 --dport ssh -j ACCEPT

# ipchains -A input -p tcp -s 152.16.91.0/24 --dport ssh -j ACCEPT

# ipchains -A input -j REJECT

The REJECT rule in the preceding iptables and ipchains examples prevents all other incoming connections. If you want to prevent only SSH connections (from nonapproved hosts), use this REJECT rule instead:

For iptables:

# iptables -A INPUT -p tcp --dport ssh -j REJECT

For ipchains:

# ipchains -A input -p tcp --dport ssh -j REJECT

Alternatively you can use TCP-wrappers. [Recipe 3.9] [Recipe 3.11] [Recipe 3.13]

2.12.4 See Also

iptables(8), ipchains(8), ssh(1).

Prohibiting Outgoing Telnet Connections

2.13.1 Problem

You want to block outgoing Telnet connections.

2.13.2 Solution

To block all outgoing Telnet connections:

For iptables:

# iptables -A OUTPUT -p tcp --dport telnet -j REJECT

For ipchains:

# ipchains -A output -p tcp --dport telnet -j REJECT

To block all outgoing Telnet connections except to yourself from yourself:

For iptables:

# iptables -A OUTPUT -p tcp -o lo --dport telnet -j ACCEPT

# iptables -A OUTPUT -p tcp --dport telnet -j REJECT

For ipchains:

# ipchains -A output -p tcp -i lo --dport telnet -j ACCEPT

# ipchains -A output -p tcp --dport telnet -j REJECT

2.13.3 Discussion

Telnet is notoriously insecure in its most common form, which transmits your login name and password in plaintext over the network. This recipe is a sneaky way to encourage your users to find a more secure alternative, such as ssh. (Unless your users are running Telnet in a secure fashion with Kerberos authentication. [Recipe 4.15])

2.13.4 See Also

iptables(8), ipchains(8), telnet(1).

Protecting a Dedicated Server

2.14.1 Problem

You want to run a specific set of services on your machine, accessible to the outside world. All other services should be rejected and logged. Internally, however, local users can access all services.

2.14.2 Solution

Suppose your services are www, ssh, and smtp.

For iptables :

# iptables -F INPUT

# iptables -A INPUT -i lo -j ACCEPT

# iptables -A INPUT -m multiport -p tcp --dport www,ssh,smtp -j ACCEPT

# iptables -A INPUT -j LOG -m limit

# iptables -A INPUT -j REJECT

For ipchains:

# ipchains -F input

# ipchains -A input -i lo -j ACCEPT

# ipchains -A input -p tcp --dport www -j ACCEPT

# ipchains -A input -p tcp --dport ssh -j ACCEPT

# ipchains -A input -p tcp --dport smtp -j ACCEPT

# ipchains -A input -l -j REJECT

2.14.3 Discussion

Local connections from your own host arrive via the loopback interface.

2.14.4 See Also

iptables(8), ipchains(8).

Preventing pings

2.15.1 Problem

You don't want remote sites to receive responses if they ping you.

2.15.2 Solution

For iptables :

# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

For ipchains:

# ipchains -A input -p icmp --icmp-type echo-request -j DENY

2.15.3 Discussion

In this case, we use DROP and DENY instead of REJECT. If you're trying to hide from pings, then replying with a rejection kind of defeats the purpose, eh?

Don't make the mistake of dropping all ICMP messages, e.g.:

WRONG!! DON'T DO THIS!

# iptables -A INPUT -p icmp -j DROP

because pings are only one type of ICMP message, and you might not want to block all types. That being said, you might want to block some others, like redirects and source quench. List the available ICMP messages with:

$ iptables -p icmp -h

$ ipchains -h icmp

2.15.4 See Also

iptables(8), ipchains(8). The history of ping, by its author, is at The Story of the PING Program.

Listing Your Firewall Rules

2.16.1 Problem

You want to see your firewall rules.

2.16.2 Solution

For iptables:

# iptables -L [chain]

For ipchains:

# ipchains -L [chain]

For more detailed output, append the -v option.

If iptables takes a long time to print the rule list, try appending the -n option to disable reverse DNS lookups. Such lookups of local addresses, such as 192.168.0.2, may cause delays due to timeouts.

2.16.3 Discussion

An iptables rule like:

# iptables -A mychain -p tcp -s 1.2.3.4 -d 5.6.7.8 --dport smtp -j chain2

has a listing like:

Chain mychain (3 references)

target prot opt source destination

chain2 tcp -- 1.2.3.4 5.6.7.8 tcp dpt:smtp

which is basically a repeat of what you specified: any SMTP packets from IP address 1.2.3.4 to 5.6.7.8 should be forwarded to target chain2. Here's a similar ipchains rule that adds logging:

# ipchains -A mychain -p tcp -s 1.2.3.4 -d 5.6.7.8 --dport smtp -l -j chain2

Its listing looks like:

Chain mychain (3 references):

target prot opt source destination ports

chain2 tcp ----l- 1.2.3.4 5.6.7.8 any -> smtp

A detailed listing (-L -v) adds packet and byte counts and more:

Chain mychain (3 references):

pkts bytes target prot opt tosa tosx ifname source destination ports

15 2640 chain2 tcp ----l- 0xFF 0x00 any 1.2.3.4 5.6.7.8 any -> smtp

Another way to view your rules is in the output of iptables-save or ipchains-save [Recipe 2.19], but this more concise format is not as readable. It's meant only to be processed by iptables-restore or ipchains-restore, respectively:

# ipchains-save

... Saving 'mychain'.

-A foo -s 1.2.3.4/255.255.255.255 -d 5.6.7.8/255.255.255.255 25:25 -p 6 -j chain2 -l

2.16.4 See Also

iptables(8), ipchains(8).

Deleting Firewall Rules

2.17.1 Problem

You want to delete firewall rules, individually or all at once.

2.17.2 Solution

To delete rules en masse, also called flushing a chain, do the following:

For iptables:

# iptables -F [chain]

For ipchains:

# ipchains -F [chain]

To delete rules individually:

For iptables:

# iptables -D chain rule_number

For ipchains:

# ipchains -D chain rule_number

2.17.3 Discussion

Rules are numbered beginning with 1. To list the rules:

# iptables -L

# ipchains -L

select one to delete (say, rule 4 on the input chain), and type:

# iptables -D INPUT 4

# ipchains -D input 4

If you've previously saved your rules and want your deletions to remain in effect after the next reboot, re-save the new configuration. [Recipe 2.19]

2.17.4 See Also

iptables(8), ipchains(8).

Inserting Firewall Rules

2.18.1 Problem

Rather than appending a rule to a chain, you want to insert or replace one elsewhere in the chain.

2.18.2 Solution

Instead of the -A option, use -I to insert or -R to replace. You'll need to know the numeric position, within the existing rules, of the new rule. For instance, to insert a new rule in the fourth position in the chain:

# iptables -I chain 4 ...specification...

# ipchains -I chain 4 ...specification...

To replace the second rule in a chain:

# iptables -R chain 2 ...specification...

# ipchains -R chain 2 ...specification...

2.18.3 Discussion

When you insert a rule at position N in a chain, the old rule N becomes rule N+1, rule N+1 becomes rule N+2, and so on. To see the rules in a chain in order, so you can determine the right numeric offset, list the chain with -L. [Recipe 2.16]

2.18.4 See Also

iptables(8), ipchains(8).

Saving a Firewall Configuration

2.19.1 Problem

You want to save your firewall configuration.

2.19.2 Solution

Save your settings:

For iptables :

# iptables-save > /etc/sysconfig/iptables

For ipchains:

# ipchains-save > /etc/sysconfig/ipchains

The destination filename is up to you, but some Linux distributions (notably Red Hat) refer to the files we used, inside their associated /etc/init.d scripts.

2.19.3 Discussion

ipchains-save and iptables-save print your firewall rules in a text format, readable by ipchains-restore and iptables-restore, respectively. [Recipe 2.20]

Our recipes using iptables-save, iptables-restore, ipchains-save, and ipchains-restore will work for both Red Hat and SuSE. However, SuSE by default takes a different approach. Instead of saving and restoring rules, SuSE builds rules from variables set in /etc/sysconfig/SuSEfirewall2.

2.19.4 See Also

iptables-save(8), ipchains-save(8), iptables(8), ipchains(8).

Loading a Firewall Configuration

2.20.1 Problem

You want to load your firewall rules, e.g., at boot time.

2.20.2 Solution

Use ipchains-restore or iptables-restore. Assuming you've saved your firewall configuration in /etc/sysconfig: [Recipe 2.19]

For iptables:

#!/bin/sh

echo 1 > /proc/sys/net/ipv4/ip_forward (optional)

iptables-restore < /etc/sysconfig/iptables

For ipchains:

#!/bin/sh

echo 1 > /proc/sys/net/ipv4/ip_forward (optional)

ipchains-restore < /etc/sysconfig/ipchains

To tell Red Hat Linux that firewall rules should be loaded at boot time:

# chkconfig iptables on

# chkconfig ipchains on

2.20.3 Discussion

Place the load commands in one of your system rc files. Red Hat Linux already has rc files "iptables" and "ipchains" in /etc/init.d that you can simply enable using chkconfig. SuSE Linux, in contrast, has a script /sbin/SuSEpersonal-firewall that invokes iptables or ipchains rules, and it's optionally started by /etc/init.d/personal-firewall.initial and /etc/init.d/personal-firewall.final at boot time.

To roll your own solution, you can write a script like the following and invoke it from an rc file of your choice:

#!/bin/sh

# Uncomment either iptables or ipchains

PROGRAM=/usr/sbin/iptables

#PROGRAM=/sbin/ipchains

FIREWALL=`/bin/basename $PROGRAM`

RULES_FILE=/etc/sysconfig/${FIREWALL}

LOADER=${PROGRAM}-restore

FORWARD_BIT=/proc/sys/net/ipv4/ip_forward

if [ ! -f ${RULES_FILE} ]

then

echo "$0: Cannot find ${RULES_FILE}" 1>&2

exit 1

fi

case "$1" in

start)

echo 1 > ${FORWARD_BIT}

${LOADER} < ${RULES_FILE} || exit 1

;;

stop)

${PROGRAM} -F # Flush all rules

${PROGRAM} -X # Delete user-defined chains

echo 0 > ${FORWARD_BIT}

;;

*)

echo "Usage: $0 start|stop" 1>&2

exit 1

;;

esac

Make sure you load your firewall rules for all appropriate runlevels where networking is enabled. On most systems this includes runlevels 2 (multiuser without NFS), 3 (full multiuser), and 5 (X11). Check /etc/inittab to confirm this, and use chkconfig to list the status of the networking service at each runlevel:

$ chkconfig --list network

network 0:off 1:off 2:on 3:on 4:on 5:on 6:off

2.20.4 See Also

iptables-load(8), ipchains-load(8), iptables(8), ipchains(8).

Testing a Firewall Configuration

2.21.1 Problem

You want to create and test an ipchains configuration nondestructively, i.e., without affecting your active firewall.

2.21.2 Solution

Using ipchains, create a chain for testing:

# ipchains -N mytest

Insert your rules into this test chain:

# ipchains -A mytest ...

# ipchains -A mytest ....

Specify a test packet:

SA=source_address

SP=source_port

DA=destination_address

DP=destination_port

P=protocol

I=interface

Simulate sending the packet through the test chain:

# ipchains -v -C mytest -s $SA --sport $SP -d $DA --dport $DP -p $P -i $I

At press time, iptables does not have a similar feature for testing packets against rules. iptables 1.2.6a has a -C option and provides this teaser:

# iptables -v -C mytest -p $P -s $SA --sport $SP -d $DA --dport $DP -i $I

iptables: Will be implemented real soon. I promise ;)

but the iptables FAQ (netfilter/iptables FAQ) indicates that the feature might never be implemented, since checking a single packet against a stateful firewall is meaningless: decisions can depend on previous packets.

2.21.3 Discussion

This process constructs a packet with its interface, protocol, source, and destination. The response is either "accepted," "denied," or "passed through chain" for user-defined chains. With -v, you can watch each rule match or not.

The mandatory parameters are:

-C chain_name

-s source_addr --sport source_port

-d dest_addr --dport dest_port

-p protocol

-i interface_name

For a more realistic test of your firewall, use nmap to probe it from a remote machine. [Recipe 9.13]

2.21.4 See Also

ipchains(8).

Building Complex Rule Trees

2.22.1 Problem

You want to construct complex firewall behaviors, but you are getting lost in the complexity.

2.22.2 Solution

Be modular: isolate behaviors into their own chains. Then connect the chains in the desired manner.

For iptables:

# iptables -N CHAIN1

# iptables -N CHAIN2

# iptables -N CHAIN3

# iptables -N CHAIN4

# iptables -N CHAIN5

Add your rules to each chain. Then connect the chains; for example:

# iptables -A INPUT ...specification... -j CHAIN1

# iptables -A CHAIN1 ...specification... -j CHAIN2

# iptables -A CHAIN2 ...specification... -j CHAIN3

# iptables -A INPUT ...specification... -j CHAIN4

# iptables -A INPUT ...specification... -j CHAIN5

to create a rule structure as in Figure 2-1.

lsc_0201.gif

For ipchains:

# ipchains -N chain1

# ipchains -N chain2

# ipchains -N chain3

# ipchains -N chain4

# ipchains -N chain5

Add your rules to each chain. Then connect the chains, for example:

# ipchains -A input ...specification... -j chain1

# ipchains -A chain1 ...specification... -j chain2

# ipchains -A chain2 ...specification... -j chain3

# ipchains -A input ...specification... -j chain4

# ipchains -A input ...specification... -j chain5

to create the same rule structure as in Figure 2-1.

2.22.3 Discussion

Connecting chains is like modular programming with subroutines. The rule:

# iptables -A CHAIN1 ...specification... -j CHAIN2

creates a jump point to CHAIN2 from this rule in CHAIN1, if the rule is satisfied. Once CHAIN2 has been traversed, control returns to the next rule in CHAIN1, similar to returning from a subroutine.

2.22.4 See Also

iptables(8), ipchains(8).

Logging Simplified

2.23.1 Problem

You want your firewall to log and drop certain packets.

2.23.2 Solution

For iptables, create a new rule chain that logs and drops in sequence:

# iptables -N LOG_DROP

# iptables -A LOG_DROP -j LOG --log-level warning --log-prefix "dropped" -m limit

# iptables -A LOG_DROP -j DROP

Then use it as a target in any relevant rules:

# iptables ...specification... -j LOG_DROP

For ipchains:

# ipchains ...specification... -l -j DROP

2.23.3 Discussion

iptables's LOG target causes the kernel to log packets that match your given specification. The ?log-level option sets the syslog level [Recipe 9.27] for these log messages and ?log-prefix adds an identifiable string to the log entries. The further options ?log-prefix, ?log-tcp-sequence, ?log-tcp-options, and ?log-ip-options affect the information written to the log; see iptables(8).

LOG is usually combined with the limit module (-m limit) to limit the number of redundant log entries made per time period, to prevent flooding your logs. You can accept the defaults (3 per hour, in bursts of at most 5 entries) or tailor them with ?limit and ?limit-burst, respectively.

ipchains has much simpler logging: just add the -l option to the relevant rules.

2.23.4 See Also

iptables(8), ipchains(8).

Sursa: eTutorials.org

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...