Skip to content

Commit 3142cbe

Browse files
committed
ipv6 support
1 parent c7c9299 commit 3142cbe

6 files changed

Lines changed: 189 additions & 22 deletions

File tree

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,21 @@ no staged binary for, see the manual install:
4444

4545
## Firewall
4646

47-
A node listens for the panel on TCP **62050**. That port speaks mTLS and accepts
48-
the panel's client certificate and nothing else, but there is no reason to leave
49-
it open to the internet — restrict it to the panel's address:
47+
A node listens for the panel on TCP **62050**, on IPv4 and IPv6 both (it binds
48+
`[::]`, which serves v4 too, and falls back to `0.0.0.0` on a host with IPv6
49+
switched off). That port speaks mTLS and accepts the panel's client certificate
50+
and nothing else, but there is no reason to leave it open to the internet —
51+
restrict it to the panel's address:
5052

5153
```bash
5254
ufw allow from PANEL_IP to any port 62050 proto tcp
55+
ufw allow from 2001:db8::1 to any port 62050 proto tcp # if the panel arrives over IPv6
5356
```
5457

58+
A server with only an IPv6 address needs nothing special: add it in the panel as
59+
`2001:db8::1` (brackets optional) and the panel brackets it wherever a link or a
60+
client profile needs it.
61+
5562
Client traffic arrives on whatever ports the inbounds assigned to this node use.
5663
Those are chosen in the panel, so open them there first and here second.
5764

docker-compose.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ services:
1212
restart: unless-stopped
1313
container_name: nexora-node
1414
environment:
15-
NEXORA_NODE_LISTEN: "0.0.0.0:62050"
15+
# The IPv6 wildcard, which on a dual-stack host accepts IPv4 too. 0.0.0.0
16+
# would leave the node unreachable from a panel that only has IPv6; a host
17+
# with IPv6 switched off cannot bind it, and the node falls back to
18+
# 0.0.0.0 by itself there.
19+
NEXORA_NODE_LISTEN: "[::]:62050"
1620
NEXORA_NODE_CERT: /app/certs/ssl_cert.pem
1721
NEXORA_NODE_KEY: /app/certs/ssl_key.pem
1822
NEXORA_NODE_CLIENT_CA: /app/certs/panel_ca.pem

docs/en/install.md

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ cannot reach.
1616
- A Linux server with systemd — or with Docker, which the installer will use
1717
instead. amd64, arm64, armv5/v6/v7, 386, s390x and riscv64 are all published.
1818
- Root, or a user with sudo.
19-
- TCP **62050** reachable *from the panel*. Outbound access to the panel is
20-
needed by the one-line command below, but not by the automatic install, which
21-
pushes everything down its own SSH connection.
19+
- TCP **62050** reachable *from the panel*, over IPv4 or IPv6 — a node listens
20+
on both. Outbound access to the panel is needed by the one-line command below,
21+
but not by the automatic install, which pushes everything down its own SSH
22+
connection.
2223
- Whatever ports the inbounds you assign to this node will listen on.
2324

2425
A node does not need a licence key of its own. The panel's licence caps how many
@@ -52,7 +53,7 @@ Options you can add to the command:
5253

