Przejdź do treści

🦉 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.

1
2
3
4
5
6
# 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 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