Соединяем две локальные сети через VPS с помощью VPN Wireguard

Задача была следующей: соединить между собой две сети, не имеющие «белого» IP-адреса. Одна сеть выходит в интернет через роутер Mikrotik, вторая сеть выходит через Zyxel Speedster. В качестве связующего звена было решено использовать VPS с установленным Wireguard VPN.

Получилась такая схема:

LAN0 (192.168.0.0/24) -> Mikrotik -> Internet -> VPS <- Internet <- Zyxel <- LAN1 (192.168.2.0/24)

1. Настраиваем Wireguard на VPS

Подробно останавливаться на установке Wireguard, наверное, большого смысла нет, инструкций по установке более чем достаточно. Покажу лишь конфиг:

root@vpn-vps:~# cat /etc/wireguard/wg0.conf
[Interface]
Address = 10.36.36.1/24,fd42:24:24::1/64
ListenPort = 54073
PrivateKey = (hidden)
PostUp = iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;
PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;

### Client router-mikrotik
[Peer]
PublicKey = <...skipped...>
PresharedKey = <...skipped...>
AllowedIPs = 10.36.36.2,192.168.0.0/24,fd42:24:24::2/128

### Client router-zyxel
[Peer]
PublicKey = <...skipped...>
PresharedKey = <...skipped...>
AllowedIPs = 10.36.36.3,192.168.2.0/24,fd42:24:24::3/128

И интерфейс:

root@vpn-vps:~# wg show wg0
interface: wg0
  public key: <...skipped...>
  private key: (hidden)
  listening port: 54073

peer: <...skipped...>
  preshared key: (hidden)
  endpoint: xx.xx.xx.xx:21371
  allowed ips: 10.36.36.2/32, 192.168.0.0/24, fd42:24:24::2/128
  latest handshake: 1 minute, 6 seconds ago
  transfer: 231.14 MiB received, 11.05 GiB sent

peer: <...skipped...>
  preshared key: (hidden)
  endpoint: yy.yy.yy.yy:56043
  allowed ips: 10.36.36.3/32, 192.168.2.0/24, fd42:24:24::3/128
  latest handshake: 1 minute, 5 seconds ago
  transfer: 11.02 GiB received, 230.29 MiB sent

На что здесь нужно обратить внимание? На разрешённые подсети в параметрах allowed-ips.

Также не лишним будет проверить, что в /etc/sysctl.conf раскомментирован форвардинг пакетов:

net.ipv4.ip_forward=1

2. Настраиваем Mikrotik

В Mikrotik RouterOS Wireguard поддерживается «из коробки». Для настройки нужно зайти в раздел Wireguard, добавить новое соединение:


Далее добавляем peer:


И правило в маршруты для доступа в подсеть LAN1:


После этого роутер Microtik будет соединяться с VPN сервером, если мы захотим из сети 192.168.0.0/24 пойти на адреса сети 192.168.2.0/24

3. Настраиваем Zyxel Speedster

Добавим соединение с Wireguard


и настроим peer. В отличие от Mikrotik’а в Zyxel это делается в одном месте:


После этого настраиваем маршрутизацию:


И в настройках файрвола разрешаем доступ из сети LAN0 и VPN:


На этом настройка закончена.

Теперь из сети 192.168.0.0/24 можно заходить на устройства в сети 192.168.2.0/24, также как и наоборот. При этом в интернет из этих сетей клиенты идут через основной выход, а не через VPN.

Итого — мы имеем доступ из двух этих сетей друг к другу. С момента настройки и до написания записи прошло около месяца, надеюсь, я ничего не забыл по пути. Но, как обычно, если есть вопрос, можно его написать в комментариях. Всем спасибо. 🙂

Обновление прошивок с помощью fwupdmgr

Как и всё остальное, обновить прошивки железа в Debian Linux довольно просто. В этом нам поможет утилита fwupdmgr. Рассмотрим процесс пошагово.

Для начала, добавим в источник репозиториев новый компонент non-free-firmware. Именно в него переехали все «несвободные» прошивки:

deb http://ftp.ru.debian.org/debian/ testing main contrib non-free non-free-firmware

Затем подтянем обновления:

root@laptop:~# fwupdmgr get-updates
Devices with no available firmware updates: 
 • SSD 860 EVO M.2 500GB
 • UEFI dbx
