# This is the ipchains configuration I use on this site. The general policy # is "anything not explicitly allowed is denied" (and usually logged). Also, # DENY is used instead of REJECT because it doesn't send any reply at all. # Sending a reject reply shows the presence of your machine during a port # scan, even if the port is not being used. And it takes up bandwidth. # # These rules do not, however, attempt to prevent "inside" users from doing # anything bad except sending out packets with invalid source addresses. If # you are running a home network or a hosted site, this should be sufficient. # # - Bruce Tomlin - b r u c e @ x i 6 . c o m #---------------------------------------------------------------------------- # This sets up the interface name and address range for the "local" # (masqueraded) network. The actual local IP address is not needed, as the # network address range is sufficient for spoof-proofing the internal network. # # Note that I am using CIDR-style netmasks here. "/24" means 24 1-bits in # the subnet mask, which translates to "255.255.255.0". "0/0" is a netmask # of "0.0.0.0" and matches everything. #---------------------------------------------------------------------------- LOCAL_IF=eth0 LOCAL_NET=10.27.64.0/24 #---------------------------------------------------------------------------- # This sets up the interface name and addresses for the "rest of the world" # network. The second line gets the IP address of the interface, to be used # in "spoof-proofing" outgoing packets, by making sure that only packets with # the correct source address get out. If you are using DHCP, uncomment the # third line to allow packets to be sent with any source IP address. # # The magic command for WORLD_IP comes from Slackware, and is used to get # an interface address from the output of the ifconfig command. #---------------------------------------------------------------------------- WORLD_IF=eth1 WORLD_IP="`/sbin/ifconfig $WORLD_IF | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`" #WORLD_IP=0/0 #---------------------------------------------------------------------------- # This defines the interface name for my ppp link. Since the address is # dynamically assigned, there is no easy way to spoof-proof the output, # so packets are sent with any source IP address. #---------------------------------------------------------------------------- PPP_IF=ppp0 #PPP_IP="`/sbin/ifconfig ppp0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`" PPP_IP=0/0 #---------------------------------------------------------------------------- # These commands load the IP masquerading protocol translation modules. # These are needed because some protocols are not masquerade-friendly. Any # protocol which puts the IP address or a port number from a masqueraded # machine into the packet has to have the packets translated. You really # shouldn't load any of these modules (other than FTP) unless you know you # need them. # # Note that if ip_masq_raudio is not enabled, the Real Audio player should # fall back to TCP mode and still work. I prefer TCP mode myself since it # doesn't glitch as much as UDP mode. #---------------------------------------------------------------------------- # ftp masquerading module /sbin/modprobe ip_masq_ftp # real audio over UDP masquerading module /sbin/modprobe ip_masq_raudio # masquerading of IRC DCC file transfers #/sbin/modprobe ip_masq_irc # Quake I / QuakeWorld (ports 26000 and 27000) #/sbin/modprobe ip_masq_quake # Quake I/II/III / QuakeWorld (ports 26000, 27000, 27910, 27960) #/sbin/modprobe ip_masq_quake ports=26000,27000,27910,27960 # masquerading of the CuSeeme video conferencing software #/sbin/modprobe ip_masq_cuseeme # masquerading of the VDO-live video conferencing software #/sbin/modprobe ip_masq_vdolive #---------------------------------------------------------------------------- # The first command enables IP forwarding. If IP forwarding is not enabled # with this command, masquerading will not work, and you will pull your hair # out wondering why it isn't working. I believe the second command is only # needed if you are running DHCP and masquerading for other machines. But # turning it on shouldn't hurt anything, so I just leave it on. #---------------------------------------------------------------------------- # turn on IP forwarding if necessary echo "1" > /proc/sys/net/ipv4/ip_forward # turn on masquerading support for DHCP if necessary echo "1" > /proc/sys/net/ipv4/ip_dynaddr #---------------------------------------------------------------------------- # When a masqueraded connection dies on the "inside", there is no way for the # gateway (this machine) to know that has happened and clean up the # masqueraded connections. This sets the timeout values for "idle" links to # avoid using up resources for dead connections, while leaving them large # enough not to kill truly idle (or just slow) connections. #---------------------------------------------------------------------------- # MASQ timeouts # 2 hrs timeout for TCP session timeouts # 10 sec timeout for traffic after the TCP/IP "FIN" packet is received # 160 sec timeout for UDP traffic (Important for MASQ'ed ICQ users) # /sbin/ipchains -M -S 7200 10 160 #---------------------------------------------------------------------------- # --- clear out all chains --- # # This clears out any existing ipchains rules and starts with a clean slate. # Some people recommend adding a first rule of "deny everything" to the input # output and forward chains, which are removed after all the ipchains rules # are set up. I personally think that the exploitable window of time is so # small that someone would have to already be hammering away at your machine # with IP packets to even have a chance to do anything bad. #---------------------------------------------------------------------------- /sbin/ipchains -F #---------------------------------------------------------------------------- # If you are using DHCP, you need to be able to connect to the DHCP server. # By explicitly allowing it, this ensures that you will never accidentally # deny yourself access to the DHCP server. I don't use DHCP, so I leave it # commented out. #---------------------------------------------------------------------------- #/sbin/ipchains -A input -j ACCEPT -i $WORLD_IF -s 0/0 67 -d 0/0 68 -p udp #---------------------------------------------------------------------------- # --- set up filtering rules for input from the rest of the world --- # # This starts a new chain called "net-in". This chain is used to filter # packets coming in from the outside world via a "hostile" interface. #---------------------------------------------------------------------------- /sbin/ipchains -N net-in # --- spoof-proof (and log) on internal addresses --- # # If you receive a packet from the outside world that claims to be coming # from your internal network, it is probably someone trying something # naughty. Log and deny. /sbin/ipchains -A net-in -s $LOCAL_NET -l -j DENY # --- allow incoming ftp connections (ports 20 and 21) --- # # FTP is one of the more complicated filtering rules. In this case, I am # running an FTP server, so I allow any inbound connection to my ftp port. # Comment out the first line if you are not running an FTP server. # # The back-channel for FTP data (when you are a client) is created on one of # your non-privileged (1024 and above) ports, and will always receive data # from the other end's ftp-data port. However, X Windows uses ports 6000 # thru 6010 with a source port of ftp-data, so those should be filtered to # prevent people from connecting to you with their own X Windows server. # (Remember, the display is the server, and the applications are the clients.) /sbin/ipchains -A net-in -p TCP -d 0/0 ftp -j ACCEPT /sbin/ipchains -A net-in -p TCP -s 0/0 ftp-data -d 0/0 1024:5999 -j ACCEPT /sbin/ipchains -A net-in -p TCP -s 0/0 ftp-data -d 0/0 6000:6010 -l -j DENY /sbin/ipchains -A net-in -p TCP -s 0/0 ftp-data -d 0/0 6011: -j ACCEPT # --- allow incoming SSH connections (port 22) --- # # If you run a secure shell (SSH) server, uncomment this line. #/sbin/ipchains -A net-in -p TCP -d 0/0 ssh -j ACCEPT # --- allow incoming telnet connections (port 23) --- # # It's generally a bad idea to allow plain telnet connections into your # machine from the outside world, because it's so easy to snoop the protocol # for passwords. Uncomment it if you must, but don't blame me if someone # snoops your root password. #/sbin/ipchains -A net-in -p TCP -d 0/0 telnet -j ACCEPT # --- allow incoming SMTP connections (port 25) --- # # I run an e-mail server, so I need to open up my smtp port. If you don't # run an e-mail server, comment out this line. /sbin/ipchains -A net-in -p TCP -d 0/0 smtp -j ACCEPT # --- allow incoming DNS connections (port 53) --- # # I run a domain name server, so I need to open up my DNS port. If you don't # run a domain name server, comment out these lines. /sbin/ipchains -A net-in -p UDP -d 0/0 domain -j ACCEPT /sbin/ipchains -A net-in -p TCP -d 0/0 domain -j ACCEPT # --- allow incoming http connections (port 80) --- # # I run a web server, so I need to open up my www port. If you don't run a # web server, comment out this line. /sbin/ipchains -A net-in -p TCP -d 0/0 www -j ACCEPT # --- allow or reject ident requests (port 113) --- # # When you connect to services on other machines, they might send back an # ident request to find out the user name under which a give port was opened. # This is of dubious use, since many sites block these requests, but other # sites (particularly IRC servers) won't let you in or will make you wait # without an ident lookup. And connections from masqueraded machines still # won't ident. The third line does a REJECT instead of a DENY to politely # say "no thanks". # # If you want to allow ident requests, uncomment the second line. # # If you want to log ident request packets, uncomment both the first and # second lines. But there is really no need to do this, as ident does # its own logging. #/sbin/ipchains -A net-in -p TCP -d 0/0 ident -y -l -j ACCEPT /sbin/ipchains -A net-in -p TCP -d 0/0 ident -j ACCEPT /sbin/ipchains -A net-in -p TCP -d 0/0 ident -j REJECT # --- allow incoming AFP-TCP connections (port 548) --- # # If I wanted to run a publically available Appleshare server, I would # uncomment these lines. (and configure afpd to work with TCP connections) #/sbin/ipchains -A net-in -p TCP -d 0/0 afpovertcp -j ACCEPT #/sbin/ipchains -A net-in -p UDP -d 0/0 afpovertcp -j ACCEPT # --- log incoming echo-request packets (ICMP type 8) --- # # Want to know who is pinging you? This will log all incoming pings. /sbin/ipchains -A net-in -p ICMP --icmp-type 8 -l -j ACCEPT # --- deny all privileged TCP ports not explicitly allowed --- # # As stated from the start, the general policy is "anything not explicitly # allowed is denied". First, any inbound connections to unspecified # privileged ports are deined. Outbound connections don't normally come # from privileged ports, so even without the SYN flag they should be denied. /sbin/ipchains -A net-in -p TCP -s 0/0 -d 0/0 0:1023 -l -j DENY # --- allow established TCP connections --- # # If an outbound connection has already been established, and this is a # response, the SYN flag will not be present in the packet. /sbin/ipchains -A net-in -p TCP -s 0/0 -d 0/0 ! -y -j ACCEPT # --- deny all privileged UDP ports not explicitly allowed --- # # Deny inbound packets to any remaining privileged UDP port. /sbin/ipchains -A net-in -p UDP -s 0/0 -d 0/0 0:1023 -l -j DENY # --- can't one-way filter UDP or ICMP packets, so pass everything else --- # # Since UDP and ICMP are connectionless protocols, there is nothing like the # SYN flag to indicate whether an inbound packet to an unprivileged port is # valid or not. So all of them have to be accepted. You have to run # something like Psionic Portsentry to catch probes of unused UDP ports. /sbin/ipchains -A net-in -p UDP -s 0/0 -d 0/0 -j ACCEPT /sbin/ipchains -A net-in -p ICMP -s 0/0 -d 0/0 -j ACCEPT #---------------------------------------------------------------------------- # --- set up input chains --- # # This sets up the primary input chain rules. If further filtering is # needed for a "hostile" interface, the net-in rule is applied. #---------------------------------------------------------------------------- # --- default input action = deny --- # # Anything not explicitly allowed is denied. This is a catch-all in case # all the rules fail. /sbin/ipchains -P input DENY # --- loopback and local network packets are okay --- # # This accepts all packets coming in from the local "lo" interface, and all # properly addressed packets from the internal masqueraded network interface. /sbin/ipchains -A input -i lo -s 0/0 -d 0/0 -j ACCEPT /sbin/ipchains -A input -i $LOCAL_IF -s $LOCAL_NET -d 0/0 -j ACCEPT # --- install rest-of-the-world filter rules --- # # This installs the filtering rules for the "hostile" interfaces which get # packets from the rest of the world. /sbin/ipchains -A input -i $PPP_IF -j net-in /sbin/ipchains -A input -i $WORLD_IF -j net-in # --- catch-all rule logs anything not explicity accepted or rejected --- # # This denies and logs any packet that has not been already accepted. /sbin/ipchains -A input -s 0/0 -d 0/0 -l -j DENY #---------------------------------------------------------------------------- # --- set up output priority rules --- # # These rules show how you can change the type-of-service flags to tune # the system for certain types of packets. For more information, see the # ipchains-HOWTO file or other ipchains documentation. #---------------------------------------------------------------------------- /sbin/ipchains -N net-out # minimum delay for http & telnet /sbin/ipchains -A net-out -p TCP -d 0/0 80 -t 0x01 0x10 /sbin/ipchains -A net-out -p TCP -d 0/0 telnet -t 0x01 0x10 # minimum cost for ftp data, nntp, pop3 /sbin/ipchains -A net-out -p TCP -d 0/0 ftp-data -t 0x01 0x02 /sbin/ipchains -A net-out -p TCP -d 0/0 nntp -t 0x01 0x02 /sbin/ipchains -A net-out -p TCP -d 0/0 pop3 -t 0x01 0x02 #---------------------------------------------------------------------------- # --- set up output chains --- # # This sets up the primary output chain rules. #---------------------------------------------------------------------------- # --- default output action = reject --- # # Anything not explicitly allowed is denied. This is a catch-all in case # all the rules fail. # # Note that REJECT is used instead of deny, because the packets are coming # from (presumably) friendly internal machines, and we want them to get an # icmp-unreachable response so they know they "can't get there from here". /sbin/ipchains -P output REJECT # --- install outbound priority rules --- # # This lets outbound packets be "tuned" for maximum efficiency. /sbin/ipchains -A output -i $PPP_IF -j net-out /sbin/ipchains -A output -i $WORLD_IF -j net-out # --- prevent packets from escaping with internal IP addresses --- # # If the destination address is the local network, it is a case of "stuffed # routing". If the source address is the local network, it is a case of # "stuffed masquerading". Either way, this is a Bad Thing. /sbin/ipchains -A output -i $PPP_IF -b -s $LOCAL_NET -d 0/0 -l -j REJECT /sbin/ipchains -A output -i $WORLD_IF -b -s $LOCAL_NET -d 0/0 -l -j REJECT # --- if external interface IP address is known, spoof-proof outbound packets # # If you have a fixed IP address on any of your "hostile" interfaces, set up # PPP_IP, WORLD_IP, etc. to prevent "spoofed" packets from escaping. /sbin/ipchains -A output -i $PPP_IF -s $PPP_IP -d 0/0 -j ACCEPT /sbin/ipchains -A output -i $WORLD_IF -s $WORLD_IP -d 0/0 -j ACCEPT # --- accept output going to local interface and local ethernet --- # # Always allow packets to be sent to the local interface, and always allow # packets with an internal address to be sent to the internal network. /sbin/ipchains -A output -i lo -s 0/0 -d 0/0 -j ACCEPT /sbin/ipchains -A output -i $LOCAL_IF -s 0/0 -d $LOCAL_NET -j ACCEPT # --- special routing for DSL modem web interface --- # # This is a special case which allows packets to be addressed to my DSL modem # so I can use its web interface. It also requires some routing tricks. # You should probably comment this out. /sbin/ipchains -A output -i $LOCAL_IF -s 0/0 -d 10.0.0.138/32 -j ACCEPT # --- catch-all rule logs anything not explicity accepted or rejected --- # # This denies and logs any packet that has not been already accepted. /sbin/ipchains -A output -s 0/0 -d 0/0 -l -j REJECT #---------------------------------------------------------------------------- # --- set up forwarding/masquerading chains --- # # This sets up the forwarding rules, primarily for IP masquerading. # # Note that you don't want to masquerade or forward for just anybody. If # you do, people will bounce off of your system to hide their real identity, # and YOU could get blamed for any naughty things they are doing. #---------------------------------------------------------------------------- # --- default forwarding action = deny --- # # Anything not explicitly allowed is denied. This is a catch-all in case # all the rules fail. /sbin/ipchains -P forward REJECT # --- masquerade (and spoof-proof) for the local ethernet --- # # This enables masquerading for any packet coming from the internal network # and going to an "outside world" interface. /sbin/ipchains -A forward -i $PPP_IF -s $LOCAL_NET -d 0/0 -j MASQ /sbin/ipchains -A forward -i $WORLD_IF -s $LOCAL_NET -d 0/0 -j MASQ # --- catch-all rule logs anything not explicity accepted or rejected --- # # This denies and logs any packet that has not been already accepted. /sbin/ipchains -A forward -s 0/0 -d 0/0 -l -j REJECT #---------------------------------------------------------------------------- # --- put port forwarding commands here --- # # Normally, masqueraded machines can not be connected to from the outside # world, because they have no real IP address. # # If you want to run a server (such as a web server) on a machine inside a # masqueraded network, you must explicitly set forwarding for the port to # connect it to the inside machine. Use ipmasqadm with -L set to the port # number by which the server will be accessed on the internet, and -R to # set the port number of the actual server. # # This usage of "local" and "remote" may sound backwards, but it's local and # remote relative to the machine from which the ipmasqadm command is run. #---------------------------------------------------------------------------- # these are some examples: local port remote port # /usr/sbin/ipmasqadm portfw -a -P tcp -L 10.1.2.3 2000 -R 192.168.0.10 2000 # /usr/sbin/ipmasqadm portfw -a -P tcp -L 10.1.2.3 2001 -R 192.168.0.10 2001 # /usr/sbin/ipmasqadm portfw -a -P tcp -L 10.1.2.3 2002 -R 192.168.0.10 2002 # /usr/sbin/ipmasqadm portfw -a -P tcp -L 10.1.2.3 2003 -R 192.168.0.10 2003 # here is an example to forward a range of ports: # port=2000 # while [ $port -lt 2020 ] # do # /usr/sbin/ipmasqadm portfw -a -P tcp -L 10.1.2.3 $port -R 192.168.0.10 $port # port=$(port+1) # done