Starlink Mini 2 hinter CGNAT: Standorte erreichen, die umziehen

Starlink Mini 2 hinter CGNAT: Standorte erreichen, die umziehen

Starlink Mini 2 hinter CGNAT: Standorte erreichen, die umziehen

Kurz gesagt (geprüft am 2026-11-11): SpaceX nimmt Vorbestellungen für die Starlink Mini 2 an, vorerst nur auf Einladung. Die tragbare Antenne hat einen abnehmbaren Akku. Sie wird mehr Kameras, Sensoren, Feld-Laptops und temporäre Büros dort ans Netz bringen, wo keine Glasfaser liegt. Was ein Standardtarif ihnen nicht gibt, ist eine Adresse, die aus dem Internet erreichbar ist: IPv4 läuft bei Starlink standardmäßig über Carrier-Grade NAT (CGNAT), eingehende Verbindungen sind gesperrt. Wir haben den IPv4-Adressraum gezählt, den das Starlink-Netz ankündigt (990.208 Adressen für mehr als 12 Millionen Kunden), ein Skript geschrieben, das zeigt, ob ein Host hinter CGNAT sitzt, und vier Wege verglichen, einen wandernden Standort zu erreichen.

Quellen. Die Mini 2 laut Notebookcheck (Daniel Zlatev, 2026-11-10) und DishyTech (Colby Baber, 2026-11-09), Diskussion auf Hacker News mit 369 Punkten und 380 Kommentaren bis 2026-11-11. Adressrichtlinie: Artikel des Starlink Help Center "What IP address does Starlink provide?" und "IP Address", gelesen am 2026-11-11. Routingdaten: RIPEstat, abgefragt von unserem Skript am 2026-11-11.

Was an der Mini 2 neu ist

Merkmal Mini 2, laut Berichten vom 2026-11-10
Akku Abnehmbar, 71 Wh, bis 4,5 h (Angabe von SpaceX), Laden per USB-C mit 60 W
WLAN Wi-Fi 6 (die erste Mini hatte Wi-Fi 5)
Bauform IP67, 314 x 263 x 23,1 mm, 1,6 kg mit Akku und Ständer
Verfügbarkeit Vorbestellung auf Einladung für ausgewählte US-Kunden, weitere Länder später
Preis Offen: Kit für $249 und Akku für $50 im Code der Starlink-Website (DishyTech), anderswo $999 ohne Aufschlüsselung

Durchsatzwerte wurden nicht veröffentlicht. Für diesen Artikel zählt der Akku: Eine Antenne, die vier Stunden ohne Stromnetz läuft, wird von Standort zu Standort getragen, und das verändert, wie Sie erreichen, was dahinter hängt.

Das Adressproblem: CGNAT als Standard

Die Hilfeseiten von Starlink beschreiben zwei IPv4-Richtlinien. Standard ist CGNAT: Der Router bekommt eine Adresse aus 100.64.0.0/10, dem gemeinsam genutzten Bereich aus RFC 6598, viele Kunden teilen sich jede öffentliche Adresse, und eingehender IPv4-Verkehr ist nicht erlaubt. Eine öffentliche IPv4-Adresse gibt es nur als Option in Priority-Tarifen (die beiden Hilfeseiten benennen sie unterschiedlich: Local und Global Priority auf der einen, Priority, Mobile Priority und Maritime auf der anderen). Jeder Anschluss bekommt zudem ein IPv6-Präfix /56 per DHCPv6-PD, und laut Starlink funktioniert natives IPv6 auf allen Routern, Kits und Tarifen.

Für eine tragbare Antenne zählen zwei weitere Sätze. Die eigenen WLAN-Router von Starlink unterstützen weder Portweiterleitung noch Firewallregeln, weder für IPv4 noch für IPv6. Und die reservierte IPv4-Adresse und das IPv6-Präfix überstehen einen Neustart, können sich aber ändern, wenn die Antenne umgestellt wird oder ihre Software ein Update bekommt. Eine Antenne, die umzieht, ist eine Adresse, die umzieht.

