├── README.md
└── ovpnx.sh
/README.md:
--------------------------------------------------------------------------------
1 | # 当前脚本不可用。脚本新增用户的角色流程暂时没想到好的处理方案。
2 | ## 改动
3 |
4 | - TODO
5 |
6 | - [] 新增添加用户角色的访问iptables限制
7 |
8 | - 优化
9 | - [x] 优化安装前检查系统命令
10 | - [x] 增加安装期间检查临时变更系统软件源为国内镜像源
11 | - [x] 修改记录客户端连接信息到钉钉的方式为记录到日志文件
12 | - [x] 优化系统日志文件路径
13 | - [x] 优化文件存放目录
14 | - [x] 20220428: 修复卸载后删除iptables规则的问题
15 | - [x] 20220429: 优化easyrsa工具的下载安装方式
16 | - [x] 20220429: 优化输出及安装步骤
17 | - [x] 20220430: 删除用户,备份用户信息文件,释放IP地址
18 | - [x] 20221102: 优化安装输出、不修改腾讯apt镜像源、添加安装配置异常处理
19 | - 新增
20 | - [x] 在邮件中增加发送Windows客户端配置文件
21 | - [x] 新增设置SMTP服务时是否使用SSL协议端口
22 | - [x] 新增设置SMTP服务时发送测试邮件
23 | - [x] 新增IP地址池,直接给每个客户端分配固定IP地址,删除用户后并归还IP地址进行重复利用
24 | - [x] 实现根据角色划分网段的功能,使用iptables限制角色访问的网段,实现网络权限隔离限制
25 | - [x] 检查并优化系统参数
26 | - [x] 20220429: 新增卸载时备份配置和iptables规则等相关文件到/tmp目录中
27 | - [x] 20221102: 新增安装时安装管理脚本,添加删除时备份管理脚本步骤
28 |
29 | # 一、OpenVPN安装管理脚本
30 |
31 | ## 根据 https://github.com/Nyr/openvpn-install 进行的功能优化
32 |
33 | 1. 汉化
34 | 2. 增加选择客户端分配固定IP地址池网段的功能
35 | 3. 增加用户名密码验证脚本
36 | 4. 增加配置SMTP发送邮件的功能
37 | 5. 去除发送客户端连接、断开状态到钉钉Webhook机器人,改为记录到日志文件
38 | 6. 增加配置简单密码认证管理端口的功能
39 | 7. 增加创建用户后将用户名密码及配置文件等信息通过SMTP邮件服务发送到用户邮箱
40 | 8. 增加安装时控制是否允许客户端之间进行网络互联,是否允许客户端访问服务端所在的网络
41 | 9. 实现根据角色划分网段的功能,使用iptables限制角色访问的网段,实现网络权限隔离限制
42 | 10. 卸载时备份配置文件和iptables规则等相关文件到/tmp目录中
43 | 11. 新增用户时分配角色,设置网络访问策略
44 | 12. 去除不必要的脚本代码
45 |
46 | # 二、安装使用方法
47 |
48 | ```bash
49 | git clone https://github.com/RationalMonster/install-manage-openvpn.git
50 | bash install-manage-openvpn/ovpnx.sh
51 | ```
52 |
53 | # 三、客户端连接方法
54 |
55 | ## Linux
56 |
57 | ```bash
58 | openvpn --config 客户端配置文件(以.ovpn结尾的文件) --auth-user-pass --daemon
59 | # 断开连接
60 | ps -ef |grep openvpn |grep "daemon" |awk '{print $2}' | xargs kill -9
61 | ```
62 |
63 | ## Windows
64 |
65 | - Windows下使用客户端openvpn gui,将配置文件放置在`C盘:\用户\您的用户名\OpenVPN\config`目录下即可导入配置文件
66 | - Openvpn GUI下载地址:https://openvpn.net/community-downloads/
67 | - Openvpn GUI一次只能一个连接
68 |
69 | ## MacOS
70 |
71 | - MacOS下使用客户端tunnelblick,将配置文件使用tunnelblick打开即可导入配置文件
72 | - Tunnelblick下载地址:https://tunnelblick.net/downloads.html
73 | - Tunnelblick同时可以连接多个实例
74 |
75 |
76 | # 参考文章
77 |
78 | - https://gitbook.curiouser.top/origin/openvpn-server.html
79 | - https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4
80 |
--------------------------------------------------------------------------------
/ovpnx.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #请勿删除该预制空变量,后续会赋予将安装后的用户角色编号
4 | setup_subnet_roles_nu=
5 | setup_subnet_roles=
6 | developer_allowed_access_net=
7 | tester_allowed_access_net=
8 | manager_allowed_access_net=
9 | bussiness_allowed_access_net=
10 | robots_allowed_access_net=
11 | # set -x
12 |
13 | INSTALL_DIR=/etc/openvpn
14 | SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
15 |
16 | check_command() {
17 | no_command=""
18 | if ! command -v ifconfig >/dev/null 2>&1; then
19 | no_command=$no_command"net-tools "
20 | fi
21 | if ! command -v ip >/dev/null 2>&1; then
22 | no_command=$no_command"iproute2 "
23 | fi
24 | if ! command -v curl >/dev/null 2>&1; then
25 | no_command=$no_command"curl "
26 | fi
27 | if ! command -v wget >/dev/null 2>&1; then
28 | no_command=$no_command"wget "
29 | fi
30 | if ! command -v ipset >/dev/null 2>&1; then
31 | no_command=$no_command"ipset "
32 | fi
33 | if ! command -v tail >/dev/null 2>&1; then
34 | no_command=$no_command"coreutils "
35 | fi
36 | if ! command -v sed >/dev/null 2>&1; then
37 | no_command=$no_command"sed "
38 | fi
39 | if ! command -v grep >/dev/null 2>&1; then
40 | no_command=$no_command"grep "
41 | fi
42 | if [[ ! -z "$no_command" ]]; then
43 | echo -e "\033[31m$no_command 命令不存在,正在下载安装!\033[0m"
44 | if os="ubuntu"; then
45 | apt install -y $no_command >/dev/null 2>&1
46 | rm -f /etc/apt/sources.list.d/tmp.list
47 | elif os="debian"; then
48 | apt install -y $no_command >/dev/null 2>&1
49 | rm -f /etc/apt/sources.list.d/tmp.list
50 | elif os="centos"; then
51 | yum install -y $no_command >/dev/null 2>&1
52 | elif os="fedora"; then
53 | dnf install -y $no_command >/dev/null 2>&1
54 | fi
55 | fi
56 | }
57 |
58 | system_check() {
59 | # Detect OS
60 | # $os_version variables aren't always in use, but are kept here for convenience
61 | if grep -qs "ubuntu" /etc/os-release; then
62 | os="ubuntu"
63 | os_version=$(grep 'VERSION_ID' /etc/os-release | cut -d '"' -f 2 | tr -d '.')
64 | group_name="nogroup"
65 |
66 | elif [[ -e /etc/debian_version ]]; then
67 | os="debian"
68 | os_version=$(grep -oE '[0-9]+' /etc/debian_version | head -1)
69 | group_name="nogroup"
70 | elif [[ -e /etc/centos-release ]]; then
71 | os="centos"
72 | os_version=$(grep -oE '[0-9]+' /etc/centos-release | head -1)
73 | group_name="nobody"
74 | elif [[ -e /etc/fedora-release ]]; then
75 | os="fedora"
76 | os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1)
77 | group_name="nobody"
78 | else
79 | echo "本脚本只支持Ubuntu, Debian, CentOS, and Fedora."
80 | exit
81 | fi
82 |
83 | # Detect Debian users running the script with "sh" instead of bash
84 | if readlink /proc/$$/exe | grep -q "dash"; then
85 | echo '本脚本不支持使用sh执行'
86 | exit
87 | fi
88 |
89 | # Discard stdin. Needed when running from an one-liner which includes a newline
90 | read -N 999999 -t 0.001
91 |
92 | # Detect OpenVZ 6
93 | if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then
94 | echo "内核太旧,本脚本不支持,请升级内核!"
95 | exit
96 | fi
97 |
98 | if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then
99 | echo "本脚本仅支持Ubuntu 18.04 或更高的版本!"
100 | exit
101 | fi
102 |
103 | if [[ "$os" == "ubuntu" ]]; then
104 | if cat /etc/apt/sources.list | grep -vE "#" | grep -E "ustc.edu|aliyun|tuna.tsinghua|163|tencentyun"; then
105 | echo "apt源已经是国内源,无需设置"
106 | else
107 | cp /etc/apt/sources.list /etc/apt/sources.list.d/tmp.list
108 | sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/tmp.list
109 | sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/tmp.list
110 | echo "临时更换Ubuntu apt源为中科大镜像站,正在apt update"
111 | apt update >/dev/null 2>&1
112 | check_command
113 | fi
114 | fi
115 |
116 | if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then
117 | echo "本脚本仅支持Debian 9 或更高的版本!"
118 | exit
119 | fi
120 | if [[ "$os" == "debian" ]]; then
121 | cp /etc/apt/sources.list /etc/apt/sources.list.d/tmp.list
122 | sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/tmp.list
123 | sed -i 's/security.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/tmp.list
124 | echo "临时更换Debian apt源为中科大镜像站,正在apt update"
125 | apt update >/dev/null 2>&1
126 | fi
127 |
128 | if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then
129 | echo "本脚本仅支持CentOS 7 或更高的版本!"
130 | exit
131 | fi
132 |
133 | # if [[ "$os" == "centos" ]];then
134 | # # todo: 临时更换Yum源
135 | # fi
136 |
137 | # Detect environments where $PATH does not include the sbin directories
138 | if ! grep -q sbin <<<"$PATH"; then
139 | echo '$PATH does not include sbin. Try using "su -" instead of "su".'
140 | exit
141 | fi
142 |
143 | if [[ "$EUID" -ne 0 ]]; then
144 | echo "本脚本仅支持使用root权限执行"
145 | exit
146 | fi
147 |
148 | if [[ ! -e /dev/net/tun ]] || ! (exec 7<>/dev/net/tun) >/dev/null 2>&1; then
149 | echo "The system does not have the TUN device available. Tun needs to be enabled before running this installer."
150 | exit
151 | fi
152 |
153 | }
154 |
155 | setup_smtp_server_profile() {
156 | read -p "SMTP服务器地址: " smtp_server_addr
157 |
158 | read -p "SMTP服务器是否使用SSL/TLS安全连接?[Yy/Nn] " setup_smtp_server_tls_ssl
159 | until [[ -z "$setup_smtp_server_tls_ssl" || "$setup_smtp_server_tls_ssl" =~ ^[yYnN]*$ ]]; do
160 | read -p "$setup_smtp_server_tls_ssl为无效的选项,SMTP服务器是否使用SSL/TLS连接?[Yy/Nn] " setup_client_profile_nat_pub_ip_domain
161 | done
162 | if [[ $setup_smtp_server_tls_ssl =~ ^[nN] ]]; then
163 | read -p "SMTP服务器端口: " smtp_server_port
164 | if [[ $smtp_server_port == 25 ]]; then
165 | smtp_url="smtp://$smtp_server_addr:$smtp_server_port"
166 | else
167 | echo "$smtp_server_port 是非常见SMTP服务商的普通端口,请和SMTP服务商确认。"
168 | exit
169 | fi
170 | elif [[ $setup_smtp_server_tls_ssl =~ ^[yY] ]]; then
171 | read -p "SMTP服务器安全端口: " smtp_server_security_port
172 | if [[ "$smtp_server_security_port" =~ ^[465|587] ]]; then
173 | smtp_url="smtps://$smtp_server_addr:$smtp_server_security_port"
174 | else
175 | echo "$smtp_server_security_port 是非常见SMTP服务商的安全端口,请和SMTP服务商确认。"
176 | exit
177 | fi
178 |
179 | fi
180 |
181 | read -p "SMTP服务器用户名: " smtp_server_user
182 | read -s -p "SMTP服务器用户密码: " smtp_server_passwd
183 |
184 | echo "FROM: $smtp_server_user
185 | To: $smtp_server_user <$smtp_server_user>
186 | Subject: SMTP测试邮件
187 | Cc:
188 | MIME-Version: 1.0
189 | Content-Type: multipart/alternative; boundary="DELIMETER"
190 |
191 | --DELIMETER
192 | Content-Type: text/html; charset="utf-8"
193 |
194 |
195 |
196 | OpenVPN服务SMTP测试邮件,请勿回复!
197 |
198 |
199 |
200 | --DELIMETER
201 | " >/tmp/emai-data.txt
202 |
203 | response=$(
204 | curl -s --ssl-reqd --write-out %{http_code} --output /dev/null \
205 | --url "$smtp_url" \
206 | --user "$smtp_server_user:$smtp_server_passwd" \
207 | --mail-from "$smtp_server_user" \
208 | --mail-rcpt $smtp_server_user \
209 | --upload-file /tmp/emai-data.txt
210 | )
211 | if [ $response -eq 250 ]; then
212 | {
213 | echo "smtp_server_addr=$smtp_server_addr"
214 | echo "smtp_server_port=${smtp_url##*:}"
215 | echo "smtp_server_user=$smtp_server_user"
216 | echo "smtp_server_passwd=$smtp_server_passwd"
217 | } >$INSTALL_DIR/server/smtp.conf
218 | echo
219 | echo "已通过SMTP服务器发送测试邮件。SMTP服务器设置成功!如需重新配置请直接修改$INSTALL_DIR/server/smtp.conf或删除后重新运行该脚本进行配置]"
220 | echo
221 | else
222 | echo "无法通过SMTP服务器发送测试邮件。SMTP服务返回状态码:$response 。请根据SMTP服务状态码检查SMTP服务配置!"
223 | exit 1
224 | fi
225 | }
226 |
227 | check_smtp_server_profile() {
228 | if [[ -f $INSTALL_DIR/server/smtp.conf ]]; then
229 | while read line; do
230 | eval "$line"
231 | done <$INSTALL_DIR/server/smtp.conf
232 |
233 | if [[ -z $smtp_server_addr || -z $smtp_server_port || -z $smtp_server_user || -z $smtp_server_passwd ]]; then
234 | echo "SMTP配置不全,请重新配置!"
235 | rm -rf $INSTALL_DIR/server/smtp.conf
236 | setup_smtp_server_profile
237 | exit
238 | else
239 | if [[ "$smtp_server_port" =~ ^[465|587] ]]; then
240 | smtp_url="smtps://$smtp_server_addr:$smtp_server_security_port"
241 | fi
242 | if [[ "$smtp_server_port" =~ ^[25] ]]; then
243 | smtp_url="smtp://$smtp_server_addr:$smtp_server_security_port"
244 | fi
245 | fi
246 | else
247 | echo "SMTP配置文件不存在,无法通过邮件发送新用户的配置!请先正确配置SMTP服务"
248 | setup_smtp_server_profile
249 | fi
250 | }
251 |
252 | send_email() {
253 | check_smtp_server_profile
254 | if [ $? -eq 0 ]; then
255 | windows_config_context=$(
256 | echo "windows-driver wintun"
257 | cat $4
258 | )
259 | echo "FROM: $smtp_server_user
260 | To: $2 <$1>
261 | Subject: VPN配置信息
262 | Cc:
263 | MIME-Version: 1.0
264 | Content-Type: multipart/alternative; boundary="DELIMETER"
265 |
266 | --DELIMETER
267 | Content-Type: text/html; charset="utf-8"
268 |
269 |
270 |
271 |
272 |
277 |
278 |
279 | Dear $2 :
280 | 1. VPN配置信息
281 |
282 |
283 | 用户名 |
284 | 密码 |
285 | 配置文件 |
286 |
287 |
288 |
289 | $2
290 | |
291 |
292 | $3
293 | |
294 |
295 | 见附件
296 | |
297 |
298 |
299 | 2. 使用说明
300 | Windows下使用客户端openvpn gui,下载附件中的配置文件,放置在\"C盘:\用户\您的用户名\OpenVPN\config\"目录下即可导入配置文件
301 | MacOS下使用客户端tunnelblick,下载附件中的配置文件,使用tunnelblick打开即可导入配置文件
302 |
303 |
304 |
305 | --DELIMETER
306 | Content-Type: text/plain
307 | Content-Transfer-Encoding: base64
308 | Content-Disposition: attachment; filename=\"OpenVPN-Windows.ovpn\"
309 |
310 | [$(echo "$windows_config_context" | base64)]
311 |
312 | --DELIMETER
313 |
314 | --DELIMETER
315 | Content-Type: text/plain
316 | Content-Transfer-Encoding: base64
317 | Content-Disposition: attachment; filename=\"OpenVPN-MacOS.ovpn\"
318 |
319 | [$(cat "$4" | base64)]
320 |
321 | --DELIMETER
322 | " >/tmp/emai-data.txt
323 | response=$(
324 | curl -s --ssl-reqd --write-out %{http_code} --output /dev/null \
325 | --url "$smtp_url" \
326 | --user "$smtp_server_user:$smtp_server_passwd" \
327 | --mail-from "$smtp_server_user" \
328 | --mail-rcpt $1 \
329 | --upload-file /tmp/emai-data.txt
330 | )
331 | if [ $response -eq 250 ]; then
332 | echo "新用户配置等信息已通过SMTP服务发送至用户邮箱,请提醒用户及时查收!"
333 | rm -f /tmp/emai-data.txt
334 | else
335 | echo "新用户配置等信息通过SMTP服务无法发送至用户邮箱,SMTP服务返回状态码:$response 。请根据SMTP服务状态码检查SMTP服务配置!"
336 | fi
337 | else
338 | exit
339 | fi
340 | }
341 |
342 | # 参数1:用户名
343 | # 参数2;用户角色
344 | # 参数3: 用户角色放行的IP地址段
345 | new_client_profile() {
346 | cd $INSTALL_DIR/server/easy-rsa/
347 | EASYRSA_CERT_EXPIRE=36500 ./easyrsa build-client-full "$1" nopass
348 | # Generates the custom client.ovpn
349 | {
350 | cat $INSTALL_DIR/server/client-common.txt
351 | echo ""
352 | cat $INSTALL_DIR/server/easy-rsa/pki/ca.crt
353 | echo ""
354 | echo ""
355 | sed -ne '/BEGIN CERTIFICATE/,$ p' $INSTALL_DIR/server/easy-rsa/pki/issued/"$1".crt
356 | echo ""
357 | echo ""
358 | cat $INSTALL_DIR/server/easy-rsa/pki/private/"$1".key
359 | echo ""
360 | echo ""
361 | sed -ne '/BEGIN OpenVPN Static key/,$ p' $INSTALL_DIR/server/pki/tc.key
362 | echo ""
363 | } >$INSTALL_DIR/client/profiles/"$1".ovpn
364 | client_random_password=$(echo $(date +%s)$RANDOM | md5sum | head -c 15)
365 | echo "$1 $client_random_password" >>$INSTALL_DIR/server/psw-file
366 | if [[ ! -f $INSTALL_DIR/server/ccd/$1 ]]; then
367 | cleint_ip=$(head -n 1 $INSTALL_DIR/server/ip-pools/$2-ip-pools)
368 | echo "ifconfig-push $cleint_ip 255.255.255.0" >>$INSTALL_DIR/server/ccd/$1
369 | echo -e "push \"route $3 255.255.255.0 $cleint_ip\"" >>$INSTALL_DIR/server/ccd/$1
370 | sed -i "/\<$cleint_ip\>/d" $INSTALL_DIR/server/ip-pools/$2-ip-pools
371 | fi
372 | echo "$2 $1" >>$INSTALL_DIR/server/clients-info
373 | }
374 | # 参数1:用户名
375 | # 参数2;用户角色id
376 | # 参数3:用户邮箱地址
377 | # 参数4:用户角色放行的IP地址段
378 | new_client() {
379 | check_smtp_server_profile
380 | if [ $? -eq 0 ]; then
381 | case "$2" in
382 | 1)
383 | new_client_profile $1 developer $4
384 | ;;
385 | 2)
386 | new_client_profile $1 tester $4
387 | ;;
388 | 3)
389 | new_client_profile $1 manager $4
390 | ;;
391 | 4)
392 | new_client_profile $1 bussiness $4
393 | ;;
394 | 5)
395 | new_client_profile $1 robots $4
396 | ;;
397 | esac
398 |
399 | send_email $3 $1 $client_random_password $INSTALL_DIR/client/profiles/$1.ovpn
400 |
401 | fi
402 | }
403 |
404 | mask2cdr() {
405 | local x=${1##*255.}
406 | set -- 0^^128^192^224^240^248^252^254^ $(((${#1} - ${#x}) * 2)) ${x%%.*}
407 | x=${1%%$3*}
408 | echo $(($2 + (${#x} / 4)))
409 | }
410 |
411 | if [[ ! -e $INSTALL_DIR/server/server.conf ]]; then
412 | system_check
413 | clear
414 | echo 'OpenVPN安装管理脚本(根据https://github.com/Nyr/openvpn-install进行的优化), 以下为优化的功能:'
415 | echo " 1. 汉化"
416 | echo " 2. 增加选择客户端分配IP地址池网段的功能"
417 | echo " 3. 增加用户名密码验证脚本"
418 | echo " 4. 增加配置SMTP发送邮件的功能"
419 | echo " 5. 增加发送客户端连接、断开状态到日志文件"
420 | echo " 6. 增加配置简单密码认证管理端口的功能"
421 | echo " 7. 增加创建用户后将用户名密码及配置文件等信息通过SMTP邮件服务发送到用户邮箱"
422 | echo " 8. 增加安装时控制是否允许客户端之间进行网络互联,是否允许客户端访问服务端所在的网络"
423 | echo " 9. 去除不必要的脚本代码"
424 | # If system has a single IPv4, it is selected automatically. Else, ask the user
425 |
426 | if [[ $(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}') -eq 1 ]]; then
427 | ip=$(ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}')
428 | else
429 | ip_nu=$(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}')
430 | echo
431 | echo "1. OpenVPN服务端监听在以下哪个IPv4地址上?"
432 | ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | nl -s ') '
433 | read -p "IPv4地址,默认[1]: " listen_ip_nu
434 | until [[ -z "$listen_ip_nu" || "$listen_ip_nu" =~ ^[0-9]+$ && "$listen_ip_nu" -le "$ip_nu" ]]; do
435 | echo "$listen_ip_nu: 无效的选项."
436 | read -p "IPv4地址[1]: " listen_ip_nu
437 | done
438 | [[ -z "$listen_ip_nu" ]] && ip_number="1"
439 | ip=$(ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | sed -n "$listen_ip_nu"p)
440 | fi
441 | server_ip_local_netmask=$(ifconfig -a | grep $ip | grep -w 'inet' | awk -F'[ :]+' '{print $5}')
442 |
443 | server_ip_local_net_cdr=$(mask2cdr $server_ip_local_netmask)
444 | case "$server_ip_local_net_cdr" in
445 | 8)
446 | server_ip_local_net=$(echo $ip | awk -F'.' '{print $1".0.0.0"}')
447 | server_ip_local_net_with_cdr=$(echo $server_ip_local_net"/8")
448 | ;;
449 | 16)
450 | server_ip_local_net=$(echo $ip | awk -F'.' '{print $1"."$2".0.0"}')
451 | server_ip_local_net_with_cdr=$(echo $server_ip_local_net"/16")
452 | ;;
453 | 24)
454 | server_ip_local_net=$(echo $ip | awk -F'.' '{print $1"."$2"."$3".0"}')
455 | server_ip_local_net_with_cdr=$(echo $server_ip_local_net"/24")
456 | ;;
457 | 32)
458 | server_ip_local_net=$(echo $ip | awk -F'.' '{print $1"."$2"."$3"."$4}')
459 | server_ip_local_net_with_cdr=$(echo $server_ip_local_net"/32")
460 | ;;
461 | esac
462 |
463 | # If system has a single IPv6, it is selected automatically
464 | if [[ $(ip -6 addr | grep -c 'inet6 [23]') -eq 1 ]]; then
465 | ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}')
466 | fi
467 | # If system has multiple IPv6, ask the user to select one
468 | if [[ $(ip -6 addr | grep -c 'inet6 [23]') -gt 1 ]]; then
469 | number_of_ip6=$(ip -6 addr | grep -c 'inet6 [23]')
470 | echo
471 | echo "Which IPv6 address should be used?"
472 | ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | nl -s ') '
473 | read -p "IPv6 address [1]: " ip6_number
474 | until [[ -z "$ip6_number" || "$ip6_number" =~ ^[0-9]+$ && "$ip6_number" -le "$number_of_ip6" ]]; do
475 | echo "$ip6_number: 无效的选项."
476 | read -p "IPv6 address [1]: " ip6_number
477 | done
478 | [[ -z "$ip6_number" ]] && ip6_number="1"
479 | ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | sed -n "$ip6_number"p)
480 | fi
481 |
482 | echo
483 |
484 | echo "2. 配置OpenVPN使用的通信协议?"
485 | echo -e " 1) \033[41;30mTCP (推荐)\033[0m"
486 | echo -e " 2) \033[41;30mUDP\033[0m"
487 | read -p "默认协议(默认TCP[1]): " protocol
488 | until [[ -z "$protocol" || "$protocol" =~ ^[12]$ ]]; do
489 | echo "$protocol: 无效的选项."
490 | read -p "Protocol [1]: " protocol
491 | done
492 | case "$protocol" in
493 | 1 | "")
494 | protocol=tcp
495 | ;;
496 | 2)
497 | protocol=udp
498 | ;;
499 | esac
500 |
501 | echo
502 |
503 | echo "3. 配置客户端IP地址池网段模式:"
504 | echo -e " 1) 单网络段模式:\033[41;30m所有客户端分配至在一个网络段中,所有用户访问相同的服务端网段。适用于客户端个数少于254个的情况\033[0m"
505 | echo -e " 2) 多网络段模式:\033[41;30m可将客户端划分角色分配到不同网络段中,不同角色访问不同的服务端网段。同时适用于客户端个数多于254个的情况\033[0m"
506 | read -p "客户端IP地址池网段模式(默认单网段模式[1]): " server_ip_subnet_option
507 | until [[ -z "$server_ip_subnet_option" || "$server_ip_subnet_option" =~ ^[1|2]$ ]]; do
508 | read -p "$server_ip_subnet_option 为无效的选项。客户端IP地址池网段模式[1]: " server_ip_subnet_option
509 | done
510 | [[ -z "$server_ip_subnet_option" ]] && server_ip_subnet_option="1"
511 | echo
512 |
513 | case "$server_ip_subnet_option" in
514 | 1)
515 | echo "4. 单网络段模式:配置OpenVPN客户端IP地址池网段"
516 | echo -e " 1) \033[41;30m10.8.1.0\033[0m"
517 | echo -e " 2) \033[41;30m10.6.2.0\033[0m"
518 | echo -e " 3) \033[41;30m自定义客户端IP地址池网段\033[0m"
519 | read -p "单网络段模式:默认分配客户端IP地址池网段[1]: " server_single_ip_net_option
520 |
521 | [[ -z "$server_single_ip_net_option" ]] && server_single_ip_net_option="1"
522 | case "$server_single_ip_net_option" in
523 | 1)
524 | server_ip_net="10.8.1.0"
525 | ;;
526 | 2)
527 | server_ip_net="10.6.2.0"
528 | ;;
529 | 3)
530 | read -p "请输入自定义的客户端IP地址池网段(规则: 四段位,前三段位数值范围1~254,最后一段需为0): " unsanitized_server_ip_net
531 | server_ip_net=$(sed 's/[^[1-9][0-9]{1,3}\.[0-9]{1,3}\.[1-9][0-9]{1,3}\.0$]/_/g' <<<"$unsanitized_server_ip_net")
532 | until [[ -z "$server_ip_net" || $server_ip_net =~ ^[1-9][0-9]{1,3}\.[0-9]{1,3}\.[1-9][0-9]{1,3}\.0$ && $(echo $server_ip_net | awk -F. '$1<255&&$2<255&&$3<255&&$4<255{print "yes"}') == "yes" ]]; do
533 | echo " $server_ip_net为无效的IP地址池网段"
534 | read -p " 请输入有效的客户端IP地址池网段: " server_ip_net
535 | done
536 | ;;
537 | esac
538 | ;;
539 | 2)
540 |
541 | read -p "4. 请客户端IP地址池主网段(例如:10.6.0.0): " server_ip_net
542 | until [[ -z "$server_ip_net" || $server_ip_net =~ ^[1-9][0-9]{1,3}\.[0-9]{1,3}\.0\.0$ && $(echo $server_ip_net | awk -F. '$1<255&&$2<255&&$3<255&&$4<255{print "yes"}') == "yes" ]]; do
543 | echo " $server_ip_net为无效的IP地址池网段"
544 | read -p " 请设置有效的客户端IP地址池网段: " server_ip_net
545 | done
546 | [[ -z "$server_ip_net" ]] && server_ip_net="10.6.0.0"
547 | echo
548 | server_ip_net_prefix=$(echo $server_ip_net | cut -d . -f 1,2)
549 | echo "5. 请设置客户端角色,内置角色网段划分,可根据编号选择,多选以逗号分割:"
550 | echo -e " 1) \033[41;30m开发人员角色\033[0m"
551 | echo -e " 2) \033[41;30m测试人员角色\033[0m"
552 | echo -e " 3) \033[41;30m运维人员角色\033[0m"
553 | echo -e " 4) \033[41;30m业务人员角色\033[0m"
554 | echo -e " 5) \033[41;30m机器人 角 色\033[0m"
555 | echo -e " 6) \033[41;30m以上所有角色\033[0m"
556 | read -p "请选择预设置客户端角色: " server_ip_subnet_roles
557 | until [[ -z "$server_ip_subnet_roles" || ${server_ip_subnet_roles} =~ ^[1-6,]{1,9}$ ]]; do
558 | echo " $server_ip_subnet_roles为无效值"
559 | read -p "请重新设置客户端角色: " server_ip_subnet_roles
560 | done
561 | if [[ $server_ip_subnet_roles == 6 ]]; then
562 | server_ip_subnet_roles=1,2,3,4,5
563 | fi
564 | sed -i -e "s/^setup_subnet_roles_nu=.*/setup_subnet_roles_nu=$server_ip_subnet_roles/g" $0
565 | for i in ${server_ip_subnet_roles//,/ }; do
566 | case $i in
567 | 1)
568 | read -e -p " 请设置开发人员角色IP地址网段:" -i "${server_ip_net_prefix}." server_subnet_developer_ip_pool
569 | until [[ ! -z "$server_subnet_developer_ip_pool" && $server_subnet_developer_ip_pool =~ ^$server_ip_net_prefix.[1-9]{1,3}\.0$ ]]; do
570 | read -e -p " $server_subnet_developer_ip_pool不属于$server_ip_net下的子网段,请重新设置开发人员角色IP地址网段: " -i "${server_ip_net_prefix}." server_subnet_developer_ip_pool
571 | done
572 | sed -i -e "/^setup_subnet_roles=.*/ s/$/1:developer,/g" $0
573 | ;;
574 | 2)
575 | read -e -p " 请设置测试人员角色IP地址网段:" -i "${server_ip_net_prefix}." server_subnet_tester_ip_pool
576 | until [[ ! -z "$server_subnet_tester_ip_pool" && ! $server_subnet_tester_ip_pool == $server_subnet_developer_ip_pool ]]; do
577 | read -p " $server_subnet_tester_ip_pool网段已被占用,请重新设置测试人员角色IP地址网段:" server_subnet_tester_ip_pool
578 | until [[ $server_subnet_tester_ip_pool =~ ^$server_ip_net_prefix.[1-9]{1,3}\.0$ ]]; do
579 | read -e -p " $server_subnet_tester_ip_pool不属于$server_ip_net下的子网段,请重新设置测试人员角色IP地址网段: " -i "${server_ip_net_prefix}." server_subnet_tester_ip_pool
580 | done
581 | done
582 | sed -i -e "/^setup_subnet_roles=.*/ s/$/2:tester,/g" $0
583 | ;;
584 | 3)
585 | read -e -p " 请设置运维人员角色IP地址网段:" -i "${server_ip_net_prefix}." server_subnet_manager_ip_pool
586 | until [[ ! -z "$server_subnet_manager_ip_pool" && ! $server_subnet_manager_ip_pool == $server_subnet_developer_ip_pool && ! $server_subnet_manager_ip_pool == $server_subnet_tester_ip_pool ]]; do
587 | read -p " $server_subnet_manager_ip_pool网段已被占用,请重新设置运维人员角色IP地址网段:" server_subnet_manager_ip_pool
588 | until [[ $server_subnet_manager_ip_pool =~ ^$server_ip_net_prefix.[1-9]{1,3}\.0$ ]]; do
589 | read -e -p " $server_subnet_manager_ip_pool不属于$server_ip_net下的子网段,请重新设置运维人员角色IP地址网段: " -i "${server_ip_net_prefix}." server_subnet_manager_ip_pool
590 | done
591 | done
592 | sed -i -e "/^setup_subnet_roles=.*/ s/$/3:manager,/g" $0
593 | ;;
594 | 4)
595 | read -e -p " 请设置业务人员角色IP地址网段:" -i "${server_ip_net_prefix}." server_subnet_bussiness_ip_pool
596 |
597 | until [[ ! -z "$server_subnet_bussiness_ip_pool" && ! $server_subnet_bussiness_ip_pool == $server_subnet_developer_ip_pool && ! $server_subnet_bussiness_ip_pool == $server_subnet_tester_ip_pool && ! $server_subnet_bussiness_ip_pool == $server_subnet_manager_ip_pool ]]; do
598 | read -p " $server_subnet_bussiness_ip_pool网段已被占用,请重新设置业务人员角色IP地址网段:" server_subnet_bussiness_ip_pool
599 | until [[ $server_subnet_bussiness_ip_pool =~ ^$server_ip_net_prefix.[1-9]{1,3}\.0$ ]]; do
600 | read -e -p " $server_subnet_bussiness_ip_pool不属于$server_ip_net下的子网段,请重新设置业务人员角色IP地址网段: " -i "${server_ip_net_prefix}." server_subnet_bussiness_ip_pool
601 | done
602 | done
603 | sed -i -e "/^setup_subnet_roles=.*/ s/$/4:bussiness,/g" $0
604 | ;;
605 | 5)
606 | read -e -p " 请设置机器人 角 色IP地址网段:" -i "${server_ip_net_prefix}." server_subnet_robots_ip_pool
607 |
608 | until [[ ! -z "$server_subnet_robots_ip_pool" && ! $server_subnet_robots_ip_pool == $server_subnet_developer_ip_pool && ! $server_subnet_robots_ip_pool == $server_subnet_tester_ip_pool && ! $server_subnet_robots_ip_pool == $server_subnet_manager_ip_pool && ! $server_subnet_robots_ip_pool == $server_subnet_bussiness_ip_pool ]]; do
609 | read -p " $server_subnet_robots_ip_pool网段已被占用,请重新设置机器人角色IP地址网段:" server_subnet_robots_ip_pool
610 | until [[ $server_subnet_robots_ip_pool =~ ^$server_ip_net_prefix.[1-9]{1,3}\.0$ ]]; do
611 | read -e -p " $server_subnet_robots_ip_pool不属于$server_ip_net下的子网段,请重新设置机器人角色IP地址网段: " -i "${server_ip_net_prefix}." server_subnet_robots_ip_pool
612 | done
613 | done
614 | sed -i -e "/^setup_subnet_roles=.*/ s/$/5:robots/g" $0
615 | ;;
616 | *)
617 | echo "客户端角色设置错误:$i"
618 | ;;
619 | esac
620 | done
621 | ;;
622 | esac
623 |
624 | echo
625 |
626 | read -p "6. 配置OpenVPN服务端监听的端口? 默认端口[11940]: " port
627 | until [[ -z "$port" || "$port" =~ ^[1-9]+$ && "$port" -le 65535 && "$port" -gt 1024 ]]; do
628 | echo "$port 端口无效,请设置1025 <= => 65535范围之内的端口号: "
629 | read -p "默认端口[1194]: " port
630 | done
631 | [[ -z "$port" ]] && port="11940"
632 |
633 | echo
634 |
635 | read -p "7. 是否在客户端配置文件中设置NAT的公网IP地址或域名[Yy/Nn]? " setup_client_profile_nat_pub_ip_domain
636 | until [[ -z "$setup_client_profile_nat_pub_ip_domain" || "$setup_client_profile_nat_pub_ip_domain" =~ ^[yYnN]*$ ]]; do
637 | read -p "$setup_client_profile_nat_pub_ip_domain为无效的选项,是否在客户端配置文件中设置NAT的公网IP地址或域名[Yy/Nn]? " setup_client_profile_nat_pub_ip_domain
638 | done
639 | [[ -z "$setup_client_profile_nat_pub_ip_domain" ]] && setup_client_profile_nat_pub_ip_domain="y"
640 | case "$setup_client_profile_nat_pub_ip_domain" in
641 | y | Y)
642 | read -p "设置NAT的公网IP地址或域名: " client_profile_nat_pub_ip_domain
643 | until [[ ! -z "$client_profile_nat_pub_ip_domain" && "$client_profile_nat_pub_ip_domain" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ || "$client_profile_nat_pub_ip_domain" =~ ^[a-zA-Z\.]*$ ]]; do
644 | read -p "$client_profile_nat_pub_ip_domain为无效的IP地址与域名,请重新设置NAT的公网IP地址或域名: " client_profile_nat_pub_ip_domain
645 | done
646 | ;;
647 | n | N) ;;
648 |
649 | esac
650 |
651 | echo
652 |
653 | read -p "8. 是否允许客户端间互联[Yy/Nn]? " setup_client_conn
654 | until [[ -z "$setup_client_conn" || "$setup_client_conn" =~ ^[yYnN]*$ ]]; do
655 | read -p " $setup_client_conn为无效的选项,是否允许客户端间互联[Yy/Nn]? " setup_client_conn
656 | done
657 | [[ -z "$setup_client_conn" ]] && setup_client_conn="y"
658 |
659 | echo
660 |
661 | read -p "9. 是否允许客户端访问服务端所在网段[Yy/Nn]? " setup_client_conn_server_net
662 | until [[ -z "$setup_client_conn_server_net" || "$setup_client_conn_server_net" =~ ^[yYnN]*$ ]]; do
663 | read -p " $setup_client_conn_server_net为无效的选项,是否允许客户端访问服务端所在网段[Yy/Nn]? " setup_client_conn_server_net
664 | done
665 | [[ -z "$setup_client_conn_server_net" ]] && setup_client_conn_server_net="y"
666 |
667 | for i in ${server_ip_subnet_roles//,/ }; do
668 | case $i in
669 | 1)
670 | read -p " 请设置开发人员角色允许访问的内网网段或特定IP地址(多个网段或IP地址以逗号分割):" client_role_developer_allow_net
671 | sed -i -e "s/^developer_allowed_access_net=.*/developer_allowed_access_net=$client_role_developer_allow_net/g" $0
672 | ;;
673 | 2)
674 | read -p " 请设置测试人员角色允许访问的内网网段或特定IP地址(多个网段或IP地址以逗号分割):" client_role_tester_allow_net
675 | sed -i -e "s/^tester_allowed_access_net=.*/tester_allowed_access_net=$client_role_developer_allow_net/g" $0
676 | ;;
677 | 3)
678 | read -p " 请设置运维人员角色允许访问的内网网段或特定IP地址(多个网段或IP地址以逗号分割):" client_role_manager_allow_net
679 | sed -i -e "s/^manager_allowed_access_net=.*/manager_allowed_access_net=$client_role_developer_allow_net/g" $0
680 | ;;
681 | 4)
682 | read -p " 请设置业务人员角色允许访问的内网网段或特定IP地址(多个网段或IP地址以逗号分割):" client_role_bussiness_allow_net
683 | sed -i -e "s/^bussiness_allowed_access_net=.*/bussiness_allowed_access_net=$client_role_developer_allow_net/g" $0
684 | ;;
685 | 5)
686 | read -p " 请设置机器人 角 色允许访问的内网网段或特定IP地址(多个网段或IP地址以逗号分割):" client_role_robots_allow_net
687 | sed -i -e "s/^robots_allowed_access_net=.*/robots_allowed_access_net=$client_role_developer_allow_net/g" $0
688 | ;;
689 | esac
690 | done
691 |
692 | echo
693 |
694 | read -p "10. 是否配置管理端口?[Yy/Nn]? " setup_management
695 | until [[ -z "$setup_management" || "$setup_management" =~ ^[yYnN]*$ ]]; do
696 | read -p " $setup_management为无效的选项,是否配置管理端口?[Yy/Nn] " setup_management
697 | done
698 | [[ -z "$setup_management" ]] && setup_management="y"
699 |
700 | echo
701 |
702 | case "$setup_management" in
703 | y | Y)
704 | read -p " 设置管理端口[默认27506]: " management_port
705 | until [[ -z "$management_port" || ${management_port} =~ ^[0-9]{0,5}$ && $management_port -le 65535 && $management_port -gt 1024 ]]; do
706 | read -p " $management_port为无效的端口,请重新设置1025 <= => 65535之内的端口: " management_port
707 | done
708 | [[ -z "$management_port" ]] && management_port=27506
709 |
710 | read -p $' 设置管理端口登录密码(默认生产15位随机0-9a-zA-Z字符串密码): ' management_psw
711 | until [[ -z "$management_psw" || ${management_psw} =~ ^[0-9a-zA-Z]{15}$ ]]; do
712 | read -s -p " 设置的密码过于简单,请重新设置更为复杂的密码: " management_psw
713 | done
714 | [[ -z "$management_psw" ]] && management_psw=$(echo $(date +%s)$RANDOM | md5sum | base64 | head -c 15)
715 | ;;
716 | n | N) ;;
717 |
718 | esac
719 |
720 | echo
721 |
722 | echo "11. 开始准备安装OpenVPN服务端"
723 | read -n1 -r -p " 按任意键继续"
724 | if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
725 | echo " 正在下载安装OpenVPN软件"
726 | apt-get update >/dev/null 2>&1
727 | apt-get install -y openvpn openssl ca-certificates $firewall >/dev/null 2>&1
728 | elif [[ "$os" = "centos" ]]; then
729 | echo " 正在下载安装OpenVPN软件"
730 | yum install -y epel-release >/dev/null 2>&1
731 | yum install -y openvpn openssl ca-certificates tar $firewall >/dev/null 2>&1
732 | else
733 | # Else, OS must be Fedora
734 | echo " 正在下载安装OpenVPN软件"
735 | dnf install -y openvpn openssl ca-certificates tar $firewall >/dev/null 2>&1
736 | fi
737 | # 下载安装证书工具easy-rsa
738 | mkdir -p $INSTALL_DIR/server/{easy-rsa,ccd,logs,ip-pools,pki} $INSTALL_DIR/client/profiles
739 | easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz'
740 | echo " 正在下载easy-rsa证书工具"
741 | wget --tries=5 --continue --timeout=10 --show-progress --progress=dot -q $easy_rsa_url -O - | tar -xzf - -C /etc/openvpn/server/easy-rsa --strip-components 1 --exclude doc
742 | if [[ $? == 0 && -f $INSTALL_DIR/server/easy-rsa/easyrsa ]]; then
743 | chown -R root:root $INSTALL_DIR/server
744 | # 创建CA和客户端证书
745 | cd $INSTALL_DIR/server/easy-rsa/
746 | echo
747 | echo " 正在创建CA和客户端证书"
748 | ./easyrsa init-pki >/dev/null 2>&1
749 | EASYRSA_CA_EXPIRE=36500 ./easyrsa --batch build-ca nopass >/dev/null 2>&1
750 | EASYRSA_CERT_EXPIRE=36500 ./easyrsa build-server-full server nopass >/dev/null 2>&1
751 | # EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass
752 | EASYRSA_CRL_DAYS=36500 ./easyrsa gen-crl >/dev/null 2>&1
753 | # Move the stuff we need
754 | cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem $INSTALL_DIR/server/pki
755 | # CRL is read with each client connection, while OpenVPN is dropped to nobody
756 | chown nobody:"$group_name" $INSTALL_DIR/server/pki/crl.pem
757 | # Without +x in the directory, OpenVPN can't run a stat() on the CRL file
758 | chmod o+x $INSTALL_DIR/server/
759 | # Generate key for tls-crypt
760 | openvpn --genkey --secret $INSTALL_DIR/server/pki/tc.key >/dev/null 2>&1
761 | # Create the DH parameters file using the predefined ffdhe2048 group
762 | echo '-----BEGIN DH PARAMETERS-----
763 | MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
764 | +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
765 | 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
766 | YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
767 | 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
768 | ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
769 | -----END DH PARAMETERS-----' >$INSTALL_DIR/server/pki/dh.pem
770 | else
771 | echo "easy-rsa证书工具下载失败,请检查网络状态"
772 | sed -i 's/^setup_subnet_roles_nu=.*/setup_subnet_roles_nu=/g' $0
773 | rm -rf $INSTALL_DIR
774 | exit 1
775 | fi
776 | # Install a firewall in the rare case where one is not already available
777 | if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then
778 | if [[ "$os" == "centos" || "$os" == "fedora" ]]; then
779 | firewall="firewalld"
780 | # We don't want to silently enable firewalld, so we give a subtle warning
781 | # If the user continues, firewalld will be installed and enabled during setup
782 | echo "安装防火墙软件firewalld"
783 | elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then
784 | # iptables is way less invasive than firewalld so no warning is given
785 | firewall="iptables"
786 | echo "安装防火墙软件iptables"
787 | fi
788 | fi
789 | echo " 正在检查防火墙软件,当前操作系统的防护墙为: $firewall"
790 |
791 | # If running inside a container, disable LimitNPROC to prevent conflicts
792 | if systemd-detect-virt -cq; then
793 | mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/nul
794 | echo "[Service]
795 | LimitNPROC=infinity" >/etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
796 | fi
797 | # If firewalld was just installed, enable it
798 | if [[ "$firewall" == "firewalld" ]]; then
799 | echo " 开启防火墙"
800 | systemctl enable --now firewalld.service >/dev/null 2>&1
801 | fi
802 |
803 | if [[ ! -z "$server_subnet_developer_ip_pool" ]]; then
804 | seq -f "${server_subnet_developer_ip_pool%.*}.%g" 2 254 >$INSTALL_DIR/server/ip-pools/developer-ip-pools
805 | fi
806 | if [[ ! -z "$server_subnet_tester_ip_pool" ]]; then
807 | seq -f "${server_subnet_tester_ip_pool%.*}.%g" 2 254 >$INSTALL_DIR/server/ip-pools/tester-ip-pools
808 | fi
809 | if [[ ! -z "$server_subnet_manager_ip_pool" ]]; then
810 | seq -f "${server_subnet_manager_ip_pool%.*}.%g" 2 254 >$INSTALL_DIR/server/ip-pools/manager-ip-pools
811 | fi
812 | if [[ ! -z "$server_subnet_bussiness_ip_pool" ]]; then
813 | seq -f "${server_subnet_bussiness_ip_pool%.*}.%g" 2 254 >$INSTALL_DIR/server/ip-pools/bussiness-ip-pools
814 | fi
815 | if [[ ! -z "$server_subnet_robots_ip_pool" ]]; then
816 | seq -f "${server_subnet_robots_ip_pool%.*}.%g" 2 254 >$INSTALL_DIR/server/ip-pools/robots-ip-pools
817 | fi
818 |
819 | # 生成OpenVPN服务端配置文件
820 | echo " 正在生成OpenVPN服务端配置文件"
821 | echo "local 0.0.0.0
822 | port $port
823 | proto $protocol
824 | dev tun
825 | ca pki/ca.crt
826 | cert pki/server.crt
827 | key pki/server.key
828 | dh pki/dh.pem
829 | auth SHA512
830 | tls-crypt pki/tc.key
831 | crl-verify pki/crl.pem
832 | topology subnet
833 | mute 30
834 | auth-user-pass-verify openvpn-utils.sh via-env
835 | username-as-common-name
836 | verb 3
837 | script-security 3
838 | client-config-dir ccd
839 | ifconfig-pool-persist ipp.txt
840 | log-append logs/openvpn-server.log
841 | server $server_ip_net 255.255.0.0" >$INSTALL_DIR/server/server.conf
842 | echo " 正在生成OpenVPN服务端脚本"
843 | echo "#!/bin/sh
844 | PASSFILE=\"$INSTALL_DIR/server/psw-file\"
845 | LOG_FILE=\"$INSTALL_DIR/server/logs/openvpn-all-\$(date \"+%Y-%m-%d\").log\"
846 | TIME_STAMP=\`date \"+%Y-%m-%d %T\"\`
847 | swap_seconds ()
848 | {
849 | SEC=\$1
850 | [ \"\$SEC\" -le 60 ] && echo \"\$SEC秒\"
851 | [ \"\$SEC\" -gt 60 ] && [ \"\$SEC\" -le 3600 ] && echo \"\$(( SEC / 60 ))分钟\$(( SEC % 60 ))秒\"
852 | [ \"\$SEC\" -gt 3600 ] && echo \"\$(( SEC / 3600 ))小时\$(( (SEC % 3600) / 60 ))分钟\$(( (SEC % 3600) % 60 ))秒\"
853 | }
854 |
855 | if [ \$script_type = 'user-pass-verify' ] ; then
856 | if [ ! -r \"\${PASSFILE}\" ]; then
857 | echo \"\${TIME_STAMP}: Could not open password file \"\${PASSFILE}\" for reading.\" >> \${LOG_FILE}
858 | exit 1
859 | fi
860 | CORRECT_PASSWORD=\`awk '!/^;/&&!/^#/&&\$1==\"'\${username}'\"{print \$2;exit}' \${PASSFILE}\`
861 | if [ \"\${CORRECT_PASSWORD}\" = \"\" ]; then
862 | echo \"\${TIME_STAMP}: User does not exist: username=\"\${username}\", password=\"\${password}\".\" >> \${LOG_FILE}
863 | exit 1
864 | fi
865 | if [ \"\${password}\" = \"\${CORRECT_PASSWORD}\" ]; then
866 | echo \"\${TIME_STAMP}: Successful authentication: username=\"\${username}\".\" >> \${LOG_FILE}
867 | exit 0
868 | fi
869 | echo \"\${TIME_STAMP}: Incorrect password: username=\"\${username}\", password=\"\${password}\".\" >> \${LOG_FILE}
870 | exit 1
871 | fi
872 |
873 | case \"\$IV_PLAT\" in
874 | os )
875 | device_type=ios
876 | ;;
877 | win )
878 | device_type=Windows
879 | ;;
880 | linux )
881 | device_type=Linux
882 | ;;
883 | solaris )
884 | device_type=Solaris
885 | ;;
886 | openbsd )
887 | device_type=OpenBSD
888 | ;;
889 | mac )
890 | device_type=Mac
891 | ;;
892 | netbsd )
893 | device_type=NetBSD
894 | ;;
895 | freebsd )
896 | device_type=FreeBSD
897 | ;;
898 | * )
899 | device_type=None
900 | ;;
901 | esac
902 |
903 | if [ \$script_type = 'client-connect' ] ; then
904 | echo \"\${TIME_STAMP}: \$common_name 连接了OpenVPN. 设备: \$device_type IP端口: \$trusted_ip:\$trusted_port 端对端IP: \$ifconfig_pool_remote_ip <===> \$ifconfig_local\" >> \${LOG_FILE}
905 | fi
906 | if [ \$script_type = 'client-disconnect' ]; then
907 | duration_time=\`swap_seconds \$time_duration\`
908 | echo \"\${TIME_STAMP}: \$common_name 断开了OpenVPN. 设备: \$device_type IP端口: \$trusted_ip:\$trusted_port 端对端IP: \$ifconfig_pool_remote_ip <===> \$ifconfig_local 持续时间: \$duration_time \" >> \${LOG_FILE}
909 | fi
910 | " >$INSTALL_DIR/server/openvpn-utils.sh
911 | chmod +x $INSTALL_DIR/server/openvpn-utils.sh
912 |
913 | echo "keepalive 10 120
914 | cipher AES-256-CBC
915 | user root
916 | group $group_name
917 | persist-key
918 | persist-tun
919 | status logs/openvpn-status.log
920 | client-connect openvpn-utils.sh
921 | client-disconnect openvpn-utils.sh" >>$INSTALL_DIR/server/server.conf
922 | if [[ "$protocol" = "udp" ]]; then
923 | echo "explicit-exit-notify" >>$INSTALL_DIR/server/server.conf
924 | fi
925 |
926 | # if [[ "$setup_client_conn_server_net" =~ ^[yY]$ ]]; then
927 | # echo "push \"route $server_ip_local_net $server_ip_local_netmask\"" >>$INSTALL_DIR/server/server.conf
928 | # fi
929 |
930 | if [[ "$setup_client_conn" =~ ^[yY]$ ]]; then
931 | echo "client-to-client" >>$INSTALL_DIR/server/server.conf
932 | fi
933 | if [[ "$setup_management" =~ ^[yY]$ && ${management_port} ]]; then
934 | echo $management_psw >$INSTALL_DIR/server/management-psw-file
935 | echo "management 127.0.0.1 $management_port management-psw-file" >>$INSTALL_DIR/server/server.conf
936 | fi
937 |
938 | # Enable net.ipv4.ip_forward for the system
939 | echo 'net.ipv4.ip_forward=1' >/etc/sysctl.d/30-openvpn-forward.conf
940 | # Enable without waiting for a reboot or service restart
941 | echo " 正在开起内核路由转发功能"
942 | echo 1 >/proc/sys/net/ipv4/ip_forward
943 | if [[ -n "$ip6" ]]; then
944 | # Enable net.ipv6.conf.all.forwarding for the system
945 | echo "net.ipv6.conf.all.forwarding=1" >/etc/sysctl.d/30-openvpn-forward.conf
946 | # Enable without waiting for a reboot or service restart
947 | echo 1 >/proc/sys/net/ipv6/conf/all/forwarding
948 | fi
949 | if systemctl is-active --quiet firewalld.service; then
950 | # Using both permanent and not permanent rules to avoid a firewalld
951 | # reload.
952 | # We don't use --add-service=openvpn because that would only work with
953 | # the default port and protocol.
954 | firewall-cmd --add-port="$port"/"$protocol"
955 | firewall-cmd --zone=trusted --add-source="$server_ip_net"/24
956 | firewall-cmd --permanent --add-port="$port"/"$protocol"
957 | firewall-cmd --permanent --zone=trusted --add-source="$server_ip_net"/24
958 | # Set NAT for the VPN subnet
959 | firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s "$server_ip_net"/24 ! -d "$server_ip_net"/24 -j SNAT --to "$ip"
960 | firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s "$server_ip_net"/24 ! -d "$server_ip_net"/24 -j SNAT --to "$ip"
961 | if [[ -n "$ip6" ]]; then
962 | firewall-cmd --zone=trusted --add-source=fddd:1194:1194:1194::/64
963 | firewall-cmd --permanent --zone=trusted --add-source=fddd:1194:1194:1194::/64
964 | firewall-cmd --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
965 | firewall-cmd --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
966 | fi
967 | else
968 | # Create a service to set up persistent iptables rules
969 | iptables_path=$(command -v iptables)
970 | ip6tables_path=$(command -v ip6tables)
971 | # nf_tables is not available as standard in OVZ kernels. So use iptables-legacy
972 | # if we are in OVZ, with a nf_tables backend and iptables-legacy is available.
973 | if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f "$(command -v iptables)" | grep -q "nft" && hash iptables-legacy 2>/dev/null; then
974 | iptables_path=$(command -v iptables-legacy)
975 | ip6tables_path=$(command -v ip6tables-legacy)
976 | fi
977 |
978 | echo " 正在生成OpenVPN的iptables规则"
979 | echo "[Unit]
980 | Before=network.target
981 |
982 | [Service]
983 | Type=oneshot
984 | ExecStart=$iptables_path -I INPUT -p $protocol --dport $port -j ACCEPT
985 | ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT
986 |
987 | ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
988 | ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
989 |
990 | RemainAfterExit=yes
991 | [Install]
992 | WantedBy=multi-user.target
993 | " >>/etc/systemd/system/openvpn-iptables.service
994 | systemctl enable --now openvpn-iptables.service >/dev/null 2>&1
995 |
996 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $server_subnet_developer_ip_pool ]]; then
997 | echo "[Unit]
998 | Before=network.target
999 |
1000 | [Service]
1001 | Type=oneshot
1002 | ExecStart=$iptables_path -I FORWARD -s $server_subnet_developer_ip_pool/24 -j ACCEPT
1003 | ExecStop=$iptables_path -D FORWARD -s $server_subnet_developer_ip_pool/24 -j ACCEPT
1004 | # ============================开发人员放行网段============================" >>/etc/systemd/system/openvpn-iptables-developer.service
1005 | if [[ ! -z $client_role_developer_allow_net ]]; then
1006 | for i in ${client_role_developer_allow_net//,/ }; do
1007 | echo -e "ExecStart=$iptables_path -t nat -I POSTROUTING -s $server_subnet_developer_ip_pool/24 -d $i -j SNAT --to $ip\nExecStop=$iptables_path -t nat -D POSTROUTING -s $server_subnet_developer_ip_pool/24 -d $i -j SNAT --to $ip\n" >>/etc/systemd/system/openvpn-iptables-developer.service
1008 | done
1009 | fi
1010 | echo -e "RemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target" >>/etc/systemd/system/openvpn-iptables-developer.service
1011 | systemctl enable --now openvpn-iptables-developer.service >/dev/null 2>&1
1012 | fi
1013 |
1014 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $server_subnet_tester_ip_pool ]]; then
1015 | echo "[Unit]
1016 | Before=network.target
1017 |
1018 | [Service]
1019 | Type=oneshot
1020 | ExecStart=$iptables_path -I FORWARD -s $server_subnet_tester_ip_pool/24 -j ACCEPT
1021 | ExecStop=$iptables_path -D FORWARD -s $server_subnet_tester_ip_pool/24 -j ACCEPT
1022 | # ============================测试人员放行网段============================" >>/etc/systemd/system/openvpn-iptables-tester.service
1023 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $client_role_tester_allow_net ]]; then
1024 | for i in ${client_role_tester_allow_net//,/ }; do
1025 | echo -e "ExecStart=$iptables_path -t nat -I POSTROUTING -s $server_subnet_tester_ip_pool/24 -d $i -j SNAT --to $ip\nExecStop=$iptables_path -t nat -D POSTROUTING -s $server_subnet_tester_ip_pool/24 -d $i -j SNAT --to $ip\n" >>/etc/systemd/system/openvpn-iptables-tester.service
1026 | done
1027 | fi
1028 | echo -e "RemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target" >>/etc/systemd/system/openvpn-iptables-tester.service
1029 | systemctl enable --now openvpn-iptables-tester.service >/dev/null 2>&1
1030 | fi
1031 |
1032 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $server_subnet_manager_ip_pool ]]; then
1033 | echo "[Unit]
1034 | Before=network.target
1035 |
1036 | [Service]
1037 | Type=oneshot
1038 | ExecStart=$iptables_path -I FORWARD -s $server_subnet_manager_ip_pool/24 -j ACCEPT
1039 | ExecStop=$iptables_path -D FORWARD -s $server_subnet_manager_ip_pool/24 -j ACCEPT
1040 | # ============================运维人员放行网段============================" >>/etc/systemd/system/openvpn-iptables-manager.service
1041 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $client_role_manager_allow_net ]]; then
1042 | for i in ${client_role_manager_allow_net//,/ }; do
1043 | echo -e "ExecStart=$iptables_path -t nat -I POSTROUTING -s $server_subnet_manager_ip_pool/24 -d $i -j SNAT --to $ip\nExecStop=$iptables_path -t nat -D POSTROUTING -s $server_subnet_manager_ip_pool/24 -d $i -j SNAT --to $ip\n" >>/etc/systemd/system/openvpn-iptables-manager.service
1044 | done
1045 | fi
1046 | echo -e "RemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target" >>/etc/systemd/system/openvpn-iptables-manager.service
1047 | systemctl enable --now openvpn-iptables-manager.service >/dev/null 2>&1
1048 | fi
1049 |
1050 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $server_subnet_bussiness_ip_pool ]]; then
1051 | echo "[Unit]
1052 | Before=network.target
1053 |
1054 | [Service]
1055 | Type=oneshot
1056 | ExecStart=$iptables_path -I FORWARD -s $server_subnet_bussiness_ip_pool/24 -j ACCEPT
1057 | ExecStop=$iptables_path -D FORWARD -s $server_subnet_bussiness_ip_pool/24 -j ACCEPT
1058 | # ============================业务人员放行网段============================" >>/etc/systemd/system/openvpn-iptables-bussiness.service
1059 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $client_role_bussiness_allow_net ]]; then
1060 | for i in ${client_role_bussiness_allow_net//,/ }; do
1061 | echo -e "ExecStart=$iptables_path -t nat -I POSTROUTING -s $server_subnet_bussiness_ip_pool/24 -d $i -j SNAT --to $ip\nExecStop=$iptables_path -t nat -D POSTROUTING -s $server_subnet_bussiness_ip_pool/24 -d $i -j SNAT --to $ip\n" >>/etc/systemd/system/openvpn-iptables-bussiness.service
1062 | done
1063 | fi
1064 | echo -e "RemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target" >>/etc/systemd/system/openvpn-iptables-bussiness.service
1065 | systemctl enable --now openvpn-iptables-bussiness.service >/dev/null 2>&1
1066 | fi
1067 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $server_subnet_robots_ip_pool ]]; then
1068 | echo "[Unit]
1069 | Before=network.target
1070 |
1071 | [Service]
1072 | Type=oneshot
1073 | ExecStart=$iptables_path -I FORWARD -s $server_subnet_robots_ip_pool/24 -j ACCEPT
1074 | ExecStop=$iptables_path -D FORWARD -s $server_subnet_robots_ip_pool/24 -j ACCEPT
1075 | # ============================机器人放行网段============================" >>/etc/systemd/system/openvpn-iptables-robots.service
1076 |
1077 | if [[ "$setup_client_conn_server_net" =~ ^[yY]$ && ! -z $client_role_robots_allow_net ]]; then
1078 | for i in ${client_role_robots_allow_net//,/ }; do
1079 | echo -e "ExecStart=$iptables_path -t nat -I POSTROUTING -s $server_subnet_robots_ip_pool/24 -d $i -j SNAT --to $ip\nExecStop=$iptables_path -t nat -D POSTROUTING -s $server_subnet_robots_ip_pool/24 -d $i -j SNAT --to $ip\n" >>/etc/systemd/system/openvpn-iptables-robots.service
1080 | done
1081 | fi
1082 | echo -e "RemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target" >>/etc/systemd/system/openvpn-iptables-robots.service
1083 | systemctl enable --now openvpn-iptables-robots.service >/dev/null 2>&1
1084 | fi
1085 | fi
1086 | # If SELinux is enabled and a custom port was selected, we need this
1087 | if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
1088 | # Install semanage if not already present
1089 | if ! hash semanage 2>/dev/null; then
1090 | if [[ "$os_version" -eq 7 ]]; then
1091 | # Centos 7
1092 | yum install -y policycoreutils-python >/dev/null 2>&1
1093 | else
1094 | # CentOS 8 or Fedora
1095 | dnf install -y policycoreutils-python-utils >/dev/null 2>&1
1096 | fi
1097 | fi
1098 | semanage port -a -t openvpn_port_t -p "$protocol" "$port"
1099 | fi
1100 | # If the server is behind NAT, use the correct IP address
1101 | [[ -n "$client_profile_nat_pub_ip_domain" ]] && ip="$client_profile_nat_pub_ip_domain"
1102 | # client-common.txt is created so we have a template to add further users later
1103 | echo " 正在生成通用客户端配置文件"
1104 | echo "client
1105 | dev tun
1106 | proto $protocol
1107 | remote $ip $port
1108 | resolv-retry infinite
1109 | nobind
1110 | persist-key
1111 | persist-tun
1112 | remote-cert-tls server
1113 | auth SHA512
1114 | cipher AES-256-CBC
1115 | verb 3
1116 | auth-user-pass" >$INSTALL_DIR/server/client-common.txt
1117 | # Enable and start the OpenVPN service
1118 | echo " 正在启动OpenVPN服务并设置开机自启"
1119 | systemctl enable --now openvpn-server@server.service >/dev/null 2>&1
1120 | cp $SHELL_FOLDER/$0 /usr/local/bin/ovpnx
1121 | echo "########################################################"
1122 | echo
1123 | echo "1. 管理端口密码已保存在$INSTALL_DIR/server/management-psw-file文件中,更多管理端口的使用方法详见:https://openvpn.net/community-resources/management-interface"
1124 | echo "2. OpenVPN服务安装完成!可重新运行此脚本执行添加用户等其他功能"
1125 | echo "3. 管理脚本已移动至/usr/local/bin/下"
1126 | echo
1127 | echo "########################################################"
1128 | else
1129 | clear
1130 | echo "OpenVPN服务已安装"
1131 | echo
1132 | echo "选择以下功能:"
1133 | echo " 0) 配置SMTP"
1134 | echo " 1) 添加用户"
1135 | echo " 2) 查看已有用户"
1136 | echo " 3) 删除用户"
1137 | echo " 4) 卸载OpenVPN"
1138 | echo " 5) 退出"
1139 | read -p "功能选项: " option
1140 | until [[ "$option" =~ ^[0-4]$ ]]; do
1141 | read -p "$option为无效的选项,请重新输入选项: " option
1142 | done
1143 | case "$option" in
1144 | 0)
1145 | check_smtp_server_profile
1146 | ;;
1147 | 1)
1148 | check_smtp_server_profile
1149 | read -p "新用户名(3~16位,包含以下字符a-zA-Z0-9_-): " client
1150 | until [[ -z ${client+x} || ! -e $INSTALL_DIR/server/easy-rsa/pki/issued/$client.crt && $client =~ ^[a-zA-Z0-9_\-]{3,16}$ ]]; do
1151 | read -p "$client已存在或不符合规则,请设置新的用户名: " client
1152 | done
1153 |
1154 | if [[ ! -z $setup_subnet_roles_nu ]]; then
1155 | echo "已配置的用户角色:"
1156 | display_nu=1
1157 | for i in ${setup_subnet_roles_nu//,/ }; do
1158 | case $i in
1159 | 1)
1160 | echo " ${display_nu}: 开发人员角色,允许访问的网段或IP:$developer_allowed_access_net"
1161 | display_nu=$((display_nu + 1))
1162 | ;;
1163 | 2)
1164 | echo " ${display_nu}: 测试人员角色,允许访问的网段或IP:$tester_allowed_access_net"
1165 | display_nu=$((display_nu + 1))
1166 | ;;
1167 | 3)
1168 | echo " ${display_nu}: 运维人员角色,允许访问的网段或IP:$manager_allowed_access_net"
1169 | display_nu=$((display_nu + 1))
1170 | ;;
1171 | 4)
1172 | echo " ${display_nu}: 业务人员角色,允许访问的网段或IP:$bussiness_allowed_access_net"
1173 | display_nu=$((display_nu + 1))
1174 | ;;
1175 | 5)
1176 | echo " ${display_nu}: 机器人 角 色,允许访问的网段或IP:$robots_allowed_access_net"
1177 | display_nu=$((display_nu + 1))
1178 | ;;
1179 | esac
1180 | done
1181 | fi
1182 |
1183 | read -p "请设置新用户角色(单选): " new_client_role
1184 | until [[ -z "$new_client_role" || "$new_client_role" =~ ^[1|2|3|4|5]$ ]]; do
1185 | echo "$new_client_role: 无效的选项."
1186 | read -p "请重新设置新用户角色" new_client_role
1187 | done
1188 |
1189 | read -p "设置用户邮箱: " user_email_address
1190 | until [[ -z ${user_email_address+x} || ${user_email_address} =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ ]]; do
1191 | read -p "${user_email_address}不是一个正确的邮箱格式,请重新设置: " user_email_address
1192 | done
1193 | for i in ${setup_subnet_roles//,/ }; do
1194 | case $new_client_role in
1195 | 1) ;;
1196 |
1197 | 2) ;;
1198 |
1199 | 3) ;;
1200 |
1201 | esac
1202 | done
1203 | tmp_var=${new_client_role}_allowed_access_net
1204 |
1205 | new_client $client $new_client_role $user_email_address ${tmp_var}
1206 | exit
1207 | ;;
1208 | 2)
1209 | tail -n +2 $INSTALL_DIR/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
1210 | ;;
1211 | 3)
1212 | number_of_clients=$(tail -n +2 $INSTALL_DIR/server/easy-rsa/pki/index.txt | grep -c "^V")
1213 | if [[ "$number_of_clients" = 0 ]]; then
1214 | echo
1215 | echo "暂时没有已存在的客户端用户"
1216 | exit
1217 | fi
1218 | echo
1219 | echo "请选择要删除的客户端用户:"
1220 | tail -n +2 $INSTALL_DIR/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
1221 | read -p "用户编号: " client_number
1222 | until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do
1223 | echo "$client_number: 无效的选项."
1224 | read -p "用户编号: " client_number
1225 | done
1226 | release_client_username=$(tail -n +2 $INSTALL_DIR/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p)
1227 |
1228 | read -p "请确认是否要删除用户$release_client_username? [Y/n]: " revoke_client_option
1229 | until [[ "$revoke_client_option" =~ ^[Y]$ ]]; do
1230 | echo "$revoke_client_option: 无效的选项."
1231 | read -p "请确认是否要删除客户端用户$release_client_username [Y/n]: " revoke_client_option
1232 | done
1233 |
1234 | if [[ "$revoke_client_option" =~ ^[Y]$ && -f $INSTALL_DIR/server/ccd/$release_client_username ]]; then
1235 | cd $INSTALL_DIR/server/easy-rsa
1236 | ./easyrsa --batch revoke "$release_client_username" >/dev/null 2>&1
1237 | # EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl >/dev/null 2>&1
1238 | # rm -f $INSTALL_DIR/server/crl.pem
1239 | # cp $INSTALL_DIR/server/easy-rsa/pki/crl.pem $INSTALL_DIR/server/crl.pem
1240 | # CRL is read with each client connection, when OpenVPN is dropped to nobody
1241 | # chown nobody:"$group_name" $INSTALL_DIR/server/crl.pem
1242 | client_ip_ready_release=$(grep "ifconfig-push" $INSTALL_DIR/server/ccd/$release_client_username | awk '{print $2}')
1243 | release_client_role=$(grep -w "$release_client_username" /etc/openvpn/server/clients-info | awk -F" " '{print $1}')
1244 | sed -i "/$release_client_username/d" $INSTALL_DIR/server/clients-info
1245 | sed -i "/\<$release_client_username\>/d" $INSTALL_DIR/server/psw-file
1246 | echo "$client_ip_ready_release" >>$INSTALL_DIR/server/ip-pools/$release_client_role-ip-pools
1247 | rm -f $INSTALL_DIR/server/ccd/$release_client_username $INSTALL_DIR/client/profiles/$release_client_username.ovpn
1248 | echo "用户$release_client_username已删除!"
1249 | else
1250 | echo "客户端用户$release_client_username删除中断!"
1251 | fi
1252 | exit
1253 | ;;
1254 | 4)
1255 | echo
1256 | read -p "请确认是否卸载OpenVPN? [Y/N]: " remove
1257 | until [[ "$remove" =~ ^[YN]*$ ]]; do
1258 | echo "$remove: 无效的选项."
1259 | read -p "请确认是否卸载OpenVPN? [Y/N]: " remove
1260 | done
1261 | if [[ "$remove" =~ ^[Y]$ ]]; then
1262 | port=$(grep '^port ' $INSTALL_DIR/server/server.conf | cut -d " " -f 2)
1263 | protocol=$(grep '^proto ' $INSTALL_DIR/server/server.conf | cut -d " " -f 2)
1264 | if systemctl is-active --quiet firewalld.service; then
1265 | ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s $server_ip_net/24 '"'"'!'"'"' -d $server_ip_net/24' | grep -oE '[^ ]+$')
1266 | # Using both permanent and not permanent rules to avoid a firewalld reload.
1267 | firewall-cmd --remove-port="$port"/"$protocol"
1268 | firewall-cmd --zone=trusted --remove-source="$server_ip_net"/24
1269 | firewall-cmd --permanent --remove-port="$port"/"$protocol"
1270 | firewall-cmd --permanent --zone=trusted --remove-source="$server_ip_net"/24
1271 | firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s "$server_ip_net"/24 ! -d "$server_ip_net"/24 -j SNAT --to "$ip"
1272 | firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s "$server_ip_net"/24 ! -d "$server_ip_net"/24 -j SNAT --to "$ip"
1273 | # if grep -qs "server-ipv6" $INSTALL_DIR/server/server.conf; then
1274 | # ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$')
1275 | # firewall-cmd --zone=trusted --remove-source=fddd:1194:1194:1194::/64
1276 | # firewall-cmd --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64
1277 | # firewall-cmd --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
1278 | # firewall-cmd --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
1279 | # fi
1280 | else
1281 |
1282 | systemctl disable --now openvpn-iptables.service >/dev/null 2>&1
1283 |
1284 | fi
1285 | if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
1286 | semanage port -d -t openvpn_port_t -p "$protocol" "$port"
1287 | fi
1288 |
1289 | if [[ ! -z $setup_subnet_roles_nu ]]; then
1290 | for i in ${setup_subnet_roles_nu//,/ }; do
1291 | case $i in
1292 | 1)
1293 | systemctl disable --now openvpn-iptables-developer.service >/dev/null 2>&1
1294 | systemctl stop --now openvpn-iptables-developer.service >/dev/null 2>&1
1295 | ;;
1296 | 2)
1297 | systemctl disable --now openvpn-iptables-tester.service >/dev/null 2>&1
1298 | systemctl stop --now openvpn-iptables-tester.service >/dev/null 2>&1
1299 | ;;
1300 | 3)
1301 | systemctl disable --now openvpn-iptables-manager.service >/dev/null 2>&1
1302 | systemctl stop --now openvpn-iptables-manager.service >/dev/null 2>&1
1303 | ;;
1304 | 4)
1305 | systemctl disable --now openvpn-iptables-bussiness.service >/dev/null 2>&1
1306 | systemctl stop --now openvpn-iptables-bussiness.service >/dev/null 2>&1
1307 | ;;
1308 | 5)
1309 | systemctl disable --now openvpn-iptables-robots.service >/dev/null 2>&1
1310 | systemctl stop --now openvpn-iptables-robots.service >/dev/null 2>&1
1311 | ;;
1312 | esac
1313 | done
1314 | fi
1315 |
1316 | systemctl disable --now openvpn-server@server.service >/dev/null 2>&1
1317 | sed -i -e 's/^setup_subnet_roles_nu=.*/setup_subnet_roles_nu=/g' \
1318 | -e 's/^developer_allowed_access_net=.*/developer_allowed_access_net=/g' \
1319 | -e 's/^tester_allowed_access_net=.*/tester_allowed_access_net=/g' \
1320 | -e 's/^manager_allowed_access_net=.*/manager_allowed_access_net=/g' \
1321 | -e 's/^bussiness_allowed_access_net=.*/bussiness_allowed_access_net=/g' \
1322 | -e 's/^robots_allowed_access_net=.*/robots_allowed_access_net=/g' $0
1323 | cp /etc/systemd/system/openvpn-iptables*.service /etc/openvpn
1324 | mv /usr/local/bin/ovpnx /etc/openvpn
1325 | backupdate=$(date "+%Y%m%d%M")
1326 | tar -czf /tmp/openvpn-$backupdate.tar.gz --exclude=logs -C /etc openvpn
1327 | rm -rf $INSTALL_DIR /etc/systemd/system/openvpn-iptables*.service /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf /etc/sysctl.d/30-openvpn-forward.conf
1328 | if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
1329 | apt-get remove --purge -y openvpn >/dev/null 2>&1
1330 | else
1331 | # Else, OS must be CentOS or Fedora
1332 | yum remove -y openvpn >/dev/null 2>&1
1333 | fi
1334 | echo
1335 | echo "######################################################################"
1336 | echo
1337 | echo "OpenVPN已卸载!相关文件已备份在/tmp/openvpn-$backupdate.tar.gz,请及时下载到其他存储位置!"
1338 | echo
1339 | echo "######################################################################"
1340 | else
1341 | echo
1342 | echo "OpenVPN卸载中断!"
1343 | fi
1344 | exit
1345 | ;;
1346 | 5)
1347 | exit
1348 | ;;
1349 | esac
1350 | fi
1351 |
--------------------------------------------------------------------------------