Pinpoint PKH-Blockierung auf einem OpenWrt-Router mit WireGuard und DNSCrypt

Was ist der Unterschied zu ähnlichen Materialien?


  • Reine OpenWrt-Implementierung
  • Verwenden von WireGuard
  • Die Konfiguration des Routers wird mithilfe von OpenWrt-Konfigurationen und nicht in einem Skript organisiert
  • Es gibt Situationen beim Neustart des Netzwerks und beim Neustart
  • Es verbraucht wenig Router-Ressourcen: Gesperrte Subnetze sind in iptables und nicht in Routing-Tabellen enthalten. Was ermöglicht es Ihnen, dieses Geschäft auch auf schwachen Geräten bereitzustellen?
  • Automatisieren Sie die Konfiguration mit Ansible (auf dem Router ist kein Python erforderlich).

Videoversion



Warum OpenWrt und WireGuard?


OpenWrt ist auf so vielen Modellen von Soho-Routern installiert, dass es nach Herzenslust konfiguriert und erweitert wird. Jetzt sind viele Router-Firmwares Add-Ons über OpenWrt.


Wireguard wird wegen seiner schnellen und einfachen Einrichtung und auch wegen der hohen Übertragungsgeschwindigkeit durch den Tunnel verwendet.


Ein bisschen über WireGuard


In unserem Fall ist der Server ein VPS außerhalb des ILV, der Client ist zu Hause ein OpenWrt-Router. Wenn du gehen willst Pornolab Telegramm, Ihr Router leitet den Datenverkehr mit WireGuard über einen Server.
WireGuard stellt eine Site-to-Site-Verbindung her, d. H. Sowohl der Server als auch der Client haben die Server- und Clientseite der Konfiguration. Wenn es nicht klar ist, wird es klar, wenn Sie die Konfiguration sehen.


Der Server und der Client haben ihre eigenen privaten und öffentlichen Schlüssel.


WireGuard auf dem Server konfigurieren


Ich mache alles unter Ubuntu 18.04, aber in der offiziellen Dokumentation finden Sie Installationsanweisungen für alle bekannten und nicht sehr Betriebssysteme.


Installation


sudo add-apt-repository ppa:wireguard/wireguard 

Wenn ein Fehler auftritt
 sudo: add-apt-repository: command not found 


Installieren Sie software-properties-common - das Paket bietet die Möglichkeit, PPA hinzuzufügen und zu entfernen
 sudo apt install software-properties-common 


 sudo apt update sudo apt install wireguard-dkms wireguard-tools 

Wir generieren Schlüssel für den Server. Wir werden die Schlüssel der Einfachheit halber im WireGuard-Verzeichnis speichern.


 cd /etc/wireguard/ wg genkey | tee privatekey-server | wg pubkey > publickey-server 

Dementsprechend gibt es einen privaten Schlüssel in der Privatekey-Server-Datei und einen öffentlichen Schlüssel in der Publickey-Server-Datei.
Wir generieren auch sofort einen Schlüssel für den Kunden:


 wg genkey | tee privatekey-client | wg pubkey > publickey-client 


Konfiguration


Die Konfiguration wird in /etc/wireguard/wg0.conf gespeichert. Die Serverseite sieht folgendermaßen aus:


 [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 für die wg-Schnittstelle (Adresse innerhalb des Tunnels)
PrivateKey - Privater Schlüssel (Privatekey-Server)
ListenPort - Der Port, an dem der Dienst auf eine Verbindung wartet


Nun, wir maskieren uns, weil wir diesen Server verwenden werden, um auf das Internet zuzugreifen
Bitte beachten Sie, dass der Name der Schnittstelle in Ihrem Fall abweichen kann:


Client-Teil


 [Peer] PublicKey = publickey-client AllowedIPs = 192.168.100.3/24 

PublicKey - der öffentliche Schlüssel unseres Routers (publickey-client)
AllowedIPs sind die Subnetze, die über diesen Tunnel verfügbar sind. Der Server benötigt nur Zugriff auf die Clientadresse.


Beide Teile sind in einer Konfiguration gespeichert.


Aktivieren Sie den Autostart beim Neustart:


 systemctl enable wg-quick@wg0 

Wir machen den Server zu einem Router:


 sysctl -w net.ipv4.ip_forward=1 

Konfigurieren Sie die Firewall. Angenommen, wir haben nur WireGuard und ssh auf unserem Server:


 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 

Speichern Sie die iptables-Konfiguration:


 sudo apt-get install iptables-persistent sudo netfilter-persistent save 

Wir heben die wg-Schnittstelle zum ersten Mal manuell an:


 wg-quick up wg0 


Der WireGuard-Server ist bereit.


UPD 27.06.19 Wenn Ihr Anbieter weiterhin PPoE verwendet, müssen Sie eine Regel hinzufügen. Danke denix123


 iptables -t mangle -I POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 

Router-Setup


Ich verwende OpenWrt Version 18.06.1 auf Xiaomi mi 3G und Asus RT-N16.


Die Logik des Routers


Wir laden die Listen, fügen sie in iptables ein, iptables markiert alle Adressen aus diesen Listen mit einem 0x1-Marker. Ferner werden alle mit 0x1 gekennzeichneten Pakete in eine separate Routing-Tabelle verschoben, wobei alle in diese Routing-Tabelle fallenden Pakete die wg-Schnittstelle durchlaufen.



Paketinstallation


Was den belegten Platz auf dem Blitz betrifft, benötigt alles ungefähr 0,9 MB. Wenn Sie einen sehr schlechten Platz haben, ersetzen Sie curl durch wget und Sie müssen möglicherweise dnscrypt-proxy nicht installieren.


Wir legen Pakete. In OpenWrt ist dies über den opkg-Paketmanager einfach zu bewerkstelligen:


 opkg update opkg install ipset wireguard curl 

Listen herunterladen


Alles, was mit den Standardfunktionen von OpenWrt erreicht werden kann, erfolgt über sie. Alles andere (außer Hotplug) habe ich in ein kleines Skript geschrieben:


 #!/bin/sh START=99 dir=/tmp/lst mkdir -p $dir echo "Run download lists" curl -z $dir/subnet.lst https://antifilter.download/list/subnet.lst --output $dir/subnet.lst curl -z $dir/ipsum.lst https://antifilter.download/list/ipsum.lst --output $dir/ipsum.lst echo "Firewall restart" /etc/init.d/firewall restart 

Listen verbotener Subnetze und Adressen werden von Dateien abgerufen. Für sie erstellen wir ein Verzeichnis in / tmp. In / tmp - da es sich um RAM handelt, ist eine solche Funktion von OpenWrt sehr praktisch. Es lohnt sich nicht, noch einmal etwas in das ROM des Routers zu schreiben.


Wir pumpen die Listen mit antifilter.download curl aus. Das z-Flag bedeutet, dass curl die Datei nur herunterlädt, wenn sich die entfernte Datei von der lokalen Datei unterscheidet oder wenn sie nicht vorhanden ist, wie dies beim Laden des Routers der Fall ist.


subnet.lst - Eine Liste blockierter Subnetze, die sich nicht oft ändert.
ipsum.lst ist eine Liste blockierter Adressen, die nach Maske zusammengefasst ist. Anstelle von 150.000 Datensätzen erhalten wir 15.000 - bequem.


Nachdem wir die Dateien haben, starten wir die Firewall neu. Dies ist erforderlich, damit ipset funktioniert und Listen zu iptables hinzugefügt werden. Wir konfigurieren ipset in / etc / config / firewall.


Dieses Skript, das wir in /etc/init.d/ hinzufügen, heißt hirkn. Mach es ausführbar


 chmod +x /etc/init.d/hirkn 

Jetzt haben wir nicht nur ein Skript, sondern einen ganzen Dienst. Damit es beim Booten startet, erstellen wir einen Symlink in /etc/rc.d. Wir brauchen es, um nach allen anderen Diensten zu starten, also machen wir das S99-Präfix


 ln -s /etc/init.d/hirkn /etc/rc.d/S99hirkn 

Listen müssen von Zeit zu Zeit aktualisiert werden, wir fügen Datensatz in cron hinzu:


 crontab -e 

 0 4 * * * /etc/init.d/hirkn 

Es scheint völlig ausreichend, sie einmal am Tag zu aktualisieren. Beachten Sie, dass beim Hinzufügen von Listen zu ipset das Netzwerk ausfällt. In meinem Fall sind es 2 Sekunden.
UPD : Wenn Sie keine Pausen möchten, haben sigo73 und Grayver in den Kommentaren vorgeschlagen, wie dies zu tun ist.


Schalten Sie auch die Krone ein. Standardmäßig ist sie deaktiviert:


 /etc/init.d/cron enable /etc/init.d/cron start 

Konfiguration der Routing-Tabelle


Erstellen Sie eine Routing-Tabelle für den Verkehr durch den Tunnel, indem Sie einfach die folgende Zeile hinzufügen:


 99 vpn 

in die Datei / etc / iproute2 / rt_tables.


Sie können eine Standardroute für die Tabelle "vpn" über die wg-Schnittstelle mit dem folgenden Befehl erstellen:


 ip route add table vpn default dev wg0 

Wenn Sie das Netzwerk jedoch neu starten, verschwindet die Route. Daher erstellen wir die 30-Knoten-Datei im Verzeichnis /etc/hotplug.d/iface/ mit einfachem Inhalt:


 #!/bin/sh ip route add table vpn default dev wg0 

Dies bedeutet, dass beim Ein- und Ausschalten der Schnittstellen unsere Route hinzugefügt wird. Dementsprechend wird diese Route immer registriert.


Netzwerkkonfiguration


Wir müssen WireGuard und die Regel für Pakete mit der Bezeichnung 0x1 konfigurieren.


Die WireGuard-Konfiguration befindet sich in / etc / config / network


Der "Server" Teil:


 config interface 'wg0' option private_key 'privatekey-client' list addresses '192.168.100.3/24' option listen_port '51820' option proto 'wireguard' 

private_key ist der privatekey-client, den wir bei der Konfiguration des Servers generiert haben
Listenadressen - wg-Schnittstellenadresse
listen_port - der Port, an dem WireGuard Verbindungen akzeptiert. Die Verbindung wird jedoch über den Port auf dem Server hergestellt, sodass wir hier den Port auf der Firewall nicht dafür öffnen
proto - Geben Sie das Protokoll an, damit openwrt versteht, dass es sich um eine WireGuard-Konfiguration handelt


"Client" Teil:


 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 - publickey-server key
allow_ips - Subnetze, in die Verkehr durch den Tunnel gelangen kann. In unserem Fall sind keine Einschränkungen erforderlich, daher 0.0.0.0/0
route_allowed_ips - Ein Flag, das aus dem Parameter allow_ips eine Route durch die wg-Schnittstelle für die aufgelisteten Netzwerke erstellt. In unserem Fall ist dies nicht erforderlich, iptables erledigt diese Arbeit
endpoint_host - IP / URL unseres WG-Servers
persistent_keepalive - Zeitintervall, nach dem Pakete gesendet werden, um die Verbindung zu unterstützen
endpoint_port - Wireguard-Port auf dem Server


Wir werden der Netzwerkkonfiguration auch eine Regel hinzufügen, die den gesamten mit 0x1 gekennzeichneten Datenverkehr an die Routing-Tabelle "vpn" sendet:


 config rule option priority '100' option lookup 'vpn' option mark '0x1' 

Firewall-Konfiguration


Wir fügen zwei Regeln zum Markieren von Paketen hinzu, die nicht in die openwrt-UCI-Syntax passen. Daher fügen wir sie "wie besehen" zu /etc/firewall.user hinzu.
UPD : Grayver schlug vor, dass sie recht gut passen. Wir setzen sie nach dem Einrichten von ipset


Die Firewall-Konfiguration befindet sich in / etc / config / firewall


Fügen Sie eine Zone für Wireguard hinzu. In openwrt sind Zonen benutzerdefinierte Ketten in iptables. Auf diese Weise wird eine Zone mit einer / mehreren Schnittstellen erstellt, an die bereits Regeln gehängt sind. Die Zone für wg sieht folgendermaßen aus:


 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' 

Wir erlauben nur dem Verkehr, die Schnittstelle zu verlassen und das Maskieren zu aktivieren.


Jetzt müssen Sie die Weiterleitung von der LAN-Zone zur WG-Zone aktivieren:


 config forwarding option src 'lan' option dest 'wg' 

Nun, das Letzte ist, Listen in iptables mit ipset zu erstellen:


 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 - die Datei, aus der wir die Liste entnehmen
name - name für unsere liste
Speicherung , Übereinstimmung - hier legen wir fest, wie und welche Art von Daten gespeichert werden sollen. Wir werden den Typ "Subnetz" speichern


UPD : Wenn Sie die Liste der einzelnen IP-Adressen verwenden möchten, müssen Sie die Größe der ipset-Liste erhöhen. In der Konfiguration ipset hinzufügen


  option hashsize '1000000' option maxelem '1000000' 

Andernfalls erhalten Sie eine Fehlermeldung


 ipset v6.38: Hash is full, cannot add more elements 

UPD : Fügen Sie zwei Regeln zum Beschriften von Paketen hinzu


 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' 

Diese Regeln implizieren, dass alle Pakete, die aus den Listen vpn_subnets und vpn_ipsum in die Subnetze gehen, mit 0x1 gekennzeichnet sein müssen.


Danach starten wir das Netzwerk neu:


 /etc/init.d/network restart 


und führen Sie das Skript aus:


 /etc/init.d/hirkn 


Nach dem Ausarbeiten des Skripts sollte alles für Sie funktionieren. Überprüfen Sie die Route auf dem Router-Client:


 mtr/traceroute telegram.org/linkedin.com 


Bonus DNSCrypt konfigurieren


Warum? Ihr Provider kann die IP-Adresse der blockierten Ressource sorgfältig ersetzen und Sie so mit einem Stub auf Ihre IP umleiten. In diesem Fall hilft unser IP-Bypass nicht weiter. Für die Ersetzung ist es nicht immer erforderlich, den DNS-Server des Anbieters zu verwenden. Ihre Anforderungen können abgefangen werden und die Antworten werden ersetzt. Das kann übrigens nicht nur der Anbieter.


 opkg install dnscrpt-proxy 

Konfigurieren Sie die Konfiguration / etc / config / dnscrypt-proxy folgendermaßen:


 config dnscrypt-proxy ns1 option address '127.0.0.1' option port '5353' option resolver 'cpunks-ru' 

Wir haben also den dnscrypt-Dienst auf Port 5353 auf localhost verfügbar.


Resolver ist ein DNS-Server, der die Verschlüsselung unterstützt. Auf dem Router enthält die Datei /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv eine Liste der verfügbaren Server zum Zeitpunkt der Veröffentlichung der installierten Version von dnscrypt. Und hier sind https://dnscrypt.info/public-servers/ im Allgemeinen alle verfügbaren dnscrypt-Server. Sie können einen anderen Resolver auswählen und / oder Server für die Fehlertoleranz hinzufügen. Beachten Sie, dass DNSCrypt in dnscrypt-resolvers.csv angegeben werden muss, damit es mit dem ausgewählten Resolver funktioniert.


Wir konfigurieren dnsmasq für die Arbeit mit dnscrypt. Kommentieren Sie in / etc / config / dhcp die Zeile aus:


 option resolvfile '/tmp/resolv.conf.auto' 

Damit sind die DNS-Server des Anbieters nicht beteiligt.


Und füge hinzu:


  list server '/pool.ntp.org/208.67.222.222' list server '127.0.0.1#5353' 

Der Eintrag 'domain / ip_dns' des Listenservers gibt an, welcher DNS-Server zum Auflösen der angegebenen Domäne verwendet werden soll. Daher verwenden wir dnscrypt nicht für die NTP-Synchronisation - es ist wichtig, dass der dnscrypt-Dienst die aktuelle Zeit hat.


Wenn der Router geladen wird, wird das Hirkn-Skript schneller ausgeführt als der Start von dnscrypt, sodass die Domäne antifilter.download nicht aufgelöst wird und die Listen nicht heruntergeladen werden. Sie können eine Verzögerung oder etwas anderes einfallen lassen, aber bisher sehe ich keinen Grund.
UPD : muss eine Zeile hinzufügen


 START=99 

zu hirkn Skript


Als Ergebnis erhalten wir eine solche Einfügung in der Konfiguration:


  #option resolvfile '/tmp/resolv.conf.auto' list server '/pool.ntp.org/208.67.222.222' list server '127.0.0.1#5353' 

UPD : Auf einigen Geräten wird DNSCrypt trotzdem nach dem Skript gestartet. Der einfachste Weg, dies zu beheben, besteht darin, die Zeile zu / etc / config / dhcp hinzuzufügen


  list server '/antifilter.download/208.67.222.222' 

Deaktivieren Sie die Verwendung von Provider-DNS für die WAN-Schnittstelle
Fügen Sie in / etc / config / network die Zeile hinzu


 option peerdns '0' 

zur WAN-Schnittstelle.
Wir bekommen diese Konfiguration


 config interface 'wan' option ifname 'eth0.2' option proto 'dhcp' option peerdns '0' 

Starten Sie das Netzwerk neu


 /etc/init.d/network restart 

Zum Start hinzufügen und dnscrypt starten:


 /etc/init.d/dnscrypt-proxy enable /etc/init.d/dnscrypt-proxy start 

Starten Sie dnsmasq neu:


 /etc/init.d/dnsmasq restart 


Illustration der Arbeit ohne DNSCrypt und mit DNSCrypt


Automatisch mit Ansible bereitgestellt


Playbook und Vorlagen sind auf Github . Es verwendet ein Modul , benötigt kein Python auf dem Router und es gibt Unterstützung für uci. Ich habe versucht sicherzustellen, dass Ihre OpenWrt-Konfiguration unberührt bleibt, aber seien Sie trotzdem vorsichtig.


Installieren Sie das gekmihesg / ansible-openwrt-Modul:


 ansible-galaxy install gekmihesg.openwrt 

Kopieren Sie das Spielbuch und Tempeyta:


 cd /etc/ansible git clone https://github.com/itdoginfo/ansible-openwrt-hirkn mv ansible-openwrt-hirkn/* . rm -rf ansible-openwrt-hirkn 

Fügen Sie Ihren Router zu Hosts hinzu:


 [openwrt] 192.168.1.1 

Ersetzen Sie Ihre Variablen in 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 

Stellen Sie sicher, dass Sie Folgendes einstellen:


wg_server_address - IP / URL-Wireguard-Server
wg_private_key , wg_public_key - privater Schlüssel des Clients und des öffentlichen Servers
Der Rest kann nicht geändert werden, je nachdem, wie der WireGuard-Server konfiguriert ist


Starten Sie das Playbook


 ansible-playbook playbooks/hirkn.yml 

Nach Abschluss des Playbooks beginnt der Router sofort, die Sperren durch Ihren Wireguard-Server zu umgehen.


Warum nicht BGP?


Unter openwrt gibt es zwei Dienstprogramme, die BGP implementieren - quagga und bird. Quagg Ich konnte keine Daten vom Antifilter sammeln. Bird hat sich nach einem halben Kick mit dem Service angefreundet, aber leider habe ich nicht verstanden, wie man das Hinzufügen der Standardschnittstelle zu den empfangenen Subnetzen erzwingt. (Ich werde froh sein zu wissen, wie dies umgesetzt werden kann).


In den Kommentaren zu solchen Artikeln habe ich gesehen, dass die Router von Personen eine Weile „nachdenklich“ waren, als sie Listen in die Routing-Tabelle einfügten. Bei der Implementierung über ipset denkt mein Xiaomi mi 3G 2 Sekunden lang nach (Asus rt-n16 5 Sekunden lang), wenn Sie ihm eine Liste mit 15.000 Subnetzen geben. Bei weiteren Arbeiten bemerkte ich die Belastung des Prozessors nicht.


Alle Materialien sind kein Aufruf zum Handeln und werden vorgestellt, um sich mit der Funktionalität des Linux-Betriebssystems vertraut zu machen.

Source: https://habr.com/ru/post/de440030/


All Articles