Warum nicht jeder eine Adresse bekommt: unsere Zählung

Unser Skript fragte RIPEstat, was AS14593 (SPACEX-STARLINK) ankündigt: 2.274 IPv4-Präfixe mit 990.208 eindeutigen Adressen, überwiegend /23 und /24. Starlink meldete im Juni 2026 mehr als 12 Millionen aktive Kunden (Mezha). Das ist etwa eine öffentliche IPv4-Adresse pro 12 Kunden. Zum 90-Tage-Median von ip4.market für ein /24, $25,25 pro Adresse (Index aktualisiert am 2026-11-02, siehe IPv4-Preise), würde eine Adresse pro Kunde rund $303 Millionen kosten; der von AS14593 angekündigte Raum ist zu diesem Kurs rund $25 Millionen wert. Bei IPv6 ist es umgekehrt: 1.130 Präfixe, davon 668 /40, und ein /40 fasst 65.536 Kunden-/56, also fassen allein diese /40 rund 43,8 Millionen.

Grenzen der Zählung: RIPEstat lässt Routen weg, die weniger als 10 RIS-Peers sehen, Starlink kann Verkehr auch über andere AS-Nummern führen, und angekündigter Raum ist nicht genutzter Raum. Das Verhältnis erklärt trotzdem, warum CGNAT der Standard ist.

Skript: Sitzt dieser Host hinter CGNAT?

cgnat_check.js listet die Adressen des Hosts samt Art (öffentlich, RFC 1918, 100.64.0.0/10), fragt einen öffentlichen Endpunkt, welche Adresse er sieht, ermittelt das Netz, das sie ankündigt, und sagt, ob eingehendes IPv4 funktionieren kann. Mit einer AS-Nummer als Argument summiert es zusätzlich den Adressraum dieses Netzes und fasst überlappende Präfixe zusammen.

// cgnat_check.js - am I behind CGNAT, and can anything reach me from outside?
// Usage: bun cgnat_check.js [ASN]    (Bun or Node 18+, no dependencies)
import os from 'node:os'

const v4n = (ip) => ip.split('.').reduce((a, o) => a * 256 + Number(o), 0)
const inV4 = (ip, cidr) => {
  const [net, bits] = cidr.split('/')
  const size = 2 ** (32 - Number(bits))
  return Math.floor(v4n(ip) / size) === Math.floor(v4n(net) / size)
}
const kindV4 = (ip) =>
  inV4(ip, '100.64.0.0/10') ? 'CGNAT (RFC 6598)'
  : ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'].some((c) => inV4(ip, c)) ? 'private (RFC 1918)'
  : inV4(ip, '169.254.0.0/16') ? 'link-local'
  : inV4(ip, '127.0.0.0/8') ? 'loopback' : 'public'
const kindV6 = (ip) => {
  const h = parseInt(ip.split(':')[0] || '0', 16)
  return (h & 0xe000) === 0x2000 ? 'global' : (h & 0xfe00) === 0xfc00 ? 'ULA' : (h & 0xffc0) === 0xfe80 ? 'link-local' : 'other'
}

async function trace(url) {
  try {
    const r = await fetch(url, { signal: AbortSignal.timeout(5000) })
    return Object.fromEntries((await r.text()).trim().split('\n').map((l) => l.split('=')))
  } catch { return null }
}
async function ripestat(call, res) { // RIPEstat sometimes answers an HTML error page: retry
  for (let i = 0; i < 3; i++) {
    try {
      const r = await fetch(`https://stat.ripe.net/data/${call}/data.json?resource=${res}&sourceapp=cgnat-check`, { signal: AbortSignal.timeout(15000) })
      return (await r.json()).data
    } catch { await new Promise((ok) => setTimeout(ok, 2000)) }
  }
  return null
}
async function origin(ip) {
  const d = await ripestat('prefix-overview', ip)
  return d ? { prefix: d.resource, asn: d.asns?.[0]?.asn, holder: d.asns?.[0]?.holder } : {}
}

