Saturday, November 22, 2025

FreeBSD - Basic Operational Procedures

FreeBSD is a free, open-source operating system based on the Berkeley Software Distribution (BSD), a branch of UNIX developed at the University of California, Berkeley. It’s known for being stable, secure, highly performant, and extremely well-suited for servers, networking, storage, and appliances.

In this blog post we will document basic FreeBSD 14.3 operational procedures.

Procedure to update operating system

# Check current version of kernel, runtime, userland
freebsd-version -kru

# OS update
freebsd-update fetch
freebsd-update install

# Check current version of kernel, runtime, userland
freebsd-version -kru

# if kernel patch level is higher than runtime patch level, reboot the system to use new kernel 
reboot

# try if there is something more to install
freebsd-update install

# Update software packages installed in OS as additional software
pkg update

Procedure to change hostname

# Check current hostname
hostname

# Change hostname
hostname r1.int.msp.businesscloud.cz

# Change hostname permanently
sysrc hostname="r1.int.msp.businesscloud.cz"

Procedure to use DNS

To use particular DNS server, edit configuration file /etc/resolve.conf. File should contain something like ...

search int.example.com
nameserver 10.1.10.254

Procedure to change IP settings permanently 

FreeBSD configuration is saved in /etc/rc.conf and managed by sysrc.

# Set IP settings on vmx0 interface
sysrc ifconfig_vmx0="inet 10.1.0.254 netmask 255.255.255.0"

# Set IP on loopback
sysrc ifconfig_lo0_alias0="inet 10.0.0.1/32"

# set default router (default gateway)
sysrc defaultrouter="10.1.0.1"

# show the current IP settings on vmx0 interface
ifconfig vmx0

Procedure to change IP settings on running system

# Set IP settings on vmx0 interface
ifconfig vmx0 inet 10.1.0.254 netmask 255.255.255.0

# Set IP alias on loopback
ifconfig lo0 alias 10.0.0.1/32

Procedure to set Time Servers 

To use above Time Servers, edit configuration file /etc/ntp.conf and ensure time servers are there …

# These servers must be defined
server time.cloudflare.com iburst
server time.google.com iburst
server ntp.cesnet.cz iburst

# Default public servers from the pool.ntp.org must be disabled
#pool 0.freebsd.pool.ntp.org iburst
#pool 2.freebsd.pool.ntp.org iburst

Procedure to enable and restart time service

# Enable NTPD as a service
sysrc ntpd_enable="YES"
sysrc ntpd_sync_on_start="YES"

# Start service
service ntpd start

# Restart service
service ntpd restart

# Check and Verify NTP time servers
ntpq -p

Procedure to set and verify Time Zone

timedatectl set-timezone UTC
timedatectl

Procedure to configure IPFW firewall

sysrc firewall_enable="YES"
sysrc firewall_script="/etc/ipfw.rules"
sysrc firewall_nat_enable="YES"

Firewall Script /etc/ipfw.rules to apply Zero Trust policy and allow only specific connections.

#!/bin/sh

# Define binaries
ipfw="/sbin/ipfw"

# Define interfaces
wan_if="vmx0"
mgmt_if="vmx4"

################# DESTROY FIREWALL – FW RULES, NAT RULES, TABLES #################

# FLUSH EXISTING IPFW RULES
$ipfw -q -f flush

# FLUSH EXISTING DYNAMIC NAT TRANSITION TABLE
$ipfw -q nat flush

# DELETE EXISTING NAT INSTANCE DEFINITION
$ipfw nat delete 1

# DELETE ALL EXISTING TABLES (FW ZONES)
ipfw table all destroy

################# NAT CONFIGURATION  #################

# DNAT RULE
$ipfw nat 1 config if $wan_if redirect_port tcp 10.1.10.1:22 2222 redirect_port tcp 10.1.3.10:443 4443 redirect_port tcp 10.1.3.10:80 8080

# SNAT RULE
$ipfw add 50 nat 1 ip from any to any via $wan_if

# Allow the traffic destined for the NAT's rewritten destination (10.1.10.1 - JUMP-01)
$ipfw add 51 allow ip from any to 10.1.10.1 via $mgmt_if
$ipfw add 52 allow ip from 10.1.10.1 to any via $mgmt_if

# BEST PRACTICE INIT FIREWALL RULES
$ipfw add 100 allow ip from any to any via lo0
$ipfw add 200 deny ip from any to 127.0.0.0/8
$ipfw add 300 deny ip from 127.0.0.0/8 to any
$ipfw add 400 deny ip from any to ::1
$ipfw add 500 deny ip from ::1 to any
$ipfw add 600 allow ipv6-icmp from :: to ff02::/16
$ipfw add 700 allow ipv6-icmp from fe80::/10 to fe80::/10
$ipfw add 800 allow ipv6-icmp from fe80::/10 to ff02::/16
$ipfw add 900 allow ipv6-icmp from any to any icmp6types 1
$ipfw add 1000 allow ipv6-icmp from any to any icmp6types 2,135,136