5354
| Flag | Effect |
5455
| --- | --- |
55-
| `--listen ADDR` | bind the control API somewhere other than `0.0.0.0:62050` |
56+
| `--listen ADDR` | bind the control API somewhere other than `[::]:62050` (the IPv6 wildcard, which serves IPv4 too) |
5657
| `--method script\|docker` | deploy as a systemd service or a container (default: whatever is already there) |
5758
| `--source panel\|github` | take the binary from the panel or from a public release |
5859
| `--version TAG` | install a specific release (implies `--source github`) |
@@ -152,10 +153,46 @@ to advertise it:
152153
ufw allow from PANEL_IP to any port 62050 proto tcp
153154
```
154155

156+
If the panel reaches this node over IPv6, the rule has to name the address it
157+
actually arrives from — a v4 rule does not cover a v6 connection:
158+
159+
```bash
160+
ufw allow from 2001:db8::1 to any port 62050 proto tcp
161+
```
162+
155163
Client-facing ports are a separate matter. They are whatever the inbounds
156164
assigned to this node use, so they are chosen in the panel — open them here after
157165
you have assigned the template, not before.
158166

167+
## A node reached over IPv6
168+
169+
Nothing special is required, on either side. The node binds `[::]:62050` by
170+
default, which on a dual-stack host accepts IPv4 connections as well — so the
171+
same install works whether the panel reaches it over v4, v6, or both. On a host
172+
with IPv6 switched off entirely the node cannot bind that address and falls back
173+
to `0.0.0.0:62050` on its own, which is what that host meant anyway.
174+
175+
A server with **only** an IPv6 address needs nothing extra either. Add it in the
176+
panel with its address written plainly:
177+
178+
```
179+
2001:db8::1
180+
```
181+
182+
Brackets are accepted and stripped — `[2001:db8::1]` and `2001:db8::1` are the
183+
same node. The panel puts them back where the syntax needs them and leaves them
184+
off where it does not: a share link comes out as
185+
`vless://…@[2001:db8::1]:443?…`, a wireguard profile as
186+
`Endpoint = [2001:db8::1]:51820`, while a clash or sing-box config and an
187+
OpenVPN `remote` line carry the bare address. The same goes for **Public
188+
address** (the address published in links, when it differs from the one the
189+
panel connects to) and for the SSH host of an automatic install.
190+
191+
One thing IPv6 does not change: if an inbound uses TLS with no SNI set, the
192+
client validates the certificate against the address, so that address has to be
193+
on the certificate. Reissue the node's certificate with the IPv6 address in its
194+
SAN list, exactly as you would with an IPv4 one.
195+
159196
## Panel and node on the same server
160197

161198
**Not recommended.** It works, and nothing in Nexora forbids it — but read why
@@ -238,7 +275,7 @@ panel.
238275
```bash
239276
cat > /opt/nexora-node/config.json <<'JSON'
240277
{
241-
"listen": "0.0.0.0:62050",
278+
"listen": "[::]:62050",
242279
"cert_file": "/var/opt/nexora/certs/ssl_cert.pem",
243280
"key_file": "/var/opt/nexora/certs/ssl_key.pem",
244281
"client_ca_file": "/var/opt/nexora/certs/panel_ca.pem"
@@ -344,10 +381,14 @@ dropping the connection. Check, in order:
344381
systemctl status nexora-node # on the node
345382
journalctl -u nexora-node -n 50 # on the node
346383
nc -vz NODE_IP 62050 # from the panel server
384+
nc -vz -6 2001:db8::1 62050 # …if the panel reaches it over IPv6
347385
```
348386

349387
A firewall rule that does not include the panel's address is the usual cause; a
350-
cloud provider security group is the second.
388+
cloud provider security group is the second. If the node is reached over IPv6,
389+
check that the firewall rule is a v6 rule — a v4 one does not cover it — and that
390+
`ss -lnt | grep 62050` shows the node on `[::]` rather than `0.0.0.0`, which
391+
means IPv6 is switched off on the host and the node fell back.
351392

352393
**The node was reinstalled and the panel refuses it.** A reinstall generates a
353394
new server certificate, and the panel is still pinning the old one. Delete the

docs/fa/install.md

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
- یک سرور لینوکسی با systemd. معماری‌های amd64، arm64، armv5/v6/v7، ‏386، s390x و
1717
riscv64 همگی منتشر می‌شوند.
1818
- دسترسی root.
19-
- دسترسی خروجی به پنل، و پورت TCP ‏**62050** که *از سمت پنل* در دسترس باشد.
19+
- دسترسی خروجی به پنل، و پورت TCP ‏**62050** که *از سمت پنل* در دسترس باشد — روی
20+
IPv4 یا IPv6؛ نود روی هر دو گوش می‌دهد.
2021
- هر پورتی که inboundهای اختصاص‌یافته به این نود روی آن گوش می‌دهند.
2122

