# UniFi‑Switch ohne SSH hinter NAT‑Firewall adoptieren per DHCP‑Option 43

Diese Anleitung beschreibt Schritt für Schritt, wie du einen UniFi-Switch *(z. B. USW-Flex-Mini)*, der **kein SSH** bietet, mit einem Controller koppelst, der sich **hinter einer NAT-Firewall** befindet.   
Der Trick: Wir geben dem Switch die Controller-IP direkt via `DHCP Option 43`.

<div class="note" id="bkmrk-voraussetzungen-debi">**Voraussetzungen**  
- Debian-/Ubuntu-System mit zwei NICs (`eth0` = uplink/NAT-Seite, `eth1` = Switch-Port).
- UniFi Controller ist aus dem Uplink-Netz unter `10.0.0.1` erreichbar.
- Root-Zugriff auf den Debian-Host (oder du wechselst per `su -` auf root).

</div>## 1 · Netzdesign / Topologie

```
# uplink-LAN (10.0.0.0/24)
Internet/Router ──> eth0 (10.0.0.2/24) [Debian]  \
                                                   \ NAT (Masquerade)
                            eth1 (172.0.0.1/24)    [Debian] ──> UniFi-Switch (DHCP, z. B. 172.0.0.10)

# Controller liegt im Uplink-LAN: 10.0.0.1

```

- **eth1** bekommt ein separates /24 (hier `172.0.0.0/24`), damit der Switch sofort erkennt, dass `10.0.0.1` außerhalb seines Netzes liegt und das Gateway nutzt.
- **NAT / Masquerade** auf dem Debian-Host erlaubt dem Switch, den Controller über `eth0` zu erreichen.

## 2 · Interface- und System-Basis

```bash
# /etc/network/interfaces – Ausschnitt
auto eth1
iface eth1 inet static
    address 172.0.0.1
    netmask 255.255.255.0

```

```bash
# IP-Forwarding permanent einschalten (als root)
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-nat.conf
sysctl -p /etc/sysctl.d/99-nat.conf

```

```bash
# Einfaches Masquerading für das Subnetz 172.0.0.0/24 (als root)
iptables -t nat -A POSTROUTING -s 172.0.0.0/24 -o eth0 -j MASQUERADE

# Regeln persistent speichern – z. B. via iptables-persistent / netfilter-persistent

```

### 2.3 · Forwarding erlauben (falls dein Host ein “Sicherheitsbunker” ist)

Einige Systeme haben die Standard-Policy der `FORWARD`-Chain auf `DROP`. Dann reicht *Masquerading allein* nicht: Pakete werden zwar NAT-ted, aber beim Forwarding verworfen.

**Prüfen:**

```bash
iptables -L FORWARD -n -v
```

Wenn dort oben `policy DROP` steht (und die Zähler hochlaufen), erlaube Forwarding für dein Switch-Netz:

```bash
# Forwarding von "Switch-Seite" (eth1) ins Uplink (eth0) erlauben
iptables -I FORWARD 1 -i eth1 -o eth0 -s 172.0.0.0/24 -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

# Rückverkehr (Replies) wieder zurück zur Switch-Seite erlauben
iptables -I FORWARD 2 -i eth0 -o eth1 -d 172.0.0.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

```

**Hinweis:** Wenn deine Interface-Namen anders heißen (z. B. `enp0s31f6` statt `eth1` oder `wlp0s20f3` statt `eth0`), ersetze sie entsprechend.

Danach ggf. Regeln persistent speichern, sonst sind sie nach dem Reboot weg.

## 3 · ISC-DHCP-Server installieren &amp; konfigurieren

```bash
# als root
apt-get update
apt-get install isc-dhcp-server

```

### 3.1 Server-Interface festlegen

```bash
# /etc/default/isc-dhcp-server
INTERFACESv4="eth1"

```

### 3.2 `/etc/dhcp/dhcpd.conf`

```dhcp
subnet 172.0.0.0 netmask 255.255.255.0 {
  range 172.0.0.10 172.0.0.50;
  option routers 172.0.0.1;
  option broadcast-address 172.0.0.255;

  # *** UniFi-Magie: DHCP Option 43 ***
  # 01  -> Sub-Option 1  (Controller-IP)
  # 04  -> Länge in Bytes (4)
  # 0a 00 00 01 -> 10.0.0.1 in Hex
  option vendor-encapsulated-options 01:04:0a:00:00:01;

  # DNS für Clients (hier Cloudflare)
  option domain-name-servers 1.1.1.1, 1.0.0.1;
}

```

<div class="note" id="bkmrk-ip%C2%A0%E2%86%92%C2%A0hex%E2%80%91konvertieru">**IP → Hex-Konvertierung**  
</div>Jedes Oktett der Controller-IP in Hex schreiben:

<div class="note" id="bkmrk-10-0-0-1-hex">- 10 = `0a`
- 0 = `00`
- 0 = `00`
- 1 = `01`

`01:04:0a:00:00:01`</div>```bash
systemctl enable --now isc-dhcp-server
systemctl status isc-dhcp-server

```

## 4 · Firewall / Ports

