Fundamentos de la proxy transparente utilizando 3proxy e iptables/netfilter o cómo "redirigir todo a través de un proxy"

En este artículo nos gustaría explorar las capacidades del proxy transparente, que permite redirigir todo o parte del tráfico a través de servidores proxy externos de manera completamente imperceptible para los clientes.

Cuando comencé a abordar esta tarea, me encontré con un problema significativo en su implementación: el protocolo HTTPS. En los buenos viejos tiempos, no había problemas especiales con el proxy transparente de HTTP, pero al proxyizar HTTPS, los navegadores informan sobre una intervención en el protocolo y ahí termina la felicidad.

En las instrucciones comunes para el servidor proxy Squid incluso se sugiere generar un certificado propio e instalarlo en los clientes, lo cual es absurdo, al menos poco racional, y parece un ataque MITM. Sé que Squid ya puede hacer algo similar, pero en este artículo hablaremos de un método comprobado y funcional utilizando 3proxy de la respetada 3APA3A.

A continuación, veremos en detalle el proceso de compilación de 3proxy a partir de su código fuente, su configuración, el proxy completo y selectivo utilizando NAT, la distribución del canal a varios servidores proxy externos, así como el uso de un router y rutas estáticas. Utilizaremos Debian 9 x64 como sistema operativo. ¡Comencemos!

Instalación de 3proxy y lanzamiento de un servidor proxy básico

1. Instalamos ifconfig (del paquete net-tools)
apt-get install net-tools
2. Instalamos Midnight Commander
apt-get install mc
3. Ahora tenemos 2 interfaces:
enp0s3 — externo, conectado a Internet
enp0s8 — interno, debe conectarse a la red local
En otras distribuciones basadas en Debian, las interfaces suelen llamarse eth0 y 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)
RX packets 6412 bytes 8676619 (8.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1726 bytes 289128 (282.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

enp0s8: flags=4098 mtu 1500
ether 08:00:27:79:a7:e3 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 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 packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

La interfaz enp0s8 actualmente no está en uso, la activaremos cuando deseemos usar la configuración de Proxy NAT o NAT. Es en ese momento cuando tendrá sentido asignarle una IP estática.

4. Procedemos a la instalación de 3proxy

4.1 Instalación de paquetes básicos para compilar 3proxy a partir del código fuente

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

4.2. Creamos una carpeta para descargar el archivo con las fuentes

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

4.3. Entramos en esta carpeta

root@debian9:~# cd /opt/proxy

4.4. Ahora descargamos el último paquete 3proxy. En el momento de escribir este artículo, la última versión estable era 0.8.12 (18/04/2018). La descargamos desde el sitio oficial de 3proxy

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

4.5. Descomprimimos el archivo descargado

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

4.6. Vamos a la carpeta descomprimida para compilar el programa

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

4.7. Luego, es necesario agregar una línea en el archivo de encabezado para que nuestro servidor sea completamente anónimo (realmente funciona, todo ha sido comprobado, las IP de los clientes están ocultas)

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

Agregamos la línea

#define ANONYMOUS 1

Presionamos Ctrl+x y Enter para guardar los cambios.

4.8. Procedemos a compilar el programa

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

Makelogmake[2]: Salida del directorio ‘/opt/proxy/3proxy-0.8.12/src/plugins/TransparentPlugin’
make[1]: Salida del directorio ‘/opt/proxy/3proxy-0.8.12/src’

No hay errores, continuamos.

4.9. Instalamos el programa en el sistema

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

4.10. Vamos al directorio raíz y verificamos dónde se instaló el programa

root@debian9:~# cd ~/
root@debian9:~# whereis 3proxy

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

4.11. Creamos una carpeta para los archivos de configuración y logs en el directorio personal del usuario

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

4.12. Entramos en el directorio donde debe estar el config

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

4.13. Creamos un archivo vacío y copiamos el config allí

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 guardar presionamos Ctrl + Z

4.14. Creamos un archivo pid para evitar errores al iniciar.

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

Para guardar presionamos Ctrl + Z

4.15. ¡Iniciamos el servidor proxy!

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

4.16. Verificamos si el servidor está escuchando los puertos

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

netstat logConexiones de Internet activas (solo servidores)
Proto Recv-Q Send-Q Dirección Local Dirección Remota Estado PID/Nombre del 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

Como se indicó en el config, el web-proxy está escuchando en el puerto 8080, el Socks5-proxy en el 3128.

4.17. Para el autoinicio del servicio proxy después de reiniciar, es necesario agregarlo al cron.

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

Agregamos la línea

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

Presionamos Enter, ya que cron debe ver el símbolo de fin de línea y guardamos el archivo.

Debería haber un mensaje sobre la instalación del nuevo crontab.

crontab: instalando nuevo crontab

4.18. Reiniciaremos el sistema y probaremos conectar a través del navegador al proxy. Para la prueba utilizaremos el navegador Firefox (para el proxy web) y la extensión FoxyProxy para socks5 con autenticación.

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

4.19. Una vez comprobado el funcionamiento del proxy después de reiniciar, se pueden revisar los registros. La configuración del servidor proxy ha finalizado.

3 registro 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

Configuración y lanzamiento de la configuración del Proxy Transparente NAT

En esta configuración, todos los dispositivos de la red interna funcionarán transparentemente en Internet a través de un servidor proxy remoto. Todas las conexiones TCP serán redirigidas a uno o varios (realmente ampliando el ancho de banda, ejemplo de configuración nº 2!) servidores proxy. El servicio DNS utilizará las capacidades de 3proxy (dnspr). UDP no saldrá al exterior ya que aún no estamos utilizando el mecanismo de reenvío (por defecto está deshabilitado en el núcleo de Linux).

1. Es hora de activar la interfaz 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

Aquí hemos asignado a la interfaz enp0s8 una dirección estática 192.168.201.254 y una máscara 255.255.255.0
Guardamos la configuración Ctrl+X y reiniciamos

root@debian9:~# reiniciar

2. Verificamos las interfaces

root@debian9:~# ifconfig

registro 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)
RX paquetes 61 bytes 7873 (7.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX paquetes 65 bytes 10917 (10.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 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 packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX paquetes 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 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 packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

3. Todo ha funcionado, ahora es necesario configurar 3proxy para el proxy transparente.

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

Ejemplo de configuración del 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 DIRECCIÓN_IP_DEL_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. Ahora iniciamos 3proxy con la nueva configuración
root@debian9:\/home\/joke\/proxy# \/usr\/local\/bin\/3proxy \/home\/joke\/proxy\/3proxytransp.conf

5. Nuevamente agregaremos a crontab
root@debian9:\/home\/joke\/proxy# crontab -e
@reboot \/usr\/local\/bin\/3proxy \/home\/joke\/proxy\/3proxytransp.conf

6. Veremos qué está escuchando ahora nuestro proxy
root@debian9:~# netstat -nlp

netstat logConexiones de Internet activas (solo servidores)
Proto Recv-Q Send-Q Dirección Local Dirección Remota Estado PID/Nombre del 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. Ahora el proxy está listo para aceptar cualquier conexión TCP en el puerto 888, DNS en el puerto 53, para luego redirigirlas al proxy socks5 remoto y al DNS de Google 8.8.8.8. Solo nos queda configurar las reglas de netfilter (iptables) y DHCP para la asignación de direcciones.

8. Instalamos el paquete iptables-persistent y dhcpd

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

9. Modificamos el archivo de inicio de 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 y verificamos el servicio en el puerto 67
root@debian9:~# reiniciar
root@debian9:~# netstat -nlp

netstat logConexiones de Internet activas (solo servidores)
Proto Recv-Q Send-Q Dirección Local Dirección Remota Estado PID/Nombre del 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. Solo falta redirigir todas las solicitudes tcp al puerto 888 y guardar la regla en 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 ampliar el ancho de banda se pueden usar varios servidores proxy a la vez. La suma total debe ser 1000. Nuevas conexiones se establecen con probabilidades de 0.2, 0.2, 0.2, 0.2, 0.1, 0.1 hacia los proxies indicados.

Nota: si usamos un proxy web, en lugar de socks5 debemos escribir connect, si es socks4, entonces socks4 (socks4 NO SOPORTA AUTORIZACIÓN DE USUARIO/PAROLE!).

Ejemplo de configuración del 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 DIRECCIÓN_IP_DEL_PROXY_EXTERNO#1 3128 tester 1234
parent 200 socks5 DIRECCIÓN_IP_DEL_PROXY_EXTERNO#2 3128 tester 1234
parent 200 socks5 DIRECCIÓN_IP_DEL_PROXY_EXTERNO#3 3128 tester 1234
parent 200 socks5 DIRECCIÓN_IP_DEL_PROXY_EXTERNO#4 3128 tester 1234
parent 100 socks5 DIRECCIÓN_IP_DEL_PROXY_EXTERNO#5 3128 tester 1234
parent 100 socks5 DIRECCIÓN_IP_DEL_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

Configuración y lanzamiento de la configuración de NAT + Proxy Transparente

En esta configuración utilizaremos el mecanismo de NAT habitual con proxy transparente selectivo o total para direcciones o subredes. Los usuarios de la red interna trabajarán con ciertos servicios/subredes sin siquiera darse cuenta de que están utilizando un proxy. Todas las conexiones https funcionan perfectamente, no es necesario generar/cambiar certificados.

Primero, definamos qué subredes/servicios queremos proxear. Supongamos que los servidores proxy externos están donde opera un servicio como pandora.com. Ahora solo falta determinar sus subredes/direcciones.

1. Hacemos ping

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

2. Buscamos en Google BGP 208.85.40.20

Visitemos el sitio bgp.he.net/net/208.85.40.0/24#_netinfo
Se observa que la subred buscada es AS40428 Pandora Media, Inc.

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

Abrimos los prefijos v4

bgp.he.net/AS40428#_prefixes

¡Aquí están las subredes buscadas!

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 reducir la cantidad de subredes, es necesario realizar una agregación. Vamos al sitio ip-calculator.ru/aggregate y copiamos nuestra lista allí. Como resultado, — 6 subredes en 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. Limpiamos las reglas de iptables

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

Activamos el mecanismo de forwarding y 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 el forwarding esté habilitado permanentemente después del reinicio, modificamos el archivo

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

Y descomentamos la línea

net.ipv4.ip_forward = 1

Ctrl+X para guardar el archivo

5. Envolvemos las subredes de pandora.com en el 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. Guardamos las reglas

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

Configuración y lanzamiento de la configuración de Proxy Transparente a través del router

En esta configuración, el proxy transparente puede ser una PC o máquina virtual detrás del router doméstico/corporativo. Solo es necesario configurar rutas estáticas en el router o dispositivos, y toda la subred utilizará el proxy sin necesidad de configuraciones adicionales.

¡IMPORTANTE! Es necesario que nuestra puerta de enlace reciba una IP estática del router o esté configurada como estática.

1. Configuramos la dirección estática de la puerta de enlace (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. Permitimos que los dispositivos de la subred 192.168.23.0/24 utilicen el 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. Guardamos las reglas
root@debian9:~# iptables-save > /etc/iptables/rules.v4

4. Escribimos las subredes en el router

Lista de redes del router199.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

Materiales/recursos utilizados

1. Sitio oficial del programa 3proxy 3proxy.ru

2. Instrucciones de instalación de 3proxy desde el código fuente www.ekzorchik.ru/2015/02/how-to-take-your-socks-proxy

3. Rama del desarrollador de 3proxy en GitHub github.com/z3APA3A/3proxy/issues/274

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster