Найти:

- Взлом
- Приватность
- Трюки
- Кодинг
- Админ
- Geek
- Обучение
- Магазин

- Windows
- Linux
- Android
- Железо
- Мессенджеры
- Утечки
- Коронавирус
- Все выпуски «Хакера»

### Содержание статьи

- Немного теории
- Что есть что
- Коротко о двух вариантах
- Реализация
- Вариант 1: клиент VPN на машине пользователя
- Вариант 2: клиент VPN на маршрутизаторе
- IPSet
- Автоматизация после сбоев/перезагрузок
- Заключение

Есть много способов обойти региональные блокировки и обеспечить анонимность. Такие термины, как TOR, VPN, прокси, у всех на слуху. Чтобы подключить и настроить их, не требуется специальных знаний, но существуют и более изящные решения. Сегодня я расскажу о методике обхода блокировок в Linux с маскировкой трафика и покажу несколько скриптов для автоматизации этого. Их можно без труда перенести на Raspberry Pi, чтобы сделать умный маршрутизатор.

## WARNING

Эта статья не является руководством. Она написана исключительно с целью ознакомить тебя с некоторыми функциональными возможностями маршрутизации в системах Linux. Автор и редакция не несут никакой ответственности за результат использования описанных здесь методов и приемов.

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

- определимся с тем, что нам требуется: установим необходимые пакеты и разберемся, зачем они нужны;
- изучим общий принцип работы связки;
- настроим защищенный канал VPN с использованием OpenVPN + stunnel;
- составим списки адресов и опишем области их применения;
- создадим скрипт для быстрого добавления домена или IP-адреса в списки IPSet с добавлением в таблицу маршрутизации и включением в правила перенаправления;
- используем SSH для предоставления безопасного канала связи в эти ваши интернеты.

## Немного теории

Что нам понадобится, чтобы все работало, и желательно — комфортно? Само собой, iptables, куда же без него. Еще iproute2, он и позволит нам насоздавать кучу таблиц. IPSet потребуется для того, чтобы не городить огород из множества правил iptables.

### Что есть что

- iptables — утилита командной строки. Базовое средство управления работой файрвола для ядер Linux.
- iproute2 — набор утилит для управления параметрами сетевых устройств в ядре Linux.
- IPSet — инструмент для работы со списками IP-адресов и сетевых портов в сетевом фильтре. Формирует список в специальном формате для передачи файрволу.
- stunnel — инструмент организации шифрованных соединений для клиентов или серверов, которые не поддерживают TLS или SSL. Stunnel перехватывает незашифрованные данные, которые должны были отправиться в сеть, и шифрует их. Программа работает как в Unix-системах, так и в Windows. В качестве шифрования использует OpenSSL для реализации базового протокола TLS и SSL.
- OpenVPN — VPN-сервер с поддержкой шифрования библиотекой OpenSSL. Клиентские части доступны практически на всех платформах. Умеет работать через прокси типа Socks, HTTP, через NAT и сетевые фильтры.

Про все эти утилиты можно отыскать много информации в интернете, причем с примерами настроек в самых разных вариантах. Мы станем использовать iptables для маркировки пакетов. У нас будут два варианта настройки. Первый — когда машина, на которой выполняется обход, сама подключена к VPN. Второй вариант — когда в сети находится узел (виртуалка, Raspberry Pi или любой другой хост с Linux), играющий роль маршрутизатора. Далее мы разберем эти варианты чуть подробнее.

## Коротко о двух вариантах

Клиент и сервер будут устанавливать зашифрованный канал связи по 443-му порту (stunnel) и передавать внутри OpenVPN по 995-му порту. Снаружи это должно выглядеть как обычный HTTPS.

Иллюстрация работы stunnel + OpenVPN
Другие статьи в выпуске:

### Xakep #246. Учиться, учиться, учиться!

- Содержание выпуска
- Подписка на «Хакер»-70%

И вот тут можно реализовать две схемы подключения.

Вариант 1. На клиентской машине iptables будет маркировать пакеты неким флагом, если адреса в пакетах и списках IPSet совпадут, и передавать их для маршрутизации.

