TFTP Server в VyOS

TFTP (Trivial File Transfer Protocol) - это простой протокол передачи файлов, широко используемый для загрузки конфигураций, прошивок и образов на сетевое оборудование. VyOS может выступать в роли TFTP-сервера для централизованного управления конфигурациями устройств.

Основные возможности

  • Простота: Минимальные требования к клиентам (нет аутентификации)
  • PXE Boot: Загрузка операционных систем по сети (бездисковые рабочие станции)
  • Сетевое оборудование: Загрузка конфигураций и прошивок на коммутаторы, маршрутизаторы, IP-телефоны
  • Backup конфигураций: Централизованное хранение конфигураций устройств
  • Низкие требования: Работает поверх UDP, не требует установления соединения
  • Интеграция с DHCP: Автоматическая настройка клиентов через DHCP option 66/67

Особенности протокола TFTP

Преимущества:

  • Простота реализации
  • Минимальные требования к ресурсам
  • Поддержка всеми сетевыми устройствами
  • Работает в pre-boot окружении (PXE)

Ограничения:

  • Нет аутентификации (только ACL по IP)
  • Нет шифрования (передача в открытом виде)
  • Максимальный размер файла: 32 МБ (расширенный режим до 4 ГБ)
  • Только чтение и запись файлов (нет листинга директорий)
  • UDP порт 69

Рекомендации по безопасности:

  • Использовать только в доверенных сетях (management VLAN)
  • Ограничивать доступ через firewall ACL
  • Не хранить конфиденциальные данные
  • Использовать read-only режим где возможно

Базовая конфигурация

Простой TFTP-сервер

# Включить TFTP-сервер
set service tftp-server listen-address 192.168.1.1

# Директория для файлов (по умолчанию /srv/tftp)
set service tftp-server directory /config/tftp

# Разрешить загрузку файлов на сервер
set service tftp-server allow-upload

commit
save

Проверка:

# Статус TFTP-сервера
show service tftp-server

# Проверить порт
show system connections port 69

# Посмотреть файлы в TFTP-директории
ls -lh /config/tftp

Тестирование с клиента:

# Linux
tftp 192.168.1.1
tftp> get test.txt
tftp> put backup.cfg
tftp> quit

# Или одной командой
tftp -m binary 192.168.1.1 -c get test.txt

# Windows
tftp -i 192.168.1.1 get test.txt
tftp -i 192.168.1.1 put backup.cfg

TFTP с контролем доступа

# TFTP-сервер
set service tftp-server listen-address 192.168.100.1
set service tftp-server directory /config/tftp

# Разрешить только чтение (запретить upload)
delete service tftp-server allow-upload

# Firewall - разрешить доступ только с management сети
set firewall group network-group MGMT_NETWORKS network 192.168.100.0/24
set firewall group network-group MGMT_NETWORKS network 10.10.10.0/24

set firewall name MGMT_LOCAL rule 100 action accept
set firewall name MGMT_LOCAL rule 100 protocol udp
set firewall name MGMT_LOCAL rule 100 destination port 69
set firewall name MGMT_LOCAL rule 100 source group network-group MGMT_NETWORKS

# Применить firewall к интерфейсу
set firewall interface eth1 local name MGMT_LOCAL

commit
save

Создание структуры директорий

# Создать директории для разных типов устройств
sudo mkdir -p /config/tftp/{configs,firmware,pxe,phones}
sudo chown -R tftp:tftp /config/tftp
sudo chmod -R 755 /config/tftp

# Для upload необходимы права записи
sudo chmod 777 /config/tftp/configs

Структура директорий:

/config/tftp/
├── configs/          # Конфигурации устройств
│   ├── switches/
│   ├── routers/
│   └── wireless/
├── firmware/         # Прошивки
│   ├── cisco/
│   ├── mikrotik/
│   └── ubiquiti/
├── pxe/             # PXE boot образы
│   ├── pxelinux.0
│   ├── kernel
│   └── initrd
└── phones/          # Конфигурации IP-телефонов
    ├── yealink/
    └── grandstream/

Расширенная конфигурация

Интеграция с DHCP для PXE Boot

# TFTP-сервер
set service tftp-server listen-address 192.168.1.1
set service tftp-server directory /config/tftp/pxe

# DHCP-сервер с опциями PXE
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 range 0 start 192.168.1.100
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 range 0 stop 192.168.1.200
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option default-router 192.168.1.1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option name-server 192.168.1.1

# DHCP Option 66 - TFTP server IP
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option tftp-server-name 192.168.1.1

# DHCP Option 67 - Boot filename
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option bootfile-name 'pxelinux.0'

commit
save

TFTP для IP-телефонов

# TFTP для телефонов Yealink, Grandstream
set service tftp-server listen-address 192.168.10.1
set service tftp-server directory /config/tftp/phones

# DHCP для IP-телефонов (отдельная VLAN)
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 range 0 start 192.168.10.100
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 range 0 stop 192.168.10.200
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option default-router 192.168.10.1
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option name-server 192.168.10.1

# TFTP server для телефонов
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option tftp-server-name 192.168.10.1

# Option 66 (альтернативный синтаксис)
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option tftp-server 192.168.10.1

commit
save

Подготовка конфигураций телефонов:

# Yealink - автоматическая настройка
sudo tee /config/tftp/phones/y000000000000.cfg > /dev/null <<'EOF'
#!version:1.0.0.1
account.1.enable = 1
account.1.label = Office
account.1.display_name = John Doe
account.1.auth_name = 1001
account.1.user_name = 1001
account.1.password = SecretPassword
account.1.sip_server.1.address = pbx.example.com
account.1.sip_server.1.port = 5060
EOF

# Grandstream
sudo tee /config/tftp/phones/cfg000b82000000 > /dev/null <<'EOF'
## Grandstream Config
P47 = pbx.example.com
P35 = 1001
P36 = SecretPassword
P34 = 1001
P3 = 5060
EOF

sudo chown tftp:tftp /config/tftp/phones/*.cfg

TFTP для сетевого оборудования Cisco

# TFTP-сервер для Cisco устройств
set service tftp-server listen-address 10.0.0.1
set service tftp-server directory /config/tftp/cisco
set service tftp-server allow-upload

# Firewall - разрешить доступ только с устройств Cisco
set firewall group network-group CISCO_SWITCHES network 10.0.1.0/24
set firewall group network-group CISCO_SWITCHES network 10.0.2.0/24

set firewall name CISCO_MGMT_LOCAL rule 50 action accept
set firewall name CISCO_MGMT_LOCAL rule 50 protocol udp
set firewall name CISCO_MGMT_LOCAL rule 50 destination port 69
set firewall name CISCO_MGMT_LOCAL rule 50 source group network-group CISCO_SWITCHES

set firewall interface eth0 local name CISCO_MGMT_LOCAL

commit
save

Резервное копирование конфигурации Cisco:

# На Cisco устройстве
Switch# copy running-config tftp:
Address or name of remote host []? 10.0.0.1
Destination filename [switch-confg]? switch-01-backup.cfg

# Восстановление конфигурации
Switch# copy tftp: running-config
Address or name of remote host []? 10.0.0.1
Source filename []? switch-01-backup.cfg

Автоматизация резервного копирования

# Скрипт для автоматического backup конфигураций Cisco
sudo tee /config/scripts/tftp-backup-cisco.sh > /dev/null <<'EOF'
#!/bin/bash
# Автоматическое резервное копирование конфигураций Cisco через TFTP

TFTP_DIR="/config/tftp/cisco/backups"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="$TFTP_DIR/$DATE"

mkdir -p "$BACKUP_DIR"

# Список устройств (IP:hostname)
DEVICES=(
    "10.0.1.10:core-switch-01"
    "10.0.1.11:core-switch-02"
    "10.0.2.10:access-switch-01"
)

for device in "${DEVICES[@]}"; do
    IP="${device%%:*}"
    NAME="${device##*:}"

    echo "Backing up $NAME ($IP)..."

    # Использовать expect для автоматизации (требует установки expect)
    /usr/bin/expect <<EXPECT_EOF
    spawn ssh admin@$IP
    expect "Password:"
    send "YourPassword\r"
    expect "#"
    send "copy running-config tftp://10.0.0.1/$DATE/$NAME.cfg\r"
    expect "Address or name of remote host"
    send "\r"
    expect "Destination filename"
    send "\r"
    expect "#"
    send "exit\r"
EXPECT_EOF

    echo "Backup completed: $NAME"
done

# Удалить старые резервные копии (старше 30 дней)
find "$TFTP_DIR" -type d -mtime +30 -exec rm -rf {} \;

echo "All backups completed on $DATE"
EOF

sudo chmod +x /config/scripts/tftp-backup-cisco.sh

# Запланировать ежедневный backup в 3 утра
set system task-scheduler task cisco-backup interval '0 3 * * *'
set system task-scheduler task cisco-backup executable path '/config/scripts/tftp-backup-cisco.sh'

commit
save

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

1. PXE Boot сервер для бездисковых станций

Задача: Настроить VyOS как PXE-сервер для загрузки Linux по сети.

# TFTP-сервер для PXE
set service tftp-server listen-address 192.168.1.1
set service tftp-server directory /config/tftp/pxe

# DHCP с PXE опциями
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 range 0 start 192.168.1.50
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 range 0 stop 192.168.1.150
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option default-router 192.168.1.1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option name-server 192.168.1.1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option tftp-server-name 192.168.1.1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option bootfile-name 'pxelinux.0'

commit
save

Подготовка PXE окружения:

# Установить необходимые пакеты
sudo mkdir -p /config/tftp/pxe/{pxelinux.cfg,images}

# Скачать PXELINUX
wget https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz
tar -xzf syslinux-6.03.tar.gz
sudo cp syslinux-6.03/bios/core/pxelinux.0 /config/tftp/pxe/
sudo cp syslinux-6.03/bios/com32/elflink/ldlinux/ldlinux.c32 /config/tftp/pxe/
sudo cp syslinux-6.03/bios/com32/menu/vesamenu.c32 /config/tftp/pxe/
sudo cp syslinux-6.03/bios/com32/libutil/libutil.c32 /config/tftp/pxe/

# Скачать Ubuntu Live для PXE
cd /config/tftp/pxe/images
wget http://archive.ubuntu.com/ubuntu/dists/jammy/main/installer-amd64/current/legacy-images/netboot/netboot.tar.gz
tar -xzf netboot.tar.gz

# Создать меню загрузки
sudo tee /config/tftp/pxe/pxelinux.cfg/default > /dev/null <<'EOF'
DEFAULT vesamenu.c32
TIMEOUT 300
PROMPT 0

MENU TITLE PXE Boot Menu

LABEL ubuntu-install
    MENU LABEL Install Ubuntu 22.04 Server
    KERNEL images/ubuntu-installer/linux
    APPEND vga=788 initrd=images/ubuntu-installer/initrd.gz

LABEL ubuntu-live
    MENU LABEL Ubuntu 22.04 Live (no install)
    KERNEL images/ubuntu-live/vmlinuz
    APPEND initrd=images/ubuntu-live/initrd boot=casper netboot=nfs nfsroot=192.168.1.1:/srv/nfs/ubuntu-live

LABEL local
    MENU LABEL Boot from local disk
    LOCALBOOT 0
EOF

sudo chown -R tftp:tftp /config/tftp/pxe

Тестирование PXE:

  1. Загрузить клиентскую машину
  2. В BIOS включить PXE/Network Boot
  3. Выбрать сетевую карту как первое загрузочное устройство
  4. Перезагрузить - должно появиться PXE меню

2. TFTP для централизованного backup конфигураций Mikrotik

Задача: Автоматическое резервное копирование конфигураций Mikrotik роутеров.

# TFTP-сервер для Mikrotik
set service tftp-server listen-address 10.0.0.1
set service tftp-server directory /config/tftp/mikrotik
set service tftp-server allow-upload

# Firewall
set firewall group network-group MIKROTIK_DEVICES network 10.0.1.0/24

set firewall name MIKROTIK_MGMT_LOCAL rule 60 action accept
set firewall name MIKROTIK_MGMT_LOCAL rule 60 protocol udp
set firewall name MIKROTIK_MGMT_LOCAL rule 60 destination port 69
set firewall name MIKROTIK_MGMT_LOCAL rule 60 source group network-group MIKROTIK_DEVICES

set firewall interface eth0 local name MIKROTIK_MGMT_LOCAL

commit
save

Создать структуру для backup:

sudo mkdir -p /config/tftp/mikrotik/backups
sudo chmod 777 /config/tftp/mikrotik/backups

Скрипт на Mikrotik для автоматического backup:

# Mikrotik RouterOS скрипт
/system script add name=backup-to-tftp source={
    /system backup save name=backup-latest
    :delay 5s
    /tool fetch address=10.0.0.1 src-path=backup-latest.backup dst-path=backups/[/system identity get name]-[/system clock get date].backup upload=yes mode=tftp
}

# Запланировать ежедневный backup в 4 утра
/system scheduler add name=daily-backup interval=1d start-time=04:00:00 on-event=backup-to-tftp

Мониторинг backup на VyOS:

# Скрипт для проверки свежести backup
sudo tee /config/scripts/check-mikrotik-backups.sh > /dev/null <<'EOF'
#!/bin/bash
BACKUP_DIR="/config/tftp/mikrotik/backups"
TODAY=$(date +%Y-%m-%d)
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)

echo "Checking Mikrotik backups..."

for device in router-01 router-02 router-03; do
    LATEST=$(find "$BACKUP_DIR" -name "$device-*" -mtime -1 | wc -l)

    if [ "$LATEST" -eq 0 ]; then
        echo "WARNING: No recent backup for $device"
        # Отправить алерт (email, telegram, syslog)
        logger -t mikrotik-backup "WARNING: Missing backup for $device"
    else
        echo "OK: $device backup found"
    fi
done
EOF

sudo chmod +x /config/scripts/check-mikrotik-backups.sh

# Запланировать проверку каждое утро в 8:00
set system task-scheduler task check-backups interval '0 8 * * *'
set system task-scheduler task check-backups executable path '/config/scripts/check-mikrotik-backups.sh'

commit
save

3. TFTP для IP-телефонов Yealink в офисе

Задача: Централизованное управление конфигурацией 50 IP-телефонов Yealink.

# TFTP для Voice VLAN
set service tftp-server listen-address 192.168.10.1
set service tftp-server directory /config/tftp/yealink

# DHCP для Voice VLAN (802.1Q VLAN 10)
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 range 0 start 192.168.10.100
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 range 0 stop 192.168.10.200
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option default-router 192.168.10.1
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option name-server 192.168.10.1
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option tftp-server-name 192.168.10.1

# VLAN для Voice
set interfaces ethernet eth1 vif 10 address 192.168.10.1/24
set interfaces ethernet eth1 vif 10 description 'Voice VLAN'

commit
save

Создать общий конфигурационный файл для всех телефонов:

# Общая конфигурация для всех Yealink (y000000000000.cfg)
sudo tee /config/tftp/yealink/y000000000000.cfg > /dev/null <<'EOF'
#!version:1.0.0.1

## Общие настройки
lang.gui = Russian
lang.wui = Russian
local_time.time_zone = +3
local_time.ntp_server1 = pool.ntp.org
local_time.dhcp_time = 0

## SIP сервер
account.1.sip_server.1.address = pbx.corp.local
account.1.sip_server.1.port = 5060
account.1.outbound_proxy.1.address = pbx.corp.local
account.1.outbound_proxy.1.port = 5060

## Автоматическая подготовка
auto_provision.mode = 6
auto_provision.schedule.periodic_minute = 1440
auto_provision.server.url = http://192.168.10.1/provision/

## Качество звука
voice.codec.1.enable = 1
voice.codec.1.payload_type = PCMU
voice.codec.2.enable = 1
voice.codec.2.payload_type = PCMA
voice.codec.3.enable = 1
voice.codec.3.payload_type = G722

## Сетевые настройки
network.vlan.internet_port_enable = 1
network.vlan.internet_port_vid = 10
network.vlan.internet_port_priority = 5
network.lldp.enable = 1

## Безопасность
security.user_password = admin:AdminPassword123

## Функциональные клавиши
programablekey.1.type = 15
programablekey.1.line = 1
programablekey.1.value = Voicemail
programablekey.1.label = Голосовая почта

## Обои и заставка
wallpaper.file_name = /config/tftp/yealink/wallpaper.jpg
screensaver.file_name = /config/tftp/yealink/screensaver.jpg
EOF

sudo chown tftp:tftp /config/tftp/yealink/y000000000000.cfg

Индивидуальные конфигурации по MAC-адресу:

# Пример для конкретного телефона (MAC: 00:15:65:12:34:56)
sudo tee /config/tftp/yealink/001565123456.cfg > /dev/null <<'EOF'
#!version:1.0.0.1
# Наследуем общую конфигурацию
include:config y000000000000.cfg

## Индивидуальные настройки для конкретного телефона
account.1.enable = 1
account.1.label = Reception
account.1.display_name = Стойка регистрации
account.1.auth_name = 1000
account.1.user_name = 1000
account.1.password = SecretPass1000

## BLF кнопки (мониторинг других линий)
programablekey.2.type = 16
programablekey.2.line = 1
programablekey.2.value = 1001
programablekey.2.label = Директор

programablekey.3.type = 16
programablekey.3.line = 1
programablekey.3.value = 1002
programablekey.3.label = Бухгалтерия
EOF

sudo chown tftp:tftp /config/tftp/yealink/*.cfg

Массовое развертывание через скрипт:

# Скрипт для генерации конфигураций из CSV
sudo tee /config/scripts/generate-yealink-configs.sh > /dev/null <<'EOF'
#!/bin/bash
# Генерация конфигураций Yealink из CSV файла
# Формат CSV: MAC,Extension,Name,Password

CSV_FILE="/config/tftp/yealink/phones.csv"
CONFIG_DIR="/config/tftp/yealink"

while IFS=, read -r mac ext name password; do
    # Пропустить заголовок
    [[ "$mac" == "MAC" ]] && continue

    # Убрать двоеточия из MAC
    mac_clean=$(echo "$mac" | tr -d ':' | tr '[:upper:]' '[:lower:]')

    cat > "$CONFIG_DIR/${mac_clean}.cfg" <<CONFIG
#!version:1.0.0.1
include:config y000000000000.cfg

account.1.enable = 1
account.1.label = $name
account.1.display_name = $name
account.1.auth_name = $ext
account.1.user_name = $ext
account.1.password = $password
CONFIG

    echo "Generated config for $name ($ext) - MAC: $mac"
done < "$CSV_FILE"

chown tftp:tftp "$CONFIG_DIR"/*.cfg
echo "All phone configs generated"
EOF

sudo chmod +x /config/scripts/generate-yealink-configs.sh

Файл phones.csv:

MAC,Extension,Name,Password
00:15:65:12:34:56,1000,Reception,Pass1000
00:15:65:12:34:57,1001,Director,Pass1001
00:15:65:12:34:58,1002,Accounting,Pass1002
00:15:65:12:34:59,1003,Sales,Pass1003

Запуск генерации:

sudo /config/scripts/generate-yealink-configs.sh

4. TFTP с HTTP provisioning для Cisco устройств

Задача: Комбинированное использование TFTP и HTTP для Cisco устройств.

# TFTP для legacy устройств
set service tftp-server listen-address 10.0.0.1
set service tftp-server directory /config/tftp/cisco

# HTTP для современных устройств
set service https listen-address 10.0.0.1
set service https allow-client address 10.0.0.0/8

commit
save

Создать HTTP provisioning структуру:

# Создать web-директорию для provisioning
sudo mkdir -p /var/www/html/cisco/{configs,firmware,scripts}
sudo ln -s /config/tftp/cisco /var/www/html/cisco/legacy

# Создать index.html для навигации
sudo tee /var/www/html/cisco/index.html > /dev/null <<'EOF'
<!DOCTYPE html>
<html>
<head>
    <title>Cisco Device Provisioning</title>
</head>
<body>
    <h1>Cisco Provisioning Server</h1>
    <ul>
        <li><a href="configs/">Configurations</a></li>
        <li><a href="firmware/">Firmware Images</a></li>
        <li><a href="scripts/">Scripts</a></li>
        <li><a href="legacy/">TFTP Files (Legacy)</a></li>
    </ul>
</body>
</html>
EOF

Скрипт для автоматического provisioning Cisco:

# ZTP (Zero Touch Provisioning) скрипт
sudo tee /var/www/html/cisco/scripts/ztp.py > /dev/null <<'EOF'
#!/usr/bin/env python3
import cli
import sys

# Базовая конфигурация для нового Cisco устройства
commands = [
    'hostname new-cisco-switch',
    'ip domain-name corp.local',
    'username admin privilege 15 secret AdminPassword123',
    'enable secret EnablePassword123',
    'ip default-gateway 10.0.0.1',
    'ip name-server 10.0.0.1',
    'ntp server 10.0.0.1',
    'logging host 10.0.0.1',
    'snmp-server community public RO',
    'snmp-server host 10.0.0.1 version 2c public',
    'line vty 0 4',
    'transport input ssh',
    'login local',
    'exit',
    'interface Vlan1',
    'ip address dhcp',
    'no shutdown',
    'exit',
    'crypto key generate rsa modulus 2048',
]

print("Starting Zero Touch Provisioning...")

for cmd in commands:
    try:
        cli.configure(cmd)
        print(f"OK: {cmd}")
    except Exception as e:
        print(f"ERROR: {cmd} - {e}")

print("Saving configuration...")
cli.execute('copy running-config startup-config')
print("ZTP completed successfully")
EOF

sudo chmod +x /var/www/html/cisco/scripts/ztp.py

DHCP с опциями для ZTP:

# DHCP для Cisco с ZTP
set service dhcp-server shared-network-name CISCO_MGMT subnet 10.0.0.0/24 range 0 start 10.0.0.100
set service dhcp-server shared-network-name CISCO_MGMT subnet 10.0.0.0/24 range 0 stop 10.0.0.200
set service dhcp-server shared-network-name CISCO_MGMT subnet 10.0.0.0/24 option default-router 10.0.0.1
set service dhcp-server shared-network-name CISCO_MGMT subnet 10.0.0.0/24 option name-server 10.0.0.1

# DHCP Option 150 - TFTP server (Cisco-specific)
set service dhcp-server shared-network-name CISCO_MGMT subnet 10.0.0.0/24 option tftp-server-name 10.0.0.1

# DHCP Option 67 - Boot file для ZTP
set service dhcp-server shared-network-name CISCO_MGMT subnet 10.0.0.0/24 option bootfile-name 'http://10.0.0.1/cisco/scripts/ztp.py'

commit
save

5. TFTP с ротацией и архивированием backup

Задача: Автоматическое архивирование старых backup с ротацией.

# TFTP-сервер
set service tftp-server listen-address 192.168.1.1
set service tftp-server directory /config/tftp
set service tftp-server allow-upload

commit
save

Скрипт для ротации и архивирования:

sudo tee /config/scripts/tftp-backup-rotation.sh > /dev/null <<'EOF'
#!/bin/bash
# Автоматическая ротация TFTP backup с архивированием

TFTP_DIR="/config/tftp"
ARCHIVE_DIR="/var/backups/tftp-archives"
RETENTION_DAYS=90

DATE=$(date +%Y%m%d)
ARCHIVE_NAME="tftp-backup-$DATE.tar.gz"

# Создать директорию для архивов
mkdir -p "$ARCHIVE_DIR"

echo "Starting TFTP backup rotation..."

# 1. Архивировать текущие backup старше 7 дней
find "$TFTP_DIR" -name "*.cfg" -mtime +7 -type f | while read file; do
    echo "Archiving: $file"

    # Создать структуру директорий в архиве
    relative_path="${file#$TFTP_DIR/}"
    archive_file="$ARCHIVE_DIR/$(dirname $relative_path)"
    mkdir -p "$archive_file"

    # Сжать и переместить
    gzip -c "$file" > "$archive_file/$(basename $file).gz"
    rm "$file"
done

# 2. Создать общий архив за месяц
if [ $(date +%d) -eq 01 ]; then
    LAST_MONTH=$(date -d "last month" +%Y%m)
    echo "Creating monthly archive for $LAST_MONTH..."

    tar -czf "$ARCHIVE_DIR/tftp-monthly-$LAST_MONTH.tar.gz" \
        -C "$ARCHIVE_DIR" \
        $(find "$ARCHIVE_DIR" -name "tftp-backup-${LAST_MONTH}*.tar.gz" -type f -printf "%f ")

    # Удалить дневные архивы после создания месячного
    find "$ARCHIVE_DIR" -name "tftp-backup-${LAST_MONTH}*.tar.gz" -type f -delete
fi

# 3. Удалить архивы старше срока хранения
find "$ARCHIVE_DIR" -name "tftp-monthly-*.tar.gz" -mtime +$RETENTION_DAYS -type f -delete

# 4. Статистика
TOTAL_SIZE=$(du -sh "$ARCHIVE_DIR" | cut -f1)
ARCHIVE_COUNT=$(find "$ARCHIVE_DIR" -type f | wc -l)

echo "Backup rotation completed"
echo "Total archives: $ARCHIVE_COUNT"
echo "Total size: $TOTAL_SIZE"

# Логировать в syslog
logger -t tftp-rotation "Backup rotation completed: $ARCHIVE_COUNT archives, $TOTAL_SIZE total"
EOF

sudo chmod +x /config/scripts/tftp-backup-rotation.sh

# Запланировать ежедневную ротацию в 5 утра
set system task-scheduler task tftp-rotation interval '0 5 * * *'
set system task-scheduler task tftp-rotation executable path '/config/scripts/tftp-backup-rotation.sh'

commit
save

6. Мониторинг TFTP-сервера с алертингом

Задача: Мониторинг доступности и активности TFTP-сервера.

# TFTP-сервер
set service tftp-server listen-address 192.168.1.1
set service tftp-server directory /config/tftp

# SNMP для мониторинга
set service snmp community public authorization ro
set service snmp listen-address 192.168.1.1

commit
save

Скрипт мониторинга с Telegram алертами:

sudo tee /config/scripts/tftp-monitor.sh > /dev/null <<'EOF'
#!/bin/bash
# Мониторинг TFTP-сервера с Telegram алертами

TFTP_DIR="/config/tftp"
TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN"
TELEGRAM_CHAT_ID="YOUR_CHAT_ID"

send_telegram() {
    local message="$1"
    curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
        -d "chat_id=$TELEGRAM_CHAT_ID" \
        -d "text=$message" \
        -d "parse_mode=Markdown" > /dev/null
}

# 1. Проверить, запущен ли TFTP
if ! systemctl is-active --quiet tftpd-hpa; then
    send_telegram "ALERT: TFTP service is DOWN on $(hostname)"
    logger -t tftp-monitor "CRITICAL: TFTP service is not running"
    exit 1
fi

# 2. Проверить доступность порта
if ! netstat -ln | grep -q ':69 '; then
    send_telegram "ALERT: TFTP port 69 is not listening on $(hostname)"
    logger -t tftp-monitor "CRITICAL: TFTP port not listening"
    exit 1
fi

# 3. Проверить место на диске
DISK_USAGE=$(df -h "$TFTP_DIR" | tail -1 | awk '{print $5}' | tr -d '%')
if [ "$DISK_USAGE" -gt 85 ]; then
    send_telegram "WARNING: TFTP disk usage is ${DISK_USAGE}% on $(hostname)"
    logger -t tftp-monitor "WARNING: High disk usage: ${DISK_USAGE}%"
fi

# 4. Проверить активность (файлы за последние 24 часа)
RECENT_FILES=$(find "$TFTP_DIR" -type f -mtime -1 | wc -l)
if [ "$RECENT_FILES" -eq 0 ]; then
    send_telegram "INFO: No TFTP activity in last 24 hours on $(hostname)"
    logger -t tftp-monitor "INFO: No TFTP activity detected"
fi

# 5. Статистика
TOTAL_FILES=$(find "$TFTP_DIR" -type f | wc -l)
TOTAL_SIZE=$(du -sh "$TFTP_DIR" | cut -f1)

logger -t tftp-monitor "OK: TFTP is running - $TOTAL_FILES files, $TOTAL_SIZE total"
EOF

sudo chmod +x /config/scripts/tftp-monitor.sh

# Запланировать проверку каждые 15 минут
set system task-scheduler task tftp-health-check interval '*/15 * * * *'
set system task-scheduler task tftp-health-check executable path '/config/scripts/tftp-monitor.sh'

commit
save

Мониторинг и диагностика

Операционные команды

# Статус TFTP-сервера
show service tftp-server

# Активные TFTP-соединения
show system connections port 69

# Логи TFTP (в syslog)
show log | match tftp

# Список файлов в TFTP-директории
ls -lh /config/tftp

# Использование дискового пространства
df -h /config

# Последние измененные файлы (upload)
find /config/tftp -type f -mtime -1 -ls

# Топ-10 самых больших файлов
du -ah /config/tftp | sort -rh | head -10

Анализ активности

# Скрипт для анализа TFTP логов
sudo tee /config/scripts/tftp-stats.sh > /dev/null <<'EOF'
#!/bin/bash
# Статистика использования TFTP

echo "TFTP Activity Statistics"
echo "========================"

# Количество обращений за сегодня
TODAY_REQUESTS=$(journalctl -u tftpd-hpa --since today | grep -c "RRQ\|WRQ")
echo "Requests today: $TODAY_REQUESTS"

# Топ запрашиваемых файлов
echo -e "\nTop requested files:"
journalctl -u tftpd-hpa --since "7 days ago" | \
    grep "RRQ" | \
    awk '{print $NF}' | \
    sort | uniq -c | sort -rn | head -10

# Топ клиентов
echo -e "\nTop clients:"
journalctl -u tftpd-hpa --since "7 days ago" | \
    grep -oP '\d+\.\d+\.\d+\.\d+' | \
    sort | uniq -c | sort -rn | head -10

# Ошибки
echo -e "\nErrors:"
journalctl -u tftpd-hpa --since "7 days ago" | grep -i "error\|fail" | wc -l
EOF

sudo chmod +x /config/scripts/tftp-stats.sh

Устранение неполадок

1. TFTP-сервер не отвечает

Симптомы: Клиенты получают timeout при попытке подключения.

Проверка:

# Проверить статус службы
show service tftp-server

# Проверить порт
show system connections port 69

# Проверить firewall
show firewall

# Проверить директорию
ls -ld /config/tftp

Решение:

# Перезапустить TFTP
restart service tftp-server

# Проверить права на директорию
sudo chown -R tftp:tftp /config/tftp
sudo chmod -R 755 /config/tftp

# Для upload нужны права записи
sudo chmod 777 /config/tftp/uploads

# Проверить firewall (разрешить UDP 69)
set firewall name WAN_LOCAL rule 100 action accept
set firewall name WAN_LOCAL rule 100 protocol udp
set firewall name WAN_LOCAL rule 100 destination port 69

commit
save

Тестирование:

# С клиента
tftp -v 192.168.1.1 -c get test.txt

# Или с VyOS (установить tftp-client)
sudo apt-get update
sudo apt-get install tftp-hpa
tftp localhost -c get test.txt

2. Upload не работает

Симптомы: Чтение работает, но запись файлов не удается.

Проверка:

# Проверить, включен ли allow-upload
show configuration service tftp-server | grep allow-upload

# Проверить права на директорию
ls -ld /config/tftp

Решение:

# Включить upload
set service tftp-server allow-upload

commit
save

# Дать права записи
sudo chmod 777 /config/tftp

# Или создать отдельную upload директорию
sudo mkdir -p /config/tftp/uploads
sudo chmod 777 /config/tftp/uploads

3. PXE Boot не работает

Симптомы: Клиент получает DHCP, но PXE загрузка не начинается.

Проверка:

# Проверить DHCP опции
show configuration service dhcp-server

# Проверить файлы PXE
ls -l /config/tftp/pxe/pxelinux.0

# Проверить TFTP
show service tftp-server

Решение:

# Убедиться, что DHCP передает правильные опции
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option tftp-server-name 192.168.1.1
set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 option bootfile-name 'pxelinux.0'

commit
save

# Проверить наличие pxelinux.0
sudo ls -l /config/tftp/pxe/pxelinux.0

# Права должны быть читаемыми
sudo chmod 644 /config/tftp/pxe/pxelinux.0

# Проверить зависимости
sudo ls -l /config/tftp/pxe/{ldlinux.c32,vesamenu.c32}

