2012년 2월 13일 월요일

CentOS에서 PPTP 및 L2TP/IPSec 프로로콜을 이용한 VPN 서버 구축하기


이 문서는 CentOS 6 배포판에서 poptop/xl2tp 오픈소스를 이용하여 VPN 서비스를 구축하는 것을 설명한다. 이 문서에서 CentOS 6.0 Basic Installation을 기반으로 하기 때문에 poptop/xl2tp 설치에 필요한 므든 의존 라이브러리에 대하여서는 언급 하지 않는다.

Point to Point Tunneling Protocol과 Layer 2 Tunneling Protocol은 VPN 프로토콜을 가장 전형적인 프로토콜이며 각기 PPTP 및 L2TP라는 짧은 약자를 가지고 있다. 이하 설명은 모두 약자를 사용하여 진행한다.

PPTP는 LAN 환경이 구축되기 이전의 모뎀 사용시에 많이 사용 되었던 Point to Point Protocol을 사용하여 구성 되었다. PPTP는 마이크로 소프트에 의하여 VPN을 구축하기 위하여 창안되었으며 현재 가장 널리 사용되는 VPN 프로토콜이기도 하다.

L2TP 역시 많이 사용하는 VPN 프로토콜이지만 IPSec와 연동하여 많이 사용되며 IPSec을 위한 키를 만들기에 여러가지 번거로움이 있다.

PPTP는 PPP의 여러 인증 방식을 사용하는데 여기서 PAP와 MS-CHAP2가 가장 전형적이다.

A. PAP
Password Authentication Protocol (PAP)은 인증 프로토콜로 인증 파일의 암호부분을 지정하지 않으면 시스템 계정의 비밀번호를 이용하여 인증하므로 sniffing에 취약하다.

B. MS-CHAP v2
이 역시 암호화된 인증 프로토콜로 VPN 사용자 인증시 사용 된다.

PAP는 보안에 많이 취약하며 현재 많이 사용되지 않는다. 이 문서에서는 MS-CHAP v2 인증 방식을 이용하여 VPN 서비스를 구축하는것을 예를 들어 설명하고자 한다.

위에서 설명한 두가지 암호화의 의미는 인증단계에서의 비밀번호 암호화만 의미하며 PPTP는 패킷에 특정 헤더를 추가하여 패킷을 캡슐화하는 것이 아니기 때문에 이런 상태에서 전송되는 모든 데이터는 암호화 되어 있지 않다. 모든 전송 패킷을 암호화 하기 위하여 MPPE라는 암호화 프로토콜을 사용한다. MPPE는 전송 되는 모든 데이터를 암호화 시시켜주는 역할을 한다. MPPE는 PAP환경에서 사용 할 수 없다.

 이제 그럼 설치를 시작 해보자.

설치 환경
운영체제: CentOS 6.0 x86_64
커널: 3.0

1. pptpd의 설치

2011년 7월 현재 CentOS 공식 및 EPEL 레포지터리에는 아직 PPTPD 패키지가 등록되어 있지 않았다. 소스 컴파일로 PPTPD를 설치하기 귀찮으므로 RPM패키지를 모아 놓은 레포지터리를 찾아서 추가한다. poptop 오픈 소스 개발 팀에서 이미 PPTPD 패키지를 레포지터리에 올려 레포지터리 추가만으로 쉽게 PPTPD를 설치 할 수 있다.


 yum을 이용한 설치가 끝났다... 필자는 인터넷 상에 존재하는 수많은 문서들을 참고하면서 시도를 했는데 대부분 문서들에서 kernel_ppp_mppe를 설치하는 부분까지 있었다. 하지만 CentOS 5.0이상부터 커널에 기본 kernel_ppp_mppe 모듈이 포함이 되어 있으므로 이 부분은 건너뛸 수 있다. kernel_ppp_mppe 모듈 설치 여부를 알아 보는 방법은 다음과 같다.

# modprobe ppp-compress-18 && echo ok

 만약 OK를 반환하면 kernel_ppp_mppe 모듈이 설치되어있음을 의미한다.