Далее помеченные флагом пакеты будут отправлены по заранее созданной таблице маршрутизации, остальные пойдут по маршруту, заданному по умолчанию. С помощью консоли или небольшого скрипта мы поправим этот список адресов. В зависимости от ситуации списков может быть несколько.

Вариант 2. В качестве клиента выступит хост в локальной сети (виртуалка, Raspberry Pi или какое-нибудь другое устройство). Он будет указан в качестве основного шлюза на компьютерах, с которых нужен доступ к ресурсам через VPN. Получив запрос для IP-адреса из списка, шлюз включит NAT и отправит такой трафик в VPN. Остальной трафик будет маршрутизироваться до шлюза по умолчанию без NAT.

Для Linux-систем мы можем оставить шлюз по умолчанию и установить у себя IPSet и iproute2, а потом настроить их аналогично настройкам «промежуточного» хоста-маршрутизатора. В этом случае на уровне клиента будет отбираться трафик по тому же списку IPSet. То есть то, что в списке, будет отправляться на промежуточный хост-маршрутизатор и далее в VPN. Остальное будет маршрутизироваться по умолчанию.

## Реализация

Предположим, что где-то далеко в облаке у нас уже есть VPS-сервер с Ubuntu или Debian. В других дистрибутивах отличия будут, скорее всего, только в установке необходимых пакетов. Этот хост в нашей конфигурации будет использоваться в качестве сервера VPN. Рекомендаций, какой VPS лучше использовать, в интернетах полным-полно — на разный бюджет, с разными конфигурациями и условиями.

Устанавливаем на сервере OpenVPN, stunnel, git:

    sudo apt install openvpn stunnel4 git

Далее воспользуемся готовым скриптом для настройки сервера OpenVPN. Можно, конечно, настроить все вручную, и я советую поступить именно так. Информацию о том, как правильно сконфигурировать OpenVPN, нетрудно отыскать в Сети. Но если нужно получить результат очень быстро и тебе лень возиться, то вот решение.

    git clone https://github.com/Nyr/openvpn-install.git
    cd openvpn-install
    sudo ./openvpn-install.sh

Получаем скрипт установки и запускаем его. Он поможет нам создать пользовательские ключи и сертификаты, если нужно — изменить адресацию сети. Все очень доступно и понятно. На выходе для каждого пользователя мы получим один файл, внутри которого будет конфигурационный ключ и сертификаты (сервера и пользователя). Передаем этот файл на клиент.

Открываем конфигурационный файл сервера OpenVPN и правим его. Выбираем нужный порт — тот, который на сервере будет свободен для подключения. Порт лучше использовать более-менее неприметный (я выбрал 995-й, обычно почтовые порты оставляют открытыми), чтобы клиент мог гарантированно подключиться к VPN-серверу.

Вот как будет выглядеть наш конфиг:

    port 443
    proto tcp
    dev tun0
    sndbuf 0
    rcvbuf 0
    ca ca.crt
    cert server.crt
    key server.key
    dh dh.pem
    auth SHA512
    tls-auth ta.key 0
    topology subnet
    server 10.8.0.0 255.255.255.0
    ifconfig-pool-persist ipp.txt
    push "redirect-gateway def1 bypass-dhcp"
    push "dhcp-option DNS 208.67.222.222"
    push "dhcp-option DNS 208.67.220.220"
    push "route 10.8.0.0 255.255.255.0"
    route 192.168.31.0 255.255.255.0
    keepalive 10 120
    cipher AES-256-CBC
    user nobody
    group nogroup
    persist-key
    persist-tun
    status openvpn-status.log
    verb 3
    crl-verify crl.pem

Следующим шагом настроим stunnel:

    sudo nano /etc/stunnel/stunnel.conf

    output = /var/log/stunnel.log
    [openvpn]
    client = no
    accept = 443
    connect = localhost:443
    cert = /etc/stunnel/stunnelsrv.pems

Тут все просто:

