¿Cuál es la diferencia con materiales similares?
- Implementación pura de OpenWrt
- Usando WireGuard
- La configuración del enrutador se organiza usando configuraciones OpenWrt, y no un montón en un script
- Hay situaciones al reiniciar la red y reiniciar
- Consume pocos recursos de enrutador: las subredes bloqueadas están contenidas en iptables y no en tablas de enrutamiento. Lo que le permite implementar este negocio incluso en dispositivos débiles
- Automatice la configuración con Ansible (no se requiere python en el enrutador)
Versión de video
¿Por qué OpenWrt y WireGuard?
OpenWrt está instalado en muchos modelos de enrutadores soho, está configurado y ampliado según lo desee su corazón. Ahora muchos firmwares de enrutadores son complementos sobre OpenWrt.
Wireguard se utiliza debido a su configuración rápida y fácil, y también debido a la alta velocidad de transmisión a través del túnel.
Un poco sobre WireGuard
En nuestro caso, el servidor es un VPS fuera del ILV, el cliente es un enrutador OpenWrt en casa. Cuando quieres ir a pornolab telegrama, su enrutador dirigirá el tráfico a través de un servidor con WireGuard.
WireGuard genera una conexión de sitio a sitio, es decir tanto el servidor como el cliente tienen el lado del servidor y el cliente de la configuración. Si no está claro, quedará claro cuando vea la configuración.
El servidor y el cliente tienen sus propias claves públicas y privadas.
Configurar WireGuard en el servidor
Estoy haciendo todo en Ubuntu 18.04, pero en la documentación oficial hay instrucciones de instalación para todos los sistemas operativos conocidos y no muy.
Instalación
sudo add-apt-repository ppa:wireguard/wireguard
Si ocurre un error
sudo: add-apt-repository: command not found
Instalar software-properties-common: el paquete proporciona la capacidad de agregar y eliminar PPA
sudo apt install software-properties-common
sudo apt update sudo apt install wireguard-dkms wireguard-tools
Generamos claves para el servidor. Guardaremos las claves en el directorio WireGuard para mayor comodidad.
cd /etc/wireguard/ wg genkey | tee privatekey-server | wg pubkey > publickey-server
En consecuencia, habrá una clave privada en el archivo del servidor de clave privada y una clave pública en el archivo del servidor de clave pública.
También generamos inmediatamente una clave para el cliente:
wg genkey | tee privatekey-client | wg pubkey > publickey-client

Configuracion
La configuración se almacena en /etc/wireguard/wg0.conf. El lado del servidor se ve así:
[Interface] Address = 192.168.100.1 PrivateKey = privatekey-server ListenPort = 51820 PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
Dirección : dirección de la interfaz wg (dirección dentro del túnel)
PrivateKey : clave privada (privatekey-server)
ListenPort : el puerto en el que el servicio está esperando para conectarse
Bueno, hacemos máscaras, porque usaremos este servidor para acceder a Internet
Tenga en cuenta que el nombre de la interfaz en su caso puede diferir:
Parte del cliente
[Peer] PublicKey = publickey-client AllowedIPs = 192.168.100.3/24
PublicKey : la clave pública de nuestro enrutador (publickey-client)
Las IP permitidas son las subredes que estarán disponibles a través de este túnel. El servidor solo necesita acceso a la dirección del cliente.
Ambas partes se almacenan en una configuración.
Active el inicio automático al reiniciar:
systemctl enable wg-quick@wg0
Hacemos del servidor un enrutador:
sysctl -w net.ipv4.ip_forward=1
Configura el cortafuegos. Supongamos que solo tenemos WireGuard y ssh en nuestro servidor:
sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A INPUT -p udp -m udp --dport 51820 -j ACCEPT sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A INPUT -p icmp -j ACCEPT sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT sudo iptables -A INPUT -j DROP
Guarde la configuración de iptables:
sudo apt-get install iptables-persistent sudo netfilter-persistent save
Levantamos la interfaz wg por primera vez manualmente:
wg-quick up wg0

El servidor WireGuard está listo.
UPD 27/06/19 Si su proveedor todavía usa PPoE, entonces necesita agregar una regla. Gracias denix123
iptables -t mangle -I POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Configuración del enrutador
Estoy usando OpenWrt versión 18.06.1 en Xiaomi mi 3G y Asus RT-N16.
La lógica del enrutador
Cargamos las listas, las colocamos en iptables, iptables marca todas las direcciones de estas listas con un marcador 0x1. Además, todos los paquetes marcados con 0x1 van a una tabla de enrutamiento separada, todos los paquetes que caen en esta tabla de enrutamiento pasan por la interfaz wg.