2. pptpd의 설정

# vi /etc/pptpd.conf

맨 마지막 부분


# localip 192.168.0.1
# remoteip 192.168.0.234-238,192.168.0.245

를 주석문 속에서 빼낸다.

위에서 처럼 설정하면 서버는 192.168.0.1 IP를 할당 받고 VPN 클라이언트는 자동으로 이 IP 게이트웨이로 할당 받아 모든 패킷은 이 IP로 전송 된다.
또한 remoteip가 234 - 245이므로 총 11개의 IP를 VPN 클라이언트가 할당 받게 되고, 다 시 말해서 최대 11개의 클라이언트의 동시 접속을 지원 할 수 있다. 만약 서버의 네트워크 throughput이 크고 사양도 좋다면 클라이언트에 할당 가능한 IP의 개수를 적절히 늘일 수 있다.

# vi /etc/ppp/options.pptpd

mppe-128를 주석문속에 넣는다. 이유는 이 설정을 주석처리 하지 않으면 특정 사이트에 접속이 되지 않는다. 주석처리하고 pptp 클라이언트 상에서도 해당 옵션을 사용치 않도록 한다.

ms-dns를 주속문속에서 빼고 DNS를 설정 해준다.

나머지는 기본 설정대로 사용 하면 된다.

# vi  /etc/ppp/chap-secrets

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
####### redhat-config-network will overwrite this part!!! (begin) ##########
aaa                *    password@                      *
bbb                *    password@                      *
####### redhat-config-network will overwrite this part!!! (end) ############

위에서 처럼 사용자명, 사용할 프로토콜, 비밀번호 및 접속허용할 아이피대역을 설정한다.
여기서 만약 비밀번호를 ""로 지정하면 (즉 공백) PAM을 이용하여 VPN 사용자를 인증할 수 있는데 이때 /etc/passwd에 사용자 인증정보를 사용한다.

이제 iptables 설정을 해보자. iptables 설정을 하지 않으면 VPN 서버에 연결되었다 할 지라도 패킷 포워딩을 하지 않아 인터넷에 연결되지 않는다.


# iptables --append INPUT --protocol 47 --jump ACCEPT
# iptables --append INPUT --protocol tcp --match tcp --destination-port 1723 --jump ACCEPT

다음 클라이언트에서 ipv4 패킷을 받으면 포워딩 하도록 설정 해준다.

# vi /etc/sysctl.conf 

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

net.ipv4.ip_forward를 0에서 1로 바꾼다.

변경사항을 저장하고 빠져나와서

# sysctl -p

명령어를 날려 포워딩 설정을 곧바로 적용한다.

# service iptables save

지금 까지 설정한 iptables 설정들을 저장한다.

# vi /etc/sysconfig/iptables

# Generated by iptables-save v x.x.x on xxx
*nat
:PREROUTING ACCEPT [10:584]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Wed Jan 10 15:17:43 2007
# Generated by iptables-save v1.2.11 on Wed Jan 10 15:17:43 2007
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [387:86918]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A INPUT -p gre -j ACCEPT  
-A INPUT -p tcp -m tcp --dport 1723 -j ACCEPT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p ipv6-crypt -j ACCEPT
-A RH-Firewall-1-INPUT -p ipv6-auth -j ACCEPT
-A RH-Firewall-1-INPUT -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
#-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on xxx

위에서 처럼 설정이 저장되었는지 확인한다. 볼드체로 표시된 부분을 눈 여겨 보자.

iptables 변경 사항들을 적용한다.

# service iptables restart

pptpd 서버를 시작 하거나 재시동 한다.

# service pptpd restart-kill
# service pptpd start 

3. L2TPD 설치

L2TPD VPN 오픈 소스는 많으며 이 문서에서는 그중 많이 사용되는 xl2tp 설치 과정을 예제로 보여준다.
L2TPD 설치에 앞서 IPSec 설치 및 설정을 해야 한다.

# yum install openswan