<table id="bkmrk-port-protokoll-zweck"><thead><tr><th>Port</th><th>Protokoll</th><th>Zweck</th></tr></thead><tbody><tr><td>8080</td><td>TCP</td><td>Inform &amp; Adoption</td></tr><tr><td>3478</td><td>UDP</td><td>STUN</td></tr><tr><td>10001</td><td>UDP</td><td>Discovery (alt)</td></tr><tr><td>8443</td><td>TCP</td><td>Controller-GUI/API</td></tr></tbody></table>

Achte darauf, dass diese Ports von `172.0.0.0/24` über NAT zu `10.0.0.1` passieren dürfen.

## 5 · Switch anschließen &amp; adoptieren

1. Switch auf Werkseinstellungen zurücksetzen (Reset-Taster &gt; 5 s).
2. An `eth1` des Debian-Hosts stecken.
3. Mit `tcpdump` überprüfen, dass Option 43 im `DHCPACK` auftaucht:  
    ```bash
    tcpdump -ni eth1 port 67 or port 68 | grep -i "Vendor specific"
    ```
4. Controller-UI öffnen `https://10.0.0.1:8443` ➜ *Devices » Pending Adoption*.  
    Gerät erscheint? → **Adopt**.

### Debugging-Checks

```bash
# Kommt der Switch raus?
ping -c3 10.0.0.1

# Siehst du Inform-Traffic?
tcpdump -ni eth1 host 10.0.0.1 and port 8080

# Controller-Logs (Pfad je nach Installation/Container ggf. anders)
tail -f /usr/lib/unifi/logs/server.log

```

<div class="warn" id="bkmrk-ger%C3%A4t-taucht-nicht-a">**Gerät taucht nicht auf?**  
- Option 43 fehlt ➜ DHCP checken.
- NAT/Firewall blockt Port 8080 ➜ iptables-Regeln prüfen (Forwarding + NAT!).
- Falsche Subnetzmaske ➜ Switch glaubt, Controller sei lokal.

</div>## Anhang A · IP-Adresse in Hexadezimal umrechnen – Schritt für Schritt

**Warum überhaupt Hex?**  
DHCP-Option 43 braucht die Controller-IP als rohe Bytefolge. Bytes schreibt man in der Netzwerktechnik üblich in *Hexadezimal* (“Hex”). Ein Byte kann Werte von `00` bis `ff` (= 0 – 255 dezimal) annehmen.

### 1 · Vier Oktette der IP aufschreiben

Beispiel-IP unseres Controllers:

```
10 . 0 . 0 . 1
```

### 2 · Jedes Oktett einzeln nach Hex konvertieren

<table id="bkmrk-dezimal-rechenweg-he"><thead><tr><th>Dezimal</th><th>Rechenweg</th><th>Hexadezimal</th></tr></thead><tbody><tr><td>10</td><td>10 / 16 = 0 Rest 10 → 0 = `0`, 10 = `a`</td><td>`0a`</td></tr><tr><td>0</td><td>0 = 0 → `00`</td><td>`00`</td></tr><tr><td>0</td><td>0 = 0 → `00`</td><td>`00`</td></tr><tr><td>1</td><td>1 / 16 = 0 Rest 1 → `01`</td><td>`01`</td></tr></tbody></table>

**Merksatz:** Wenn das Ergebnis nur ein Hex-Zeichen hat (z. B. `a`), wird immer eine führende Null ergänzt → `0a`. So entstehen exakt vier Byte.

### 3 · Bytes zusammenfügen

```
0a 00 00 01
```

### 4 · In DHCP-Option 43 einbauen

Die Struktur lautet: `01 : 04 : <IP-Hex-Byte1> : <IP-Hex-Byte2> : <IP-Hex-Byte3> : <IP-Hex-Byte4>`

- `01` = Sub-Option 1 (Controller-IP)
- `04` = Länge (4 Byte)
- `0a:00:00:01` = die vier Hex-Bytes von oben

```
option vendor-encapsulated-options 01:04:0a:00:00:01;
```

### Schnell-Check mit Python

Für größere Netze lohnt es sich, nicht zu rechnen, sondern einen Einzeiler zu nutzen:

```bash
python3 -c 'import sys,ipaddress; \
print(":".join(f"{b:02x}" for b in ipaddress.IPv4Address(sys.argv[1]).packed))' \
10.0.0.1
```

Ausgabe: `0a:00:00:01` – genau wie von Hand.

### Spickzettel 0 – 255 → Hex

<table id="bkmrk-dez-hex-dez-hex-dez-"><thead><tr><th>Dez</th><th>Hex</th><th>Dez</th><th>Hex</th><th>Dez</th><th>Hex</th><th>Dez</th><th>Hex</th></tr></thead><tbody><tr><td>0</td><td>00</td><td>16</td><td>10</td><td>128</td><td>80</td><td>240</td><td>f0</td></tr><tr><td>1</td><td>01</td><td>32</td><td>20</td><td>144</td><td>90</td><td>241</td><td>f1</td></tr><tr><td>2</td><td>02</td><td>64</td><td>40</td><td>160</td><td>a0</td><td>250</td><td>fa</td></tr><tr><td>3</td><td>03</td><td>100</td><td>64</td><td>176</td><td>b0</td><td>255</td><td>ff</td></tr></tbody></table>

Damit können auch Azubis ohne Vorwissen eine IP schnell in Hex umbrechen und die Option 43 korrekt setzen.