WireGuard Server Manual (Orange Pi / Armbian): Difference between revisions
Created page with "== 📘 Описание == Этот документ описывает пошаговую установку и настройку '''WireGuard VPN''' на Orange Pi (или другом Debian/Armbian сервере), включая: * ручную установку и устранение ошибок DNS; * корректную настройку NAT с интерфейсом <code>end0</code>; * скрипты для '''добавления''', '''просмот..." |
No edit summary |
||
| (One intermediate revision by the same user not shown) | |||
| Line 9: | Line 9: | ||
⚙️ 1. Подготовка системы | ⚙️ 1. Подготовка системы | ||
1.1 Проверяем интерфейс<syntaxhighlight lang="bash">ip a | grep -E 'eth|end'</syntaxhighlight> | '''<big>1.1 Проверяем интерфейс</big>'''<syntaxhighlight lang="bash">ip a | grep -E 'eth|end'</syntaxhighlight>На Orange Pi часто вместо <code>eth0</code> используется интерфейс <code>end0</code>. | ||
Запомни его имя — оно нужно для NAT-маскарадинга. | |||
=== 1.2 Настройка DNS (если apt не работает) === | |||
Если при <code>apt update</code> видишь:<syntaxhighlight lang="nginx"> | |||
System error resolving 'deb.debian.org:http' - getaddrinfo (16: Device or resource busy) | |||
</syntaxhighlight>— тогда пересоздай <code>/etc/resolv.conf</code>:<syntaxhighlight lang="bash"> | |||
sudo rm -f /etc/resolv.conf | |||
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf | |||
</syntaxhighlight>И запрети автоматическую перезапись (чтобы Armbian не ломал DNS):<syntaxhighlight lang="bash"> | |||
sudo chattr +i /etc/resolv.conf | |||
</syntaxhighlight>'''<big>🛠️ 2. Установка WireGuard вручную</big>'''<pre> | |||
sudo apt update | |||
sudo apt install wireguard qrencode -y | |||
</pre>Проверим:<pre> | |||
modprobe wireguard | |||
lsmod | grep wireguard | |||
</pre>'''<big>🔑 3. Создание ключей и конфига сервера</big>'''<pre> | |||
cd /etc/wireguard | |||
umask 077 | |||
wg genkey | tee privatekey | wg pubkey > publickey | |||
</pre>Создаём <code>/etc/wireguard/wg0.conf</code>:<pre> | |||
[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> | |||
</pre>(Если у тебя не <code>end0</code>, замени на нужный интерфейс.) | |||
'''<big>🔥 4. Включаем IP-форвардинг</big>'''<pre> | |||
sudo sysctl -w net.ipv4.ip_forward=1 | |||
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf | |||
</pre>'''<big>🚀 5. Запуск сервера</big>'''<pre> | |||
sudo wg-quick up wg0 | |||
sudo systemctl enable wg-quick@wg0 | |||
sudo systemctl status wg-quick@wg0 | |||
</pre>Проверяем:<pre> | |||
sudo wg show | |||
sudo iptables -t nat -L -n -v | |||
</pre>'''<big>📡 6. Port Forwarding</big>''' | |||
На роутере нужно открыть '''UDP-порт 51820''' и пробросить его на IP Orange Pi (например, <code>10.10.0.2</code>). | |||
'''<big>👤 7. Добавление клиента</big>''' | |||
Создай скрипт <code>/root/wg-add-client.sh</code>:<syntaxhighlight lang="bash"> | |||
#!/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" | |||
</syntaxhighlight>Делаем исполняемым:<pre> | |||
chmod +x /root/wg-add-client.sh | |||
</pre>'''<big>🗑️ 8. Удаление клиента (без риска “missing public key”)</big>''' | |||
Создай <code>/root/wg-del-client.sh</code>:<syntaxhighlight lang="bash"> | |||
#!/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' больше не будет)." | |||
</syntaxhighlight>'''<big>📊 9. Просмотр подключений</big>''' | |||
Можно быстро проверить активных клиентов:<pre> | |||
sudo wg show | |||
</pre>Для красивого вывода можно добавить <code>/root/wg-list-clients.sh</code> (опционально):<syntaxhighlight lang="bash"> | |||
#!/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} | |||
' | |||
</syntaxhighlight>'''<big>🧠 10. Полезные команды</big>''' | |||
{| class="wikitable" | |||
|+ | |||
!Команда | |||
!Назначение | |||
|- | |||
|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 правил | |||
|} | |||
'''<big>✅ Итог</big>''' | |||
Теперь твой WireGuard: | |||
* полностью автоматизирован; | |||
* работает на <code>end0</code>; | |||
* не ломается при удалении клиента; | |||
* создаёт и удаляет peers с бэкапами; | |||
* позволяет быстро добавить пользователя через QR-код. | |||
Latest revision as of 10:45, 10 October 2025
📘 Описание
Этот документ описывает пошаговую установку и настройку 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-код.