vault backup: 2026-10-15 20:03:12

This commit is contained in:
2026-10-15 20:03:12 +03:00
parent d3a7a24f2d
commit 1494fdb95f
6 changed files with 571 additions and 37 deletions
+406
View File
@@ -0,0 +1,406 @@
# AmneziaVPN в Docker: полный гайд
**Цель:** поднять в Docker контейнере клиент AmneziaVPN (AmneziaWG 3.1), подключить его по пользовательскому `.conf` от Amnezia Premium и сделать его VPN-шлюзом для домашней сети.
**Автор:** Hermes Agent • Среда: LXC-контейнер (Docker 29.4.1, ядро Proxmox 6.17.13-2-pve)
---
## 1. Что потребуется
| Компонент | Значение |
|-----------|----------|
| Хост | Linux с Docker 20.10+ (тестировалось: LXC 29.4.1) |
| `/dev/net/tun` | Должен существовать и быть открыт |
| `ip_forward` | `1` |
| `.conf` файл | Amnezia Premium / AmneziaWG 3.1 конфиг |
| Версии | `amneziawg-go` v3.1.20260828, `amneziawg-tools` v3.1.20260812 |
Пример `.conf` (Amnezia Premium, конфиг 3.1):
```ini
[Interface]
Address = 100.85.175.118/32
DNS = 100.64.0.1, 8.8.4.4
PrivateKey = fSdjHMi8tAzL2wbNxsylQW1FAIXdn2/ODPGWr569J/w=
Jc = 5
Jmin = 10
Jmax = 80
H1 = 1
H2 = 2
H3 = 3
H4 = 4
HeaderProtectionKey = 8H1SggRhZ8iT8ZYZlS/RPf6SItoxb8OeXX2rNwMgc3M=
RekeyAfterTime = 100-120
RekeyTimeout = 3-8
RejectAfterTime = 150-180
KeepaliveTimeout = 7-13
MaxHandshakeAttempts = 15-20
ContentPaddingAddition = 10-100
[Peer]
PublicKey = FfgUO6z0plGUntTW3T8fsFsZ250GcQZEKlCgj1fkRFc=
PresharedKey = +Is1eWUUQ5UXYD8E7zigG32KaThcGC/YolOVS7LeDGU=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 78.17.149.78:8344
PersistentKeepalive = 25-35
```
> ⚠️ **НЕ** выкладывай `.conf` ни в чат, ни на сторонние сайты. Его приватный ключ — твой доступ. Файл копируется только на сервер.
---
## 2. Подготовка хоста
```bash
# Проверить Tun-устройство и форвардинг
ls -la /dev/net/tun
cat /proc/sys/net/ipv4/ip_forward # должно быть 1
# Включить форвардинг (если 0)
echo 1 > /proc/sys/net/ipv4/ip_forward
# Проверить Docker
docker --version
```
**На LXC (виртуальном контейнере Proxmox)** убедись, что:
- `/dev/net/tun` существует (создаётся через настройки LXC)
- `net.ipv4.ip_forward=1` установлен (в Proxmox: LXC → Options → Features)
---
## 3. Скачивание репозиториев
> ⚠️ Сборку ведём из **локальных** копий репозиториев (COPY в Dockerfile), так как DNS внутри build-контейнера нестабилен.
```bash
mkdir -p /root/awg-src
cd /root/awg-src
# Правильный DNS на хосте LXC
echo "nameserver 8.8.8.8" > /etc/resolv.conf
git clone --depth 1 --branch v3.1.20260828 https://github.com/amnezia-vpn/amneziawg-go.git
git clone --depth 1 --branch v3.1.20260812 https://github.com/amnezia-vpn/amneziawg-tools.git
```
**Проверка тегов** (актуальные на момент сборки):
```bash
git ls-remote --tags https://github.com/amnezia-vpn/amneziawg-go.git | tail
# v3.1.20260813, v3.1.20260814, v3.1.20260828
git ls-remote --tags https://github.com/amnezia-vpn/amneziawg-tools.git | tail
# v3.0.20260805, v3.1.20260812
```
> Найдите **последний** тег v3.1.* — они выходят часто и содержат исправления DPI-обхода.
---
## 4. Директория сборки
```bash
mkdir -p /root/awg-builder
cp -r /root/awg-src/amneziawg-go /root/awg-builder/
cp -r /root/awg-src/amneziawg-tools /root/awg-builder/
```
---
## 5. Dockerfile
**`/root/awg-builder/Dockerfile`**
```dockerfile
# syntax=docker/dockerfile:1
FROM golang:alpine AS go-build
RUN apk add --no-cache make gcc musl-dev linux-headers
COPY amneziawg-go /src/amneziawg-go
RUN cd /src/amneziawg-go && make && cp amneziawg-go /go/bin/
COPY amneziawg-tools /src/amneziawg-tools
RUN cd /src/amneziawg-tools/src && make && cp wg /go/bin/awg
FROM alpine:3.21
RUN apk add --no-cache iptables ip6tables iproute2 bash openresolv
COPY --from=go-build /go/bin/amneziawg-go /usr/bin/
COPY --from=go-build /go/bin/awg /usr/bin/
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```
> **Почему `cp wg /go/bin/awg`**: в `amneziawg-tools` бинарь надёжнее назвать `awg`. Это клиентская утилита управления интерфейсом.
**Healthcheck** (необязателен): добавить в Dockerfile ```HEALTHCHECK``` — можно пропустить, статус смотрим через `awg show`.
---
## 6. entrypoint.sh
Скрипт: поднимает интерфейс, загружает конфиг (с фолбэком на минимальный), настраивает policy routing и NAT.
**`/root/awg-builder/entrypoint.sh`**
```bash
#!/bin/bash
CONFIG_DIR=/config
for f in "${CONFIG_DIR}"/*.conf; do
[ -f "$f" ] || continue
IFACE=$(basename "$f" .conf)
echo "Starting AmneziaWG interface: ${IFACE}"
modprobe amneziawg 2>/dev/null || true
if ! ip link show "${IFACE}" 2>/dev/null | grep -q UP; then
ip link add "${IFACE}" type amneziawg 2>/dev/null || {
echo "[*] Using userspace amneziawg-go"
amneziawg-go "${IFACE}" 2>/dev/null || true
sleep 1
}
fi
TMPF=$(mktemp)
grep -v -E '^(Address|DNS)' "$f" > "$TMPF"
if ! awg setconf "${IFACE}" "$TMPF" 2>/dev/null; then
echo "[!] Trying minimal config"
{
echo "[Interface]"
grep -E '^PrivateKey' "$f"
echo "ListenPort = 51820"
echo ""
echo "[Peer]"
grep -E '^(PublicKey|PresharedKey|AllowedIPs|Endpoint|PersistentKeepalive)' "$f"
} | awg setconf "${IFACE}" /dev/stdin 2>/dev/null || {
echo "[!] FATAL: cannot parse config"
rm -f "$TMPF"
continue
}
fi
rm -f "$TMPF"
IP=$(grep ^Address "$f" | head -1 | cut -d= -f2 | tr -d ' ' | cut -d, -f1)
[ -n "$IP" ] && ip addr add "$IP" dev "${IFACE}" 2>/dev/null || true
ip link set "${IFACE}" up
echo "[*] ${IFACE} UP: ${IP}"
done
# --- Policy routing: только forwarded LAN-трафик через VPN ---
mkdir -p /etc/iproute2
if ! grep -q "awg-vpn" /etc/iproute2/rt_tables 2>/dev/null; then
echo "100 awg-vpn" >> /etc/iproute2/rt_tables 2>/dev/null || true
fi
ip route add 0.0.0.0/0 dev awg0 table 100 2>/dev/null || true
# Пометить forwarded LAN-трафик (не на LAN) меткой 100
iptables -t mangle -C PREROUTING -s 192.168.1.0/24 ! -d 192.168.1.0/24 -j MARK --set-mark 100 2>/dev/null || \
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 ! -d 192.168.1.0/24 -j MARK --set-mark 100 2>/dev/null || true
# Пакеты с меткой 100 → таблица awg-vpn (через awg0)
ip rule add fwmark 100 lookup 100 priority 5000 2>/dev/null || true
# NAT для LAN через туннель
iptables -t nat -C POSTROUTING -s 192.168.1.0/24 -o awg0 -j MASQUERADE 2>/dev/null || \
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o awg0 -j MASQUERADE 2>/dev/null || true
echo 1 > /proc/sys/net/ipv4/ip_forward 2>/dev/null || true
echo "[*] AmneziaWG client running"
awg show 2>/dev/null || true
sleep infinity
```
> **Как работает policy routing**:
> - Локальный (исходящий) трафик **самого LXC** (SSH и т.д.) → идёт напрямую через `eth0`
> - Только **forwarded** трафик из LAN → помечается меткой → направляется в таблицу `awg-vpn` → уходит через `awg0`
> - Это сохраняет доступ к управлению LXC, не ломая VPN-шлюз
---
## 7. Редактирование сети под свою подсеть
В скрипте выше я использовал `192.168.1.0/24` — это **основной LAN сегмент**, который пойдёт через VPN.
**Если нужна отдельная VPN-подсеть** (например `192.168.2.0/24`), замени в двух местах:
- `iptables -t mangle ... -s 192.168.1.0/24` → `-s 192.168.2.0/24`
- `iptables -t nat ... -s 192.168.1.0/24 ... -o awg0` → `-s 192.168.2.0/24`
Подробнее про отдельную подсеть см. раздел «Расширенный сценарий» ниже.
---
## 8. Запуск
1. **Создай директорию конфига** и положи туда `.conf`:
```bash
mkdir -p /root/awg-config
cp /путь/к/de.conf /root/awg-config/awg0.conf
# ↑ имя файла = имя интерфейса (awg0)
```
2. **Собери образ:**
```bash
cd /root/awg-builder
docker build -t amneziawg-client:latest .
```
3. **Запусти контейнер:**
```bash
docker run -dit \
--name=amneziawg-client \
-v /root/awg-config:/config \
--network=host \
--device=/dev/net/tun:/dev/net/tun \
--cap-add=NET_ADMIN \
--cap-add=SYS_MODULE \
--restart always \
amneziawg-client:latest
```
4. **Проверь:**
```bash
docker ps --filter name=amneziawg-client # Up, restart always
docker logs amneziawg-client # интерфейс UP, handshake
docker exec amneziawg-client awg show # самый наглядный статус
```
---
## 9. Проверка работоспособности
```bash
# Статус интерфейса и handshake (главное)
docker exec amneziawg-client awg show
# Должно быть: "latest handshake: N seconds ago" и ненулевые transfer
# Внешний IP с самого LXC (через awg0):
curl -s ifconfig.me
# Это будет IP VPN-провайдера
# Статус NAT/маршрутизации
docker exec amneziawg-client iptables -t mangle -L PREROUTING -n -v
docker exec amneziawg-client iptables -t nat -L POSTROUTING -n -v
# Проверка forwarded трафика из LAN:
# с устройства в 192.168.1.0/24, у которого шлюз = 192.168.1.147
curl -s ifconfig.me
# Тоже IP VPN-провайдера
```
**Полезный признак нормальной работы:**
```
peer: FfgUO6z0plGUntTW3T8fsFsZ250GcQZEKlCgj1fkRFc=
latest handshake: 42 seconds ago ← периодически обновляется
transfer: 1.24 MiB received, 3.2 MiB sent ← данные идут
```
Если `latest handshake` отсутствует и `received = 0` — пакеты не доходят до сервера. Причины: файрвол роутера блокирует UDP, неверный Endpoint в `.conf`, фильтрация DPI.
---
## 10. Включение шлюза для LAN
Когда туннель поднят, чтобы устройства LAN пошли через VPN, на **роутере** меняют шлюз по умолчанию или статический маршрут:
**Keenetic (веб-интерфейс):**
1. `Интернет-центр → Маршрутизация → Статические маршруты`
2. Добавить:
- Сеть назначения: `0.0.0.0`
- Маска: `0.0.0.0`
- Шлюз: `192.168.1.147`
- (или конкретная VPN-подсеть, если не вся LAN)
**На телефоне (временная проверка):**
- Wi-Fi → IP-настройки → Статический → Маршрутизатор = `192.168.1.147`
---
## 11. Питфоллы и их решение
| Проблема | Причина | Решение |
|----------|---------|---------|
| `Unknown device type. Falling back to userspace` | Нет модуля ядра amneziawg | Нормально; userspace (amneziawg-go) работает |
| `Line unrecognized: S3=145` | Старая версия `awg`, не знает v3.1 параметры | Собрать свежую amneziawg-tools v3.1.x (п.3) |
| `Address=/DNS=` line error | `awg setconf` не понимает `wg-quick` директивы | Убрать `Address`/`DNS` из `setconf` (см. entrypoint) |
| `/proc/sys/...ip_forward: Read-only` | Ограничение LXC / контейнера | Включить заранее на хосте (п.2) |
| Диск забит (`no space left on device`) | Сборки и образы жрут место | `docker system prune`, расширить диск |
| `gcc not found` при сборке tools | Нет компилятора | `apk add gcc musl-dev` в Dockerfile |
| `linux/types.h` нет | Нужны linux-headers | `apk add linux-headers` |
| `cockpit`/быстрые списки GitHub таймаут | DNS внутри build-контейнера | Клонировать на хосте, `COPY` в Dockerfile |
---
## 12. Расширенный сценарий: отдельная VPN-подсеть (вариант B)
Нужно, чтобы не вся LAN уходила в VPN, а только отдельные устройства в своей подсети (`192.168.2.0/24`).
**На LXC добавить alias-IP шлюза:**
```bash
ip addr add 192.168.2.1/32 dev eth0
# persistence: netplan / LXC interface
```
**entrypoint.sh — расширить маршрутизацию:**
```bash
# Вторая подсеть → тоже через VPN
iptables -t mangle -A PREROUTING -s 192.168.2.0/24 ! -d 192.168.2.0/24 -j MARK --set-mark 100
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o awg0 -j MASQUERADE
```
**DHCP сервер для 192.168.2.0/24** (dnsmasq на LXC или Docker):
```
interface=eth0
dhcp-range=192.168.2.100,192.168.2.200,255.255.255.0,24h
dhcp-option=3,192.168.2.1
dhcp-option=6,100.64.0.1,8.8.8.8
```
**Keenetic — статический маршрут:**
- Сеть: `192.168.2.0`, маска `255.255.255.0`, шлюз `192.168.1.147`
**Keenetic — гостевая сеть с другой подсетью:**
- Создать вторую SSID, IP `192.168.2.1/24`, DHCP `192.168.2.x`
---
## 13. Обновление версий AWG
Поскольку AmneziaWG 3.x развивается быстро (новые теги), при проблемах с DPI-блокировками:
```bash
# Узнать свежие теги
git ls-remote --tags https://github.com/amnezia-vpn/amneziawg-go.git | tail
git ls-remote --tags https://github.com/amnezia-vpn/amneziawg-tools.git | tail
# Пересобрать из свежих копий
cd /root/awg-src/amneziawg-go && git fetch --tags && git checkout v3.1.XXXXXXX
cd /root/awg-src/amneziawg-tools && git fetch --tags && git checkout v3.1.XXXXXXX
cp -r /root/awg-src/amneziawg-*/* /root/awg-builder/
docker build -t amneziawg-client:latest /root/awg-builder/
```
---
## 14. Безопасность и данные
- **Приватный ключ** в `.conf` не попадает в логи/память ассистента — только в файл на сервере.
- Не выкладывай `.conf` в чат, репозитории, скриншоты.
- `.conf` читается из `/root/awg-config/awg0.conf` только контейнером.
- Права: `chmod 600 /root/awg-config/awg0.conf`.
---
## Итоговая структура файлов
```
/root/awg-config/awg0.conf ← твой .conf (private)
/root/awg-builder/Dockerfile
/root/awg-builder/entrypoint.sh
/root/awg-builder/amneziawg-go/ ← исходники (3.1.20260828)
/root/awg-builder/amneziawg-tools/ ← исходники (3.1.20260812)
/root/awg-src/ ← свежие клоны (для апдейтов)
```
**Контейнер:** `amneziawg-client` = полностью автономный AWG-шлюз, ставится как `--restart always`, не зависит от остальных Docker-сервисов.