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:
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:
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:
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.