const local = Object.entries(os.networkInterfaces()).flatMap(([dev, list]) =>
  list.filter((a) => !a.internal).map((a) => ({ dev, ip: a.address, fam: a.family === 'IPv4' || a.family === 4 ? 4 : 6 })))
console.log('Local addresses:')
for (const a of local) console.log(`  ${a.dev.padEnd(8)} ${a.ip.padEnd(40)} ${a.fam === 4 ? kindV4(a.ip) : kindV6(a.ip)}`)

const t4 = await trace('https://1.1.1.1/cdn-cgi/trace')
const t6 = await trace('https://[2606:4700:4700::1111]/cdn-cgi/trace')
const pub4 = t4?.ip, pub6 = t6?.ip
console.log(`\nSeen from outside: IPv4 ${pub4 ?? 'none'}, IPv6 ${pub6 ?? 'none'}`)
if (pub4) {
  const o = await origin(pub4)
  console.log(`  ${pub4} in ${o.prefix ?? '?'} originated by AS${o.asn ?? '?'} ${o.holder ?? ''}`)
  if (o.asn === 14593) console.log('  AS14593 = SpaceX Starlink')
}

const v4local = local.filter((a) => a.fam === 4)
let verdict
if (pub4 && v4local.some((a) => a.ip === pub4)) verdict = 'IPv4: public address on this host, inbound possible (firewall permitting)'
else if (v4local.some((a) => kindV4(a.ip).startsWith('CGNAT'))) verdict = 'IPv4: CGNAT on this host, no inbound IPv4'
else if (pub4) verdict = 'IPv4: behind NAT (home router and maybe CGNAT upstream): inbound only via port forward on every NAT layer'
else verdict = 'IPv4: no IPv4 path out'
console.log(`\n${verdict}`)
if (pub6 && local.some((a) => a.ip === pub6)) console.log('IPv6: global address on this host, inbound depends on the router firewall')
else console.log('IPv6: no global IPv6 path seen')

// Optional: bun cgnat_check.js AS14593 - how much address space does a network announce?
const asArg = process.argv[2]
if (asArg) {
  const ps = (await ripestat('announced-prefixes', asArg)).prefixes.map((p) => p.prefix)
  const v4 = ps.filter((p) => !p.includes(':')).map((p) => { const [n, b] = p.split('/'); return { s: v4n(n), e: v4n(n) + 2 ** (32 - b) } })
    .sort((a, b) => a.s - b.s || b.e - a.e)
  let total = 0, end = -1
  for (const p of v4) { if (p.e > end) { total += p.e - Math.max(p.s, end); end = p.e } }
  const v6 = ps.filter((p) => p.includes(':'))
  const by = (l) => Object.entries(l.reduce((m, p) => ((m[p.split('/')[1]] = (m[p.split('/')[1]] || 0) + 1), m), {})).sort((a, b) => a[0] - b[0]).map(([k, n]) => `/${k} x${n}`).join(', ')
  console.log(`\n${asArg}: ${v4.length} IPv4 prefixes, ${total.toLocaleString('en')} unique addresses; ${v6.length} IPv6 prefixes`)
  console.log(`  IPv4 sizes: ${by(ps.filter((p) => !p.includes(':')))}`)
  console.log(`  IPv6 sizes: ${by(v6)}`)
}
bun cgnat_check.js            # this host only
bun cgnat_check.js AS14593    # plus the space a network announces

Ausgabe, ausgeführt auf einem DCXV Cloud-Server mit Bun 1.4.4 am 2026-11-11 (Host-Oktette maskiert):

Local addresses:
  eth0     178.23.189.x                             public
  eth0     fe80::x                                  link-local
  int0     10.10.x.x                                private (RFC 1918)
  int0     fe80::x                                  link-local

