#!/bin/sh ######### 函数区.开始 ######### # 校验 ROOT 用户 function validRoot () { if [ "$EUID" -ne 0 ]; then return 1 fi return 0 } # 校验 TUN function validTun () { if [ -e /dev/net/tun ]; then return 0 fi return 1 } # 校验系统 function validOS() { if [ ! -e /etc/redhat-release ]; then return 1 fi for ((i=8; i<99; i++)); do if [ ! "`grep \" $i.\" /etc/redhat-release`" == "" ]; then return 0 fi done return 1 } # 校验必备条件 function validAll() { if ! validRoot; then echo "请使用 root 用户安装" return 1 fi if ! validTun; then echo "系统不支持 TUN 设备" return 1 fi if ! validOS; then echo "不支持的系统;请使用 CentOS8 或更高的系统安装" return 1 fi } # 开始安装 function startInstall() { echo ; echo "正在安装 OpenVPN 服务器,请稍候 ..." echo ; # PORT=`expr $RANDOM % 2000 + 30000` PORT=1194 PROTOCOL="tcp" CIPHER="AES-256-GCM" #"AES-128-GCM" # CERT_CURVE="prime256v1" CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" #"TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" # DH_CURVE="prime256v1" HMAC_ALG="SHA384" #"SHA256" # EASY_RSA_VERSION="3.0.6" # NIC=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1) echo -n "▋▋"; yum install -qy epel-release elrepo-release > /dev/null 2>&1 echo -n "▋▋"; # yum update -qy > /dev/null 2>&1 echo -n "▋▋"; yum install -qy openvpn openssl wget ca-certificates curl tar langpacks-zh_CN tuned net-tools bind-utils > /dev/null 2>&1 # IP=$(ip addr | grep 'inet' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1) IP=`dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | tr -d '"*[:space:]*'` echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf ; echo 'LC_ALL="zh_CN.UTF-8"' >> /etc/locale.conf ; source /etc/locale.conf > /dev/null 2>&1 ; if grep -qs "^nogroup:" /etc/group; then NOGROUP=nogroup else NOGROUP=nobody fi echo -n "▋▋"; wget -q -c -N -T 60 --retry-connrefused -t 10 -O $HOME/EasyRSA-unix-v${EASY_RSA_VERSION}.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v${EASY_RSA_VERSION}/EasyRSA-unix-v${EASY_RSA_VERSION}.tgz > /dev/null 2>&1 echo -n "▋▋"; rm -rf $HOME/EasyRSA-v${EASY_RSA_VERSION} > /dev/null 2>&1 tar xzf $HOME/EasyRSA-unix-v${EASY_RSA_VERSION}.tgz -C $HOME/ > /dev/null 2>&1 || ( echo "下载 EasyRSA-unix-v${EASY_RSA_VERSION}.tgz 文件失败" ; return 1 ) echo -n "▋▋"; rm -rf /etc/openvpn/easy-rsa > /dev/null 2>&1 mkdir -p /etc/openvpn > /dev/null 2>&1 mv $HOME/EasyRSA-v${EASY_RSA_VERSION} /etc/openvpn/easy-rsa > /dev/null 2>&1 chown -R root:root /etc/openvpn/easy-rsa/ > /dev/null 2>&1 # rm -f $HOME/EasyRSA-unix-v${EASY_RSA_VERSION}.tgz > /dev/null 2>&1 cd /etc/openvpn/easy-rsa/ > /dev/null 2>&1 echo "set_var EASYRSA_ALGO ec" > vars echo "set_var EASYRSA_CURVE $CERT_CURVE" >> vars SERVER_CN="cn_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)" SERVER_NAME="server_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)" echo "set_var EASYRSA_REQ_CN $SERVER_CN" >> vars echo -n "▋▋"; ./easyrsa init-pki > /dev/null 2>&1 || return 1 echo -n "▋▋"; sed -i 's/^RANDFILE/#RANDFILE/g' pki/openssl-easyrsa.cnf echo -n "▋▋"; ./easyrsa --batch build-ca nopass > /dev/null 2>&1 || return 1 echo -n "▋▋"; ./easyrsa build-server-full "$SERVER_NAME" nopass > /dev/null 2>&1 || return 1 EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl > /dev/null 2>&1 || return 1 echo -n "▋▋"; openvpn --genkey --secret /etc/openvpn/tls-crypt.key > /dev/null 2>&1 || return 1 echo -n "▋▋"; cp pki/ca.crt pki/private/ca.key "pki/issued/$SERVER_NAME.crt" "pki/private/$SERVER_NAME.key" /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn > /dev/null 2>&1 chmod 644 /etc/openvpn/crl.pem > /dev/null 2>&1 echo "port $PORT" > /etc/openvpn/server.conf echo "proto $PROTOCOL" >> /etc/openvpn/server.conf echo "dev tun tun-mtu 65535 user nobody group $NOGROUP persist-key persist-tun keepalive 10 120 topology subnet server 10.10.10.0 255.255.255.0 ifconfig-pool-persist ipp.txt" >> /etc/openvpn/server.conf sed -i 's/^[ \t]*//g' /etc/openvpn/server.conf echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server.conf echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server.conf echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf echo "dh none" >> /etc/openvpn/server.conf echo "ecdh-curve $DH_CURVE" >> /etc/openvpn/server.conf echo "tls-crypt tls-crypt.key 0" >> /etc/openvpn/server.conf echo "crl-verify crl.pem ca ca.crt cert $SERVER_NAME.crt key $SERVER_NAME.key auth $HMAC_ALG cipher $CIPHER ncp-ciphers $CIPHER tls-server tls-version-min 1.2 tls-cipher $CC_CIPHER status /var/log/openvpn/status.log verb 3" >> /etc/openvpn/server.conf sed -i 's/^[ \t]*//g' /etc/openvpn/server.conf mkdir -p /var/log/openvpn > /dev/null 2>&1 echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/20-openvpn.conf echo 'net.ipv4.tcp_congestion_control=bbr' >> /etc/sysctl.d/20-openvpn.conf ; echo 'net.core.default_qdisc=fq' >> /etc/sysctl.d/20-openvpn.conf ; systemctl enable tuned > /dev/null 2>&1 ; systemctl start tuned > /dev/null 2>&1 ; tuned-adm profile network-latency > /dev/null 2>&1 ; echo -n "▋▋"; sysctl --system > /dev/null 2>&1 echo -n "▋▋"; setenforce 0 > /dev/null 2>&1 sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config cp /usr/lib/systemd/system/openvpn-server@.service /etc/systemd/system/openvpn-server@.service > /dev/null 2>&1 sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn-server@.service sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn-server@.service echo -n "▋▋"; systemctl daemon-reload > /dev/null 2>&1 systemctl restart openvpn-server@server > /dev/null 2>&1 systemctl enable openvpn-server@server > /dev/null 2>&1 # firewall-cmd --permanent --add-port=$PORT/$PROTOCOL > /dev/null 2>&1 if [ "`firewall-cmd --permanent --query-forward-port=port=31001-32000:proto=tcp:toport=1194`" == "no" ]; then firewall-cmd --permanent --add-forward-port=port=31001-32000:proto=tcp:toport=1194 > /dev/null 2>&1 ; fi ; if [ "`firewall-cmd --permanent --query-masquerade`" == "no" ]; then firewall-cmd --permanent --add-masquerade > /dev/null 2>&1 ; fi ; firewall-cmd --reload > /dev/null 2>&1 echo -n "▋▋"; echo "" > /etc/openvpn/client-template.txt echo "" >> /etc/openvpn/client-template.txt if [[ "$PROTOCOL" = 'udp' ]]; then echo "proto udp" >> /etc/openvpn/client-template.txt elif [[ "$PROTOCOL" = 'tcp' ]]; then echo "proto tcp-client" >> /etc/openvpn/client-template.txt fi echo "remote-random tun-mtu 65535 dev tun resolv-retry infinite nobind persist-key persist-tun remote-cert-tls server verify-x509-name $SERVER_NAME name auth $HMAC_ALG auth-nocache cipher $CIPHER tls-client tls-version-min 1.2 tls-cipher $CC_CIPHER setenv opt block-outside-dns verb 3" >> /etc/openvpn/client-template.txt sed -i 's/^[ \t]*//g' /etc/openvpn/client-template.txt echo -n "▋▋"; echo ; echo ; # 批量创建 9 个用户 for ((i=1;i<10;i++)); do CLIENT="client$i" addClient done echo ; echo "恭喜你!已成功安装 OpenVPN" echo ; echo "查看配置文件,复制内容并保存为本地同名文件" echo ; echo "使用 OpenVPN Connect 等客户端导入文件,即可连接" echo ; echo ; return 0 } # 新建用户 function addClient () { if [ ! -e /etc/openvpn/easy-rsa ]; then echo "还没有安装 EasyRSA,不能新建用户" return 1 fi cd /etc/openvpn/easy-rsa > /dev/null 2>&1 ./easyrsa build-client-full "$CLIENT" nopass > /dev/null 2>&1 cp /etc/openvpn/client-template.txt "$HOME/$CLIENT.ovpn" > /dev/null 2>&1 || return 1 for ((p=0;p<20;p++)); do PORTx=`expr $RANDOM % 1000 + 31001` echo "remote $IP $PORTx" >> "$HOME/$CLIENT.ovpn" done { echo "" cat "/etc/openvpn/easy-rsa/pki/ca.crt" echo "" echo "" awk '/BEGIN/,/END/' "/etc/openvpn/easy-rsa/pki/issued/$CLIENT.crt" echo "" echo "" cat "/etc/openvpn/easy-rsa/pki/private/$CLIENT.key" echo "" echo "" cat /etc/openvpn/tls-crypt.key echo "" echo "" echo "" } >> "$HOME/$CLIENT.ovpn" echo "成功创建 $CLIENT 用户,查看配置文件 cat $CLIENT.ovpn" return 0 } # 删除用户 function delClient () { if [ ! -e /etc/openvpn/easy-rsa ]; then echo "还没有安装 EasyRSA,不能删除用户" return 0 fi CLIENT_COUNT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V") if [[ "$CLIENT_COUNT" = '0' ]]; then echo "还没有任何用户" return 0 fi echo "请选择需要删除的用户" echo ; tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') ' || return 1 echo ; if [[ "$CLIENT_COUNT" = '1' ]]; then read -rp "请输入一个序号 [1]: " CLIENT_NO else read -rp "请输入一个序号 [1-$CLIENT_COUNT]: " CLIENT_NO fi if ! [[ "$CLIENT_NO" =~ ^[0-9]+$ ]]; then echo ; echo "已取消删除用户操作" return 0 fi if [ $CLIENT_NO -lt 1 ] || [ $CLIENT_NO -gt $CLIENT_COUNT ]; then echo ; echo "无效的序号" return 0 fi CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENT_NO"p) > /dev/null 2>&1 || return 1 cd /etc/openvpn/easy-rsa/ ./easyrsa --batch revoke "$CLIENT" > /dev/null 2>&1 || return 1 EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl > /dev/null 2>&1 || return 1 rm -f "pki/reqs/$CLIENT.req" > /dev/null 2>&1 || return 1 rm -f "pki/private/$CLIENT.key" > /dev/null 2>&1 || return 1 rm -f "pki/issued/$CLIENT.crt" > /dev/null 2>&1 || return 1 rm -f /etc/openvpn/crl.pem > /dev/null 2>&1 || return 1 cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem > /dev/null 2>&1 || return 1 chmod 644 /etc/openvpn/crl.pem > /dev/null 2>&1 || return 1 rm -f "$HOME/$CLIENT.ovpn" > /dev/null 2>&1 || return 1 sed -i "s|^$CLIENT,.*||" /etc/openvpn/ipp.txt > /dev/null 2>&1 || return 1 echo ; echo "用户 $CLIENT 已经被删除" } # 删除 OpenVPN function delVPN () { echo ; read -rp "确定要删除 OpenVPN? [y/n]: " REMOVE if [[ "$REMOVE" = 'y' ]]; then echo ; echo "正在删除 OpenVPN,请稍候 ..." PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2) systemctl disable openvpn-server@server > /dev/null 2>&1 systemctl stop openvpn-server@server > /dev/null 2>&1 rm /etc/systemd/system/openvpn-server@.service > /dev/null 2>&1 systemctl daemon-reload > /dev/null 2>&1 yum remove -qy openvpn > /dev/null 2>&1 # firewall-cmd --permanent --remove-port=$PORT/$PROTOCOL > /dev/null 2>&1 # firewall-cmd --permanent --remove-masquerade > /dev/null 2>&1 if [ "`firewall-cmd --permanent --query-forward-port=port=31001-32000:proto=tcp:toport=1194`" == "yes" ]; then firewall-cmd --permanent --remove-forward-port=port=31001-32000:proto=tcp:toport=1194 > /dev/null 2>&1 ; fi ; firewall-cmd --reload > /dev/null 2>&1 find $HOME/ -maxdepth 1 -name "*.ovpn" -delete > /dev/null 2>&1 rm -rf /etc/openvpn > /dev/null 2>&1 rm -rf /usr/share/doc/openvpn* > /dev/null 2>&1 rm -f /etc/sysctl.d/20-openvpn.conf > /dev/null 2>&1 rm -rf /var/log/openvpn > /dev/null 2>&1 echo ; echo "已成功删除 OpenVPN" else echo ; echo "已取消删除 OpenVPN" fi echo ; return 0 } # 操作菜单 function startMenu () { clear echo ; echo "系统已经有 OpenVPN,你可以:" echo ; echo " 1) 新建十个用户" echo " 2) 删除一个用户" echo " 3) 删除 OpenVPN" echo " 4) 退出" echo ; until [[ "$MENU_NO" =~ ^[1-4]$ ]]; do read -rp "请输入一个序号 [1-4]: " MENU_NO done case $MENU_NO in 1) echo ; read -rp "确定要新建十个用户? [y/n]: " -e OK if [[ "$OK" = 'y' ]]; then echo ; # IP=$(ip addr | grep 'inet' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1) ; IP=`dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | tr -d '"*[:space:]*'` for ((i=1,x=0;i<1000;i++)); do CLIENT=client$i if [ ! -f $HOME/$CLIENT.ovpn ]; then addClient let x=x+1 if [ "$x" == "10" ]; then break; fi; fi done ; echo ; echo "查看配置文件,复制内容并保存为本地同名文件" echo ; echo "使用 OpenVPN Connect 等客户端导入文件,即可连接" echo ; echo ; fi echo ; ;; 2) echo ; delClient echo ; ;; 3) delVPN ;; 4) exit 0 ;; esac } ######### 函数区.结束 ######### # 检查必备条件 validAll if [[ -e /etc/openvpn/server.conf ]]; then startMenu else startInstall fi