WireGuard Server Manual (Orange Pi / Armbian): Difference between revisions

From wiki.baghirzade.pro
Jump to navigation Jump to search
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-код.