MikroTik CHR: статический IP, DHCP сервер, SNAT и маршрутизация через Proxmox

MikroTik CHR: статический IP, DHCP сервер и SNAT на Proxmox
Что получишь на выходе
Настроишь полноценную сеть на MikroTik CHR: статический IP вместо DHCP, дефолтный маршрут, DNS, DHCP сервер для LAN клиентов и SNAT для выхода в интернет. Клиенты за CHR будут получать адреса автоматически и ходить в интернет через роутер. Всё проверено на реальном стенде CHR 7.22.1 + Proxmox 9.1.4.

Архитектура стенда

В этой статье строим полноценную двухинтерфейсную схему. CHR получает второй сетевой интерфейс и становится настоящим шлюзом для LAN сети.

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#ffffff',
    'primaryTextColor': '#1e293b',
    'primaryBorderColor': '#94a3b8',
    'lineColor': '#64748b',
    'fontSize': '15px',
    'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
  },
  'flowchart': {'curve': 'linear', 'nodeSpacing': 50, 'rankSpacing': 50}
}}%%
flowchart TD
    A["Интернет"] --> B["Proxmox vmbr0\n192.168.168.0/24"]
    B --> C["CHR ether1\n192.168.168.29/24 - WAN"]
    C --> D["CHR ether2\n192.168.88.1/24 - LAN"]
    D --> E["vmbr1 - internal bridge"]
    E --> F["LXC Ubuntu\n192.168.88.254/24 - клиент"]
    style A fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#1e293b
    style B fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
    style C fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
    style D fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
    style E fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#1e293b
    style F fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d

Два интерфейса — стандартная схема для роутера. ether1 смотрит наружу в сеть Proxmox и дальше в интернет. ether2 смотрит внутрь — это LAN для клиентов. SNAT транслирует адреса клиентов в IP ether1 при выходе наружу.

Системные требования

Компонент Версия
Proxmox VE 9.1.4
MikroTik CHR 7.22.1 stable
Состояние CHR после статьи 2 — безопасность настроена
LXC шаблон ubuntu-24.04-standard_24.04-2_amd64

Часть 1: Подготовка Proxmox

Видео пошаговый скринкаст:

Шаг 1. Скачиваем шаблон Ubuntu для LXC

Нам понадобится LXC контейнер как клиент в LAN сети — чтобы проверить что DHCP и NAT работают на реальном трафике. Скачиваем шаблон заранее:


pveam update
pveam download local ubuntu-24.04-standard_24.04-2_amd64.tar.zst

Результат:


update successful
downloading http://download.proxmox.com/images/system/ubuntu-24.04-standard_24.04-2_amd64.tar.zst
calculating checksum of existing file...OK, got correct file already, no need to download

Шаг 2. Создаём внутренний bridge vmbr1

vmbr1 — это изолированная LAN сеть внутри Proxmox. Без физического интерфейса — только виртуальный bridge. Через него CHR и LXC контейнер будут общаться между собой.


cat >> /etc/network/interfaces << 'EOF'

auto vmbr1
iface vmbr1 inet static
    address 0.0.0.0
    bridge-ports none
    bridge-stp off
    bridge-fd 0
    bridge-vlan-aware no
EOF
ifup vmbr1
ip link show vmbr1

Результат:


162: vmbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether d6:79:5b:2b:1b:3b brd ff:ff:ff:ff:ff:ff

Bridge поднялся. address 0.0.0.0 — намеренно. Proxmox не получает IP в этой сети — она только для VM и контейнеров.

Шаг 3. Добавляем второй интерфейс в CHR VM


qm set 110 --net1 virtio,bridge=vmbr1
qm reboot 110
sleep 20
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 "/interface print"

Результат:


Flags: R - RUNNING
Columns: NAME, TYPE, ACTUAL-MTU, MAC-ADDRESS
#   NAME    TYPE      ACTUAL-MTU  MAC-ADDRESS
0 R ether1  ether           1500  BC:24:11:2B:B9:99
1 R ether2  ether           1500  BC:24:11:BD:08:E9
2 R lo      loopback       65536  00:00:00:00:00:00

CHR увидел новый интерфейс как ether2. Оба запущены.

Если появился ether3 вместо ether2
RouterOS запоминает MAC адреса интерфейсов. Если VM пересоздавалась или интерфейс добавлялся повторно — CHR назначит следующий номер. Исправляется переименованием: /interface set ether3 name=ether2

Часть 2: Настройка сети на CHR

Шаг 4. Статический IP на ether1

Роутер должен иметь постоянный адрес — DHCP для шлюза это плохая практика. Убираем DHCP клиент и сразу назначаем статику в одной SSH сессии.

Почему обе команды в одной сессии
Если сначала удалить DHCP клиент и только потом добавить статику — SSH отвалится сразу после удаления DHCP. CHR потеряет IP раньше чем получит статический. Точка с запятой между командами выполняет их в одной сессии без разрыва.

ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip dhcp-client remove [find interface=ether1]; /ip address add address=192.168.168.29/24 interface=ether1"

Проверяем:


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 "/ip address print"

Результат:


Columns: ADDRESS, NETWORK, INTERFACE, VRF
# ADDRESS            NETWORK        INTERFACE  VRF
0 192.168.168.29/24  192.168.168.0  ether1     main

Шаг 5. Дефолтный маршрут и DNS

После удаления DHCP клиента CHR потерял маршрут по умолчанию. Прописываем вручную:


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip route add dst-address=0.0.0.0/0 gateway=192.168.168.1"
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip dns set servers=8.8.8.8,8.8.4.4 allow-remote-requests=yes"

Проверяем маршруты:


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 "/ip route print"

Результат:


Flags: D - DYNAMIC; A - ACTIVE; c - CONNECT, s - STATIC
Columns: DST-ADDRESS, GATEWAY, ROUTING-TABLE, DISTANCE
#     DST-ADDRESS       GATEWAY        ROUTING-TABLE  DISTANCE
0  As 0.0.0.0/0         192.168.168.1  main                  1
   DAc 192.168.168.0/24  ether1        main                  0

Флаг As — Active Static. Маршрут активен и прописан руками. allow-remote-requests=yes на DNS — CHR будет отвечать на DNS запросы от клиентов в LAN.

Шаг 6. Проверяем связь CHR с интернетом

Прежде чем настраивать NAT для клиентов — убеждаемся что сам роутер ходит наружу:


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 "/ping 8.8.8.8 count=3"

Результат:


SEQ HOST     SIZE TTL TIME
  0 8.8.8.8   56 104 36ms586us
  1 8.8.8.8   56 104 36ms397us
  2 8.8.8.8   56 104 36ms516us
sent=3 received=3 packet-loss=0%

CHR видит интернет. Теперь настраиваем LAN.

Шаг 7. IP адрес на ether2

ether2 получает первый адрес подсети — он будет шлюзом для всех клиентов:


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip address add address=192.168.88.1/24 interface=ether2"
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip address print"

Результат:


Columns: ADDRESS, NETWORK, INTERFACE, VRF
# ADDRESS            NETWORK        INTERFACE  VRF
0 192.168.168.29/24  192.168.168.0  ether1     main
1 192.168.88.1/24    192.168.88.0   ether2     main

Часть 3: DHCP сервер для LAN

Шаг 8. Настраиваем DHCP сервер

Три шага: создаём пул адресов, описываем сеть, создаём сервер:


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip pool add name=lan-pool ranges=192.168.88.10-192.168.88.254"
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip dhcp-server network add address=192.168.88.0/24 gateway=192.168.88.1 dns-server=8.8.8.8,8.8.4.4"
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip dhcp-server add name=lan-dhcp interface=ether2 address-pool=lan-pool disabled=no"
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip dhcp-server print"

Результат:


Columns: NAME, INTERFACE, ADDRESS-POOL, LEASE-TIME
# NAME      INTERFACE  ADDRESS-POOL  LEASE-TIME
0 lan-dhcp  ether2     lan-pool      30m

DHCP сервер запущен на ether2. Пул от .10 до .254 — адреса .1 до .9 оставляем для статических назначений если понадобится.

Часть 4: SNAT и firewall

Шаг 9. Настраиваем SNAT

SNAT против masquerade — в чём разница. Masquerade определяет исходящий IP динамически на каждый пакет — удобно когда внешний IP меняется. SNAT использует фиксированный адрес — работает быстрее потому что не делает лишних вычислений. У нас статический IP на ether1 — берём SNAT.


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip firewall nat add chain=srcnat src-address=192.168.88.0/24 action=src-nat to-addresses=192.168.168.29 out-interface=ether1 comment=snat-lan"
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip firewall nat print"

