This is a multi-part article. There are too many components to fit all of them into a single writeup. The first part will cover the FreeBSD install and initial setup of the OS.

I’ve discussed various components of mailservers before, but this will cover building one from the ground up. For simplicity, all this is done in VMware Fusion. It could just as easily be done with VirtualBox, Parallels, ESX, bhyve, or actual hardware. I’ve tried to arrange the sub topics in an order that facilitates testing the component(s) before moving forward. I’ve also made an effort to have as many services speaking over SSL as possible. Where something doesn’t speak over SSL, I will explicitly note it.

This is very much a self-contained box. It doesn’t have to be done this way, in fact, there could be good reasons to do it differently (you may want to have your web server on a different host, you might want to have your IMAP server on a different host). For the purpose of illustration, its easier to put it all in one box, but I’ve gone to some effort to construct it in such a way that you can move any of the components to other hosts. At the end is a diagram showing how services could be split up/broken out across a multitude of hosts, including some load balancers/proxies where appropriate.

Installation

The only shortcut I took was to provision a single disk. If you’re working with hardware, you would want some kind of redundancy (multiple disks) so ZFS can actually benefit you. Before taking this beyond a proof of concept, please ensure that you have sufficient redundancy in your storage, either directly through ZFS, or indirectly via your virtualization provider.

This is just a string of images. If you want more details about a FreeBSD install, check out a previous post on how to do a freebsd-install.

FreeBSD update

We start by updating the ports tree, and ensuring FreeBSD is up to date. The portsnap(8) program will fetch the current snapshot of the ports tree, and the freebsd-update(8) program will pull down patches for the current release of FreeBSD. After we’ve done the updates, its a good idea to reboot. Until we have sudo(8) installed, these have to be executed as root.

freebsd-update fetch install
portsnap fetch extract
reboot

Basic System Setup

We won’t be needing X11 support, so we can disable that flag when we are building ports (this has the effect of, by default, excluding X11 support in packages we build from source). If you don’t already have an /etc/make.conf file, you can copy the example file from /usr/share/examples/etc/.

We also want to tell all ports to use the OpenSSL port, and then define the OpenSSL port as security/libressl.

# Build ports without X11 support
UNSET_OPTIONS=          X11
# Build ports against security/openssl (replace openssl with libressl if you
# nolonger have dependencies on openssl as they can't coexist)
DEFAULT_VERSIONS+=ssl=openssl

We need to create the /usr/local dataset.

zfs create zpool/usr/local

These are reasonable to include for our system (/etc/rc.conf). The only one I wouldn’t consider to be “default” is the ‘local_unbound’, but since we’ll be doing lots of DNS lookups, a local cache makes sense.

dumpdev=             "AUTO"
hostname=            "mx.cryptomonkeys.net"
ifconfig_em0=        "192.168.3.60"
defaultrouter=       "192.168.3.1"
ifconfig_em0_ipv6=   "inet6 2001:db8::3:60/64"
defaultrouter_ipv6=  "2001:db8::3:1"
local_unbound_enable="YES"
ntpd_enable=         "YES"
ntpd_sync_on_start=  "YES"
sshd_enable=         "YES"
zfs_enable=          "YES"

I typically comment out the forwarder.conf line in /etc/unbound/unbound.conf. This causes unbound to make lookups against the root servers.

If you don’t make any other modifications to /etc/ssh/sshd_config, do this one. It restricts SSH to public key only. If you want more on securing SSH, see the footnotes section on Securing the Secure Shell.

ChallengeResponseAuthentication no

pf firewall

Every box needs a firewall. It doesn’t have to be pf, but pf does offer lots of nice features. I’ve taken the sample from Calomel’s pf and modified it. You can also find more documentation in the FreeBSD Handbook.

Enable it with sysrc (which writes to /etc/rc.conf):

sudo sysrc pf_enable=YES
sudo sysrc pflog_enable=YES

Here is the /etc/pf.conf.

#
### Calomel.org pf.conf
#
################ FreeBSD pf.conf ##########################
# Required order: options, normalization, queueing, translation, filtering.
# Note: translation rules are first match while filter rules are last match.
################ Macros ###################################

### Interfaces (ensure the correct interface or traffic will be dropped) ###
ExtIf ="vmx0"

# Intnernal networks
CMHome_Net_v4 = "192.168.0.0/20"
CMHome_Net_v6 = "fc00:101:ca7::/48"

# Internal networks excluding IoT subnet
CMHome_Net_v4_No_IoT = "{ 192.168.0.0/24, 192.168.1.0/24, 192.168.2.0/24, 192.168.3.0/24, 192.168.4.0/24, 192.168.5.0/24, 192.168.6.0/24, 192.168.7.0/24, 192.168.8.0/24, 192.168.10.0/24, 192.168.11.0/24, 192.168.12.0/24, 192.168.13.0/24, 192.168.14.0/24, 192.168.15.0/24 }"
CMHome_Net_v6_No_IoT = "{ fc00:101:ca7::/64, fc00:101:ca7:1::/64, fc00:101:ca7:2::/64, fc00:101:ca7:3::/64, fc00:101:ca7:4::/64, fc00:101:ca7:5::/64, fc00:101:ca7:6::/64, fc00:101:ca7:7::/64, fc00:101:ca7:8::/64, fc00:101:ca7:10::/64 }"

# Monitoring host
Zabbix_v4 ="{ 192.168.3.200/32, 192.168.3.10/32 }"
Zabbix_v6 ="{ fc00:101:ca7:3::200/128, fc00:101:ca7:3::10/128 }"

# Salt host
Salt_v4 ="192.168.3.250/32"
Salt_v6 ="fc00:101:ca7:2::250/128"

### States and Types ###
ICMP4_Types="{ echoreq, unreach }"
ICMP6_Types="{ 1, 2, 3, 4, 128, 129, 133, 134, 135, 136, 137 }"
SYN_State ="flags S/SA synproxy state"
TCP_State ="flags S/SA modulate state"
UDP_State ="keep state"

### Ports ###
Anti_Scan_Port="{23, 24, 26:79, 6000:8000}"
Mail_Port="{ 25, 465, 587, 993, 995 }"
Web_Port="{ 80, 443 }"
UniFi_TCP_Port="{ 8080, 8443, 8880, 8843 }"
UniFi_UDP_Port="{ 3478, 10001 }"
Gogs_SSH_Port="2222"
DHCP4_Port="{ 67:68 }"
DHCP6_Port="{ 546:547 }"
DNS_Port="53"
Zabbix_Client_Port="10050"
Zabbix_Server_Port="{ 10051, 10052 }"
Salt_Server_Port="4506"
SSH_Port="22"
Syslog_Port="514"
Filebeat_Port="5044"

### Stateful Tracking Options (STO) ###
Open_STO     ="(max 90000, source-track rule, max-src-conn 1000, max-src-nodes 256)"
Mail_STO     ="(max 20000, source-track rule, max-src-conn 1000, max-src-nodes 512, max-src-conn-rate 500/100)"
SSH_STO      ="(max    20, source-track rule, max-src-conn   10, max-src-nodes 100, max-src-conn-rate 5/3,     overload <SSHGUARD>  flush global)"
Web_STO      ="(max  4096, source-track rule, max-src-conn   64, max-src-nodes 512, max-src-conn-rate 500/100, overload <BLOCKTEMP> flush global)"
Anti_Scan_STO ="(max    60,  source-track rule, max-src-conn  1, max-src-nodes  60, max-src-conn-rate 1/60,    overload <BLACKLIST> flush global)"

### Tables ###
table <SSHGUARD> counters
table <BLOCKTEMP> counters
table <BLOCKPERM> counters file "/etc/pf_block_permanent"
table <BLACKLIST> persist
table <WHITELIST> counters file "/etc/pf_whitelist"

################ Options ######################################################
### Misc Options
set skip on lo
set debug urgent
set block-policy drop
set loginterface $ExtIf
set state-policy if-bound
set fingerprints "/etc/pf.os"
set ruleset-optimization none

### Timeout Options
set optimization normal
set timeout { tcp.closing 60, tcp.established 7200}

################ Normalization ###############################################
# set-tos 0x1c is Maximize-Reliability + Minimize-Delay + Maximize-Throughput
scrub out log on $ExtIf all random-id min-ttl 15 set-tos 0x1c fragment reassemble

################ Filtering ###################################################
# Rules are best (closest) match. Notice we optimized the rules so external
# interface parsing is first followed by the internal interface.

### $ExtIf block abusive hosts in temp and perm tables
block drop in  log quick on $ExtIf           from <BLOCKPERM>   to any
block drop in  log quick on $ExtIf proto udp from <BLOCKTEMP>   to any
block drop in  log quick on $ExtIf proto tcp from <SSHGUARD>    to any
block drop in  log quick on $ExtIf proto tcp from <BLOCKTEMP>   to any port != $SSH_Port
block drop in  log quick on $ExtIf           from <BLACKLIST>   to any

### $ExtIf default block with drop
block drop in  log       on $ExtIf

### $ExtIf inbound

# Whitelist (is this necessary?)
#pass in quick on $ExtIf inet   proto tcp   from <WHITELIST>     to ($ExtIf)                             $TCP_State
#pass in quick on $ExtIf inet6  proto tcp   from <WHITELIST>     to ($ExtIf)                             $TCP_State

# Zabbix Server queries
#pass in quick on $ExtIf inet   proto tcp   from any             to ($ExtIf)   port $Zabbix_Server_Port  $TCP_State $Open_STO
#pass in quick on $ExtIf inet6  proto tcp   from any             to ($ExtIf)   port $Zabbix_Server_Port  $TCP_State $Open_STO
#pass in quick on $ExtIf inet   proto udp   from any             to ($ExtIf)   port $Zabbix_Server_Port  $UDP_State $Open_STO
#pass in quick on $ExtIf inet6  proto udp   from any             to ($ExtIf)   port $Zabbix_Server_Port  $UDP_State $Open_STO

# Salt Server ports
#pass in quick on $ExtIf inet   proto tcp   from $CMHome_Net_v4  to $Salt_v4   port $Salt_Server_Port   $TCP_State $Open_STO
#pass in quick on $ExtIf inet6  proto tcp   from $CMHome_Net_v6  to $Salt_v6   port $Salt_Server_Port   $TCP_State $Open_STO
#pass in quick on $ExtIf inet   proto udp   from $CMHome_Net_v4  to $Salt_v4   port $Salt_Server_Port   $UDP_State $Open_STO
#pass in quick on $ExtIf inet6  proto udp   from $CMHome_Net_v6  to $Salt_v6   port $Salt_Server_Port   $UDP_State $Open_STO

# DNS/DHCP Server
#pass in quick on $ExtIf inet   proto tcp   from any             to ($ExtIf)   port $DNS_Port            $TCP_State $Open_STO
#pass in quick on $ExtIf inet6  proto tcp   from any             to ($ExtIf)   port $DNS_Port            $TCP_State $Open_STO
#pass in quick on $ExtIf inet   proto udp   from any             to ($ExtIf)   port $DNS_Port            $UDP_State $Open_STO
#pass in quick on $ExtIf inet6  proto udp   from any             to ($ExtIf)   port $DNS_Port            $UDP_State $Open_STO
#pass in quick on $ExtIf inet   proto tcp   from any             to ($ExtIf)   port $DHCP4_Port          $TCP_State
#pass in quick on $ExtIf inet   proto udp   from any             to ($ExtIf)   port $DHCP4_Port          $UDP_State
#pass in quick on $ExtIf inet6  proto tcp   from any             to ($ExtIf)   port $DHCP6_Port          $TCP_State
#pass in quick on $ExtIf inet6  proto udp   from any             to ($ExtIf)   port $DHCP6_Port          $UDP_State

# Web services
pass in       on $ExtIf inet   proto tcp   from !($ExtIf)       to ($ExtIf)   port $Web_Port            $TCP_State $Web_STO
pass in       on $ExtIf inet6  proto tcp   from !($ExtIf)       to ($ExtIf)   port $Web_Port            $TCP_State $Web_STO
#pass in       on $ExtIf inet   proto tcp   from !($ExtIf)       to ($ExtIf)   port $UniFi_TCP_Port      $TCP_State $Web_STO
#pass in       on $ExtIf inet6  proto tcp   from !($ExtIf)       to ($ExtIf)   port $UniFi_TCP_Port      $TCP_State $Web_STO
#pass in       on $ExtIf inet   proto udp   from !($ExtIf)       to ($ExtIf)   port $UniFi_UDP_Port      $UDP_State
#pass in       on $ExtIf inet6  proto udp   from !($ExtIf)       to ($ExtIf)   port $UniFi_UDP_Port      $UDP_State

# Gogs services
#pass in       on $ExtIf inet   proto tcp   from !($ExtIf)       to ($ExtIf)   port $Gogs_SSH_Port       $TCP_State $SSH_STO
#pass in       on $ExtIf inet6  proto tcp   from !($ExtIf)       to ($ExtIf)   port $Gogs_SSH_Port       $TCP_State $SSH_STO

# Log collection
#pass in       on $ExtIf inet   proto udp   from $CMHome_Net_v4  to ($ExtIf)   port $Syslog_Port         $UDP_State 
#pass in       on $ExtIf inet6  proto udp   from $CMHome_Net_v6  to ($ExtIf)   port $Syslog_Port         $UDP_State 

# Filebeat (logstash)
#pass in       on $ExtIf inet   proto tcp   from !($ExtIf)       to ($ExtIf)   port $Filebeat_Port     $TCP_State $SSH_STO
#pass in       on $ExtIf inet6  proto tcp   from !($ExtIf)       to ($ExtIf)   port $Filebeat_Port     $TCP_State $SSH_STO

# Mail
pass in       on $ExtIf inet   proto tcp   from !($ExtIf)       to ($ExtIf)   port $Mail_Port           $TCP_State $Mail_STO
pass in       on $ExtIf inet6  proto tcp   from !($ExtIf)       to ($ExtIf)   port $Mail_Port           $TCP_State $Mail_STO

### Shouldn't need to modify below here ###

# Zabbix Client queries
pass in quick on $ExtIf inet   proto tcp   from $Zabbix_v4      to ($ExtIf)   port $Zabbix_Client_Port  $TCP_State $Open_STO
pass in quick on $ExtIf inet6  proto tcp   from $Zabbix_v6      to ($ExtIf)   port $Zabbix_Client_Port  $TCP_State $Open_STO
pass in quick on $ExtIf inet   proto udp   from $Zabbix_v4      to ($ExtIf)   port $Zabbix_Client_Port  $UDP_State $Open_STO
pass in quick on $ExtIf inet6  proto udp   from $Zabbix_v6      to ($ExtIf)   port $Zabbix_Client_Port  $UDP_State $Open_STO

# SSH
pass in       on $ExtIf inet   proto tcp   from !($ExtIf)       to ($ExtIf)   port $SSH_Port            $TCP_State $SSH_STO
pass in       on $ExtIf inet6  proto tcp   from !($ExtIf)       to ($ExtIf)   port $SSH_Port            $TCP_State $SSH_STO

# NTP Multicast
pass  in       on $ExtIf inet6  proto udp  from any             to ff02::1010 port 123

# mDNS
pass  in       on $ExtIf inet6  proto udp  from any             to ff02::fb   port 5353

# ICMP
pass in       on $ExtIf inet   proto icmp       from !($ExtIf)  to any icmp-type  $ICMP4_Types          $UDP_State $Open_STO
pass in       on $ExtIf inet6  proto ipv6-icmp  from any        to any icmp6-type $ICMP6_Types          $UDP_State
pass in       on $ExtIf inet6  proto ipv6-icmp  from any        to FF02::/16                            $UDP_State
pass in       on $ExtIf inet6  proto ipv6-icmp  from fe80::/10  to fe80::/10                            $UDP_State
pass in       on $ExtIf inet6  proto ipv6-icmp  from fe80::/10  to ff02::/16                            $UDP_State

# Antiscan bits
pass in       on $ExtIf inet   proto tcp   from any             to any        port $Anti_Scan_Port      $TCP_State $Anti_Scan_STO
pass in       on $ExtIf inet6  proto tcp   from any             to any        port $Anti_Scan_Port      $TCP_State $Anti_Scan_STO

### $ExtIf outbound
pass out      on $ExtIf inet   proto tcp   from ($ExtIf)        to any                                  $TCP_State $Open_STO
pass out      on $ExtIf inet6  proto tcp   from ($ExtIf)        to any                                  $TCP_State $Open_STO
pass out      on $ExtIf inet   proto udp   from ($ExtIf)        to any                                  $UDP_State $Open_STO
pass out      on $ExtIf inet6  proto udp   from ($ExtIf)        to any                                  $UDP_State $Open_STO
pass out      on $ExtIf inet   proto icmp  from ($ExtIf)        to any                                  $UDP_State $Open_STO
pass out      on $ExtIf inet6  proto icmp6 from ($ExtIf)        to any                                  $UDP_State $Open_STO

############# END of FreeBSD pf.conf https://calomel.org #######################

I’ve created a couple of persistent tables that you will need to create before pf will start.

  1. touch “/etc/pf_block_permanent”
  2. touch “/etc/pf_whitelist”

Now we can start pf with either:

  1. reboot
  2. service pf start

NOTE: If you choose the second, and you are connected over SSH, it will kill your connection. You will have to re-login.

What ports do we install?

There are a number of packages that need to be installed. Installing them will pull in many others as dependancies. My total list of installed ports is around 170.

I start off with a couple ports to make things easier.

pkg install sudo tmux portmaster

Then I move on to install the rest of the ports that will be needed.

