[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Request for comments: iptables script for use on laptops.



Hello,

Uwe Hermann a écrit :

#!/bin/sh
#------------------------------------------------------------------------------
# File: fw_laptop
# Author: Uwe Hermann <uwe@hermann-uwe.de>
# URL: http://www.hermann-uwe.de/files/fw_laptop
# License: GNU GPL (version 2, or any later version).
# $Id: fw_laptop 515 2006-05-21 17:13:43Z uh1763 $
#------------------------------------------------------------------------------

# A firewall script intended to be used on workstations / laptops. It basically
# blocks all incoming traffic and only allows minimal outgoing traffic.

# Note: This is work in progress! Any comments and suggestions are welcome!

# Thanks for comments and suggestions:
#   * Jean Christophe André <jean-christophe.andre@auf.org>
#   * Ryan Giobbi <rgiobbi@gmail.com>


#------------------------------------------------------------------------------
# Configuration.
#------------------------------------------------------------------------------

# For debugging.
# IPTABLES="/sbin/iptables -v"

IPTABLES="/sbin/iptables"
MODPROBE="/sbin/modprobe"

# Logging options.
# Note: We use --log-level debug, so that the messages are not output
# to all virtual consoles (which would be quite annoying).
# Alternative: Start klogd with -c 4 (e.g. by setting KLOGD="-c 4" in the
# /etc/init.d/klogd startup-script.
LOG="LOG --log-level debug --log-tcp-sequence --log-tcp-options"
LOG="$LOG --log-ip-options"

# Load required kernel modules (if automatic module loading is disabled).
$MODPROBE ip_conntrack_ftp


#------------------------------------------------------------------------------
# Kernel configuration.
# For details see:
#   * http://www.securityfocus.com/infocus/1711
#   * http://www.linuxgazette.com/issue77/lechnyr.html
#   * /usr/src/linux/Documentation/filesystems/proc.txt
#   * /usr/src/linux/Documentation/networking/ip-sysctl.txt
#------------------------------------------------------------------------------

# Disable IP forwarding.
# Note: Turning this on and off should reset all settings to their defaults.
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 0 > /proc/sys/net/ipv4/ip_forward

Shouldn't the first line be commented out ?

# Enable IP spoofing protection (i.e. source address verification).
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

Incomplete. The function is enabled on interface $INTERFACE when both net/ipv4/conf/all/rp_filter *and* net/ipv4/conf/$INTERFACE/rp_filter are set to 1 (logical AND). The second condition can be achieved on a specific interface by setting net/ipv4/conf/$INTERFACE/rp_filter to 1 *after* the interface is bound to IPv4 (that is, mostly, when configured with an IPv4 address), or it can be achieved on all interfaces by setting net/ipv4/conf/default/rp_filter to 1 *before* the interfaces are bound to IPv4 (which can be done in /etc/syctl.conf).

# Protect against SYN flood attacks (see http://cr.yp.to/syncookies.html).
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Ignore all (incoming + outgoing) ICMP ECHO requests (i.e. disable PING).

No, this option only ignores incoming ICMP echo requests. When set, sending echo requests (and receiving the replies) is still possible.

# Usually not a good idea, as some protocols and users need/want this.
# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all

Usually not a good idea, indeed.

# Ignore ICMP ECHO requests to broadcast/multicast addresses. We do not
# want to participate in smurf (and similar) DoS attacks.
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Log packets with impossible addresses.
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

# Don't log invalid responses to broadcast frames, they just clutter the logs.
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

# Don't accept or send ICMP redirects.
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

# Don't accept source routed packets.
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route

# Disable multicast routing. Should not be needed, usually.
# TODO: This throws an "Operation not permitted" error. Why?
# echo 0 > /proc/sys/net/ipv4/conf/all/mc_forwarding

# Disable proxy_arp. Should not be needed, usually.
echo 0 > /proc/sys/net/ipv4/conf/all/proxy_arp
# Enable secure redirects, i.e. only accept ICMP redirects for gateways
# listed in the default gateway list. Helps against MITM attacks.
echo 1 > /proc/sys/net/ipv4/conf/all/secure_redirects
# Disable bootp_relay. Should not be needed, usually.
echo 0 > /proc/sys/net/ipv4/conf/all/bootp_relay

# TODO: These may mitigate ARP poisoning attacks?
# /proc/sys/net/ipv4/neigh/*/locktime
# /proc/sys/net/ipv4/neigh/*/gc_stale_time

# TODO: Check rest of /usr/src/linux/Documentation/networking/ip-sysctl.txt.
# Are there any security-relevant options I missed? Check especially:
# icmp_ratelimit, icmp_ratemask, icmp_errors_use_inbound_ifaddr, arp_*.


#------------------------------------------------------------------------------
# Cleanup.
#------------------------------------------------------------------------------

# Delete all rules.
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F

# Delete all (non-builtin) user-defined chains.
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X

# Zero all packet and byte counters.
$IPTABLES -Z
$IPTABLES -t nat -Z
$IPTABLES -t mangle -Z


#------------------------------------------------------------------------------
# Default policies: drop everything.
#------------------------------------------------------------------------------

$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP


#------------------------------------------------------------------------------
# Custom user-defined chains.
#------------------------------------------------------------------------------

# LOG packets, then ACCEPT them.
$IPTABLES -N ACCEPTLOG
$IPTABLES -A ACCEPTLOG -j $LOG --log-prefix "ACCEPTLOG "
$IPTABLES -A ACCEPTLOG -j ACCEPT

# LOG packets, then DROP them.
$IPTABLES -N DROPLOG
$IPTABLES -A DROPLOG -j $LOG --log-prefix "DROPLOG "
$IPTABLES -A DROPLOG -j DROP

# LOG packets, then REJECT them. TCP packets are rejected with TCP Reset.
$IPTABLES -N REJECTLOG
$IPTABLES -A REJECTLOG -j $LOG --log-prefix "REJECTLOG "
$IPTABLES -A REJECTLOG -p tcp -j REJECT --reject-with tcp-reset
$IPTABLES -A REJECTLOG -j REJECT


#------------------------------------------------------------------------------
# ICMP.
#------------------------------------------------------------------------------

# Allow outgoing pings (echo request, fragmentation needed, time exceeded).

Err no, "ping" is only the echo request type. Destination unreachable (of which fragmentation needed is a sub-type), time exceeded are different ICMP types.

$IPTABLES -A OUTPUT -m state --state NEW -p icmp --icmp-type 8 -j ACCEPT $IPTABLES -A OUTPUT -m state --state NEW -p icmp --icmp-type 3 -j ACCEPT $IPTABLES -A OUTPUT -m state --state NEW -p icmp --icmp-type 11 -j ACCEPT

You will never see an ICMP types 3 or 11 with state NEW. Either they are related to an existing connection and marked with state RELATED, or they are not and they are marked with state INVALID. So the 2nd and 3rd rules will never match and are useless.

# Allow incoming pings, but rate-limit them. We don't want to be DoS'd.
$IPTABLES -A INPUT -m limit --limit 3/s --limit-burst 8 \
-p icmp --icmp-type 8 -j ACCEPT $IPTABLES -A INPUT -m limit --limit 3/s --limit-burst 8 \
          -p icmp --icmp-type 3 -j ACCEPT
$IPTABLES -A INPUT -m limit --limit 3/s --limit-burst 8 \
          -p icmp --icmp-type 11 -j ACCEPT

Same as above about the 2nd and 3rd rules.

#------------------------------------------------------------------------------
# Miscellaneous.
#------------------------------------------------------------------------------

# Drop SMB, CIFS, and related Windows traffic without logging. We don't care.
$IPTABLES -A INPUT -p tcp -m multiport \
          --sports 135,137,138,139,445,1433,1434 -j DROP
$IPTABLES -A INPUT -p udp -m multiport \
          --sports 135,137,138,139,445,1433,1434 -j DROP

Aren't you supposed to filter the destination port ?

# Hinder portscanners a bit.
$IPTABLES -A INPUT -m state --state NEW -p tcp --tcp-flags ALL ALL -j DROP
$IPTABLES -A INPUT -m state --state NEW -p tcp --tcp-flags ALL NONE -j DROP

# Limit logging in case of flooding.
# $IPTABLES -A INPUT -j LOG -m limit --limit 1/s --limit-burst 8

What is exactly the purpose of logging packets here ?

# TODO: Block known-bad IPs (see http://www.dshield.org/top10.php).
# $IPTABLES -A INPUT -s INSERT-BAD-IP-HERE -j DROPLOG


#------------------------------------------------------------------------------
# Drop any traffic from IANA-reserved IPs.
# For details see:
#   * ftp://ftp.iana.org/assignments/ipv4-address-space
#   * http://www.cymru.com/Documents/bogon-bn-agg.txt
#------------------------------------------------------------------------------

# TODO: Is this a good idea? Does it work?

Well, it can be hazardous, it may block legitimate traffic and needs to be updated after each allocation change. Even though, a block allocated to a RIR does not mean that all its addresses are actually allocated to end users.

$IPTABLES -A INPUT -s 0.0.0.0/7 -j DROP
$IPTABLES -A INPUT -s 2.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 5.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 7.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 10.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 23.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 27.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 31.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 36.0.0.0/7 -j DROP
$IPTABLES -A INPUT -s 39.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 42.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 49.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 50.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 77.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 78.0.0.0/7 -j DROP
$IPTABLES -A INPUT -s 92.0.0.0/6 -j DROP
$IPTABLES -A INPUT -s 96.0.0.0/4 -j DROP
$IPTABLES -A INPUT -s 112.0.0.0/5 -j DROP
$IPTABLES -A INPUT -s 120.0.0.0/8 -j DROP
# $IPTABLES -A INPUT -s 127.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 169.254.0.0/16 -j DROP
$IPTABLES -A INPUT -s 172.16.0.0/12 -j DROP
$IPTABLES -A INPUT -s 173.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 174.0.0.0/7 -j DROP
$IPTABLES -A INPUT -s 176.0.0.0/5 -j DROP
$IPTABLES -A INPUT -s 184.0.0.0/6 -j DROP
$IPTABLES -A INPUT -s 192.0.2.0/24 -j DROP
# $IPTABLES -A INPUT -s 192.168.0.0/16 -j DROP
$IPTABLES -A INPUT -s 197.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 198.18.0.0/15 -j DROP
$IPTABLES -A INPUT -s 223.0.0.0/8 -j DROP
$IPTABLES -A INPUT -s 224.0.0.0/3 -j DROP


#------------------------------------------------------------------------------
# Selectively allow certain special types of traffic.
#------------------------------------------------------------------------------

# Allow all ingoing and outgoing connections on the loopback interface.
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT

# Allow incoming connections related to existing allowed connections.
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow outgoing connections related to existing allowed connections.
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

You should put these rules on top of the ruleset because they are the most likely to match.

# Uncomment this (and comment the above line) to allow ALL outgoing traffic.
# $IPTABLES -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

This rule does not accept ALL traffic : packets in the INVALID state do not match.

#------------------------------------------------------------------------------
# Selectively allow certain outbound connections, block the rest.
# TODO: This could be tightened a bit more (limit source/dest port ranges).
#------------------------------------------------------------------------------

# Allow outgoing DNS requests. Few things will work without this.
$IPTABLES -A OUTPUT -m state --state NEW -p udp --dport 53 -j ACCEPT
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT

# Allow outgoing HTTP requests. Unencrypted, use with care.
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT

# Allow outgoing HTTPS requests.
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT

# Allow outgoing SMTPS requests. Do NOT allow unencrypted SMTP!
# $IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 465 -j ACCEPT

# Allow outgoing "submission" requests.
# Submission (RFC 2476) is used for sending email, and uses port 587.
# This can be encrypted or unencrypted, depending on the server (I think).
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 587 -j ACCEPT

# Allow outgoing POP3S requests. Do NOT allow unencrypted POP3!
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 995 -j ACCEPT

# Allow outgoing SSH requests.
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT

# Allow outgoing FTP requests. Unencrypted, use with care.
# Note: This usually needs the ip_conntrack_ftp kernel module.
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 21 -j ACCEPT

# Allow outgoing NNTP requests. Unencrypted, use with care.
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 119 -j ACCEPT

# Allow outgoing Tor (http://tor.eff.org) requests.
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 9001 -j ACCEPT
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 9030 -j ACCEPT
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 9031 -j ACCEPT
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 9090 -j ACCEPT
$IPTABLES -A OUTPUT -m state --state NEW -p tcp --dport 9091 -j ACCEPT

# TODO: DCHP, IRC, ICQ, ...?


#------------------------------------------------------------------------------
# Selectively allow certain inbound connections, block the rest.
#------------------------------------------------------------------------------

# Allow DNS requests.
# $IPTABLES -A INPUT -m state --state NEW -p udp --dport 53 -j ACCEPT
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT

# Allow HTTP requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT

# Allow HTTPS requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT

# Allow POP3 requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 110 -j ACCEPT

# Allow POP3S requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 995 -j ACCEPT

# Allow SMTP requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT

# Allow SSH requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT

# Allow FTP requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 21 -j ACCEPT

# Allow NNTP requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 119 -j ACCEPT

# Allow BitTorrent requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 6881 -j ACCEPT
# $IPTABLES -A INPUT -m state --state NEW -p udp --dport 6881 -j ACCEPT

# # Allow nc requests.
# $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 2030 -j ACCEPT
# $IPTABLES -A INPUT -m state --state NEW -p udp --dport 2030 -j ACCEPT


#------------------------------------------------------------------------------
# Log and drop / reject everything else.
#------------------------------------------------------------------------------

# Explicitly REJECT (not DROP) incoming auth requests for increased speed.
$IPTABLES -A INPUT -m state --state NEW -p tcp --dport 113 -j REJECTLOG

$IPTABLES -A INPUT -j DROPLOG

REJECT for all undesired although valid (i.e. not INVALID) packets would be more RFC-compliant.

$IPTABLES -A OUTPUT -j REJECTLOG
$IPTABLES -A FORWARD -j DROPLOG


#------------------------------------------------------------------------------
# Exit gracefully.
#------------------------------------------------------------------------------

exit 0



Reply to: