Customising FreeBSD

Standard

In this article, I share my my usual customisation steps to a fresh FreeBSD installation.  FreeBSD is very minimal, but one can definitely even go further.  These steps are similar to Charray’s approach to FreeBSD 8, and they are updated for FreeBSD 11 with the software RAID skipped.

Major Edited on 2 Feb 2017: Fixing the WordPress Auto-corrption.

Major Edited on 17 Feb 2017: Updating periodic configuration and firewall rules.

Step 1: Disabling Sendmail

FreeBSD has minimal set of services enabled.  However, there is one more service I want to disable—sendmail.  It is a really traditional mail server.  If you ask me, I would say there is nothing wrong with it.  I just do not want a mail server running on every server.

Simply, add this line in “/etc/rc.conf”:

sendmail_enable="NONE"

Usually, to disable a service, one use the word “NO”.  But sendmail is an exception, one has to use “NONE” to disable everything.  (You can refer to “/etc/rc.d/sendmail” if you understand the scripting language.)  To stop the sendmail, either stop the service gracefully or in brute force.  “pkill” means kill processes with the given name;  “-9” means the most forceful way:

pkill -9 sendmail

If you want to see what other services can be enabled or disabled, check “/etc/defaults/rc.conf”, just make sure not to change the default file.

Step 2: Disabling Periodic Mails

What are the consequences disabling the local mail server?  By default, FreeBSD performs some periodic checks and sends the results to the mail server, and also does some mail server housekeeping.  We can disable the mails and redirect them to the “/var/log” directory, and then also disable the mail server housekeeping.  Add these lines to a new “/etc/periodic.conf”:

daily_output="/var/log/daily.log"
weekly_output="/var/log/weekly.log"
monthly_output="/var/log/monthly.log"
daily_status_security_output="/var/log/daily.log"
weekly_status_security_output="/var/log/weekly.log"
monthly_status_security_output="/var/log/monthly.log"
daily_clean_hoststat_enable="NO"
daily_backup_aliases_enable="NO"
daily_status_mailq_enable="NO"
daily_status_include_submit_mailq="NO"
daily_status_mail_rejects_enable="NO"
daily_queuerun_enable="NO"

Since periodic mails are not long-running services (they are started indirectly by another service), the changes are taken effetely on the next run.

Step 3: Disabling Terminals

FreeBSD comes with seven virtual text terminals so one can switch between while working with it.  To my taste, I do not use these terminals, especially when it is on the cloud.  These configuration are in “/etc/ttys”.  One can change “on” to “off” to switch off the terminals “ttyv2” to “ttyv7”.  Let me be lazy and tell you the script for so.

sed -ibak '/ttyv2/s/on /off/; /ttyv3/s/on /off/; /ttyv4/s/on /off/; /ttyv5/s/on /off/; /ttyv6/s/on /off/; /ttyv7/s/on /off/' /etc/ttys

Then, to make it effective, send a hangup signal to the “init” process.  It is the very first process started directly by the kernel so it is having process number 1 every single time.

kill -HUP 1

Step 4: Enabling Time Services

Computers are usually keeping the time in inaccurate manners even if you have them constantly powered.  It is nice to have the time synchronised to somewhere better prepared.

ntpd_enable="YES"

By default, the system will point to places predefined by the FreeBSD distributions which can be changed in “/etc/ntpd.conf”.   For purpose of a single FreeBSD server, it is already good enough.  Finally, to start the service:

service ntpd start

The “ntpd” service will synchronise and drift the system clock accordingly.

Step 5: Enabling Firewall

Edit the file “/etc/pf.conf”.  This is usually the template I start from.  In short, it does the following: 1) set up a spammer table; 2) allow local network; 3) drop the spammers; 4) do not allow intranet addresses on the external interfaces; 5) allow connections to particular ports; 6) treat a user as spammer if there are more than 100 existing connections; 7) treat a user as spammer if there are more than 100 connection attempts per second.

extif="vtnet0"
tcpports="{22,80,443}"
martians="{127.0.0.0/8,192.168.0.0/16,172.16.0.0/12,
  10.0.0.0/8,169.254.0.0/16,192.0.2.0/24,
  0.0.0.0/8,240.0.0.0/4}"