Instalación de paquete
En cuanto al espacio ocupado en el flash, todo necesitará aproximadamente 0.9MB. Si tiene un lugar muy malo, reemplace curl con wget y es posible que no necesite instalar dnscrypt-proxy.
Ponemos paquetes. En OpenWrt, esto es fácil de hacer a través del administrador de paquetes opkg:
opkg update opkg install ipset wireguard curl
Descargar listas
Todo lo que se puede hacer a través de las características estándar de OpenWrt se hace a través de ellos. Todo lo demás (excepto hotplug) lo puse en un pequeño script:
Las listas de subredes y direcciones prohibidas se obtienen por archivos. Para ellos creamos un directorio en / tmp. In / tmp: como es RAM, esta característica de OpenWrt es bastante conveniente. No vale la pena volver a escribir algo en la ROM del enrutador.
Bombeamos las listas con antifilter.download curl, el indicador z significa que curl descargará el archivo solo si el archivo remoto es diferente del archivo local o si no está allí, como es el caso al cargar el enrutador.
subnet.lst : una lista de subredes bloqueadas; no cambia con frecuencia.
ipsum.lst es una lista de direcciones bloqueadas, que se resume por máscara. En lugar de 150 mil registros, obtenemos 15 mil, convenientemente.
Después de tener los archivos, reiniciamos el firewall, esto es necesario para que ipset funcione y agregue listas a iptables, configuraremos ipset en / etc / config / firewall.
Este script que agreguemos en /etc/init.d/ se llamará hirkn. Hazlo ejecutable
chmod +x /etc/init.d/hirkn
Ahora no solo tenemos un script, sino un servicio completo. Para que comience en el arranque, hacemos un enlace simbólico en /etc/rc.d. Lo necesitamos para comenzar después de todos los demás servicios, por lo que creamos el prefijo S99
ln -s /etc/init.d/hirkn /etc/rc.d/S99hirkn
Las listas deben actualizarse de vez en cuando, agregamos registros en cron:
crontab -e
0 4 * * * /etc/init.d/hirkn
Parece bastante suficiente actualizarlos una vez al día. Tenga en cuenta que al agregar listas a ipset, la red se cae, en mi caso son 2 segundos.
UPD : Si no desea descansos, sigo73 y Grayver sugirieron en los comentarios cómo hacerlo.
También encienda la corona, por defecto está deshabilitada:
/etc/init.d/cron enable /etc/init.d/cron start
Configuración de la tabla de enrutamiento
Cree una tabla de enrutamiento para el tráfico a través del túnel simplemente agregando la línea:
99 vpn
al archivo / etc / iproute2 / rt_tables.
Puede crear una ruta predeterminada para la tabla "vpn" a través de la interfaz wg con el comando:
ip route add table vpn default dev wg0
Pero cuando reinicia la red, la ruta desaparece, por lo que creamos el archivo 30-rknroute en el directorio /etc/hotplug.d/iface/ con contenido simple:
Esto significa que cuando activa / desactiva las interfaces, se agregará nuestra ruta. Y en consecuencia, esta ruta siempre estará registrada.
Configuración de red
Necesitamos configurar WireGuard y la regla para paquetes etiquetados 0x1.
La configuración de WireGuard se encuentra en / etc / config / network
La parte del "servidor":
config interface 'wg0' option private_key 'privatekey-client' list addresses '192.168.100.3/24' option listen_port '51820' option proto 'wireguard'
private_key es el privatekey-client que generamos al configurar el servidor
lista de direcciones - dirección de interfaz wg
listen_port : el puerto en el que WireGuard acepta conexiones. Pero la conexión se realizará a través del puerto en el servidor, por lo que aquí no abriremos el puerto en el firewall para ello.
proto : especifique el protocolo para que openwrt entienda que esta es una configuración de WireGuard
Parte "Cliente":
config wireguard_wg0 option public_key 'publickey-server' option allowed_ips '0.0.0.0/0' option route_allowed_ips '0' option endpoint_host 'wg-server-ip' option persistent_keepalive '25' option endpoint_port '51820'
public_key - clave del servidor publickey
allowed_ips : subredes en las que el tráfico puede atravesar el túnel, en nuestro caso no se requieren restricciones, por lo tanto, 0.0.0.0/0
route_allowed_ips : una marca que realiza una ruta a través de la interfaz wg para las redes enumeradas desde el parámetro allow_ips. En nuestro caso, esto no es necesario, iptables funciona
endpoint_host - ip / url de nuestro servidor wg
persistent_keepalive : intervalo de tiempo después del cual se envían los paquetes para admitir la conexión
endpoint_port - puerto wireguard en el servidor
También agregaremos una regla a la configuración de red que enviará todo el tráfico marcado 0x1 a la tabla de enrutamiento "vpn":
config rule option priority '100' option lookup 'vpn' option mark '0x1'
Configuración de firewall
Agregamos dos reglas para marcar paquetes, no se ajustan a la sintaxis UCI de openwrt, por lo que las agregamos "tal cual" a /etc/firewall.user.
UPD : Grayver sugirió que encajan bastante bien. Los configuramos después de configurar ipset
La configuración del firewall está en / etc / config / firewall
Agregue una zona para protección de cables. En openwrt, las zonas son cadenas personalizadas en iptables. Por lo tanto, se crea una zona con una / varias interfaces y las reglas ya están colgadas en ella. La zona para wg se ve así:
config zone option name 'wg' option family 'ipv4' option masq '1' option output 'ACCEPT' option forward 'REJECT' option input 'REJECT' option mtu_fix '1' option network 'wg0'
Solo permitimos que el tráfico salga de la interfaz y habilitemos el enmascaramiento.
Ahora debe habilitar el reenvío desde la zona lan a la zona wg:
config forwarding option src 'lan' option dest 'wg'
Bueno, lo último es crear listas en iptables usando ipset:
config ipset option name 'vpn_subnets' option storage 'hash' option loadfile '/tmp/lst/subnet.lst' option match 'dst_net' config ipset option name 'vpn_ipsum' option storage 'hash' option loadfile '/tmp/lst/ipsum.lst' option match 'dst_net'
loadfile : el archivo del que tomamos la lista
nombre - nombre para nuestra lista
almacenamiento , coincidencia : aquí especificamos cómo almacenar y qué tipo de datos. Almacenaremos el tipo "subred"
UPD : si desea utilizar la lista de direcciones IP individuales, debe aumentar el tamaño de la lista de IPset. En config ipset add
option hashsize '1000000' option maxelem '1000000'
De lo contrario, recibirá un error
ipset v6.38: Hash is full, cannot add more elements
UPD : agregue dos reglas para etiquetar paquetes
config rule option name 'mark_subnet' option src 'lan' option proto 'all' option ipset 'vpn_subnets' option set_mark '0x1' option target 'MARK' config rule option name 'mark_ipsum' option src 'lan' option proto 'all' option ipset 'vpn_ipsum' option set_mark '0x1' option target 'MARK'
Estas reglas implican que todos los paquetes que van a las subredes desde las listas vpn_subnets y vpn_ipsum deben marcarse con 0x1.
Después de eso, reiniciamos la red:
/etc/init.d/network restart

