介绍

OpenVPN 虽然安全方便,但也存在一定的安全隐患,比如当我们的用户配置文件被盗走后,拿着这个文件就可以直接连接进我们的 VPN ,对此我们可以通过添加账号密码认证,来防范这种情况。


1. 创建认证脚本

$ vim /etc/openvpn/checkpsw.sh
#!/bin/sh
WORK_DIR=/data/openvpn


PASSFILE="${WORK_DIR}/user_passwd.txt"
LOG_FILE="${WORK_DIR}/logs/openvpn-login.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`

if [ ! -r "${PASSFILE}" ]; then
  echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}
  exit 1
fi

CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`

if [ "${CORRECT_PASSWORD}" = "" ]; then
  echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
  exit 1
fi

if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
  echo "${TIME_STAMP}: User $common_name Successful authentication." >>${LOG_FILE}
  exit 0
fi

echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
  • 授权认证脚本及创建日志目录
$ chmod 755 /etc/openvpn/checkpsw.sh
$ mkdir /data/openvpn/logs && chmod 777 -R /data/openvpn/logs

2. 修改 OpenVPN 配置文件

$ vim /etc/openvpn/server/server.conf
local 192.168.253.146
port 21194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-crypt tc.key
topology subnet
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 223.5.5.5"
push "dhcp-option DNS 114.114.114.114"
push "block-outside-dns"
keepalive 10 120
cipher AES-256-CBC
user nobody
group nobody
persist-key
persist-tun
verb 3
crl-verify crl.pem
explicit-exit-notify

# 开启密码验证脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
# 使用客户提供的UserName作为Common Name
username-as-common-name
script-security 3

3. 重启 OpenVPN 服务

$ systemctl restart openvpn-server@server

4. 创建 OpenVPN 用户管理脚本

$ cd /data/openvpn
$ vim edit_user.sh
#!/bin/bash
### OpenVPN 用户管理脚本 v1.2 ###
# 作者:Hzbb                    #
# 时间:2023-08-16              #
#################################

mkdir ${WORK_DIR}/client -p
WORK_DIR="$(cd `dirname $0`;pwd)"
new_client () {
	{
	cat /etc/openvpn/server/client-common.txt
	echo "reneg-sec 0"
	echo "auth-user-pass"
	echo "<ca>"
	cat /etc/openvpn/server/easy-rsa/pki/ca.crt
	echo "</ca>"
	echo "<cert>"
	sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt
	echo "</cert>"
	echo "<key>"
	cat /etc/openvpn/server/easy-rsa/pki/private/"$client".key
	echo "</key>"
	echo "<tls-crypt>"
	sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/tc.key
	echo "</tls-crypt>"
	} > ${WORK_DIR}/client/"$client".ovpn
}

if [[ ! -e /etc/openvpn/server/server.conf ]]; then
	echo "OpenVPN未安装,请先安装."
else
	clear
	echo "##### OpenVPN 用户管理 #####"
	echo
	echo "请输入以下选项编号:"
	echo "   1) 创建用户"
	echo "   2) 删除用户"
	echo "   3) 退出"
	read -p "选项: " option
	until [[ "$option" =~ ^[1-3]$ ]]; do
		echo "$option: 无效的选择。"
		read -p "选项: " option
	done
	case "$option" in
		1)
			echo
			echo "请输入新用户名(字母大小写、数字、符号-_):"
			read -p "用户名: " unsanitized_client
			client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
			while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do
				echo "$client: 用户名无效."
				read -p "用户名: " unsanitized_client
				client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
			done
			cd /etc/openvpn/server/easy-rsa/
			./easyrsa --batch --days=3650 build-client-full "$client" nopass
			new_client
			echo
			Passwd=`openssl rand -base64 8`
			echo "$client $Passwd" >> $WORK_DIR/user_passwd.txt
			echo "$client 用户创建成功"
			echo
			echo "用户名:$client 密码:$Passwd"
			echo
			echo "配置文件位于: $WORK_DIR"/client/"$client.ovpn"
			echo
			exit
		;;
		2)
			number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V")
			if [[ "$number_of_clients" = 0 ]]; then
				echo
				echo "用户为空!"
				exit
			fi
			echo
			echo "选择要删除的用户:"
			tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
			read -p "选项('q'退出): " client_number
		
			if [[ "$client_number" = 'q' ]]; then
				exit
			fi

			until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do
				echo "$client_number: 无效的选择。"
				read -p "选项('q'退出): " client_number
				if [[ "$client_number" = 'q' ]]; then
					exit
				fi	
			done
			client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p)
			echo
			read -p "是否删除 $client 用户? [y/N]: " revoke
			until [[ "$revoke" =~ ^[yYnN]*$ ]]; do
				echo "$revoke: 无效的选择。"
				read -p "是否删除 $client 用户? [y/N]: " revoke
			done
			if [[ "$revoke" =~ ^[yY]$ ]]; then
				cd /etc/openvpn/server/easy-rsa/
				./easyrsa --batch revoke "$client"
				./easyrsa --batch --days=3650 gen-crl
				rm -f /etc/openvpn/server/crl.pem
				cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem
				chown nobody:"$group_name" /etc/openvpn/server/crl.pem
				sed -i "/^$client\s/d" $WORK_DIR/user_passwd.txt
				rm -f $WORK_DIR/client/$client.ovpn 
				echo
				echo "$client 用户已删除!"
				echo
			else
				echo
				echo "$client 用户取消删除!"
				echo
			fi
			exit
		;;
		3)
			exit
		;;
	esac
fi


5. 添加执行权限

$ chmod 755 edit_user.sh

6. 创建一个用户

选项: 1 为创建用户
输入用户名 hzbb
创建用户后生成的配置文件位于 /data/openvpn/client 目录下,同时会在控制台输出用户密码,并将用户名和密码写入/data/openvpnuser_passwd.txt 文件

1718446778968.png


7. 删除一个用户

./edit_user.sh

选项: 2 为删除用户
选择要删除的用户:1
是否删除 hzbb 用户? [y/N]: y
删除用户后会自动清理 /data/openvpn/client 目录下对应用户的配置文件,并清理/data/openvpnuser_passwd.txt 文件中对应的用户信息
1718448603759.png

文章作者: hzbb
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 运维小记
Linux OpenVPN
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