Тестирование на клиенте:

  • Включить PXE в BIOS/UEFI
  • Проверить, получает ли клиент IP через DHCP
  • Проверить логи TFTP: show log | match tftp

4. Cisco не может сохранить конфигурацию на TFTP

Симптомы: Cisco устройство выдает “Error opening tftp…” при попытке copy.

Проверка:

# Проверить firewall (убедиться, что Cisco устройство может подключиться)
show firewall

# Проверить upload
show configuration service tftp-server | grep allow-upload

# Проверить права
ls -ld /config/tftp

Решение:

# 1. Включить upload
set service tftp-server allow-upload

# 2. Создать директорию для Cisco backup с правами записи
sudo mkdir -p /config/tftp/cisco/backups
sudo chmod 777 /config/tftp/cisco/backups

# 3. Firewall - разрешить с Cisco устройств
set firewall group network-group CISCO_DEVICES network 10.0.1.0/24

set firewall name CISCO_LOCAL rule 50 action accept
set firewall name CISCO_LOCAL rule 50 protocol udp
set firewall name CISCO_LOCAL rule 50 destination port 69
set firewall name CISCO_LOCAL rule 50 source group network-group CISCO_DEVICES

set firewall interface eth0 local name CISCO_LOCAL

commit
save

На Cisco устройстве:

