WireGuard Server Manual (Orange Pi / Armbian)
📘 Описание
Этот документ описывает пошаговую установку и настройку WireGuard VPN на Orange Pi (или другом Debian/Armbian сервере), включая:
- ручную установку и устранение ошибок DNS;
- корректную настройку NAT с интерфейсом
end0; - скрипты для добавления, просмотра и удаления клиентов (с QR-кодом);
- защиту от ошибки
A peer is missing a public key.
⚙️ 1. Подготовка системы
1.1 Проверяем интерфейс
ip a | grep -E 'eth|end'
На Orange Pi часто вместо eth0 используется интерфейс end0.
Запомни его имя — оно нужно для NAT-маскарадинга.
1.2 Настройка DNS (если apt не работает)
Если при apt update видишь:
System error resolving 'deb.debian.org:http' - getaddrinfo (16: Device or resource busy)
— тогда пересоздай /etc/resolv.conf:
sudo rm -f /etc/resolv.conf
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
И запрети автоматическую перезапись (чтобы Armbian не ломал DNS):
sudo chattr +i /etc/resolv.conf
🛠️ 2. Установка WireGuard вручную
sudo apt update sudo apt install wireguard qrencode -y
Проверим:
modprobe wireguard lsmod | grep wireguard
🔑 3. Создание ключей и конфига сервера
cd /etc/wireguard umask 077 wg genkey | tee privatekey | wg pubkey > publickey
Создаём /etc/wireguard/wg0.conf:
[Interface] Address = 10.10.100.1/24 SaveConfig = false PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o end0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o end0 -j MASQUERADE ListenPort = 51820 PrivateKey = <твой_privatekey>
(Если у тебя не end0, замени на нужный интерфейс.)
🔥 4. Включаем IP-форвардинг
sudo sysctl -w net.ipv4.ip_forward=1 echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
🚀 5. Запуск сервера
sudo wg-quick up wg0 sudo systemctl enable wg-quick@wg0 sudo systemctl status wg-quick@wg0
Проверяем:
sudo wg show sudo iptables -t nat -L -n -v
📡 6. Port Forwarding
На роутере нужно открыть UDP-порт 51820 и пробросить его на IP Orange Pi (например, 10.10.0.2).
👤 7. Добавление клиента
Создай скрипт /root/wg-add-client.sh:
#!/usr/bin/env bash
# ==============================================
# WireGuard Add Client Script
# Author: Niji’s version, 2025
# ==============================================
set -euo pipefail
WG_CONF="/etc/wireguard/wg0.conf"
WG_IF="wg0"
WG_DIR="/etc/wireguard"
if [ "$(id -u)" -ne 0 ]; then echo "❌ Запустите от root"; exit 1; fi
if [ ! -f "$WG_CONF" ]; then echo "❌ Конфиг $WG_CONF не найден"; exit 1; fi
read -rp "Введите имя клиента: " CLIENT
CLIENT_IP=$(awk '/AllowedIPs/{print $3}' $WG_CONF | awk -F'[./]' '{print $4}' | sort -n | tail -1)
CLIENT_IP=$((CLIENT_IP+1))
[ "$CLIENT_IP" -lt 2 ] && CLIENT_IP=2
cd $WG_DIR
wg genkey | tee ${CLIENT}-privatekey | wg pubkey > ${CLIENT}-publickey
SERVER_PUB=$(awk '/PrivateKey/{getline; print $3}' /etc/wireguard/publickey 2>/dev/null || echo "")
SERVER_PUB=$(cat /etc/wireguard/publickey)
CLIENT_PRIV=$(cat ${CLIENT}-privatekey)
CLIENT_PUB=$(cat ${CLIENT}-publickey)
SERVER_IP=$(hostname -I | awk '{print $1}')
cat > ${CLIENT}.conf <<EOF
[Interface]
PrivateKey = ${CLIENT_PRIV}
Address = 10.10.100.${CLIENT_IP}/32
DNS = 1.1.1.1
[Peer]
PublicKey = ${SERVER_PUB}
Endpoint = ${SERVER_IP}:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF
cat >> $WG_CONF <<EOF
# ### Client ${CLIENT}
[Peer]
PublicKey = ${CLIENT_PUB}
AllowedIPs = 10.10.100.${CLIENT_IP}/32
PersistentKeepalive = 25
EOF
wg-quick down $WG_IF >/dev/null 2>&1 || true
wg-quick up $WG_IF
qrencode -t ansiutf8 < ${CLIENT}.conf
echo "✅ Клиент ${CLIENT} создан успешно!"
echo "📄 Конфиг: ${WG_DIR}/${CLIENT}.conf"
Делаем исполняемым:
chmod +x /root/wg-add-client.sh
🗑️ 8. Удаление клиента (без риска “missing public key”)
Создай /root/wg-del-client.sh:
#!/usr/bin/env bash
# ==============================================
# WireGuard client remover (safe + auto-clean)
# Author: Niji’s version, 2025
# ==============================================
set -euo pipefail
WG_CONF="/etc/wireguard/wg0.conf"
WG_IF="wg0"
if [ "$(id -u)" -ne 0 ]; then echo "❌ Запустите скрипт от root"; exit 1; fi
if [ ! -f "$WG_CONF" ]; then echo "❌ Файл $WG_CONF не найден!"; exit 1; fi
echo "📋 Найденные клиенты:"
echo
mapfile -t KEYS < <(grep -A1 "^\[Peer\]" "$WG_CONF" | grep PublicKey | awk '{print $3}')
if [ "${#KEYS[@]}" -eq 0 ]; then echo "❌ Клиенты не найдены."; exit 0; fi
for i in "${!KEYS[@]}"; do
key="${KEYS[$i]}"
name=$(awk -v k="$key" '/^# ### Client /{n=$4} /^PublicKey/ && $3==k{print n; exit}' "$WG_CONF")
name="${name:-Unnamed-$((i+1))}"
printf " %2d. %-15s %s\n" "$((i+1))" "$name" "$key"
done
echo
read -rp "Введите номер клиента для удаления: " NUM
if ! [[ "$NUM" =~ ^[0-9]+$ ]] || [ "$NUM" -lt 1 ] || [ "$NUM" -gt "${#KEYS[@]}" ]; then
echo "❌ Неверный номер."; exit 1
fi
CLIENT_KEY="${KEYS[$((NUM-1))]}"
CLIENT_NAME=$(awk -v k="$CLIENT_KEY" '/^# ### Client /{n=$4} /^PublicKey/ && $3==k{print n; exit}' "$WG_CONF")
CLIENT_NAME="${CLIENT_NAME:-Unnamed-$NUM}"
echo
echo "⚠️ Подтвердите удаление клиента '$CLIENT_NAME' (PublicKey: $CLIENT_KEY)"
read -rp "Введите YES для подтверждения: " CONFIRM
if [ "$CONFIRM" != "YES" ]; then echo "❎ Отменено пользователем."; exit 0; fi
cp "$WG_CONF" "$WG_CONF.bak.$(date +%s)"
echo "🧩 Создан бэкап wg0.conf."
awk -v key="$CLIENT_KEY" '
BEGIN{inside=0}
/^\[Peer\]/ {if (inside==1) inside=0; block=""}
{block = block $0 ORS}
/^PublicKey/ && $3==key {inside=1}
inside==0 && !/^$/ {print $0}
' "$WG_CONF" > "${WG_CONF}.tmp" && mv "${WG_CONF}.tmp" "$WG_CONF"
# 🧹 Удаляем пустые блоки
awk '
BEGIN{inside=0}
/^\[Peer\]/ {inside=1; peer=""}
inside {peer=peer $0 ORS}
/^$/ && inside {
if (peer ~ /PublicKey/) print peer;
peer=""; inside=0
}
!inside && !/^\[Peer\]/ && !/^$/ {print $0}
END {
if (inside && peer ~ /PublicKey/) print peer;
}
' "$WG_CONF" > "${WG_CONF}.clean" && mv "${WG_CONF}.clean" "$WG_CONF"
wg-quick down "$WG_IF" >/dev/null 2>&1 || true
wg-quick up "$WG_IF"
echo "✅ Клиент '$CLIENT_NAME' удалён успешно!"
echo "📄 Бэкап сохранён: ${WG_CONF}.bak.*"
echo "🧹 Конфиг очищен автоматически (никаких 'missing public key' больше не будет)."
📊 9. Просмотр подключений Можно быстро проверить активных клиентов:
sudo wg show
Для красивого вывода можно добавить /root/wg-list-clients.sh (опционально):
#!/usr/bin/env bash
echo "📡 WireGuard peers:"
echo "----------------------------------------"
sudo wg show | awk '
/interface:/ {iface=$2}
/peer:/ {peer=$2}
/allowed ips:/ {ips=$3}
/endpoint:/ {endpoint=$2}
/transfer:/ {recv=$2 " " $3 ", " $5 " " $6}
/latest handshake:/ {print iface " | " peer " | " ips " | " endpoint " | " $3 " " $4 " " $5 " | " recv}
'
🧠 10. Полезные команды
| Команда | Назначение |
|---|---|
| sudo wg show | Список клиентов и статистика |
| sudo wg-quick up wg0 | Запуск WireGuard |
| sudo wg-quick down wg0 | Остановка WireGuard |
| sudo systemctl restart wg-quick@wg0 | Перезапуск |
| sudo wg syncconf wg0 <(wg-quick strip wg0) | Применить изменения без перезапуска |
| sudo iptables -t nat -L -n -v | Проверка NAT правил |
✅ Итог Теперь твой WireGuard:
- полностью автоматизирован;
- работает на
end0; - не ломается при удалении клиента;
- создаёт и удаляет peers с бэкапами;
- позволяет быстро добавить пользователя через QR-код.