- описываем, куда будут сохраняться логи;
- указываем название сервиса в произвольной форме;
- выбираем, в каком режиме работает устройство: сервера или клиента. В данном случае `client = no` указывает на режим сервера;
- accept = 443 указывает порт, к которому будем подключаться снаружи (443-й порт выбран не просто так — в 99% случаев он всегда открыт, проще прикинуться обычным HTTPS, и нас не заметят даже при DPI).

Генерируем ключи и сертификаты для stunnel:

    sudo openssl req -nodes -new -days 365 -newkey rsa:1024 -x509 -keyout stunnelsrv.pem -out stunnel.pem

На этом этапе важно помнить, что у нас на стороне сервера работают OpenVPN на порте 995, proto tcp, dev tun0 и stunnel на порте 443. Все остальные настройки — стандартные.

Переходим к клиенту:

    sudo apt install iproute2 ipset stunnel4 git openvpn

Все, что нужно, поставили, теперь настраиваем stunnel на стороне клиента:

    output = /var/log/stunnel.log

    [openvpn]
    client = yes
    accept = 127.0.0.1:995
    connect = IP:443

    cert = /etc/stunnel/stunnel.pem

Здесь мы указываем, куда выводить логи, режим клиента включен. С помощью директивы `accept` мы говорим, на какой адрес и порт передавать соединение и куда, собственно, подключаться клиенту stunnel (опция `connect`). Ну и какой сертификат использовать.

Передаем файл клиента OpenVPN с сервера. Проверяем настройки: используется порт 995, proto tcp, dev tun0. Очень важный момент: нам нужно объявить маршрут до нашего VPS через шлюз по умолчанию. Иначе получится, что stunnel установит соединение, потом подключится VPN и попытается все перенаправить в туннель, но stunnel уже не сможет работать, так как хост и порт будут недоступны. Также отключаем перенаправление всего трафика в VPN, проверяем адрес подключения и порт. Адрес VPN-сервера в конфиге будет 127.0.0.1 — то есть `localhost`. Подразумевается, что stunnel уже пробросил нужный порт клиента. Должно получиться примерно следующее:

    client
    dev tun
    proto tcp
    sndbuf 0
    rcvbuf 0
    remote 127.0.0.1 995
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    remote-cert-tls server
    auth SHA512
    cipher AES-256-CBC
    setenv opt block-outside-dns
    key-direction 1
    #redirect-gateway def1
    pull-filter ignore redirect-gateway
    #добавляем в конфиг OpenVPN клиента белый IP-адрес VPN-сервера
    route IP 255.255.255.255 net_gateway
    #ip route add table obhod default dev tun0
    verb 3

Итак, на сервере и клиенте установлены и настроены OpenVPN и stunnel. Безопасное соединение установлено. Дальше будем рассматривать каждый вариант по очереди.

### Вариант 1: клиент VPN на машине пользователя

Первым делом создадим список IP-адресов, который будем использовать далее:

    sudo ipset -N vpn iphash

Добавим в него один адрес для тестов:

    sudo ipset -A vpn 8.8.8.8

Теперь нам необходимо маркировать пакеты с адресами назначения, которые совпадают со списком.

    sudo iptables - OUTOUT -t mangle -m set --match-set vpn dst -j MARK --set-mark (1 или 0x1)

В результате наших действий iptables при совпадении в адресе назначения и адресе из списка IPSet начнет маркировать такой трафик. Дальше создадим новую таблицу маршрутизации, для этого пропишем ее в файле `/etc/iproute2/rt_tables` с очередностью выше, чем `default (253)`:

    252     vpn

Теперь надо создать правило и маршрут для маркированных пакетов.

    sudo ip rule add table vpn prio 1000 fwmark (1 или 0x1)
    sudo ip route add table vpn dev tun0 default

Не забываем включить `rp_filter` для обеспечения асимметричной маршрутизации и разрешаем переброс пакетов между интерфейсами, на случай если кому-то нужно будет предоставить доступ к закрытым ресурсам в локальной сети.

    sudo sysctl net.ipv4.tcp_fwmark_accept=1
    sudo sysctl net.ipv4.conf.all.rp_filter=2
    sudo net.ipv4.ip_forward=1

