sni-proxy: Beschreibung der Funktionsweise
01-env build environment Details
02-git-checkout git checkout Details
03-hugo-version hugo version Details
04-hugo-build hugo build Details
05-preview website preview Details
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
Johannes Kimmel 2023-01-24 15:22:38 +01:00
parent 3ed483cabb
commit 56550ee12e
1 changed files with 22 additions and 7 deletions

View File

@ -15,17 +15,24 @@ Technik, um HTTPS Verbindungen weiterzuleiten, ohne die Verschlüsselung aufzubr
## Anwendung: HTTPS Website im Freifunk hosten
Innerhalb des Freifunk Netzes war es schon immer recht simpel Websites zu hosten. Dank IPv6 und wie es im Freifunk Franken Netz umgesetzt ist, kann jeder sogar globale IPv6 Adressen nutzen. Man ist also weltweit per IPv6 erreichbar. Damit ist es recht einfach von einem kleinen Computer zuhause Services im Internet bereit zu stellen, ohne einen Server mieten zu müssen. Leider ist man gelegentlich trotzdem zusätzlich auf Erreichbarkeit via IPv4 angewießen. Leider haben wir im Freifunk Franken Netz nur eine sehr begrenzte Anzahl an IPv4 Adressen und können daher nicht jedem Nutzer eine globale Adresse zur Verfügung stellen.
Innerhalb des Freifunk Netzes war es schon immer recht simpel Websites zu hosten. Dank IPv6 und wie es im Freifunk Franken Netz umgesetzt ist, kann jeder sogar globale IPv6 Adressen nutzen. Man ist also weltweit per IPv6 erreichbar. Damit ist es einfach auch von einem kleinen Computer zuhause Services im Internet bereit zu stellen, ohne einen Server mieten zu müssen. Leider ist man gelegentlich trotzdem zusätzlich auf Erreichbarkeit via IPv4 angewiesen. Im Freifunk Franken Netz haben wir allerdings nur eine sehr begrenzte Anzahl an IPv4 Adressen und können daher nicht jedem Nutzer eine globale Adresse zur Verfügung stellen.
Mit dem [SNI Proxy]({{% relref "sni.fff.community.md" %}}), wie er auf [sni.fff.community][] betrieben wird, kann man seine IPv6-only Websites auch für IPv4 Geräte verfügbar machen. Dazu muss man zunächst einen `AAAA` DNS Eintrag auf die gewünschte IPv6 Adresse setzen. Als IPv4 Adresse für den `A` DNS Record wählt man die öffentliche IPv4, wie sie auf der Anleitung von [sni.fff.community][] steht. Der Service hat eine öffentlich zugängliche IPv4 Adresse und kann dadurch IPv4 Verbindungen entgegen nehmen.
Mit dem [SNI Proxy]({{% relref "sni.fff.community.md" %}}), wie er auf [sni.fff.community][] betrieben wird, kann man seine IPv6-only Websites auch für IPv4-only Geräte verfügbar machen, indem man:
Der SNI Proxy inspiziert dann die ersten Bytes und ermittelt welcher Hostname angesprochen ist. Der Proxy baut dann eine Verbindung via IPv6 zu dem Webserver auf und leitet dann sämtliche Bytes einfach weiter. Dabei wird keine Verschlüsselung aufgebrochen. Dadurch funktioniert auch der Betrieb mit [Let's Encrypt Certificates](https://letsencrypt.org/).
1. einen `AAAA` DNS Eintrag vom eigenen Webservice auf die gewünschte IPv6 Adresse setzt
2. für den `A` DNS Eintrag die IPv4 Adresse wählt, wie sie auf der Anleitung von [sni.fff.community][] steht
Der Service hat eine öffentlich zugängliche IPv4 Adresse und kann dadurch IPv4 Verbindungen entgegen nehmen.
Der SNI Proxy inspiziert die ersten Bytes und ermittelt welcher Hostname angesprochen ist. Der Proxy baut dann eine Verbindung via IPv6 zu dem Webserver auf und leitet dann sämtliche Bytes zwischen Client und Server einfach weiter. Dabei wird keine Verschlüsselung aufgebrochen. Dadurch funktioniert insbesondere auch der Betrieb mit [Let's Encrypt Certificates](https://letsencrypt.org/) und Ende-zu-Ende Verschlüsselung bleibt erhalten.
## Funktionsweise im Detail
### TLS Handshake
Wireshark mitschnitt beim Verbindungsaufbau nach <https://wiki.freifunk-franken.de>
Der Proxy macht sich zu Nutze, dass selbst bei einer verschlüsselten Verbindung via HTTPS häufig der Zielhostname in Klartext übermittelt wird (SNI: Server Name Indication).
Hier ein gekürzter Wireshark Mitschnitt beim Verbindungsaufbau nach <https://wiki.freifunk-franken.de>
```
...
@ -42,10 +49,10 @@ Transport Layer Security
...
```
Die aufgerufene Domain wird selbst bei `https://` im Klartext übertragen!
### IPv6
Sind Client und Server IPv6-fähig passiert der Verbindungsaufbau ganz normal direkt über IPv6 ohne extra Proxy.
```mermaid
sequenceDiagram
participant client as Client<br>2001:db8::
@ -53,13 +60,15 @@ sequenceDiagram
participant DNS
client ->>+ DNS: AAAA? example.com
DNS -->>- client: 2001:db8::
DNS -->>- client: 2001:db8:1::
client ->>+ srv: https://example.com
srv -->- client: Connection
```
### IPv4
Für einen IPv4-only Client und einem IPv6-only Server sieht es folgendermaßen aus: Der Client fragt die IPv4 Adresse vom Zielhost ab und bekommt die IPv4 Adresse vom SNI Proxy geliefert. Der Client baut sodann die Verbindung mit dem SNI Proxy auf und übermittelt dabei beim TLS Handshake das eigentliche Ziel. Der SNI Proxy fragt dann die IPv6 Adresse vom Server ab und stellt eine Verbindung her. Die bereits vom Client übertragenen Bytes werden einfach dorthin kopiert und die Antworten vom Server zurück in Verbindung zum Client gegeben.
```mermaid
sequenceDiagram
participant client as Client<br>192.0.2.1
@ -79,6 +88,10 @@ sequenceDiagram
### NAT46 Mode
Als Erweiterung kann der SNI Proxy noch die Adresse anpassen, mit der die Verbindungen zu den Servern aufgebaut wird. Das ist sinnvoll, damit aus der Sicht vom Server nicht alle Clients von der selben IPv6 kommen. Damit lassen sich also im Notfall auch Firewall regeln bauen, sollte aus einem bestimmten IP Bereich vermehrt Angriffe kommen. Man muss also nicht gleich sämtlichen Verkehr vom SNI Proxy sperren.
Dazu bettet der SNI Proxy die 4 Bytes aus der Adresse vom Client in die unteren Bytes der IPv6 Adresse mit der der SNI Proxy die Verbindung aufbaut:
```mermaid
sequenceDiagram
participant client as Client<br>192.0.2.1
@ -91,4 +104,6 @@ sequenceDiagram
deactivate sni
```
Im Beispiel hat der Client die IP `192.0.2.1`. Diese 4 Bytes entsprechen `c000:201` in IPv6 Hexadezimalschreibweise. Zum SNI Proxy selber wird nicht nur eine IPv6 Adresse, sondern ein ganzen `/96` Netz geroutet. Damit sind genug Adressen vorhanden, um das ganze IPv4 Internet in IPv6 Adressen einzubetten. Der SNI Proxy erzeugt die Adresse, indem er an das Prefix `2001:db8:2::/96` noch die übrigen 4 Bytes mit der Client Adresse auffüllt. Das ergibt dann die Adresse `2001:db8:2::c000:201`, die für die Verbindung benutzt wird.
[sni.fff.community]: https://sni.fff.community "Anleitung für den SNI Proxy"