table <spammers> persist
set skip on lo

block all
block drop in quick from <spammers> to any
block drop in quick on $extif from $martians to any
pass out quick inet proto udp from any to 255.255.255.255 port {67,68}
block drop out quick on $extif from any to $martians

pass out quick
pass in quick inet proto icmp from any to any
pass in quick inet proto tcp from any to any port $tcpports keep state \
  (max-src-conn 100, max-src-conn-rate 100/1 \
   overload <spammers> flush global)

Then, we add a line in “/etc/crontab” to clear the spammers after 1 day (86400 seconds).  The check is taken once every 5 minutes.  Sometimes legitimate users are blocked due to network resends.  It is therefore important to unblock them before they raise a complaint.

*/5 * * * * root /sbin/pfctl -t spammers -T expire 86400 > /dev/null 2>&1

To enable the firewall, find a physical connection (or the cloud remote management console) and issue the command:

service pf start

Your network connections will be dropped.  It is not disastrous if you can reconnect.  But it definitely is, if something is wrong with your script.  You have been warned.

Step 6: Personalisation

Personally, I like “tcsh” with autocomplete and the current directory hint in the shell.  Also, I prefer being prompted when I am going to overwrite a file.  Here is what I do to the “.cshrc” file:

alias h history 25
alias j jobs -l
alias la ls -aF
alias lf ls -FA
alias ll ls -lAF
umask 22
set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin)
setenv EDITOR vi
setenv PAGER more
setenv BLOCKSIZE K
if ($?prompt) then
  alias ls ls -G
  alias cp cp -i
  alias mv mv -i
  alias rm rm -i
  alias ln ln -i
  alias link link -i
  if ($uid == 0) then
    set user = root
  endif
  set prompt="%B%n%b@%B%m%b %B%~%b%# "
  set noclobber
  set rmstar
  set autolist
  set filec
  set history = 1000
  set savehist = (1000 merge)
  set autolist = ambiguous
  set autoexpand
  set autorehash
  set mail = (/var/mail/$USER)
  if ($?tcsh) then
     bindkey "^W" backward-delete-word
     bindkey -k up history-search-backward
     bindkey -k down history-search-forward
  endif
endif

And I want to make sure “tcsh” is my shell:

chpass -s /bin/tcsh

And finally, if I want to share this with upcoming new users, I will put it to the skeleton directory:

cp -a /root/.cshrc /usr/share/skel/dot.cshrc

And another thing I like to customise is “vim”.  I edit the “.vimrc” file as follows.  Interestingly, while some would argue it is not comprehensive enough, I really made my research-related programming on such a simple environment.

set nomodeline
set copyindent
set autoindent
set nowrap
set cc=80
syntax on

Then share it in the skeleton directory:

cp -a /root/.vimrc /usr/share/skel/dot.vimrc

Step 7: Initialisation Scripts

Finally, in Vultr, I have the initialisation scripts as follows.  This way, I can get the operating system customised to my flavour when it finishes booting.  I will skip my explanation for laziness sake.  Até a proxima semana.

#!/bin/sh -x

#
# Disable Sendmail
#
logger Disabling Sendmail
sysrc sendmail_enable="NONE"

#
# Disable Periodic Email
#
logger Disabling Periodic Emails
pfile="/etc/periodic.conf"
sysrc -f $pfile daily_output="/var/log/daily.log"
sysrc -f $pfile daily_output="/var/log/daily.log"
sysrc -f $pfile weekly_output="/var/log/weekly.log"
sysrc -f $pfile monthly_output="/var/log/monthly.log"
sysrc -f $pfile daily_status_security_output="/var/log/daily.log"
sysrc -f $pfile weekly_status_security_output="/var/log/weekly.log"
sysrc -f $pfile monthly_status_security_output="/var/log/monthly.log"
sysrc -f $pfile daily_clean_hoststat_enable="NO"
sysrc -f $pfile daily_backup_aliases_enable="NO"
sysrc -f $pfile daily_status_mailq_enable="NO"
sysrc -f $pfile daily_status_include_submit_mailq="NO"
sysrc -f $pfile daily_status_mail_rejects_enable="NO"
sysrc -f $pfile daily_queuerun_enable="NO"

