Пользовательские скрипты и задачи pfSense

pfSense построен на FreeBSD и предоставляет полноценную командную строку, PHP-интерпретатор и механизмы автозагрузки. Это позволяет создавать пользовательские скрипты для задач, которые не покрываются веб-интерфейсом: автоматическое резервное копирование на удаленный сервер, ротация логов, мониторинговые проверки и обновление сертификатов. Для управления скриптами и задачами по расписанию в pfSense доступны пакеты Shellcmd и Cron.

Выполнение команд через веб-интерфейс

pfSense предоставляет два инструмента для работы с системой через браузер без SSH-доступа.

Diagnostics - Command Prompt

Страница Diagnostics > Command Prompt позволяет выполнять shell-команды и PHP-код непосредственно из веб-интерфейса.

Execute Shell Command - выполняет произвольную команду FreeBSD:

# Проверка дискового пространства
df -h

# Просмотр запущенных процессов
ps aux | grep openvpn

# Проверка сетевых соединений
netstat -an | grep ESTABLISHED | wc -l

Execute PHP Command - выполняет PHP-код с доступом к функциям pfSense:

require_once("config.inc");
require_once("interfaces.inc");

// Вывод имени хоста
echo $config['system']['hostname'] . "." . $config['system']['domain'];

Diagnostics - Edit File

Страница Diagnostics > Edit File предоставляет текстовый редактор для просмотра и изменения файлов на файловой системе. Полезна для редактирования конфигурационных файлов без SSH-доступа.

Пакет Shellcmd - команды при загрузке

Пакет Shellcmd позволяет задавать команды, которые выполняются при загрузке pfSense. Это замена ручному редактированию config.xml для добавления тегов <shellcmd>.

Установка

System > Package Manager > Available Packages - найти и установить Shellcmd.

После установки настройка доступна через Services > Shellcmd.

Типы команд

ТипМомент выполненияИспользование
shellcmdКонец процесса загрузкиОсновные задачи при старте
earlyshellcmdНачало процесса загрузки (до запуска сервисов)Загрузка модулей ядра, монтирование файловых систем
afterfilterchangeshellcmdПосле каждого изменения правил файрволаДинамические правила, интеграции

Пример конфигурации

Command: /usr/local/bin/custom-startup.sh
Type: shellcmd
Description: Custom startup script

Команды также можно добавлять напрямую в config.xml:

<shellcmd>/usr/local/bin/custom-startup.sh</shellcmd>
<earlyshellcmd>kldload if_tap</earlyshellcmd>

Рекомендации

  • Используйте абсолютные пути к исполняемым файлам
  • Скрипты должны быть исполняемыми (chmod +x)
  • Длительные операции запускайте в фоне с &
  • Перенаправляйте вывод в лог для отладки: /usr/local/bin/script.sh > /var/log/custom-startup.log 2>&1 &

Пакет Cron - задачи по расписанию

Пакет Cron предоставляет веб-интерфейс для управления cron-задачами. pfSense использует стандартный FreeBSD cron, но пакет добавляет графическое управление через Services > Cron.

Установка

System > Package Manager > Available Packages - найти и установить Cron.

Формат расписания

*    *    *    *    *    command
|    |    |    |    |
|    |    |    |    +--- День недели (0-7, 0 и 7 = воскресенье)
|    |    |    +-------- Месяц (1-12)
|    |    +------------- День месяца (1-31)
|    +------------------ Час (0-23)
+----------------------- Минута (0-59)

Примеры задач

ЗадачаРасписаниеКоманда
Бэкап конфигурации ежедневно в 2:000 2 * * */usr/local/bin/backup-config.sh
Перезапуск OpenVPN каждые 6 часов0 */6 * * */usr/local/sbin/pfSsh.php playback svc restart openvpn
Очистка tmp каждое воскресенье0 3 * * 0/usr/bin/find /tmp -type f -mtime +7 -delete
Проверка дискового пространства каждый час0 * * * */usr/local/bin/check-disk.sh

Пользовательские PHP-скрипты

PHP-скрипты имеют полный доступ к конфигурации и функциям pfSense. Интерпретатор находится по пути /usr/local/bin/php.

Структура скрипта

#!/usr/local/bin/php
<?php
require_once("config.inc");
require_once("functions.inc");
require_once("filter.inc");

// Доступ к конфигурации
$hostname = $config['system']['hostname'];
$interfaces = $config['interfaces'];

// Пример: подсчет активных правил файрвола
$rules = $config['filter']['rule'];
$active_rules = array_filter($rules, function($rule) {
    return !isset($rule['disabled']);
});

echo "Active firewall rules: " . count($active_rules) . "\n";

Полезные include-файлы