y ejecuta el script:
/etc/init.d/hirkn

Después de elaborar el guión, todo debería funcionar para usted. Verifique la ruta en el cliente del enrutador:
mtr/traceroute telegram.org/linkedin.com

Bonus configure DNSCrypt
Por qué Su proveedor puede sustituir cuidadosamente la dirección IP del recurso bloqueado, redirigiéndolo a su ip con un código auxiliar, bueno, nuestra omisión de IP no ayudará en este caso. Para la sustitución, no siempre es necesario utilizar el servidor dns del proveedor, sus solicitudes pueden ser interceptadas y las respuestas serán sustituidas. Bueno, por cierto, no solo el proveedor puede hacer esto.
opkg install dnscrpt-proxy
Configure la configuración / etc / config / dnscrypt-proxy de esta manera:
config dnscrypt-proxy ns1 option address '127.0.0.1' option port '5353' option resolver 'cpunks-ru'
Entonces tenemos el servicio dnscrypt en el puerto 5353 disponible en localhost.
Resolver es un servidor dns que admite cifrado. En el enrutador, el archivo /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv contiene una lista de servidores disponibles en el momento del lanzamiento de la versión instalada de dnscrypt. Y aquí está https://dnscrypt.info/public-servers/ en general todos los servidores dnscrypt disponibles. Puede elegir otro solucionador y / o agregar servidores para tolerancia a fallas. Tenga en cuenta que para que DNSCrypt funcione con el solucionador seleccionado, debe especificarse en dnscrypt-resolvers.csv.
Configuramos dnsmasq para que funcione con dnscrypt. En / etc / config / dhcp, comente la línea:
option resolvfile '/tmp/resolv.conf.auto'
para que el servidor dns del proveedor no esté involucrado.
Y agregue:
list server '/pool.ntp.org/208.67.222.222' list server '127.0.0.1#5353'
La entrada del servidor de lista 'dominio / ip_dns' indica qué servidor dns usar para resolver el dominio especificado. Por lo tanto, no usamos dnscrypt para la sincronización de ntp; es importante que el servicio dnscrypt tenga la hora actual.
Cuando se carga el enrutador, el script hirkn se ejecuta más rápido de lo que se inicia dnscrypt, por lo que el dominio antifilter.download no se resuelve y las listas no se descargan. Puedes hacer un retraso u otra cosa, pero hasta ahora no veo ninguna razón.
UPD : necesita agregar una línea
START=99
a hirkn script
Como resultado, obtenemos dicha inserción en la configuración:
UPD : en algunos dispositivos, DNSCrypt se inicia de todos modos después del script. La forma más fácil de solucionar esto es agregar la línea a / etc / config / dhcp
list server '/antifilter.download/208.67.222.222'
Deshabilite el uso del DNS del proveedor para la interfaz wan
En / etc / config / network agregue la línea
option peerdns '0'
a la interfaz wan.
Obtenemos esta configuración
config interface 'wan' option ifname 'eth0.2' option proto 'dhcp' option peerdns '0'
Reiniciar la red
/etc/init.d/network restart
Agregar al inicio e iniciar dnscrypt:
/etc/init.d/dnscrypt-proxy enable /etc/init.d/dnscrypt-proxy start
Reinicie dnsmasq:
/etc/init.d/dnsmasq restart