────────────────────────────────────────────────
Devices that have been updated successfully:
 • System Firmware (1.29.4 → 1.33.3)
 • UEFI dbx (13 → 217)
Uploading firmware reports helps hardware vendors to quickly identify failing and successful updates on real devices.
Upload report now? (Requires internet connection) [Y|n]: N

А теперь накатим полученные обновления:

root@laptop:~# fwupdmgr update
Devices with no available firmware updates: 
 • SSD 860 EVO M.2 500GB
 • UEFI dbx
╔══════════════════════════════════════════════════════════════════════════════╗
║ Upgrade System Firmware from 1.33.3 to 1.34.3?                               ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Some new functionality has also been added:                                  ║
║                                                                              ║
║ Firmware updates to address security vulnerabilities including.              ║
║                                                                              ║
║ Latitude E5470 must remain plugged into a power source for the duration of   ║
║ the update to avoid damage.                                                  ║
╚══════════════════════════════════════════════════════════════════════════════╝
Perform operation? [Y|n]: Y
Waiting…                 [***************************************]
Successfully installed firmware
Do not turn off your computer or remove the AC adapter while the update is in progress.
╔══════════════════════════════════════════════════════════════════════════════╗
║ Upgrade TPM 1.2 from 5.81.0.0 to 5.81.2.1?                                   ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Initial release                                                              ║
║                                                                              ║
║ TPM 1.2 and all connected devices may not be usable while updating.          ║
╚══════════════════════════════════════════════════════════════════════════════╝
Perform operation? [Y|n]: Y
Updating TPM 1.2…        [ -                                     ]
Waiting…                 [***************************************]
Successfully installed firmware
Do not turn off your computer or remove the AC adapter while the update is in progress.
An update requires a reboot to complete. Restart now? [y|N]: N

Автоматически рестартовать ноутбук я не стал, сделал это вручную, закрыв все работающие программы.

После перезагрузки процесс обновления продолжится:

Обновление прошивки с помощью fwupmgr

И на этом всё. 🙂

Установка и настройка knockd

Для чего нужен knockd? Для реализации метода port knocking — «стука» в фаервол для открытия определённых портов. Это обычное применение данной программы, но этим оно не ограничивается и можно придумать более экзотическое её использование.

Для начала установовим пакеты knockd и iptables-persistent. Последний нужен для постоянного хранения правил фаервола в случае перезагрузки сервера.

apt-get install knockd iptables-persistent

Минимальный набор правил для iptables при это будет выглядеть так:

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X

iptables -P INPUT DROP

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -i eth0 -j DROP

В данном случае eth0 — это название сетевого интерфейса. На свежих системах название будет другое. Например enp3s0 или подобное. 😉

После того, как правила изменены, нужно их сохранить. Делается это командой

iptables-save > /etc/iptables/rules.v4

Теперь можно перейти непосредственно к настройке knockd. Для примера рассмотрим использование port knocking для открытия порта ssh сервиса.

Разрешим запуск knockd в режиме демон. Для этого отредактируем файл /etc/default/knockd и поменяем в нём строку на следующую:

START_KNOCKD=1

Если у вас, как и у меня, используется systemd, приведём файл /lib/systemd/system/knockd.service, который выглядит вот так:

[Unit]
Description=Port-Knock Daemon
After=network.target
Documentation=man:knockd(1)

[Service]
EnvironmentFile=-/etc/default/knockd
ExecStart=/usr/sbin/knockd $KNOCKD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
SuccessExitStatus=0 2 15
ProtectSystem=full
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN

к следующему виду:

[Unit]
Description=Port-Knock Daemon
After=network.target
Requires=network.target
Documentation=man:knockd(1)

[Service]
EnvironmentFile=-/etc/default/knockd
ExecStartPre=/bin/sleep 1
ExecStart=/usr/sbin/knockd $KNOCKD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
SuccessExitStatus=0 2 15
ProtectSystem=full
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN

[Install]
WantedBy=multi-user.target

После редактирования нужно, чтобы systemd узнал об изменении в конфигурационных файлах. Для этого выполним:

systemctl daemon-reload

Теперь можно разрешить запускать knockd как сервис:

systemctl enable knockd.service

И осталось последнее — отредактировать конфигурационный файл knockd /etc/knockd.conf. Так он выглядит при установке:

[options]
        UseSyslog

[openSSH]
        sequence    = 7000,8000,9000
        seq_timeout = 5
        command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