Теперь включим NAT для трафика, который направляется в VPN.

    sudo iptables -t nat -I POSTROUTING -o tun0 -j MASQUERADE

Если нужно предоставить доступ из локальной сети через свой VPN, правило iptables нужно немного подправить, а именно перенести в другую цепочку.

    sudo iptables -I PREROUTING -t mangle -m set --match-set tovpn dst -j MARK --set-mark 0x1

В итоге у нас получается, что все адреса из списка IPSet VPN идут через безопасное соединение, остальные направляются через маршрут по умолчанию.

### Вариант 2: клиент VPN на маршрутизаторе

Теперь рассмотрим случай, когда VPN-соединение у нас выполняет не клиентская машина, а некий узел в сети и все настроено на нем аналогично примеру выше. Тогда нам нужно либо указать этот узел в качестве шлюза по умолчанию, либо установить на клиентской машине IPSet и `iproute2` и правильно ее настроить.

В этом случае сработают локальные IPSet и `iproute2` и направят на промежуточный сервер-маршрутизатор пакет, а тот сверит адрес назначения со своим списком IPSet и, если обнаружит совпадение, отправит пакет в VPN, если совпадения не найдет — перешлет на шлюз по умолчанию.

Неудобство такого приема состоит в том, что нужно дважды вносить IP-адреса в списки. Сначала на сервере-маршрутизаторе, а второй раз — в свой локальный список IPSet. Зато это позволяет более гибко пользоваться маршрутизацией.

Стоит также отметить еще один вариант, о котором не говорилось выше. Можно установить на сервер-маршрутизатор VPN-клиент и stunnel, а потом убрать из конфига строку `pull-filter ignore redirect-gateway`. Тогда весь полученный трафик будет завернут в VPN-туннель. Останется лишь локально вести IPSet для направления нужного трафика через разные шлюзы.

## IPSet

Списки IPSet очень удобно использовать, если нужно быстро разрешить либо запретить входящие или исходящие соединения на сервер. Так, например, многие реализуют географическую фильтрацию: проще один раз занести все в списки и одним правилом запретить весь входящий трафик отовсюду, кроме этого списка. Например:

    sudo iptables -A INPUT -m set --match-set !RU src -j DROP

Это правило заблокирует все входящие соединения, кроме адресов из списка `ipset RU`.

IPSet, как видишь, удобный инструмент, который значительно сокращает таблицу правил iptables. В частности, хорошо бывает объединять в отдельные списки сети серверов, адреса админов, остальных пользователей и так далее. А потом уже разом запрещать доступ одним и разрешать другим.

## Автоматизация после сбоев/перезагрузок

Чтобы не потерять все настроенные нами параметры, добавим в crontab периодическое сохранение правил IPSet и iptables.

    sudo crontab -e

    # Каждую первую минуту каждого часа, то есть раз в час
    1 * * * * /bin/bash root ipset save > /opt/ipset.rules
    1 * * * * iptables-save root > /opt/firewall.rules

И в `/etc/rc.local` добавим восстановление:

    ipset restore < /opt/routers/ipset.rules
    iptables-restore < /opt/routers/iptables.rules

А теперь напишем скрипт, который будет обходить правила `iprule` и `iproute` и в случае, если чего-то не хватает, допишет недостающее. Скрипт можно сделать демоном, чтобы он постоянно висел в памяти и мониторил состояние системы, а можно запускать только при старте ОС. В целом второго варианта вполне достаточно.

Исходный код скрипта check ты найдешь в архиве по ссылке в конце статьи, а общий его смысл такой: проверяем таблицу маршрутизации и, если маршрута нет, добавляем его. Потом ту же проверку выполняем с правилом таблицы. Затем смотрим правило iptables, которое маркирует пакеты.

