🦉 FreeBSD RC and Jails
FreeBSD's rc system provides robust service management, while jails offer lightweight virtualization for secure system isolation. This reference covers both essential system administration components.
🎯 FreeBSD RC System Overview
RC System Architecture
The FreeBSD rc system is a hierarchical service management framework that controls system startup, shutdown, and service lifecycle management.
| # RC system components
# /etc/rc.conf - System configuration
# /etc/rc.d/ - Base system services
# /usr/local/etc/rc.d/ - Third-party services
# /etc/defaults/rc.conf - Default configuration
# /etc/rc.local - Local customization
|
Service Management Basics
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | # Basic service operations
service sshd start # Start SSH daemon
service sshd stop # Stop SSH daemon
service sshd restart # Restart SSH daemon
service sshd status # Check SSH status
service sshd rcvar # Show service variables
# List all available services
service -l
# List running services
service -r
# Run service in foreground (for debugging)
service sshd onestart
service sshd onestop
|
🔧 RC Configuration Management
System Configuration with rc.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | # /etc/rc.conf - Main system configuration file
# Basic system settings
hostname="freebsd.example.com"
ifconfig_em0="DHCP"
sshd_enable="YES"
ntpd_enable="YES"
# Service-specific configurations
apache24_enable="YES"
mysql_enable="YES"
postgresql_enable="YES"
# Network services
sendmail_enable="NONE" # Disable sendmail
firewall_enable="YES"
firewall_type="open" # Open firewall
# Custom configurations
dumpdev="AUTO" # Enable crash dumps
background_fsck="YES" # Background filesystem check
|
Using sysrc for Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | # sysrc - Safe configuration management tool
# View current settings
sysrc sshd_enable # Show SSH enablement
sysrc -a # Show all settings
# Modify settings
sysrc sshd_enable=YES # Enable SSH
sysrc sshd_enable=NO # Disable SSH
sysrc apache24_enable=YES # Enable Apache
# Multiple settings at once
sysrc nginx_enable=YES php_fpm_enable=YES mysql_enable=YES
# Remove settings
sysrc -x sshd_enable # Remove SSH setting
# Configuration in different files
sysrc -f /etc/rc.conf.local sshd_enable=YES
|
Service Dependencies
1
2
3
4
5
6
7
8
9
10
11
12 | # Service dependency management
# Services can declare dependencies in their rc scripts
# Example service dependency declaration
# REQUIRE: LOGIN
# PROVIDE: myservice
# BEFORE: DAEMON
# KEYWORD: shutdown
# Check service dependencies
service sshd depend # Show SSH dependencies
service apache24 depend # Show Apache dependencies
|
🏠 Jails - FreeBSD Virtualization
Jail Fundamentals
Jails provide OS-level virtualization that isolates processes and filesystems while sharing the host kernel.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | # Basic jail management
# Using ezjail for simplified management
pkg install ezjail # Install ezjail
# Initialize ezjail
ezjail-admin install # Install base jail system
# Create a new jail
ezjail-admin create webjail 'lo1|192.168.1.100'
# Start/stop jails
ezjail-admin start webjail
ezjail-admin stop webjail
ezjail-admin restart webjail
# List jails
ezjail-admin list
# Console access
ezjail-admin console webjail
|
Manual Jail Creation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | # Manual jail setup without ezjail
# Create jail directory
JAIL_ROOT="/usr/jails/myjail"
mkdir -p "$JAIL_ROOT"
# Install base system
bsdinstall jail "$JAIL_ROOT"
# Or use bsdinstall for newer versions
bsdinstall distfetch
bsdinstall distextract
# Configure jail in /etc/jail.conf
cat >> /etc/jail.conf << 'EOF'
myjail {
host.hostname = "myjail.example.com";
ip4.addr = 192.168.1.100;
path = "/usr/jails/myjail";
devfs_ruleset = 4;
enforce_statfs = 2;
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
mount.devfs;
mount.fstab = "/etc/fstab.myjail";
}
EOF
# Start the jail
service jail start myjail
|
Jail Configuration Options
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 | # Advanced jail configuration in /etc/jail.conf
webserver {
# Basic settings
host.hostname = "web.example.com";
ip4.addr = 192.168.1.100;
ip6.addr = 2001:db8::100;
path = "/usr/jails/webserver";
# Security settings
devfs_ruleset = 4;
enforce_statfs = 2;
allow.raw_sockets;
allow.chflags;
# Resource limits
maxproc = 100;
cputime = "300";
persist;
# Execution commands
exec.prestart = "/bin/sh /etc/jail.prestart";
exec.start = "/bin/sh /etc/rc";
exec.poststart = "/bin/sh /etc/jail.poststart";
exec.prestop = "/bin/sh /etc/jail.prestop";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.poststop = "/bin/sh /etc/jail.poststop";
# Mount points
mount.devfs;
mount.fstab = "/etc/fstab.webserver";
# VNET (if enabled)
vnet;
vnet.interface = "epair0b";
}
|
🛠️ Service Script Development
Creating Custom RC Scripts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | #!/bin/sh
# /usr/local/etc/rc.d/myservice
# Custom service script example
# PROVIDE: myservice
# REQUIRE: LOGIN
# BEFORE: DAEMON
# KEYWORD: shutdown
. /etc/rc.subr
name="myservice"
rcvar="myservice_enable"
# Default values
: ${myservice_enable="NO"}
: ${myservice_user="nobody"}
: ${myservice_config="/usr/local/etc/myservice.conf"}
# Command to execute
command="/usr/local/bin/myservice"
command_args="--config=${myservice_config}"
run_rc_command "$1"
|
Advanced Service Script Features
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 | #!/bin/sh
# Advanced service script with custom functions
# PROVIDE: advancedservice
# REQUIRE: NETWORK SERVERS
# KEYWORD: shutdown
. /etc/rc.subr
name="advancedservice"
rcvar="advancedservice_enable"
# Configuration
load_rc_config "$name"
: ${advancedservice_enable="NO"}
: ${advancedservice_user="daemon"}
: ${advancedservice_flags=""}
# Paths
command="/usr/local/sbin/advancedservice"
pidfile="/var/run/advancedservice.pid"
required_files="/usr/local/etc/advancedservice.conf"
# Custom pre-start function
advancedservice_prestart() {
# Check prerequisites
if [ ! -r "$required_files" ]; then
echo "Configuration file not readable: $required_files"
return 1
fi
# Create runtime directories
install -d -o "$advancedservice_user" /var/run/advancedservice
}
# Custom start function
advancedservice_start() {
echo "Starting $name..."
# Start with custom environment
/usr/sbin/daemon \
-u "$advancedservice_user" \
-p "$pidfile" \
-r \
$command $advancedservice_flags
}
# Custom stop function
advancedservice_stop() {
echo "Stopping $name..."
# Graceful shutdown
if [ -f "$pidfile" ]; then
kill -TERM $(cat "$pidfile")
sleep 5
# Force kill if still running
if [ -f "$pidfile" ]; then
kill -KILL $(cat "$pidfile") 2>/dev/null || true
rm -f "$pidfile"
fi
fi
}
# Use custom functions
start_cmd="advancedservice_start"
stop_cmd="advancedservice_stop"
prestart_cmd="advancedservice_prestart"
run_rc_command "$1"
|
📊 Monitoring and Management
Service Monitoring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | # Service status monitoring
service_status_check() {
local service="$1"
if service "$service" status >/dev/null 2>&1; then
echo "$service: RUNNING"
return 0
else
echo "$service: STOPPED"
return 1
fi
}
# Monitor multiple services
monitor_services() {
local services=("sshd" "nginx" "postgresql" "redis")
for svc in "${services[@]}"; do
service_status_check "$svc"
done
}
# Automated service restart
auto_restart_service() {
local service="$1"
if ! service "$service" status >/dev/null 2>&1; then
echo "Restarting $service..."
service "$service" restart
# Log restart event
logger -t "service-monitor" "Restarted $service"
fi
}
|
Jail Monitoring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 | # Jail status monitoring
jail_status() {
echo "=== Jail Status ==="
jls -v # Verbose jail list
echo -e "\n=== Jail Resource Usage ==="
for jail in $(jls -h name); do
echo "Jail: $jail"
jexec "$jail" top -b -n 1 | head -20
echo "---"
done
}
# Jail health checks
check_jail_health() {
local jail_name="$1"
# Check if jail is running
if ! jls | grep -q "$jail_name"; then
echo "Jail $jail_name is not running"
return 1
fi
# Check basic connectivity
local jail_ip
jail_ip=$(jls -j "$jail_name" ip4.addr)
if ping -c 1 "$jail_ip" >/dev/null 2>&1; then
echo "Jail $jail_name network connectivity: OK"
else
echo "Jail $jail_name network connectivity: FAILED"
return 1
fi
# Check service inside jail
if jexec "$jail_name" pgrep -f "nginx" >/dev/null 2>&1; then
echo "Jail $jail_name nginx service: RUNNING"
else
echo "Jail $jail_name nginx service: STOPPED"
return 1
fi
return 0
}
|
🔍 Troubleshooting
Common RC Issues
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | # Service won't start
# 1. Check configuration
service servicename rcvar
# 2. Check logs
tail /var/log/messages
dmesg | tail
# 3. Run in foreground for debugging
service servicename onestart
# 4. Check dependencies
service servicename depend
# Service starts but fails quickly
# Check service-specific logs
# Review service configuration files
# Verify required files/directories exist
# Configuration issues
# Validate syntax
sysrc -a | grep servicename
# Reset to defaults
sysrc -x servicename_enable
|
Jail Troubleshooting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | # Jail won't start
# 1. Check configuration syntax
jail -n -f /etc/jail.conf -c
# 2. Check filesystem permissions
ls -la /usr/jails/jailname
# 3. Check network configuration
ifconfig | grep epair
# 4. Check logs
tail /var/log/messages
# Jail networking issues
# 1. Verify IP configuration
jls -v
# 2. Check routing
route -n get 192.168.1.100
# 3. Test connectivity from host
ping 192.168.1.100
# Inside jail issues
# 1. Access jail console
jexec jailname /bin/sh
# 2. Check jail processes
jexec jailname ps aux
# 3. Check jail filesystem
jexec jailname df -h
|
🎨 Advanced Features
Hierarchical Jails
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | # Nested jail configuration
# Parent jail
parent {
host.hostname = "parent.example.com";
ip4.addr = 192.168.1.100;
path = "/usr/jails/parent";
children = "child1 child2";
# Child jails inherit some properties
child1 {
ip4.addr = 192.168.1.101;
path = "/usr/jails/parent/child1";
}
child2 {
ip4.addr = 192.168.1.102;
path = "/usr/jails/parent/child2";
}
}
|
VNET Jails
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | # VNET (Virtual Network Stack) jails
# Provides complete network stack isolation
vnetjail {
host.hostname = "vnet.example.com";
path = "/usr/jails/vnetjail";
vnet;
vnet.interface = "epair0b";
# VNET specific configuration
exec.prestart = "/sbin/ifconfig epair0 create";
exec.created = "/sbin/ifconfig epair0a up";
exec.poststart = "/sbin/ifconfig epair0b up";
exec.prestop = "/sbin/ifconfig epair0a destroy";
}
|
🧾 Security Best Practices
Service Security
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | # Run services with minimal privileges
service_user_nobody() {
local service="$1"
sysrc "${service}_user"="nobody"
sysrc "${service}_group"="nobody"
}
# Chroot services when possible
# Configure services to run in restricted directories
# Use service-specific configuration files with proper permissions
# Regular service audits
audit_services() {
echo "=== Service Security Audit ==="
# Check for services running as root
for svc in $(service -l); do
if service "$svc" rcvar 2>/dev/null | grep -q "_user.*root"; then
echo "WARNING: $svc running as root"
fi
done
# Check service configuration permissions
find /usr/local/etc -name "*.conf" -perm 644 -exec chmod 600 {} \;
}
|
Jail Security
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | # Secure jail configuration
secure_jail() {
local jail_name="$1"
# Minimal devfs rules
echo 'devfs_ruleset="4"' >> "/etc/jail.conf"
# Restrict filesystem access
echo 'enforce_statfs="2"' >> "/etc/jail.conf"
# Disable dangerous syscalls
echo 'allow.raw_sockets="false"' >> "/etc/jail.conf"
# Limit resources
echo 'maxproc="50"' >> "/etc/jail.conf"
echo 'cputime="300"' >> "/etc/jail.conf"
# Regular security updates
jexec "$jail_name" freebsd-update fetch install
}
# Jail hardening
harden_jail() {
# Remove unnecessary packages
jexec jailname pkg autoremove
# Disable unnecessary services
jexec jailname service -l | grep -E "(bluetooth|cups|avahi)" | \
while read svc; do
jexec jailname sysrc "${svc}_enable"="NO"
done
# Secure SSH access
jexec jailname sysrc sshd_enable="NO" # If not needed
}
|
🧾 Summary Commands
Essential RC Commands
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | # Service management
service servicename start|stop|restart|status
sysrc servicename_enable=YES|NO
service -l # List services
service -r # List running services
# Configuration management
sysrc -a # Show all settings
sysrc -x setting # Remove setting
sysrc -f /path/to/file setting # Use specific file
# System information
rcorder /etc/rc.d/* # Show boot order
service -e # Show enabled services
|
Essential Jail Commands
| # Jail management
jls # List jails
jexec jailname command # Execute in jail
jail -f /etc/jail.conf -c jailname # Start jail
service jail start|stop jailname # Service control
# Jail creation (with ezjail)
ezjail-admin install # Install ezjail
ezjail-admin create name ip # Create jail
ezjail-admin start|stop name # Control jail
ezjail-admin console name # Console access
|
🧾 See Also