OpenVPN通过MySQL进行用户验证有很多种方案,比较常见的是自编写脚本、PAM和FreeRadius等。各有各的缺点,如PAM只能验证而不能监控流量;自写脚本太麻烦,效率不够高;FreeRaduis配置麻烦,消耗资源有点大,等等。
有个“openvpn-mysql-auth”插件可以单独完成用户验证,并且可以自定义SQL语句,且各种具备事件前后执行的功能,相当强大好用。
假设已经根据《Linux下OpenVPN服务安装记》一文编译安装好了OpenVPN服务端。
首先,从https://github.com/chantra/openvpn-mysql-auth获得源代码,进入源代码目录。运行
./autogen.sh
./configure
make
如果出现“undefined reference to 'mysql_init'”或者相关的mysql函数未定义的错误,则运行
ln -s /usr/lib/mysql/libmysqlclient.so /usr/lib/libmysqlclient.so
然后再make一次。
接着,执行命令将编译好的库放到OpenVPN目录:
cp -a src/.libs/libopenvpn-mysql-auth.so* /etc/openvpn/mysql-auth/
进入OpenVPN的目录,生成tls-auth key:
cd /usr/local/openvpn/
sbin/openvpn --genkey --secret ta.key
mv ta.key etc/
在etc/server.conf对应位置加上:
tls-auth /usr/local/openvpn/etc/ta.key 0
在etc/server.conf最后加上
plugin /usr/local/openvpn/plugin/libopenvpn-mysql-auth.so -c /usr/local/openvpn/etc/plugin/mysql-auth.conf
其中的mysql-auth.conf根据自己需要和实际的账户数据库进行填写,具体可以参考它的README。比如我的实现登录验证和登录日志功能,非常简单:
hostname blog.creke.net
port 3306
login creke
password creke
db creke
s_path noneauth_user_pass_verify_query SELECT uid FROM creke_users WHERE usr='{{escaped_username}}' AND pwd=MD5('{{escaped_password}}') AND
client_connect_query INSERT INTO creke_log (usr, ip, time) VALUES ('{{escaped_username}}', '{{trusted_ip}}', {{time_unix}})
PS:如果希望不用client证书验证而仅通过用户名密码加TLS认证,可以只给用户ca和tls-auth对应的文件,在客户端配置中将cert和key注释。但服务器端不能将cert和key注释,否则会报错。并在server.conf最后加上
client-cert-not-required
username-as-common-name
0
技术性很强呀,收藏备用!