September 23, 2025

Proxy&Tunnel

Проксирование

Proxy-Server

Прокси (proxy), или прокси-сервер — это сервер-посредник между пользователем и ресурсом в сети. Прокси-сервер сообщает целевому ресурсу только информацию о себе и подключается он, а не пользователь.

Proxy-Server работает на прикладном уровне сетевой модели TCP/IP. Это означает, что Proxy-Server работает над протоколами транспортного уровня (например, TCP или UDP), а также над протоколами сетевого уровня (например, IPv4 или IPv6). Прокси-серверы работают по разным протоколам, обеспечивающим связь с ресурсом (например, FTP, HTTP или SSH)

Прокси-серверы в основном функционируют на уровне приложения и в быту, разговаривая о них, имеют ввиду именно это, однако дальше речь пойдет о прокси, которые могут также взаимодействовать с данными на более низких уровнях, например на уровне транспорта (TCP/UDP).

Socks-Proxy

Протокол представляет собой транслятор (что-то вроде прокси-сервера), но в отличие от обычных прокси Socks «сидит» между прикладным и транспортным уровнем в сетевой модели. Он обеспечивает передачу данных одновременно по нескольким протоколам в одном «контейнере» (HTTPS, FTP, SSH, SMTP, IMAP и др.). Он не привязан к конкретному приложению.

SOCKS4 - предназначен для работы через межсетевой экран без аутентификации для приложений типа клиент-сервер. SOCKS-сервер можно рассматривать как межсетевой экран.

SOCKS5 — это несовместимое расширение протокола SOCKS 4. Он добавляет поддержку UDP, доменных имен и адресов IPv6.Использует несколько способов аутентификации:

  • Null authentication – в этом случае для подключения к прокси проходить процедуру аутентификации не нужно;
  • Аутентификация по логину и паролю – соединение устанавливается после введения корректных учетных данных;
  • Аутентификация с помощью GSS-API – как клиент, так и сервер используют методы аутентификации, работающие на уровне ОС.

Shadowsocks

Это протокол, основанный на SOCKS и созданный китайскими пользователями для обхода блокировок интернета. Его особенность — в шифровании. Пользователь сам может указать, какую информацию хочет шифровать, а какую нет.

В результате протокол обеспечивает большую безопасность при передаче информации, чем обычный SOCKS, и лучше обходит блокировки. К тому же трафик маскируется под обычное HTTPS-подключение.

Туннелирование

Введение и термины SSH туннелирования

0.0.0.0, он же «*», он же «пустота» – все адреса IPv4 на локальной машине. Если машина имеет два IP-адреса, а сервер, запущенный на машине, прослушивает 0.0.0.0, он будет доступен на обоих этих IP-адресах.

127.0.0.1 – адрес loopback - петля. Используется для установки соединения клиента с сервером внутри одной машины. Ни один пакет данных, адресованный 127.0.0.1, никогда не покидает компьютер.

SSH-клиент – машина которая хочет куда-то подключиться и инициирует соединение.

SSH-сервер – машина, к которой подключается клиент.

Прокси-сервер SSH – машина, работающая по протоколу SOCKS(4/5) и перенаправляющая трафик из одного порта и/или сети в другой порт и/или сеть. SSH поддерживает соединение по протоколу SOCKS4 и SOCKS5.

Сокет отправителя – совокупность ip-адреса и порта отправителя.

Сокет получателя – совокупность ip-адрес и порта получателя.

Важно помнить, что каждое соединение между SSH-сервером, сокет отправителя и сокет получателя являются отдельным TCP-соединениями (сессиями).

Документация по SSH

Проброс локального порта «ssh -L»

Фактически bind shell через ssh-proxy. Машина на которой исполняется команда работает с чувствительными данными (забирает их у кого-то в своей сети или же генерит на своем localhost), которые надо передать через недоверенную среду.

Схема команды:

ssh -L «X»:«port_x»:«Y»:«port_y» «SSH-сервер»

Откуда направлять - «X»:«port_x»:

«X»:«port_x» – адрес(интерфейс) и порт машины, который мы слушаем. На этой машине мы выполняем команду. В этот адрес и порт будут стучаться и создавать подключения. Подключения могут быть из интернета, а могут быть и из localhost, например, какое-то приложение.