Результат:


Flags: X - DISABLED, I - INVALID; D - DYNAMIC
0    ;;; snat-lan
     chain=srcnat action=src-nat to-addresses=192.168.168.29
     src-address=192.168.88.0/24 out-interface=ether1

Шаг 10. Разрешаем forward трафик

По умолчанию RouterOS не пропускает трафик между интерфейсами — нужны явные правила в chain forward. Добавляем два: разрешаем трафик из LAN наружу и разрешаем ответы обратно:


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip firewall filter add chain=forward src-address=192.168.88.0/24 action=accept comment=allow-lan-forward"
ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip firewall filter add chain=forward connection-state=established,related action=accept comment=allow-forward-established"

Финальный вид firewall filter:


Flags: X - DISABLED, I - INVALID; D - DYNAMIC
#    CHAIN    ACTION   COMMENT
0    input    accept   accept-established-related
1    input    accept   accept-icmp
2    input    accept   accept-ssh-mgmt
3    input    accept   accept-winbox-mgmt
4    input    drop     drop-all
5    input    add-src  detect-ssh-scan
6    input    add-src  blacklist-stage1
7    input    add-src  blacklist-stage2
8    input    add-src  blacklist-stage3
9    input    drop     drop-ssh-bruteforce
10   forward  accept   allow-lan-forward
11   forward  accept   allow-forward-established

Часть 5: Проверка на клиенте

Шаг 11. Создаём LXC контейнер

Ubuntu 24.04 как клиент в LAN сети. Подключаем на vmbr1, IP получает по DHCP:


CTID=$(pvesh get /cluster/nextid)
pct create $CTID local:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst \
  --hostname lan-client \
  --memory 256 \
  --rootfs local-lvm:2 \
  --net0 name=eth0,bridge=vmbr1,ip=dhcp \
  --password test1234 \
  --unprivileged 1 \
  --start 1
sleep 15
pct exec $CTID -- ip addr show eth0

Результат:


2: eth0@if166: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
    link/ether bc:24:11:c5:3c:5a brd ff:ff:ff:ff:ff:ff
    inet 192.168.88.254/24 metric 1024 brd 192.168.88.255 scope global dynamic eth0
       valid_lft 1786sec preferred_lft 1786sec

Клиент получил 192.168.88.254 из пула CHR. Адрес динамический — флаг dynamic.

Шаг 12. Проверяем DHCP lease на CHR


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/ip dhcp-server lease print"

Результат:


Flags: D - DYNAMIC
Columns: ADDRESS, MAC-ADDRESS, HOST-NAME, SERVER, STATUS, LAST-SEEN
#   ADDRESS         MAC-ADDRESS        HOST-NAME   SERVER    STATUS  LAST-SEEN
0 D 192.168.88.254  BC:24:11:C5:3C:5A  lan-client  lan-dhcp  bound   22s

CHR видит клиента — MAC адрес, hostname, статус bound. Lease активен.

Шаг 13. Проверяем интернет с клиента

Пингуем сначала IP — проверяем SNAT. Потом домен — проверяем DNS:


pct exec 111 -- ping -c 3 8.8.8.8
pct exec 111 -- ping -c 3 google.com

Результат:


PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=103 time=37.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=103 time=36.1 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=103 time=38.1 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, packet-loss=0%

PING google.com (74.125.131.102) 56(84) bytes of data.
64 bytes from lu-in-f102.1e100.net: icmp_seq=1 ttl=103 time=36.4 ms
64 bytes from lu-in-f102.1e100.net: icmp_seq=2 ttl=103 time=37.4 ms
64 bytes from lu-in-f102.1e100.net: icmp_seq=3 ttl=103 time=37.5 ms
--- google.com ping statistics ---
3 packets transmitted, 3 received, packet-loss=0%

SNAT работает — пакеты идут наружу. DNS резолвится — CHR отвечает на запросы клиентов. Потери нулевые.

Шаг 14. Финальный бэкап


ssh -o StrictHostKeyChecking=no -p 2222 -i /root/.ssh/mikrotik_key sys0dmin@192.168.168.29 \
  "/system backup save name=chr-nat-dhcp"

Таблица портов и интерфейсов

