Как подключиться к Synology без белого ip через VPS

Всем привет!!!

В этой статье я приведу необходимые ссылки, команды и скрипты для настройки подключения к Synology NAS через интернет без белого IP адреса с помощью VPS сервера. В теории разобраться в этом сможет любой даже совсем не подготовленный человек.

В статье только ссылки и команды, основная инструкция в видео ролике на моих площадках



Когда стоит задача подключаться к своему NAS через интернет, то самый простой и оптимальный способ получить у провайдера белый общедоступный IP адрес. Как правило, провайдеры сейчас продают такой в виде статического IP адреса. Это самый простой и надежный способ получить доступ к серверу через интернет. К такому адресу можно привязать как Synology QuickConnect, DDNS, так и любое купленное доменное имя. Например, купить доменно имя со скидкой 5% можно на хостинге reg.ru по промо-коду 9B29-F41D-CD32-5243.

Иногда бывает, что провайдеры не продают белые IP адреса или просят за это очень много денег, поэтому решать задачу с доступом придется через VPS сервер, благо их сейчас много.

Хостинг для VPS под эту задачу из статьи я рекомендую firstbyte.ru, т.к. там есть интересный тариф всего за 75 рублей в месяц в Российской локации. Если нужен за пределами РФ, то можно рассмотреть Аеза. Лучше выбирать локацию исходя из вашего проживания. Согласитесь не логично подключаться к вашему серверу в РФ из РФ через Амстердам.

firstbyte.ru

Схема организации доступа к Synology будет выглядеть таким образом: Т.к. у нас нет белого IP адреса, то нужно поднять приватный туннель (VPN) до сервера VPS с белым IP. Затем на сервере сделать NAT и проброс нужных портов по туннелю до нашего Synology. Пользователи будут подключаться к белому IP адресу на VPS сервер (например использую DDNS или свой домен) и попадать на Synology NAS.

В этой схеме есть недостаток. Когда вы будете использовать Synology QuickConnect, то проблем нет, а если DDNS или свой домен, то весь трафик будет лететь на VPS, да же если вы находитесь в одной локальной сети с Synology. Решение этой проблемы описано тут: Как решить проблему Hairpin NAT?

Между Synology и VPS я предлагаю использовать протокол OpenVPN. Почему OpenVPN? Это оптимальное сочетание безопасности, надежности и совместимости. Он идеально подходит для этих задач: универсальный (работает на ПК и телефонах, если понадобится), достаточно простой в настройке (особенно с помощью мастера в DSM) и, что самое главное, надежный и безопасный.

В общем купили VPS сервер и начинаем настраивать.

Необходимые команды для VPS на базе Ubuntu сервер

Обновление пакетов и перезагрузка

sudo apt update
sudo apt upgrade
sudo apt install nano
sudo reboot

Установка OpenVPN сервера и настройка первого клиента

Страница скрипта на GitHUB

curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
chmod +x openvpn-install.sh
sudo ./openvpn-install.sh

Просмотр файла клиента для сохранения его на ПК

cat /home/sadmin/имя-клиента.ovpn

Посмотреть все интерфейсы на VPS

ip address show

Как и в случаи с белым IP на роутере, на VPS так же нужно пробросить порты. Я долго думал как это сделать по проще и ничего лучше не придумал, как попросить ИИ DeepSeek сделать скрипт для проброса портов, а ниже будет его описание и применение:

🛠 Что нужно установить на VPS:

  1. Установить iptables-persistent (для сохранения правил после перезагрузки):
sudo apt update
sudo apt install iptables-persistent
  1. Установить скрипт:
sudo nano /usr/local/bin/synology-port-forward.sh

(вставить содержимое финального скрипта)

Не забудьте заменить основной внешний интерфейс ens3 на свой, а так же номер порта 1194, если вы используете не стандартный

#!/bin/bash

# Конфигурация
IPTABLES="/sbin/iptables"
EXTERNAL_IFACE="ens3"          # Основной внешний интерфейс
VPN_IFACE="tun0"                # VPN интерфейс
SYNOLOGY_VPN_IP="10.8.0.2"      # VPN IP адрес Synology
VPN_NETWORK="10.8.0.0/24"       # VPN сеть
VPN_PORT="1194"                 # VPN порт

