Starlink Mini 2 CGNAT артында: көшіп жүретін нысанға қалай жетуге болады
Қысқаша (2026-11-11 тексерілді): SpaceX шақыру бойынша Starlink Mini 2 алдын ала тапсырысын ашты. Бұл алынбалы аккумуляторы бар портативті антенна. Ол оптика жоқ жерлерде көбірек камераны, датчикті, далалық ноутбукті және уақытша кеңсені желіге қосады. Бірақ стандартты тариф оларға интернеттен қол жеткізуге болатын мекенжай бермейді: Starlink-те IPv4 әдепкі бойынша операторлық NAT (CGNAT) арқылы жұмыс істейді, ал кіріс қосылымдар бұғатталған. Біз Starlink желісі жариялайтын IPv4 кеңістігін санадық (12 миллионнан астам клиентке 990 208 мекенжай), хосттың CGNAT артында тұрғанын көрсететін скрипт жаздық және көшіп жүретін нысанға жетудің төрт тәсілін салыстырдық.
Дереккөздер. Mini 2 туралы Notebookcheck (Daniel Zlatev, 2026-11-10) және DishyTech (Colby Baber, 2026-11-09) деректері, Hacker News талқылауы: 2026-11-11 күнгі жағдай бойынша 369 ұпай және 380 пікір. Мекенжай саясаты: Starlink Help Center мақалалары "What IP address does Starlink provide?" және "IP Address", 2026-11-11 оқылды. Маршруттау деректері: RIPEstat, біздің скрипт 2026-11-11 сұрады.
Mini 2-де не жаңа
| Параметр | Mini 2, 2026-11-10 хабарламалары бойынша |
|---|---|
| Аккумулятор | Алынбалы, 71 Вт-сағ, 4,5 сағатқа дейін (SpaceX деректері), USB-C арқылы 60 Вт зарядтау |
| Wi-Fi | Wi-Fi 6 (бірінші Mini-де Wi-Fi 5 болған) |
| Корпус | IP67, 314 x 263 x 23,1 мм, аккумулятор мен тірекпен 1,6 кг |
| Қолжетімділік | АҚШ-тағы таңдаулы клиенттерге шақыру бойынша алдын ала тапсырыс, басқа елдер кейінірек |
| Бағасы | Белгісіз: Starlink сайтының кодында $249 жинақ және $50 аккумулятор (DishyTech), басқа дереккөздерде түсіндірмесіз $999 |
Жылдамдық деректері жарияланған жоқ. Бұл мақала үшін ең маңыздысы аккумулятор: электр желісінсіз төрт сағат жұмыс істейтін антеннаны нысаннан нысанға алып жүреді, ал бұл оның артындағы құрылғыларға қалай жететініңізді өзгертеді.
Мекенжай мәселесі: әдепкі бойынша CGNAT
Starlink анықтамасы IPv4-тің екі саясатын сипаттайды. Әдепкісі - CGNAT: роутер RFC 6598 бойынша ортақ ауқым 100.64.0.0/10-нан мекенжай алады, көп клиент бір жария мекенжайды бөліседі, ал кіріс IPv4 трафигіне рұқсат жоқ. Жария IPv4 мекенжайы тек Priority тарифтерінде опция ретінде беріледі (анықтаманың екі беті оларды әртүрлі атайды: бірінде Local және Global Priority, екіншісінде Priority, Mobile Priority және Maritime). Әр желі DHCPv6-PD арқылы /56 IPv6 префиксін де алады, ал Starlink нативті IPv6 оның барлық роутерлерінде, жинақтарында және тарифтерінде жұмыс істейтінін айтады.
Портативті антенна үшін тағы екі жол маңызды. Starlink-тің өз Wi-Fi роутерлері порт бағыттауды да, файрвол ережелерін де қолдамайды, IPv4 үшін де, IPv6 үшін де. Ал резервтелген IPv4 мекенжайы мен IPv6 префиксі қайта жүктеуден кейін сақталады, бірақ антенна басқа жерге көшкенде немесе бағдарламасы жаңартылғанда өзгеруі мүмкін. Көшетін антенна - көшетін мекенжай.
Неге мекенжай бәріне жетпейді: біздің есебіміз
Біздің скрипт RIPEstat-тан AS14593 (SPACEX-STARLINK) не жариялайтынын сұрады: 990 208 бірегей мекенжайды қамтитын 2 274 IPv4 префиксі, негізінен /23 және /24. 2026 жылғы маусымда Starlink 12 миллионнан астам белсенді клиенті бар екенін хабарлады (Mezha). Бұл шамамен 12 клиентке бір жария IPv4 мекенжайы. ip4.market-тің /24 үшін 90 күндік медианасы бойынша, бір мекенжайға $25,25 (индекс 2026-11-02 жаңартылған, қараңыз: IPv4 бағалары), әр клиентке бір мекенжай шамамен $303 миллион тұрар еді; AS14593 жариялайтын кеңістік осы бағамен шамамен $25 миллион тұрады. IPv6-да керісінше: 1 130 префикс, оның 668-і /40, ал бір /40 ішіне 65 536 клиенттік /56 сыяды, сондықтан тек осы /40-тардың өзіне шамамен 43,8 миллион сыяды.
Есептің шектеулері: RIPEstat 10-нан аз RIS пирі көретін маршруттарды есептемейді, Starlink трафиктің бір бөлігін басқа AS нөмірлері арқылы өткізуі мүмкін, ал жарияланған кеңістік пайдаланылатын кеңістікпен бірдей емес. Соған қарамастан дәл осы арақатынас CGNAT неге әдепкі екенін түсіндіреді.
Скрипт: бұл хост CGNAT артында ма?
cgnat_check.js хосттың мекенжайларын және олардың түрін (жария, RFC 1918, 100.64.0.0/10) көрсетеді, жария нүктеден қандай мекенжайды көретінін сұрайды, оны жариялайтын желіні анықтайды және кіріс IPv4 жұмыс істей ала ма, соны айтады. Аргумент ретінде AS нөмірін берсеңіз, ол сол желі жариялайтын кеңістікті де қосып, қабаттасатын префикстерді біріктіреді.
// 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
Нәтиже, DCXV бұлттық серверінде Bun 1.4.4 арқылы 2026-11-11 іске қосылды (хост октеттері жасырылған):
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
Біздің сервер жария мекенжайды eth0 интерфейсінде ұстайды, сондықтан файрвол рұқсат етісімен кіріс қосылымдар оған жетеді; бұл машинада IPv6 жай ғана бапталмаған. Бізде Starlink желісі жоқ, сондықтан Starlink нәтижесін көрсетпейміз және ол туралы ештеңе бекітпейміз. Скрипт онда не істейді: Starlink роутерінің артындағы ноутбукте жергілікті мекенжай жеке, ал жария мекенжай AS14593 префиксінде жатады, сондықтан ол NAT туралы хабарлап, Starlink жолын басып шығарады; бөгде роутердің WAN портында ол 100.64.0.0/10 мекенжайын тікелей көріп, CGNAT туралы хабарлайды.
Starlink артындағы нысанға жетудің төрт тәсілі
| Тәсіл | Кез келгеннен кіріс? | Не қажет | Не бұзады |
|---|---|---|---|
| Нысанға тікелей IPv6 | Тек IPv6 келушілер | Өз роутеріңіз (Starlink роутерінде файрвол ережелері жоқ) | Көшкеннен кейін /56 өзгеруі мүмкін; көп желі әлі тек IPv4 |
| Priority тарифі, жария IPv4 | Иә | Priority тарифі | Көшкеннен немесе жаңартудан кейін мекенжай өзгеруі мүмкін |
| Mesh VPN (Tailscale, ZeroTier) | Тек өз құрылғыларыңыз | Әр құрылғыда агент | Жария келушілерге және агентсіз құрылғыларға жарамайды |
| Бұлттық сервердегі WireGuard ретрансляторы | Иә, тұрақты IPv4 | Статикалық IPv4 бар шағын сервер | Тағы бір хоп және күтіп-ұстауды қажет ететін тағы бір машина |
Ретранслятор жұмыс істейді, өйткені CGNAT өзі жасалған нәрсеге рұқсат береді: шығыс қосылымдарға. Нысан ретрансляторға өзі қосылады, ал PersistentKeepalive = 25 NAT жазбасы ашық тұруы үшін әр 25 секунд сайын пакет жібереді (WireGuard quick start құжатында 25 с файрволдардың кең ауқымымен жұмыс істейтін аралық деп аталған). Келушілер ретранслятордың мекенжайына қосылады, ол дата-орталықта тұрады және антеннамен бірге көшпейді.
Ретранслятор: екі конфигурация файлы
Мұнда іске қосылған жоқ: екі машинада root және қашықтағы нысан қажет. Бұл wg-quick стандартты пішіндері; 192.0.2.10 - құжаттамалық мекенжай, орнына өз ретрансляторыңыздың мекенжайын қойыңыз.
# /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
Үш ескерту. MASQUERADE әр қосылымды нысанға 10.99.0.1-ден келетіндей етеді, сондықтан нысан журналдары келушінің мекенжайын жоғалтады; ол қажет болса, бұл ережені алып тастап, нысанның жауаптарын wg0 арқылы кері бағыттаңыз. Енді әр пакет спутниктік арнадан да, ретранслятордан да өтеді, сондықтан дауысты немесе басқару контурын жібермес бұрын кідірісті өлшеңіз. Және арнаның өзі құлайтын жағдайды жоспарлаңыз: 2025 жылғы шілдедегі Starlink-тің жаһандық іркілісі екі сағаттан астам созылды.
Ретранслятордың өлшемі мен бағасы
Ретранслятор пакеттерді жібереді және басқа көп нәрсе істемейді. Біздің Small бұлттық тарифіміз (2 vCPU, 4 ГБ RAM, 40 ГБ, айына EUR 15,00, бір статикалық IPv4 бағаға кіреді) өз тапсырмалар тізімімізде 25 туннельге дейінгі WireGuard үшін есептелген; VPN сервер беті командаларға арналған дәл осындай баптауды сипаттайды. Әрқайсысына мекенжай қажет құрылғылар паркі үшін қараңыз: IoT және IPv4 тапшылығы.
Ретрансляторды бізде іске қосыңыз
Прага мен Ковильядағы Tier III дата-орталықтарымызда бұлттық серверлер жұмыс істейді, әрқайсысында статикалық IPv4 бар. Серверді іске қосып, қашықтағы нысанда cgnat_check.js орындаңыз және нәтижені sales@dcxv.com мекенжайына жіберіңіз: ретрансляторды баптауға көмектесеміз.
