от vm(18-12-2006)

рейтинг (19)   [ добре ]  [ зле ]

Printer Friendly Вариант за отпечатване

Изграждане на X.509 PKI VPN


Веселин Марков 12.2006

 
Този документ разглежда осъществяването на свързаност между частни мрежи през публична среда (WAN) посредством криптографско тунелиране.
Решението се базира на SSL/TLS комуникация и енкапсулиране на данни върху TUN/TAP интерфейси посредством OpenVPN.  

 
.: Въведение


По дефиниция VPN мрежите могат да бъдат сигурни (IPSec, SSL/TLS, L2TP, PPTP) и такива, които предават данни по нешифриран начин, доверявяйки се на транзитна сигурност от страна на доставчика (MPLS, L2F).

Все повече доставчици предоставят услуга "VPN", като в някои случаи клиентът трудно може да избегне поръчването й ако се нуждае от съответен начин на свързване до отдалечена мрежа. Често протоколи като ESP/AH биват напълно "отрязвани" от употреба без преминаване към по-висок ценови план.
Очевидно, бъдейки в пъти по-изгодно, установяване на VPN решение (вместо изграждане и разширяване MAN или WAN) е предмет на избор за голям брой организации.

Алтернативно, експлоатация на VPN техология е възможно чрез използване на SSL/TLS тунелиране. OpenVPN е такъв пример, поддръжащ различни методи на свързване, удостоверяване, в т.ч. споделен ключ, сертификати, смарт карти, комбинация от потребителско име и парола, както и комплексни начини за криптиране на сесията и запазване на интегритета й.

OpenVPN е свободен софтуер, първоначално разработен от Джеймс Йонан, базиран на OpenSSL и е наличен под GNU/Linux, BSD вариации, OS X, Solaris, Windows.

При реализацията на OpenVPN могат да се използват 2 допълнителни интерфейса за комуникация - tun и tap. Идеята при тях е да се симулират мрежови устройства. TUN симулира Point to Point у-во (OSI L3) при рутиран VPN, докато TAP - Ethernet (L2), при VPN с мрежов мост (bridge). По-късно ще се спра отново на тях.

Интересен факт е, че OpenSSH (след вер 4.3) също има поддръжка на tun/tap драйвера:

http://www.securityfocus.com/columnists/375
http://marc2.theaimsgroup.com/?l=secure-shell&m=114467685608028&w=2

Характена възможност на OpenVPN е функционирането му по UDP или TCP (и по този начин върху proxy сървъри). OpenVPN може да работи с динамични крайни точки, да тунелира мрежи през NAT, да се "разбира" добре със stateful защитни стени, да позволява приоритизация на трафика който минава през него, както и симултанно да поддръжа голям брой клиенти/трафик. Обмяната на ключове е възможна чрез статични, споделени такива или динамично, на база на TLS. Трафикът се компресира в реално време чрез LZO библютеката.

От гледна точка на системна сигурност самият процес може да работи с понижени права и/или в chroot среда. Бъдейки базиран на OpenSSL(1) библютеката, OpenVPN може да използва всички шифри до който (1) има достъп, в т.ч. AES-256, различна големина на ключ, множество HMAC digests. Възможно е и "заключване" на процеса в паметта (не попада в swap) чрез mlockall().

.: Конфигурация на OpenVPN сървър


Теоритично погледнато, възможни методи при идентификация на клиент биват класифицирани според:

- нещо което потребителят знае (парола)
- нещо притежавано от потребителя (таен ключ към сертификат, смарт карта)
- нещо което потребителят е (биометрични данни - пръстов отпечатък, данни от сканиране на ретина)

Разглежданият от статията метод на идентификация на потребител се свежда до PKI система, изградена чрез СА. Информация касаеща аспектите от създаване и администриране на Достоверен Източник на Сертификати могат да бъдат намерени тук:

http://linux-bg.org/cgi-bin/y/index.pl?page=article&id=advices&key=386394133&layout=clean

За улеснение на редовия потребител, в пакета OpenVPN има скриптове, които намаляват услията по създаване на клиентски и сървърни сертификати.

Съществен момент от аминистрацията на VPN сървър работещ с X.509 сертификати е създаването и обновяването на CRL списък. В зависимост от това дали клиент използва валиден или анулиран сертификат, из лог файловете на openvpn ще срещнете следните записи:

Thu Dec  7 00:42:23 2006 224.100.200.191:63402 CRL CHECK OK: /C=BG/ST=_/ L=_/O=Example_Corp./OU=IT_Dept./ CN=Example_Corp._VPN_designated_CA-2/ emailAddress=admin@example.net
Thu Dec  7 00:42:23 2006 224.100.200.191:63402 CRL CHECK OK: /C=BG/ST=_/L=_/O=Example_Corp./OU=Marketing/CN=client1/emailAddress=admin@example.net

или

Fri Dec  8 01:16:59 2006 236.32.2.7:38889 CRL CHECK FAILED: /C=BG/ST=_/L=_/O=Example_Corp./OU=HR/CN=client2/emailAddress=admin@example.net is REVOKED


Важна особеност ако използвате chroot среда е CRL да бъде поставен на мястото където заключвате процеса (например /var/empty).

Схематично представен мрежови модел:


 [ priv net 10.0.0.0/24 ]
    [ client gw 224.100.200.191 ]  -  WAN  -  [ company gw 225.50.100.5 ]
                                                                         [ dmz node addr 225.50.100.8 ]
                                                                                     [ priv net 192.168.0.0/22 ]
                                                                                             други vpn терминационни точки
 

Всъщност, въпросният VPN се изгражда между хостовете impala (10.0.0.2) и vpndial (192.168.0.156).
Случаят, който разглеждам, използва мост (bridge) между eth0 и tap0 (tap1, tap2, tapX). Следните компоненти са необходими заредени като модули или компилирани статично в ядрото:

CONFIG_BRIDGE=m
CONFIG_TUN=m

Можете, разбира се, да си спестите евентуални главоболия в тази насока, решавайки че и рутиран VPN ви върши работа. Разликата е в това, че при използване на такъв тунел (tun) се налага да добавите няколко правила с iptables, за да маскирате трафика преминаващ през tun устройството. Този вариант би бил донякъде проблемен по отношение на NAT, например ако се опитвате да ползвате H.323 или SIP протокол през VPN-а си, или искате по друга причина машината ви да бъде "видима" на отсещната мрежа (в ядро 2.6.19 има експериментална поддръжка на connection tracking и за 2-та протокола).

Ако се наложи да ползвате описаният VPN с bridge от dial-up до сравнително голяма мрежа има опасност каналът да бъде запълнен от broadcast пакети.

По подразбиране, портът на който слуша за заявки демон процесът е UDP/1194. Ако възнамерявате да разрешите достъп на клиенти с произволни IP адреси, следва да го позволите за всички във filter/INPUT. Също така препращането на пакети към br0 трябва да е разрешено във filter/FORWARD.

Конфигурационният файл изглежда така:

port 6644
proto udp
dev tap0
tls-auth priv/ta.key 0
user nobody
group nobody
chroot /var/empty
cipher AES-256-CBC
auth RSA-SHA512
reneg-sec 1800
persist-key
persist-tun
ca priv/ca.crt
cert priv/server.crt
key priv/server.key
dh priv/dh2048.pem
crl-verify ca.crl
push "route 192.168.0.0 255.255.0.0"
server-bridge 192.168.0.156 255.255.252.0 192.168.3.10 192.168.3.150
push "redirect-gateway def1"
keepalive 10 120
comp-lzo
status openvpn-status.log
log         openvpn.log
verb 3

 
Някой бележки по него:

 - ca.crl се намира във /var/empty и е прочитаем за nobody
 - ключът към сървърския сертификат е достъпен единствено от root
 - файлът с Diffie-Hellman параметри може да бъде създаден така: openssl dhparam -out dh2048.pem 2048 (възможно е да отнеме повече време)
 - ta.key е споделен ключ (стойност 0 при сървър и 1 за клиент) генерира се така: openvpn --genkey --secret ta.key
 - redirect-gateway def1 указва целият клиентски трафик да бъде рутиран през vpn, което от една страна е удобно ако има добра свързаност, а от друга повишава сигурността след като клиентът попада зад корпоративен firewall, до края на сесията си.

Маршрутната таблица при клиентски хост би изглеждала така при наличност на тази опция

225.50.100.8 via 10.0.0.1 dev eth0
192.168.0.0/22 dev tap0  proto kernel  scope link  src 192.168.3.10
192.168.0.0/16 via 192.168.0.156 dev tap0
10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
127.0.0.0/8 dev lo  scope link
0.0.0.0/1 via 192.168.0.156 dev tap0
128.0.0.0/1 via 192.168.0.156 dev tap0
default via 10.0.0.1 dev eth0

- редът с push route указва достъп до посочените частни мрежи
- server-bridge 192.168.0.156 (openvpn адрес на сървър) 255.255.252.0 (мрежова маска) 192.168.3.10 192.168.3.150 (адреси предназначени за VPN потребители)
- persist-key, persist-tun запзват някои вече изградени ресурси/настройки при HUP-ване (или пращане на друг сигнал) на процеса, тъй като не се очаква nobody да има достъп до тях
- reneg-sec определя време в секунди до нов TLS handshake


 .: Конфигурация на OpenVPN клиент
 

client
dev tap
# proto tcp
proto udp
remote 225.50.100.8 6644
# http-proxy 10.0.0.1 80
nobind
persist-key
persist-tun
auth RSA-SHA512
reneg-sec 1800
tls-auth priv/ta.key 1
cipher AES-256-CBC
user nobody
group nobody
ns-cert-type server
ca priv/ca.crt
cert priv/client1.crt
key priv/client1.key
comp-lzo
verb 3

 - remote определя адрес/порт на vpn сървъра
 - nobind указва процесът да не отваря слушащ порт
 - ns-cert-type server е спомага за предотвратяване на mitm атака в случай че притежател на сертификат издаден от същото CA се опита да се представи за сървър, ще бъде проверено дали низ от сертификата му отговаря на изискваният тип
 - verb указва степен на изчерпателност на лог съобщенията
 - http-proxy дефинира адрес на proxy сървър, както и различни типове оторизация (basic, ntlm)

При squid, openvpn сесията ще бъде регистрирана по сходен начин в access.log:

1165770141.590 368564 10.0.0.1 TCP_MISS/200 1412503 CONNECT 225.50.100.8:6644 - DIRECT/225.50.100.8 -

Документацията по проекта OpenVPN е съвсем изчерпателна и препоръчителна. Към същият има и пощенски лист с архив.

 

.: Връзки

 [1] http://www.openvpn.net
 [2] http://www.openssl.org/docs/
 [3] http://www.oberhumer.com/opensource/lzo/
 [4] http://sourceforge.net/mailarchive/forum.php?forum_id=8453
 [5] http://www.kernel.org/hg/linux-2.6/raw-file/d1f4bbb0befc/Documentation/networking/tuntap.txt
 


 .: Приложение


root@impala:pts/7 /opt/openvpn-2.0.9# openvpn --config cfg

Tue Dec 12 11:36:08 2006 OpenVPN 2.0.9 i686-pc-linux [SSL] [LZO] built on Nov 11 2006
Tue Dec 12 11:36:08 2006 IMPORTANT: OpenVPN's default port number is now 1194, based on an official port number assignment by IANA.  OpenVPN 2.0-beta16 and earlier used 5000 as the default port.
Tue Dec 12 11:36:08 2006 Control Channel Authentication: using 'priv/ta.key' as a OpenVPN static key file
Tue Dec 12 11:36:08 2006 Outgoing Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
Tue Dec 12 11:36:08 2006 Incoming Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
Tue Dec 12 11:36:08 2006 LZO compression initialized
Tue Dec 12 11:36:08 2006 Control Channel MTU parms [ L:1634 D:210 EF:110 EB:0 ET:0 EL:0 ]
Tue Dec 12 11:36:08 2006 Data Channel MTU parms [ L:1634 D:1450 EF:102 EB:135 ET:32 EL:0 AF:3/1 ]
Tue Dec 12 11:36:08 2006 Local Options hash (VER=V4): '90db4a0f'
Tue Dec 12 11:36:08 2006 Expected Remote Options hash (VER=V4): '5b6da2ed'
Tue Dec 12 11:36:08 2006 NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
Tue Dec 12 11:36:08 2006 UDPv4 link local: [undef]
Tue Dec 12 11:36:08 2006 UDPv4 link remote: 225.50.100.8:6644
Tue Dec 12 11:36:09 2006 TLS: Initial packet from 225.50.100.8:6644, sid=199b7f24 c1ee9f76
Tue Dec 12 11:36:09 2006 VERIFY OK: depth=1, /C=BG/ST=_/L=_/O=Example_Corp./OU=IT_Dept./CN=Example_Corp._VPN_designated_CA-2/emailAddress=admin@example.net
Tue Dec 12 11:36:09 2006 VERIFY OK: nsCertType=SERVER
Tue Dec 12 11:36:09 2006 VERIFY OK: depth=0, /C=BG/ST=_/L=_/O=Example_Corp./OU=IT_Dept./CN=server/emailAddress=admin@example.net
Tue Dec 12 11:36:11 2006 Data Channel Encrypt: Cipher 'AES-256-CBC' initialized with 256 bit key
Tue Dec 12 11:36:11 2006 Data Channel Encrypt: Using 512 bit message hash 'SHA512' for HMAC authentication
Tue Dec 12 11:36:11 2006 Data Channel Decrypt: Cipher 'AES-256-CBC' initialized with 256 bit key
Tue Dec 12 11:36:11 2006 Data Channel Decrypt: Using 512 bit message hash 'SHA512' for HMAC authentication
Tue Dec 12 11:36:11 2006 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 2048 bit RSA
Tue Dec 12 11:36:11 2006 [server] Peer Connection Initiated with 225.50.100.8:6644
Tue Dec 12 11:36:12 2006 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)
Tue Dec 12 11:36:12 2006 PUSH: Received control message: 'PUSH_REPLY,route 192.168.0.0 255.255.0.0,redirect-gateway def1,route-gateway 192.168.0.156,ping 10,ping-restart 120,ifconfig 192.168.3.10 255.255.252.0'
Tue Dec 12 11:36:12 2006 OPTIONS IMPORT: timers and/or timeouts modified
Tue Dec 12 11:36:12 2006 OPTIONS IMPORT: --ifconfig/up options modified
Tue Dec 12 11:36:12 2006 OPTIONS IMPORT: route options modified
Tue Dec 12 11:36:12 2006 TUN/TAP device tap0 opened
Tue Dec 12 11:36:12 2006 /sbin/ifconfig tap0 192.168.3.10 netmask 255.255.252.0 mtu 1500 broadcast 192.168.3.255
Tue Dec 12 11:36:12 2006 /sbin/route add -net 225.50.100.8 netmask 255.255.255.255 gw 10.0.0.1
Tue Dec 12 11:36:12 2006 /sbin/route add -net 0.0.0.0 netmask 128.0.0.0 gw 192.168.0.156
Tue Dec 12 11:36:12 2006 /sbin/route add -net 128.0.0.0 netmask 128.0.0.0 gw 192.168.0.156
Tue Dec 12 11:36:12 2006 /sbin/route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.0.156
Tue Dec 12 11:36:12 2006 GID set to nobody
Tue Dec 12 11:36:12 2006 UID set to nobody
Tue Dec 12 11:36:12 2006 Initialization Sequence Completed

root@impala:pts/5 ~# traceroute google.com

traceroute: Warning: google.com has multiple addresses; using 64.233.167.99
traceroute to google.com (64.233.167.99), 30 hops max, 38 byte packets
 1  192.168.0.156 (192.168.0.156)  77.031 ms  37.725 ms  37.310 ms
 2  rtr.example.net (225.50.100.1)  56.517 ms  44.999 ms  45.874 ms

...

root@vpndial:pts/0 ~# cat openvpn-status.log

OpenVPN CLIENT LIST
Updated,Thu Dec  7 00:48:40 2006
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
client1,224.100.200.191:63402,99624,1415849,Thu Dec  7 00:42:14 2006
client2,236.32.2.7:43495,739726,130506933,Wed Dec  6 12:58:40 2006
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
4a:5e:ca:f3:3c:67,client1,224.100.200.191:63402,Thu Dec  7 00:48:03 2006
56:c7:1f:65:5d:d1,client2,236.32.2.7:43495,Wed Dec  6 12:58:41 2006
GLOBAL STATS
Max bcast/mcast queue length,122
END

Последният файл се актуализира на всеки 60 сек.





<< | >>