# Указать полный путь с поддиректорией
Switch# copy running-config tftp://10.0.0.1/cisco/backups/switch01.cfg

5. IP-телефоны не загружают конфигурацию

Симптомы: Телефоны получают IP, но не применяют конфигурацию.

Проверка:

# Проверить DHCP option 66
show configuration service dhcp-server | grep tftp

# Проверить файлы конфигурации
ls -l /config/tftp/yealink/

# Логи TFTP
show log | match tftp | tail 50

Решение:

# 1. Убедиться, что DHCP передает TFTP server
set service dhcp-server shared-network-name VOICE subnet 192.168.10.0/24 option tftp-server-name 192.168.10.1

commit
save

# 2. Проверить naming convention для Yealink
# Формат: MAC address без разделителей + .cfg
# Пример: 001565123456.cfg для MAC 00:15:65:12:34:56

# Проверить формат имени файла
ls -l /config/tftp/yealink/*.cfg

# 3. Права на файлы
sudo chmod 644 /config/tftp/yealink/*.cfg
sudo chown tftp:tftp /config/tftp/yealink/*.cfg

# 4. Проверить общий конфигурационный файл
ls -l /config/tftp/yealink/y000000000000.cfg

На телефоне (через веб-интерфейс):

  • Settings > Auto Provision
  • Server URL: tftp://192.168.10.1
  • Нажать Auto Provision Now

6. Большие файлы не передаются

Симптомы: Файлы >32 МБ не передаются или обрываются.

Причина: Стандартный TFTP имеет ограничение 32 МБ.

Решение:

# 1. Использовать HTTP/FTP для больших файлов
set service https listen-address 192.168.1.1

# 2. Разместить файлы в веб-директории
sudo mkdir -p /var/www/html/firmware
sudo cp large-firmware.bin /var/www/html/firmware/

# 3. На клиенте использовать HTTP вместо TFTP
# Cisco:
Switch# copy http://192.168.1.1/firmware/large-firmware.bin flash:

# Mikrotik:
/tool fetch url=http://192.168.1.1/firmware/large-firmware.bin

# 4. Для PXE использовать HTTP boot (iPXE)
# Скачать iPXE
wget http://boot.ipxe.org/ipxe.pxe -O /config/tftp/pxe/ipxe.pxe

# В pxelinux.cfg/default добавить
LABEL ipxe
    KERNEL ipxe.pxe

Лучшие практики

  1. Безопасность доступа

    • Использовать TFTP только в изолированных management VLAN
    • Ограничивать доступ через firewall ACL
    • Отключать upload где не требуется
    • Не хранить конфиденциальные данные в TFTP
  2. Структура директорий

    • Создавать отдельные директории для типов устройств
    • Использовать понятные имена файлов
    • Хранить firmware отдельно от configs
    • Создавать timestamped backups
  3. Резервное копирование

    • Автоматизировать backup конфигураций устройств
    • Использовать ротацию и архивирование
    • Хранить архивы минимум 90 дней
    • Тестировать восстановление из backup
  4. Мониторинг

    • Мониторить доступность TFTP-сервера
    • Отслеживать дисковое пространство
    • Логировать все операции
    • Настроить алерты на сбои
  5. Интеграция с DHCP

    • Использовать DHCP option 66/67 для автоматизации
    • Указывать IP-адрес, а не hostname для TFTP server
    • Проверять consistency между DHCP и TFTP конфигурацией
  6. Производительность

    • Использовать SSD для TFTP директории при высокой нагрузке
    • Ограничивать размер TFTP директории
    • Регулярно удалять старые файлы
    • Мониторить сетевую пропускную способность
  7. Документация

    • Вести реестр устройств с MAC-адресами
    • Документировать naming conventions для файлов
    • Записывать версии firmware и даты обновления
    • Создать runbook для типовых операций
  8. Для больших файлов

    • Использовать HTTP/FTP вместо TFTP для файлов >32 МБ
    • Включить HTTP server на VyOS для firmware
    • Использовать iPXE для HTTP boot
  9. Автоматизация

    • Использовать скрипты для массовых операций
    • Автоматизировать генерацию конфигураций
    • Планировать регулярные задачи через task-scheduler
    • Использовать Ansible для управления
  10. Тестирование

    • Тестировать конфигурации на тестовых устройствах
    • Проверять backup перед применением в production
    • Иметь rollback план для firmware updates
    • Документировать проверенные конфигурации

Заключение

TFTP-сервер в VyOS предоставляет простой и эффективный способ централизованного управления конфигурациями и прошивками сетевого оборудования. Правильная конфигурация TFTP с автоматизацией backup, интеграцией с DHCP и надежным мониторингом значительно упрощает администрирование сетевой инфраструктуры и повышает надежность операций.