Основи на прозрачно проксиране с 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 интерфейсите обикновено се наричат eth0 и eth1.
ifconfig -a

Интерфейсиenp0s3: flags=4163 mtu 1500
inet 192.168.23.11 netmask 255.255.255.0 broadcast 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 MiB)
RX грешки 0 пропуснати 0 надвишени 0 рамка 0
TX пакети 1726 байта 289128 (282.3 KiB)
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 B)
RX грешки 0 пропуснати 0 надвишени 0 рамка 0
TX пакети 0 байта 0 (0.0 B)
TX грешки 0 пропуснати 0 надвишени 0 носител 0 сблъсъци 0

lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1 (Локален Loopback)
RX пакети 0 байта 0 (0.0 B)
RX грешки 0 пропуснати 0 надвишени 0 рамка 0
TX пакети 0 байта 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). Ще я свалим от официалния сайт на 3proxy.

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]: Напуска директорията '/opt/proxy/3proxy-0.8.12/src/plugins/TransparentPlugin'
make[1]: Напуска директорията '/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:~# 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.confdaemon
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"
rotate 3
auth strong
flush
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 логАктивни интернет връзки (само сървъри)
Протокол Recv-Q Send-Q Локален адрес Чужд адрес Състояние PID/име на програмата
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: инсталиране на нов 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_HTTP/1.1
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# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug enp0s3
iface enp0s3 inet dhcp

# The secondary network interface
allow-hotplug enp0s8
iface enp0s8 inet static
address 192.168.201.254
netmask 255.255.255.0

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

root@debian9:~# рестартирай

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

root@debian9:~# ifconfig

ifconfig логenp0s3: flags=4163 mtu 1500
inet 192.168.23.11 netmask 255.255.255.0 broadcast 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 packets 65 bytes 10917 (10.6 KiB)
TX грешки 0 пропуснати 0 надвишени 0 носител 0 сблъсъци 0

enp0s8: flags=4163 mtu 1500
inet 192.168.201.254 netmask 255.255.255.0 broadcast 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 B)
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 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1 (Локален Loopback)
RX пакети 0 байта 0 (0.0 B)
RX грешки 0 пропуснати 0 надвишени 0 рамка 0
TX пакети 0 байта 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

Примерна конфигурация на прозрачен прокси-сървър №1daemon
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"
rotate 3
flush
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 логАктивни интернет връзки (само сървъри)
Протокол Recv-Q Send-Q Локален адрес Чужд адрес Състояние PID/име на програмата
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";
option domain-name-servers ns1.example.org, ns2.example.org;

default-lease-time 600;
max-lease-time 7200;

ddns-update-style none;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.

authoritative;

# A slightly different configuration for an internal subnet.
subnet 192.168.201.0 netmask 255.255.255.0 {
range 192.168.201.10 192.168.201.250;
option domain-name-servers 192.168.201.254;
option routers 192.168.201.254;
option broadcast-address 192.168.201.255;
default-lease-time 600;
max-lease-time 7200;
}

11. Рестартираме и проверяваме услугата на порт 67
root@debian9:~# рестартирай
root@debian9:~# netstat -nlp

netstat логАктивни интернет връзки (само сървъри)
Протокол Recv-Q Send-Q Локален адрес Чужд адрес Състояние PID/име на програмата
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 НЕ ПОДДЪРЖА ВХОД С ПОЛЬЗВАТЕЛСКО И ПАРОЛА!)

Пример за конфигурация на прозрачен прокси сървър №2daemon
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"
rotate 3
flush
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 + Прозрачен прокси

В тази конфигурация ще използваме обикновен механизъм NAT с изборно или пълно прозрачно проксиране на определени адреси или подмрежи. Потребителите на вътрешната мрежа ще работят с определени услуги/подмрежи, дори да не подозират, че работят през прокси. Всички https връзки работят отлично, не е необходимо генерирането/заменянето на сертификати.

Първо да уточним кои подмрежи/услуги искаме да проксируем. Да предположим, че външните прокси сървъри се намират там, където работи такъв сервис, като pandora.com. Сега остава да определим подмрежите/адресите му.

1. Пингуем

root@debian9:~# ping pandora.com
PING pandora.com (208.85.40.20) 56(84) байта данни.

2. Набираме в Google 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 чрез рутер

В тази конфигурация прозрачният прокси сървър може да бъде отделен компютър или виртуална машина зад домашен/корпоративен рутер. Достатъчно е да зададете статични маршрути на рутера или устройствата и цялата подмрежа ще използва проксито без необходимост от допълнителни настройки.

ВАЖНО! Необходимо е нашият шлюз да получава статичен IP от рутера или да бъде настроен сам на статичен IP.

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

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

/etc/network/interfaces file# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug enp0s3
iface enp0s3 inet static
address 192.168.23.2
netmask 255.255.255.0
gateway 192.168.23.254

# The secondary network interface
allow-hotplug enp0s8
iface enp0s8 inet static
address 192.168.201.254
netmask 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

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster