FreeBSD – OpenVPN

작성자 : 김용복 ([email protected]) – 2010/07/21 AM 00:10
원제목 : FreeBSD – OpenVPN 설치
설치순 : OpenSSL – > OpenVPN
설   명 : 가상 사설망(Virtual Private Network)을 FreeBSD에서 오픈소스인 OpenVPN 을 사용하여 VPN 서버를 구축하는 방법입니다.

1. OpenSSL 설치
SSL+VPN을 이용하여 구성 할것이므로 SSL이 필요하기 때문에 설치를 진행하겠습니다.

[root@yongbok ~]# cd /usr/ports/security/openssl && make install clean

2. OpenVPN 설치
OpenVPN을 설치하려면 lzo2 라이브러리가 필요하는데 FreeBSD의 Ports 시스템 특성상 해당 라이브러리가 없으면 자동으로 설치가 되기 때문에 lzo2 라이브러리 설치를 생략하겠습니다.

[root@yongbok ~]# cd /usr/ports/security/openvpn && make install clean

3. vars 환경설정 파일 수정 및 적용
OpenVPN 설치가 완료 되면 키 생성에 필요한 파일들이 /usr/local/share/doc/openvpn 디렉토리에 존재하게 됩니다.
openvpn 설치 디렉토리에 easy-rsa/2.0 디렉토리로 이동하여 vars 파일의 내용 중 맨 아래부분을 알맞게 수정 후 환경설정을 적용 시켜줍니다.

[root@yongbok ~]# cd /usr/local/share/doc/openvpn/easy-rsa/2.0
[root@yongbok ~]# ee vars

# These are the default values for fields
# which will be placed in the certificate.
# Don’t leave any of these fields blank.
export KEY_COUNTRY=”KR”
export KEY_PROVINCE=”NA”
export KEY_CITY=”Seoul”
export KEY_ORG=”Admin : Kim, Yong-Bok”
export KEY_EMAIL=”[email protected]

[root@yongbok ~]# source vars
WARNING: can’t open config file: /usr/local/openssl/openssl.cnf
NOTE: If you run ./clean-all, I will be doing a rm -rf on /usr/local/share/doc/openvpn/easy-rsa/2.0/keys
[root@yongbok ~]# ./clean-all

4. 서버용 key 파일 생성
ca.crt, ca.key 를 생성 해줍니다.

[root@yongbok ~]# ./build-ca
WARNING: can’t open config file: /usr/local/openssl/openssl.cnf
Generating a 1024 bit RSA private key
….++++++
……………………++++++
writing new private key to ‘ca.key’
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [KR]:
State or Province Name (full name) [NA]:
Locality Name (eg, city) [Seoul]:
Organization Name (eg, company) [Admin :Kim, Yong-Bok]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server’s hostname) [Admin :Kim, Yong-Bok CA]:
Name []:
Email Address [[email protected]]:

서버로 사용 될 key 파일을 생성 해줄때 마지막에 물어보는 2가지 항목에서 y 를 눌러 동의 하고 넘어 갑니다.

[root@yongbok ~]# ./build-key-server server

WARNING: can’t open config file: /usr/local/openssl/openssl.cnf
Generating a 1024 bit RSA private key
………………………………..++++++
…++++++
writing new private key to ‘server.key’
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [KR]:
State or Province Name (full name) [NA]:
Locality Name (eg, city) [Seoul]:
Organization Name (eg, company) [Admin :Kim, Yong-Bok]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server’s hostname) [server]:
Name []:
Email Address [[email protected]]:

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:yongbok.net
WARNING: can’t open config file: /usr/local/openssl/openssl.cnf
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName           :PRINTABLE:’KR’
stateOrProvinceName   :PRINTABLE:’NA’
localityName          :PRINTABLE:’Seoul’
organizationName      :PRINTABLE:’Admin :Kim, Yong-Bok’
commonName            :PRINTABLE:’server’
emailAddress          :IA5STRING:’[email protected]
Certificate is to be certified until Jul 17 13:53:08 2020 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

5. 클라이언트용 key 파일 생성
VPN을 사용할 클라이언트의 key 파일을 생성합니다. 이것 역시 마지막 부분에 동의 하는 부분에 대해서 y 를 눌러 주세요.

[root@yongbok ~]# ./build-key ruo91

WARNING: can’t open config file: /usr/local/openssl/openssl.cnf
Generating a 1024 bit RSA private key
………++++++
…………………………………………++++++
writing new private key to ‘ruo91.key’
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [KR]:
State or Province Name (full name) [NA]:
Locality Name (eg, city) [Seoul]:
Organization Name (eg, company) [Admin :Kim, Yong-Bok]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server’s hostname) [ruo91]:
Name []:
Email Address [[email protected]]:

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:yongbok.net
WARNING: can’t open config file: /usr/local/openssl/openssl.cnf
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName           :PRINTABLE:’KR’
stateOrProvinceName   :PRINTABLE:’NA’
localityName          :PRINTABLE:’Seoul’
organizationName      :PRINTABLE:’Admin :Kim, Yong-Bok’
commonName            :PRINTABLE:’ruo91′
emailAddress          :IA5STRING:’[email protected]
Certificate is to be certified until Jul 17 13:55:38 2020 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

6. pem 파일 생성

[root@yongbok ~]# ./build-dh
WARNING: can’t open config file: /usr/local/openssl/openssl.cnf
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
…………………………….+………+..+……………………………………………………………………………………………………………………..+…………………………………………………………+…+………………………+………………………..+……………………………………+………………………………………………….+…….+……………………………………..+…..+…………………+………………………….+…………………………………….+………………………+………………..+…………………………+……………………………+..+………………………………+…………………………………………..+……………..+………………………………………………………+………………………………..+……+………………………………………+…………………………..+……………………………………….+………………………………………………………………………….+………………………………….+………………………………………………….+……………+……………………..+…..+………………………………………+………………………+………………+……………………………….+………………………………………………..+……….+…………………………….+……………………………………………………………………………….+…………………….+……+……………………+…………………………………..+…………………………+………..++*++*++*

7. key 폴더 이동

[root@yongbok ~]# mv /usr/local/share/doc/openvpn/easy-rsa/2.0/keys /usr/local/etc/openvpn

8. OpenVPN 설정
FreeBSD에서 Ports를 이용해서 설치하면 기본 환경설정 파일들은 /usr/local/etc 디렉토리 안에 존재하게 됩니다. OpenVPN은 이상하게.. openvpn 이라는 디렉토리를 하나 만든 후 거기에 openvpn.conf 설정 파일을 만들어 사용해야 합니다. (물론 꼭 openvpn을 만들지 않아도 /usr/local/etc/rc.d/openvpn 쉘 스크립트를 수정해서 강제로 /usr/local/etc 로 지정 가능합니다.)

[root@yongbok ~]# mkdir /usr/local/etc/openvpn
[root@yongbok ~]# ee /usr/local/etc/openvpn/openvpn.conf

# vpn 서버로 사용할 포트를 지정 합니다. (기본은 1194)
port 1194
# TCP 프로토콜을 사용합니다.
proto tcp
# tun, tap 타입
dev tun
# 위에서 생성한 key 파일의 경로를 지정해줍니다.
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
# VPN 클라이언트가 사용할 아이피 대역을 지정해줍니다.
# 아래 처럼 지정 해주시면 10.10.10.0 ~ 10.10.10.254 처럼 C클래스가 DHCP로 할당 됩니다.
server 10.10.10.0 255.255.255.0
# 클라이언트에 아이피를 할당시 DNS 서버를 지정 해줍니다.
# VPN 자체의 DNS 서버가 있다면 더욱 좋습니다.
push “dhcp-option DNS 168.126.63.1″
push “dhcp-option DNS 168.126.63.2″
push “dhcp-option DNS 8.8.8.8″
push “dhcp-option DNS 8.8.4.4″
# 만약 VPN 클라이언트의 네트워크 환경이 10.10.10.0 대역의 아이피가 존재 한다면
# 자동으로 11.11.11.0/24 대역으로 변경해서 할당 받게 해줍니다.
push “route 11.11.11.0 255.255.255.0″
# 머무르는 시간입니다.
keepalive 10 120
# 암호화 해서 보낼꺼냐.. 하는듯..?
comp-lzo
# 사용자/그룹을 nobody 로 VPN 서버를 실행합니다.
user nobody
group nobody
#
persist-key
persist-tun
# VPN 서버 로그를 활성화 합니다.
status openvpn-status.log
log openvpn.log
log-append openvpn.log
verb 3
client-to-client
duplicate-cn

OpenVPN이 실행 될수 있도록 rc.conf 파일에 등록을 해줍니다.

[root@yongbok ~]# echo “openvpn_enable=\”YES\”” >> /etc/rc.conf

OpenVPN을 시작 합니다.

[root@yongbok ~]# /usr/local/etc/rc.d/openvpn start
Starting openvpn.

9. 클라이언트 설정
OpenVPN GUI 프로그램을 아래 주소에서 다운로드 합니다.

http://openvpn.se/download.html

설치 과정은 생략하며 보통 Next 버튼을 눌러 설치를 완료 하시면 됩니다.

4, 5 번 과정에서 생성한 ca.crt(서버용), ruo91.crt(클라이언트용), ruo91.key(클라이언트용) 파일을 안전하게 받아 C:\Program Files\OpenVPN\config 경로에 이동 시킵니다.
서버와 연결을 위한 설정파일을 C:\Program Files\OpenVPN\sample-config 폴더에 가서 client.ovpn 파일을 config 폴더로 복사 해옵니다.


시계쪽 트레이 부분에 빨간 모니터 두개에 오른쪽 마우스 클릭하시고 Edit Config 를 누르시면 메모장으로 편집할수 있는 상태가 됩니다.
client.ovpn 파일의 내용을 아래와 같이 사용자 환경에 맞게 수정 해주세요.

# 클라이언트로 설정
client
#
dev tun
# TCP 프로토콜 사용
proto tcp
# VPN 서버의 도메인주소 또는 아이피주소 와 포트를 설정
# remote VPN서버 포트
remote vpn.example.com 1194

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server.  Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don’t need to bind to
# a specific local port number.
nobind

# Try to preserve some state across restarts.
persist-key
persist-tun
# 사용자 키 파일 경로 지정
ca ca.crt
cert ruo91.crt
key ruo91.key
#
comp-lzo
#
# Set log file verbosity.
verb 3

수정 완료가 됐으면 시계 쪽 트레이의 빨간색 모니터 두개가 그려진 아이콘을 더블클릭 하시면 VPN 서버로 접속 연결을 시도 하게 됩니다.

연결이 정상적으로 성립이 되면 파란색으로 나타나며 VPN 서버와 클라이언트간에 패킷이 암호화 되어 전송 됩니다.
※ 전체 트래픽을 VPN 서버로 라우팅 하고자 할때..
보통 위의 방식으로 VPN 서버를 구성할 경우 클라이언트와 VPN 서버로 통과하는 것만 암호화가 진행 됩니다.
회사 컴터1  <—— VPN 서버 ——> Cyworld 접속
따라서, 컴터2에서 사용하는 사람이 컴터1에 대한 트래픽을 스니핑 하게 된다면 VPN 서버 있으나 마나가 되는 상황이 벌어집니다.

클라이언트의 전체 트래픽을 VPN 서버로 통과시켜 주면 됩니다.

openvpn.conf 설정 파일에 아래 구문을 추가 합니다.

[root@yongbok ~]# ee /usr/local/etc/openvpn/openvpn.conf
# 전체 패킷 VPN 으로 암호화
push “redirect-gateway def1″

VPN 서버에 트래픽을 통과 시켜 주기 위해서 IP 포워딩과 NAT 을 사용하도록 설정 해줘야 합니다. 두개다 사용하려면 커널 컴파일이 필요 합니다.

[root@yongbok ~]# cp /usr/sys/i386/conf/GENERIC /usr/sys/i386/conf/ruo91
[root@yongbok ~]# ee /usr/sys/i386/conf/ruo91
options IPFIREWALL                                      # IPFW 활성화 필수 옵션
options IPFIREWALL_VERBOSE                      # IPFW 의 syslogd(8)을 통해 로그를 출력하도록 해줍니다.
options IPFIREWALL_VERBOSE_LIMIT=100      # IPFW 의 패킷 메시지의 한도를 정해줍니다.
options IPFIREWALL_FORWARD                     # IPFW 의 패킷 전송 기능을 사용할 수 있도록 합니다.
options IPFIREWALL_DEFAULT_TO_ACCEPT  # IPFW 모든 패킷 전송을 허용합니다.
options IPDIVERT

커널 컴파일

[root@yongbok ~]# cd /usr/src
[root@yongbok ~]# make buildkernel KERNCONF=ruo91 ; make installkernel KERNCONF=ruo91

IP 포워딩과 NAT을 활성화 시켜 줍니다.

[root@yongbok ~]# echo “gateway_enable=\”YES\”” >> /etc/rc.conf
[root@yongbok ~]# echo “natd_enable=\”YES\”” >> /etc/rc.conf
[root@yongbok ~]# echo “natd_interface=\”fxp0\”” >> /etc/rc.conf

재부팅 하고 클라이언트에서 VPN 연결을 합니다.

[root@yongbok ~]# reboot

기본 게이트웨이 주소를 확인 해보면 VPN 서버로부터 할당 받은 아이피가 보이며 모든 트래픽은 VPN 서버를 통해 나가기 때문에 보안면에서 좋기는 하나 속도가 약간 느릴수 있습니다.