Seen from outside: IPv4 178.23.189.x, IPv6 none
  178.23.189.x in 178.23.189.0/24 originated by AS204057 DCXV-AS DCXV INTERNATIONAL LTD

IPv4: public address on this host, inbound possible (firewall permitting)
IPv6: no global IPv6 path seen

AS14593: 2274 IPv4 prefixes, 990,208 unique addresses; 1130 IPv6 prefixes
  IPv4 sizes: /20 x2, /21 x28, /22 x58, /23 x1434, /24 x752
  IPv6 sizes: /36 x1, /38 x67, /40 x668, /41 x173, /42 x11, /44 x4, /45 x4, /46 x11, /47 x20, /48 x171

Unser Server hält seine öffentliche Adresse auf eth0, eingehende Verbindungen erreichen ihn also, sobald die Firewall sie zulässt; IPv6 ist auf dieser Maschine schlicht nicht konfiguriert. Wir haben keinen Starlink-Anschluss, zeigen daher keine Starlink-Ausgabe und behaupten nichts darüber. Was das Skript dort tut: Auf einem Laptop hinter dem Starlink-Router ist die lokale Adresse privat und die öffentliche liegt in einem Präfix von AS14593, also meldet es NAT und druckt die Starlink-Zeile; am WAN-Port eines Fremdrouters sieht es die Adresse aus 100.64.0.0/10 direkt und meldet CGNAT.

Vier Wege zu einem Standort hinter Starlink

Weg Eingehend von allen? Was nötig ist Was ihn bricht
IPv6 direkt zum Standort Nur IPv6-Besucher Eigener Router (der von Starlink hat keine Firewallregeln) Das /56 kann sich nach einem Umzug ändern; viele Netze sind noch reines IPv4
Priority-Tarif, öffentliche IPv4 Ja Ein Priority-Tarif Die Adresse kann sich nach Umzug oder Software-Update ändern
Mesh-VPN (Tailscale, ZeroTier) Nur eigene Geräte Ein Agent auf jedem Gerät Nichts für öffentliche Besucher oder Geräte ohne Agent
WireGuard-Relay auf einem Cloud-Server Ja, feste IPv4 Ein kleiner Server mit statischer IPv4 Ein Hop mehr und eine Maschine mehr, die laufen muss

Das Relay funktioniert, weil CGNAT erlaubt, wofür es gebaut ist: ausgehende Verbindungen. Der Standort wählt sich beim Relay ein, und PersistentKeepalive = 25 schickt alle 25 Sekunden ein Paket, damit der NAT-Eintrag offen bleibt (der Quick Start von WireGuard nennt 25 s als Intervall, das mit sehr vielen Firewalls funktioniert). Besucher verbinden sich mit der Adresse des Relays, die im Rechenzentrum liegt und nicht mit der Antenne umzieht.

Das Relay: zwei Konfigurationsdateien

Hier nicht ausgeführt: Es braucht root auf zwei Maschinen und einen entfernten Standort. Das sind die üblichen wg-quick-Formen; 192.0.2.10 ist eine Dokumentationsadresse, setzen Sie die Ihres Relays ein.

# /etc/wireguard/wg0.conf on the cloud server (public IPv4 192.0.2.10)
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = <relay-private-key>
# forward TCP 443 that arrives on the public address to the site
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.99.0.2:443
PostUp = iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
PostUp = iptables -A FORWARD -i eth0 -o wg0 -p tcp --dport 443 -j ACCEPT
PostUp = iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.99.0.2:443
PostDown = iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE
PostDown = iptables -D FORWARD -i eth0 -o wg0 -p tcp --dport 443 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

[Peer]
# the site behind Starlink
PublicKey = <site-public-key>
AllowedIPs = 10.99.0.2/32
# /etc/wireguard/wg0.conf at the site (behind CGNAT)
[Interface]
Address = 10.99.0.2/24
PrivateKey = <site-private-key>

