W tym artykule chciałbym omówić możliwości przezroczystego proxy, które umożliwia niewidoczne dla klientów przekierowywanie całego lub części ruchu przez zewnętrzne serwery proxy.
Kiedy zaczynałem rozwiązywać to zadanie, natknąłem się na jedną poważną przeszkodę — protokoł HTTPS. W dawnych czasach nie było większych problemów z przezroczystym proxy HTTP, ale przy proxy HTTPS przeglądarki informują o ingerencji w protokół i na tym kończy się przyjemność.
W popularnych instrukcjach dotyczących serwera proxy Squid proponuje się nawet wygenerowanie własnego certyfikatu i zainstalowanie go na komputerach klientów, co jest całkowicie absurdalne, a przynajmniej nieefektywne i wygląda jak atak MITM. Wiem, że Squid już coś podobnego potrafi, ale w tym artykule mówimy o sprawdzonym i działającym sposobie z użyciem 3proxy uznawanego za efektywny przez 3APA3A.
Następnie szczegółowo omówimy proces budowy 3proxy z źródeł, jego konfigurację, pełne i selektywne proxy z użyciem NAT, podział pasma na kilka zewnętrznych serwerów proxy, a także wykorzystanie routera i statycznych tras. Jako system operacyjny użyjemy Debian 9 x64. Zaczynamy!
Instalacja 3proxy i uruchomienie standardowego serwera proxy
1. Instalujemy ifconfig (z pakietu net-tools)
apt-get install net-tools
2. Instalujemy Midnight Commander
apt-get install mc
3. Obecnie mamy 2 interfejsy:
enp0s3 — zewnętrzny, łączy się z internetem
enp0s8 — wewnętrzny, powinien łączyć się z siecią lokalną
W innych dystrybucjach opartych na Debianie interfejsy są zazwyczaj nazywane eth0 i eth1.
ifconfig -a
Interfejsyenp0s3: 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 pakiety 6412 bajty 8676619 (8.2 MiB)
RX błędy 0 utracone 0 przepełnienia 0 ramki 0
TX pakiety 1726 bajty 289128 (282.3 KiB)
TX błędy 0 utracone 0 przepełnienia 0 nośnika 0 kolizje 0
enp0s8: flags=4098 mtu 1500
ether 08:00:27:79:a7:e3 txqueuelen 1000 (Ethernet)
RX pakiety 0 bajty 0 (0.0 B)
RX błędy 0 utracone 0 przepełnienia 0 ramki 0
TX pakiety 0 bajty 0 (0.0 B)
TX błędy 0 utracone 0 przepełnienia 0 nośnika 0 kolizje 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 (Local Loopback)
RX pakiety 0 bajty 0 (0.0 B)
RX błędy 0 utracone 0 przepełnienia 0 ramki 0
TX pakiety 0 bajty 0 (0.0 B)
TX błędy 0 utracone 0 przepełnienia 0 nośnika 0 kolizje 0
Interfejs enp0s8 nie jest obecnie używany, uruchomimy go, gdy zechcemy skorzystać z konfiguracji Proxy NAT lub NAT. Wtedy zasadne będzie przypisanie mu statycznego adresu IP.
4. Przechodzimy do instalacji 3proxy
4.1 Instalacja podstawowych pakietów do kompilacji 3proxy z kodu źródłowego
root@debian9:~# apt-get install build-essential libevent-dev libssl-dev -y
4.2. Utworzymy folder do pobrania archiwum z kodem źródłowym
root@debian9:~# mkdir -p /opt/proxy
4.3. Przechodzimy do tego folderu
root@debian9:~# cd /opt/proxy
4.4. Teraz pobierzemy najnowszą wersję 3proxy. W momencie pisania artykułu ostatnią stabilną wersją była 0.8.12 (18/04/2018). Pobrać ją można z oficjalnej strony 3proxy
root@debian9:/opt/proxy# wget https://github.com/z3APA3A/3proxy/archive/0.8.12.tar.gz
4.5. Rozpakowujemy pobrane archiwum
root@debian9:/opt/proxy# tar zxvf 0.8.12.tar.gz
4.6. Przechodzimy do rozpakowanego katalogu, aby zbudować program
root@debian9:/opt/proxy# cd 3proxy-0.8.12
4.7. Następnie musimy dodać linię do pliku nagłówkowego, aby nasz serwer był całkowicie anonimowy (działa sprawdzono, adresy IP klientów są ukryte)
root@debian9:/opt/proxy/3proxy-0.8.12# nano +29 src/proxy.h
Dodajemy linię
#define ANONYMOUS 1
Naciskamy Ctrl+x i Enter, aby zapisać zmiany.
4.8. Przechodzimy do kompilacji programu
root@debian9:/opt/proxy/3proxy-0.8.12# make -f Makefile.Linux
Makelogmake[2]: Opuściłem katalog ‘/opt/proxy/3proxy-0.8.12/src/plugins/TransparentPlugin’
make[1]: Opuściłem katalog ‘/opt/proxy/3proxy-0.8.12/src’
Brak błędów, kontynuujemy.
4.9. Zainstalujemy program w systemie
root@debian9:/opt/proxy/3proxy-0.8.12# make -f Makefile.Linux install
4.10. Przechodzimy do katalogu głównego i sprawdzamy, gdzie zainstalowano program
root@debian9:~/opt/proxy/3proxy-0.8.12# cd ~/
root@debian9:~# whereis 3proxy
3proxy: /usr/local/bin/3proxy /usr/local/etc/3proxy
4.11. Utworzymy folder na pliki konfiguracyjne i logi w katalogu domowym użytkownika
root@debian9:~# mkdir -p /home/joke/proxy/logs
4.12. Przechodzimy do katalogu, gdzie powinien być plik konfiguracyjny
root@debian9:~# cd /home/joke/proxy/
4.13. Tworzymy pusty plik i kopiujemy tam konfigurację
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
Aby zapisać, naciskamy Ctrl + Z
4.14. Tworzymy plik pid, żeby uniknąć błędów przy uruchomieniu.
root@debian9:/home/joke/proxy# cat > 3proxy.pid
Aby zapisać, naciskamy Ctrl + Z
4.15. Uruchamiamy serwer proxy!
root@debian9:/home/joke/proxy# 3proxy /home/joke/proxy/3proxy.conf
4.16. Sprawdzamy, czy serwer nasłuchuje na portach
root@debian9:~/home/joke/proxy# netstat -nlp
log netstatAktywne połączenia internetowe (tylko serwery)
Proto Recv-Q Send-Q Adres lokalny Adres zdalny Stan PID/Nazwa programu
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
Zgodnie z tym, co podano w konfiguracji, nasz proxy webowy nasłuchuje na porcie 8080, a proxy Socks5 – na 3128.
4.17. Aby automatycznie uruchomić usługę proxy po ponownym uruchomieniu, należy dodać ją do crontaba.
root@debian9:~ /home/joke/proxy# crontab -e
Dodajemy linię
@reboot /usr/local/bin/3proxy /home/joke/proxy/3proxy.conf
Naciskamy Enter, ponieważ cron musi zobaczyć znak końca linii i zapisujemy plik.
Powinno pojawić się сообщение о установке нового crontab-a.
crontab: instalacja nowego crontab-a
4.18. Zrestartujemy system i spróbujemy połączyć się z proxy za pomocą przeglądarki. Do testów użyjemy przeglądarki Firefox (dla web-proxy) i dodatku FoxyProxy dla socks5 z autoryzacją.
root@debian9:/home/joke/proxy# reboot
4.19. Po sprawdzeniu działania proxy po restarcie, można przejrzeć logi. Na tym kończy się konfiguracja serwera proxy.
3 log proxy1542573996.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
Konfiguracja i uruchomienie Transparent Proxy NAT
W tej konfiguracji wszystkie urządzenia w sieci wewnętrznej będą działać przez zdalny serwer proxy. Wszystkie połączenia tcp będą przekierowywane do jednego lub kilku (co naprawdę zwiększa przepustowość, przykład konfiguracji nr 2!) serwerów proxy. Usługa DNS będzie wykorzystywać możliwości 3proxy (dnspr). UDP nie będzie dostępne, ponieważ obecnie nie używamy mechanizmu forward (domyślnie wyłączony w jądrze Linux).
1. Nadszedł czas na włączenie interfejsu 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
Tutaj przypisaliśmy interfejsowi enp0s8 statyczny adres 192.168.201.254 oraz maskę 255.255.255.0.
Zapisujemy konfigurację Ctrl+X i restartujemy.
root@debian9:~# reboot
2. Sprawdzamy interfejsy
root@debian9:~# ifconfig
ifconfig logenp0s3: 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 błędy 0 utracone 0 przepełnienia 0 ramki 0
TX packets 65 bytes 10917 (10.6 KiB)
TX błędy 0 utracone 0 przepełnienia 0 nośnika 0 kolizje 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 pakiety 0 bajty 0 (0.0 B)
RX błędy 0 utracone 0 przepełnienia 0 ramki 0
TX packets 8 bytes 648 (648.0 B)
TX błędy 0 utracone 0 przepełnienia 0 nośnika 0 kolizje 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 (Local Loopback)
RX pakiety 0 bajty 0 (0.0 B)
RX błędy 0 utracone 0 przepełnienia 0 ramki 0
TX pakiety 0 bajty 0 (0.0 B)
TX błędy 0 utracone 0 przepełnienia 0 nośnika 0 kolizje 0
3. Udało się, teraz musimy skonfigurować 3proxy do przezroczystego proxy.
root@debian9:~# cd /home/joke/proxy/
root@debian9:/home/joke/proxy# cat > 3proxytransp.conf
Przykład konfiguracji serwera proxy nr 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 ADRES_IP_ZEWNETRZNEGO_PROXY 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. Teraz uruchamiamy 3proxy z nową konfiguracją
root@debian9:/home/joke/proxy# /usr/local/bin/3proxy /home/joke/proxy/3proxytransp.conf
5. Ponownie dodajemy do crontab
root@debian9:~ /home/joke/proxy# crontab -e
@reboot /usr/local/bin/3proxy /home/joke/proxy/3proxytransp.conf
6. Sprawdzimy, co teraz nasz proxy nasłuchuje
root@debian9:~# netstat -nlp
log netstatAktywne połączenia internetowe (tylko serwery)
Proto Recv-Q Send-Q Adres lokalny Adres zdalny Stan PID/Nazwa programu
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. Teraz proxy jest gotowe do przyjmowania wszelkich połączeń TCP na porcie 888, a DNS na porcie 53, aby następnie przekierować je do zdalnego proxy socks5 i DNS Google 8.8.8.8. Pozostaje nam skonfigurować zasady netfilter (iptables) oraz DHCP do przydzielania adresów.
8. Zainstalujemy pakiety iptables-persistent oraz dhcpd.
root@debian9:~# apt-get install iptables-persistent isc-dhcp-server
9. Edytujemy plik uruchamiania 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. Restartujemy i sprawdzamy usługę na porcie 67.
root@debian9:~# reboot
root@debian9:~# netstat -nlp
log netstatAktywne połączenia internetowe (tylko serwery)
Proto Recv-Q Send-Q Adres lokalny Adres zdalny Stan PID/Nazwa programu
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. Pozostało przekierować wszystkie zapytania tcp na port 888 i zapisać regułę w 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. Aby zwiększyć pasmo, można używać kilku serwerów proxy jednocześnie. Łączna suma powinna wynosić 1000. Nowe połączenia nawiązywane są z prawdopodobieństwem 0.2, 0.2, 0.2, 0.2, 0.1, 0.1 do wskazanych serwerów proxy.
Uwaga: jeśli mamy proxy webowe, to zamiast socks5 należy wpisać connect, jeśli socks4, to socks4 (socks4 NIE WSPiera AUTORYZACJI LOGIN/HASŁO!)
Przykład konfiguracji przejrzystego serwera proxy nr 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 ADRES_IP_ZEWNETRZNEGO_PROXY№1 3128 tester 1234
parent 200 socks5 ADRES_IP_ZEWNETRZNEGO_PROXY№2 3128 tester 1234
parent 200 socks5 ADRES_IP_ZEWNETRZNEGO_PROXY№3 3128 tester 1234
parent 200 socks5 ADRES_IP_ZEWNETRZNEGO_PROXY№4 3128 tester 1234
parent 100 socks5 ADRES_IP_ZEWNETRZNEGO_PROXY№5 3128 tester 1234
parent 100 socks5 ADRES_IP_ZEWNETRZNEGO_PROXY№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
Konfiguracja i uruchomienie konfiguracji NAT + Transparent Proxy
W tej konfiguracji będziemy używać standardowego mechanizmu NAT z wybiórczym lub pełnym przezroczystym proxy dla określonych adresów lub podsieci. Użytkownicy wewnętrznej sieci będą korzystać z określonych usług/podsieci nawet nie zdając sobie sprawy, że działają przez proxy. Wszystkie połączenia https działają doskonale, nie trzeba generować ani wymieniać certyfikatów.
Na początku ustalmy, jakie podsieci/usługi chcemy proxy. Załóżmy, że zewnętrzne serwery proxy znajdują się tam, gdzie działa taki serwis jak pandora.com. Teraz musimy zdefiniować jego podsieci/adresy.
1. Pingujemy
root@debian9:~# ping pandora.com
PING pandora.com (208.85.40.20) 56(84) bajtów danych.
2. Wpisujemy w Google BGP 208.85.40.20
Przechodzimy na stronę
Widać, że poszukiwana podsieć to AS40428 Pandora Media, Inc
Otwieramy prefiksy v4
I oto są poszukiwane podsieci!
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. Aby zmniejszyć liczbę podsieci, należy wykonać agregację. Przechodzimy na stronę i kopiujemy naszą listę. W rezultacie powstaje 6 podsieci zamiast 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. Czyszczenie reguł iptables
root@debian9:~# iptables -F
root@debian9:~# iptables -X
root@debian9:~# iptables -t nat -F
root@debian9:~# iptables -t nat -X
Włączamy mechanizm forward i 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
Aby forward był włączony na stałe po restarcie, zmieniamy plik
root@debian9:~# nano /etc/sysctl.conf
I odkomentowujemy linię
net.ipv4.ip_forward = 1
Ctrl+X, aby zapisać plik
5. Pakujemy podsieci pandora.com w proxy
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. Zapisujemy reguły
root@debian9:~# iptables-save > /etc/iptables/rules.v4
Konfiguracja i uruchomienie Transparent Proxy przez router
W tej konfiguracji serwer proxy może być oddzielnym komputerem lub maszyną wirtualną za domowym/firmowym routerem. Wystarczy ustawić statyczne trasy na routerze lub urządzeniach, a cała podsieć będzie korzystać z proxy bez potrzeby dodatkowych ustawień.
WAŻNE! Należy, aby nasza brama otrzymywała statyczny IP od routera lub była ustawiona na statykę samodzielnie.
1. Konfigurujemy statyczny adres bramy (adapter 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. Pozwalamy urządzeniom z podsieci 192.168.23.0/24 korzystać z proxy
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. Zapisujemy reguły
root@debian9:~# iptables-save > /etc/iptables/rules.v4
4. Wprowadzamy podsieci na routerze
Lista sieci routera199.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
Wykorzystane materiały/źródła
1. Oficjalna strona programu 3proxy
2. Instrukcja instalacji 3proxy ze źródeł
3. Wątek dewelopera 3proxy na GitHubie
Źródło: habr.com