OpenSwan IPSec 서비스의 한 오픈소스이다.
openswan이 설치 되었으면 이제 설정을 할 차례이다.

# vi /etc/ipsec.conf

version 2.0

config setup
        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
        oe=off
        protostack=netkey
        nat_traversal=yes

conn L2TP-PSK-NAT
        rightsubnet=vhost:%priv
        also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT
        authby=secret
        pfs=no
        auto=add
        keyingtries=3
        rekey=no
        ikelifetime=8h
        keylife=1h
        type=transport
        left=서버아이피를 기입한다
        leftprotoport=17/1701
        right=%any
        rightprotoport=17/%any

IPSec에 쓰일 Shared Key를 설정하자.

# vi /etc/ipsec.secrets

서버아이피주소 %any: PSK "암호화키"

패킷 리다이렉션 설정을 한다.


# for each in /proc/sys/net/ipv4/conf/*
> do
> echo 0 > $each/accept_redirects
> echo 0 > $each/send_redirects
> done

IPSec 서비스를 재시동 한다.

# service ipsec restart

IPSec 서비스의 유효성 여부를 체크한다.

# ipsec verify

이제 L2TP를 구현한 오픈 소스 xl2tp를 설치한다.

# yum install libpcap-devel xl2tp ppp

4. L2TPD 설정

# vi /etc/xl2tpd/xl2tpd.conf

[global]
ipsec saref = yes

[lns default]
ip range = 10.1.2.2-10.1.2.254
local ip = 10.1.2.1
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

# vi /etc/ppp/options.xl2tpd

require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

기타 설정은 PPTP 설정시 했으므로 여기서 skip한다.

마지막으로 xl2tp 데몬을 구동해보자

# service xl2tpd start

5. Windows 7 클라이언트 설정

바탕 화면에서 네트워크 아이콘에 오른쪽 마우스를 클릭하여 속성에 들어가거나 제어판에서 네트워크 및 공유 센터에 들어간다.




새 연결 또는 네트워크 설정을 클릭한다.




회사에 연결을 선택하여 VPN 연결을 새로 생성한다.
 



연결 방법에서 내 인터넷 연결 사용 (VPN) (I) 선택한다.



연결할 VPN 주소 및 그에 대한 설명을 기입한다.



 
사용자 이름 및 암호를 입력한다.



 
첫 연결 시 오류가 발생 할 것이다. 당황하지 말자. 연결 설정을 꾸욱 눌러 현재까지 생성한 VPN연결 설정을 저장한다.



 
다시 네트워크 및 공유 센터로 돌아온다. 이번엔 어댑터 설정 변경 항목을 선택한다.



 
생성한 xxx SERVER를 마우스 오른쪽 버튼으로 클릭한 속성으로 들어간다.



 
만약 PPTP 기반 VPN 서비스를 사용려면 보안 탭에서 VPN종류 및 데이터 암호화 방식을 아래 그림에서와 같이 설정한다.



 
PPTP가 아닌 L2TP 기반 VPN 서비스를 사용려면 보안 탭에서 VPN종류 및 데이터 암호화 방식을 아래 그림에서와 같이 설정한다.




네트워킹 탭에서 IPV4가 하이라이트 된걸 확인한 후 속성을 클릭한다.



 
IP및 DNS는 서버에서 자동으로 할당 받으므로 넘어가자. 고급을 클릭한다.



 
원격 네트워크에 기본 게이트웨이 사용(U) 항목이 선택되어 있음을 확인 한다.



 
확인을 쭉 클릭하여 창에서 빠져 나온 후, xxx SERVER에 연결한다.
 

연결 대화창이 뜨면 연결을 누른다. 이미 아이디와 비밀번호는 기본으로 입력이 되어있으므로 무시한다.



 
약 5초 정도 지나면 VPN연결이 되고 네트워크 및 공유 센터에서 xxx SERVER 엑세스 형식이 인터넷으로 되어 있음을 확인 할 수 있다.



 
VPN 서비스를 즐긴다~