[Peer]
PublicKey = <relay-public-key>
Endpoint = 192.0.2.10:51820
AllowedIPs = 10.99.0.1/32
PersistentKeepalive = 25
wg genkey | tee private.key | wg pubkey > public.key
wg-quick up wg0

Drei Hinweise. MASQUERADE lässt jede Verbindung beim Standort von 10.99.0.1 ankommen, die Logs dort verlieren also die Besucheradresse; brauchen Sie sie, entfernen Sie die Regel und leiten Sie die Antworten des Standorts über wg0 zurück. Jedes Paket läuft jetzt über die Satellitenstrecke und das Relay, messen Sie also die Latenz, bevor Sie Sprache oder einen Regelkreis darüber legen. Und planen Sie den Ausfall der Strecke selbst ein: der weltweite Starlink-Ausfall im Juli 2025 dauerte mehr als zwei Stunden.

Größe und Preis des Relays

Ein Relay leitet Pakete weiter und tut sonst wenig. Unser Cloud-Tarif Small (2 vCPU, 4 GB RAM, 40 GB, EUR 15,00 im Monat, eine statische IPv4 inklusive) ist in unserer eigenen Aufgabenliste für WireGuard mit bis zu 25 Tunneln ausgelegt; die Seite VPN-Server beschreibt denselben Aufbau für Teams. Für Geräteflotten, die jeweils eine Adresse brauchen, siehe IoT und die IPv4-Knappheit.

Starten Sie ein Relay bei uns

Unsere Tier-III-Rechenzentren in Prag und Covilha betreiben Cloud-Server, jeden mit statischer IPv4. Starten Sie einen, lassen Sie cgnat_check.js am entfernten Standort laufen und senden Sie die Ausgabe an sales@dcxv.com: Wir helfen beim Einrichten des Relays.

Starlink Mini 2 hinter CGNAT: Standorte erreichen, die umziehen
networkingcloudinfrastructure

Starlink Mini 2 hinter CGNAT: Standorte erreichen, die umziehen

Die Starlink Mini 2 ist da, doch Standardtarife sitzen hinter CGNAT. Wir zählten 990.208 IPv4 für 12+ Mio. Kunden und vergleichen vier Wege zum Standort.

LACNIC-IPv4-Transfer 2026: Regeln, Gebühren, ein Jahr Sperre
ipv4transfernetworking

LACNIC-IPv4-Transfer 2026: Regeln, Gebühren, ein Jahr Sperre

IPv4-Transfers bei LACNIC 2026: die Regeln aus Abschnitt 2.3.2.18, US$ 1,037 Gebühr, NIC.br und NIC México und ein Skript über 1,929 Transfers 2016 bis 2026.

Proteste gegen Rechenzentren in Europa: Was Kunden tun
clouddedicatedinfrastructure

Proteste gegen Rechenzentren in Europa: Was Kunden tun

Am 6. November drangen Hunderte auf Microsofts Baustelle in Amsterdam ein. Die Stromzahlen der Niederlande, gemessene Latenz zu EU-Hubs und Tipps für Kunden.

US-Wähler gegen Rechenzentren 45 zu 1: Lehren für Kunden
clouddedicatedinfrastructure

US-Wähler gegen Rechenzentren 45 zu 1: Lehren für Kunden

47 Abstimmungen über Rechenzentren in den USA, die restriktive Seite gewann 45. Wir zählen die Rohdaten nach und erklären, was das für Servermieter heißt.

AWS BYOIP 2026: $43.80 pro IPv4 oder ein eigenes /24
ipv4pricingcloud

AWS BYOIP 2026: $43.80 pro IPv4 oder ein eigenes /24

AWS berechnet $0,005 pro Stunde je öffentlicher IPv4, $43,80 im Jahr. BYOIP-Adressen sind frei: wann sich ein gekauftes oder gemietetes /24 lohnt, mit Skript.