Add ovpn.sh

This commit is contained in:
bvn13 2026-09-19 21:27:35 +03:00
commit d5b911abb9

152
ovpn.sh Normal file
View File

@ -0,0 +1,152 @@
#!/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