Add ovpn.sh
This commit is contained in:
commit
d5b911abb9
152
ovpn.sh
Normal file
152
ovpn.sh
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user