Help - Search - Members - Calendar
Full Version: Secure your freebsd box (HOWTO)
The Planet Forums > Operating Systems > BSD
facecake
Got FreeBSD... Now what? .. make it more secure of course!



Step one.
open your /etc/rc.conf in your favourite editor and make sure the following lines are in it
CODE
#syslog

syslogd_enable="YES"

syslogd_flags="-ss"



#nfs

nfs_server_enable="NO"

nfs_client_enable="NO"

portmap_enable="NO"



#/tmp

clear_tmp_enable="YES"





#motd

update_motd="NO"



#Disable 192.x.x.x 10.x.x.x 172.whaterver.it.is

tcp_extensions="NO"



#icmp broadcast pings

icmp_bmcastecho="NO"

#icmp error bandwidth limiting

icmp_bandlim="YES"

This disables NFS, and makes syslogd only listen on the unix socket (rather than port 514 either

localhost or on your

external ip(s). It also will clear /tmp on each boot.
Also we set the motd to not get overwriten everyreboot. Private addresses are disabled (we don't

want these on our server now

do we? also helps with people attemping to spoof ips
We stop answering ICMP Ping's to the broadcast address and also limit the bandwidth that icmp errors

can use (helps with anti

ddos)


Step 2,
Password security

Want even more security on your system passwords? Lets encrypt them in blowfish

open /etc/login.conf up in your editor and change your passwd_format line to

CODE
:passwd_format=blf:


also you could add
CODE
:idletime=60:

:passwordtime=30d:

:mixpasswordcase=true:

:minpasswordlen=8:

this would auto log out people after 60mins of inactivity, force passwords to be changed every

30days,
require mixedcase passwords and a min length of 8 chars for the passwords


after you have saved you changed run

CODE
cap_mkdb /etc/login.conf

to update your login database.

now for each account you will need to change your password.

CODE
passwd user


MAKE SURE YOU CHANGE THE PASSWORD FOR ROOT if you don't, you wont

be able to login

after you have done this do

CODE
cat /etc/master.passwd | grep root


if you get a result lik
CODE
root:$2$Ja41vsQ$7m12avsxV7124gALYANvHr.:0:0::0:0:Charlie &:/root:/usr/local/bin/bash

then your plain sailing (your looking for $2 after root:

also edit your /etc/auth.conf so that it contains
CODE
crypt_default=blf

Try connecting using another ssh session to check that you can still login.

[size=18]Step 3.

Editing MOTD and Issue

Simply edit your /etc/motd and then your /etc/issue

MOTD = message of the day (dispalyed AFTER the user has loged in)
issue = message "banner" before login


Step 4.
SSHD security

First of all lets make sure your non privilaged user is in the wheel group.

CODE
cat /etc/group | grep wheel


you should get something like
CODE
wheel:*:0:root,welby


if not, edit /etc/group and add
CODE
,user
where user is your username

now edit your /etc/ssh/sshd_config

make sure your config contains
CODE
Port 22

Protocol 2

PermitRootLogin no

X11Forwarding no

PrintMotd yes

PrintLastLog yes

KeepAlive yes

GatewayPorts no

PermitEmptyPasswords no

PasswordAuthentication yes

ReverseMappingCheck no

AllowTcpForwarding yes

AllowGroups ssh

Banner /etc/issue


This stops root logins, X11 forwarding, only allows users in the SSH group to login, and displays

/etc/issue on each connect.

make sure that your user is in the ssh group (same procedure as above for the wheel group)

if you don't have a ssh group. make one!
edit your /etc/group file to contain
CODE
ssh:*:24601:user

where user is your user (or a list of users in the format user1,user2,user3

Restart sshd
CODE
killall -HUP sshd

and try to login useing your normal user account


step 5.
File / Directory premisions


CODE
cd /var && mv ./tmp/* /tmp/ && rm –rf tmp && ln –s /tmp tmp

cd /var/log

chmod 600 *

chmod 640 wtmp

chmod 600 /etc/crontab

chmod 700 /root

chmod 700 /home/*

chmod 650 /etc/rc.*

chmod 600 /etc/master.passwd

touch /etc/pf.conf

chmod 600 /etc/pf.conf

This makes just one tmp (theres usually one in /var/tmp as well as /tmp)
Makes it so only root/the file owner can get acces to everything in /var/log (bar wtmp). Also

restricts /etc/crontab /root

all the home dirs master.passwd and pf.conf to access from their owners. and restricst access to

/etc/rc.*


step 6.
Sendmail
Love it or hate it, its already installed. Its up to you if you remove it (personally i would, and install qmail) but thats

your choice. HOWEVER we don't need it listening on port 537.

edit /etc/mail/sendmail.cf

and remove the line
CODE
O DaemonPortOptions=Port=587, Name=MSA, M=E

then restart sendmail
CODE
killall -HUP sendmail



step 7.
Updating "stuff"


unlike dead rat and the likes theres no "up2date" service. Instead theres the far superiour ports

collection for

packagemanagement and tools like portupgrade to update your ports. and of course CVSUP to update the

ports them self.

first of all, we need to install cvsup

CODE
cd /usr/ports/net/cvsup-without-gui

make install clean

if you don't have the ports collection available,
CODE
pkg_add -r cvsup-without-gui

This will install cvsup without its X11 gui (we don't need it!)

after this is done we need to create a supfile.

heres a copy of the one i use at SM/TP

CODE
*default host=cvsup.theplanet.com

*default base=/usr

*default prefix=/usr

*default release=cvs

*default delete use-rel-suffix

*default compress



ports-all tag=.

src-all tag=RELENG_5_2

(note, this is 5.2(.1)'s release tag, change this to your releases (at the time of posting 5.2.1 was

the newest non "beta" or "rc"
put that in a file (i use ~/sup). then run
CODE
cvsup ~/sup
and wait for it update the ports files and your kernel source (in this case

its using the 5.2 tag)

after this is done (can take 30 secs -> 10 mins) we need to install portupgrade

CODE
cd /usr/ports/sysutils/portupgrade

make install clean



Now everytime you update your ports collection you need to rebuild your index.db, do this by running

CODE
portsdb -Uu


This can take a fair while. After that, lets see what ports need to be upgraded

CODE
portversion -l "<"

This shows you all the ports that are out of date. lets update them and their dependancies

CODE
portupgrade -arR


Go grap a coffee/irn-bru/tea/40 winks/whatever this will probally take a while (depends on what

needs updated of coure)


step 8.
Recompiling Kernel

THIS CAN BORK YOUR SYSTEM IF YOU ARE NOT CAREFUL

and that again for those who don't read
THIS CAN BORK YOUR SYSTEM IF YOU ARE NOT CAREFUL

I CANNOT STRESS THIS ENOUGH, make sure you can get console access (rs232 or KVM(DRAC?)) to the

bootload just incase
to enable rs232 access to the bootload + kernel messages do the following
CODE
echo "-Dh" > /boot.config

Its also a good idea to turn on a RS232 terminal as well.
edit /etc/ttys

and look for the line

CODE
tyd0   "/usr/libexec/getty std.9600"   dialup  off secure


change it to
CODE
tyd0   "/usr/libexec/getty std.9600"   vt100  on secure



What i am going to cover here is how to enable the PF firewall on a 5.2.1 Kernel

CODE
cd /usr/src/sys/i386/conf

cp GENERIC FACECAKE


This is going to be our kernel config name (FACECAKE) change this if you want. add the following to

the file


CODE
device pf

options INET6

options RANDOM_IP_ID


for 5.3 you need

CODE
device pf

device pflog

device pfsync      

#####the below are optional, and are used for traffic shaping/prioritizing

options         ALTQ    

options         ALTQ_CBQ

options         ALTQ_RED

options         ALTQ_RIO

options         ALTQ_HFSC

options         ALTQ_CDNR

options         ALTQ_PRIQ

options         ALTQ_NOPCC



After this has been added lets make it!

CODE
cd /usr/src

make buildkernel KERNCONF=FACECAKE



that is the kernel built. Pretty painless really, but its not over yet. Before we can install it, we

have to install pf and

generate a config for it.

CODE
cd /usr/ports/security/pf/

make install clean


Here's a pretty lenient PF config file

QUOTE (/etc/pf.conf)
#scrubadubdub
scrub in all

#lets allow EVERYTHING
pass in all
pass out all

#allow SSH, just to be sure
pass in proto tcp from any to any port 22 keep state


set your pf.conf to that and that won't lock you out on rebooting the new kernel

now we can install it
CODE
make installkernel KERNCONF=FACECAKE


Its at about this point that you get your self 30 pairs of boxers, and buckle your seatbelt dorthy,

as kannsas is going bye

bye

reboot your server

CODE
shutdown -r now


start a ping on your local box to it, you should see it still beeing there, and if you've got DRAC

access, watch it, same

with serial console, watch that as well.

Hopefully everything goes fine and you can log in via ssh.


[size=18]step 9.


Spamd

spamd (pfspamd not spamassasin spamd) is a daemon that interfaces along wth pf to take know spammers

and send them to a tarpit.
the default settings for spamd are to send one character per second.
To install
cd /usr/ports/mail/spamd && make install clean

Next we need to edit our /usr/local/etc/spamd.conf file.
mv /usr/local/etc/spamd.conf.example /usr/local/etc/spamd.conf
$EDITOR /usr/local/etc/spamd.conf

CODE
all:

    :spews1:



spews1:

                  :black:

                  :msg="SPAM. Your address %A is in the spews

                  level 1 databasensee http://www.spews.org/ask.cgi?x=%An":

                  :method=http:

                  :file=www.spews.org/spews_list_level1.txt:


This will set spamd-setup to grab spews "level1" list.

Next we need to edit your pf.conf to contain
CODE
table <spamd> persist



#spamd

rdr pass inet proto tcp from <spamd> to any port smtp -> 127.0.0.1 port 8025

This creates a persistant table for spamd, and also redirects all tcp (via ipv4) from anyone in the

spamd table communicating on port 25 to 127.0.0.1 8025 (spamd)

reload your pf rules (pfctl -v -f /etc/pf.conf) and start spamd with /usr/local/etc/rc.d/pf-spamd.sh

start

and there you go, should all be updated.
check to see if they are in the spamd table by
CODE
pfctl -t spamd -T show | wc -l

theres 4697 lines in mine.

One thing to note is, that the current rc.d init script checks for spamd_enable=YES in rc.conf, but

so does spamassasin's spamd! you can happily run both, but for the moment (unless you edit the init

script) spamd_enable will enable both (only if both are installed though)

step 10.

PF
PF (the openbsd packet filter) can act brilliantly as a firewall

The pf.conf file has seven parts:

Macros, these are user made vars
Tables, these hold ips
Options, theses are the various options that you can change in pf
Scrub, this defines packets to normalise and defrag
Queueing: bandwitch / traffic shaping
Translation: NAT and redirection
Filter Rules: Firewall, blocking / allowing of packets

Note: Operators like = and != are used, also a # (thats hash, not pound (which is £), hash, ok good)

is a comment
Macros
In this section we want to define as many of the repeating items in the rules as we can, for

instance, ext_if="em0" for the external (internet facing) interfacecake. we can also define lists

in the macros, for instance, if i wanted to allow say, the planets ipalert system to access my

machine on a few ports, but didnt want to keep having to put the ips down in each rule, i could

simply do
CODE
ipalert = "{ 192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.1.0/24 }"

(note these are not the proper ips, check in orbit / open a support ticket for the proper ones for

your DC (dc2 and dc4 (and i presume 5 when it opens) have different ip alert ips) However, as stated

below, its not really practical for more than arround 5 ip (due to memory + processor power thats

taken up).
The above defines $ipalert as 192.168.0.1 - 3 and 192.168.1.0/24 (which is 192.168.1.*).

Another idea for a common macro is ports that you want everyone to be allowed access to, for

instance
CODE
plebian_ports = "{ http smtp imap }"


so, an example section of the macros section of the configuration may look like

CODE
###1. Macros



#external interface

ext_if="em0"



#pelbian ports

#ports for the plebs

plebian_ports = "{ http smtp imap 6667}"



#restricted ports

#ports for me, and me alone

restricted_ports = "{ ssh 5060 }"


Tables
tables, are much like macros, except can be used for groups of ip's only, and can also be read from

files. They also take up less memory + cpu than a list (when processing rules). tables can also be

changed "on the fly" but thats beyond the scope of this breif tutorial (may the man pages guide you

icon_razz.gif (also have a look at the openbsd pf site)
to create a simple table like we did above in the macros example, do the following

CODE
table <ipalert> { 192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.1.0/24 }


Options
I'm not going to cover any options here, bar the log interface one. this will log all droped packets

to a seperate interface on the system, called "pflog0" (usually). This will just allow us to easily

see droped packets.


########I've been writing this in the car, and will continue another time.#########
--------- END OF GUIDE FOR NOW ---------
facecake
reserved for expansion
facecake
oh i do love replying to my self icon_razz.gif


1:edit: added note, as hogie suggested, that people should be informed aobut the release tag for their cvsups
divzero
Good coverage, very useful. I actually have a customer that needed to access sendmail on 537 believe it or not. It didn't necessarily need to be 537, but sendmail needed to have an alternate port because his isp had blocked outgoing connections to anything on port 25 other than their own mail servers, I'm assuming to fight against relayers.

There are some very important sysctl vars to set as well:
security.bsd.see_other_uids=0
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1

and optionally:
kern.coredump=0

Keep the updates coming!

Craig
thoroughfare
Can we make this a sticky?

Matt
Hogie
me too
facecake
QUOTE (divzero)
Good coverage, very useful. I actually have a customer that needed to access sendmail on 537 believe it or not. It didn't necessarily need to be 537, but sendmail needed to have an alternate port because his isp had blocked outgoing connections to anything on port 25 other than their own mail servers, I'm assuming to fight against relayers.


Interesting, i never knew that sendmail also used 25 as the originateing port, i'm not a fan of sendmail at all (each to their own, but imo configuring sendmaiil is about as paiinless as getting your eyes gouged out go*tse tatooed on your retinas and then someone pouring acid in your eye sockets...)


QUOTE
There are some very important sysctl vars to set as well:
security.bsd.see_other_uids=0
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1

and optionally:
kern.coredump=0


I have got sysctl values on the list, in the near future i should be adding PF, pf with snort (and a BFD style "block"), pf with spamd to stop/slow down known spammers, and anything else i can think of / anyone can suggest.
divzero
Maybe some of the stuff from the jail thread a few months ago can be incorporated into this. I'd also like to see some info on securelevel....dunno about other people but I'm pretty tempted to set it up once my remote console support is in place and I can get into singleuser if I ever need to.

Can't wait to see the pf/spamd stuff. This forum needs some action!

Craig
Hogie
I installed spamd at work recently (Our exchange server is behind an openbsd box that does nat/firewalling for our dmz/direct connected hosts). I can tell you, that just adding the Korean/Chinese ip addresses to the <spamd> table has cut my spam attempts down from 1500 - 2000 a day to about 100-150 a day. This is without using spews or any other list, except blacklisting korean/chinese ips (We dont do any business out of the states, so these dont matter to us).
facecake
i'v not forgotton about this / stoped the updates, just busy with worky type things..... updates are still coming
facecake
just added a wee bit about spamd
facecake
and the first parts of the pf part
thoroughfare
QUOTE (facecake)
CODE
device pf

options INET6

options RANDOM_IP_ID


I get the following error when running 'make buildkernel KERNCONF=MYCONF':

CODE
config: Error: device "pf" is unknown

config: 1 errors

*** Error code 1



Stop in /usr/src.

*** Error code 1



Stop in /usr/src.


CODE
-su-2.05b# uname -a

FreeBSD myhostname.blahblahblah.com 5.2.1-RELEASE-p13 FreeBSD 5.2.1-RELEASE-p13 #1: Thu Dec  9 03:32:38 EST 2004     root@myhostname.blahblahblah.com:/usr/obj/usr/src/sys/MYCONF i386


Any ideas?

Thanks!
Matt icon_smile.gif
facecake
QUOTE (thoroughfare)
QUOTE (facecake)

CODE
device pf

options INET6

options RANDOM_IP_ID


I get the following error when running 'make buildkernel KERNCONF=MYCONF':

CODE
config: Error: device "pf" is unknown

config: 1 errors

*** Error code 1



Stop in /usr/src.

*** Error code 1



Stop in /usr/src.


CODE
-su-2.05b# uname -a

FreeBSD myhostname.blahblahblah.com 5.2.1-RELEASE-p13 FreeBSD 5.2.1-RELEASE-p13 #1: Thu Dec  9 03:32:38 EST 2004     root@myhostname.blahblahblah.com:/usr/obj/usr/src/sys/MYCONF i386


Any ideas?

Thanks!
Matt icon_smile.gif

Hi matt,
i presume you've cvsup'ed your source tree yes ?

you may have to apply a patch to 5.2.1, i can't actaully remeber. it MAY be in ports along with all the user land programs.
However, may i suggest biting the bulet and going for 5.3, its stable (hence why the RELENG_5 (stable branch) is 5.3)
thoroughfare
All cvssed up over here icon_smile.gif

I'll keep Googling icon_rolleyes.gif
Thanks Facecake!

Matt
dspielman
Here is a great how-to for securing a BSD system http://www.littlewhitedog.com/content-72.html
Yeedog
QUOTE (facecake)
CODE
cd /usr/ports/security/pf/

make install clean


when I do this i get the following message...

"pf moved to the base system, please build it from there"

I'm not exactly sure what to do here in responce to the error message. I'm running 5.3-STABLE FreeBSD 5.3-STABLE #1

Thanks!
facecake
there is no need to install pf on 5.3 as its already part of base, you can skip that step
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.