How I Secured my FreeBSD System
by che guevara
of the phonerangers
che@cheggy.net
che@phonerangers.org
www.cheggy.net
www.phonerangers.org
I'm really paranoid. I am also a geek. I got a kick out of doing this, and feel like
sharing. This is how I made my FreeBSD system as secure to the outside world as I could.
I still run X, Netscape 4.5, etc. on my system, so it isn't as secure as it could
be. If I made as secure as possible, I wouldn't be able to use it and that would suck.
Well, my paranoia paid off. Two seperate times my computer has come under what
I considered attack. The first time it came from some big corporation's server. It was
an attempt to use Back Orifice on me (which is kinda stupid cause i run freebsd, bo
only works on windows!). The second was more interesting.
Somebody portscanned me, both TCP/UDP, about ten minutes after I finger'd them.
Strange, retaliating to an unagressive finger with a portscan. I noticed the portscan
because of the unique noise my hard drive made as it wrote over thirteen hundred log
entries to disk. Well, this person found no ports open on my machine, and I found 27
open on his (without even trying UDP!). He left his SMTP port wide open.... So I sent
him some mail asking him to cut it out. Well, those were the times my security
actually stopped attacks against my machine.
The outermost layer of my security is a firewall. Your basic, everyday packet
filtering chunk of kernel code. I want to be able to talk to the outside world, but I
don't want anybody being able to talk to me. Since I have no need for other computers
to be able to initiate a connection to my machine, as few as possible can.
First the firewall allows everything to pass internally . This is accomplished with:
ipfw add 1000 pass all from any to any via lo0
I need my DNS, because being able to resolve hostnames is a good thing. I have to
use four lines here, two for my primary DNS server and two for my secondary. So:
ipfw add 1010 pass udp from {DNS server's IP} to {My IP}
ipfw add 1011 pass udp from {My IP} to {DNS server's IP}
ipfw add 1015 pass udp from {DNS server's IP} to {My IP}
ipfw add 1016 pass udp from {My IP} to {DNS server's IP}
I want to be able to connect outwards, but I don't want any connections coming in.
I enable out going TCP setup, and disable incoming TCP setup. I also have a rule passing
established TCP data, so that once I get my connection setup I can get subsequent data
in and out of my system. The setup denial rule is global, because it comes after the
out going setup rule and so the first one matches.
ipfw add 1020 pass tcp from {My IP} to any setup
ipfw add 1030 deny log tcp from any to any setup
ipfw add 1040 pass tcp from any to any established
Next I pass all ICMP, which is really only so I can ping.
ipfw add 1050 pass icmp from any to any
Finally, everything else gets denied.
ipfw add 2000 deny log ip from any to any
I have a dynamic IP dialup connection to the outside world, and so I need to be able
to change {My IP} every time I dialup and initialize my firewall. I have written two
simple scripts to get my IP out of my routing table and then sets my firewall rules
accordingly.
The first of these scripts gets my IP and then calls the second. It is named getip,
and reads:
#!/bin/sh
netstat -rn |
grep {Terminal server's IP} |
grep UH |
awk '{print $2}' |
xargs -t /root/firewall_rules
This script lists the contents of my routing table, finds the route leading to my
IP, and then sticks my IP in as the first argument to /root/firewall_rules, the second
script. This script reads:
#!/bin/sh
ipfw -f flush
ipfw add 1000 pass all from any to any via lo0
ipfw add 1010 pass udp from {DNS server's IP} to $1
...
This allows me to dynamically initialize my firewall according to the new IP which
I get assigned every time I dialup.
After my firewall, any intruder will have to deal with tcp_wrappers. My wrapper's
configuration is simple, is contained in /usr/local/etc/hosts.deny, and reads:
ALL : ALL EXCEPT localhost
This denies all hosts except localhost access to all daemons.
Alternatively, if an intruder wishes to access any port which is not covered by
inetd, they must deal with Abacus Sentry. I run Sentry in both standard TCP and UDP
modes, and cover the following ports:
TCP: 1,7,9,11,15,25,70,79,80,109,110,111,119,138,139, 143,512,513,514
515,540,2000,2001,4000,4001,6001,6667,32771,32772,32773,32774,31337,49724
UDP: 1,7,9,25,66,67,68,69,111,137,138,161,162,474,513,517,518,
635,640,641,666,700,2049,32770,32771,32772,32773,32774
This provides extensive screening of often targeted ports.
As well as running sentry, I run fakebo on UDP port 31337. This program mimics a
Back Orifice server, and will treat all recieved commands as if they were successfully
executed.
I have also taken some other miscelaneous precautions.
Behind every port on my computer I have set my kernel to log packets that were sent
to a given port but not recieved by any program bound to that port. I have done this by
changing net.inet.{tcp|udp}.log_in_vain to 1. A useful side effect of this is that it
catches TCP SYN stealth scans that hit unbound ports of my computer.
I do not run sendmail or any other MTA.
I have good passwords (as in, contain spaces, variable capitalization, etc.).
I read my logs for sign of intrusion.
I listen to my hard drive for sign of intrusion. Yes, this is true. The noise of all
those log entries getting written to disk when my security picks up on the fact that I
am getting port scanned is (in my experience) unique, and since I have a loud hard
drive I can hear it. Heehee, I love being a geek.
Other sites:
http://www.freebsd.org/
http://www.psionic.com/tools/sentry/
ftp://ftp.porcupine.org/pub/security/
http://www.insecure.org/nmap
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH