Статья SSH Multi-Hop туннелирование на Android (без root)

Доброго времени суток!

Всем известно что для достижения анонимности используются Tor, I2P, цепочки Socks-proxy, всяческие VPN (OperaVPN hello) или их цепочки, в том числе собственные. И почти никто не использует SSH-транспорт для туннелирования дальше одного хоста.

Информация по этому вопросу присутствует в сети, но в разрозненном виде и в малом количестве.

Сегодня мы это исправим и соберем в одну статью.

В ней я наглядно покажу как можно завернуть весь трафик с устройства Android в цепочку SSH-туннелей без необходимости рутировать устройство.
Отмечу сразу, чтобы потом не возникли вопросы. SSH-туннель для Android можно построить на рутированном андройде, используя программы типа JuiseSSH (она, к слову, позволяет пробрасывать порты через множество серверов сразу) или ConnectionBot(вот эта так не умеет) используя конструкцию Lpost:host:Dport.
С нерутированного андройда можно тоже создать перенаправление портов на localhost, типа:
upload_2017-6-1_13-11-10.png


а в конфигурации OpenVPN клиента указать так:
upload_2017-6-1_13-11-51.png


то соединение в конечным узлом будет установлено:
upload_2017-6-1_13-12-26.png


только трафик не пойдет. Во всяком случае, мне пока не удалось.

Для Windows есть Putty/OpenSSH, для Ubuntu есть sshuttle/autossh и разные поделки с гитхаба.

А вот с Android все несколько иначе :)

В качестве серверов используем бесплатные мощности Amazon AWS. На нем нам потребуется зайти в разные регионы и создать в каждом их них новый Instance.
Каждому New Instance генерируйте новый ключ и не теряйте. Они нам понадобятся :)

upload_2017-5-31_16-38-26.png


Проблем возникнуть не должно, мануалов в сети масса.

Для разнообразия входная нода будет на Windows 2008 Server, промежуточные и выходная ноды на Ubuntu 14.04.

Итак, какие способы существуют, чтобы направить весь трафик с андройда? Их вообще мало. Большинство подумало про OpenVPN? Правильно. Его то мы и будем использовать, но OpenVPN-сервер нужно будет установить только один раз - на выходную ноду и настроить ip4.forward+добавить правила в iptables (получится VPN via SSH MultiHop, но не N-VPN)

Туннель, который я хочу построить будет проходить через несколько стран.
Я выбрал USA (in) --> UK(relay) --> India(relay)--> Japan(out)

upload_2017-5-31_17-16-49.png


Сейчас я напишу принцип и те, кто поймут, могут дальше не читать:

Код:
USA 2015:1194 Japan

Если более развернуто:

Код:
L2015:USA:3131:UK:3232:INDIA:3232:Japan:1194

Ведь просто, да? :)

Но сначала разберемся с конфигурацией OpenVPN для клиента. Она не сильно отличается от обычных, за исключением пары мелочей:

Код:
allow-recursive-routing

ifconfig-nowarn
client
verb 4

connect-retry 2 300
resolv-retry 60

dev tun

remote ec2-XX-XXX-XXX-XX.usa.amazonaws.com 2015 tcp-client

route 0.0.0.0 0.0.0.0 vpn_gateway
route-ipv6 ::/0

dhcp-option DNS 8.8.4.4   ;u can change it
dhcp-option DNS 8.8.4.4 
dhcp-option DOMAIN google.com

nobind

float
management-query-proxy
ns-cert-type server
ping 10

Обращаю внимание, что использовать мы будем порт 2015, а не 1194. Почему так? Ответ будет ниже.

Поскольку первый хост у нас на Windows (можно и linux, но так интереснее), то заходим по RDP и ставим Putty/PuttyGen.
PuttyGen нам будет нужен чтобы сконвертировать PEM-ключи от инстансов для Putty. Как известно, она с PEM напрямую не работает.

1. Сохраняем pem-ключи с Amazon куда-нибудь в отдельную папку
2. Открываем PuttyGen (она лежит там же, где и Putty)
3. Нажимаем Load
upload_2017-6-1_9-4-45.png

4. Выбираем наш pem-ключ, ждем ОК
upload_2017-6-1_9-5-38.png

5. Нажимаем Save private key.
6. На предупреждение PuttyGen нажимаем Да.
7. Выбираем куда сохранить. Сохраняем.

Для ubuntu-серверов ничего конвертировать не придётся.

Теперь на хосте создаем подключение к тому хосту, который будет первым в списке туннелей.
В имени хоста указываем ubuntu@host:22
upload_2017-6-1_9-9-32.png


Идем в раздел Connection --> SSH --> Tunnels.
Создаем правило Port Forwarding: L2015:127.0.0.1:3131
upload_2017-6-1_9-16-45.png


Таким образом трафик с порта 2015 сервера USA будет идти на порт 3131 сервера UK
В разделе Auth указываем путь для Private Key (PPK-файл)
Сохраняем конфигурацию и запускаем.

Если всё сделали правильно то легко попадаем на хост UK.


Поскольку у нас строится цепочка и авторизация идет по ключам, то на хосты нужно положить ключ авторизации для следующего сервера:
Т.е. для цепочки --> India --> Japan на UK должен быть ключ для India, а на India должен быть ключ для Japan.
Скинуть файлы проще через WinSCP (он позволяет импортировать конфигурацию и ключи из Putty)
Когда закинули ключи куда нужно, не забываем сделать на каждом хосте
Код:
chmod 400 *.pem

Теперь нам нужно сделать то же, что мы делали через Putty, только на ssh и для следующего хоста.
В консоли пишем:

Код:
sudo ssh -v -L3131:localhost:3232 -i IndiaKey.pem ubuntu@mumbai.compute.amazonaws.com

