Quelle est la différence avec des matériaux similaires?
- Implémentation Pure OpenWrt
- Utilisation de WireGuard
- La configuration du routeur est organisée à l'aide de configurations OpenWrt, et non d'un groupe dans un script
- Il existe des situations lors du redémarrage du réseau et du redémarrage
- Il consomme peu de ressources de routeur: les sous-réseaux verrouillés sont contenus dans iptables et non dans les tables de routage. Ce qui vous permet de déployer cette entreprise même sur des appareils faibles
- Automatisez la configuration Ă l'aide d'Ansible (aucun python requis sur le routeur)
Version vidéo
Pourquoi OpenWrt et WireGuard?
OpenWrt est installé sur de nombreux modèles de routeurs soho, il est configuré et étendu à votre guise. Maintenant, de nombreux firmwares de routeurs sont des modules complémentaires sur OpenWrt.
Wireguard est utilisé en raison de sa configuration rapide et facile, ainsi qu'en raison de la vitesse de transmission élevée à travers le tunnel.
Un peu sur WireGuard
Dans notre cas, le serveur est un VPS en dehors de l'ILV, le client est un routeur OpenWrt à la maison. Quand tu veux aller à pornolab télégramme, votre routeur dirigera le trafic via un serveur avec WireGuard.
WireGuard établit une connexion de site à site, c'est-à -dire le serveur et le client ont tous deux le côté serveur et client de la configuration. Si ce n'est pas clair, cela deviendra clair lorsque vous verrez la configuration.
Le serveur et le client ont leurs propres clés privées et publiques.
Configuration de WireGuard sur le serveur
Je fais tout sur Ubuntu 18.04, mais dans la documentation officielle il y a des instructions d'installation pour tous les OS connus et pas très.
L'installation
sudo add-apt-repository ppa:wireguard/wireguard
En cas d'erreur
sudo: add-apt-repository: command not found
Installer les propriétés du logiciel communes - le package offre la possibilité d'ajouter et de supprimer PPA
sudo apt install software-properties-common
sudo apt update sudo apt install wireguard-dkms wireguard-tools
Nous générons des clés pour le serveur. Nous enregistrerons les clés dans le répertoire WireGuard pour plus de commodité.
cd /etc/wireguard/ wg genkey | tee privatekey-server | wg pubkey > publickey-server
Par conséquent, il y aura une clé privée dans le fichier privatekey-server et une clé publique dans le fichier publickey-server.
Nous générons également immédiatement une clé pour le client:
wg genkey | tee privatekey-client | wg pubkey > publickey-client

La configuration
La configuration est stockée dans /etc/wireguard/wg0.conf. Le côté serveur ressemble à ceci:
[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
Adresse - adresse de l'interface wg (adresse à l'intérieur du tunnel)
PrivateKey - Clé privée (privatekey-server)
ListenPort - Le port sur lequel le service attend pour se connecter
Eh bien, nous faisons du masquage, car nous allons utiliser ce serveur pour accéder à Internet
Veuillez noter que le nom de l'interface dans votre cas peut différer:
Partie client
[Peer] PublicKey = publickey-client AllowedIPs = 192.168.100.3/24
PublicKey - la clé publique de notre routeur (publickey-client)
Les IP autorisés sont les sous-réseaux qui seront disponibles via ce tunnel. Le serveur n'a besoin que d'accéder à l'adresse client.
Les deux parties sont stockées dans une seule configuration.
Activez le démarrage automatique au redémarrage:
systemctl enable wg-quick@wg0
Nous faisons du serveur un routeur:
sysctl -w net.ipv4.ip_forward=1
Configurez le pare-feu. Supposons que nous ayons uniquement WireGuard et ssh sur notre serveur:
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
Enregistrez la configuration iptables:
sudo apt-get install iptables-persistent sudo netfilter-persistent save
Nous élevons l'interface wg pour la première fois manuellement:
wg-quick up wg0

Le serveur WireGuard est prĂŞt.
UPD 27/06/19 Si votre fournisseur utilise toujours PPoE, vous devez ajouter une règle. Merci denix123
iptables -t mangle -I POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Configuration du routeur
J'utilise la version 18.06.1 d'OpenWrt sur Xiaomi mi 3G et Asus RT-N16.
La logique du routeur
Nous chargeons les listes, les mettons dans iptables, iptables marque toutes les adresses de ces listes avec un marqueur 0x1. De plus, tous les paquets marqués de 0x1 vont dans une table de routage distincte, tous les paquets tombant dans cette table de routage passent par l'interface wg.

