Скрипт фаервола IPTables для ipv4 и ipv6 с автозагрузкой в Linux (systemd)
Простой и надежный скрипт для загрузки правил фаервола IPTables в GNU Linux используя сценарий авто-запуска для демона инициализации systemd (новая замена для /sbin/init). Правила загружаются и работают как для протокола IPv4, так и для IPv6.
Содержание:
- Немного о systemd и IPv6
- IPTables и IPv6
- Отключение IPv6
- Скрипт брандмауэра с общим набором правил для IPv4 и IPv6
- Скрипт брандмауэра с раздельными наборами правил для IPv4 и IPv6
- Полезные инструменты для IPv4 и IPv6
- Заключение
Немного о systemd и IPv6
Раньше, в одной из статей по Linux, я уже описывал создание простого фаервола для защиты сервера и мониторинга количества "вредных" сетевых пакетов. Для авто-запуска скрипта мы размещали его в папке "/etc/init.d", а также добавляли в автостарт системных процессов используя команду "update-rc.d".
Время идет, технологии меняются и в некоторых дистрибутивах GNU Linux на смену старому демону инициализации /sbin/init пришел новый, более мощный - systemd. Кто-то встретил такое нововведение с недовольством, а кто-то поковырявшись оценил преимущества и новые мощные инструменты.
Также время наложило свой отпечаток и на адресное пространство протокола IPv4, которое уже считается исчерпанным, а внешние IPv4-адреса для арендованных VPS/VDS уже не раздают так просто по несколько штук в одни руки, как это было раньше.
Поскольку я работаю с системами на основе Debian/Ubuntu то мне пришлось познакомиться с новым systemd, а также учесть наличие внешних IPv6-адресов на интерфейсах моих серверов и рабочих станций. Сейчас многие провайдеры при аренде у них VPS/VDS серверов предоставляют один или два IPv4-адреса и целую подсеть адресов IPv6.
К примеру при аренде даже самого бюджетного VPS у Ramnode (15$ в год = 1,25$ в месяц) в придачу к адресу IPv4 вам выделят целую подсеть /64, в которой доступно всего-навсего 18,446,744,073,709,551,616 IPv6-адресов!
Любой из таких адресов можно прописать к внешнему сетевому интерфейсу (который смотрит в интернет) и смело получить по нему доступ к вашему серверу из любой точки мира по протоколу IPv6.
IPTables и IPv6
Многие кто арендовал себе VPS и настраивают базовую защиту на основе IPTables даже не подозревают что те правила, которые загружаются при помощи команды "iptables" действуют только для входящих-исходящих пакетов с протоколом IPv4, а трафик что приходит и уходит по протоколу IPv6 в таком случае вообще никак не фильтруется.
Давайте для примера рассмотрим небольшую историю: человек арендовал VPS в Германии, настроил на нем связку Apache+PHP+MySQL, ну и прикрутил еще MongoDB для хранения 100000+ однотипных документов, которые плодят его проекты.
Сервис баз данных MongoDB по умолчанию принимает соединения на портах 27017 и 28017 для всех интерфейсов на сервере. Админ это знал, лезть в настройки MongoDB он не хотел, поэтому добавил несколько правил для брандмауэра используя команду "iptables", которые заблокируют все входящие соединения что поступают с внешнего интерфейса (интернет), как исключения разрешил только порты 80 и 433 для подключения к веб-серверу Apache.
И казалось бы все сделано верно, беспокоиться нет причины...но не тут то было! После установки Linux из образа который предоставил провайдер, сервер получил два внешних адреса в интернете: один для протокола IPv4, а другой - для IPv6.
Невнимательный админ забыл о наличии второго адреса и о вообще "забил" на протокол IPv6 (казалось-бы кто им пользуется, он не популярный еще и т.п.). Как результат - сервер взломали, затерли документы и натворили других чудес.
Кто и как взломал сервер? - судя по последствиям после взлома сервер взломали скорее всего для забавы, получив доступ к MongoDB по портам 27017 и 28017, используя для этого внешний адрес сервера с протоколом IPv6.
Сервер с открытым портом был найден при помощи поискового сервиса Shodan, который сканирует целые подсети IPv4 и IPv6 адресов и собирает признаки интернет-железок, выявляет на них открытые порты, сигнатуры демонов и т.п. Все что нужно было сделать, так это подключиться к базе данных на сервере используя адрес IPv6, сетевые пакеты на котором не фильтровались вообще.
Что можно сделать чтобы подобное не повторилось:
- Отключить на сервере поддержку протокола IPv6, если в нем нет надобности;
- Настроить брандмауэр для блокировки нежелательных подключений как для IPv4, так и для IPv6.
При работе с брандмауэром IPTables правила для протокола IPv6 нужно загружать используя бинарник "ip6tables", а для протокола IPv4 - используем бинарный файл "iptables". Таким образом для защиты сервера по двум протоколам нужно загрузить два набора правил, которые для каждого из протоколов имеют свои цепочки и таблички.
Отключение IPv6
Если вы все же решили отключить поддержку протокола IPv6 на сервере под управлением Debian/Ubuntu-подобного GNU Linux, то сделать это можно в несколько простых шагов.
Откроем для редактирования файл с настройками sysctl - sysctl.conf:
nano /etc/sysctl.conf
Добавим в самый низ этого файла следующие строчки:
# IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
Заставим sysctl перечитать настройки из файла sysctl.conf:
sysctl -p
Желательно перезагрузить сервер и все перепроверить. Убедиться в отключенном IPv6 можно посмотрев нет ли адресов c данным протоколом в выводе команды:
ifconfig | grep inet6
Также можно проверить не загружены ли модули поддержки IPv6 в ядре:
lsmod | grep ipv6
В выводах приведенных двух команд не должны встречаться упоминания "inet6" и "ipv6", то есть вывод должен быть пуст.
Скрипт брандмауэра с общим набором правил для IPv4 и IPv6
Раньше для автоматической загрузки ранее сохраненных правил в IPTables я использовал пакет "iptables-persistent". В новой версии GNU Debian Linux (9.0 - Stretch) этот пакет уже исключен из репозитория. Теперь всю необходимую работу по организации авто-запуска какого-либо сервиса можно удобно реализовать с помощью systemd.
Для базовой защиты Linux-сервера или рабочей станции в сети интернет по двум протоколам (IPv4 и IPv6) я написал простой скрипт, который будет автоматически стартовать при загрузке системы используя собственный файл-описание для демона инициализации systemd. Набор правил для каждого из протоколов одинаковый и он определяет вот такую фильтрацию пакетов:
- Весь ЛОКАЛЬНЫЙ трафик (через виртуальный интерфейс lo0) - разрешен;
- Все ИСХОДЯЩИЕ пакеты - разрешены;
- ВХОДЯЩИЕ пакеты, которые относятся к уже установленным соединениям (established) - разрешены;
- Все остальные ВХОДЯЩИЕ пакеты - логируются и отбрасываются (drop);
- Все пакеты с перенаправлением (политика forward, для включенной маршрутизации) - логируются и отбрасываются (drop);
- Блокировка пакетов, которые используются для "тихого" сканирования портов.
Таким образом, мы сможем отправлять с машины любые пакеты (http, ftp, ssh, ping и другие) и получать ответные на них пакеты (что относятся к тому же соединению). Все пакеты что будут приходить снаружи на сервер без предварительно установленного соединения будут писаться в лог системы (смотрим используя journalctl) и отбрасываться.
Такой набор правил отлично подойдет для рабочей станции, удаленный доступ к которой не планируется.
Создадим файл под именем "systemd-iptables.sh" в папке для пользовательских скриптов "/usr/local/sbin/", для этого выполним команду:
nano /usr/local/sbin/systemd-iptables.sh
Скопируем приведенный ниже исходный код скрипта в окно редактора:
#!/bin/sh
# IPTables (ipv4+ipv6) init script for systemd
# 2016 by Ph0en1x (https://ph0en1x.net)
IP4TABLES_BIN=/sbin/iptables
IP6TABLES_BIN=/sbin/ip6tables
# Flush active rules, flush custom tables, and set default policy
Flush_Rules () {
if [ $1 = "ipv6" ]; then
IPTABLES=$IP6TABLES_BIN
else
IPTABLES=$IP4TABLES_BIN
fi
$IPTABLES --flush
$IPTABLES -t nat --flush
$IPTABLES -t mangle --flush
$IPTABLES --delete-chain
$IPTABLES -t nat --delete-chain
$IPTABLES -t mangle --delete-chain
# Set default policies to ACCEPT
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
}
# Loading rules
Load_Rules () {
if [ $1 = "ipv6" ]; then
IPTABLES=$IP6TABLES_BIN
IPV='IPv6'
else
IPTABLES=$IP4TABLES_BIN
IPV='IPv4'
fi
# Flush
Flush_Rules $1
# Localhost
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
# Default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
# Input filter chain
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A INPUT -j LOG --log-prefix "${IPV}Tables INPUT Dropped:"
# Forward chain
$IPTABLES -A FORWARD -j LOG --log-prefix "${IPV}Tables FORWARD Dropped:"
# disable furtive port scanning
$IPTABLES -N PORT-SCAN
$IPTABLES -A PORT-SCAN -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j RETURN
$IPTABLES -A PORT-SCAN -j DROP
}
case $1 in
start)
Load_Rules ipv4
Load_Rules ipv6
echo "IPTables rules loaded."
;;
stop)
Flush_Rules ipv4
Flush_Rules ipv6
echo "IPTables rules flushed."
;;
restart)
Flush_Rules ipv4
Flush_Rules ipv6
Load_Rules ipv4
Load_Rules ipv6
echo "IPTables rules reloaded."
;;
*)
echo "Usage: systemctl {start|stop|restart} iptables.service"
exit 1
esac
exit 0
Если использование какого-либо из протоколов не планируется, то можно отключить загрузку правил для него закомментировав строчки запуска в управляющей секции.
Например, если планируется использовать только IPv6 то загрузку правил для IPv4 можно отключить выполнив следующие изменения в скрипте:
start)
#Load_Rules ipv4
Load_Rules ipv6
echo "IPTables rules loaded."
;;
stop)
#Flush_Rules ipv4
Flush_Rules ipv6
echo "IPTables rules flushed."
;;
restart)
#Flush_Rules ipv4
Flush_Rules ipv6
#Load_Rules ipv4
Load_Rules ipv6
Для использования данного скрипта на удаленном сервере (VPS/VDS) нужно открыть возможность принимать входящие соединения, как минимум на порте 22 (SSH, администрирование, туннелирование).
Например, для пропускания входящих пакетов на порты 80, 443 и 22 нужно добавить после правила "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT") в скрипт следующие строчки:
$IPTABLES -A INPUT -p tcp --dport 22 -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 80 -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 443 -j ACCEPT
Также, для открытия данных портов можно добавить всего одно правило с указанием названий протоколов:
$IPTABLES -A INPUT -p tcp -m state --state NEW -m multiport --dports ssh,http,https -j ACCEPT
Если у вас на сервере несколько сетевых интерфейсов и входящие пакеты на порты 80, 443 и 22 должны проходить только на один из них, то можно указать в правиле название интерфейса.
Например, для сетевого интерфейса "venet0" разрешающее правило для того же набора протоколов будет выглядеть следующим образом:
$IPTABLES -A INPUT -p tcp -i venet0 -m state --state NEW -m multiport --dports ssh,http,https -j ACCEPT
После правки и сохранения содержимого скрипта systemd-iptables.sh ему нужно дать права на выполнение, для этого выполним команду:
chmod +x /usr/local/sbin/systemd-iptables.sh
Теперь перейдем к созданию юнита (файл с правилами контроля и управления запуском) для systemd. В данном файле мы опишем назначение, команды управления и условия запуска нашего скрипта.
nano /etc/systemd/system/iptables.service
Разместим в нем вот такой текст:
[Unit]
Description=IPTables rules
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/systemd-iptables.sh start
ExecStop=/usr/local/sbin/systemd-iptables.sh stop
ExecReload=/usr/local/sbin/systemd-iptables.sh restart
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Содержимое данного файла очень напоминает содержимое INI-файлов в Windows. В разделе Unit объявлено описание нового демона (Description), а также название группы демонов (сетевая подсистема - network.target) после инициализации которой должен стартовать наш ново-созданный SH-скрипт.
В разделе "Service" описаны опции для запуска и управления демоном. Как видим, здесь мы вызываем наш скрипт с правилами файрвола, передавая ему в качестве аргументов: start, stop, restart.
После сохранения содержимого файла iptables.service мы можем проверить все ли в порядке с его синтаксисом, для этого выполним команду:
systemctl status iptables.service
Если все ОК то укажем systemd что нужно разрешить запуск демона iptables.service при старте системы:
systemctl enable iptables.service
Теперь мы можем перезагрузить ОС для авто-запуска скриптов или же запустить наш сервис вручную с помощью команды:
systemctl start iptables.service
Скрипт брандмауэра с раздельными наборами правил для IPv4 и IPv6
Выше был приведен простой скрипт для управления iptables+ip6tables, в котором используется один и тот же набор правил как для протокола IPv4, так и для IPv6.
Он прост и удобен, но при использовании более сложных наборов правил может оказаться неработоспособным, и вот почему:
- При указании IP-адреса для какого-либо узла в сети, iptables откажется его обрабатывать если это IPv6-адрес, а ip6tables выдаст ошибку при попытке скормить ему правило с указанием IPv4-адреса;
- Синтаксис некоторых ключей в правилах для iptables и ip6tables может отличаться, хотя в подавляющем большинстве своем он одинаков для двух протоколов.
Как пример различия в синтаксисе для iptables и ip6tables можно рассмотреть правило которое блокирует icmp-трафик отсылая сообщение что пакет был отклонен (refused):
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
ip6tables -A INPUT -j REJECT --reject-with icmp6-adm-prohibited
Если попробовать в правиле с ip6tables указать "--reject-with icmp-host-prohibited" то получим ошибку:
ip6tables v1.6.0: unknown reject type "icmp-host-prohibited"
Try `ip6tables -h' or 'ip6tables --help' for more information.
В приведенном ниже скрипте правила для iptables и ip6tables можно задавать раздельно для каждого из протоколов. В данном случае, для примера, правила просто продублированы, вы можете их изменить и дополнить для каждого протокола по своему усмотрению. Без изменений, результат работы правил фильтрации у этого скрипта будет такой же как и у предыдущего.
#!/bin/sh
# IPTables (ipv4+ipv6) init script for systemd
# 2018 by Ph0en1x (https://ph0en1x.net)
IP4TABLES_BIN=/sbin/iptables
IP6TABLES_BIN=/sbin/ip6tables
# Flush active rules, custom tables, and set default policy.
Flush_Rules () {
if [ $1 = "ipv6" ]; then
IPTABLES=$IP6TABLES_BIN
else
IPTABLES=$IP4TABLES_BIN
fi
$IPTABLES --flush
$IPTABLES -t nat --flush
$IPTABLES -t mangle --flush
$IPTABLES --delete-chain
$IPTABLES -t nat --delete-chain
$IPTABLES -t mangle --delete-chain
# Set default policies to ACCEPT
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
}
# Loading rules for IPv4 and IPv6.
Load_Rules () {
if [ $1 = "ipv6" ]; then
IPTABLES=$IP6TABLES_BIN
IPV='IPv6'
Flush_Rules $1
# ----------------- IPv6 rules ----------------- #
# Localhost
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
# Default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
# Input filter chain
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A INPUT -j LOG --log-prefix "${IPV} Tables INPUT Dropped:"
# Forward chain
$IPTABLES -A FORWARD -j LOG --log-prefix "${IPV} Tables FORWARD Dropped:"
# disable furtive port scanning
$IPTABLES -N PORT-SCAN
$IPTABLES -A PORT-SCAN -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j RETURN
$IPTABLES -A PORT-SCAN -j DROP
# ---------------------------------------------- #
else
IPTABLES=$IP4TABLES_BIN
IPV='IPv4'
Flush_Rules $1
# ----------------- IPv4 rules ----------------- #
# Localhost
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
# Default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
# Input filter chain
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A INPUT -j LOG --log-prefix "${IPV} Tables INPUT Dropped:"
# Forward chain
$IPTABLES -A FORWARD -j LOG --log-prefix "${IPV} Tables FORWARD Dropped:"
# disable furtive port scanning
$IPTABLES -N PORT-SCAN
$IPTABLES -A PORT-SCAN -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j RETURN
$IPTABLES -A PORT-SCAN -j DROP
# ---------------------------------------------- #
fi
}
case $1 in
start)
Load_Rules ipv4
Load_Rules ipv6
echo "IPTables rules loaded."
;;
stop)
Flush_Rules ipv4
Flush_Rules ipv6
echo "IPTables rules flushed."
;;
restart)
Flush_Rules ipv4
Flush_Rules ipv6
Load_Rules ipv4
Load_Rules ipv6
echo "IPTables rules reloaded."
;;
*)
echo "Usage: systemctl {start|stop|restart} iptables.service"
exit 1
esac
exit 0
Вместо символа табуляции для форматирования здесь использованы 2 пробела - строки получились короче, удобнее для длинных правил с множеством ключей.
Установка и настройка юнита для автоматического запуска скрипта при старте системы такая же как и для предыдущего скрипта.
Полезные инструменты для IPv4 и IPv6
Для управления и мониторинга состояния iptables.service, а также для просмотра правил IPTables (IPv4 и IPv6) используем следующие команды:
systemctl start iptables.service
systemctl stop iptables.service
systemctl restart iptables.service
systemctl status iptables.service
iptables -nvL
ip6tables -nvL
Наблюдать за попаданием пакетов в правила брандмауэра удобно используя утилитку "watch":
watch -n 1 iptables -nvL
watch -n 1 ip6tables -nvL
Пропинговать хосты для каждого из протоколов можно вот так (пингуем публичные DNS-сервера Google):
ping 8.8.8.8
ping6 2001:4860:4860::8888
Смотрим состояние сокетов используя утилиту ss (socket stats), выведем TCP-сокеты которые прослушиваются (listening), а также информацию о процессах которые их открыли для каждого из протоколов IPv4 и IPv6 по отдельности:
ss -tlnp -f inet
ss -tlnp -f inet6
То же самое только для UDP-сокетов:
ss -ulnp -f inet
ss -ulnp -f inet6
Наблюдаем за TCP и UDP портами под номером 44444 на машинах с интернет-адресами IPv4 и IPv6 (используем nmap):
watch -n 5 "nmap -P0 -sU -p44444 123.123.123.1"
watch -n 5 "nmap -6 -P0 -sU -p44444 2504:fd01:1002:81::6"
Приведенные команды позволят протестировать работоспособность брандмауэра для каждого из протоколов, а также предоставят дополнительную полезную информацию по серверу и статусу его сетевых сокетов.
Заключение
Используя приведенный скрипт для брандмауэра можно защитить свой десктоп или выделенный сервер от вторжений снаружи по протоколам IPv4 и IPv6. Он предельно простой и может быть модифицирован под ваши нужды. Демон инициализации systemd имеет очень широкие возможности и содержит целый ряд мощных инструментов.
- sureshkumarpakalapati.in - Suresh Kumar Pakalapati - posts with label "IPtables"
- binarytides.com - 10 examples of Linux ss command to monitor network connections
- Jethro Carr - "ip6tables: ipv6-icmp vs icmp"
- "man iptables", "man systemd", 'man systemctl' - команды в консоли, всегда доступные справочники по инструментам.
Статья дополнена, приведен скрипт с раздельным указанием правил для протоколов IPv4 и IPv6.
Здравствуйте !
Не подскажите, в чем можеть быть проблема?
systemctl status iptables.service
П iptables.service - IPTables rules
Loaded: error (Reason: Invalid argument)
Active: inactive (dead)
Apr 07 20:39:08 yuri-linmin systemd[1]: /etc/systemd/system/iptables.service:14: Missing '='.
Здравствуйте.
У вас в файле /etc/systemd/system/iptables.service в строчке под номером 14 что-то прописано или там присутствует какой-то лишний символ. В скрипте из статьи всего 13 строчек. Сотрите все что ниже строчки "WantedBy=multi-user.target", сохраните файл и проверьте исчезла ли проблема.
Здравствуйте! Подскажите пожалуйста, возможно ли при помощи iptables и ip6tables сделать вот такую штуку:
1.Имеется vps сервер с ipv4 и ipv6 адресами.
2.Имеется роутер с динамическим ipv6 адресом.
3.Имеется ПК, только с ipv4 адресом.
Необходимо иметь доступ по SSH с ПК на роутер.
На роутере стоит скрипт, который при перезагрузке обновляет в DNS запись о новом айпи. Хотел сделать что-то типа прокси из vps, При обращении с ПК по ipv4, по порту 222 на vps, делать форвард через ipv6 до роутера на порт 22. Усложняется задача тем, что адрес у роутера динамический и следовательно желательно писать правило, которое бы выполняло форвард не на ip адрес а на dns имя. Но тут проблема, т.к. iptables (который v4), не может отрезолвить айпи адрес v6, то правило рода: ip6tables -A FORWARD -p tcp --dport 443 -d ipv6.router.com -j ACCEPT становится бесполезным, т.к. необходимо как-то иметь связку между iptables и ip6tables.
Здравствуйте. С IPv6 работал не много, знаю что IPTables пока еще на научился делать подобных вещей. Для маршрутизации трафика "IPv4 <--> IPv6" понадобится дополнительный туннельный интерфейс, попробуйте поискать информацию и примеры, включая в поисковый запрос название вашей ОС на VPS и фразы: "6to4", "6in4".
Еще один вариант - поднять на VPS службу OpenVPN и настроить туннель с поддержкой IPv6. Подключаемся c ПК к IPv4-адресу VPS используя OpenVPN-client, будет поднят туннель, а дальше пробовать коннектиться с ПК к роутеру на сопоставленное ему доменное имя, IPv6 трафик должен пойти через проложенный сетевой туннель.
Поскольку вам нужна всего лишь одна служба (SSH, порт - 22) на роутере, то можно обойтись простым перенаправлением (редиректом) трафика между интерфейсами и портами, один из вариантов - использовать утилиту socat (похожа на netcat, умеет fork'аться от имени указанного пользователя и еще много всего, плюс к безопасности).
Где:
Программа socat во время подключения к прослушиваемому порту выполняет резолвинг IP-адреса цели, это можно проверить на локальной Linux-машине:
В окне телнета вводим "GET" и ЕНТЕР, увидим листинг индексного HTML файла сайта google.com. Теперь в /etc/hosts временно прописываем в сопоставление домену 'google.com' IP-адрес какого-то другого сайта, сохраняем и пробуем снова "зателнетиться" на локальный порт который слушает socat - должны увидеть HTML-код странички уже не от 'google.com'. По завершению не забудьте убрать тестовую запись из /etc/hosts.
Таким образом, вам скорее всего не придется придумывать что-то дополнительно, кроме автозапуска этой команды при старте VPS (можете использовать пример юнита для systemd из этой статьи, поправив его под свои цели).
Если резолвинг DNS-имени роутера в программе socat по какой-то причине не работает, то проще всего написать небольшой скрипт (на BASH или PYTHON) и добавить его в автозапуск системы. Суть работы скрипта: в бесконечном цикле каждые несколько минут пинговать хост роутера по домену, извлекать из вывода IP-адрес и сопоставлять с тем, который указан для запуска процесса socat, если адрес изменился - перезапускать socat с новыми параметрами.
Больше информации и описаний параметров по socat:
Во всех случаях нужно позаботиться о безопасности. В случае с OpenVPN - настроить авторизацию и шифрование трафика. Для варианта с перенаправлением портов - используя IPTables строго ограничить порт на IPv4 интерфейсе VPS на доступ с других внешних IP, иначе будут подбирать пароли к службе SSH роутера через перенаправленный на IPv4 порт на вашем VPS.