2223
نود به لایسنس مستقل نیاز ندارد. لایسنس پنل تعیین می‌کند چند نود را می‌تواند
@@ -50,7 +51,7 @@ curl -fsSL https://PANEL/install-node.sh | bash -s -- --panel PANEL --token TOKE
5051

5152
| فلگ | اثر |
5253
| --- | --- |
53-
| `--listen ADDR` | بایند کردن API کنترلی روی جایی غیر از `0.0.0.0:62050` |
54+
| `--listen ADDR` | بایند کردن API کنترلی روی جایی غیر از `[::]:62050` (وایلدکارد IPv6 که IPv4 را هم پاسخ می‌دهد) |
5455
| `--binary-url URL` | گرفتن باینری از جایی غیر از پنل |
5556

5657
اگر پنل برای معماری این سرور باینری آماده نداشته باشد، نصب در گام ۱ با پیام
@@ -134,10 +135,44 @@ amd64 و arm64 را آماده می‌کند؛ armv7 و ۳۸۶ و s390x و riscv
134135
ufw allow from PANEL_IP to any port 62050 proto tcp
135136
```
136137

138+
اگر پنل از طریق IPv6 به این نود می‌رسد، قانون باید همان آدرسی را نام ببرد که اتصال
139+
واقعاً از آن می‌آید؛ یک قانون v4 اتصال v6 را پوشش نمی‌دهد:
140+
141+
```bash
142+
ufw allow from 2001:db8::1 to any port 62050 proto tcp
143+
```
144+
137145
پورت‌های سمت کاربر موضوع جداگانه‌ای هستند. آن‌ها همان پورت‌هایی‌اند که inboundهای
138146
اختصاص‌یافته به این نود استفاده می‌کنند، پس در پنل انتخاب می‌شوند — بعد از اینکه
139147
تمپلیت را اختصاص دادید بازشان کنید، نه قبلش.
140148

149+
## نودی که از طریق IPv6 در دسترس است
150+
151+
هیچ کار خاصی در هیچ‌کدام از دو طرف لازم نیست. نود به‌صورت پیش‌فرض روی `[::]:62050`
152+
بایند می‌شود که روی یک هاست dual-stack اتصال‌های IPv4 را هم می‌پذیرد — پس یک نصب
153+
یکسان کار می‌کند، چه پنل از v4 برسد، چه از v6، چه از هر دو. روی هاستی که IPv6 در
154+
آن کاملاً خاموش است نود نمی‌تواند این آدرس را بایند کند و خودش به `0.0.0.0:62050`
155+
برمی‌گردد، که همان چیزی است که آن هاست منظورش بوده.
156+
157+
سروری که **فقط** آدرس IPv6 دارد هم چیز اضافه‌ای نمی‌خواهد. در پنل با آدرسش به شکل
158+
ساده اضافه‌اش کنید:
159+
160+
```
161+
2001:db8::1
162+
```
163+
164+
براکت هم پذیرفته و حذف می‌شود — `[2001:db8::1]` و `2001:db8::1` یک نود هستند. پنل
165+
براکت‌ها را هرجا که نحو لازم دارد برمی‌گرداند و هرجا که لازم ندارد نمی‌گذارد: لینک
166+
اشتراک‌گذاری به شکل `vless://…@[2001:db8::1]:443?…` درمی‌آید و پروفایل وایرگارد به
167+
شکل `Endpoint = [2001:db8::1]:51820`، در حالی که کانفیگ clash یا sing-box و خط
168+
`remote` در OpenVPN آدرس را بدون براکت می‌گیرند. همین قاعده برای **آدرس عمومی**
169+
(آدرسی که در لینک‌ها منتشر می‌شود، وقتی با آدرسی که پنل به آن وصل می‌شود فرق دارد) و
170+
برای هاست SSH نصب خودکار هم برقرار است.
171+
172+
یک چیز را IPv6 عوض نمی‌کند: اگر inbound شما TLS دارد و SNI تنظیم نشده، کلاینت گواهی
173+
را با خود آدرس تطبیق می‌دهد، پس آن آدرس باید روی گواهی باشد. گواهی نود را دقیقاً
174+
مثل حالت IPv4 با آدرس IPv6 در فهرست SAN دوباره صادر کنید.
175+
141176
## پنل و نود روی یک سرور
142177

143178
**پیشنهاد نمی‌شود.** کار می‌کند و چیزی در Nexora جلوی آن را نمی‌گیرد — ولی پیش از
@@ -219,7 +254,7 @@ install -m 0755 /tmp/nexora-node/nexora-node /opt/nexora-node/nexora-node
219254
```bash
220255
cat > /opt/nexora-node/config.json <<'JSON'
221256
{
222-
"listen": "0.0.0.0:62050",
257+
"listen": "[::]:62050",
223258
"cert_file": "/var/opt/nexora/certs/ssl_cert.pem",
224259
"key_file": "/var/opt/nexora/certs/ssl_key.pem",
225260
"client_ca_file": "/var/opt/nexora/certs/panel_ca.pem"
@@ -323,10 +358,14 @@ rm -rf /opt/nexora-node /var/opt/nexora
323358
systemctl status nexora-node # روی نود
324359
journalctl -u nexora-node -n 50 # روی نود
325360
nc -vz NODE_IP 62050 # از سرور پنل
361+
nc -vz -6 2001:db8::1 62050 # …اگر پنل از طریق IPv6 می‌رسد
326362
```
327363

328364
معمول‌ترین علت، قانون فایروالی است که آدرس پنل را در بر نمی‌گیرد؛ دومین علت،
329-
security group ارائه‌دهندهٔ ابری است.
365+
security group ارائه‌دهندهٔ ابری است. اگر نود از طریق IPv6 در دسترس است، مطمئن شوید
366+
قانون فایروال یک قانون v6 است — قانون v4 آن را پوشش نمی‌دهد — و اینکه
367+
`ss -lnt | grep 62050` نود را روی `[::]` نشان می‌دهد، نه `0.0.0.0`؛ حالت دوم یعنی
368+
IPv6 روی هاست خاموش است و نود عقب‌نشینی کرده.
330369

331370
**نود دوباره نصب شده و پنل قبولش نمی‌کند.** نصب دوباره گواهی سرور تازه‌ای می‌سازد و
332371
پنل هنوز گواهی قبلی را پین کرده است. نود را در پنل حذف و دوباره اضافه کنید — پین

docs/ru/install.md

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
- Linux-сервер с systemd. Публикуются amd64, arm64, armv5/v6/v7, 386, s390x и
1818
riscv64.
1919
- Доступ root.
20-
- Исходящий доступ к панели и TCP-порт **62050**, доступный *со стороны панели*.
20+
- Исходящий доступ к панели и TCP-порт **62050**, доступный *со стороны панели*
21+
по IPv4 или IPv6 — нода слушает оба.
2122
- Порты, на которых будут слушать назначенные этой ноде inbound'ы.
2223

2324
Собственный лицензионный ключ ноде не нужен. Лицензия панели ограничивает,
@@ -49,7 +50,7 @@ curl -fsSL https://PANEL/install-node.sh | bash -s -- --panel PANEL --token TOKE
4950

5051
| Флаг | Действие |
5152
| --- | --- |
52-
| `--listen ADDR` | привязать управляющий API не к `0.0.0.0:62050` |
53+
| `--listen ADDR` | привязать управляющий API не к `[::]:62050` (IPv6-wildcard, который обслуживает и IPv4) |
5354
| `--binary-url URL` | взять бинарник не с панели |
5455

5556
Если у панели нет подготовленного бинарника для архитектуры этого сервера,
@@ -140,9 +141,45 @@ s390x и riscv64 приходят из релиза). Установка в Dock
140141
ufw allow from PANEL_IP to any port 62050 proto tcp
141142
```
142143

144+
Если панель приходит к этой ноде по IPv6, правило должно называть тот адрес, с
145+
которого соединение действительно приходит: правило для v4 не покрывает
146+
соединение по v6:
147+
148+
```bash
149+
ufw allow from 2001:db8::1 to any port 62050 proto tcp
150+
```
151+
143152
Клиентские порты — отдельная история. Это порты назначенных ноде inbound'ов, то
144153
есть они выбираются в панели: открывайте их после назначения шаблона, а не до.
145154

155+
## Нода, доступная по IPv6
156+
157+
Ничего особенного не требуется ни с одной стороны. По умолчанию нода слушает
158+
`[::]:62050`, что на dual-stack хосте принимает и соединения по IPv4 — то есть
159+
одна и та же установка работает, приходит ли панель по v4, по v6 или по обоим. На
160+
хосте, где IPv6 выключен полностью, нода не может привязать этот адрес и сама
161+
откатывается на `0.0.0.0:62050`, что для такого хоста и имелось в виду.
162+
163+
Серверу **только** с адресом IPv6 тоже не нужно ничего дополнительного. Добавьте
164+
его в панели, записав адрес просто:
165+
166+
```
167+
2001:db8::1
168+
```
169+
170+
Скобки принимаются и отбрасываются — `[2001:db8::1]` и `2001:db8::1` это одна и та
171+
же нода. Панель возвращает их там, где этого требует синтаксис, и не ставит там,
172+
где не требует: ссылка получается как `vless://…@[2001:db8::1]:443?…`, профиль
173+
wireguard — как `Endpoint = [2001:db8::1]:51820`, тогда как конфигурация clash или
174+
sing-box и строка `remote` в OpenVPN несут голый адрес. То же касается **публичного
175+
адреса** (адреса, публикуемого в ссылках, когда он отличается от того, к которому
176+
подключается панель) и SSH-хоста автоматической установки.
177+
178+
Одного IPv6 не меняет: если у inbound'а включён TLS и SNI не задан, клиент
179+
проверяет сертификат по адресу, а значит этот адрес должен быть в сертификате.
180+
Перевыпустите сертификат ноды с адресом IPv6 в списке SAN — ровно так же, как
181+
сделали бы с IPv4.
182+
146183
## Панель и нода на одном сервере
147184

148185
**Не рекомендуется.** Это работает, и ничто в Nexora этого не запрещает — но
@@ -224,7 +261,7 @@ install -m 0755 /tmp/nexora-node/nexora-node /opt/nexora-node/nexora-node
224261
```bash
225262
cat > /opt/nexora-node/config.json <<'JSON'
226263
{
227-
"listen": "0.0.0.0:62050",
264+
"listen": "[::]:62050",
228265
"cert_file": "/var/opt/nexora/certs/ssl_cert.pem",
229266
"key_file": "/var/opt/nexora/certs/ssl_key.pem",
230267
"client_ca_file": "/var/opt/nexora/certs/panel_ca.pem"
@@ -328,10 +365,14 @@ rm -rf /opt/nexora-node /var/opt/nexora
328365
systemctl status nexora-node # на ноде
329366
journalctl -u nexora-node -n 50 # на ноде
330367
nc -vz NODE_IP 62050 # с сервера панели
368+
nc -vz -6 2001:db8::1 62050 # …если панель приходит по IPv6
331369
```
332370

333371
Обычная причина — правило файрвола, не включающее адрес панели; вторая по
334-
частоте — security group облачного провайдера.
372+
частоте — security group облачного провайдера. Если нода доступна по IPv6,
373+
проверьте, что правило файрвола именно v6 — правило v4 его не покрывает — и что
374+
`ss -lnt | grep 62050` показывает ноду на `[::]`, а не на `0.0.0.0`: второе значит,
375+
что IPv6 на хосте выключен и нода откатилась.
335376

336377
**Нода переустановлена, и панель её не принимает.** Переустановка создаёт новый
337378
серверный сертификат, а панель всё ещё держит закреплённым старый. Удалите ноду в

0 commit comments

Comments
 (0)