Основи прозорого проксування з використанням 3proxy та iptables/netfilter або як «пустити все через проксі»

У цій статті хотілося б розкрити можливості прозорого проксіювання, яке дозволяє абсолютно непомітно для клієнтів перенаправляти весь або частину трафіку через зовнішні проксі-сервери.

Коли я починав вирішувати це завдання, то зіткнувся з тим, що її реалізація має одну суттєву проблему — протокол HTTPS. У старі добрі часи особливих проблем із прозорим проксуванням HTTP не виникало, але при проксуванні HTTPS браузери повідомляють про втручання у протокол і на цьому щастя закінчується.

У поширених інструкціях до проксі-сервера Squid пропонують навіть згенерувати власний сертифікат і встановити його клієнтам, що повне марення як мінімум нераціонально і виглядає як MITM - атака. Я знаю, що Squid вже щось подібне вміє робити, але мова в цій статті про перевірений та робочий спосіб з використанням 3proxy від шановного 3APA3A.

Далі ми докладно розглянемо процес складання 3proxy з вихідних джерел, його налаштування, повне та вибіркове проксування з використанням NAT, розподіл каналу на декілька зовнішніх проксі-серверів, а також використання роутера та статичних маршрутів. Як ОС використовуємо Debian 9 x64. Починаємо!

Установка 3proxy та запуск звичайного проксі-сервера

1. Встановлюємо ifconfig (з пакета net-tools)
apt-get install net-tools
2. Встановлюємо Midnigth Commander
apt-get install mc
3. У нас зараз 2 інтерфейси:
enp0s3 - зовнішній, дивиться в інтернет
enp0s8 - внутрішній, повинен дивитися в локальну мережу
В інших Debian-based дистрибутивах інтерфейси зазвичай називаються eth0 та eth1.
ifconfig -a

інтерфейсиenp0s3: flags=4163 mtu 1500
inet 192.168.23.11 маска мережі 255.255.255.0 трансляція 192.168.23.255
inet6 fe80::a00:27ff:fec2:bae4 prefixlen 64 scopeid 0x20 ether 08:00:27:c2:ba:e4 txqueuelen 1000 (Ethernet)
Пакети RX 6412 байт 8676619 (8.2 МіБ)
Помилки RX 0 вилучено 0 переповнень 0 кадр 0
Пакети TX 1726 байт 289128 (282.3 КіБ)
Помилки TX 0 викинуто 0 переповнень 0 несучої 0 колізій 0

enp0s8: flags=4098 mtu 1500
ether 08:00:27:79:a7:e3 txqueuelen 1000 (Ethernet)
Пакети RX 0 байт 0 (0.0 Б)
Помилки RX 0 вилучено 0 переповнень 0 кадр 0
TX packets 0 bytes 0 (0.0 B)
Помилки TX 0 викинуто 0 переповнень 0 несучої 0 колізій 0

lo: flags=73 mtu 65536
inet 127.0.0.1 маска мережі 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1 (Local Loopback)
Пакети RX 0 байт 0 (0.0 Б)
Помилки RX 0 вилучено 0 переповнень 0 кадр 0
TX packets 0 bytes 0 (0.0 B)
Помилки TX 0 викинуто 0 переповнень 0 несучої 0 колізій 0

Інтерфейс enp0s8 зараз не використовується, ми його включимо, коли захочемо використовувати конфігурацію Proxy NAT або NAT. Саме тоді логічним буде призначити йому статичний IP.

4. Приступимо до встановлення 3proxy

4.1 Встановлення базових пакетів для компіляції 3proxy із вихідних джерел

root@debian9:~# apt-get install build-essential libevent-dev libssl-dev -y

4.2. Створимо папку для завантаження архіву з вихідними джерелами

root@debian9:~# mkdir -p /opt/proxy

4.3. Перейдемо до цієї папки

root@debian9:~# cd /opt/proxy

4.4. Тепер завантажимо останній пакет 3proxy. На момент написання статті останньою стабільною версією була 0.8.12 (18/04/2018) Скачаємо її з офіційного сайту

