返回介绍

最佳实践 58:使用 OpenVPN 提供的各种 script 功能

发布于 2025-04-20 17:44:46 字数 2192 浏览 0 评论 0 收藏

在以上的各个最佳实践中,分别使用了静态密码或者证书的方式来提供客户端的认证。那么,是不是还有其他方法呢?

答案是肯定的。

可以体现 OpenVPN 灵活性特点的一个重要方面是它提供了从客户端认证前、认证中、认证后、隧道建立后等各个阶段的 script 处理功能。读者可以用这些 script 来实现各种控制功能。

OpenVPN 按照执行的顺序,提供了以下的一系列脚本功能:

- --up:在 TCP/UDP 在 socket 上执行了 bind、TUN/TAP 后执行。

- --tls-verify:远程开始进行 tls 认证时执行。

- --ipchange:在客户端,OpenVPN 连接认证后执行。

- --client-connect:在服务器端,客户端认证后立即执行。

- --route-up:连接认证后执行。

- --route-pre-down:路由删除前执行。

- --client-disconnect:在服务器上,客户端断开连接时执行。

- --down:TCP/UDP 和 TUN/TAP 关闭后执行。

- --learn-address:在服务器端,任何路由或者 IP 地址被 MAC 地址学习到时执行。

- --auth-user-pass-verify:在服务器端,新的客户端连接开始建立的时候。

回归到前面提到的对客户端进行其他方式认证的问题,可以使用--auth-user-pass-verify 指令。

在 server.conf 中,增加配置项如下:

auth-user-pass-verify /etc/openvpn/myauth.pl via-file

myauth.pl 脚本输出 0(成功)或者 1(失败)以通知 OpenVPN 是否认证通过。

通过如下脚本,使用 Windows Active Directory 来进行用户的控制,只有合法的 Active Directory 账户才可以连接到虚拟专用网络。脚本内容如下:

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Net::LDAP;
my $tmpfile = $ARGV[0];#OpenVPN 进程会把客户端提交过来的用户名和密码记录在临时文件中
my $line    = 1;
my $username;
my $password;
my $not_verified = 1;

open( TMP, '<', $tmpfile ) or exit(1); #打开临时文件
while (<TMP>) {
     chomp;
     if ( $line eq 1 ) {
          $username = $_; #获取用户名
     }
     else {
          $password = $_; #获取密码
     }
     $line++;
}
close(TMP);
if ( !( $username && $password ) ) {
     exit(1);
}

# verify via active directory
my $ldap = Net::LDAP->new('shrd.woyo.com', timeout =>3) or exit(1);
my $mesg =
  $ldap->bind( $username . "\@" . 'shrd.woyo.com', password => $password );
$mesg->code && exit(1); #使用用户名和密码到 AD 中进行认证
my $searchbase = 'dc=shrd,dc=woyo,dc=com';
#VPN 用户必须属于 vpn 组
my $filter     = "memberOf=CN=vpn,OU=Accounts,DC=shrd,DC=woyo,DC=com"; 
my $results    = $ldap->search( base => $searchbase, filter => $filter );
foreach my $entry ( $results->entries ) {
     if($entry->get_value('mailNickname') && ($entry->get_value('mailNickname') eq $username )) {
          $not_verified = 0;
          last;
     }
}
$ldap->unbind;
exit($not_verified);

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。