(泉州經貿職業(yè)技術學院 信息技術系,福建 泉州 362000)
VPN是一種基于隧道技術、加解密技術、密鑰管理與身份驗證等多種技術,通過公共傳輸通道構建的虛擬專用網絡。利用VPN隧道可以實現(xiàn)遠程用戶通過公共網絡訪問內網資源,并能夠保證數據的安全傳輸。目前,多數高校為了滿足校園網用戶能夠通過Internet訪問校內私有資源以及實現(xiàn)遠程辦公等需求,大多購買VPN硬件設備以實現(xiàn)搭建遠程訪問VPN,極大地方便師生在校外訪問內部資源。OpenVPN作為一種目前主流且應用廣泛、基于SSL的開源VPN技術,可用于創(chuàng)建虛擬專用網絡加密通道,其具有強大、高度可配置的優(yōu)越性能以及較強的網絡穿透力、安全性和穩(wěn)定性,并且支持Windows、Linux等眾多平臺的應用,實現(xiàn)在不增加VPN硬件設備的情況下,在連接公網的點與站點、站點與站點之間構建一條虛擬通道,并可保證數據傳輸的安全性,故OpenVPN同樣也可適用于搭建高校校園遠程訪問VPN。同時,由于LDAP目錄服務可用于實現(xiàn)大量數據的快速查詢,且具有跨平臺的特性,通??膳c校園網多種應用相結合以實現(xiàn)用戶的身份認證。OpenVPN與OpenLDAP均作為目前主流的優(yōu)秀跨平臺開源軟件,二者結合可廣泛應用于校園網遠程訪問的多種場景,并且OpenVPN客戶端軟件除了支持Windows、Linux和MAC系統(tǒng)等多種平臺的應用外,還支持目前常見的智能手機系統(tǒng)等其他移動設備終端,故本方案在搭建校園遠程訪問VPN方面具有較好的應用前景。
OpenVPN軟件集成了虛擬網卡設備、TCP/IP網絡技術、路由技術以及SSL數據傳輸加密等多種技術,允許參與建立VPN的連接雙方使用預共享私鑰、第三方數字證書或者用戶名/密碼進行身份驗證,該軟件應用SSL V3/TLS V1協(xié)議,大量使用了OpenSSL加密庫,可通過TLS/SSL加密以保證數據傳輸的安全。
OpenVPN技術核心是虛擬網卡。虛擬網卡是OpenVPN實現(xiàn)SSL VPN功能的關鍵,其使用TUN/TAP驅動程序,提供了通用TUN/TAP兩種類型虛擬網絡接口,分別支持路由和橋接兩種運行模式。OpenVPN驅動部分實現(xiàn)了網卡處理和字符設備,利用網卡驅動處理網絡數據,可以接收來自TCP/IP協(xié)議棧的數據包并發(fā)送或者將接收到的數據包傳給協(xié)議棧處理;利用字符設備完成與應用層的數據交互,實現(xiàn)將數據包在內核與用戶空間傳送,模擬物理鏈路的數據接收和發(fā)送[1]。在OpenVPN的使用過程中要求必須修改路由表。當遠程用戶連接OpenVPN服務程序時,應用程序發(fā)送數據,則系統(tǒng)會通過路由機制將數據發(fā)送到虛擬網卡,由字符設備讀取數據并送至應用層,最后通過物理網卡完成數據發(fā)送;OpenVPN服務程序可通過物理網卡接收到數據,由字符設備將數據傳至虛擬網卡,最后通過網絡堆棧將數據傳給上層應用程序。
利用開源軟件OpenVPN和OpenLDAP搭建高校遠程訪問VPN的網絡拓撲如圖1所示,二者均為Client/Server架構,本方案的實現(xiàn)是基于CentOS 5.6平臺,采用軟件分別為OpenVPN 2.0.9和OpenLDAP 2.3.43穩(wěn)定版本。為了保證在Internet上的通信安全,VPN服務器與客戶端可進行相互間的身份認證,本方案的VPN客戶端采用證書方式認證VPN服務器;VPN服務器則要求客戶端提供用戶名和密碼以實現(xiàn)遠程連接用戶的身份認證,具體實現(xiàn)過程為:遠程客戶端利用VPN隧道連接至校園網OpenVPN服務器,并將用戶名與密碼的認證信息加密后提交至OpenVPN服務器,此時OpenVPN服務器作為OpenLDAP目錄服務器的客戶端,通過比較來自VPN客戶端的認證信息與OpenLDAP服務器事先存放的所有允許連接OpenVPN服務器的用戶信息以實現(xiàn)認證。當遠程VPN用戶認證成功之后,通過檢查OpenVPN服務器的本地授權文件以決定是否允許遠程用戶訪問校內資源,從而實現(xiàn)遠程連接用戶的認證與授權。
圖1 高校校園遠程訪問VPN拓撲結構
由于OpenVPN需要對通過VPN隧道的數據進行壓縮以提高傳輸速度,所以應先編譯安裝LZO壓縮模塊,接著進行OpenVPN服務軟件包的編譯安裝。首先修改OpenVPN安裝路徑下的vars文件的相關變量值,然后構建PKI證書及交換密鑰協(xié)議文件dh1024.pem,這里分別創(chuàng)建CA證書文件及其私鑰文件、OpenVPN服務器證書文件及私鑰文件,最后配置OpenVPN服務器。本例中創(chuàng)建服務器配置文件ljl-vpn.conf,其基本內容如下:
local 192.168.100.2 //設置OpenVPN監(jiān)聽所使用的本地網卡IP
port 52115 //設置OpenVPN監(jiān)聽端口
proto tcp
dev tun //設置OpenVPN服務器使用路由模式
ca /etc/OpenVPN/keys/ca.crt
cert /etc/OpenVPN/keys/server.crt
key /etc/OpenVPN/keys/server.key
//以上分別指定CA證書、服務器證書及私鑰文件
dh /etc/OpenVPN/keys/dh1024.pem //指定DH參數,用于增強OpenVPN安全性
server 10.8.0.0 255.255.255.0
//OpenVPN成功連接之后,VPN服務器動態(tài)分配給VPN客戶端的地址范圍
push “route 192.168.100.0 255.255.255.0"
//在VPN客戶端本地生成VPN服務器所在內網網段路由
……
完成以上配置之后,需要編輯內核參數配置文件etc/sysctl.conf,設置net.ipv4.ip forward=1,并執(zhí)行sysctl -p命令使之生效,以實現(xiàn)開啟服務器的內核轉發(fā)功能,最后通過以下命令啟動VPN服務:
#/usr/local/sbin/OpenVPN --config /etc/OpenVPN/ljl-vpn.conf &
考慮到校園網用戶基本都是使用Windows客戶端,所以選擇安裝與當前OpenVPN服務器版本相匹配的Windows平臺客戶端軟件,之后將/etc/OpenVPN文件夾下的OpenVPN客戶端配置文件client.conf與服務器創(chuàng)建的CA證書ca.crt復制至C:Program FilesOpenVPNconfig文件夾,然后編輯修改OpenVPN客戶端配置文件client.conf,這里將其更名為適用于Windows平臺下擴展名為.ovpn的文件c-ljl.ovpn,其主要配置如下:
client
dev tun
proto tcp
remote 100.0.0.1 52115
//指定連接校園網防火墻外網IP及端口,將會映射到VPN服務器的本地IP及端口
ca ca.crt //指定CA證書文件
OpenLDAP是一種提供LDAP輕量級目錄訪問協(xié)議的跨平臺開源軟件,目錄中的信息是按照樹狀結構進行存儲的,具有高效的查詢速度,能夠適應大并發(fā)數的查詢請求[2],在校園網中搭建OpenLDAP服務通常用于實現(xiàn)用戶的身份認證,可以在內網的另一Linux主機上進行OpenLDAP的安裝、配置與管理,這里主要用于實現(xiàn)VPN用戶的認證。首先配置/etc/hosts文件,此處設置LDAP域名為“qzjmc.cn”,對應IP為192.168.100.3,然后進行OpenLDAP服務器的安裝與配置,接下來針對OpenLDAP主配置文件slapd.conf中以suffix、rootdn開頭的行做如下修改:
suffix “dc=qzjmc,dc=cn" //指定要搜索的后綴
rootdn “cn=admin,dc=qzjmc,dc=cn" //指定管理員dn路徑
復制/etc/OpenLDAP目錄下的數據庫配置文件DB CONFIG.example至/var/lib/ldap目錄并將其改名為DB CONFIG。在完成以上配置之后,首先啟動LDAP服務,接著進行OpenLDAP數據庫的初始化工作。本例實現(xiàn)直接遷移系統(tǒng)用戶數據至目錄服務數據庫中作為LDAP用戶,將/usr/share/OpenLDAP/migration下的migrate common.ph文件進行如下修改:
$DEFAULT MAIL DOMAIN = “qzjmc.cn";
$DEFAULT BASE = “dc=qzjmc,dc=cn";
通過執(zhí)行以下命令進行系統(tǒng)用戶遷移,即向LDAP數據庫添加用戶信息:
# /usr/share/OpenLDAP/migration/migrate base.pl > base.ldif
# /usr/share/OpenLDAP/migration/migrate passwd.pl /etc/passwd > passwd.ldif
# /usr/share/OpenLDAP/migration/migrate group.pl /etc/group > group.ldif
#ldapadd -W -x -H ldap://127.0.0.1 -D “cn=admin,dc=qzjmc,dc=cn"-f base.ldif
#ldapadd -W -x -H ldap://127.0.0.1 -D “cn=admin,dc=qzjmc,dc=cn"-f passwd.ldif
#ldapadd -W -x -H ldap://127.0.0.1 -D “cn=admin,dc=qzjmc,dc=cn"-f group.ldif
由于本方案中的OpenVPN服務器同時也作為OpenLDAP客戶端,所以可直接在OpenVPN服務器上安裝OpenLDAP客戶端軟件,然后執(zhí)行authconfig-tui命令,顯示如圖2所示的界面進行配置。
圖2 OpenLDAP客戶端配置界面
選中圖中標出的各個選項,并在“LDAP Settings"對話框設置LDAP服務器域名為“l(fā)dap://qzjmc.cn",Base DN為“dc=qzjmc,dc=cn"。完成OpenLDAP客戶端配置之后,遠程VPN用戶即可撥號連接OpenVPN服務器,該服務器作為OpenLDAP客戶端需要查詢OpenLDAP服務器上允許連接VPN的用戶信息,以實現(xiàn)遠程連接VPN用戶的身份驗證,此時應分別在OpenLDAP服務器及客戶端的防火墻上開放LDAP服務所使用的端口。在VPN用戶連接的整個過程,可以通過查看OpenLDAP客戶端的系統(tǒng)登錄信息日志以實現(xiàn)用戶登錄故障的排查。
為了實現(xiàn)OpenVPN服務器以用戶名/密碼的方式對于遠程撥入用戶的身份認證,本例在OpenVPN服務器配置文件中加入以下三行命令:
auth-user-pass-verify /etc/OpenVPN/check credit.py via-file
client-cert-not-required
username-as-common-name
其中OpenVPN服務器參數auth-user-pass-verify用于指定Web認證的方式,這里調用自定義的Python腳本文件check credit.py實現(xiàn)通過LDAP認證;參數client-cert-not-required表示不請求客戶端的CA證書認證而直接使用用戶名/密碼的方式認證;username-as-common-name參數指定使用客戶提供的username作為Common Name。
遠程OpenVPN客戶端若只使用用戶名/密碼的方式進行認證,必須在其配置文件中注釋掉指定客戶端證書與密鑰的兩行內容,即為客戶端不使用證書認證,并在其末尾添加“auth-user-pass”一行。
本方案通過創(chuàng)建Python腳本讀取LDAP數據庫實現(xiàn)認證,并且配合OpenVPN服務器本地文件進行登錄訪問的授權控制。由于Python腳本含有內置的LDAP函數,故可直接連接LDAP服務器,check credit.py腳本文件用于接收OpenVPN客戶端傳過來的用戶名與密碼,并與OpenLDAP服務器目錄數據庫中存放的LDAP用戶信息進行比對,從而實現(xiàn)用戶認證,當認證成功之后再通過檢查本地授權文件實現(xiàn)控制哪些用戶能夠連接登錄OpenVPN服務器并允許訪問內網資源。
在OpenVPN服務器的/etc/OpenVPN目錄下創(chuàng)建Python腳本文件check credit.py,其主要代碼如下:
#!/usr/bin/python
......
import ldap //導入內置的LDAP函數
# settings for ldap 設置LDAP連接的地址及搜索路徑
ldap uri = “l(fā)dap://192.168.100.3:389"
ldap starttls = True
ldap dn = “dc=qzjmc,dc=cn"
auth filename = “/etc/OpenVPN/grant-users.conf"
//指定本地授權文件,用于實現(xiàn)控制已通過認證的用戶是否具有訪問內網資源的權限
def get users(fpath): //獲取OpenVPN服務器本地授權文件中的用戶列表
fp = open(fpath, “rb")
lines = fp.readlines()
fp.close()
users = {}
for line in lines:
line = line.strip()
if len(line) <= 0 or line.startswith(‘#'):
!continue
users[line] = True
return users
def get credits(fpath): //獲取遠程VPN客戶端提交的用戶名與密碼
fp = open(fpath, “rb")
lines = fp.readlines()
fp.close()
assert len(lines)>=2, “invalid credit file"
username = lines[0].strip()
password = lines[1].strip()
return (username, password)
def check credits(username, password):
//檢查并驗證遠程VPN連接用戶是否在LDAP目錄數據庫中,以實現(xiàn)用戶認證
passed = False
ldap.set option(ldap.OPT PROTOCOL VERSION, ldap.VERSION3)
l = ldap.initialize(ldap uri)
if ldap starttls:
l.start tls s()
try:
l.simple bind s(ldap dn % (username,), password)
passed = True
except ldap.INVALID CREDENTIALS, e:
logging.error(“username/password failed verifying")
l.unbind()
return passed
def main(argv):
credit fpath = argv[1]
(username,password) = get credits(credit fpath)
if check credits(username, password):
users = get users(auth filename)
if not username in users: //判斷已認證用戶是否在授權訪問用戶列表中
logging.error(“user ‘%s' not authorized to access" % username)
return 1 //返回1表示拒絕連接訪問
logging.info(“access of user ‘%s' granted" % username)
return 0 //返回0表示授權連接訪問
else:
logging.error(“access of user ‘%s' denied" % username)
return 1
......
在OpenVPN服務器的/etc/OpenVPN目錄下創(chuàng)建本地授權文件grant-users.conf,并將允許授權訪問的VPN用戶名添加至該文件,以上的Python腳本文件通過讀取本地授權文件,檢查已通過認證的用戶是否也出現(xiàn)在該授權文件的用戶列表中,若存在的話則返回值為0,表示已認證用戶允許授權連接訪問;否則返回值為1,則表示未被授權訪問。
在完成OpenVPN服務器與客戶端的配置之后,必須在VPN通信雙方的主機及校園網防火墻網關上分別開放OpenVPN連接所使用的端口,本例為TCP的52115端口,并且應在校園網防火墻上配置OpenVPN服務器映射的公網IP及端口,這里映射為防火墻外網卡IP及TCP的52115端口,然后便可在VPN客戶端上運行OpenVPN GUI程序,通過利用映射的公網IP及連接端口并輸入用戶名與密碼進行撥號連接,在成功認證并授權建立訪問連接之后,OpenVPN服務器便會增加一塊名為tun0的虛擬網卡,其IP為之前服務器配置文件ljl-vpn..conf中server字段指定的屬于10.8.0.0網段的IP地址10.8.0.1,同時VPN服務器給客戶端分配一個同屬于10.8.0.0網段的IP地址10.8.0.6,此時VPN客戶端可以Ping通VPN服務器的tun0虛擬網卡IP及本地網卡IP,但無法訪問與OpenVPN服務器在同一網段的其他內網主機,可以通過配置VPN服務器所在的Linux主機IPtables防火墻的SNAT源地址轉換功能,使得所有訪問VPN服務器所在內網主機的請求數據包的源IP地址重新映射為VPN服務器的本地IP,則遠程VPN客戶端便可在成功建立VPN連接之后使用校園網私有IP地址訪問OpenVPN服務器所在內網網段的主機。OpenVPN服務器的IPtables防火墻SNAT功能配置命令為:
#/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth1 -j SNAT --to-source 192.168.100.2
以上IPtables命令實現(xiàn)在NAT鏈中添加一條SNAT轉換規(guī)則,其中-o eth1代表VPN服務器本地網卡,其IP地址為192.168.100.2。
目前OpenVPN主要使用兩種用戶訪問控制方法,分別為包過濾機制與IPtables防火墻機制[3]。通過OpenVPN內建的包過濾機制,可以實現(xiàn)對訪問者進行細粒度的訪問控制。針對每一用戶建立相應的包過濾策略文件或添加默認的過濾文件,可以限制VPN客戶端對OpenVPN服務器所在的內部網絡中指定子網或IP的主機訪問。另外,也可以通過配置IPtables防火墻實現(xiàn)VPN用戶的訪問控制,給撥入OpenVPN服務器的不同用戶分配不同的訪問權限,即首先為不同的OpenVPN撥入用戶分配不同的IP地址,然后編寫IPtables策略對不同的IP控制不同的訪問。通過IPtables規(guī)則可以實現(xiàn)針對VPN用戶的IP地址、被訪問資源的IP地址以及所開啟的端口服務進行訪問限制[4](P370)。
OpenLDAP服務器與客戶端之間默認使用明文進行通信,包括發(fā)送的用戶認證信息,OpenLDAP支持TLS加密[5](P203),可以將LDAP協(xié)議與SSL協(xié)議相結合即為實現(xiàn)LDAPS服務。通過利用openssl軟件構建PKI證書實現(xiàn)OpenLDAP服務器與客戶端之間的身份認證,也可配置雙方支持使用SSL安全通信。另外,為了防止針對LDAP目錄數據的非法訪問或篡改等越權操作[6](P77),通常可以在OpenLDAP服務器主配置文件slapd.conf中使用ACL功能的access語句實現(xiàn)控制用戶是否具有讀取、寫入、創(chuàng)建及刪除條目的授權權限。
相對于PPTP VPN、L2TP VPN和IPSec VPN等其他VPN技術而言,OpenVPN提供了一種經濟、可行且具有較高安全性與穩(wěn)定性的遠程SSL VPN解決方案,其具有較強的網絡穿透力,并且可實現(xiàn)基于用戶和IP地址的細粒度訪問控制。利用OpenVPN技術實現(xiàn)點到站點的遠程連接訪問,并通過配合OpenLDAP進行VPN撥入用戶的認證與訪問授權,可以較好地解決校園網用戶通過Internet訪問校內私有資源的需求。另外,OpenVPN也可用于搭建經由Internet連接的多個不同校區(qū)內網之間的站點到站點VPN,下一步研究重點是利用OpenVPN實現(xiàn)各校區(qū)間如同在同一局域網內部,可以使用私有IP地址的方式進行內部資源共享及相互訪問。
參考文獻:
[1] 林圣東,陳小惠,趙瑞卿. 基于OpenVPN 的Lan-to-Lan VPN的設計與實現(xiàn)[J]. 電子測試,2012,(4):88.
[2]李吉勇. 基于OpenLDAP 的校園網統(tǒng)一身份認證設計[J]. 電腦編程技巧與維護,2012,(14):112.
[3]金寶龍. Linux 下OpenVPN 的兩種用戶訪問控制方法[J]. 電腦知識與技術 2013,9(11):25-55.
[4]陶利軍.構建虛擬專用通道-OpenVPN服務器詳解與架設指南(基于Linux)[M]. 北京:清華大學出版社,2013.
[5]曹江華,林捷. RedHat Enterprise 6.0服務器構建[M]. 北京:電子工業(yè)出版社,2012.
[6]李晨光. Linux企業(yè)應用案例精解[M]. 北京:清華大學出版社,2012.