Через что направлять - «SSH-сервер»:

«SSH-сервер» – сервер, через который будет направляться трафик, например доменное имя ssh-сервера в интернете или, например, какой-то сервер имеющий доступ по локальной сети к БД.

Куда направлять - «Y»:«port_y»:

«Y»:«port_y» – адрес и порт куда «SSH-сервер» должен перенаправить соединение. В этот адрес будет перенаправлен трафик. Может на себя, может на другой хост.

Необходимые конфигурации в «SSH-серверe»:

Переадресация TCP

/etc/ssh/sshd_config -> AllowTcpForwarding -> yes

Необходимые конфигурации в «SSH-клиенте»:

При переадресации портов на интерфейсы, отличные от 127.0.0.1, в локальной системе необходимо включить GatewayPorts

/etc/ssh/ssh_config -> GatewayPorts -> yes

Пример 1:

Перенаправление трафика локальной системы на порт удаленного хоста с помощью ssh-сервера:

ssh -L 127.0.0.1:8080:example.org:80 user@ssh-server.com

Эта команда указывает, что соединения с портом 8080 на локальной машине 127.0.0.1 должны быть перенаправлены на хост example.org и порт 80 через ssh-сервер. Трафик между локальной системой и SSH-сервером идет по SSH-туннелю. Трафик между SSH-сервером и example.org — нет. С точки зрения example.org трафик идет от SSH-сервера.

Рис.1

Пример 2:

Следующие команды перенаправляют трафик к example.org:80 через SSH-туннель для подключений на порт 8080 на всех интерфейсах локальной системы

ssh -L 8080:example.org:80 user@ssh-server.com

идентично

ssh -L *:8080:example.org:80 user@ssh-server.com
Рис.2

Это означает, что кто бы не попытался подключиться к нашей локальной машине по порту 8080 по любому из интерфейсов, он будет перенаправлен по SSH-туннелю к SSH-серверу, а оттуда на порт 80 к example.org

Пример 3:

Следующая команда перенаправляет трафик, идущий на адрес локальной машины 192.168.10.10 по порту 5432 (PostgreSQL) через SSH-туннелю к SSH-серверу и далее на адрес 127.0.0.1 и порт 5432.

Другими словами, допустим у нас на машине поднята БД, кто-то к ней подключается, а мы его перенаправляем через SSH-туннель на SSH-сервер, а оттуда на наш localhost тоже на порт 5432.

ssh -L 192.168.10.10:5432:127.0.0.1:5432 user@ssh-server.com
Рис.3

Проброс удаленного порта «ssh -R»

Фактически reverse shell через ssh-proxy. Машина на которой исполняется команда не имеет своего SSH-сервера или не имеет возможности принять входящее соединение SSH из-за NAT или FireWall. Однако если машина имеет возможность подключаться своим SSH-клиентом к удаленному SSH-серверу, то эта команда позволит осуществить проброс портов на стороне SSH-клиента.

Схема команды:

ssh -R «X»:«port_x»:«Y»:«port_y» «SSH-сервер»

Откуда направлять - «X»:«port_x»:

«X»:«port_x» – адрес(интерфейс) и порт на котором «SSH-сервер» будет ждать подключения. Как правило пишут только порт, тогда слушаются все интерфейсы «SSH-серверa».

Через что направлять - «SSH-сервер»:

«SSH-сервер» – сервер, через который будет направляться трафик, например доменное имя ssh-сервера в интернете или, например, какой-то сервер имеющий доступ по локальной сети к БД. К нему мы подключимся своим SSH-клиентом, с которого, будет выполнена команда.

Куда направлять - «Y»:«port_y»:

«Y»:«port_y» – адрес и порт с которым мы установим соединение. Это может быть как localhost, так и удаленный хост. Эта часть выполняется SSH-клиентом на котором и выполняется данная команда.

Как только «X»:«port_x» установит соединение с «SSH-сервером», машина установит соединение с «Y»:«port_y» и пробросит данные между «X»:«port_x» и «Y»:«port_y»

Необходимые конфигурации «SSH-сервера»:

· При переадресации портов на интерфейсы, отличные от 127.0.0.1, в локальной системе необходимо включить GatewayPorts

/etc/ssh/sshd_config -> GatewayPorts -> yes

· Указать каким клиентам разрешен доступ

/etc/ssh/sshd_config -> GatewayPorts clientspecified -> ip_address

Пример 1:

После успешного подключения, на «user@ssh-server.com» со стороны «HOST1» SSH-сервер начинает слушать порт 9999. При подключении «HOST2» к «ssh-server.com» на порт 9999, SSH-клиент на «HOST1» устанавливает соединение со своим localhost на порт 5432 и передает по этому соединению данные, принятые «ssh-server.com» на порт 9999 от «HOST2».

ssh -R 9999:localhost:5432 user@ssh-server.com
Рис.4

Пример 2:

После успешного подключения, на «user@ssh-server.com» со стороны «HOST1» SSH-сервер начинает слушать порт 443 на интерфейсе с адресом 192.168.10.10. При подключении «HOST2» к «ssh-server.com» на порт 443, SSH-клиент на «HOST1» устанавливает соединение со своим localhost на порт 80 и передает по этому соединению данные, принятые «ssh-server.com» на порт 443 от «HOST2».

ssh -R 192.168.10.10:443:localhost:80 user@ssh-server.com
Рис.5

Пример 3:

После успешного подключения, на «user@ssh-server.com» со стороны «HOST1» SSH-сервер начинает слушать порт 80 на интерфейсе с адресом 192.168.10.10. При подключении «HOST2» к «ssh-server.com» на порт 80, SSH-клиент на «HOST1» устанавливает соединение с своим example.com на порт 443 и передает данные, принятые «ssh-server.com» на порт 443 от «HOST2».

ssh -R 192.168.10.10:80:example.org:443 user@ssh-server.com
Рис.6

Динамический проброс портов «ssh -D»

Динамическая переадресация портов даёт возможность создать сокет на локальном компьютере, и пробросить весь трафик на удаленный ssh-сервер. Когда кто-то подсоединяется к указанному порту, соединение перенаправляется на удаленный ssh-сервер, а оттуда по роутам этого ssh-сервера.

Схема команды:

ssh -D «X»:«port_x» «SSH-сервер»

Откуда направлять - «X»:«port_x»:

«X»:«port_x» – адрес(интерфейс) и порт на котором «SSH-сервер» будет ждать подключения. Как правило пишут только порт, тогда слушаются все интерфейсы «SSH-серверa».

Через что направлять - «SSH-сервер»:

«SSH-сервер» – сервер, через который будет направляться трафик, например доменное имя ssh-сервера в интернете или, например, какой-то сервер имеющий доступ по локальной сети к БД. К нему мы подключимся своим SSH-клиентом, с которого, будет выполнена команда.

Необходимые конфигурации «SSH-клиента»:

· При переадресации портов на интерфейсы, отличные от 127.0.0.1, в локальной системе необходимо включить GatewayPorts

/etc/ssh/ssh_config -> GatewayPorts -> yes

Пример 1:

HOST1 не имеет доступа в интернет, но имеет доступ к SSH-серверу, который уже имеет доступ в интернет. HOST1 создает туннель с SSH-сервером и при подключение его браузера на порт 6000, перенаправляет весь трафик на SSH-сервер.

ssh -D 127.0.0.1:6000 user@ssh-server.com
Рис.7

Jump-хосты «ssh -J»

Необходимо добраться до какого-то сервера. Прямого доступа нет, однако знаем, как пробраться через несколько хопов – промежуточных SSH-серверов.

Схема команды:

ssh - J user1@jump_ssh-server1,user2@jump_ssh-server2 user@ssh-server.com
Рис.8

Туннелирование – это процесс упаковки одного сетевого протокола внутри другого для создания безопасного логического канала (туннеля) между двумя точками, часто с целью защиты данных. Проксирование – это действие, при котором прокси-сервер (посредник) обрабатывает запросы клиентов к другим сетевым службам, выступая как шлюз и скрывая IP-адрес клиента. Основное отличие: туннелирование создает зашифрованный канал, а проксирование – это функция посредничества, которая может выполняться без шифрования.