[closeSSH]
        sequence    = 9000,8000,7000
        seq_timeout = 5
        command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

Но я предпочитаю не убиать доступ к открытым портам вручную, а использую встроенную возможность «закрытия». Конфигурационный файл при этом выглядит так:

[options]
    UseSyslog
    Interface = eth0

[opencloseSSH]
    sequence      = 7000,8000,9000
    seq_timeout   = 10
    cmd_timeout   = 60
    tcpflags      = syn
    start_command = /sbin/iptables -I INPUT 3 -s %IP% -p tcp --dport 22 -j ACCEPT
    stop_command  = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

В sequence можно указать любые свободные порты, которые вам нравятся. Через 60 секунд после выполнения команды, указанной в start_command, выполнится команда stop_command, которая уберёт правило, открывающее доступ к 22 порту.

Запустим knockd сервис:

systemctl start knockd.service

И проверим, что он работает корректно:

root@tests:~# systemctl status knockd.service 
● knockd.service - Port-Knock Daemon
     Loaded: loaded (/lib/systemd/system/knockd.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2023-02-04 08:41:19 MSK; 53s ago
       Docs: man:knockd(1)
    Process: 1762844 ExecStartPre=/bin/sleep 1 (code=exited, status=0/SUCCESS)
   Main PID: 1762845 (knockd)
      Tasks: 1 (limit: 9507)
     Memory: 768.0K
        CPU: 25ms
     CGroup: /system.slice/knockd.service
             └─1762845 /usr/sbin/knockd

Feb 04 08:41:18 tests systemd[1]: Starting Port-Knock Daemon...
Feb 04 08:41:19 tests systemd[1]: Started Port-Knock Daemon.
Feb 04 08:41:19 tests knockd[1762845]: starting up, listening on eth0

Теперь проверим, что сервис действительно работает. Для этого «постучим» на сервер снаружи:

knock  7000:tcp 8000:tcp 9008:tcp

На сервере в /var/log/syslog мы увидим следующее:

Feb  4 08:43:43 tests knockd: xx.xx.xx.xx: opencloseSSH: Stage 1
Feb  4 08:43:43 tests knockd: xx.xx.xx.xx: opencloseSSH: Stage 2
Feb  4 08:43:43 tests knockd: xx.xx.xx.xx: opencloseSSH: Stage 3
Feb  4 08:43:43 tests knockd: xx.xx.xx.xx: opencloseSSH: OPEN SESAME
Feb  4 08:43:43 tests knockd: opencloseSSH: running command: /sbin/iptables -I INPUT 3 -s xx.xx.xx.xx -p tcp --dport 22 -j ACCEPT

Это означает, что 22 порт открылся. Убедимся в этом, посмотрев список правил iptables:

iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  xx.xx.xx.xx          0.0.0.0/0            tcp dpt:22
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy DROP)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Продолжая наблюдать логи в /var/log/syslog, через 60 секунд мы увидим отработку команды stop_command, указанной в конфиге:

Feb  4 08:44:43 tests knockd: xx.xx.xx.xx: opencloseSSH: command timeout
Feb  4 08:44:43 tests knockd: opencloseSSH: running command: /sbin/iptables -D INPUT -s xx.xx.xx.xx -p tcp --dport 22 -j ACCEPT

Правило для открытия 22 порта удалилось. Проверям в iptables:

iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy DROP)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Так и есть. Всё работает отлично. 🙂

Теперь пару слов о том, как ещё можно использовать knockd. В start_command в /etc/knockd.conf можно необязательно указывать добавление/удаление правил iptables. Можно сделать, например, выключение сервера в экстренной ситуации, указав:

start_command = /sbin/shutdown -h now

Выключением можно не ограничиваться. В случае получения уведомления о взломе сервера, можно блокировать все соединения с внешним миром, удалить данные с диска, если её раскрытие критично. В общем, возможны любые действия, которые только можно придумать. 🙂

Как настроить DKIM и SPF в Postfix

Краткая инструкция по настройке DKIM/SPF для домена example.com. Нужно это для того, чтобы снизить вероятность попадания в спам писем, отправляемых с вашего сервера.

Установим opendkim и mailutils

apt-get update
apt-get install opendkim opendkim-tools mailutils

Теперь перейдём непосредственно к настройке. Для настройки SPF необходимо создать TXT-запись следующего вида:

Хост        Указатель                    TTL
@           v=spf1 ip4:server_ip ~all    3600

server_ip — IP-адрес вашего почтового сервера, который отправляет письма.
~all означает, что письмо, которое не прошло проверку, будет отклонено.

Теперь настроим DKIM

mkdir /etc/postfix/dkim/

Создаём ключи ключи для домена example.com:

opendkim-genkey -D /etc/postfix/dkim/ -d example.com -s mail

После выполнения последней команды в каталоге /etc/postfix/dkim/ появится пара ключей — публичный и приватный для домена example.com:

Установим права на приватный ключ:

chmod 600 /etc/postfix/dkim/example.com.private

Поменяем владельца каталога:

chown -R opendkim /etc/postfix/dkim/

В опции в файле /etc/opendkim.conf необходимо внести следующие правки:

Syslog yes
Mode sv
KeyTable file:/etc/postfix/dkim/keytable
SigningTable file:/etc/postfix/dkim/signingtable

Mode sv — режим подписи и проверка подписей
KeyTable — список ключей
SigningTable — соответствие доменов и подписывающих их ключей

В файле /etc/postfix/dkim/keytable указываем данные о приватных ключах для доменов в формате имя_ключа домен:селектор:/путь/до/ключа

mail._domainkey.example.com example.com:mail:/etc/postfix/dkim/example.com.private

В файле /etc/postfix/dkim/signingtable указываются домены, которые необходимо подписывать в формате домен имя_ключа:

example.com mail._domainkey.example.com

В /etc/default/opendkim необходимо указать сокет, на котором будет opendkim. Другие настройки можно закомментировать:

SOCKET="inet:8891@localhost"

Добавляем в /etc/postfix/main.cf:

milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Перезапускаем postfix и opendkim:

systemctl restart postfix
systemctl restart opendkim

Теперь осталось настроить DNS.

В панели управления доменом создаём TXT-запись следующего вида:

Запись                      Содержимое                               TTL
mail._domainkey             v=DKIM1; h=sha256; k=rsa; p=MII...QAB    3600

Содержимое строки p=MII…QAB берём из файла /etc/postfix/dkim/example.com.txt.

После обновления DNS, всё должно заработать.

Как проверить, что всё сделано правильно? Для проверки можно отправить тестовое сообщение на свой почтовый ящик с помощью утилиты mail:

"test message" | mail -aFrom:mail@example.com my_email@google.com

В заголовках полученного сообщения проверки SPF и DKIM должны выполниться успешно:

spf=pass
dkim=pass

Также проверить DKIM можно с помощью утилиты opendkim-testkey:

opendkim-testkey -d example.com -s mail -vvv -k /etc/opendkim/keys/mail.private

opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'mail._domainkey.example.com'
opendkim-testkey: key not secure
opendkim-testkey: key OK

Таким образом мы получаем настроенный DKIM, что позволяет письмам доходить до получателя, а не сразу улетать в спам. 🙂

Исправляем ошибку с сертификатами для сайта Сбербанка

Краткая инструкция, как вернуть безопасный доступ к сайту Сбербанка.

Несколько дней назад заходя на сайт Сбербанка (нынче Сбер) пользователи сторонних браузеров столкнулись с проблемой небезопасного соединения в браузерах Chrome, Firefox и прочих. Произошло это по причине того, что теперь сертификат Сбербанка подписан российским удостоверяющим центром, а в перечисленных браузерах его корневого сертификата нет. Для решения проблемы можно использовать Яндекс.Браузер, а можно добавить сертификаты в свой браузер.

Например, я пользуюсь браузером Brave. Его и будем «приводить в чувства». 🙂

1. Заходим на сайт Госуслуг — https://www.gosuslugi.ru/crt. Прокручиваем страницу чуть ниже, находим кнопки «Скачать корневой сертификат» и «Скачать выпускающий сертификат«. Жмём их и получаем два файла:

russian_trusted_root_ca.cer
russian_trusted_sub_ca.cer

2. Заходим в настройки Brave: Setting -> Privacy and security. Выбираем Manage certificates, вкладку Authorities и импортируем скачанные сертификаты.

3. Вы великолепны! У вас снова работает безопасное соединение с сайтом Сбера.

По аналогии решается проблема в других браузерах. Всем удачи и безопасного серфинга в интернете. 🙂