외부 네트워크(192.168.25.*)와 내부 네트워크(10.10.*.*)가 분리된 상황에서 내부 네트워크의 머신들이 wget이나 패키지 설치 등의 외부(인터넷) 접속을 통한 작업을 진행할 경우의 routing, ip forwarding 을 설정하는 과정에 대해 정리한다. 이러한 기능의 핵심이 되는 서버는 그림에서 보듯이 NAT router이다(참고: 본 테스트의 수행은 Ubuntu 14.4 LTS, Xen host 상에서, 여러 개의 ubuntu guest vm들을 생성하여 진행하였다).


1. Gateway 서버와 내부 서버의 NIC 설정


* gw1(NAT router, 여기서의 서버 이름은 ubuntu14-pvha1) 서버는 2 개의 네트워크 인터페이스(NIC)을 가진다

 - eth0, ip:192.168.25.201/24, internet gw ip:192.168.25.1(인터넷공유기-라우터의 외부게이트웨이)

 - eth1, ip:10.0.0.1/16


* n개의 내부서버(여기서의 서버 이름은 ubuntu14-pv1~ 4)는 각각 1개씩의 네트워크 인터페이스를 가진다

 - Netmask 는 255.255.0.0 즉 /16 이므로 gw1의 eth1 과 동일 네트워크가 된다

 - eth0, ip:10.0.10.1 ~ 10.0.10.4/16, gateway ip:10.0.0.1


* 그림에 걸맞는 상황을 설정하기 위해 각 서버의 NIC의 ip 주소를 static으로 설정한다. ifconfig 명령을 쓸 수도 있지만, 리부트 후에도 계속 작동하도록 config file을 직접 수정한다(NIC이 여러 개일지라도 gateway 는 1개만 존재해야 함에 유의).

root@ubuntu14-pvha1:~# vi /etc/network/interfaces

# The loopback network interface

auto lo

iface lo inet loopback


# The primary network interface

auto eth0

#iface eth0 inet dhcp

iface eth0 inet static

address 192.168.25.201

netmask 255.255.255.0

network 192.168.25.0

broadcast 192.168.25.255

gateway 192.168.25.1

dns-nameservers 8.8.8.8


# The secondary network interface

auto eth1

iface eth1 inet static

address 10.0.0.1

netmask 255.255.0.0

network 10.0.0.0

broadcast 10.0.255.255


root@ubuntu14-pv4:~# vi /etc/network/interfaces
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
#iface eth0 inet dhcp
iface eth0 inet static
address 10.0.10.4
netmask 255.255.0.0
network 10.0.0.0
broadcast 10.0.255.255
gateway 10.0.0.1
dns-nameservers 8.8.8.8

* 각 서버들의 NIC 설정을 마친 후 /etc/init.d/networking restart 또는 reboot 를 한 후 내부 외부에 대한 접속이 가능한지를 ping test 해 본다. 당연히 2개의 NIC을 통해 외부 및 내부와의 접속이 모두 가능하다.

root@ubuntu14-pvha1:~# ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

64 bytes from 8.8.8.8: icmp_seq=1 ttl=52 time=36.0 ms

64 bytes from 8.8.8.8: icmp_seq=2 ttl=52 time=35.5 ms ...


root@ubuntu14-pvha1:~# ping 10.0.10.4

PING 10.0.10.4 (10.0.10.4) 56(84) bytes of data.

64 bytes from 10.0.10.4: icmp_seq=1 ttl=64 time=0.351 ms

64 bytes from 10.0.10.4: icmp_seq=2 ttl=64 time=0.517 ms ...


* n개의 내부서버 중 4번에서 외부로 ping test 를 수행해 본다. ping 수행이 실패한다. 다음 단계에서 해결해 보자.

root@ubuntu14-pv4:~# ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

^C

--- 8.8.8.8 ping statistics ---

11 packets transmitted, 0 received, 100% packet loss, time 10078ms


2. NAT Router 설정, 그리고 테스트


* NAT router 서버에서 다음과 같은 과정을 거쳐 설정을 진행한다

root@ubuntu14-pvha1:~# modprobe iptable_nat -> iptable_nat 커널모듈의 사용을 가능하게 한다


root@ubuntu14-pvha1:~# vi /etc/sysctl.conf -> 아래 라인을 찾아 comment 를 해제한다

net.ipv4.ip_forward=1


root@ubuntu14-pvha1:~# sysctl -p (또는 리부트, 변경된 Kernel 옵션을 작동시킴)

* echo 1 > /proc/sys/net/ipv4/ip_forward 로 명령어를 통해 설정할 수도 있으나, 리부트시에는 설정이 사라지므로 여기서는 사용하지 않는다.


root@ubuntu14-pvha1:~# cat /proc/sys/net/ipv4/ip_forward ->설정 값이 1인지 확인

1


root@ubuntu14-pvha1:~# vi /etc/rc.local (부팅 후 최종 수행 script, 아래 2개 라인을 추가, 완료시 리부트)

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

iptables -A FORWARD -i eth1 -j ACCEPT


* 내부서버에서 외부로 접속이 가능한지 최종 테스트를 해 본다

  (참고: /etc/network/interfaces 에서 gateway 를 잡지 않았다면 route add default gw 10.0.0.1 로 따로 잡아 주어야 한다)

root@ubuntu14-pv4:~# ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

64 bytes from 8.8.8.8: icmp_seq=1 ttl=51 time=36.2 ms

64 bytes from 8.8.8.8: icmp_seq=2 ttl=51 time=36.0 ms

^C

--- 8.8.8.8 ping statistics ---

2 packets transmitted, 2 received, 0% packet loss, time 1001ms

rtt min/avg/max/mdev = 36.099/36.172/36.246/0.203 ms


root@ubuntu14-pv4:~# wget www.naver.com

--2015-06-30 17:31:58--  http://www.naver.com/

Resolving www.naver.com (www.naver.com)... 202.179.177.22, 125.209.222.141

Connecting to www.naver.com (www.naver.com)|202.179.177.22|:80... connected.

HTTP request sent, awaiting response... 200 OK

Length: unspecified [text/html]

Saving to: ‘index.html’


    [ <=>                                                                           ] 82,478      --.-K/s   in 0.008s  


2015-06-30 17:31:58 (10.3 MB/s) - ‘index.html’ saved [82478]


[관련 글]

2015/06/28 - [Xen 가상화 2] ubuntu pv guest on Ubuntu 14.4 LTS, Xen 4.4.1 - 설치 및 설정 가이드

2015/07/01 - Haproxy, Keepalived, nginx 를 이용한 고가용성(High Availablity) 웹서비스 환경 구현



- Barracuda -


블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요


Python을 활용한 GUI 프로그래밍에 꼭 한 번씩 거론되는 것이 있다. 오픈소스 프로젝트로서, Python을 위한 C++바인딩인 PySide 프로젝트가 그것이다. 참고로, 기존의 PyQt4에는 API Level 1과 API level 2 가 각각 존재하고 있으며, 그에 비해 PySide는 PyQt API level 2 만을 고려하여 구현되어 있다(PySide 쪽이 LGPL[각주:1]이 적용되어 PyQt 보다 저작권 면에서 더 자유롭다...정도만 얘기하고, Qt의 역사나 핀란드의 노키아, 디지아 등 잡다한 궁금한 점들은 구글링으로 해결하자).


서두가 너무 길었다. 간단히 글 게재의 목적만 말하자면, PySide 1.2.1 버전은 대다수 리눅스 배포판 등의 소프트웨어 다운&설치 명령들(yum, zypper, apt-get 또는 pip)로 간단히 설치, 사용이 가능하다. 하지만 2015년 6월 현재 최신 1.2.2 버전(2014년 4월 릴리즈. 1.2.1은 2013년 8월 릴리즈)은, 공식페이지(pyside.readthedocs.org)에서도 "Linux 바이너리는 제공하지 않음" 이라고 발표하고 있는 실정이다.


뵨 글에서는 Windows 와 Linux 에서의  Python 2.7.x 를 위한 PySide 1.2.2 설치 방법에 대해 정리해 두도록 한다.


Windows 7에 PySide 1.2.2 설치 과정 & 주의사항


Windows에서는 특별히 어려운 점은 없다. Python 2.7.x 이 기존에 설치되어 있다고 가정하고, PyQt 4.10.3 for python 2.7 을 설치하면 된다(참고로, 각종 windows 용 python extensions 들은 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 로 가면 거의 찾을 수 있으며, python 버전에 맞는 바이너리를 다운로드 받아 자유롭게 사용 가능하다).


get-pip.py 다운로드c:\python2\scripts 에 저장하고 pip 설치. pip로 PySide 를 설치하면 간단히 끝.

C:\> mkdir c:\python2\scripts

C:\> CD c:\python2\scripts

C:\> python get-pip.py

C:\> ./pip install -U PySide


Linux에 PySide 1.2.2 설치하는 방법


구글링 해 보면 다양한 방법들이 존재하고 있다. 어떤 리눅스 배포판에서는 자체 공식 repo 를 통해서도 간단히 설치할 수도 있겠고, Python 관련 사이트에서 설치 바이너리(deb, rpm 등) 다운로드 받아 설치할 수도 있겠다. 여기서는 소스 다운로드 & 빌드를 통해 설치하는 방법만을 다룰텐데, 대다수의 내용은 가장 정평한 pyside.readthedocs.org 에 있는 내용을 거의 그대로 참조하였다.


* Source Build 를 위한 준비 과정

$ sudo apt-get install build-essential git cmake libqt4-dev libphonon-dev python2.7-dev libxml2-dev libxslt1-dev qtmobility-dev


* Python 2.7 용 pip 를 다운로드 & 설치. Build를 위한 wheel 설치

$ mkdir ~/PySideBuild; cd ~/PySideBuild;

$ wget https://bootstrap.pypa.io/get-pip.py

$ sudo python2.7 get-pip.py

$ sudo pip2.7 install wheel


* PySide 1.2.2 다운로드 & Build

$ wget https://pypi.python.org/packages/source/P/PySide/PySide-1.2.2.tar.gz

$ tar -xvzf PySide-1.2.2.tar.gz

$ cd PySide-1.2.2

$ python2.7 setup.py bdist_wheel --qmake=/usr/bin/qmake-qt4


* Build 된 배포 바이너리 설치 & 확인

$ ls -l dist

합계 12616

-rw-rw-r-- 1 bryan bryan 12916258  6월 13 18:00 PySide-1.2.2-cp27-none-linux_x86_64.whl

$ sudo pip2.7 install dist/PySide-1.2.2-cp27-none-linux-x86_64.whl



설치 완료된 PySide 정상 작동 확인


$ python

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 

[GCC 4.8.2] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> import PySide

>>> PySide.__version__

'1.2.2'

>>>



- Barracuda -



  1. GPL과는 달리, LGPL은 소스를 공개하지 않고도 상용프로그램을 만들 수 있다. [본문으로]
블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요


Linux host에서 가상화 지원 솔루션 중 VirtualBox를 설치하고 사용하는 경우에, 특히 OpenSuse 12.x 환경에서 virtualbox 를 설치하고, VM을 사용하고자 할 경우(ubuntu 등 기타 linux에서도 비슷하게 적용될 듯)에 주의 사항이 있다.


virtualbox를 https://www.virtualbox.org/wiki/Downloads 에서 다운로드 받고 설치, VirtualBox 기동 후 extpack 까지 설치하고 난 후, virtualbox 메뉴에서 vm을 생성하고 머신을 시작하려고 하면 "virtualbox kernel driver not installed (rc=-1908)" 라는 메시지 창이 뜨고 '/etc/init.d/vboxdrv setup' 을 실행하라고 경고창이 뜨게 된다. 이제 터미널 창에서 '/etc/init.d/vboxdrv setup' 이라고 실행하게 되는데......


이 때, 만약 커널 소스가 linux 에 설치되어 있지 않다면

/etc/init.d/vboxdrv setup

Stopping VirtualBox kernel modules          done

Recompiling VirtualBox kernel modules     failed

라고 오류가 발생되고 더 이상 진행이 되지 않는다. 또 경고창에 나타난 대로 아래와 같이 log를 조회해 보면 오류가 나타남을 알 수 있다.