Интерфейс IP Сеть Назначение
ether1 192.168.168.29/24 192.168.168.0/24 WAN — выход в интернет
ether2 192.168.88.1/24 192.168.88.0/24 LAN — шлюз для клиентов
Параметр Значение
DHCP пул 192.168.88.10 — 192.168.88.254
Шлюз для клиентов 192.168.88.1
DNS для клиентов 8.8.8.8, 8.8.4.4
SNAT to-address 192.168.168.29
Дефолтный шлюз CHR 192.168.168.1

Troubleshooting

После удаления DHCP клиента SSH отвалился

Подключайся через консоль Proxmox и назначай статику вручную:


qm terminal 110

В консоли CHR:


/ip address add address=192.168.168.29/24 interface=ether1
/ip route add dst-address=0.0.0.0/0 gateway=192.168.168.1

LXC контейнер не получает IP по DHCP

Проверь что DHCP сервер запущен на правильном интерфейсе:


/ip dhcp-server print
/ip dhcp-server network print

Проверь что ether2 имеет IP:


/ip address print

Если ether2 без адреса — DHCP сервер не знает из какой подсети выдавать адреса.

Клиент получил IP но интернета нет

Проверяем по шагам. Сначала пинг шлюза:


pct exec 111 -- ping -c 3 192.168.88.1

Если не пингуется — проблема в bridge или интерфейсе ether2. Если пингуется — проверяем SNAT:


/ip firewall nat print

Проверяем правила forward:


/ip firewall filter print where chain=forward

Появился ether3 вместо ether2

RouterOS запомнил MAC от предыдущего интерфейса. Переименовываем:


/interface set ether3 name=ether2

Как проверить что SNAT работает

Смотрим счётчики пакетов на правиле — они должны расти при активном трафике:


/ip firewall nat print stats where comment=snat-lan

FAQ

Чем SNAT отличается от masquerade?

Masquerade — это частный случай SNAT где исходящий IP определяется автоматически по интерфейсу. Удобно когда IP меняется — например при динамическом WAN. SNAT требует указать конкретный адрес явно, зато работает быстрее — не нужно вычислять IP на каждый пакет. При статическом WAN IP всегда используй SNAT.

Почему пул начинается с .10 а не с .2?

Адреса .1-.9 оставляем для статических назначений — принтеры, камеры, серверы которым нужен постоянный IP. Так не придётся делать статические резервации в DHCP для каждого такого устройства.

Как назначить конкретный IP определённому клиенту?

Через статическую привязку по MAC в DHCP:


/ip dhcp-server lease add address=192.168.88.50 mac-address=BC:24:11:C5:3C:5A server=lan-dhcp

Как посмотреть кто сейчас в сети?


/ip dhcp-server lease print where status=bound

Как удалить vmbr1 если он больше не нужен?


ifdown vmbr1
sed -i '/^auto vmbr1/,/^$/d' /etc/network/interfaces

Что дальше

Стенд теперь полноценный — CHR маршрутизирует трафик между двумя сетями, раздаёт адреса по DHCP и транслирует их через SNAT при выходе в интернет. Это базовая схема которая используется в большинстве реальных установок.

Следующая статья цикла — настройка VPN на MikroTik CHR. Поднимем WireGuard туннель для безопасного удалённого доступа в LAN сеть.

Не заработало - разберёмся
Пиши в комментарии. Описывай: версию CHR и Proxmox, что именно делал, какую ошибку получил. Разберём.
Андрей Анатольевич
Author: Андрей Анатольевич

Руководитель ИТ / Кризис-менеджер 25 лет в IT: от инженера в МегаФоне до руководителя отдела. Знаю, как выглядит бардак: нестабильные сети, устаревшая инфраструктура, конфликты в команде, раздутые сроки. Помогаю бизнесу выходить из кризиса: навожу порядок в легаси, стабилизирую то, что разваливается, выстраиваю прогнозируемые процессы. Не раз возвращал к жизни ИТ-структуры — знаю цену хаосу. 📍 Ищу проект для полной реорганизации / стабилизации. 📬 Telegram: @over_dude ✉️ mail@it-apteka.com

Оставайтесь на связи

Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.

Подписаться на IT-Аптеку →

Мы ВКонтакте

IT-Аптека — советы, новости и помощь рядом.

Вступить в группу ВКонтакте →
Поделитесь:

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх