docs/content/technik-und-konzepte/sni-proxy.md

95 lines
3.7 KiB
Markdown

---
title: "SNI Proxy"
date: 2022-11-18T00:16:35+01:00
---
Technik, um HTTPS Verbindungen weiterzuleiten, ohne die Verschlüsselung aufzubrechen
<!--more-->
## SNI
> Server Name Indication (SNI) ist eine Erweiterung des Standards Transport Layer Security (TLS), die es ermöglicht, dass sich mehrere verschlüsselt abrufbare Websites unterschiedlicher Domains einen Server auf dem TLS Port 443 teilen, auch wenn dieser nur eine IP-Adresse besitzt.
<https://de.wikipedia.org/wiki/Server_Name_Indication>
## 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.
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.
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/).
## Funktionsweise im Detail
### TLS Handshake
Wireshark mitschnitt beim Verbindungsaufbau nach <https://wiki.freifunk-franken.de>
```
...
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
...
Handshake Protocol: Client Hello
...
Extension: server_name (len=29)
...
Server Name Indication extension
...
Server Name: wiki.freifunk-franken.de
...
```
Die aufgerufene Domain wird selbst bei `https://` im Klartext übertragen!
### IPv6
```mermaid
sequenceDiagram
participant client as Client<br>2001:db8::
participant srv as example.com<br/>2001:db8:1::
participant DNS
client ->>+ DNS: AAAA? example.com
DNS -->>- client: 2001:db8::
client ->>+ srv: https://example.com
srv -->- client: Connection
```
### IPv4
```mermaid
sequenceDiagram
participant client as Client<br>192.0.2.1
participant sni as sni.fff.community<br>2001:db8:2::
participant srv as example.com<br/>2001:db8:1::
participant DNS
client ->>+ DNS: A? example.com
DNS -->>- client: 185.220.100.168
client ->>+ sni: https://example.com
sni ->>+ DNS: AAAA? example.com
DNS -->>- sni: 2001:db8:1::
sni ->>+ srv: tcp6://example.com:443
srv -->- client: Connection
deactivate sni
```
### NAT46 Mode
```mermaid
sequenceDiagram
participant client as Client<br>192.0.2.1
participant sni as sni.fff.community<br>2001:db8:2::
participant srv as example.com<br/>2001:db8:1::
client ->>+ sni: https://example.com
sni ->>+ srv: tcp6://example.com:443<br/>192.0.2.1 -> c000:201<br/>from 2001:db8:2::c000:201
srv -->- client: Connection
deactivate sni
```
[sni.fff.community]: https://sni.fff.community "Anleitung für den SNI Proxy"