#!/bin/bash
# Пути к файлам и каталогам
CDIR="/root/openvpn-ca"
CONF_DIR="/etc/openvpn/server"
SERVER_CONF="$CONF_DIR/server.conf"
OUTPUT_DIR="/root/vpn-configs"
# Цветовая палитра для вывода в консоль (Светло-голубой цвет)
GREEN='\033[0;32m'
CYAN='\033[1;36m' # <-- Яркий голубой цвет вместо темно-синего
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Проверка наличия аргументов
if [ $# -eq 0 ]; then
echo -e "${RED}Ошибка:${NC} Не указано ни одного имени клиента."
echo -e "Использование: $0 имя_клиента1 [имя_клиента2 имя_клиента3 ...]"
exit 1
fi
# Проверяем, существует ли конфиг сервера для чтения параметров
if [ ! -f "$SERVER_CONF" ]; then
echo -e "${RED}Ошибка:${NC} Файл конфигурации сервера не найден по адресу $SERVER_CONF"
exit 1
fi
# --- Динамический парсинг настроек из server.conf ---
S_PORT=$(grep -E '^port\s' "$SERVER_CONF" | awk '{print $2}')
S_PROTO=$(grep -E '^proto\s' "$SERVER_CONF" | awk '{print $2}')
S_CIPHERS=$(grep -E '^data-ciphers\s' "$SERVER_CONF" | awk '{print $2}')
# Задаем дефолты, если в конфиге сервера этих строк вдруг не оказалось
S_PORT=${S_PORT:-1194}
S_PROTO=${S_PROTO:-udp}
S_CIPHERS=${S_CIPHERS:-AES-128-GCM}
# Автоматически определяем внешний IP-адрес сервера через интерфейс ens3
SERVER_IP=$(ip -4 addr show dev ens3 | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n 1)
# Если через интерфейс определить не удалось, берем публичный IP через Web
if [ -z "$SERVER_IP" ]; then
SERVER_IP=$(curl -s ifconfig.me)
fi
mkdir -p "$OUTPUT_DIR"
# Переходим в папку CA
if ! cd "$CDIR" 2>/dev/null; then
echo -e "${RED}Ошибка:${NC} Не удалось перейти в директорию CA: $CDIR"
exit 1
fi
echo -e "${CYAN}=== Запуск генерации конфигураций (Всего: $#) ===${NC}"
echo -e "${YELLOW}Считанные параметры сервера:${NC} IP=$SERVER_IP, Port=$S_PORT, Proto=$S_PROTO, Ciphers=$S_CIPHERS\n"
# Цикл по всем переданным аргументам
for CLIENT_NAME in "$@"; do
echo -e "${CYAN}[$CLIENT_NAME]${NC} Начинаю обработку..."
# Проверка на дубликаты
if [ -f "$OUTPUT_DIR/$CLIENT_NAME.ovpn" ]; then
echo -e " ${YELLOW}⚠ Предупреждение:${NC} Файл $CLIENT_NAME.ovpn уже существует. Пропускаю."
echo -e "--------------------------------------------------"
continue
fi
# 1. Генерация запроса на сертификат (--batch убирает запрос ввода Common Name)
echo -e " -> Создание запроса на сертификат (gen-req)..."
./easyrsa --batch gen-req "$CLIENT_NAME" nopass > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e " ${RED}❌ Ошибка${NC} при создании запроса для $CLIENT_NAME"
echo -e "--------------------------------------------------"
continue
fi
# 2. Подписание сертификата (--batch убирает запрос ввода 'yes')
echo -e " -> Подписание сертификата в CA (sign-req)..."
./easyrsa --batch sign-req client "$CLIENT_NAME" > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e " ${RED}❌ Ошибка${NC} при подписании сертификата для $CLIENT_NAME"
echo -e "--------------------------------------------------"
continue
fi
# 3. Сборка финального .ovpn файла
echo -e " -> Сборка .ovpn файла конфигурации..."
BASE_CONFIG="client
dev tun
proto $S_PROTO
remote $SERVER_IP $S_PORT
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
data-ciphers $S_CIPHERS
verb 1"
{
echo "$BASE_CONFIG"
echo ""
cat "$CONF_DIR/ca.crt"
echo ""
echo ""
cat "pki/issued/$CLIENT_NAME.crt"
echo ""
echo ""
cat "pki/private/$CLIENT_NAME.key"
echo ""
echo ""
cat "$CONF_DIR/tls-crypt.key"
echo ""
} > "$OUTPUT_DIR/$CLIENT_NAME.ovpn"
if [ $? -eq 0 ]; then
echo -e " ${GREEN}✓ Успешно:${NC} Сгенерирован $OUTPUT_DIR/$CLIENT_NAME.ovpn"
else
echo -e " ${RED}❌ Ошибка${NC} при сборке файла для $CLIENT_NAME"
fi
echo -e "--------------------------------------------------"
done
echo -e "\n${GREEN}=== Генерация завершена. Все файлы сохранены в $OUTPUT_DIR ===${NC}"