· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
OpenVPN/Solaris

Solaris 10 에서 openvpn 서버 설치하기


최근 solaris 환경에 openvpn 서버를 설치할 기회가 있었는데, linux 에서와는 달리 약간의 삽질이 필요했습니다. 배포본으로부터 바이너리 및 설치 스크립트를 제공받을 수 없어서, /dev/tun 장치 파일 생성이나 ip forwarding / NAT 설정에서 조금 메모해 둘 필요가 있다고 생각되어 아래 내용을 보충해 둡니다.

작업했던 환경은 solaris 10 입니다. solaris 9 이하에서도 ip filter 설치 이외에 특별한 차이는 없습니다.
# uname -a
SunOS tomoko 5.10 Generic_127127-11 sun4v sparc SUNW,SPARC-Enterprise-T5220 Solaris

openvpn 바이너리 및 tun 드라이버 생성


본문의 [http]1.4.1 설치하기 에 해당되는 내용입니다.

우선 openvpn 소스코드에서 컴파일하지 않으면 되지 않으므로, http://www.sunfreeware.com/ 에서 gcc, libtool 등을 설치하여 기본적인 컴파일 환경을 갖추어야 합니다. 또한 openvpn 컴파일시에 필요한 openssl, lzo 라이브러리도 미리 설치해 두기로 합니다. 각 패키지가 동작하기 위한 의존성이 걸린 패키지도 설치되어 있지 않다면 함께 설치해 주세요.
# gzip -d gcc-3.4.6-sol10-sparc-local.gz
# pkgadd -d ./gcc-3.4.6-sol10-sparc-local
...
# pkgadd -d ./openssl-0.9.8h-sol10-sparc-local
# pkgadd -d ./lzo-2.03-sol10-sparc-local

이제 openvpn 소스코드를 컴파일하게 되는데, solaris 10 에는 /dev/tun 장치가 생성되어 있지 않으므로, 그냥 진행하면 아래와 같은 오류를 내면서 컴파일이 중단됩니다.
tun.c:1183:2: #error I need the symbol TUNNEWPPA from net/if_tun.h
tun.c: In function `open_tun':
tun.c:1245: error: `TUNNEWPPA' undeclared (first use in this function)
tun.c:1245: error: (Each undeclared identifier is reported only once
tun.c:1245: error: for each function it appears in.)
make[1]: *** [tun.o] Error 1
make[1]: Leaving directory `/data/pkg/openvpn/openvpn-2.0.9'

따라서 openvpn 설치 전에 미리 tun 드라이버를 생성해 둡니다. solaris 설치 시디에서 드라이버를 설치할 수 있을 것 같기도 한데, 귀찮기도 하거니와 방법도 잘 모르겠고 해서 구글링한 결과, 아래와 같은 해결책을 찾았습니다.

# wget http://vtun.sourceforge.net/tun/tun-1.1.tar.gz
# zcat tun-1.1.tar.gz | tar xvf -
# cd tun-1.1/solaris
# perl -pi~ -e 's;"TUN/TAP driver .*;"TUN/TAP driver 1.1",;' tun.c
# perl -pi~ -e 's/#define TUNSETPPA.*/$&\n\n#define TUN_VER "1.1"/' if_tun.h
# gcc -O2 -Wall -D_KERNEL -I. -m64 -mcpu=ultrasparc -c tun.c
# /usr/ccs/bin/ld -r -o tun tun.o
# file tun
tun:            ELF 64-bit MSB relocatable SPARCV9 Version 1, UltraSPARC1 Extensions Required
# cp tun /usr/kernel/drv/sparcv9/tun
# cp tun.conf /usr/kernel/drv/tun.conf
# cp if_tun.h /usr/include/net/if_tun.h
# chmod 755 /usr/kernel/drv/sparcv9/tun
# chown root:sys /usr/kernel/drv/sparcv9/tun /usr/kernel/drv/tun.conf
# chown root:bin /usr/include/net/if_tun.h
# rem_drv tun
# add_drv -v tun
# ls -als /dev/tun
1 lrwxrwxrwx 1 root sys 29 Oct 22 11:03 /dev/tun -> ../devices/pseudo/clone@0:tun

사용하는 장비의 아키텍처에 따라 gcc 옵션 및 tun 드라이버 설치 위치를 적절히 변경하면 되겠습니다. 제대로 되었다면 /dev/tun 캐릭터 디바이스가 생성됩니다.

다음으로 openvpn 소스코드 컴파일입니다. openssl 및 lzo 라이브러리 위치를 지정해 줄 필요가 있습니다. 아마도 LD_LIBRARY_PATH 에도 지정이 되어 있어야 할 것 같습니다. (귀찮아서 미확인)
# env | grep PATH
LD_LIBRARY_PATH=/usr/local/lib:/usr/local/ora:/usr/local/ssl/lib:/usr/openwin/lib:...
PATH=/usr/local/bin:/usr/local/ssl/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/ccs/bin:...
# ./configure --with-ssl-headers=/usr/local/ssl/include --with-ssl-lib=/usr/local/ssl/lib
# make
# make install
# ls -als /usr/local/sbin/openvpn
1504 -rwxr-xr-x 1 root root 1525160 Oct 22 14:57 /usr/local/sbin/openvpn

openvpn 기동시에 LD_LIBRARY_PATH 지정하는 것이 귀찮다면, 바이너리를 링크할 때 rpath 지정해 주면 편리합니다. solaris ld 는 rpath 지정하는 옵션이 -R 입니다. rpath 지정하는 것이 나쁘다는 의견도 있으므로 아래는 참고로 하시면 되겠습니다.
# gcc  -g -O2  -L/usr/local/ssl/lib -R /usr/local/lib:/usr/local/ssl/lib -o openvpn            \
    base64.o buffer.o  crypto.o error.o event.o  fdmisc.o forward.o fragment.o  gremlin.o      \
    helper.o init.o  interval.o list.o lzo.o  manage.o mbuf.o misc.o  mroute.o mss.o mtcp.o    \
    mtu.o  mudp.o multi.o ntlm.o occ.o  openvpn.o options.o otime.o  packet_id.o perf.o ping.o \
    plugin.o pool.o proto.o  proxy.o push.o reliable.o  route.o schedule.o session_id.o        \
    shaper.o sig.o socket.o  socks.o ssl.o status.o  thread.o tun.o                            \
    -lssl -lcrypto -llzo2 -lnsl -lsocket
# env | grep LD_LIBRARY_PATH
(nothing found)
# ldd openvpn
        libssl.so.0.9.8 =>       /usr/local/ssl/lib/libssl.so.0.9.8
        libcrypto.so.0.9.8 =>    /usr/local/ssl/lib/libcrypto.so.0.9.8
        liblzo2.so.2 =>  /usr/local/lib/liblzo2.so.2
        libnsl.so.1 =>   /lib/libnsl.so.1
        libsocket.so.1 =>        /lib/libsocket.so.1
        libc.so.1 =>     /lib/libc.so.1
        libdl.so.1 =>    /lib/libdl.so.1
        libgcc_s.so.1 =>         /usr/local/lib/libgcc_s.so.1
        libmp.so.2 =>    /lib/libmp.so.2
        libmd.so.1 =>    /lib/libmd.so.1
        libscf.so.1 =>   /lib/libscf.so.1
        libdoor.so.1 =>  /lib/libdoor.so.1
        libuutil.so.1 =>         /lib/libuutil.so.1
        libgen.so.1 =>   /lib/libgen.so.1
        libm.so.2 =>     /lib/libm.so.2
        /platform/SUNW,SPARC-Enterprise-T5220/lib/libc_psr.so.1
        /platform/SUNW,SPARC-Enterprise-T5220/lib/libmd_psr.so.1

ip forwarding / NAT 설정


본문의 [http]1.6.2 서버쪽의 다른 서버들 연결하기 에 해당하는 내용입니다.

solaris 10 을 기준으로 설명합니다. solaris 9 이하에서는 설정을 위한 명령어가 약간 차이가 있습니다.

ip forwarding 기능을 활성화 하기 위하여 routeadm 명령을 사용합니다. -u 옵션으로 다음 부팅시에도 적용되도록 된다고 합니다. (미확인)
# routeadm -u -e ipv4-forwarding
# routeadm
              Configuration   Current              Current
                     Option   Configuration        System State
---------------------------------------------------------------
               IPv4 routing   disabled             disabled
               IPv6 routing   disabled             disabled
            IPv4 forwarding   enabled              enabled
            IPv6 forwarding   disabled             disabled

           Routing services   "route:default ripng:default"
...
# ifconfig -a
lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
        inet 127.0.0.1 netmask ff000000
tun0: flags=10011008d1<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST,ROUTER,IPv4,FIXEDMTU> mtu 1500 index 3
        inet 10.8.0.1 --> 10.8.0.2 netmask ffffffff
        ether 0
e1000g0: flags=1100843<UP,BROADCAST,RUNNING,MULTICAST,ROUTER,IPv4> mtu 1500 index 5
        inet 210.103.xxx.xxx netmask fffffffc broadcast 210.103.xxx.xxx
        ether xx:xx:xx:xx:xx:xx

tun0, e1000g0 인터페이스 상태에 ROUTER 가 추가되었습니다. 상기 설정으로 openvpn 서버는 라우터의 역할을 하게 되고, openvpn 클라이언트로부터 tun0 를 통해 전달받은 패킷을 외부로 뿌려줄 수 있게 됩니다. 하지만 패킷의 source ip 가 openvpn 클라이언트의 사설 ip 인 상태이므로, 클라이언트가 vpn 을 통해 다른 서버와 통신할 수는 없습니다. 따라서 추가적으로 NAT 설정을 해 주어야 합니다.

linux 의 iptables 에 대응하여 solaris 에는 ip filter 가 있습니다. solaris 10 부터는 기본적으로 설치되어 있고, solaris 9 이하에서는 별도로 설치해야 합니다. 설치 방법은 어렵지 않다고 하니 구글의 도움을 받도록 합시다. 설치가 되었다면 nat 설정을 추가하고(ipnat.conf), 설정을 적용할 네트웍 디바이스를 지정합니다(pfil.ap). ipf 설정은 보다 복잡하게 할 수 있지만, 여기서는 openvpn 클라이언트의 주소지(10.8.0.0/24)에서 들어온 패킷을 외부 인터넷(e1000g)으로 연결하도록 간단하게 한 줄만 추가합니다.
# echo "map e1000g0 10.8.0.0/24 -> 0/32" >> /etc/ipf/ipnat.conf
# echo "e1000g -1 0 pfil" >> /etc/ipf/pfil.ap
# ifconfig e1000g0 down
# ifconfig e1000g0 unplumb
# ifconfig e1000g0 plumb
# ifconfig e1000g0 210.103.xxx.xxx netmask 255.255.255.252 up

pfil.ap 설정을 적용하기 위해서는 네트웍 디바이스를 내렸다 올려야 함에 유의하고, 여기까지 되었다면 pfil, ipfilter 서비스를 구동하여 상태를 확인합니다.
# svcadm enable svc:/network/pfil
# svcadm enable svc:/network/ipfilter
# ipf -V
ipf: IP Filter: v4.1.9 (592)
Kernel: IP Filter: v4.1.9
Running: yes
Log Flags: 0 = none set
Default: pass all, Logging: available
Active list: 0
Feature mask: 0x107

openvpn 클라이언트에서 인터넷을 접속할 때 vpn 서버의 ip 가 묻어 나가는 것이 확인되면 완료입니다. :-)

ID
Password
Join
As goatheard learns his trade by goat, so writer learns his trade by wrote.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2008-10-31 08:44:53
Processing time 0.0041 sec