Таким образом мы перенаправляем весь трафик с 3131 на 3232 уже следующего сервера.
Если всё сделано правильно, то откроется консоль хоста India.
В его же консоли набираем путь к следующему серверу:

Код:
sudo ssh -v -L3232:localhost:1194 -i KeyTokyo.pem ubuntu@japan.compute.amazonaws.com

Перенаправляем трафик с 3232 на 1194 сервера, который у нас является выходной нодой.
Таким образом мы построили Multi-Hop SSH туннель.

На последней ноде нужно поднять OpenVPN-сервер стандартной конфигурации, если этого еще не было сделано. Оставлю самый нормальный англоязычный tutorial по этой
А ниже расскажу по-русски и кратко:
Как создавать сертификаты писать не буду, это не сложно и инструкций полно (см. ссылку выше)

Делаем:
Код:
sudo su
apt-get install -y openvpn
apt-get install iptables-persistant

В папку /etc/openvpn/ копируете файлы CA.crt, CA.key, server.crt, server.key, dh2048.pem и ta.key (если генерировали)

В этой же папке создаем файл конфигурации server.conf
Самый удобный способ, либо создать заранее и скинуть через scp, либо сделать nano server.conf

Код:
port 1194
proto tcp
dev tun

ca ca.crt
cert server.crt
key server.key

dh dh2048.pem

server 10.8.0.0 255.255.255.0

ifconfig-pool-persist ipp.txt
keepalive 10 120

push "redirect-gateway def1"
push "route 0.0.0.0 0.0.0.0"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

duplicate-cn

user nobody
group nogroup

persist-key
persist-tun

status openvpn-status.log

log         /etc/openvpn/openvpn.log
log-append  /etc/openvpn/openvpn.log

verb 5
management localhost 7777

Устанавливаем ip_forward:

Код:
sysctl net.ipv4.ip_forward=1
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Открываем nano /etc/sysctl.conf
Раскомментируем строку net.ipv4.ip_forward=1 и сохраним.

Далее, в консоли пишем:
Код:
modprobe iptable_nat

Затем настроим iptables:
Код:
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Потом отредактируем файл /etc/rc.local, как ниже:
Код:
#!/bin/sh -e
#
# [...]
#

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

exit 0

Запускаем сервер:
Код:
service openvpn start
Сохраняем наши правила iptables:
Код:
service iptables-persistant save

Проверяем, запустился ли OpenVPN. Если да, то должен был подняться интерфейс tun0.
В консоли вводим ifconfig:
upload_2017-6-1_9-59-21.png


и если tun0 поднят, вводим service openvpn status

upload_2017-6-1_9-58-51.png


Если пишет что-то иное, то изучаем /etc/openvpn/openvpn.log
Если tun0 не поднялся (на Amazon точно поднимается), то у вас VPS, не поддерживающая dev tun.

Таким образом, мы направили весь трафик клиента, завернутый в VPN через парочку SSH-туннелей:
Для наглядности вот:

upload_2017-6-1_10-40-32.png


Теперь дело за малым. На клиенте пробуем подключиться через OpenVPN к первому серверу в цепочке (USA):

upload_2017-6-1_10-45-29.png


и тут начинается "магия": хосты начинают пробрасывать трафик через порты, которые мы им указали, ничего не спрашивая и не задавая вопросов:

TCP_CLIENT link remote: [AF_INET] XX.XXX.1X0.1X3:2015
[server] Peer Connection Initiated with [AF_INET] XX.XXX.1X0.1X3:2015
Открытие tun-интерфейса:
Адрес IPv4: IPv6: null MTU: 1500
Маршруты: , ,
Initialization Sequence Completed

Ура. Подключение успешно установилось. Идем на ipleak.net

upload_2017-6-1_13-14-23.png


или whoer.net

upload_2017-6-1_13-14-42.png


Сервис показывает нам адрес из страны Восходящего Солнца, не подозревая, что маршрут наш проходит через всю планету, а главное зашифрован.

Миссия выполнена!


Какие плюсы мы с этого имеем?
1. Анонимность в той степени, которую вообще могут дать туннели.
2. По сравнению с OpenVPN количество туннелей может быть больше, и выше будет скорость
3. Можно свободно строить очень много туннелей, не ковыряя конфиг клиента или сервера, что приходится делать для цепочки OpenVPN.
4. Для андройд не нужен рут, чтобы туннелировать трафик.
5. Все зашифровано. В нашем случаем дважды.

Минусы:
1. сервисы определяют, что вы используете средства анонимизации

И на этом всё! :)

Послесловие:
Для VPN via SSH использование протокола TCP обязательно.
Конфигурация сервера и клиента должна работать на любой другой системе. Я проверял на Windows/Android.
Возможно будут проблемы с соединением OpenVPN с устройств через 3G/4G/5G.
Стабильно работает на Verizon. Нестабильно/невозможно - Мегафон.
Что про нестабильность SSH-туннелей - за месяц ни упал ни один.
Бесплатное пользование AmazonEC2 подразумевает ограничение скорости.

Команду по SSH-туннелированию можно объединить в одну, без необходимости заходить на каждый сервер:
Код:
sudo ssh -v -L3131:localhost:3232 -i IndiaKey.pem ubuntu@mumbai.compute.amazonaws.com -t ssh -v -L3232:localhost:1194 -i KeyTokyo.pem ubuntu@japan.compute.amazonaws.com -t и так далее в зависимости от кол-ва цепочек. + можно написать алиас или скрипт для запуска и прописать его в cron
 
Последнее редактирование модератором:
как говорится, codeby - торт!
Спасибо за старания, с удовольствием почитаю ваши новые статьи.
Удачи с музой)
 
  • Нравится
Реакции: citizen2517
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!