ФайлНазначение
config.incЗагрузка массива $config
functions.incОбщие вспомогательные функции
filter.incУправление правилами файрвола
interfaces.incФункции работы с интерфейсами
openvpn.incФункции управления OpenVPN
certs.incФункции работы с сертификатами
notices.incСистема уведомлений

Автозагрузочные скрипты rc.d

Скрипты в каталоге /usr/local/etc/rc.d/ автоматически запускаются при загрузке системы в стиле FreeBSD rc.d.

Пример rc.d-скрипта

#!/bin/sh

# PROVIDE: custom_monitor
# REQUIRE: NETWORKING
# BEFORE: LOGIN

. /etc/rc.subr

name="custom_monitor"
rcvar="${name}_enable"
command="/usr/local/bin/custom-monitor.sh"
command_args="&"

load_rc_config $name
run_rc_command "$1"

Для активации добавьте в /etc/rc.conf.local:

custom_monitor_enable="YES"

Правила devd

devd (device daemon) реагирует на системные события - подключение устройств, изменение сетевых интерфейсов. Пользовательские правила devd размещаются в /etc/devd/.

notify 0 {
    match "system"    "IFNET";
    match "subsystem" "igb0";
    match "type"      "LINK_UP";
    action "/usr/local/bin/link-up-handler.sh";
};

После изменения правил перезапустите devd:

service devd restart

Типовые задачи автоматизации

Автоматический бэкап на удаленный сервер

#!/bin/sh
# /usr/local/bin/backup-config.sh
# Резервное копирование config.xml на удаленный сервер по SCP

REMOTE_USER="backup"
REMOTE_HOST="backup.example.com"
REMOTE_DIR="/backups/pfsense"
DATE=$(date +%Y%m%d-%H%M)

cp /cf/conf/config.xml /tmp/config-${DATE}.xml
scp -i /root/.ssh/backup_key /tmp/config-${DATE}.xml \
  ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/
rm /tmp/config-${DATE}.xml

logger -t backup "Configuration backed up to ${REMOTE_HOST}"

Ротация логов

#!/bin/sh
# /usr/local/bin/rotate-custom-logs.sh
# Ротация пользовательских логов

LOG_DIR="/var/log/custom"
MAX_FILES=7

for logfile in ${LOG_DIR}/*.log; do
    if [ -f "${logfile}" ]; then
        cp "${logfile}" "${logfile}.$(date +%Y%m%d)"
        : > "${logfile}"
    fi
done

# Удаление старых файлов
find ${LOG_DIR} -name "*.log.*" -mtime +${MAX_FILES} -delete

Мониторинговая проверка шлюза

#!/bin/sh
# /usr/local/bin/check-gateway.sh
# Проверка доступности шлюза и уведомление

GATEWAY="10.0.0.1"
ALERT_EMAIL="admin@example.com"

if ! ping -c 3 -W 5 ${GATEWAY} > /dev/null 2>&1; then
    echo "Gateway ${GATEWAY} unreachable at $(date)" | \
      mail -s "pfSense: Gateway Down" ${ALERT_EMAIL}
    logger -t gateway-check "Gateway ${GATEWAY} is unreachable"
fi

Скрипт обновления сертификатов

#!/usr/local/bin/php
<?php
// /usr/local/bin/check-cert-expiry.php
// Проверка срока действия сертификатов

require_once("config.inc");
require_once("certs.inc");

$warning_days = 30;

foreach ($config['cert'] as $cert) {
    $info = openssl_x509_parse(base64_decode($cert['crt']));
    if ($info === false) continue;

    $expires = $info['validTo_time_t'];
    $days_left = floor(($expires - time()) / 86400);

    if ($days_left < $warning_days) {
        $msg = "Certificate '{$cert['descr']}' expires in {$days_left} days";
        log_error($msg);
        // Можно добавить отправку уведомления
    }
}

Предупреждения о пользовательских модификациях

Пользовательские изменения в pfSense сопряжены с определенными рисками. Несоблюдение следующих правил может привести к неработоспособности системы после обновления.

РискОписаниеРекомендация
Потеря при обновленииФайлы вне /usr/local/ и /root/ перезаписываются при обновлении pfSenseРазмещайте скрипты в /usr/local/bin/ или /root/
Несовместимость APIPHP-функции pfSense могут измениться между версиямиПроверяйте работу скриптов после каждого обновления
БезопасностьСкрипты выполняются с правами rootМинимизируйте привилегии, проверяйте ввод
config.xmlПрямое редактирование config.xml может нарушить структуруИспользуйте PHP API (write_config()) вместо прямого редактирования
Пакеты Shellcmd/CronНеработающий скрипт в shellcmd может задержать загрузкуТестируйте скрипты перед добавлением в автозагрузку

Перед каждым обновлением pfSense создайте полную резервную копию и составьте список всех пользовательских модификаций.

Связанные разделы

Last updated on