################# DEFINE FIREWALL TABLES as ZONES #################

# Create the table of ZABBIX-JUMP zone
$ipfw table ZABBIX-JUMP create type addr
$ipfw table ZABBIX-JUMP add 10.1.10.1

# Create the table of ZABBIX-DEVOPS zone
$ipfw table ZABBIX-DEVOPS create type addr
$ipfw table ZABBIX-DEVOPS add 10.1.10.10

# Create the table of ZABBIX-FE-LB zone
$ipfw table ZABBIX-FE-LB create type addr
ipfw table ZABBIX-FE-LB add 10.1.3.10

# Create the table of ZABBIX-FE zone
$ipfw table ZABBIX-FE create type addr
$ipfw table ZABBIX-FE add 10.1.3.1
$ipfw table ZABBIX-FE add 10.1.3.2

# Create the table of ZABBIX-BE zone
$ipfw table ZABBIX-BE create type addr
$ipfw table ZABBIX-BE add 10.1.2.1
$ipfw table ZABBIX-BE add 10.1.2.2

# Create the table of ZABBIX-DB zone
$ipfw table ZABBIX-DB create type addr
$ipfw table ZABBIX-DB add 10.1.1.1
$ipfw table ZABBIX-DB add 10.1.1.2
$ipfw table ZABBIX-DB add 10.1.1.3
$ipfw table ZABBIX-DB add 10.1.1.10

# Create the table of ZABBIX-PROXY zone
$ipfw table ZABBIX-PROXY create type addr
$ipfw table ZABBIX-PROXY add 172.16.0.0/16

# Create the table of PRIVATE zone
$ipfw table PRIVATE create type addr
$ipfw table PRIVATE add 10.0.0.0/8
$ipfw table PRIVATE add 172.16.0.0/12
$ipfw table PRIVATE add 192.168.0.0/16

################# FIREWALL OPENINGS #############################

#################################################################
# Allow WAN access and ICMP
# ===============================
# Allow (WAN) Internet Access
$ipfw add 2000 allow ip from any to any via $wan_if

# Allow Access to everything, but not PRIVATE IP Subnets
$ipfw add 2010 allow ip from any to not "table(PRIVATE)"
$ipfw add 2011 allow ip from not "table(PRIVATE)" to any

# Allow ICMP traffic everywhere. Good for diagnostic purposes
$ipfw add 2020 allow icmp from any to any

#################################################################
# ME (R1) ALLOW RULES
# ===============================
# ALLOW RULES TO ME
# ===============================
# Allow UDP/53 (DNS) running on me
$ipfw add 3010 allow udp from any to me 53 in keep-state
# Allow TCP/22 (ssh) from JumpHost to Me (R1)
$ipfw add 3020 allow tcp from "table(ZABBIX-JUMP)" to me 22 in keep-state
# ===============================
# ALLOW RULES FROM ME
# ===============================
# Allow all IP traffic originating from Me (R1) to any destination going out to WAN
$ipfw add 3100 allow ip from me to any out via $wan_if keep-state
# Allow TCP/22 (ssh) from Me (R1) to JumpHost
$ipfw add 3110 allow tcp from me to "table(ZABBIX-JUMP)" 22 out keep-state
################################################################

#################################################################
# ZABBIX-DEVOPS RULES
# ===============================
# ALLOW RULES TO ZABBIX-DEVOPS
# ===============================
# Allow TCP/10050 (zabbix-server-agent) from ZABBIX-BE to ZABBIX-DEVOPS
$ipfw add 4000 allow tcp from "table(ZABBIX-BE)" to "table(ZABBIX-DEVOPS)" 10050 keep-state
# ===============================
# ALLOW RULES FROM ZABBIX-DEVOPS
# ===============================
# Allow TCP/22 (ssh) from ZABBIX-DEVOPS to ZABBIX-FE
$ipfw add 4100 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-FE)" 22 keep-state
# Allow TCP/22 (ssh) from ZABBIX-DEVOPS to ZABBIX-BE
$ipfw add 4110 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-BE)" 22 keep-state
# Allow TCP/22 (ssh) from ZABBIX-DEVOPS to ZABBIX-DB
$ipfw add 4120 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-DB)" 22 keep-state
################################################################

#################################################################
# ZABBIX-BE RULES
# ===============================
# ALLOW RULES TO ZABBIX-BE
# ===============================
# Allow TCP/22 (ssh) from ZABBIX-DEVOPS to ZABBIX-FE
$ipfw add 5000 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-BE)" 22 keep-state
# Allow TCP/10051 (Zabbix-agent-server) from ZABBIX-PROXY to ZABBIX-BE
$ipfw add 5010 allow tcp from "table(ZABBIX-PROXY)" to "table(ZABBIX-BE)" 10051 keep-state
# Allow TCP/10051 (Zabbix-agent-server) from ZABBIX-FE-LB to ZABBIX-BE
$ipfw add 5020 allow tcp from "table(ZABBIX-FE-LB)" to "table(ZABBIX-BE)" 10051 keep-state
# Allow TCP/10051 (Zabbix-agent-server) from ZABBIX-DB to ZABBIX-BE
$ipfw add 5021 allow tcp from "table(ZABBIX-DB)" to "table(ZABBIX-BE)" 10051 keep-state
# Allow TCP/10051 (Zabbix-agent-server) from ZABBIX-FE to ZABBIX-BE
$ipfw add 5022 allow tcp from "table(ZABBIX-FE)" to "table(ZABBIX-BE)" 10051 keep-state
# Allow TCP/10051 (Zabbix-agent-server) from ZABBIX-DEVOPS to ZABBIX-BE
$ipfw add 5022 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-BE)" 10051 keep-state

