반응형
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
[edit]
openvpn 바이너리 및 tun 드라이버 생성 ¶
본문의 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
[edit]
ip forwarding / NAT 설정 ¶
본문의 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 가 묻어 나가는 것이 확인되면 완료입니다.