# cat /var/log/vbox-install.log

Makefile: 181:  *** Error: unable to find the source of your current linux kernel. Specify KERN_DIR=<directorty> and run Make again. Stop.

...

 

이는, virtualbox가 설치되면 kernel module을 로드하기 위해서 해당 커널모듈을 컴파일하게 되는데, 커널 소스가 설치되지 않은 경우에 만날 수 있는 에러 상황이다.


터미널 명령으로 아래와 같이 실행하면 문제를 해결할 수 있다(root 권한으로 실행, 아래는 Suse 계열의 linux에 대한 명령이며, OS에 맞춰 yum, apt-get 과 같은 패키지 설치 명령을 사용하면 된다)

# zypper search kernel-source (=> OS에 따라 kernel-sources 로 나타나는 경우도 있음)

# zypper refresh

# zypper in -y kernel-source

# /etc/init.d/vboxdrv restart

# /etc/init.d/vboxdrv setup

Stopping VirtualBox kernel modules            done

Recompiling VirtualBox kernel modules       done

Starting VirtualBox kernel modules              done


블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요


이 부분을 이해 하려면 Unix의 RunLevel에 대해 알아야 한다.

기본적으로 Unix 계열의 OS는 아래의 7개 모드로 구분된 Run level을 가진다
 0 - Halt status
 1 - Single User
 2 - Multi User, No Networking
 3 - Multi User, Full Networking
 4 - Reserved
 5 - 3 & X windows
 6 - Restarting status

위 각각의 상태로 시스템이 전환될 때 자동적으로
/etc/rc.d/rc?.d/ 의 스타일로 7개의 서브 dir 이 준비되어 있고
각각의 디렉토리내에는 S??scriptname, K??scriptname 형태의 파일들이 존재하는데
S는 start, K는 kil, ??의 숫자는 해당 모드로 진입했을때의 실행순서이고
scriptname은 실행되어야 할 스크립트 파일의 이름이다. 일반적인 Daemon들의 실행방식이라면
scriptname start | stop | restart 의 형식으로 동작될 것이다.

예를 들어 aaa 라는 프로그램을 만들고 이를 실행, 중지, 재기동할 수 있는 script를 runaaa 라고 만들었다면, 이 runaaa 라는 파일을 /etc/init.d(Debian계열, ubuntu 등) 또는 /etc/rc.d/init.d(RH계열, cent등)에 복사하고 ln 명령으로 symbolic link를 /etc/rc?.d/S99runaaa 내에 생성한다. 99는 rc?.d 디렉토리의 기존 스크립트 번호를 기준으로 설정자 판단에 따라 결졍하는 순서 값이다.

실제로는 아래의 7개 link 명령을 root 계정으로 수행한다.
# ln -s /etc/init.d/runaaa /etc/rc0.d/K99runaaa
# ln -s /etc/init.d/runaaa /etc/rc1.d/K99runaaa
# ln -s /etc/init.d/runaaa /etc/rc2.d/S99runaaa
# ln -s /etc/init.d/runaaa /etc/rc3.d/S99runaaa
# ln -s /etc/init.d/runaaa /etc/rc4.d/S99runaaa
# ln -s /etc/init.d/runaaa /etc/rc5.d/S99runaaa
# ln -s /etc/init.d/runaaa /etc/rc6.d/K99runaaa
즉 위의 설정으로 runlevel 0, 1, 6일때는 Kill을, 2, 3, 4, 5 일때는 Start를 시스템에서 자동으로 수행시켜 준다

이 과정을 자동으로 해 주는 시스템유틸리티가 chkconfig 이다. 즉 /etc/init.d에 runaaa 스크립트를 복사한 상태에서
# chkconfig --add runaaa
를 수행하면 별도로 위에서처럼 symbolic link 를 수행해주지 않아도 된다. 아래와 같이 확인 해 보자
# chkconfig --list | grep runaaa

만약 chkconfig가 시스템에 설치되어 있지 않다면 yum 또는 apt-get 으로 설치하여 사용한다
# sudo apt-get install chkconfig


블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요