# Цепочка iptables для управления пробросом
CHAIN="SYNOLOGY_PORTS"

# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Функция для инициализации цепочки
init_chain() {
    # Создаем цепочку в filter таблице если не существует
    if ! $IPTABLES -L $CHAIN >/dev/null 2>&1; then
        $IPTABLES -N $CHAIN
        $IPTABLES -A FORWARD -i $EXTERNAL_IFACE -o tun+ -j $CHAIN
        echo -e "${GREEN}Создана цепочка $CHAIN${NC}"
    fi
}

# Функция для проверки и исправления дубликатов MASQUERADE
fix_masquerade_duplicates() {
    echo -e "${BLUE}=== Проверка правил MASQUERADE ===${NC}"
    
    # Получаем все правила MASQUERADE для VPN сети
    local masq_rules=($($IPTABLES -t nat -n -L POSTROUTING --line-numbers | grep "MASQUERADE.*$VPN_NETWORK" | awk '{print $1}' | sort -rn))
    
    # Если правил больше одного, удаляем дубликаты
    if [[ ${#masq_rules[@]} -gt 1 ]]; then
        echo -e "${YELLOW}Найдено ${#masq_rules[@]} правил MASQUERADE - удаляем дубликаты...${NC}"
        
        # Оставляем только первое правило, удаляем остальные
        for ((i=1; i<${#masq_rules[@]}; i++)); do
            $IPTABLES -t nat -D POSTROUTING ${masq_rules[$i]}
            echo -e "${YELLOW}Удалено дублирующее правило MASQUERADE #${masq_rules[$i]}${NC}"
        done
        echo -e "${GREEN}Оставлено одно правило MASQUERADE${NC}"
    elif [[ ${#masq_rules[@]} -eq 1 ]]; then
        echo -e "${GREEN}Правило MASQUERADE в порядке${NC}"
    else
        echo -e "${YELLOW}Правило MASQUERADE не найдено${NC}"
    fi
}

# Функция для проверки существования правила (работает с nf_tables)
check_port_exists() {
    local port=$1
    local protocol=$2
    
    # Используем iptables-save для надежной проверки с nf_tables
    if iptables-save -t nat | grep -q "PREROUTING.*-i $EXTERNAL_IFACE.*-p $protocol.*--dport $port.*DNAT.*$SYNOLOGY_VPN_IP:$port"; then
        return 0  # Правило существует
    else
        return 1  # Правило не существует
    fi
}

# Функция для добавления проброса порта
add_port() {
    local port=$1
    local protocol=${2:-tcp}
    
    # Проверка аргументов
    if [[ -z "$port" ]]; then
        echo -e "${RED}Ошибка: укажите номер порта${NC}"
        exit 1
    fi
    
    if [[ ! "$port" =~ ^[0-9]+$ ]] || [[ "$port" -lt 1 ]] || [[ "$port" -gt 65535 ]]; then
        echo -e "${RED}Ошибка: некорректный номер порта${NC}"
        exit 1
    fi
    
    protocol=$(echo "$protocol" | tr '[:upper:]' '[:lower:]')
    if [[ "$protocol" != "tcp" && "$protocol" != "udp" ]]; then
        echo -e "${RED}Ошибка: протокол должен быть tcp или udp${NC}"
        exit 1
    fi
    
    # Проверяем, существует ли уже правило PREROUTING
    if check_port_exists "$port" "$protocol"; then
        echo -e "${YELLOW}Порт $port/$protocol уже проброшен на $SYNOLOGY_VPN_IP${NC}"
        return
    fi
    
    # Добавляем правило DNAT в таблицу nat
    $IPTABLES -t nat -A PREROUTING -i $EXTERNAL_IFACE -p $protocol --dport $port -j DNAT --to-destination $SYNOLOGY_VPN_IP:$port
    
    # Добавляем правило ACCEPT в нашу цепочку
    $IPTABLES -A $CHAIN -i $EXTERNAL_IFACE -p $protocol --dport $port -j ACCEPT
    
    echo -e "${GREEN}Порт $port/$protocol проброшен на $SYNOLOGY_VPN_IP${NC}"
}

# Функция для удаления проброса порта
del_port() {
    local port=$1
    local protocol=${2:-tcp}
    
    # Проверка аргументов
    if [[ -z "$port" ]]; then
        echo -e "${RED}Ошибка: укажите номер порта${NC}"
        exit 1
    fi
    
    protocol=$(echo "$protocol" | tr '[:upper:]' '[:lower:]')
    
    # Удаляем ВСЕ правила для данного порта (так как могут быть дубли)
    local nat_rules=($($IPTABLES -t nat -n -L PREROUTING --line-numbers | grep -E "dpt:$port(\s|$)" | grep -i "$protocol" | grep "$SYNOLOGY_VPN_IP" | awk '{print $1}' | sort -rn))
    
    for rule_num in "${nat_rules[@]}"; do
        $IPTABLES -t nat -D PREROUTING $rule_num
        echo -e "${YELLOW}Удалено правило NAT #$rule_num для порта $port${NC}"
    done
    
    # Удаляем ВСЕ правила из нашей цепочки
    local filter_rules=($($IPTABLES -n -L $CHAIN --line-numbers | grep -E "dpt:$port(\s|$)" | grep -i "$protocol" | awk '{print $1}' | sort -rn))
    
    for rule_num in "${filter_rules[@]}"; do
        $IPTABLES -D $CHAIN $rule_num
        echo -e "${YELLOW}Удалено правило FILTER #$rule_num для порта $port${NC}"
    done
    
    if [[ ${#nat_rules[@]} -gt 0 || ${#filter_rules[@]} -gt 0 ]]; then
        echo -e "${GREEN}Все правила для порта $port/$protocol удалены${NC}"
    else
        echo -e "${YELLOW}Порт $port/$protocol не найден в правилах${NC}"
    fi
}

# Функция для очистки дубликатов
clean_duplicates() {
    echo -e "${BLUE}=== Очистка дублирующих правил ===${NC}"
    
    # Чистим дубликаты MASQUERADE
    fix_masquerade_duplicates
    
    # Чистим дубликаты портов
    local ports=($(iptables-save -t nat | grep "PREROUTING.*DNAT.*$SYNOLOGY_VPN_IP" | grep -oP 'dport \K[0-9]+' | sort -u))
    
    for port in "${ports[@]}"; do
        # Считаем количество правил для каждого порта
        local count=$(iptables-save -t nat | grep -c "PREROUTING.*dport $port.*DNAT.*$SYNOLOGY_VPN_IP")
        if [[ $count -gt 1 ]]; then
            echo -e "${YELLOW}Найдено $count правил для порта $port - очищаем дубли...${NC}"
            # Оставляем только первое правило, удаляем остальные
            local rules=($($IPTABLES -t nat -n -L PREROUTING --line-numbers | grep -E "dpt:$port(\s|$)" | grep "$SYNOLOGY_VPN_IP" | awk '{print $1}' | tail -n +2 | sort -rn))
            for rule_num in "${rules[@]}"; do
                $IPTABLES -t nat -D PREROUTING $rule_num
            done
        fi
    done
    
    # Чистим дубликаты в цепочке FORWARD
    echo -e "${YELLOW}Проверяем дубликаты в цепочке FORWARD...${NC}"
    local forward_rules=($($IPTABLES -n -L FORWARD --line-numbers | grep -E "($VPN_IFACE|$EXTERNAL_IFACE)" | awk '{print $1}' | sort -rn | uniq -d))
    for rule_num in "${forward_rules[@]}"; do
        $IPTABLES -D FORWARD $rule_num
        echo -e "${YELLOW}Удалено дублирующее правило FORWARD #$rule_num${NC}"
    done
    
    # Чистим дубликаты в цепочке INPUT
    echo -e "${YELLOW}Проверяем дубликаты в цепочке INPUT...${NC}"
    local input_rules=($($IPTABLES -n -L INPUT --line-numbers | grep -E "($VPN_IFACE|$VPN_PORT)" | awk '{print $1}' | sort -rn | uniq -d))
    for rule_num in "${input_rules[@]}"; do
        $IPTABLES -D INPUT $rule_num
        echo -e "${YELLOW}Удалено дублирующее правило INPUT #$rule_num${NC}"
    done
    
    echo -e "${GREEN}Очистка дубликатов завершена${NC}"
}

# Функция для показа всех проброшенных портов
show_ports() {
    echo -e "${BLUE}=== Проброшенные порты на Synology ($SYNOLOGY_VPN_IP) ===${NC}"
    
    local nat_rules=$(iptables-save -t nat | grep "PREROUTING.*DNAT.*$SYNOLOGY_VPN_IP")
    
    if [[ -z "$nat_rules" ]]; then
        echo -e "${YELLOW}Нет проброшенных портов${NC}"
        return
    fi
    
    echo -e "${GREEN}Правила NAT (PREROUTING):${NC}"
    iptables-save -t nat | grep "PREROUTING.*DNAT.*$SYNOLOGY_VPN_IP"
    
    echo -e "\n${GREEN}Правила FILTER ($CHAIN):${NC}"
    $IPTABLES -n -L $CHAIN
    
    # Показываем правила MASQUERADE
    echo -e "\n${GREEN}Правила MASQUERADE:${NC}"
    $IPTABLES -t nat -n -L POSTROUTING | grep "MASQUERADE"
    
    echo -e "\n${GREEN}Сводка:${NC}"
    echo -e "Порт\tПротокол\tНазначение\tПравил"
    echo -e "----\t--------\t----------\t------"
    
    iptables-save -t nat | grep "PREROUTING.*DNAT.*$SYNOLOGY_VPN_IP" | while read line; do
        local port=$(echo "$line" | grep -oP 'dport \K[0-9]+')
        local protocol="tcp"
        if echo "$line" | grep -q "udp"; then
            protocol="udp"
        fi
        local count=$(iptables-save -t nat | grep -c "PREROUTING.*dport $port.*DNAT.*$SYNOLOGY_VPN_IP")
        echo -e "$port\t$protocol\t\t$SYNOLOGY_VPN_IP\t$count"
    done
}

# Функция для сохранения правил (с очисткой дубликатов)
save_rules() {
    # Сначала чистим дубликаты
    clean_duplicates
    
    if command -v iptables-save >/dev/null 2>&1; then
        iptables-save > /etc/iptables/rules.v4
        echo -e "${GREEN}Правила сохранены в /etc/iptables/rules.v4${NC}"
        
        # Проверяем наличие iptables-persistent
        if ! systemctl is-enabled netfilter-persistent >/dev/null 2>&1; then
            echo -e "${YELLOW}Для автозагрузки правил установите:${NC}"
            echo -e "${YELLOW}sudo apt install iptables-persistent${NC}"
        fi
    else
        echo -e "${YELLOW}iptables-save не найден${NC}"
    fi
}

# Функция помощи
show_help() {
    echo -e "${BLUE}Использование: $0 [команда] [параметры]${NC}"
    echo
    echo "Команды:"
    echo "  add PORT [PROTOCOL]    - Добавить проброс порта (по умолчанию tcp)"
    echo "  del PORT [PROTOCOL]    - Удалить проброс порта"
    echo "  show                   - Показать все проброшенные порты"
    echo "  clean                  - Очистить дублирующие правила"
    echo "  save                   - Сохранить правила iptables (с очисткой дубликатов)"
    echo "  help                   - Показать эту справку"
    echo
    echo "Примеры:"
    echo "  $0 add 5000           - Пробросить TCP порт 5000"
    echo "  $0 add 1194 udp       - Пробросить UDP порт 1194"
    echo "  $0 del 5000           - Удалить проброс порта 5000"
    echo "  $0 clean              - Очистить дубликаты правил"
    echo "  $0 show               - Показать все порты"
}

# Главная функция
main() {
    # Проверка прав root
    if [[ $EUID -ne 0 ]]; then
        echo -e "${RED}Этот скрипт должен запускаться с правами root${NC}"
        exit 1
    fi
    
    # Инициализация цепочки
    init_chain
    
    case "$1" in
        "add")
            add_port "$2" "$3"
            ;;
        "del")
            del_port "$2" "$3"
            ;;
        "show")
            show_ports
            ;;
        "clean")
            clean_duplicates
            ;;
        "save")
            save_rules
            ;;
        "help"|"")
            show_help
            ;;
        *)
            echo -e "${RED}Неизвестная команда: $1${NC}"
            show_help
            exit 1
            ;;
    esac
}

# Запуск скрипта
main "$@"

Сделайте скрипт исполняемым:

sudo chmod +x /usr/local/bin/synology-port-forward.sh

📋 Скрипт: synology-port-forward.sh

🎯 Что умеет скрипт:

  • add PORT [PROTOCOL] — пробрасывает порт на Synology через VPN
  • del PORT [PROTOCOL] — удаляет проброс порта
  • show — показывает все проброшенные порты
  • clean — очищает дубликаты правил (MASQUERADE, FORWARD, INPUT)
  • save — сохраняет правила с автоматической очисткой дубликатов

⚙️ Важные настройки в скрипте:

EXTERNAL_IFACE="ens3"          # Основной внешний интерфейс
SYNOLOGY_VPN_IP="10.8.0.2" # VPN IP адрес вашего Synology

🚀 Примеры использования:

Проброс портов:

# Проброс TCP портов
sudo synology-port-forward.sh add 5000 # HTTP DSM
sudo synology-port-forward.sh add 5001 # HTTPS DSM
sudo synology-port-forward.sh add 6690 # Synology Drive Client ПК

# Проброс UDP порта
sudo synology-port-forward.sh add 500 udp # UDP порт

# Показать все порты
sudo synology-port-forward.sh show

# Сохранить правила
sudo synology-port-forward.sh save

Управление:

# Удалить порт
sudo synology-port-forward.sh del 5000

# Очистить дубликаты
sudo synology-port-forward.sh clean

# Получить справку
sudo synology-port-forward.sh help

🔧 Что делает скрипт технически:

  1. DNAT правила — перенаправляет трафик с внешнего IP на VPN IP Synology
  2. ACCEPT правила — разрешает трафик в цепочке FORWARD
  3. Автоматическая очистка — предотвращает дублирование правил
  4. Совместимость с nf_tables — работает с современными версиями iptables

📁 Файлы конфигурации:

  • /etc/iptables/rules.v4 — сохраняемые правила iptables
  • /usr/local/bin/synology-port-forward.sh — сам скрипт

🔄 Автозагрузка правил:

После установки iptables-persistent правила автоматически загружаются при boot.

✅ Проверка работы:

# Проверить текущие правила
sudo iptables-save -t nat
sudo iptables-save -t filter

# Проверить доступность портов
nmap -p 5000,5001,6690 YOUR_VPS_IP

Скрипт готов к использованию! Он обеспечивает безопасный проброс портов только через VPN соединение, защищая ваш Synology от прямого доступа из интернета. 🛡️

Теперь вы знаете как подключиться к Synology без белого ip через VPS

Рекомендую так же настроить защиту от подбора пароле одной командой:

sudo apt update && sudo apt install fail2ban -y && \
sudo tee /etc/fail2ban/jail.local > /dev/null << 'EOF'
[sshd]
enabled = true
maxretry = 3
bantime = 86400
findtime = 3600
EOF
sudo systemctl restart fail2ban && \
sudo fail2ban-client status sshd

Настройка Fail2ban recidive (рецидивист) — это специальный jail, который отслеживает повторные блокировки:

sudo tee -a /etc/fail2ban/jail.local > /dev/null << 'EOF'

[recidive]
enabled = true
bantime = 2592000
findtime = 604800
maxretry = 3
logpath = /var/log/fail2ban.log
EOF

sudo systemctl restart fail2ban && \
sudo fail2ban-client status recidive

Как это работает:

  • ✅ findtime = 604800 — отслеживает 7 дней (604800 секунд)
  • ✅ maxretry = 3 — после 3 блокировок в течение этого периода
  • ✅ bantime = 2592000 — блокирует на 30 дней (2592000 секунд)

Не забывайте настроить защиту от внешних угроз

Подписаться
Уведомить о
guest
16 Комментарий
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии