• OpenVPN使用纯插件通过MySQL进行用户验证(不使用PAM与FreeRadius)

    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 none

    auth_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