# ===============================
# ALLOW RULES FROM ZABBIX-BE
# ===============================
# Allow TCP/10050 (zabbix-server-agent) from ZABBIX-BE to ZABBIX-FE
$ipfw add 5100 allow tcp from "table(ZABBIX-BE)" to "table(ZABBIX-FE)" 10050 keep-state
# Allow TCP/10050 (zabbix-server-agent) from ZABBIX-BE to ZABBIX-DB
$ipfw add 5110 allow tcp from "table(ZABBIX-BE)" to "table(ZABBIX-DB)" 10050 keep-state
# Allow TCP/5432 (postgresql) from ZABBIX-BE to ZABBIX-DB
$ipfw add 5120 allow tcp from "table(ZABBIX-BE)" to "table(ZABBIX-DB)" 5432 keep-state
################################################################

#################################################################
# ZABBIX-FE RULES
# ===============================
# ALLOW RULES TO ZABBIX-FE
# ===============================
# Allow TCP/22 (ssh) from ZABBIX-DEVOPS to ZABBIX-FE
$ipfw add 6000 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-FE)" 22 keep-state
# Allow TCP/443 (https) from ZABBIX-DEVOPS to ZABBIX-FE
$ipfw add 6010 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-FE)" 443 keep-state
# Allow TCP/10050 (zabbix-server-agent) from ZABBIX-BE to ZABBIX-FE
$ipfw add 6020 allow tcp from "table(ZABBIX-BE)" to "table(ZABBIX-FE)" 10050 keep-state
# Allow TCP/80,443 (web) from ZABBIX-FE-LB to ZABBIX-FE
$ipfw add 6030 allow tcp from "table(ZABBIX-FE-LB)" to "table(ZABBIX-FE)" 80 keep-state
$ipfw add 6040 allow tcp from "table(ZABBIX-FE-LB)" to "table(ZABBIX-FE)" 443 keep-state
# ===============================
# ALLOW RULES FROM ZABBIX-FE
# ===============================
# Allow TCP/5432 (postgresql) from ZABBIX-FE to ZABBIX-DB
$ipfw add 6100 allow tcp from "table(ZABBIX-FE)" to "table(ZABBIX-DB)" 5432 keep-state
################################################################

#################################################################
# ZABBIX-FE-LB RULES
# ===============================
# ALLOW RULES TO ZABBIX-FE-LB
# ===============================
# Allow TCP/22 (ssh) from ZABBIX-DEVOPS to ZABBIX-FE-LB
$ipfw add 7000 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-FE-LB)" 22 keep-state
# Allow TCP/443 (https) from ZABBIX-DEVOPS to ZABBIX-FE-LB
$ipfw add 7010 allow tcp from "table(ZABBIX-DEVOPS)" to "table(ZABBIX-FE-LB)" 443 keep-state
# Allow TCP/80,443 (web) from ANY to ZABBIX-FE-LB
$ipfw add 7020 allow tcp from any to "table(ZABBIX-FE-LB)" 80 keep-state
$ipfw add 7030 allow tcp from any to "table(ZABBIX-FE-LB)" 443 keep-state
# ===============================
# ALLOW RULES FROM ZABBIX-FE-LB
# ===============================
# Allow TCP/10051 (Zabbix-agent-server) from ZABBIX-FE-LB to ZABBIX-BE
$ipfw add 7100 allow tcp from "table(ZABBIX-FE-LB)" to "table(ZABBIX-BE)" 10051 keep-state
################################################################

#################################################################
# RULES TO DENY EVERYTHING ELSE
# ===============================
# EVERYTHING ELSE IS DENY – ZERO TRUST
$ipfw add 65500 deny ip from any to any

Procedure to reload IPFW firewall script

# Run ipfw script on background
/etc/ipfw.rules &

IPFW DNAT Configuration Management

# Show NAT Configuration
ipfw nat show config

# Add DNAT rule
ipfw nat 1 config if vmx0 redirect_port 10.1.10.1:22 2222  

# Delete DNAT rule
ipfw nat delete 1  


IPFW TABLES Configuration Management

# Show particular Table configuration. In this example we use Table name PRIVATE
ipfw table PRIVATE list
ipfw table PRIVATE info


Conclusion

Hope these basic operational procedures helps someone.


 

No comments:

Post a Comment