root@debian9:/opt/proxy# wget https://github.com/z3APA3A/3proxy/archive/0.8.12.tar.gz

4.5. Розпакуємо завантажений архів

root@debian9:/opt/proxy# tar zxvf 0.8.12.tar.gz

4.6. Переходимо в розпакований каталог для збирання програми

root@debian9:/opt/proxy# cd 3proxy-0.8.12

4.7. Далі потрібно додати рядок до файлу заголовка, щоб наш сервер був повністю анонімним (реально працює, все перевірено, ip клієнтів ховаються)

root@debian9:/opt/proxy/3proxy-0.8.12# nano +29 src/proxy.h

Додаємо рядок

#define ANONYMOUS 1

Натискаємо Ctrl+x та Enter, щоб зберегти зміни.

4.8. Приступимо до збирання програми

root@debian9:/opt/proxy/3proxy-0.8.12# make -f Makefile.Linux

Makelogmake[2]: Leaving directory '/opt/proxy/3proxy-0.8.12/src/plugins/TransparentPlugin'
make[1]: Leaving directory '/opt/proxy/3proxy-0.8.12/src'

Помилок немає, продовжуємо.

4.9. Встановимо програму в систему

root@debian9:/opt/proxy/3proxy-0.8.12# make -f Makefile.Linux install

4.10. Переходимо до кореневого каталогу та перевіряємо, куди встановилася програма

root@debian9:/opt/proxy/3proxy-0.8.12# cd ~/
root@debian9:~# whereis 3proxy

3proxy: /usr/local/bin/3proxy /usr/local/etc/3proxy

4.11. Створимо папку для конфігураційних файлів та логів у домашньому каталозі користувача

root@debian9:~# mkdir -p /home/joke/proxy/logs

4.12. Переходимо в каталог, де має бути конфіг

root@debian9:~# cd /home/joke/proxy/

4.13. Створюємо порожній файл і копіюємо туди конфіг

root@debian9:/home/joke/proxy# cat > 3proxy.conf

3proxy.confдемон
pidfile /home/joke/proxy/3proxy.pid
nserver 8.8.8.8
nscache 65536
users tester:CL:1234
timeouts 1 5 30 60 180 1800 16 60
log /home/joke/proxy/logs/3proxy.log D
logformat "- +_L%t.%. %N.%p %E %U %C:%c %R:%r %O %I %h %T"
повернути 3
auth strong
врівень
allow tester
socks -p3128
proxy-p8080

Для збереження натискаємо Ctrl+Z

4.14. Створимо pid - файл, щоб не було помилок під час запуску.

root@debian9:/home/joke/proxy# cat > 3proxy.pid

Для збереження натискаємо Ctrl+Z

4.15. Запускаємо проксі-сервер!

root@debian9:/home/joke/proxy# 3proxy /home/joke/proxy/3proxy.conf

4.16. Подивимося, чи слухає сервер порти

root@debian9:~/home/joke/proxy# netstat -nlp

netstat logActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 504/3proxy
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 338/sshd
tcp 0 0 0.0.0.0:3128 0.0.0.0:* LISTEN 504/3proxy
tcp6 0 0 :::22 :::* LISTEN 338/sshd
udp 0 0 0.0.0.0:68 0.0.0.0:* 352/dhclient

Як і було написано в конфізі, веб-проксі слухає у нас порт 8080, Socks5-проксі - 3128.

4.17. Для автозапуску проксі після перезавантаження потрібно додати її в cron.

root@debian9:/home/joke/proxy# crontab -e

Додаємо рядок

@reboot /usr/local/bin/3proxy /home/joke/proxy/3proxy.conf

Натискаємо Enter, тому що cron має бачити символ кінця рядка та зберігаємо файл.

Повинне бути повідомлення про встановлення нового crontab-а.

crontab: installing new crontab

4.18. Перезавантажимо систему та спробуємо підключитися через браузер до проксі. Для перевірки використовуємо браузер Firefox (для веб-проксі) та доповнення FoxyProxy для socks5 з автентифікацією.