Installation du package
Quant à l'espace occupé sur le flash, tout aura besoin d'environ 0,9 Mo. Si vous avez un très mauvais endroit, remplacez curl par wget et vous n'aurez peut-être pas besoin d'installer dnscrypt-proxy.
Nous mettons des paquets. Dans OpenWrt, cela est facile Ă faire via le gestionnaire de paquets opkg:
opkg update opkg install ipset wireguard curl
Téléchargez les listes
Tout ce qui peut être fait via les fonctionnalités standard d'OpenWrt se fait par leur intermédiaire. Tout le reste (sauf hotplug) je mets dans un petit script:
Les listes de sous-réseaux et d'adresses interdits sont obtenues par fichiers. Pour eux, nous créons un répertoire dans / tmp. Dans / tmp - car il s'agit de RAM, une telle fonctionnalité d'OpenWrt est assez pratique. Cela ne vaut pas la peine d'écrire à nouveau quelque chose sur la ROM du routeur.
Nous pompons les listes avec antifilter.download curl, le drapeau z signifie que curl téléchargera le fichier uniquement si le fichier distant est différent du fichier local ou s'il ne l'est pas, comme par exemple lors du chargement d'un routeur.
subnet.lst - une liste de sous-réseaux bloqués; il ne change pas souvent.
ipsum.lst est une liste d'adresses bloquées, qui est résumée par masque. Au lieu de 150 000 enregistrements, nous en obtenons 15 000 - commodément.
Après avoir les fichiers, nous redémarrons le pare-feu, cela est nécessaire pour que l'ipset fonctionne et ajoute des listes à iptables, nous configurerons l'ipset dans / etc / config / firewall.
Ce script que nous ajoutons dans /etc/init.d/ sera appelé hirkn. Rendez-le exécutable
chmod +x /etc/init.d/hirkn
Maintenant, nous avons non seulement un script, mais un service complet. Pour qu'il démarre au démarrage, nous créons un lien symbolique dans /etc/rc.d. Nous en avons besoin pour démarrer après tous les autres services, nous créons donc le préfixe S99
ln -s /etc/init.d/hirkn /etc/rc.d/S99hirkn
Les listes doivent ĂŞtre mises Ă jour de temps en temps, nous ajoutons un enregistrement dans cron:
crontab -e
0 4 * * * /etc/init.d/hirkn
Il semble tout à fait suffisant de les mettre à jour une fois par jour. Gardez à l'esprit que lors de l'ajout de listes à l'ipset, le réseau tombe, dans mon cas, c'est 2 secondes.
UPD : Si vous ne voulez pas de pauses, alors sigo73 et Grayver ont suggéré dans les commentaires comment faire.
Allumez également la couronne, par défaut, elle est désactivée:
/etc/init.d/cron enable /etc/init.d/cron start
Configuration de la table de routage
Créez une table de routage pour le trafic à travers le tunnel en ajoutant simplement la ligne:
99 vpn
dans le fichier / etc / iproute2 / rt_tables.
Vous pouvez créer une route par défaut pour la table "vpn" via l'interface wg avec la commande:
ip route add table vpn default dev wg0
Mais lorsque vous redémarrez le réseau, l'itinéraire disparaît, nous créons donc le fichier 30-rknroute dans le répertoire /etc/hotplug.d/iface/ avec un contenu simple:
Cela signifie que lorsque vous activez / désactivez les interfaces, notre itinéraire sera ajouté. Et en conséquence, cet itinéraire sera toujours enregistré.
Configuration du réseau
Nous devons configurer WireGuard et la règle pour les paquets étiquetés 0x1.
La configuration de WireGuard se trouve dans / etc / config / network
La partie "serveur":
config interface 'wg0' option private_key 'privatekey-client' list addresses '192.168.100.3/24' option listen_port '51820' option proto 'wireguard'
private_key est le client de clé privée que nous avons généré lors de la configuration du serveur
liste des adresses - adresse de l'interface wg
listen_port - le port sur lequel WireGuard accepte les connexions. Mais la connexion se fera via le port du serveur, donc ici nous n'ouvrirons pas le port sur le pare-feu pour cela
proto - spécifiez le protocole afin que openwrt comprenne qu'il s'agit d'une configuration WireGuard
Partie "Client":
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 - clé publickey-server
allowed_ips - sous-réseaux dans lesquels le trafic peut passer par le tunnel, dans notre cas aucune restriction n'est requise, donc 0.0.0.0/0
route_allowed_ips - un indicateur qui fait un itinéraire via l'interface wg pour les réseaux répertoriés à partir du paramètre allowed_ips. Dans notre cas, ce n'est pas nécessaire, iptables fait ce travail
endpoint_host - ip / url de notre serveur wg
persistent_keepalive - intervalle de temps après lequel les paquets sont envoyés pour prendre en charge la connexion
endpoint_port - port wireguard sur le serveur
Nous allons également ajouter une règle à la configuration du réseau qui enverra tout le trafic marqué 0x1 vers la table de routage "vpn":
config rule option priority '100' option lookup 'vpn' option mark '0x1'
Configuration du pare-feu
Nous ajoutons deux règles pour marquer les packages, elles ne rentrent pas dans la syntaxe UCI openwrt, nous les ajoutons donc "telles quelles" à /etc/firewall.user.
UPD : Grayver a suggéré qu'ils s'intègrent assez bien. Nous les avons configurés après avoir configuré l'ipset
La configuration du pare-feu se trouve dans / etc / config / firewall
Ajoutez une zone pour le protège-fil. Dans openwrt, les zones sont des chaînes personnalisées dans iptables. Ainsi, une zone avec une / plusieurs interfaces est créée et des règles y sont déjà accrochées. La zone pour wg ressemble à ceci:
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'
Nous autorisons uniquement le trafic Ă quitter l'interface et Ă activer le masquage.
Vous devez maintenant activer le transfert de la zone lan vers la zone wg:
config forwarding option src 'lan' option dest 'wg'
Eh bien, la dernière chose est de créer des listes dans iptables en utilisant 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'
fichier de chargement - le fichier dont nous prenons la liste
nom - nom de notre liste
stockage , correspondance - nous spécifions ici comment stocker et quel type de données. Nous allons stocker le type "sous-réseau"
UPD : Si vous souhaitez utiliser la liste des adresses IP individuelles, vous devez augmenter la taille de la liste des ipsets. Dans la configuration ipset ajouter
option hashsize '1000000' option maxelem '1000000'
Sinon, vous obtiendrez une erreur
ipset v6.38: Hash is full, cannot add more elements
UPD : ajouter deux règles d'étiquetage des packages
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'
Ces règles impliquent que tous les paquets allant aux sous-réseaux des listes vpn_subnets et vpn_ipsum doivent être marqués avec 0x1.
Après cela, nous redémarrons le réseau:
/etc/init.d/network restart