archivers/arc
archivers/arj
archivers/cabextract
archivers/freeze
archivers/lha
archivers/libarchive
archivers/liblz4
archivers/libmspack
archivers/libzip
archivers/lzo2
archivers/lzop
archivers/p5-Archive-Zip
archivers/p7zip
archivers/php56-bz2
archivers/php56-zip
archivers/php56-zlib
archivers/rar
archivers/rpm2cpio
archivers/unarj
archivers/unrar
archivers/unzoo
archivers/zoo
converters/libiconv
converters/p5-Convert-BinHex
converters/p5-Convert-TNEF
converters/p5-Convert-UUlib
converters/p5-Encode-Detect
converters/p5-JSON-PP
converters/php56-iconv
converters/php56-mbstring
converters/tnef
databases/db5
databases/gdbm
databases/p5-BerkeleyDB
databases/p5-DBD-Pg
databases/p5-DBI
databases/pgbouncer
databases/php56-pdo
databases/php56-pdo_pgsql
databases/php56-pgsql
databases/phppgadmin
databases/postgresql96-client
databases/py-gdbm
databases/py-sqlite3
databases/sqlite3
devel/apr1
devel/autoconf
devel/autoconf-wrapper
devel/automake
devel/automake-wrapper
devel/bison
devel/boehm-gc
devel/boost-jam
devel/boost-libs
devel/cmake
devel/cmake-modules
devel/gettext-runtime
devel/gettext-tools
devel/git
devel/glib20
devel/gmake
devel/icu
devel/jansson
devel/json-c
devel/jsoncpp
devel/libatomic_ops
devel/libedit
devel/libev
devel/libevent
devel/libffi
devel/libltdl
devel/libsigsegv
devel/libtool
devel/libunistring
devel/libuv
devel/llvm36
devel/m4
devel/nasm
devel/npth
devel/oniguruma5
devel/p5-Algorithm-C3
devel/p5-B-Hooks-EndOfScope
devel/p5-CPAN-Meta
devel/p5-Cache-FastMmap
devel/p5-Canary-Stability
devel/p5-Carp-Clan
devel/p5-Class-C3
devel/p5-Class-Data-Inheritable
devel/p5-Class-Inspector
devel/p5-Class-Method-Modifiers
devel/p5-Class-Singleton
devel/p5-Config-IniFiles
devel/p5-Data-OptList
devel/p5-Date-Calc
devel/p5-DateTime
devel/p5-DateTime-Format-Mail
devel/p5-DateTime-Locale
devel/p5-DateTime-TimeZone
devel/p5-Devel-GlobalDestruction
devel/p5-Devel-StackTrace
devel/p5-Dist-CheckConflicts
devel/p5-Eval-Closure
devel/p5-Exception-Class
devel/p5-Exporter-Tiny
devel/p5-File-ShareDir
devel/p5-File-ShareDir-Install
devel/p5-File-Slurp
devel/p5-FileHandle-Unget
devel/p5-IO-Multiplex
devel/p5-IO-stringy
devel/p5-IPC-Signal
devel/p5-List-AllUtils
devel/p5-List-SomeUtils
devel/p5-List-SomeUtils-XS
devel/p5-List-UtilsBy
devel/p5-Locale-gettext
devel/p5-Log-Dispatch
devel/p5-Log-Log4perl
devel/p5-MRO-Compat
devel/p5-Module-Build
devel/p5-Module-Implementation
devel/p5-Module-Runtime
devel/p5-Package-Stash
devel/p5-Package-Stash-XS
devel/p5-Params-Util
devel/p5-Params-Validate
devel/p5-Params-ValidationCompiler
devel/p5-Proc-WaitStat
devel/p5-Role-Tiny
devel/p5-Specio
devel/p5-Sub-Exporter
devel/p5-Sub-Exporter-Progressive
devel/p5-Sub-Identify
devel/p5-Sub-Install
devel/p5-Term-ANSIColor
devel/p5-Test-NoWarnings
devel/p5-Time-Local
devel/p5-TimeDate
devel/p5-Variable-Magic
devel/p5-namespace-autoclean
devel/p5-namespace-clean
devel/pcre
devel/pecl-intl
devel/php56-json
devel/pkgconf
devel/py-Jinja2
devel/py-babel
devel/py-backports_abc
devel/py-botocore
devel/py-dateutil
devel/py-enum34
devel/py-futures
devel/py-ioflo
devel/py-jmespath
devel/py-msgpack-python
devel/py-pytz
devel/py-singledispatch
devel/py-six
devel/py-yaml
devel/py27-setuptools
devel/re2c
devel/readline
devel/scons
devel/t1lib
dns/bind-tools
dns/c-ares
dns/idnkit
dns/libidn
dns/p5-Net-DNS
dns/p5-Net-DNS-Resolver-Programmable
dns/p5-Net-Domain-TLD
dns/p5-Net-LibIDN
editors/vim
emulators/open-vm-tools-nox11
emulators/tpm-emulator
ftp/curl
graphics/gd
graphics/jbigkit
graphics/jpeg-turbo
graphics/p5-GD
graphics/p5-GD-Graph
graphics/p5-GD-Graph3d
graphics/p5-GD-TextUtil
graphics/php56-exif
graphics/php56-gd
graphics/png
graphics/py-imagesize
graphics/tiff
lang/expect
lang/gawk
lang/p5-Error
lang/p5-Scalar-List-Utils
lang/p5-Try-Tiny
lang/perl5.20
lang/php56
lang/python2
lang/python27
lang/ruby23
lang/tcl86
mail/dcc-dccd
mail/dovecot2
mail/dovecot2-antispam-plugin
mail/dovecot2-pigeonhole
mail/dspam
mail/mb2md
mail/mime-construct
mail/opendkim
mail/p5-Email-Valid
mail/p5-MIME-Charset
mail/p5-MIME-EncWords
mail/p5-MIME-Tools
mail/p5-MIME-Types
mail/p5-Mail-DKIM
mail/p5-Mail-Mbox-MessageParser
mail/p5-Mail-MboxParser
mail/p5-Mail-SPF
mail/p5-Mail-Sender
mail/p5-Mail-Sendmail
mail/p5-Mail-Tools
mail/p5-Net-SMTP-SSL
mail/panda-cclient
mail/pflogsumm
mail/php56-imap
mail/policyd2
mail/postfix
mail/postfixadmin
mail/procmail
mail/pyzor
mail/razor-agents
mail/roundcube
mail/roundcube-sieverules
mail/spamassassin
math/gmp
math/p5-Bit-Vector
misc/compat10x
misc/compat9x
misc/dejagnu
misc/getopt
misc/help2man
misc/py-progressbar
net-mgmt/net-snmp
net-mgmt/p5-Net-CIDR
net-mgmt/p5-NetAddr-IP
net-mgmt/zabbix32-agent
net/GeoIP
net/libdnet
net/libzmq4
net/mtr-nox11
net/norm
net/openldap24-client
net/openpgm
net/p5-Geo-IP
net/p5-IO-Socket-INET6
net/p5-IO-Socket-IP
net/p5-Net-Server
net/p5-Socket
net/p5-Socket6
net/p5-URI
net/php56-xmlrpc
net/py-libcloud
net/py-pyzmq
net/py-raet
net/rsync
ports-mgmt/dialog4ports
ports-mgmt/pkg
ports-mgmt/portmaster
print/freetype2
print/indexinfo
print/libpaper
print/texinfo
security/amavisd-new
security/apache-xml-security-c
security/ca_root_nss
security/clamav
security/clamav-unofficial-sigs
security/gnupg
security/gnupg1
security/gnutls
security/heimdal
security/libassuan
security/libgcrypt
security/libgpg-error
security/libksba
security/libmcrypt
security/libsodium
security/libtasn1
security/logcheck
security/nettle
security/openssl
security/p11-kit
security/p5-Authen-SASL
security/p5-Crypt-OpenSSL-Bignum
security/p5-Crypt-OpenSSL-RSA
security/p5-Crypt-OpenSSL-Random
security/p5-Digest-HMAC
security/p5-Digest-SHA1
security/p5-GSSAPI
security/p5-IO-Socket-SSL
security/p5-Net-SSLeay
security/php56-filter
security/php56-mcrypt
security/php56-openssl
security/pinentry
security/pinentry-tty
security/py-certifi
security/py-libnacl
security/py-pycrypto
security/rhash
security/sudo
security/trousers
shells/bash
shells/ksh93
sysutils/apcupsd
sysutils/beadm
sysutils/colorize
sysutils/file
sysutils/fusefs-libs
sysutils/lsof
sysutils/p5-Unix-Syslog
sysutils/php56-fileinfo
sysutils/py-salt
sysutils/tmux
textproc/asciidoc
textproc/aspell
textproc/docbook
textproc/docbook-sgml
textproc/docbook-xml
textproc/docbook-xsl
textproc/expat2
textproc/gsed
textproc/iso8879
textproc/libxml2
textproc/libxslt
textproc/libyaml
textproc/p5-Net-IDN-Encode
textproc/php56-ctype
textproc/php56-dom
textproc/php56-pspell
textproc/php56-simplexml
textproc/php56-xml
textproc/py-MarkupSafe
textproc/py-alabaster
textproc/py-docutils
textproc/py-pygments
textproc/py-pygtail
textproc/py-pystemmer
textproc/py-snowballstemmer
textproc/py-sphinx
textproc/py-sphinx_rtd_theme
textproc/ripole
textproc/sdocbook-xml
textproc/xerces-c3
textproc/xmlcatmgr
textproc/xmlcharent
textproc/xmlto
www/apache24
www/h2o
www/libnghttp2
www/nghttp2
www/p5-CGI
www/p5-HTML-Parser
www/p5-HTML-Tagset
www/p5-HTTP-Date
www/p5-Mozilla-CA
www/php56-session
www/py-requests
www/py-tornado
www/spdylay
www/w3m
x11-fonts/fontconfig

NOTE You can generate this list with

pkg info -aoq

Because a number of these have custom options, I suggest building everything from source. The easiest way to install these is probably with portmaster (already installed).

Put this list into a text file. I called mine ‘installed-port-list’. Now that portmaster(8) is installed, you can run:

sudo portmaster `cat /path/to/installed-port-list`

Optionally, you can install the VM tools pkg if you’re not running on actual hardware.

sudo portmaster emulators/open-vm-tools-nox11

Don’t forget to add the following lines to /etc/rc.conf

sudo sysrc vmware_guest_vmblock_enable=YES
sudo sysrc vmware_guest_vmhgfs_enable=YES
sudo sysrc vmware_guest_vmmemctl_enable=YES
sudo sysrc vmware_guest_vmxnet_enable=YES
sudo sysrc vmware_guestd_enable=YES

The ports that I made changes to the build options are shown below. Any port not shown was left as defaults. They are in no particular order.

Port Screenshot
databases/postgresql94-server port_config_postgresql
ftp/curl port_config_curl
mail/opendkim port_config_opendkim
mail/opendmarc port_config_opendkim
mail/panda-cclient port_config_panda-cclient
mail/php56-imap port_config_php56-imap
mail/policyd2 port_config_policyd2
mail/postfix-current port_config_postfix
mail/postfixadmin port_config_postfixadmin
www/roundcube port_config_roundcube

Next

The next article will start the process of configuring the various processes.

Footnotes and References