root@debian9:/home/joke/proxy# reboot

4.19. Перевіривши роботу проксі після перезавантаження, можна переглянути логи. На цьому налаштування проксі-сервера завершено.

3 proxy log1542573996.018 PROXY.8080 00000 tester 192.168.23.10:50915 217.12.15.54:443 1193 6939 0 CONNECT_ads.yahoo.com/443_HT
1542574289.634 SOCK5.3128 00000 tester 192.168.23.10:51193 54.192.13.69:443 0 0 0 CONNECT_normandy.cdn.mozilla.net:443

Налаштування та запуск конфігурації Transparent Proxy NAT

У цій конфігурації всі пристрої внутрішньої мережі прозоро працюватимуть в інтернеті через віддалений проксі-сервер. Абсолютно всі tcp-з'єднання будуть перенаправлятися в один або кілька (реально розширює ширину каналу, приклад конфігурації №2!) проксі-серверів. Служба DNS використовуватиме можливості 3proxy (dnspr). UDP назовні "ходити" не буде, тому що ми поки не використовуємо механізм forward (за замовчуванням відключений в ядрі Linux).

1. Настав час увімкнути інтерфейс enp0s8

root@debian9:~# nano /etc/network/interfaces

/etc/network/interfaces file# Цей файл описує мережеві інтерфейси, що перебувають у вашій системі
# Активоване і як до них. Для отримання додаткової інформації див інтерфейсів (5).