#
# Disable TTYs
#
logger Disabling Virtual Terminals
sed -ibak '/ttyv2/s/on /off/; /ttyv3/s/on /off/; /ttyv4/s/on /off/; /ttyv5/s/on /off/; /ttyv6/s/on /off/; /ttyv7/s/on /off/' /etc/ttys

#
# NTP service
#
logger Configuring NTP
sysrc ntpd_enable="YES"

#
# PF service
#
logger Configuring PF
cat > /etc/pf.conf << EOF
extif="vtnet0"
tcpports="{22,80,443}"
martians="{127.0.0.0/8,192.168.0.0/16,172.16.0.0/12,
  10.0.0.0/8,169.254.0.0/16,192.0.2.0/24,
  0.0.0.0/8,240.0.0.0/4}"
table <spammers> persist
set skip on lo

block all
block drop in quick from <spammers> to any
block drop in quick on \$extif from \$martians to any
pass out quick inet proto udp from any to 255.255.255.255 port {67,68}
block drop out quick on \$extif from any to \$martians

pass out quick
pass in quick inet proto icmp from any to any
pass in quick inet proto tcp from any to any port \$tcpports keep state \
  (max-src-conn 100, max-src-conn-rate 100/1 \
   overload <spammers> flush global)
EOF
cat >> /etc/crontab << EOF
*/5 * * * * root /sbin/pfctl -t spammers -T expire 86400 > /dev/null 2>&1
EOF
sysrc pf_enable="YES"

#
# Shell environment
#
logger Configuring TCSH environment
cat > /root/.cshrc << EOF
alias h history 25
alias j jobs -l
alias la ls -aF
alias lf ls -FA
alias ll ls -lAF

umask 22

set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin \$HOME/bin)

setenv EDITOR vi
setenv PAGER more
setenv BLOCKSIZE K

if (\$?prompt) then
  alias ls ls -G
  alias cp cp -i
  alias mv mv -i
  alias rm rm -i
  alias ln ln -i
  alias link link -i

   if (\$uid == 0) then
     set user = root
   endif

   set prompt="%B%n%b@%B%m%b %B%~%b%# "
   set noclobber
   set rmstar
   set autolist
   set filec
   set history = 1000
   set savehist = (1000 merge)
   set autolist = ambiguous
   set autoexpand
   set autorehash
   set mail = (/var/mail/\$USER)
   if (\$?tcsh) then
     bindkey "^W" backward-delete-word
     bindkey -k up history-search-backward
     bindkey -k down history-search-forward
   endif
endif
EOF
cp -a /root/.cshrc /usr/share/skel/dot.cshrc
chpass -s /bin/tcsh root #

# VIM environment
logger VIM environments
cat > /root/.vimrc << EOF
set nomodeline
set copyindent
set autoindent
set nowrap
set cc=80
syntax on
EOF
cp -a /root/.vimrc /usr/share/skel/dot.vimrc

#
# Refresh the pkg and install packages
#
logger Configuring Packages 
export ASSUME_ALWAYS_YES=yes
/usr/sbin/pkg bootstrap -f
/usr/local/sbin/pkg-static delete \*
/usr/local/sbin/pkg-static update
/usr/local/sbin/pkg-static upgrade
/usr/local/sbin/pkg-static install vim-lite tmux

#
# Restart the TTYs
# Send ALARM signal to reload rc.conf
#
kill -HUP 1
kill -SIGALRM $RC_PID
sysctl -f /etc/sysctl.conf
Advertisements

4 thoughts on “Customising FreeBSD

  1. Pingback: Minecraft with Java and Tmux on FreeBSD | Virtualisation Works

  2. Pingback: Virtual Private Network with FreeBSD (Part 1) | Virtualisation Works

  3. Pingback: [How-To] Minecraft with Java and Tmux on FreeBSD - FreeBSDNews.com

  4. Pingback: Configuring FreeBSD | Virtualisation Works

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s