if [[ ! " ${valid_ports[@]} " =~ " ${CLIENT_PORT} " ]]; then echo -e "${RED}Error: 端口号 '$CLIENT_PORT' 无效。请使用 1194、1195 或 1196 作为端口号.${NC}" exit 1 fi # 检查是否已存在指定客户端名称的证书文件 check_existing_cert() { local name=$1 local key_dir="/etc/openvpn/easy-rsa/2.0/keys" local cert_files=("$key_dir/$name.crt" "$key_dir/$name.key" "$key_dir/$name.csr")
for file in "${cert_files[@]}"; do if [ -f "$file" ]; then echo -e "${RED}Error: 已存在与客户端名称 '$name' 关联的证书文件 ($file)。请更换客户端名称或删除旧证书文件。${NC}" return 1 fi done return 0 } # 执行检查 if ! check_existing_cert "$CLIENT_NAME"; then exit 1 fi # 定义一个方法来执行命令,并显示自定义反馈结果 run_command() { local cmd="$1" local success_msg="$2" local failure_msg="$3" local dir="$4"
# 如果指定了目录,则切换到该目录 if [ -n "$dir" ]; then echo -e "${YELLOW}Changing to directory: $dir${NC}" cd "$dir" || { echo -e "${RED}Failed to change directory to $dir.${NC}"; return 1; } fi # 打印正在执行的命令 echo -e "${YELLOW}Executing: $cmd${NC}" # 执行命令并捕获输出和返回码 output=$($cmd 2>&1) status=$?
# 打印命令输出 echo -e "${YELLOW}Output:${NC}" echo "$output" # 判断命令是否成功,显示自定义反馈 if [ $status -eq 0 ]; then echo -e "${GREEN}${success_msg}${NC}" else echo -e "${RED}${failure_msg}${NC}" fi echo # 添加一个空行以区分不同命令的输出
# 返回到脚本的初始目录 if [ -n "$dir" ]; then cd - >/dev/null fi
# 返回命令的状态码,以便外部调用者可以根据结果进行进一步处理 return $status } # 加载 Easy-RSA 变量 cd /etc/openvpn/easy-rsa/2.0 source vars || { echo -e "${RED}Failed to source vars.${NC}"; exit 1; } # 创建客户端证书请求 run_command "./build-key --batch $CLIENT_NAME" \ "证书生成成功" \ "证书生成失败" \ "$EASYRSA_DIR" # 创建 client.ovpn 文件的函数,直接覆盖已存在的文件 CLIENT_OVPN="/etc/openvpn/client/client.ovpn" create_client_config() { cat << EOF > "$CLIENT_OVPN" client dev tun proto tcp remote 223.76.132.35 $CLIENT_PORT resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert $CLIENT_NAME.crt key $CLIENT_NAME.key ns-cert-type server comp-lzo route-delay 2 route-method exe verb 3 EOF }
run_command "create_client_config" \ "Client configuration file created successfully (overwritten if existed)." \ "Failed to create client configuration file."
sleep 1 # 复制生成的证书和密钥 find /etc/openvpn/easy-rsa/2.0/keys/ \( -name "$CLIENT_NAME.*" -o -name "ca.crt" \) -type f -exec cp {} /etc/openvpn/client \; if [ $? -eq 0 ]; then echo -e "${GREEN}文件复制成功${NC}" else echo -e "${RED}文件复制失败${NC}" fi sleep 1 # 打包客户端证书文件 cd /etc/openvpn/client || { echo -e "${RED}Failed to change directory to /etc/openvpn/client.${NC}"; exit 1; } run_command "tar -zcvf $CLIENT_NAME.tar.gz $CLIENT_NAME.* ca.crt client.ovpn" \ "文件打包成功,文件路径:/etc/openvpn/client/$CLIENT_NAME.tar.gz" \ "文件打包失败" sleep 2 #删除临时文件 find /etc/openvpn/client -type f ! -name "*.tar.gz" -delete if [ $? -eq 0 ]; then echo -e "${GREEN}文件清理成功${NC}" else echo -e "${RED}文件清理失败${NC}" fi