openvpn自动创建证书脚本
smartpotato 元婴
本文距离上次更新已过去 0 天,部分内容可能已经过时,请注意甄别。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/bin/bash

# 定义颜色
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
NC='\033[0m' # 重置颜色

# 设置 Easy-RSA 环境变量和目录
EASYRSA_DIR="/etc/openvpn/easy-rsa/2.0"
CLIENT_NAME=$1
CLIENT_PORT=$2

# 如果没有传入客户端名称,提示并退出
if [ -z "$CLIENT_NAME" ] || [ -z "$CLIENT_PORT" ]; then
echo -e "${RED}命令格式错误,使用方法: $0 <客户端名称> <端口号>${NC}"
exit 1
fi
valid_ports=("1194" "1195" "1196")

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

echo "=============================================================="
echo " "
echo "查看文件请输入:ls /etc/openvpn/client/$CLIENT_NAME.*"
echo " "
echo "=============================================================="
echo " "
echo "下载配置文件请输入:sz /etc/openvpn/client/$CLIENT_NAME.tar.gz"
echo " "
echo "=============================================================="
 打赏作者