source /etc/network/interfaces.d/*

# Замикання мережевий інтерфейс
автомобіль
IFACE от інет замикання

# Основний мережевий інтерфейс
allow-hotplug enp0s3
iface enp0s3 inet dhcp

# The secondary network interface
allow-hotplug enp0s8
iface enp0s8 inet static
адреса 192.168.201.254
Маска 255.255.255.0

Тут ми призначили інтерфейсу enp0s8 статичну адресу 192.168.201.254 та маску 255.255.255.0
Зберігаємо конфіг Ctrl+X та перезавантажуємося

root@debian9:~# reboot

2. Перевіряємо інтерфейси

root@debian9:~# ifconfig

ifconfig logenp0s3: flags=4163 mtu 1500
inet 192.168.23.11 маска мережі 255.255.255.0 трансляція 192.168.23.255
inet6 fe80::a00:27ff:fec2:bae4 prefixlen 64 scopeid 0x20 ether 08:00:27:c2:ba:e4 txqueuelen 1000 (Ethernet)
RX packets 61 bytes 7873 (7.6 KiB)
Помилки RX 0 вилучено 0 переповнень 0 кадр 0
Пакети TX 65 байт 10917 (10.6 КіБ)
Помилки TX 0 викинуто 0 переповнень 0 несучої 0 колізій 0

enp0s8: flags=4163 mtu 1500
inet 192.168.201.254 маска мережі 255.255.255.0 трансляція 192.168.201.255
inet6 fe80::a00:27ff:fe79:a7e3 prefixlen 64 scopeid 0x20 ether 08:00:27:79:a7:e3 txqueuelen 1000 (Ethernet)
Пакети RX 0 байт 0 (0.0 Б)
Помилки RX 0 вилучено 0 переповнень 0 кадр 0
TX packets 8 bytes 648 (648.0 B)
Помилки TX 0 викинуто 0 переповнень 0 несучої 0 колізій 0

lo: flags=73 mtu 65536
inet 127.0.0.1 маска мережі 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1 (Local Loopback)
Пакети RX 0 байт 0 (0.0 Б)
Помилки RX 0 вилучено 0 переповнень 0 кадр 0
TX packets 0 bytes 0 (0.0 B)
Помилки TX 0 викинуто 0 переповнень 0 несучої 0 колізій 0

3. Все вийшло, тепер потрібно налаштувати 3proxy для прозорого проксіювання.

root@debian9:~# cd /home/joke/proxy/
root@debian9:/home/joke/proxy# cat > 3proxytransp.conf

Приклад конфігурації прозорого проксі-сервера №1демон
pidfile /home/joke/proxy/3proxy.pid
nserver 8.8.8.8
nscache 65536
timeouts 1 5 30 60 180 1800 16 60
log /home/joke/proxy/logs/3proxy.log D
logformat "- +_L%t.%. %N.%p %E %U %C:%c %R:%r %O %I %h %T"
повернути 3
врівень
auth iponly
dnspr
allow *
parent 1000 socks5 IP_АДРЕСА_ЗОВНІШНЬОГО_ПРОКСІ 3128 tester 1234
plugin /opt/proxy/3proxy-0.8.12/src/TransparentPlugin.ld.so transparent_plugin
tcppm -i0.0.0.0 888 127.0.0.1 11111

4. Тепер запускаємо 3proxy з новим конфігом
root@debian9:/home/joke/proxy# /usr/local/bin/3proxy /home/joke/proxy/3proxytransp.conf

5. Знову додамо до crontab
root@debian9:/home/joke/proxy# crontab -e
@reboot /usr/local/bin/3proxy /home/joke/proxy/3proxytransp.conf

6. Подивимося, що тепер слухає наш проксі
root@debian9:~# netstat -nlp

netstat logActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 349/sshd
tcp 0 0 0.0.0.0:888 0.0.0.0:* LISTEN 354/3proxy
tcp6 0 0 :::22 :::* LISTEN 349/sshd
udp 0 0 0.0.0.0:53 0.0.0.0:* 354/3proxy
udp 0 0 0.0.0.0:68 0.0.0.0:* 367/dhclient

7. Тепер проксі готовий приймати будь-які TCP-з'єднання на порту 888, DNS на порту 53, щоб потім їх перенаправити у віддалений socks5 - проксі та DNS Google 8.8.8.8. Нам залишилося налаштувати правила netfilter (iptables) та DHCP для видачі адрес.

8. Встановимо пакет iptables-persistent та dhcpd

root@debian9:~# apt-get install iptables-persistent isc-dhcp-server

9. Правимо файл запуску dhcpd
root@debian9:~# nano /etc/dhcp/dhcpd.conf

dhcpd.conf# dhcpd.conf
#
# Sample configuration file for ISC dhcpd
#

# option definitions common to all supported networks…
option domain-name "example.org";
параметр Domain-name-servers ns1.example.org, ns2.example.org;

час оренди за замовчуванням 600;
максимальний час оренди 7200;

ddns-update-style none;

# Якщо цей DHCP-сервер є офіційним DHCP-сервером для локального
# network, the authoritative directive should be uncommented.

авторитетний;

# A slightly different configuration for an internal subnet.
підмережа 192.168.201.0 маска мережі 255.255.255.0 {
діапазон 192.168.201.10 192.168.201.250;
параметр доменні сервери імен 192.168.201.254;
опціональні маршрутизатори 192.168.201.254;
опція трансляція-адреса 192.168.201.255;
час оренди за замовчуванням 600;
максимальний час оренди 7200;
}

11. Перезавантажуємося та перевіряємо службу на порту 67
root@debian9:~# reboot
root@debian9:~# netstat -nlp

netstat logActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 389/sshd
tcp 0 0 0.0.0.0:888 0.0.0.0:* LISTEN 310/3proxy
tcp6 0 0 :::22 :::* LISTEN 389/sshd
udp 0 0 0.0.0.0:20364 0.0.0.0:* 393/dhcpd
udp 0 0 0.0.0.0:53 0.0.0.0:* 310/3proxy
udp 0 0 0.0.0.0:67 0.0.0.0:* 393/dhcpd
udp 0 0 0.0.0.0:68 0.0.0.0:* 405/dhclient
udp6 0 0 :::31728 :::* 393/dhcpd
raw 0 0 0.0.0.0:1 0.0.0.0:* 393/dhcpd

12. Залишилося перенаправити всі tcp запити на порт 888 і зберегти правило в iptables

root@debian9:~# iptables -t nat -A PREROUTING -s 192.168.201.0/24 -p tcp -j REDIRECT --to-ports 888

root@debian9:~# iptables-save > /etc/iptables/rules.v4

13. Для розширення лінії каналу можна використовувати відразу кілька проксі-серверів. Загальна сума має бути 1000. Нові з'єднання встановлюються з ймовірністю 0.2, 0.2, 0.2, 0.2, 0,1, 0,1 до зазначених проксі-серверів.

Примітка: якщо у нас web-проксі, то замість socks5 потрібно писати connect, якщо socks4, то socks4 (socks4 НЕ ПІДТРИМУЄ АВТОРИЗАЦІЮ ЛОГІН/ПАРОЛЬ!)

Приклад конфігурації прозорого проксі-сервера №2демон
pidfile /home/joke/proxy/3proxy.pid
nserver 8.8.8.8
nscache 65536
maxconn 500
timeouts 1 5 30 60 180 1800 16 60
log /home/joke/proxy/logs/3proxy.log D
logformat "- +_L%t.%. %N.%p %E %U %C:%c %R:%r %O %I %h %T"
повернути 3
врівень
auth iponly
dnspr
allow *

parent 200 socks5 IP_АДРЕСА_ЗОВНІШНЬОГО_ПРОКСІ№1 3128 tester 1234
parent 200 socks5 IP_АДРЕСА_ЗОВНІШНЬОГО_ПРОКСІ№2 3128 tester 1234
parent 200 socks5 IP_АДРЕСА_ЗОВНІШНЬОГО_ПРОКСІ№3 3128 tester 1234
parent 200 socks5 IP_АДРЕСА_ЗОВНІШНЬОГО_ПРОКСІ№4 3128 tester 1234
parent 100 socks5 IP_АДРЕСА_ЗОВНІШНЬОГО_ПРОКСІ№5 3128 tester 1234
parent 100 socks5 IP_АДРЕСА_ЗОВНІШНЬОГО_ПРОКСІ№6 3128 tester 1234

plugin /opt/proxy/3proxy-0.8.12/src/TransparentPlugin.ld.so transparent_plugin
tcppm -i0.0.0.0 888 127.0.0.1 11111

Налаштування та запуск конфігурації NAT + Transparent Proxy

У цій конфігурації ми будемо використовувати звичайний механізм NAT з вибірковим або повним прозорим проксіюванням окремих адрес або підмереж. Користувачі внутрішньої мережі працюватимуть з певними сервісами/підмережами, навіть не здогадуючись, що вони працюють через проксі. Всі https з'єднання працюють чудово, ніяких сертифікатів генерувати/підмінювати не потрібно.

Спочатку визначимося, які підмережі/сервіси ми хочемо проксирувати. Припустимо, зовнішні проксі-сервера знаходяться там, де працює такий сервіс, як pandora.com. Тепер залишилося визначити його підмережі/адреси.

1. Пінгуємо

root@debian9:~# ping pandora.com
PING pandora.com (208.85.40.20) 56(84) bytes of data.

2. Набираємо у гугле BGP 208.85.40.20

Переходимо на сайт bgp.he.net/net/208.85.40.0/24#_netinfo
Видно, що шукаю підсіти це AS40428 Pandora Media, Inc

bgp.he.net/net/208.85.40.0/24#_netinfo

Відкриваємо префікси v4

bgp.he.net/AS40428#_prefixes

Ось і шукані підмережі!

199.116.161.0/24
199.116.162.0/24
199.116.164.0/23
199.116.164.0/24
199.116.165.0/24
208.85.40.0/24
208.85.41.0/24
208.85.42.0/23
208.85.42.0/24
208.85.43.0/24
208.85.44.0/24
208.85.46.0/23
208.85.46.0/24
208.85.47.0/24

3. Для зменшення кількості підмереж потрібно виконати агрегацію. Переходимо на сайт ip-calculator.ru/aggregate та копіюємо туди наш список. Як результат – 6 підмереж замість 14-ти.

199.116.161.0/24
199.116.162.0/24
199.116.164.0/23
208.85.40.0/22
208.85.44.0/24
208.85.46.0/23

4. Очищаємо правила iptables

root@debian9:~# iptables -F
root@debian9:~# iptables -X
root@debian9:~# iptables -t nat -F
root@debian9:~# iptables -t nat -X

Включаємо механізм forward та NAT

root@debian9:~# echo 1 > /proc/sys/net/ipv4/ip_forward
root@debian9:~# iptables -A FORWARD -i enp0s3 -o enp0s8 -j ACCEPT
root@debian9:~# iptables -A FORWARD -i enp0s8 -o enp0s3 -j ACCEPT
root@debian9:~# iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.201.0/24 -j MASQUERADE

Щоб forward був увімкнений постійно після перезавантаження змінимо файл

root@debian9:~# nano /etc/sysctl.conf

І розкоментуємо рядок

net.ipv4.ip_forward = 1

Ctrl+X для збереження файлу

5. Завертаємо підмережі pandora.com у проксі

root@debian9:~# iptables -t nat -A PREROUTING -s 192.168.201.0/24 -d 199.116.161.0/24,199.116.162.0/24,199.116.164.0/23,208.85.40.0/22,208.85.44.0/24,208.85.46.0/23 -p tcp -j REDIRECT --to-ports 888

6. Збережемо правила

root@debian9:~# iptables-save > /etc/iptables/rules.v4

Налаштування та запуск конфігурації Transparent Proxy via router

У цій конфігурації прозорий проксі-сервер може бути окремим ПК або віртуальною машиною за домашнім/корпоративним роутером. Достатньо прописати статичні маршрути на роутері або пристроях і вся підмережа використовуватиме проксі без необхідності будь-яких додаткових налаштувань.

ВАЖЛИВО! Необхідно, щоб наш шлюз отримував статичний IP від ​​роутера, або налаштований на статику сам.

1. Налаштовуємо статичну адресу шлюзу (адаптер enp0s3)

root@debian9:~# nano /etc/network/interfaces

/etc/network/interfaces file# Цей файл описує мережеві інтерфейси, що перебувають у вашій системі
# Активоване і як до них. Для отримання додаткової інформації див інтерфейсів (5).

source /etc/network/interfaces.d/*

# Замикання мережевий інтерфейс
автомобіль
IFACE от інет замикання

# Основний мережевий інтерфейс
allow-hotplug enp0s3
iface enp0s3 inet static
адреса 192.168.23.2
Маска 255.255.255.0
Шлюз 192.168.23.254

# The secondary network interface
allow-hotplug enp0s8
iface enp0s8 inet static
адреса 192.168.201.254
Маска 255.255.255.0

2. Дозволяємо пристроям із підмережі 192.168.23.0/24 використовувати проксування

root@debian9:~# iptables -t nat -A PREROUTING -s 192.168.23.0/24 -d 199.116.161.0/24,199.116.162.0/24,199.116.164.0/23,208.85.40.0/22,208.85.44.0/24,208.85.46.0/23 -p tcp -j REDIRECT --to-ports 888

3. Збережемо правила
root@debian9:~# iptables-save > /etc/iptables/rules.v4

4. Пропишемо підмережі на роутері

Router network list199.116.161.0 255.255.255.0 192.168.23.2
199.116.162.0 255.255.255.0 192.168.23.2
199.116.164.0 255.255.254.0 192.168.23.2
208.85.40.0 255.255.252.0 192.168.23.2
208.85.44.0 255.255.255.0 192.168.23.2
208.85.46.0 255.255.254.0 192.168.23.2

Використані матеріали/ресурси

1. Офіційний сайт програми 3proxy 3proxy.ru

2. Інструкція з встановлення 3proxy з вихідних джерел www.ekzorchik.ru/2015/02/how-to-take-your-socks-proxy

3. Гілка розробника 3proxy на GitHub github.com/z3APA3A/3proxy/issues/274

Джерело: habr.com

Додати коментар або відгук