Various build shenenigans (#5)
This PR extends the build pipeline of the www service to support locale-prefixed static builds (EN/RU) with build-time SSG output injection, while also refactoring UI typography to a tokenized Tailwind v4 @theme-driven approach. Changes: - Add build-time SSG plugin to @ermnvldmr/rsbuild-config and wire multi-locale builds (/en/, /ru/) into services/www. - Introduce new @ermnvldmr/i18n package (locale constants, path helpers, keysets, pluralization) and apply it to www navigation/text. - Refactor ui typography to a shared getTypographyClassNames utility + Tailwind token definitions, with stl/cn updated for correct Tailwind-merge behavior.
This commit is contained in:
1 parent
ac9c455e5a
commit
b84ef775b8
68 files changed
+2991
-397
No files matched your search
@@ -0,0 +1,182 @@
|
||||
---
|
||||
title: 'Мимикрия подсетей Xray'
|
||||
description: 'Построение распределённой приватной сети 10.0.0.0/8 с использованием Xray-core'
|
||||
createdDate: 2026-03-08
|
||||
tags: ['networking', 'guide']
|
||||
---
|
||||
|
||||
> Это руководство предназначено **исключительно для образовательных целей**. Оно демонстрирует маршрутизацию в Xray-core и подход к мимикрии приватной подсети. Материал НЕ предназначен для обхода ограничений или незаконной деятельности. Используйте эти знания ответственно и в соответствии с местным законодательством.
|
||||
|
||||
## Зачем нужна мимикрия подсети?
|
||||
|
||||
Если построить "плоскую сеть" (Layer 3) поверх публичного интернета, можно получить единое приватное адресное пространство (`10.0.0.0/8`), распределенное между несколькими отдельными серверами.
|
||||
|
||||
- **Распределенная топология**: каждый узел выступает в роли основного шлюза для своего сегмента `/16` (например, Hub для `10.1.0.0/16`, Spoke для `10.2.0.0/16` и `10.3.0.0/16`).
|
||||
- **Преодоление NAT**: Spoke-узлы (Bridges) сами инициируют соединения с Hub-узлом (Portal), благодаря чему даже узлы за NAT остаются доступными.
|
||||
- **Централизованное разрешение DNS**: сетевые DNS-политики единообразно применяются через центральный резолвер на Hub.
|
||||
|
||||
---
|
||||
|
||||
## Обзор технического стека
|
||||
|
||||
1. **Xray-core**: движок маршрутизации для VLESS-соединений, reverse-туннелей и TPROXY-перехвата.
|
||||
2. **TPROXY**: прозрачное проксирование в таблице Linux Mangle, которое перехватывает TCP/UDP-трафик и сохраняет исходный IP назначения.
|
||||
3. **Policy Routing**: использование `ip rule` и таблицы маршрутизации 100 для принудительной отправки перехваченных пакетов в локальный loopback, где их обрабатывает Xray.
|
||||
4. **Mux.cool**: протокол мультиплексирования, который упаковывает сотни виртуальных соединений (TCP/UDP-потоков) в одно физическое TLS-соединение.
|
||||
5. **AdGuard Home**: централизованный DNS-резолвер для всей подсети.
|
||||
6. **Nginx**: используется как маскировка на основном публичном входном порту, чтобы скрыть инстанс Xray.
|
||||
|
||||
---
|
||||
|
||||
## 1. Стек развертывания
|
||||
|
||||
Эта конфигурация описывает центральный Hub (сервер A), который выступает как Portal для подключений Spoke-узлов. На Hub размещены централизованный DNS и fallback-маскировка через Nginx.
|
||||
|
||||
```yaml
|
||||
name: 'a'
|
||||
|
||||
services:
|
||||
xray:
|
||||
image: ghcr.io/xtls/xray-core:26.1.23
|
||||
container_name: a-xray
|
||||
network_mode: host
|
||||
volumes:
|
||||
- ./xray.jsonc:/etc/xray/config.jsonc:ro
|
||||
- /etc/letsencrypt/live:/etc/letsencrypt/live:ro
|
||||
command: -c '/etc/xray/config.jsonc'
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
|
||||
nginx:
|
||||
image: nginxinc/nginx-unprivileged:1.29-alpine
|
||||
container_name: a-nginx
|
||||
networks:
|
||||
direct:
|
||||
ipv4_address: 10.1.1.4
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
adguard:
|
||||
image: adguard/adguardhome:v0.107.72
|
||||
container_name: root-adguard
|
||||
volumes:
|
||||
- adguard-work:/opt/adguardhome/work
|
||||
- adguard-conf:/opt/adguardhome/conf
|
||||
networks:
|
||||
direct:
|
||||
ipv4_address: 10.1.1.3
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_BIND_SERVICE
|
||||
- SYS_NICE
|
||||
- CAP_CHOWN
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
networks:
|
||||
direct:
|
||||
name: a-direct
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 10.1.0.0/16 # Using the full /16 as defined for Server A
|
||||
gateway: 10.1.0.1
|
||||
|
||||
volumes:
|
||||
adguard-work:
|
||||
name: a-adguard-work
|
||||
adguard-conf:
|
||||
name: a-adguard-conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Конфигурация и маршрутизация
|
||||
|
||||
### Генерация UUID-идентификаторов
|
||||
|
||||
Каждому соединению нужен собственный криптографический "ключ". Для сопоставления с конфигами вам понадобятся 4 UUID.
|
||||
|
||||
```bash
|
||||
# Generate UUIDs for the Server B and Server C mappings
|
||||
docker run --rm ghcr.io/xtls/xray-core uuid
|
||||
```
|
||||
|
||||
Соответствие такое:
|
||||
|
||||
- `UUID_B_REVERSE`: управляющий туннель для сервера B.
|
||||
- `UUID_B_DIRECT`: пользовательский трафик сервера B.
|
||||
- `UUID_C_REVERSE`: управляющий туннель для сервера C.
|
||||
- `UUID_C_DIRECT`: пользовательский трафик сервера C.
|
||||
|
||||
### Маршрутизация по политикам (таблица 100)
|
||||
|
||||
Примените скрипт маршрутизации на **каждом** серверном узле, чтобы настроить параметры ядра и таблицу маршрутизации 100. Это заставляет ядро передавать пакет в наш TPROXY inbound, который слушает `127.0.0.1:12345`.
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# 1. Enable IP Forwarding
|
||||
sudo sysctl -w net.ipv4.ip_forward=1
|
||||
|
||||
# 2. IP Rule for mark 0x1 -> table 100
|
||||
sudo ip rule add fwmark 0x1 lookup 100 priority 100
|
||||
|
||||
# 3. Local route in table 100
|
||||
sudo ip route add local 0.0.0.0/0 dev lo table 100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Перехват в firewall
|
||||
|
||||
Откройте `/etc/ufw/before.rules` и сразу после обязательного заголовка `*filter` добавьте правила конкретного узла. Ниже пример для сервера A (Hub, `10.1.0.0/16`):
|
||||
|
||||
```text
|
||||
*mangle
|
||||
:XRAY - [0:0]
|
||||
:XRAY_MASK - [0:0]
|
||||
:DIVERT - [0:0]
|
||||
|
||||
# --- PREROUTING CHAIN (Traffic from other containers/nodes) ---
|
||||
-A XRAY -d 10.1.0.0/16 -j RETURN
|
||||
-A XRAY ! -d 10.0.0.0/8 -j RETURN
|
||||
-A XRAY -m mark --mark 0xff -j RETURN
|
||||
-A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
|
||||
-A PREROUTING -j XRAY
|
||||
|
||||
# --- OUTPUT CHAIN (Traffic originating from the server itself) ---
|
||||
-A XRAY_MASK -d 10.1.0.0/16 -j RETURN
|
||||
-A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN
|
||||
-A XRAY_MASK -m mark --mark 0xff -j RETURN
|
||||
-A XRAY_MASK -p udp -j MARK --set-mark 1
|
||||
-A XRAY_MASK -p tcp -j MARK --set-mark 1
|
||||
-A OUTPUT -j XRAY_MASK
|
||||
|
||||
# --- DIVERT Optimization ---
|
||||
-A DIVERT -j MARK --set-mark 1
|
||||
-A DIVERT -j ACCEPT
|
||||
-I PREROUTING -p tcp -m socket -j DIVERT
|
||||
|
||||
COMMIT
|
||||
```
|
||||
|
||||
После применения перезагрузите UFW:
|
||||
|
||||
```bash
|
||||
sudo ufw reload
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ресурсы
|
||||
|
||||
- [Официальная документация Xray-core](https://xtls.github.io/)
|
||||
- [Документация Xray Reverse Proxy](https://xtls.github.io/en/config/reverse.html)
|
||||
- [Project X (Xray) на GitHub](https://github.com/XTLS/Xray-core)
|
||||
- [Документация Linux Kernel по TPROXY](https://www.kernel.org/doc/Documentation/networking/tproxy.txt)
|
||||
- [Блог Cloudflare: TPROXY](https://blog.cloudflare.com/how-we-built-spectrum/)
|
||||
Reference in new issue
Block a user