Предисловие
В статье будут рассмотрены три независимых варианта прохождения трафика транзитом с помощью:
У меня провайдер заблокировал мой openvpn. Сначала обычный провайдер, а потом и мобильный тоже. Это был обычный
Вариант I. DoubleVPN
Конечно, первое, что пришло в голову - это просто соединить два сервера в России и в другой стране с помощью openvpn. И это получилось без проблем. Вот ниже мое решение:
Шаг первый. Установка openVPN на обоих серверах
Все, что я пишу, подходит так или иначе для любых *nix серверов, будь то ubuntu, centos, fedora, rocky и т.д.
Установить можно openvpn готовым скриптом, например, вот таким:
https://github.com/Nyr/openvpn-install
После того как вы запустили скрипт на обоих серверах, можно перейти к настройкам каждого из них.
Шаг два. Настройка на зарубежном
На сервере в стране Х настройка очень простая. После того как вы запустили вышеуказанный скрипт и openvpn установился, все что нужно сделать - это отредактировать файл конфигурации, замените его следующим содержимым.
/etc/openvpn/server/server.conf
port XXXX # Порт на котором у вас работает openvpn
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-crypt tc.key
remote-cert-tls client
server 10.100.39.0 255.255.255.0
keepalive 10 120
persist-key
persist-tun
verb 3
sndbuf 0
rcvbuf 0
push "route 10.100.39.0 255.255.255.0"
Далее сделайте рестарт опенвпн сервера:
systemctl restart openvpn-server@server.service
И скопируйте клиентский ключ, который был создан при установке на российский scp
.
На этом всё. Настройка зарубежного сервера завершена.
Шаг три. Настройка российского
На российском
Редактируем /etc/sysctl.conf
Втыкаем следующие строки:
net.ipv4.ip_forward=1
net.ipv4.conf.tun0.rp_filter=0
net.ipv4.conf.tun1.rp_filter=0
Строки net.ipv4.conf.tun0.rp_filter=0
и net.ipv4.conf.tun1.rp_filter=0
отключают проверку reverse path filtering для интерфейсов tun0 и tun1 соответственно. Можно ребутнуть сервер или ввести соответствующие команды.
Редактируем файл:
/etc/iproute2/rt_tables
И добавляем в него строку:
150 vpn_net
Здесь подробное объяснение зачем и что мы делаем (можно не читать)
Файл /etc/iproute2/rt_tables служит для определения имен пользовательских таблиц маршрутизации в Linux-системах.
-
Таблицы маршрутизации: Представьте, что у вас есть несколько маршрутов, по которым пакеты данных могут перемещаться в вашей сети. Таблицы маршрутизации позволяют организовать эти маршруты в группы, что упрощает управление и настройку сетевых соединений.
-
Зачем нужны пользовательские таблицы:
-
Разделение трафика: Вы можете направить разные типы трафика по разным маршрутам. Например, весь трафик VPN можно отправить через определенную таблицу, а остальной трафик — через другую.
-
Управление политиками: Таблицы могут использоваться для реализации различных сетевых политик, таких как маршрутизация на основе качества обслуживания (QoS) или балансировка нагрузки.
-
Управление несколькими сетевыми интерфейсами: Если у вас несколько сетевых интерфейсов, вы можете использовать разные таблицы для каждого из них.
-
Что значит число 150 и строка 150 vpn_net?
-
Число: Это просто уникальный номер, который вы присваиваете своей таблице. Вы можете выбрать любое число, кроме тех, которые уже зарезервированы системой (например, 255, 254, 253, 0).
-
Строка: Строка в формате "число имя_таблицы" связывает числовой идентификатор с понятным именем. В данном случае, вы создаете таблицу с именем "vpn_net" и присваиваете ей номер 150.
Зачем добавлять такую строку?
Предположим, у вас есть VPN-соединение, и вы хотите, чтобы весь трафик, направленный в VPN, проходил через это соединение. Вы можете создать отдельную таблицу маршрутизации для VPN-трафика и добавить в нее соответствующие маршруты. Затем, используя правила iptables или другие механизмы, вы можете перенаправлять весь трафик, предназначенный для VPN, в эту таблицу.
Теперь нам надо создать два скрипта, которые будут выполняться при старте зарубежного openvpn клиента и при остановке.
/etc/openvpn/server1_up.sh
/sbin/ip rule add from 10.8.0.0/24 table vpn_net
/sbin/ip route add default dev tun1 table vpn_net
/etc/openvpn/server1_down.sh
/sbin/ip rule del from 10.8.0.0/24 table vpn_net
/sbin/ip route del default dev tun1 table vpn_net
На оба скрипта вешаем
chmod +x /etc/openvpn/server1_up.sh
и chmod +x /etc/openvpn/server1_down.sh
Теперь нам надо взять клиентский конфиг, который мы взяли на зарубежном сервере. Сменить ему расширение: вместо .ovpn написать .conf
mv my_client.ovpn my_client.conf
Положить в папку: /etc/openvpn/client
и отредактировать примерно таким образом:
/etc/openvpn/client/my_client.conf
client
dev tun
proto udp
remote XX.XX.XX.XX YY YY # IP и порт зарубежного VDS
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
verb 3
script-security 2
up "/etc/openvpn/server1_up.sh"
down /etc/openvpn/server1_down.sh
# До этого место. Дальше не трогаем.
<ca>
-----BEGIN CERTIFICATE-----
wIBAgIJAL0WnyzV8N87MA0
......
Указываем, что у нас будут стартовать скрипты при запуске и остановке клиента.
Запускаем опенвпн-клиент
systemctl start openvpn-client@my_client
Добавляем новое правило iptables
iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o tun1 -j MASQUERADE
А старое nat правило, которое добавил установщик Nyr/openvpn-install, удаляем. Сохраняем iptables тем способом, которые есть в вашем *nix, так чтобы они сработали после загрузки. И делаем автостарт нашего клиента:
systemctl enable openvpn-client@my_client
Проверяем, что все работает, с помощью команд
ip route show table all|grep vpn_net
ip rule list| grep vpn_net
ip address
С помощью openvpn-install создаем необходимое кол-во опенвпн ключей.
Вариант II. OpenVPN + Vtun
В первом варианте у нас был openvpn + openvpn, но нам ничего не мешает соединить, например, российский
Шаг первый. Установка vtun на обоих серверах
Vtun можно собрать из исходников. Будем считать, что вы на обоих серверах vtun и openvpn поставили. Форвард пакетов разрешили, см. настройки у варианта № 1.
Шаг второй. Запуск vtun сервера на зарубежном сервере
Для сервера можно взять примерно такой конфиг и положить его в файл /etc/vtund.conf
:
/etc/vtund.conf
options {
port 5000;
ifconfig /sbin/ifconfig;
}
# Default session options
default {
proto tcp; # TCP protocol
compress no; # Compression is off
encrypt no; # ssh does the encryption
speed 0; # By default maximum speed
keepalive yes;
stat yes;
}
my_tunnel {
passwd MY_STRONG_PASS; # Password
type tun; # IP tunnel
proto tcp; # TCP protocol
up {
ifconfig "%% 10.3.0.2 pointopoint 10.3.0.1 mtu 1500";
};
down{
ifconfig "%% down";
};
}
Открываем порт 5000 и добавляем SNAT правила, где to-source XX.XX.XX.XX
это белый IP в стране Х.
-A INPUT -p tcp -m tcp --dport 5000 -j ACCEPT
-A POSTROUTING -s 10.3.0.0/24 -j SNAT --to-source XX.XX.XX.XX
Запускаем:
vtund -s
Проверяем, должен появиться интерфейс tun и ip.
ip address
Шаг три. Запуск vtun клиента и openvpn в России
Openvpn ставим как обычно, см. вариант 1.
А вот настройки vtun на российском сервере
/etc/vtund.conf
options {
port 5000;
# Path to various programs
ifconfig /sbin/ifconfig;
ip /sbin/ip;
}
# Default session options
default {
compress no;
encrypt no;
speed 0;
keepalive yes;
stat yes;
}
my_tunnel {
passwd PASS; # Password
type tun; # IP tunnel
proto udp; # TCP protocol
up {
# 10.3.0.1 локальный ip
# 10.3.0.2 удаленный ip
ifconfig "%% 10.3.0.1 pointopoint 10.3.0.2 mtu 1500";
ip "rule add from 10.8.0.0/24 table vpn_net";
ip "route add default dev %% table vpn_net";
};
down{
ip "rule del from 10.8.0.0/24 table vpn_net";
ip "route del default dev %% table vpn_net";
ifconfig "%% down";
};
}
Запускаем командной:
vtund my_tunnel ip_адрес_вашего_зарубежного_сервера
Точно так же как и с опенвпн маскарадим трафик:
iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o tun1 -j MASQUERADE
После этого все должно заработать. Если не работает, то убедитесь, что пинги проходят между 10.3.0.1 и 10.3.0.2 и смотрите логи.
Конфигурация vtun дана для примера. Там по желанию можно и трафик передавать по udp, шифровать, сжимать и т.д.
Вариант III. OpenVPN + tun2proxy
В третьем варианте мы закинем openvpn трафик в socks5 и так же выпустим наружу. Хотя с помощью tun2proxy можно туннелировать и в http прокси, поэтому даже зарубежный
https://github.com/tun2proxy/tun2proxy
Tun2proxy - это туннельный интерфейс для HTTP- и SOCKS-прокси на Linux, Android, macOS, iOS и Windows:
-
HTTP‑прокси (без аутентификации, базовая и дайджест‑аутентификация)
-
Поддержка SOCKS4 и SOCKS5 (без аутентификации, аутентификация по имени пользователя и паролю)
-
Поддержка SOCKS4a и SOCKS5h (через функцию виртуального DNS)
-
Минимальная настройка конфигурации для маршрутизации всего трафика
-
Поддержка IPv4 и IPv6
-
Механизм обхода GFW для определенных случаев использования
-
Поддержка SOCKS5 UDP
-
Встроенная поддержка проксирования DNS через TCP
Установка и настройка
Вся установка и настройка делается на сервере в России. На первом сервере. На втором (зарубежном сервере) лишь нужен ssh аккаунт для создания socks5 прокси.
Я поставил rust последнюю версию
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
И далее запустил установку
$HOME/.cargo/bin/cargo install tun2proxy
И он благополучно установился, проверил что все ок:
$HOME/.cargo/bin/tun2proxy --help
Почитал справку по использованию. Дальше я создал для проверки ssh socks5 tcp динамическую проксю такой командой:
ssh -D 14017 -q -C -N my-socks5-user@my-remote-server.com
Повесил на порт 14017. По хорошему, надо было бы udp socks5 делать (но мы же не ищем легких путей), и для теста так интереснее.
Далее запустил tun2proxy командой:
$HOME/.cargo/bin/tun2proxy --tun tun1 --proxy "SOCKS5://127.0.0.1:14017"
Потом поднял сетевой интерфейс, т.к. по умолчанию он отключен:
ifconfig tun1 up
Это и есть фишка tun2roxy, что он создает сетевой интерфейс. То есть если набрать, например ifconfig, то при включенном tun2roxy можно увидеть еще одну "сетевую карту", которую он создал на основе прокси. А если есть tun1, то можно уже делать все, что мы захотим, почти так же как и в предыдущих вариантах.
Проверил, что все работает такой командой:
curl --interface tun1 ifconfig.me
В ответ получил IP адрес своего зарубежного сервера. Все окей, трафик завернулся в tun1 и вышел из-за рубежа.
Теперь надо заставить openVPN ходить таким же макаром, чтобы выпустить наружу трафик openVPN через tun1 & socks5.
/etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.conf.tun0.rp_filter=0
net.ipv4.conf.tun1.rp_filter=0
net.ipv4.conf.all.route_localnet=1
В файл:
/etc/iproute2/rt_tables
Добавил строчку:
150 vpn_net
И ввел команды:
/sbin/ip rule add from 10.8.0.0/24 table vpn_net
/sbin/ip route add default dev tun1 table vpn_net
И дальше прикол, если просто замаскарадить трафик командой iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o tun1 -j MASQUERADE
, то работать не будут DNS запросы, ведь они идут не по TCP. Как я и писал выше, обычный socks5 tcp прокси не очень-то и подходит. Так что перед тем как маскарадить, мне пришлось поставить dnsproxy и запустить его командой:
./dnsproxy -u 8.8.8.8:53
И сам tun2proxy на этот раз запустил командой, что указана выше, но с доп. ключом --dns direct
и так же изменил настройку клиентского опенвпн, чтобы он с DNS запросами шел ко мне локально на сервер.
После этого все заработало и openvpn клиент вышел наружу через этот туннель.
Автор: Rilkener