et exécutez le script:
/etc/init.d/hirkn

Après avoir élaboré le script, tout devrait fonctionner pour vous. Vérifiez l'itinéraire sur le client du routeur:
mtr/traceroute telegram.org/linkedin.com

Bonus configurer DNSCrypt
Pourquoi? Votre fournisseur peut soigneusement remplacer l'adresse IP de la ressource bloquée, vous redirigeant ainsi vers votre adresse IP avec un talon, eh bien, notre contournement IP n'aidera pas dans ce cas. Pour la substitution, il n'est pas toujours nécessaire d'utiliser le serveur DNS du fournisseur, vos demandes peuvent être interceptées et les réponses seront substituées. Eh bien, au fait, non seulement le fournisseur peut le faire.
opkg install dnscrpt-proxy
Configurez la configuration / etc / config / dnscrypt-proxy comme ceci:
config dnscrypt-proxy ns1 option address '127.0.0.1' option port '5353' option resolver 'cpunks-ru'
Nous avons donc le service dnscrypt sur le port 5353 disponible sur localhost.
Resolver est un serveur DNS prenant en charge le chiffrement. Sur le routeur, le fichier /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv contient une liste des serveurs disponibles au moment de la sortie de la version installée de dnscrypt. Et voici https://dnscrypt.info/public-servers/ en général tous les serveurs dnscrypt disponibles. Vous pouvez choisir un autre résolveur et / ou ajouter des serveurs pour la tolérance aux pannes. Gardez à l'esprit que pour que DNSCrypt fonctionne avec le résolveur sélectionné, il doit être spécifié dans dnscrypt-resolvers.csv.
Nous configurons dnsmasq pour fonctionner avec dnscrypt. Dans / etc / config / dhcp, mettez la ligne en commentaire:
option resolvfile '/tmp/resolv.conf.auto'
afin que les serveurs DNS du fournisseur ne soient pas impliqués.
Et ajoutez:
list server '/pool.ntp.org/208.67.222.222' list server '127.0.0.1#5353'
L' entrée du serveur de liste «domaine / ip_dns» indique le serveur DNS à utiliser pour résoudre le domaine spécifié. Ainsi, nous n'utilisons pas dnscrypt pour la synchronisation ntp - il est important que le service dnscrypt ait l'heure actuelle.
Lorsque le routeur se charge, le script hirkn s'exécute plus rapidement que le démarrage de dnscrypt, donc le domaine antifilter.download ne se résout pas et les listes ne sont pas téléchargées. Vous pouvez faire un retard ou autre chose à venir, mais pour l'instant je ne vois aucune raison.
UPD : besoin d'ajouter une ligne
START=99
au script hirkn
En conséquence, nous obtenons un tel insert dans la configuration:
UPD : Sur certains appareils, DNSCrypt démarre quand même après le script. La manière la plus simple de résoudre ce problème consiste à ajouter la ligne dans / etc / config / dhcp
list server '/antifilter.download/208.67.222.222'
Désactiver l'utilisation du fournisseur DNS pour l'interface WAN
Dans / etc / config / network ajoutez la ligne
option peerdns '0'
Ă l'interface wan.
Nous obtenons cette configuration
config interface 'wan' option ifname 'eth0.2' option proto 'dhcp' option peerdns '0'
Redémarrez le réseau
/etc/init.d/network restart
Ajoutez au démarrage et démarrez dnscrypt:
/etc/init.d/dnscrypt-proxy enable /etc/init.d/dnscrypt-proxy start
Redémarrez dnsmasq:
/etc/init.d/dnsmasq restart

Illustration du travail sans DNSCrypt et avec DNSCrypt
Déployé automatiquement avec Ansible
Playbook et modèles sont sur github . Il utilise un module , il n'a pas besoin de python sur le routeur et il y a un support pour uci. J'ai essayé de m'assurer que votre configuration OpenWrt restait intacte, mais soyez prudent quand même.
Installez le module gekmihesg / ansible-openwrt:
ansible-galaxy install gekmihesg.openwrt
Copiez le playbook et tempeyta:
cd /etc/ansible git clone https://github.com/itdoginfo/ansible-openwrt-hirkn mv ansible-openwrt-hirkn/* . rm -rf ansible-openwrt-hirkn
Ajoutez votre routeur aux hĂ´tes:
[openwrt] 192.168.1.1
Remplacez vos variables dans 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
Assurez-vous de définir:
wg_server_address - serveur wireguard ip / url
wg_private_key , wg_public_key - clé privée du client et du serveur public
Le reste ne peut pas être changé ou changé, selon la configuration du serveur WireGuard
Lancer le playbook
ansible-playbook playbooks/hirkn.yml
Après avoir terminé le playbook, le routeur commencera immédiatement à contourner les verrous via votre serveur Wireguard.
Pourquoi pas BGP?
Sous openwrt, il existe deux utilitaires qui implémentent BGP - quagga et bird. Quagg je n'ai pas pu obtenir de données d'antifiltre. Bird s'est lié d'amitié avec le service à partir d'un demi-coup de pied, mais malheureusement je n'ai pas compris comment forcer l'interface par défaut à être ajoutée aux sous-réseaux reçus. (Je serai heureux de savoir comment cela peut être mis en œuvre).
Dans les commentaires sur ces articles, j'ai vu que les routeurs des gens étaient «réfléchis» pendant un certain temps, lorsqu'ils mettaient des listes dans la table de routage. Avec l'implémentation via ipset, mon Xiaomi mi 3G réfléchit pendant 2 secondes (Asus rt-n16 pendant 5 secondes), lorsque vous lui fournissez une liste de 15 mille sous-réseaux. Avec plus de travail, je n'ai pas remarqué la charge sur le processeur.
Tous les documents ne sont pas un appel à l'action et sont présentés pour se familiariser avec les fonctionnalités du système d'exploitation Linux.