├── 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 | 291 | 294 | 297 | 298 |
用户名密码配置文件
289 | $2 290 | 292 | $3 293 | 295 | 见附件 296 |
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 | --------------------------------------------------------------------------------