Напоследок напишем скрипт, который позволит нам более удобно добавлять IP-адреса в списки IPSet, чтобы каждый раз не ломиться в консоль. Этот скрипт выглядит так:

    #!/bin/bash

    test=$(zenity --entry --title="Добавление адреса в ipset списки " --text="Введите адрес ip или домена")
    initip=$(dig +short "$test" -u 1.1.1.1)

    if [ ! -n "$initip" ]; then
    zenity --password --title="Введите пароль администратора" | sudo -S ipset -exist -A vpn "$test"
    echo "$test" >> /opt/iptovpn.txt
    else
    zenity --password --title="Введите пароль администратора" | sudo -S ipset -exist -A vpn "$initip"
    echo "$initip" >> /opt/iptovpn.txt
    fi

    sudo ipset save > /opt/ipset.rules

При запуске мы вводим имя домена или сразу IP-адрес. Скрипт переварит и то и другое, после чего и запихает IP в список IPSet.

Также в архиве ты найдешь скрипт add_in_file, который читает файл со списком доменов, получает IP и складывает в списки IPSet.

## Заключение

Итак, что у нас получилось? А вот что. Мы подняли зашифрованный, «белый» с точки зрения провайдера канал HTTPS. Внутри у него ходит наш OpenVPN. Клиент заворачивает туда то, что нам нужно, и не отправляет того, что не нужно. В принципе, можно написать еще пару правил iptables, в которых указано, кому дозволено ходить по адресам из заданного списка, а кому нет. Можно указать источники запросов для большей безопасности и для того, чтобы туда, не дай бог, не залез любознательный пользователь. Это реализуется с помощью второго списка IPSet, где придется вбить доверенные хосты, которые будут пользоваться доступом.

При желании всю эту не слишком навороченную архитектуру можно развернуть на Raspberry Pi с «Линуксом» и таскать его с собой в качестве маленького маршрутизатора. Он где угодно обеспечит тебе надежное, безопасное и шифрованное соединение, до которого не доберется ни один товарищ майор.

## WWW

- Архив со скриптами к статье

#### Оцени статью:

###### Что тебе понравилось больше всего?

Статья легкая и понятная Статья глубокая и подробная Интересуюсь этой темой Данные новые и актуальные Приятный стиль изложения

###### Что тебе не понравилось больше всего?

Статья поверхностная Статья слишком сложная Тема мне не интересна Данные устарели Неприятный стиль изложения
← Ранее Злоумышленники превращают Discord в бэкдор и вынуждают воровать данные
Далее → Новая CPDoS-атака угрожает сайтам, полагающимся на популярные CDN
2 комментария к записи Пингвинья тропа. Простые рецепты для выборочного шифрования трафика в Linux

#### Последние взломы

### HTB Driver. Эксплуатируем PrintNightmare и делаем вредоносный SCF

### Routing nightmare. Как пентестить протоколы динамической маршрутизации OSPF и EIGRP

### HTB Bolt. Эксплуатируем шаблоны в Python и разбираемся с PGP

### Краденые миллиарды и плохой рэп. Как арестовали супругов, которые отмывали деньги Bitfinex и снимали тиктоки

#### Компьютерные трюки

### Поездка в Sonerezh. Поднимаем сервер для стриминга музыки

### Терминальное счастье. Колонка главреда

### Анатомия терминала. Осваиваем текстуальную графику

### Змей-стражник. Сигнализация для велосипеда из старого смартфона на Android

#### Свежие новости

- 5 часов назад

  ### Миллионы устройств Samsung подвержены аппаратной криптографической проблеме

- 6 часов назад

  ### Мидлбоксы способны усиливать DDoS-атаки в 65 раз

- 20 часов назад

  ### Малварь TeaBot снова проникла в Google Play Store

- 20 часов назад

  ### Nvidia подтвердила, что учетные данные ее сотрудников были украдены

- 21 час назад

  ### Опубликованы исходники шифровальщика Conti

Вопросы по материалам и подписке: support@glc.ru
Отдел рекламы и спецпроектов: yakovleva.a@glc.ru
Контент 18+
Сайт защищен Qrator —
самой забойной защитой от DDoS в мире
Подписка для физлиц
Подписка для юрлиц
Реклама на «Хакере»
Контакты
Posting....
wpDiscuz
FooBox
…