《Linux系统安全:纵深防御、安全扫描与入侵检测 》 —3.7 使用OpenVPN提供的各种script功能
3.7 使用OpenVPN提供的各种script功能
在以上的各个实践中,我们分别使用了静态密码或者证书的方式来提供客户端的认证。那么,是不是还有其他方法呢?
答案是肯定的。
可以体现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组
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);
- 点赞
- 收藏
- 关注作者
评论(0)