Neste artigo, gostaríamos de explorar as possibilidades de proxy transparente, que permite redirecionar todo ou parte do tráfego através de servidores proxy externos de forma absolutamente invisível para os clientes.
Quando comecei a resolver essa tarefa, encontrei um problema significativo na sua implementação — o protocolo HTTPS. Nos velhos tempos, não havia grandes problemas com o proxy transparente do HTTP, mas ao proxyizar o HTTPS, os navegadores alertam sobre a interferência no protocolo, e a felicidade acaba por aí.
Nas instruções comuns para o servidor proxy Squid, sugerem até gerar um certificado próprio e instalá-lo nos clientes, o que é, no mínimo, uma ideia absurda e se parece com um ataque MITM. Sei que o Squid já consegue fazer algo semelhante, mas este artigo aborda um método comprovado e funcional utilizando 3proxy do respeitável 3APA3A.
A seguir, vamos analisar em detalhes o processo de compilação do 3proxy a partir do código-fonte, sua configuração, proxy total e seletivo utilizando NAT, distribuição de canal para múltiplos servidores proxy externos, bem como uso de roteadores e rotas estáticas. Usaremos o Debian 9 x64 como sistema operacional. Vamos começar!
Instalação do 3proxy e inicialização de um servidor proxy normal
1. Instalamos o ifconfig (do pacote net-tools)
apt-get install net-tools
2. Instalamos o Midnight Commander
apt-get install mc
3. Atualmente, temos 2 interfaces:
enp0s3 — externa, conectada à internet
enp0s8 — interna, deve conectar à rede local
Em outras distribuições baseadas em Debian, as interfaces geralmente são nomeadas como eth0 e eth1.
ifconfig -a
Interfacesenp0s3: 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)
Pacotes RX 6412 bytes 8676619 (8.2 MiB)
Erros RX 0 descartados 0 excessos 0 quadros 0
Pacotes TX 1726 bytes 289128 (282.3 KiB)
Erros TX 0 descartados 0 excessos 0 colisões 0
enp0s8: flags=4098 mtu 1500
ether 08:00:27:79:a7:e3 txqueuelen 1000 (Ethernet)
Pacotes RX 0 bytes 0 (0.0 B)
Erros RX 0 descartados 0 excessos 0 quadros 0
Pacotes TX 0 bytes 0 (0.0 B)
Erros TX 0 descartados 0 excessos 0 colisões 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)
Pacotes RX 0 bytes 0 (0.0 B)
Erros RX 0 descartados 0 excessos 0 quadros 0
Pacotes TX 0 bytes 0 (0.0 B)
Erros TX 0 descartados 0 excessos 0 colisões 0
A interface enp0s8 no momento não está em uso; iremos ativá-la quando quisermos usar a configuração de Proxy NAT ou NAT. Nesse caso, será lógico atribuir a ela um IP estático.
4. Vamos iniciar a instalação do 3proxy
4.1 Instalação de pacotes básicos para compilar o 3proxy a partir do código-fonte
root@debian9:~# apt-get install build-essential libevent-dev libssl-dev -y
4.2. Vamos criar uma pasta para baixar o arquivo com o código-fonte
root@debian9:~# mkdir -p /opt/proxy
4.3. Vamos entrar nesta pasta
root@debian9:~# cd /opt/proxy
4.4. Agora vamos baixar o último pacote do 3proxy. No momento da redação deste artigo, a última versão estável era 0.8.12 (18/04/2018). Vamos baixá-la do site oficial do 3proxy
root@debian9:\/opt\/proxy# wget https://github.com/z3APA3A/3proxy/archive/0.8.12.tar.gz
4.5. Vamos descompactar o arquivo baixado
root@debian9:/opt/proxy# tar zxvf 0.8.12.tar.gz
4.6. Vamos entrar no diretório descompactado para compilar o programa
root@debian9:/opt/proxy# cd 3proxy-0.8.12
4.7. A seguir, precisamos adicionar uma linha no arquivo de cabeçalho para que nosso servidor seja completamente anônimo (funciona de verdade, tudo foi testado, o IP dos clientes é ocultado)
root@debian9:/opt/proxy/3proxy-0.8.12# nano +29 src/proxy.h
Vamos adicionar a linha
#define ANONYMOUS 1
Pressionamos Ctrl+x e Enter para salvar as alterações.
4.8. Vamos começar a compilar o programa
root@debian9:/opt/proxy/3proxy-0.8.12# make -f Makefile.Linux
Makelogmake[2]: Saindo do diretório ‘/opt/proxy/3proxy-0.8.12/src/plugins/TransparentPlugin’
make[1]: Saindo do diretório ‘/opt/proxy/3proxy-0.8.12/src’
Sem erros, continuamos.
4.9. Vamos instalar o programa no sistema
root@debian9:/opt/proxy/3proxy-0.8.12# make -f Makefile.Linux install
4.10. Vamos voltar ao diretório raiz e checar onde o programa foi instalado
root@debian9:\/opt\/proxy\/3proxy-0.8.12# cd ~\/
root@debian9:~# whereis 3proxy
3proxy: /usr/local/bin/3proxy /usr/local/etc/3proxy
4.11. Vamos criar uma pasta para arquivos de configuração e logs no diretório inicial do usuário
root@debian9:~# mkdir -p /home/joke/proxy/logs
4.12. Vamos entrar no diretório onde o config deve estar
root@debian9:~# cd /home/joke/proxy/
4.13. Vamos criar um arquivo vazio e copiar o config para lá
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
Para salvar, pressionamos Ctrl + Z
4.14. Vamos criar um arquivo pid para evitar erros ao iniciar.
root@debian9:/home/joke/proxy# cat > 3proxy.pid
Para salvar, pressionamos Ctrl + Z
4.15. Vamos iniciar o servidor proxy!
root@debian9:/home/joke/proxy# 3proxy /home/joke/proxy/3proxy.conf
4.16. Vamos verificar se o servidor está escutando as portas
root@debian9:~/home/joke/proxy# netstat -nlp
log do netstatConexões de Internet ativas (apenas servidores)
Proto Recv-Q Send-Q Endereço Local Endereço Estrangeiro Estado PID/Nome do programa
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
Conforme foi escrito no config, o web proxy está escutando na porta 8080, o proxy Socks5 — na porta 3128.
4.17. Para iniciar automaticamente o serviço proxy após a reinicialização, precisamos adicioná-lo ao cron.
root@debian9:\/home\/joke\/proxy# crontab -e
Vamos adicionar a linha
@reboot /usr/local/bin/3proxy /home/joke/proxy/3proxy.conf
Pressionamos Enter, pois o cron precisa ver o símbolo de fim de linha e salvamos o arquivo.
Deve haver uma mensagem sobre a instalação do novo crontab.
crontab: instalando nova crontab
4.18. Vamos reiniciar o sistema e tentar conectar através do navegador ao proxy. Para verificação, usaremos o navegador Firefox (para web-proxy) e a extensão FoxyProxy para socks5 com autenticação.
root@debian9:~/home/joke/proxy# reboot
4.19. Após verificar o funcionamento do proxy após a reinicialização, podemos conferir os logs. Com isso, a configuração do servidor proxy está finalizada.
3 log de 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
Configuração e inicialização da configuração de Proxy Transparente NAT
Nesta configuração, todos os dispositivos na rede interna irão operar de forma transparente na internet através de um servidor proxy remoto. Todas as conexões TCP serão redirecionadas para um ou mais (o que realmente expande a largura de banda, exemplo de configuração nº 2!) servidores proxy. O serviço de DNS utilizará as funcionalidades do 3proxy (dnspr). O UDP não sairá, pois ainda não estamos usando o mecanismo de forward (que por padrão está desativado no kernel do Linux).
1. Agora é hora de ativar a interface 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
Aqui designamos para a interface enp0s8 um endereço estático 192.168.201.254 e uma máscara 255.255.255.0
Salvamos a configuração Ctrl+X e reiniciamos
root@debian9:~# reiniciar
2. Verificamos as interfaces
root@debian9:~# ifconfig
log ifconfigenp0s3: 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)
Pacotes RX 61 bytes 7873 (7.6 KiB)
Erros RX 0 descartados 0 excessos 0 quadros 0
Pacotes TX 65 bytes 10917 (10.6 KiB)
Erros TX 0 descartados 0 excessos 0 colisões 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)
Pacotes RX 0 bytes 0 (0.0 B)
Erros RX 0 descartados 0 excessos 0 quadros 0
Pacotes TX 8 bytes 648 (648.0 B)
Erros TX 0 descartados 0 excessos 0 colisões 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)
Pacotes RX 0 bytes 0 (0.0 B)
Erros RX 0 descartados 0 excessos 0 quadros 0
Pacotes TX 0 bytes 0 (0.0 B)
Erros TX 0 descartados 0 excessos 0 colisões 0
3. Tudo funcionou, agora é necessário configurar o 3proxy para o proxy transparente.
root@debian9:~# cd /home/joke/proxy/
root@debian9:/home/joke/proxy# cat > 3proxytransp.conf
Exemplo de configuração do servidor proxy transparente nº 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 ENDEREÇO_IP_DO_PROXY_EXTERNO 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. Agora vamos iniciar o 3proxy com a nova configuração
root@debian9:/home/joke/proxy# /usr/local/bin/3proxy /home/joke/proxy/3proxytransp.conf
5. Vamos adicionar novamente ao crontab
root@debian9:\/home\/joke\/proxy# crontab -e
@reboot \/usr\/local\/bin\/3proxy \/home\/joke\/proxy\/3proxytransp.conf
6. Vamos ver o que o nosso proxy está ouvindo agora
root@debian9:~# netstat -nlp
log do netstatConexões de Internet ativas (apenas servidores)
Proto Recv-Q Send-Q Endereço Local Endereço Estrangeiro Estado PID/Nome do programa
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. Agora o proxy está pronto para aceitar qualquer conexão TCP na porta 888, DNS na porta 53, para depois redirecioná-las para o proxy socks5 remoto e o DNS do Google 8.8.8.8. Resta-nos configurar as regras do netfilter (iptables) e o DHCP para atribuição de endereços.
8. Vamos instalar os pacotes iptables-persistent e dhcpd
root@debian9:~# apt-get install iptables-persistent isc-dhcp-server
9. Editamos o arquivo de inicialização do 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. Reiniciamos e verificamos o serviço na porta 67
root@debian9:~# reiniciar
root@debian9:~# netstat -nlp
log do netstatConexões de Internet ativas (apenas servidores)
Proto Recv-Q Send-Q Endereço Local Endereço Estrangeiro Estado PID/Nome do programa
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. Resta redirecionar todas as solicitações TCP para a porta 888 e salvar a regra no 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. Para aumentar a largura de banda, podemos utilizar vários servidores proxy. A soma total deve ser 1000. Novas conexões são estabelecidas com a probabilidade de 0.2, 0.2, 0.2, 0.2, 0.1, 0.1 nos proxies especificados.
Nota: se tivermos um proxy web, em vez de socks5 deve-se usar connect, se for socks4, deve-se usar socks4 (socks4 NÃO SUPORTA AUTORIZAÇÃO LOGIN/SENHA!)
Exemplo de configuração do proxy transparente nº 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 ENDEREÇO_IP_PROXY_EXTERNO_1 3128 tester 1234
parent 200 socks5 ENDEREÇO_IP_PROXY_EXTERNO_2 3128 tester 1234
parent 200 socks5 ENDEREÇO_IP_PROXY_EXTERNO_3 3128 tester 1234
parent 200 socks5 ENDEREÇO_IP_PROXY_EXTERNO_4 3128 tester 1234
parent 100 socks5 ENDEREÇO_IP_PROXY_EXTERNO_5 3128 tester 1234
parent 100 socks5 ENDEREÇO_IP_PROXY_EXTERNO_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
Configuração e inicialização da configuração NAT + Proxy Transparente
Nesta configuração, usaremos o mecanismo NAT normal com proxy transparente seletivo ou total para endereços ou subredes específicas. Os usuários da rede interna trabalharão com determinados serviços/subredes sem nem perceber que estão operando através de um proxy. Todas as conexões https funcionam perfeitamente, não há necessidade de gerar/substituir certificados.
Para começar, vamos definir quais sub-redes/serviços queremos proxificar. Suponha que os servidores proxy externos estejam onde funciona um serviço como pandora.com. Agora é preciso identificar suas sub-redes/endereço.
1. Vamos fazer um ping
root@debian9:~# ping pandora.com
PING pandora.com (208.85.40.20) 56(84) bytes de dados.
2. Pesquisamos no Google BGP 208.85.40.20
Vamos para o site
Nota-se que a sub-rede desejada é AS40428 Pandora Media, Inc
Abrindo os prefixos v4
Então, aqui estão as sub-redes procuradas!
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. Para reduzir o número de sub-redes, devemos executar a agregação. Vamos acessar o site e colar nossa lista lá. O resultado será — 6 sub-redes em vez de 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. Limpar regras iptables
root@debian9:~# iptables -F
root@debian9:~# iptables -X
root@debian9:~# iptables -t nat -F
root@debian9:~# iptables -t nat -X
Ativamos o mecanismo de forward e 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
Para que o forward esteja sempre ativado após o reinício, vamos alterar o arquivo
root@debian9:~# nano /etc/sysctl.conf
E descomentamos a linha
net.ipv4.ip_forward = 1
Ctrl+X para salvar o arquivo
5. Encaminhamos as sub-redes pandora.com para o 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. Vamos salvar as regras
root@debian9:~# iptables-save > /etc/iptables/rules.v4
Configuração e inicialização do proxy transparente via roteador
Nesta configuração, o servidor proxy transparente pode ser um PC separado ou uma máquina virtual atrás do roteador doméstico/corporativo. Basta definir rotas estáticas no roteador ou nos dispositivos, e toda a sub-rede usará o proxy sem necessidade de quaisquer configurações adicionais.
IMPORTANTE! É necessário que nosso gateway receba um IP estático do roteador, ou que esteja configurado para ter um IP fixo.
1. Configurando o endereço IP estático do gateway (adaptador 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. Permitindo que dispositivos da sub-rede 192.168.23.0/24 utilizem o 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. Vamos salvar as regras
root@debian9:~# iptables-save > /etc/iptables/rules.v4
4. Definindo as sub-redes no roteador
Lista de redes do roteador199.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
Materiais/recursos utilizados
1. Site oficial do programa 3proxy
2. Instrução de instalação do 3proxy a partir do código-fonte
3. Ramo do desenvolvedor do 3proxy no GitHub
Fonte: habr.com
