ovpn-network/ovpn-server.sh
2026-09-19 21:46:50 +03:00

152 lines
4.9 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# ovpn-p2p.sh — OpenVPN только для связи клиентов между собой.
# Интернет-трафик и DNS клиентов через VPN НЕ идут.
#
# ./ovpn-p2p.sh install <публичный_IP_или_домен>
# ./ovpn-p2p.sh add <имя> <vpn_ip> # пример: add pc1 10.8.0.11
# ./ovpn-p2p.sh revoke <имя>
#
# Требования: Debian 11+/Ubuntu 22.04+ (OpenVPN 2.5+), запуск от root.
set -euo pipefail
PORT="${PORT:-1194}"
NET="10.8.0.0"
MASK="255.255.255.0"
SRV=/etc/openvpn/server
PKI_DIR=$SRV/easy-rsa
OUT=/root/ovpn-clients
export EASYRSA_CRL_DAYS=3650 # иначе через 180 дней CRL протухнет и сервер перестанет пускать всех
die(){ echo "ERROR: $*" >&2; exit 1; }
[[ $EUID -eq 0 ]] || die "запускай от root"
update_crl(){
cd "$PKI_DIR"
./easyrsa --batch gen-crl
cp pki/crl.pem "$SRV/crl.pem"
chmod 644 "$SRV/crl.pem"
}
cmd_install(){
local host="${1:-}"
[[ -n $host ]] || die "usage: $0 install <публичный_IP_или_домен>"
apt-get update
apt-get install -y openvpn easy-rsa openssl
mkdir -p "$SRV/ccd" /var/log/openvpn "$OUT"
echo "$host" > "$SRV/public_host"
[[ -d $PKI_DIR ]] || make-cadir "$PKI_DIR"
cd "$PKI_DIR"
[[ -d pki ]] || ./easyrsa --batch init-pki
[[ -f pki/ca.crt ]] || EASYRSA_REQ_CN="p2p-vpn-ca" ./easyrsa --batch build-ca nopass
[[ -f pki/issued/server.crt ]] || ./easyrsa --batch build-server-full server nopass
cp pki/ca.crt pki/issued/server.crt pki/private/server.key "$SRV/"
[[ -f $SRV/ta.key ]] || openvpn --genkey secret "$SRV/ta.key"
update_crl
cat > "$SRV/server.conf" <<EOF
port $PORT
proto udp
dev tun
topology subnet
server $NET $MASK
# Клиенты видят друг друга
client-to-client
# Статические IP по имени сертификата; клиенты без файла в ccd не пускаются
client-config-dir $SRV/ccd
ccd-exclusive
# НИКАКИХ push "redirect-gateway" / push "dhcp-option DNS" — трафик клиентов не перехватываем
ca $SRV/ca.crt
cert $SRV/server.crt
key $SRV/server.key
dh none
tls-crypt $SRV/ta.key
crl-verify $SRV/crl.pem
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
keepalive 10 60
persist-key
persist-tun
user nobody
group nogroup
status /var/log/openvpn/status.log
verb 3
explicit-exit-notify 1
EOF
if command -v ufw >/dev/null && ufw status | grep -q "Status: active"; then
ufw allow "${PORT}/udp"
fi
systemctl enable openvpn-server@server
systemctl restart openvpn-server@server
systemctl --no-pager status openvpn-server@server | head -n 5
echo
echo "Сервер готов. Теперь добавь клиентов: $0 add pc1 10.8.0.11"
}
cmd_add(){
local name="${1:-}" ip="${2:-}"
[[ -n $name && -n $ip ]] || die "usage: $0 add <имя> <vpn_ip, например 10.8.0.11>"
[[ -f $SRV/server.conf ]] || die "сначала: $0 install <host>"
[[ $ip =~ ^10\.8\.0\.([0-9]+)$ ]] && (( BASH_REMATCH[1] >= 2 && BASH_REMATCH[1] <= 254 )) \
|| die "IP должен быть в диапазоне 10.8.0.2–10.8.0.254"
for f in "$SRV"/ccd/*; do
[[ -f $f && $(basename "$f") != "$name" ]] || continue
grep -qx "ifconfig-push $ip $MASK" "$f" && die "IP $ip уже занят клиентом $(basename "$f")"
done
cd "$PKI_DIR"
[[ -f pki/issued/$name.crt ]] || ./easyrsa --batch build-client-full "$name" nopass
echo "ifconfig-push $ip $MASK" > "$SRV/ccd/$name"
local host; host=$(cat "$SRV/public_host")
mkdir -p "$OUT"
{
cat <<EOF
client
dev tun
proto udp
remote $host $PORT
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
# Страховка: даже если сервер что-то пушнет — не отдаём ему маршрут по умолчанию и DNS
pull-filter ignore "redirect-gateway"
pull-filter ignore "dhcp-option"
verb 3
EOF
echo "<ca>"; cat pki/ca.crt; echo "</ca>"
echo "<cert>"; openssl x509 -in "pki/issued/$name.crt"; echo "</cert>"
echo "<key>"; cat "pki/private/$name.key"; echo "</key>"
echo "<tls-crypt>"; cat "$SRV/ta.key"; echo "</tls-crypt>"
} > "$OUT/$name.ovpn"
chmod 600 "$OUT/$name.ovpn"
echo "Готово: $OUT/$name.ovpn (VPN IP: $ip)"
}
cmd_revoke(){
local name="${1:-}"
[[ -n $name ]] || die "usage: $0 revoke <имя>"
cd "$PKI_DIR"
./easyrsa --batch revoke "$name"
update_crl
rm -f "$SRV/ccd/$name" "$OUT/$name.ovpn"
systemctl restart openvpn-server@server
echo "Клиент $name отозван."
}
case "${1:-}" in
install) shift; cmd_install "$@" ;;
add) shift; cmd_add "$@" ;;
revoke) shift; cmd_revoke "$@" ;;
*) echo "usage: $0 {install <host> | add <name> <ip> | revoke <name>}"; exit 1 ;;
esac