Ilustración del trabajo sin DNSCrypt y con DNSCrypt
Implementado automáticamente con Ansible
Playbook y plantillas están en github . Utiliza un módulo , no necesita python en el enrutador y hay soporte para uci. Traté de asegurarme de que su configuración OpenWrt permaneciera intacta, pero tenga cuidado de todos modos.
Instale el módulo gekmihesg / ansible-openwrt:
ansible-galaxy install gekmihesg.openwrt
Copie el libro de jugadas y la tempeita:
cd /etc/ansible git clone https://github.com/itdoginfo/ansible-openwrt-hirkn mv ansible-openwrt-hirkn/* . rm -rf ansible-openwrt-hirkn
Agregue su enrutador a los hosts:
[openwrt] 192.168.1.1
Sustituya sus variables en hirkn.yml:
vars: ansible_template_dir: /etc/ansible/templates/ wg_server_address: wg_server_ip/url wg_private_key: privatekey-client wg_public_key: publickey-server wg_listen_port: 51820 wg_client_port: 51820 wg_client_address: 192.168.100.3/24
Asegúrese de configurar:
wg_server_address - servidor de protección ip / url
wg_private_key , wg_public_key - clave privada del cliente y servidor público
El resto no se puede cambiar o cambiar, dependiendo de cómo esté configurado el servidor WireGuard
Lanzar libro de jugadas
ansible-playbook playbooks/hirkn.yml
Después de completar el libro de jugadas, el enrutador comenzará inmediatamente a evitar los bloqueos a través de su servidor Wireguard.
¿Por qué no BGP?
Bajo openwrt hay dos utilidades que implementan BGP: quagga y bird. Quagg no pude obtener datos del antifiltro. Bird se hizo amigo del servicio de media patada, pero desafortunadamente no entendí cómo forzar que se agregue la interfaz predeterminada a las subredes recibidas. (Estaré encantado de saber cómo se puede implementar esto).
En los comentarios sobre tales artículos, vi que los enrutadores de las personas eran "reflexivos" por un tiempo, cuando colocaban listas en la tabla de enrutamiento. Con la implementación a través de ipset, mi Xiaomi mi 3G piensa durante 2 segundos (Asus rt-n16 durante 5 segundos), cuando le das de comer una lista de 15 mil subredes. Con más trabajo, no noté la carga en el procesador.
Todos los materiales no son un llamado a la acción y se presentan para familiarizarse con la funcionalidad del sistema operativo Linux.