노트북에 서로 다른 사설IP 대역(노트북의 랜카드와 동일한 브리징 네트워크의 IP가 아닌, 내부 사설 네트워크)로 가상네트워크를 구성해서 VM을 만들 경우가 있다. 이 경우 대개 고정IP와 함께 고정된 default gateway를 설정하게 되는데, 사무실과 집을 오가다 보면 매번 VM들의 default gateway를 변경해 주어야 한다.


이런 번거로움을 피하기 위해 VirtualBox 내에 Vyatta Router VM을 만들고, 각 VM들의 사설 IP대역에 맞는 interface(eth1, eth2, eth3, ...)를 각각 설정한 다음, VM에서는 Vyatta Router의 interface IP를 default gateway 로 설정해 둔다. 물론 Vyatta Router의 eth0는 인터넷이 가능한 IP 대역으로 Bridged Network로 구성하고, eth1/eth2/eth3 으로부터 eth0로 라우팅을 해 주어야 각 VM에서 Vyatta Router를 통해 외부로 접속이 가능할 것이다.


이 방법을 응용한다면 VMWare용 Vyatta Router Virtual Appliance나 다른 가상화 솔루션들을 사용할 경우나, Vyatta Router를 사용한 간단한 내부 네트워크를 동적으로 구성할 때도 도움이 될 만 하겠다.


아래에 그 방법에 대해 정리해 둔다.




Vyatta Router VM의 설치


  • Vyos.io 사이트에서 http://packages.vyos.net/iso/release/1.1.7/ 로 접속하여 iso 파일(vyos-1.1.7-amd64.iso)을 다운로드
    - 필요에 따라 다른 iso를 골라서 설치 사용하거나 ova 파일 자체를 appliance로 올려서 쓸수도 있다 
  • Virtual Box에서 linux 머신(CPU1, Ram 512, Disk 2GB)을 생성하고 ISO파일을 CD에 장착하고 Vyatta OS를 설치
    - VirtualBox에서의 VM 생성과 설치 방법에 대해서는 따로 설명하지 않는다
  • 사용할 네트워크에 맞게 네트워크 장치(NIC)를 생성한다. 위 그림에서와 같이 작업을 하려면 다음의 구성정보와 그림을 참고한다
    - 어댑터1: 브리지 어댑터, 무작위 모드: 모두 허용
    - 어댑터2, 3, 4: 호스트 전용 어댑터(사전에 만든 호스트 전용 네트워크 이름 지정, vboxnet0), 무작위 모드: 모두 또는 가상머신에 허용, 어댑터종류:아무거나...반가상네트워크도 가능)


어댑터2,3,4는 모두 동일하게 설정



Vyatta Router Interface 및 라우팅 설정



  • Vyos 설치가 완료되고 리부트한 후, 기본 설정된 관리자 계정 vyos(암호: vyos) 로 로그인한다
  • 초기 설정에 대해 configure, set 등의 명령으로 각각 인터페이스 생성과 설정을 수행하고 확인한다. configure 이후의 설정을 저장하려면 commit 다음에 save 를 반드시 하여야 한다

vyos@vyos:~$ configure

vyos@vyos:~$ set interfaces ethernet eth0 description OUTSIDE

vyos@vyos:~$ set interfaces ethernet eth0 address 192.168.0.201/16

vyos@vyos:~$ set system gateway-address 192.168.0.1

vyos@vyos:~$ set system domain-name 8.8.8.8

vyos@vyos:~$ set service ssh port '22'

vyos@vyos:~$ commit

vyos@vyos:~$ save

Saving configuration to '/config/config.boot'...

vyos@vyos:~$ exit

vyos@vyos:~$ show interfaces
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface        IP Address                        S/L  Description
---------        ----------                        ---  -----------
eth0             192.168.0.201/16                  u/u  OUTSIDE
lo               127.0.0.1/8                       u/u  
                 ::1/128
vyos@vyos:~$ 
vyos@vyos:~$ configure
vyos@vyos:~$ set interfaces ethernet eth1 description 10-NETWORK
vyos@vyos:~$ set interfaces ethernet eth1 10.255.10.1/24
vyos@vyos:~$ set interfaces ethernet eth1 description 20-NETWORK
vyos@vyos:~$ set interfaces ethernet eth1 10.255.20.1/24
vyos@vyos:~$ set interfaces ethernet eth1 description 30-NETWORK
vyos@vyos:~$ set interfaces ethernet eth1 10.255.30.1/24

vyos@vyos:~$ save

Saving configuration to '/config/config.boot'...

vyos@vyos:~$ exit

vyos@vyos:~$ show interfaces
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface        IP Address                        S/L  Description
---------        ----------                        ---  -----------
eth0             192.168.0.201/16                  u/u  OUTSIDE 
eth1             10.255.10.1/24                    u/u  10-NETWORK 
eth2             10.255.20.1/24                    u/u  20-NETWORK 
eth3             10.255.30.1/24                    u/u  30-NETWORK 
lo               127.0.0.1/8                       u/u  
                 ::1/128


  • 내부 사설망과 연결되는 개별 router 포트(eth1, eth2, eth3) 에 대해 다음과 같이 설정하고 저장한다

내부 사설망과 연결되는 개별 router port(eth1, 2, 3)에 대해 다음과 같이 설정한다

vyos@vyos:~$ configure

vyos@vyos:~$ set nat source rule 10 source address 10.255.10.0/24

vyos@vyos:~$ set nat source rule 10 outbound-interface eth0

vyos@vyos:~$ set nat source rule 10 protocol 'all'

vyos@vyos:~$ set nat source rule 10 translation address masquerade

vyos@vyos:~$ set nat source rule 20 source address 10.10.255.0/24

vyos@vyos:~$ set nat source rule 20 outbound-interface eth0

vyos@vyos:~$ set nat source rule 20 protocol 'all'

vyos@vyos:~$ set nat source rule 20 translation address masquerade

vyos@vyos:~$ set nat source rule 30 source address 10.255.30.0/24

vyos@vyos:~$ set nat source rule 30 outbound-interface eth0

vyos@vyos:~$ set nat source rule 30 protocol 'all'

vyos@vyos:~$ set nat source rule 30 translation address masquerade

vyos@vyos:~$ commit

vyos@vyos:~$ save

Saving configuration to '/config/config.boot'...

vyos@vyos:~$ show nat source rule 10

 outbound-interface eth0

 protocol all

 source {

     address 10.255.10.0/24

 }

 translation {

     address masquerade

 }

[edit]

vyos@vyos:~$ exit


  • Router의 정상작동은, 내부 사설망을 사용할 VM(네트워크 어댑터는 호스트 전용, Vyatta Router 의 eth1 등과 동일한 방식의 어댑터)을 생성하고 default gateway를 10.255.10.1  등 Router port의 IP로 설정하여 외부 인터넷으로 ping 이 도달되는지 확인해 보면 된다
  • Vyatta Router를 재시작하기 위해서는 명령어 상태에서 reboot 명령어를, 끄기 위해서는 단순히 poweroff 명령어를 실행한다


사설망 외부에서 내부로의 직접 접근(Port Forwarding)

  • 공유기를 통한 외부에서 내부로의 접근 방식과 동일한 개념으로 Port fordwarding을 설정하면 된다
  • 설정 방법과 과정을 예로 들어보면 아래와 같다(192.168.0.201:65022 -> 10.255.10.100:22, TCP/UDP DNAT 포워딩)
vyos@vyos:~$ configure
vyos@vyos:~$ set nat destination rule 100 description PORT_FORWARD_TEST
vyos@vyos:~$ set nat destination rule 100 destination address '192.168.0.201'
vyos@vyos:~$ set nat destination rule 100 destination port 65022
vyos@vyos:~$ set nat destination rule 100 inbound-interface 'eth0'
vyos@vyos:~$ set nat destination rule 100 protocol tcp_udp
vyos@vyos:~$ set nat destination rule 100 translation address '10.255.10.100'
vyos@vyos:~$ set nat destination rule 100 translation port '22'
vyos@vyos:~$ commit
vyos@vyos:~$ save
Saving configuration to '/config/config.boot'...
vyos@vyos:~$ show nat destination rule 100
 description SIP_FORWARD_TEST
 destination {
     address 192.168.0.201
     port 65022
 }
 inbound-interface eth0
 protocol tcp_udp
 translation {
     address 10.255.10.100
     port 22
 }
[edit]
vyos@vyos:~$ exit


한 걸음 더...

  • 노트북을 사용하는 네트워크 환경이 바뀌었는데 Vyatta Router의 eth0 주소와 각 포트의 라우팅 정보를 수시로 바꿔 주어야 하는 것은 상당히 불편하고 귀찮은 일일 것이다. 사실 본 글의 라우팅 구조를 생각해 낼 떄부터 이 내용을 결론으로 쓰기 위한 것이었는데 ...... 
    - VirtualBox VM관리 화면에서 Vyatta Router VM을 끈 후 복제(Vyatta Router Home 등의  다른 이름으로)
    - 복제할 때 Mac 주소를 자동생성하게(default이지만, 확인 필요) 설정, 단 다음 단계에서 링크가 아닌 '완전한 복제' 실행


     - 새로 만들어진 Vyatta Router VM에 로그인하여, 앞서 수행했던 configure 과정과 비슷한 내용을 다시 수행하는 것이 아니라 vi등의 편집기로 /config/config.boot 내용 중 원하는 부분(외부와 연결되는 eth0 네트워크 정보, default gateway, 4개의 NIC에 대한 MAC 주소-VirtualBox에서 자동할당한 MAC 주소)를 수정하고 reboot 하면 된다. 참고로 아래에 config.boot 파일의 수정해야 할 부분을 붉은 글씨로 따로 표시하였다


vyos@vyos:~$ cat /config/config.boot 

interfaces {

    ethernet eth0 {

        address 192.168.219.201/24

        description OUTSIDE

        duplex auto

        hw-id 08:00:27:8e:73:7a

        smp_affinity auto

        speed auto

    }

    ethernet eth1 {

        address 10.255.10.1/24

        description 10-NETWORK

        duplex auto

        hw-id 08:00:27:b5:91:0e

        smp_affinity auto

        speed auto

    }

    ethernet eth2 {

        address 10.255.20.1/24

        description 20-NETWORK

        duplex auto

        hw-id 08:00:27:6b:38:52

        smp_affinity auto

        speed auto

    }

    ethernet eth3 {

        address 10.255.30.1/24

        description 30-NETWORK

        duplex auto

        hw-id 08:00:27:60:d7:dd

        smp_affinity auto

        speed auto

    }

    loopback lo

...

}

nat {

    destination {

        rule 100 {

            description PORT_FORWARD_TEST

            destination {

                address 192.168.219.201

                port 65022

            }

            inbound-interface eth0

            protocol tcp_udp

            translation {

                address 10.255.10.100

                port 22

            }

        }

        rule 101 {

            description FORWARD_OSMASTER

            destination {

                address 192.168.219.201

                port 60160

            }

            inbound-interface eth0

            protocol tcp_udp

            translation {

                address 10.255.10.160

                port 22

            }

        }

...

    }

    source {

        rule 10 {

            outbound-interface eth0

            protocol all

            source {

                address 10.255.10.0/24

            }

            translation {

                address masquerade

            }

        }

        rule 20 {

            outbound-interface eth0

            protocol all

            source {

                address 10.255.20.0/24

            }

            translation {

                address masquerade

            }

        }

        rule 30 {

            outbound-interface eth0

            protocol all

            source {

                address 10.255.30.0/24

            }

            translation {

                address masquerade

            }

        }

    }

}

service {

    ssh {

        port 22

    }

}

system {

    config-management {

        commit-revisions 20

    }

    domain-name test.local

    gateway-address 192.168.219.1

    host-name vyos

...

vyos@vyos:~$ 



  • 이렇게 한다면, 업무 환경의 네트워크에 따라 Vyatta Router만 바꿔서 사용하므로, 수시로 업무 환경에 따라 VM의 네트워크 정보를 바꿔 주어야 했던 불편함은 깔끔하게 해결되지 않을까 한다



- Barracuda -


저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들


9월 6일자 티스토리 공지사항에 보면 아래의 내용이 올라와 있다. 밥벌이에 바쁘다 보니 뒤늦게 읽게 됐는데, 보다 보니 좀 심각한 내용이다. 티스토리의 서버가 이전함에 따라 IP가 바뀌게 되어 2차 도메인 사용자를 위한 배려(?)로 CNAME으로 host.tistory.io 만을 사용하고 도메인에 대한 A 레코드(티스토리의 IP주소로 등록한 부분)을 삭제 해 달라는 내용이다(10월6일 이후에 좀 더 상세하게 바뀐 내용으로 업데이트된 공지 참고).


그런데, DNS 표준 권고사항에서는 루트도메인(Root Domain=Naked Domain=Bare Domain=Zone Apex ... 다 같은 말이다. 즉 필자의 경우를 예로 들면, 보유 중인 2차 개인 도메인인 'bryan.wiki'가 바로 루트도메인)에 대한 CNAME 은 허용하지 않게 되어 있다(참고: RFC1034, Serverfault 포스팅).




다시 풀어서 예를 들어 보면, www.bryan.wiki 에 대해서는 CNAME 으로 host.tistory.io 를 등록할 수 있지만, bryan.wiki 에 대한 CNAME 으로 host.tistory.io 를 등록하지 못하게 되어 있다. 표준을 준수하는 메이저 DNS 제공 업체들(Ghandi, GoDaddy 등)은 이러한 등록을 시도하지 못하도록 오류를 뱉어내게 되어 있다. Amazon의 Route53(Ghandi 의 DNS 서비스사용) 의 관리 화면에서 @.bryan.wiki(또는 그냥 bryan.wiki) 에 대해 CNAME을 등록할 경우에 붉은 글씨의 오류 메시지를 볼 수 있다.


티스토리가 CNAME 만의 사용을 계속 강요한다면...?


만약 티스토리가 A 레코드를 삭제하고 bryan.wiki 에 대한 주소 등록을 CNAME 만으로 등록하도록 입장을 고수한다면, 다음의 우회적인 방법으로 구현은 가능하다. 필자가 사용중인 Amazon의 Route53과 S3 Redirection에 의한 방법을 예로 들어 보겠다.


우선 AWS 웹사이트에서 Route53 의 도메인 관리화면으로 들어간다. 일단, Create Record Set에서 다음과 같이 www.bryan.wiki 에 대한 CNAME은 host.tistory.io. 으로 등록은 가능하다. 이 부분은 표준에 어긋나지 않으므로...




다음으로, 티스토리가 요구하는 대로 현재 등록된 A 레코드를 삭제해 보자.


이제 "http://www.bryan.wiki 로는 블로그 접속이 되지만, http://bryan.wiki 로는 접속이 되지 않는다. 티스토리에서 원하는 대로 bryan.wiki 에 대한 CNAME 등록을 시도해 본다.


Create 를 눌러 보지만 등록 불가라고 붉은 글씨의 오류가 나며, 다음 단계로 진행되지 않는다. 빈칸 자리에 @ 를 넣으면 등록은 가능하지만 여전히 http://bryan.wiki 로 블로그 접속은 불가한 상태!



S3 의 Redirect request 를 써 보자


S3 는 Amazon의 스토리지 공간(Bucket)에 파일을 올려 두고 인터넷을 통해 다운로드 등의 서비스가 가능한 서비스로 알려져 있지만, 버킷 접속을 특정 주소로 전환해 주는 기능도 가지고 있다. 이 기능을 사용하면 되지만, 사용량에 따른 비용을 내야 하는 유료 서비스이다. 접속 형태와 지역에 따라 구분이 되기는 하지만 서울 Region 기준으로 1만 건당 0.37 센트(무려!!!)를 지불해야 한다.


AWS 메인 화면에서 S3를 클릭하여 해당 화면에 진입한다. Create Bucket을 선택해서 Bucket Name에 2차도메인을 입력하고 Create 클릭.

  

Bucket 접속에 대한 Redirection End Point를 설정해 보자. Bucket 왼쪽의 돋보기 아이콘이나 오른쪽 위의 Properties를 선택하고 Redirect all requests to .... 를 선택하고 Save.




이제 http://bryan.wiki 에 접속했을 때 리디렉션할 주소가 생성되었으니, Route53 에서 Create Record Set으로 루드도메인에 대한 A 레코드를 선택하고 Alias를 선택하면, 아래에 S3 endpoint가 목록에 나타난다. 이를 선택하고 Create!


여기까지 성공하였다면 다음 그림과 같은 등록 상태를 확인할 수 있을 것이다. SOA, NS, CNAME, A 타입의 레코드가 각각 하나씩이다. 이제 http://bryan.wiki 와 같은 2차 도메인으로 접속하면, CNAME으로 등록한 www 서브도메인(http://www.bryan.wiki)으로 리디렉션되고 티스토리 블로그로 접속할 수 있게 된다.



10월 6일 전후로 티스토리에서 해당 공지를 변경하여 발표했다. A 레코드에 의한 DNS 등록을 병행하기로 했다는 내용이다. 처음 발표된 9월 6일 이후로 수많은 2차도메인 사용자들에게 혼란을 초래해 왔고, 또 많은 이들의 지적과 불만에 찬 댓글에 대한 리액션인 듯 하다.


티스토리가 서버를 이전하는 일에는 인터넷 서비스회사의 특성상 그럴 수도 있다고 하지만 앞으로 IP 주소가 얼마나 자주 바뀔 예정이기에 표준 준수를 어겨가면서까지 A 레코드 방식을 버리라고 무리수를 두었는지는 도대체 지금도 알 길이 없다. 그냥 단순한 사용자 편의만을 위한 배려뿐이었을까?


- Barracuda -


저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들



Haproxy 는 두 말할 것 없이 현존 최고[각주:1]의 오픈소스 소프트웨어 Load Balancing 솔루션이다. 그림에 나오는 구성은 응용 여하에 따라 각종 모바일/웹 서비스의 기본 모델 또는 Hadoop 등 시스템의 하부 솔루션 등에서 Active-Standby 구조의 고가용성 확보 솔루션으로 활용 가능하므로, 본 포스팅을 통해 그 실제적인 부분을 모두 다루어 구현 & 검증/확인해 보고자 한다.


전체적인 구성은 크게 세 부분으로 나뉘는데, 본 구현에서는 앞선 포스팅들("Linux NAT router 설정하기 - Ubuntu 14.4 dom0, xen pv guest 환경", "[Xen 가상화 2] ubuntu pv guest on Ubuntu 14.4 LTS, Xen 4.4.1 - 설치 및 설정 가이드") 에서 다룬 Xen 환경을 확장하여 그대로 써먹고 있으며, nginx 웹서버에서 외부 접속이 가능하도록 설정됨(NAT Router)을 전제로 진행하므로 꼭 참고해 보도록 하자.


1. LB 서버에 Haproxy 설치(LB1: Active, LB2: Stand-by임에 유의)

2. LB 서버에 Keepalived 설치 & VRRP 구동, Failover 확인

3. 내부서버에 웹서버 nginx 설치 & Haproxy 구동 확인 & 테스트

4. (번외)내부서버에서 외부로 나가는 경로를 Keepalived 로 이중화



1. LB 서버에 Haproxy 설치


Ubuntu 에서 Haproxy 를 설치하려면 단순히 apt-get 으로 설치 가능하다. 다만 repo 에 포함된 버전은 1.4.x 버전으로 SSL을 자체 지원하지 않으며, 1.5.x 버전을 설치해야만 SSL 기능을 활용할 수 있다. 소스를 다운로드 받아서 빌드할 수도 있지만 여기서는 ppa:vbernat repo를 배포 받아 설치한다.


* 동일한 과정을 LB1(ubuntu14-pvha1), LB2(ubuntu14-pvha2) 서버에서 각각 수행한다

root@ubuntu14-pvha1:~# apt-add-repository ppa:vbernat/haproxy-1.5

root@ubuntu14-pvha1:~# apt-get update

root@ubuntu14-pvha1:~# apt-get install haproxy

root@ubuntu14-pvha1:~# haproxy -v

HA-Proxy version 1.5.13 2015/06/23

Copyright 2000-2015 Willy Tarreau <willy@haproxy.org>


* haproxy.cfg 파일을 수정한다(LB1, LB2 에서 각각 동일하게 적용)

* 192.168.25.203 은 가상ip(VIP, Virtual IP)이며, 평상시 LB1의 eth0에 binding 되어 있다가 LB1 down시 LB2 eth0가 넘겨 받도록  keepalived 를 통해 설정할 것이다(VRRP by keepalived)

* 서버별 주요 설정 값들은 붉은 글씨로 따로 표시해 둔 점에 유의(주요 설정 수치에 대해서는 haproxy 문서 별도 참조)

root@ubuntu14-pvha1:~# vi /etc/haproxy/haproxy.cfg

global

#log /dev/log local0

#log /dev/log local1 notice

log 127.0.0.1 local2

chroot /var/lib/haproxy

stats socket /run/haproxy/admin.sock mode 660 level admin

stats timeout 30s

user haproxy

group haproxy

daemon


# Default SSL material locations

ca-base /etc/ssl/certs

crt-base /etc/ssl/private


# Default ciphers to use on SSL-enabled listening sockets.

# For more information, see ciphers(1SSL). This list is from:

#  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/

ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

ssl-default-bind-options no-sslv3


defaults

log global

mode http

option httplog

option dontlognull

option http-server-close

option forwardfor except 127.0.0.0/8

option redispatch

retries 3

timeout http-request 20

timeout queue 86400

timeout connect 86400

timeout client 86400

timeout server 86400

timeout http-keep-alive 30

timeout check 20

maxconn 50000


frontend myLB

bind 192.168.25.203:80

default_backend myLB


backend myLB 192.168.25.203:80

mode http

stats enable

stats hide-version

stats uri /stats

stats realm Haproxy\ Statistics

stats auth haproxy:admin

balance roundrobin

option httpchk GET /hc.html

option http-server-close

option forwardfor

server pv1 10.0.10.1:80 check inter 1000 fastinter 500 downinter 5000 rise 3 fall 1

server pv2 10.0.10.2:80 check inter 1000 fastinter 500 downinter 5000 rise 3 fall 1

server pv3 10.0.10.3:80 check inter 1000 fastinter 500 downinter 5000 rise 3 fall 1

server pv4 10.0.10.4:80 check inter 1000 fastinter 500 downinter 5000 rise 3 fall 1


root@ubuntu14-pvha1:~# vi /etc/rsyslog.conf -> 아래 2개 라인을 찾아 uncomment. UDP syslog 를 port 514 로 받아들이기 위한 config 설정

$ModLoad imudp

$UDPServerRun 514


* haproxy log 가 /var/log/haproxy.log 에 쌓이는지 확인

root@ubuntu14-pvha1:~# service rsyslog restart

root@ubuntu14-pvha1:~# service haproxy restart

root@ubuntu14-pvha1:~# tail -f /var/log/haproxy.log


root@ubuntu14-pvha1:~# vi /etc/default/haproxy -> 아래 라인 추가(부팅시 자동실행)

ENABLED=1



2. LB 서버에 Keepalived 설치 & VRRP 구동, Failover 확인


* 서버 외부의 IP 주소를 NIC에 바이딩이 가능하도록 커널 옵션을 수정한다(LB1, LB2 에서 모두 수행)

root@ubuntu14-pvha1:~# vi /etc/sysctl.conf -> 아래 2개 라인을 입력해 준다

# For keepalived - vrrp

net.ipv4.ip_nonlocal_bind=1

root@ubuntu14-pvha1:~# sysctl -p (또는 리부트)

root@ubuntu14-pvha1:~# cat /proc/sys/net/ipv4/ip_nonlocal_bind 

1


* keepalived 를 설치하고 config 를 설정한다(LB1에서 수행. 우선순위는 1~254 값 중 임의로 사용. 101 값에 유의)

* [중요] Master와 Slave의 Instance 명, virtual router id 를 각각 동일하게 해야 하며, Master 우선순위를 더 높게 하는 이유는, Master 가 내려 갔다가 다시 살아날 때 원래대로 다시 Master 역할을 떠맡아 VIP를 가져가게 하려는 의도

* 기본 eth0에 할당된 192.168.25.201 과 함께 VIP인 192.168.25.203 이 바인딩되도록 설정

root@ubuntu14-pvha1:~# apt-get install keepalived 

root@ubuntu14-pvha1:~# vi /etc/keepalived/keepalived.conf

global_defs {

  router_id ubuntu14-pvha1

}

vrrp_script haproxy {

  script "killall -0 haproxy"

  interval 2

  weight 2

}

vrrp_instance VI_1 {

  virtual_router_id 50

  advert_int 1

  priority 101

  state MASTER

  interface eth0

  virtual_ipaddress {

    192.168.25.203 dev eth0

  }

  track_script {

    haproxy

  }

}

* 최소한의 기본 설정으로, event mail 발송, health-check 튜닝 등 추가적인 부분은 상황에 맞게 별도 진행


* keepalived 를 설치하고 config 를 설정한다(LB2에서 수행. 우선순위 100에 유의)

* 동일한 vrrp instance(VI_1) 가 네트워크 내에 존재하면서 자신보다 우선순위가 높으면 반응하지 않게 된다

root@ubuntu14-pvha1:~# apt-get install keepalived 

root@ubuntu14-pvha1:~# vi /etc/keepalived/keepalived.conf

global_defs {

  router_id ubuntu14-pvha2

}

vrrp_script haproxy {

  script "killall -0 haproxy"

  interval 2

  weight 2

}

vrrp_instance VI_1 {

  virtual_router_id 50

  advert_int 1

  priority 100

  state MASTER

  interface eth0

  virtual_ipaddress {

    192.168.25.203 dev eth0

  }

  track_script {

    haproxy

  }

}


* keepalived, haproxy 순으로 재시작하고 설정 확인(LB1 에서 수행)
root@ubuntu14-pvha1:~# service keepalived restart
root@ubuntu14-pvha1:~# service haproxy restart 
root@ubuntu14-pvha1:~# ip addr show -> eth0에 VIP가 추가로 할당 됨을 확인

...

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

    link/ether 00:16:3e:fa:5b:07 brd ff:ff:ff:ff:ff:ff

    inet 192.168.25.201/24 brd 192.168.25.255 scope global eth0

       valid_lft forever preferred_lft forever

    inet 192.168.25.203/32 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::216:3eff:fefa:5b07/64 scope link 

       valid_lft forever preferred_lft forever

...


* keepalived, haproxy 순으로 재시작하고 설정 확인(LB2 에서 수행)
root@ubuntu14-pvha1:~# service keepalived restart
root@ubuntu14-pvha1:~# service haproxy restart 
root@ubuntu14-pvha1:~# ip addr show -> 평상시 eth0에는 VIP가 할당되지 않음을 확인

...

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

    link/ether 00:16:3e:d9:2c:13 brd ff:ff:ff:ff:ff:ff

    inet 192.168.25.202/24 brd 192.168.25.255 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::216:3eff:fed9:2c13/64 scope link 

       valid_lft forever preferred_lft forever

...


* Keepalived 의 수행 결과로 VIP가 옮겨 지면서 Haproxy 가 Failover 에 의해 잘 작동되는지 점검한다

1. Host(Dom0)에서 별도 터미널을 띄우고 VIP(192.168.25.203) 쪽으로 ping test를 실행해 둔다

2. LB1, LB2에 각각 1개의 터미널을 띄우고 LB1 서버를 셧다운(halt)한다

3. 위에서 띄운 별도 터미널의 ping test 결과를 관찰하면 약 1~2 회 가량 redirect 발생, 1~2회 가량 순단현상 발생, 이후 정상 ping 결과가 나타난다(이러한 순단현상은 ping test에 의해서 0~2회 정도까지 관찰된다)

bryan@bryan-XenPC:~$ ping 192.168.25.203

...

64 bytes from 192.168.25.203: icmp_seq=221 ttl=64 time=0.291 ms

64 bytes from 192.168.25.203: icmp_seq=222 ttl=64 time=0.297 ms

64 bytes from 192.168.25.203: icmp_seq=223 ttl=64 time=0.242 ms

64 bytes from 192.168.25.203: icmp_seq=224 ttl=64 time=0.286 ms

64 bytes from 192.168.25.203: icmp_seq=225 ttl=64 time=0.151 ms

64 bytes from 192.168.25.203: icmp_seq=226 ttl=64 time=0.270 ms

From 192.168.25.203: icmp_seq=227 Redirect Host(New nexthop: 192.168.25.203)

64 bytes from 192.168.25.203: icmp_seq=229 ttl=64 time=0.337 ms

64 bytes from 192.168.25.203: icmp_seq=21 ttl=64 time=0.288 ms

From 192.168.25.203 icmp_seq=18 Destination Host Unreachable

64 bytes from 192.168.25.203: icmp_seq=230 ttl=64 time=0.328 ms

64 bytes from 192.168.25.203: icmp_seq=231 ttl=64 time=0.316 ms

64 bytes from 192.168.25.203: icmp_seq=232 ttl=64 time=0.319 ms

64 bytes from 192.168.25.203: icmp_seq=233 ttl=64 time=0.318 ms

...
* LB2의 터미널에서 ip addr show 를 수행하면 VIP가 LB1 으로부터 옮겨와서 eth0에 바인딩 된 것을 볼 수 있을 것이다


* LB2 서버의 eth0 에 VIP가 바인딩된 것을 볼 수 있다

root@ubuntu14-pvha2:~# ip addr show

...

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

    link/ether 00:16:3e:d9:2c:13 brd ff:ff:ff:ff:ff:ff

    inet 192.168.25.202/24 brd 192.168.25.255 scope global eth0

       valid_lft forever preferred_lft forever

    inet 192.168.25.203/32 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::216:3eff:fed9:2c13/64 scope link

       valid_lft forever preferred_lft forever

...


* 다시 LB1 서버를 켜서, 이전 상태인 LB1 eth0로 VIP가 바인딩 됨은 앞선 테스트 과정을 반복해 보면 확인 가능하다. 이 때에도 약간의 순단현상이 발생할 수 있다.



3. 내부서버에 nginx 설치, haproxy failover 구동 확인


* 4개의 vm(ubuntu14-pv1~ubuntu14-pv4)에 각각 nginx 를 설치하고 테스트를 위한 html source 를 수정

root@ubuntu14-pv1:~# apt-get install nginx

root@ubuntu14-pv1:~# nginx -v

nginx version: nginx/1.4.6 (Ubuntu)

root@ubuntu14-pv1:~# vi /usr/share/nginx/html/index.html -> 기본 제공 html을 간단히 수정

<!DOCTYPE html>

<html>

<head>

<title>Welcome to nginx!</title>

<style>

    body {

        width: 35em;

        margin: 0 auto;

        font-family: Tahoma, Verdana, Arial, sans-serif;

    }

</style>

</head>

<body>

<h1>Welcome to nginx!</h1>

<p>If you see this page, the nginx web server is successfully installed and

working. Further configuration is required.</p>


<p>For online documentation and support please refer to

<a href="http://nginx.org/">nginx.org</a>.<br/>

Commercial support is available at

<a href="http://nginx.com/">nginx.com</a>.</p>


<p><em>Thank you for using nginx.</em></p>

<p>Hostname: ubuntu14-pv1</p>

</body>

</html>


* LB로부터의 Health-check request 을 받기 위한 별도의 html 파일 준비

 root@ubuntu14-pv1:/etc/nginx# vi /usr/share/nginx/html/hc.html 

<!DOCTYPE html>

<html>

<head><title>Health Check file</title></head>

<body>

OK?

</body>

</html>


* (특별 부록1) 외부로 ping 은 나가지만 인터넷 주소로 외부 접근이 안되는 경우 DNS 설정을 해 주어야 한다. Ubuntu 12 부터는 /etc/resolve.conf 만 수정할 경우 리부트 후에 Network manager 에 의해 초기화되므로 다음과 같이 DNS server 를 변경해 주어야 한다.

<고정 ip를 사용할 경우: /etc/network/interfaces, NIC별 직접 설정만으로 충분>

iface eth0 inet static

address 10.0.10.1

...

dns-nameservers 8.8.8.8

<고정 ip 여부에 무관하게 항상 우선적으로 적용되게 할 경우>

root@ubuntu14-pv1:~# vi /etc/resolvconf/resolv.conf.d/head

nameserver 210.220.163.82

nameserver 219.250.36.130

nameserver 8.8.8.8

root@ubuntu14-pv1:~# resolvconf -u


* (특별 부록2) nginx 는 haproxy 와 같은 Load balancer 로부터의 접속에 대해 Client(web browser)의 실제 IP를 손쉽게 로깅할 수 있는 방법을 제공한다(cf: Apache의 경우 mod_rpaf 등의 별도 모듈 설치/설정 필요. 로그파일이나 Web 프로그래밍시에 사용하는  서버변수의 경우에도 Apache는 HTTP_X_FORWARDED_FOR 와 같은 별도의 변수를 써야 하지만, nginx는 LB가 없을 때의 기존 방식 그대로 REMOTE_ADDR 변수를 사용할 수 있다). 이 때 haproxy 측에서는

option http-server-close

option forwardfor

와 같이 config 를 미리 설정하여 X-Forwarded-For 헤더를 웹서버로 전달하도록 하고 nginx 측에는 아래와 같이 설정하면 간단히 구현된다. 여기서 10.0.0.1, 10.0.0.2 는 LB1, LB2(즉 Haproxy 서버) 측의 내부 네트워크 쪽 NIC의 IP 주소들이다.


root@ubuntu14-pv1:~# vi /etc/nginx/nginx.conf -> 붉은 글씨의 라인들 추가

http {

         ...

        # server_name_in_redirect off;


        ##

        # Real IP settings

        ##

        set_real_ip_from 10.0.0.1;

        set_real_ip_from 10.0.0.2;

        real_ip_header X-Forwarded-For;

         ...
         access_log /var/log/nginx/access.log;
         error_log /var/log/nginx/error.log;

         server {
                 listen 80;
                 location ~* /hc.html {
                         access_log off;
                 }
         }

         ##
         # Gzip Settings
         ...
}

root@ubuntu14-pv1:~# service nginx restart

* (특별 부록3) 위의 config 하단을 잘 보면, LB로부터의 지속적인 health-check request 들이 다량으로 로그에 쌓이게 된다. 따라서 config 파일 내의 http 블록 안에 server-location 블록을 설정하여, 80 포트로 들어온 /hc.html 페이지 호출 request 는 access_log 에 쌓지 않도록 설정하였음을 알 수 있다(옵션 사항)



* Haproxy 를 통해 들어온 접속의 Client 측 Real IP 를 확인해 보기 위해 log 에 tail 을 걸어서 확인한다. 웹브라우저는 외부 네트워크인 192.168.25.2에서 Chrome 브라우저를 띄우고 http://192.168.25.203 으로 접속을 시도한다.

root@ubuntu14-pv1:~# tail -f /var/log/nginx/access.log

...

192.168.25.2 - - [01/Jul/2015:11:43:03 +0900] "GET / HTTP/1.1" 200 414 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36"

...



* 이후의 테스트 및 검증은 위의 2에서 수행한 것과 유사한 방식으로 LB1, LB2 를 번갈아서 shutdown 하면서 nginx access.log, 테스트용 브라우저의 결과 화면을 모니터링해 보면 되겠다



* 참고로, 일반적으로 많이 사용하는 Apache Bench 를 사용하는 예를 아래에 기재해 두었다

root@bryan-XenPC:~# apt-get install apache2-utils

root@bryan-XenPC:~# ab -n 50 -c 10 http://192.168.25.203/index.html

This is ApacheBench, Version 2.3 <$Revision: 1528965 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/


Benchmarking 192.168.25.203 (be patient).....done



Server Software:        nginx/1.4.6

Server Hostname:        192.168.25.203

Server Port:            80


Document Path:          /index.html

Document Length:        642 bytes


Concurrency Level:      10

Time taken for tests:   0.013 seconds

Complete requests:      50

Failed requests:        12

   (Connect: 0, Receive: 0, Length: 12, Exceptions: 0)

Total transferred:      44102 bytes

HTML transferred:       32052 bytes

Requests per second:    3861.60 [#/sec] (mean)

Time per request:       2.590 [ms] (mean)

Time per request:       0.259 [ms] (mean, across all concurrent requests)

Transfer rate:          3326.26 [Kbytes/sec] received


Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        0    0   0.1      0       1

Processing:     1    2   0.5      2       3

Waiting:        1    2   0.5      2       3

Total:          1    2   0.5      2       4


Percentage of the requests served within a certain time (ms)

  50%      2

  66%      2

  75%      3

  80%      3

  90%      3

  95%      3

  98%      4

  99%      4

 100%      4 (longest request)




4. 내부서버에서 외부로 나가는 경로를 Keepalived 로 이중화하여 Failover


* 웹서비스를 위한 VIP(192.168.25.203) failover에 더하여, 내부서버에서 패키지업데이트 등 유지보수 활동을 위한 외부 접속을 위해 내부서버의 gateway용 VIP(10.0.0.3) 을 keepalived 에 등록한다

* LB1, LB2의 keepalived config를 아래와 같이 수정한다하고 서비스 재시작

root@ubuntu14-pvha1:~# vi /etc/keepalived/keepalived.conf <== 아래 내용을 추가

...

vrrp_instance VI_2 {

  virtual_router_id 100

  advert_int 1

  priority 101

  state MASTER

  interface eth1

  virtual_ipaddress {

    10.0.0.3 dev eth1

  }

  track_script {

    haproxy

  }

}

root@ubuntu14-pvha1:~# service keepalived restart


root@ubuntu14-pvha2:~# vi /etc/keepalived/keepalived.conf <== 아래 내용을 추가

...

vrrp_instance VI_2 {

  virtual_router_id 100

  advert_int 1

  priority 100

  state MASTER

  interface eth1

  virtual_ipaddress {

    10.0.0.3 dev eth1

  }

  track_script {

    haproxy

  }

}

root@ubuntu14-pvha1:~# service keepalived restart


* 4개의 vm(ubuntu14-pv1~ubuntu14-pv4), interfaces config의 gateway 인 10.0.0.1을 VIP인 10.0.0.3으로 수정하고 네트워크 재시작 또는 리부팅(확인 과정은 위의 keepalived 확인 과정과 유사)

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

...

auto lo

iface lo inet loopback


# The primary network interface

auto eth0

#iface eth0 inet dhcp

iface eth0 inet static

address 10.0.10.1

netmask 255.255.0.0

network 10.0.0.0

broadcast 10.0.255.255

gateway 10.0.0.3

dns-nameservers 8.8.8.8



[관련글]

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

2015/06/30 - Linux NAT router 설정하기 - Ubuntu 14.4 dom0, xen pv guest 환경

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



- Barracuda -



  1. 이의 제기가 있어서 Comment 만 달아 둡니다. 잘 알려지고 활용성 높은...정도의 의미입니다. 벤치마킹을 해 보지 않아서 소프트웨어 LB중에 성능, 기능상 최고라고는 얘기 못한다는 말. [본문으로]
저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들



외부 네트워크(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의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들

컴퓨터 작업을 하다 보면 어쩔 수 없이 특정 윈도우 서버로 원격 접속을 해야 할 경우가 가끔 있습니다. 그런데, 경력이 오래 된 전문가나 상급 엔지니어의 경우에도 의외로 방심해서 실수하는 경우가 의외로 많습니다. 수십년 경력의 보안전문가도 음주후 작업(^^;;) 때문에 "으아~ X됐다" 하면서 갑자기 뛰쳐 나가는 경우를 최근 보았기 때문입니다.


바로 피씨방이나 공항 등의 공개된 PC에서 원격 접속후에, 흔적을 지우지 않고 다리를 털고 일어날 경우의 치명적인 보안 유출 문제입니다. 자칫 아주 심각한 보안상 구멍이 되기도 합니다. 실제 경험상 거의 대다수의 정보 유출은 인재입니다.



원격 터미널 접속(데스크톱 접속) 정보 유출 시나리오(MS Windows계열)


엔지니어A 씨는 중요한 작업을 할 경우 사무실이나 서재의 개인용 컴퓨터에서만 합니다. 그러나 영업상 또는 다른 용무로 외부에 나가 있을 경우에 데이터센터(IDC)의 윈도우 서버로 다음과 같이 접속합니다.



반복적인 익숙한 작업이기 때문에 무심코 '내 자격 증명 기억' 을 선택했을 경우에, 재앙이 시작될 수 있습니다. 우선 이렇게 해서 A씨는 인증 과정을 거쳐서 서버에 접속하고 열심히 업무를 본 후, 피씨를 떠나게 됩니다.



만약 다음에 그 피씨를 사용하는 행인B씨가 같은 컴퓨터를 사용할 때, 원격 데스크톱 접속을 띄우게 된다면 어떻게 될까요?



행인B씨는 위의 창을 마주하게 됩니다. 이미 A씨는 터미널 인증 정보를 피씨에 고스란히 남겨 두었기 때문에, B씨가 연결을 누르는 순간 아무런 제약 없이, 심지어 로그인 과정도 없이 A씨가 사용하던 서버에 접속이 가능해 집니다. 자칫하면 막대한 손실(수억, 수백억의 금전적 손실이나 한 사람 또는 한 나라의 미래까지도...)로 연결 될 수 있는 시나리오가 되는 거지요. 순간의 방심이 미래를 망가뜨릴 수도 있습니다.



원격 데스크톱 연결 흔적 없애기


다음의 절차에 따라 접속 흔적을 삭제할 수 있습니다.


1. Default.rdp 파일 지우기: 이 파일에는 원격 데스크톱 접속 정보가 인증정보와 함께 자동 저장됩니다.


탐색기에 익숙한 경우는 탐색기에서 파일을 찾아서 지워도 됩니다(단, 휴지통의 파일도 지워야 겠지요). 혹은, cmd.exe 를 실행해서 Default.rdp 파일을 찾습니다. "dir /a Def*" 로 파일을 확인 한 후, "del /a Default.rdp" 를 실행해서 파일을 지웁니다.



2. 레지스트리의 원격 데스크톱 접속 주소 지우기HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default


MRU0 는 첫 번째 원격 접속 주소를 담고 있는 레지스트리 항목입니다. 마우스 우클릭으로 메뉴를 띄운 후에 삭제합니다.


이제 모든 접속 정보가 소거되었습니다. 다시 한 번 강조하지만, 방심은 절대 금물입니다! ^^. 피치 못해서 공용 피씨를 사용할 경우에 항상 잊지 말고 확인해서 대처하시고, 아주 특별한 경우가 아니면, 원격 데스크톱 접속을 공용피씨에서 사용하지 않으시기를 권고해 드립니다.


- Barracuda -

저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들

OpenSUSE 12.1 에서 powerdns 3.2 & pdns_gui with MySQL backend 설치/설정 과정 정리


[사전 환경 점검]

- DB server: MySQL(5.1 or 5.5) 설치

- Web server: 

  Apache2 + php + poweradmin 2.1.6 or pdns gui 0.3.3

  또는 lighttpd with php(php-fpm)(http://bryans.tistory.com/76, http://bryans.tistory.com/77 참고) + poweradmin 2.1.6


* 본 문서에서는 pdns 3.2 + MySQL(Percona 5.5.*) + Apache2 + php + pdns gui 0.3.3 을 채택한다


[pdns 3.2 설치]


1. libz.so 소프트 링크 설정


# cd /lib64/

# ln -s libz.so.1 libz.so

# ldconfig

# ls -l /lib64/libz.so*

lrwxrwxrwx 1 root root     9 Feb  8 15:34 /lib64/libz.so -> libz.so.1

lrwxrwxrwx 1 root root    13 Apr  1  2012 /lib64/libz.so.1 -> libz.so.1.2.5

-rwxr-xr-x 1 root root 96488 Feb  9  2012 /lib64/libz.so.1.2.5


2. MySQL, LUA 를 위한 라이브러리 설정


# zypper in -y libmysqlclient18 libmysqlclient-devel libmysqlclient18-32bit  libmysqlclient_r18 libmysqlclient_r18-32bit gcc-c++ boost-devel

# zypper in -y lua lua-devel


3. pdns 3.2 소스 다운로드 및 설치

설치 디렉토리는 /user/service/powerDNS 로 가정


# cd /user/service/download

# wget http://downloads.powerdns.com/releases/pdns-3.2.tar.gz

# tar xvzf pdns-3.2.tar.gz

# cd pdns-3.2

./configure --with-modules="gmysql" --prefix=/user/service/powerDNS

# make

# make install


4. pdns 설정


# vi /etc/init.d/pdns

#!/bin/sh

# chkconfig: 345 80 75

# description: PDNS is a versatile high performance authoritative nameserver


prefix=/user/service/powerDNS

exec_prefix=${prefix}

BINARYPATH=${exec_prefix}/bin

SBINARYPATH=${exec_prefix}/sbin

SOCKETPATH=/var/run


[ -f "$SBINARYPATH/pdns_server" ] || exit 0


cd $SOCKETPATH

suffix=`basename $0 | awk -F- '{print $2}'`

if [ $suffix ] 

then

EXTRAOPTS=--config-name=$suffix

PROGNAME=pdns-$suffix

else

PROGNAME=pdns

fi


pdns_server="$SBINARYPATH/pdns_server $EXTRAOPTS"


doPC()

{

ret=$($BINARYPATH/pdns_control $EXTRAOPTS $1 $2 2> /dev/null)

}


doPC ping

NOTRUNNING=$?


case "$1" in

status)

if test "$NOTRUNNING" = "0" 

then 

doPC status

echo $ret

else

echo "not running"

fi 

;;

stop)

echo -n "Stopping PowerDNS authoritative nameserver: "

if test "$NOTRUNNING" = "0" 

then 

doPC quit

echo $ret

else

echo "not running"

fi 

;;

force-stop)

echo -n "Stopping PowerDNS authoritative nameserver: "

killall -v -9 pdns_server

echo "killed"

;;

start)

echo -n "Starting PowerDNS authoritative nameserver: "

if test "$NOTRUNNING" = "0" 

then 

echo "already running"

else

$pdns_server --daemon --guardian=yes

if test "$?" = "0"

then

echo "started"

fi

fi 

;;

force-reload | restart)

echo -n "Restarting PowerDNS authoritative nameserver: "

echo -n stopping and waiting.. 

doPC quit

sleep 3

echo done

$0 start

;;

reload) 

echo -n "Reloading PowerDNS authoritative nameserver: "

if test "$NOTRUNNING" = "0" 

then 

doPC cycle

echo requested reload

else

echo not running yet

$0 start

fi 

;;

monitor)

if test "$NOTRUNNING" = "0" 

then 

echo "already running"

else

$pdns_server --daemon=no --guardian=no --control-console --loglevel=9

fi 

;;

dump)

if test "$NOTRUNNING" = "0" 

then 

doPC list

echo $ret

else

echo "not running"

fi 

;;

show)

if [ $# -lt 2 ]

then

echo Insufficient parameters

exit

fi 

if test "$NOTRUNNING" = "0" 

then 

echo -n "$2="

doPC show $2 ; echo $ret

else

echo "not running"

fi 

;;

mrtg)

if [ $# -lt 2 ]

then

echo Insufficient parameters

exit

fi 

if test "$NOTRUNNING" = "0" 

then 

doPC show $2 ; echo $ret

if [ "$3x" != "x" ]

then

doPC show $3 ; echo $ret

else

echo 0

fi

doPC uptime ; echo $ret

echo PowerDNS daemon

else

echo "not running"

fi 

;;

cricket)

if [ $# -lt 2 ]

then

echo Insufficient parameters

exit

fi 

if test "$NOTRUNNING" = "0" 

then 

doPC show $2 ; echo $ret

else

echo "not running"

fi 

;;

*)

echo pdns [start\|stop\|force-reload\|restart\|status\|dump\|show\|mrtg\|cricket\|monitor]

;;

esac


# chmod a+x /etc/init.d/pdns


# cd /user/service/powerDNS/etc

# cp pdns-dist.conf pdns.conf

## 주의: linux 에서 설치시 pdns-dist.conf 파일에 CR 문자가 포함되어 pdns.conf 의 설정을 pdns_server가 읽지 못하는 경우가  생길 수 있다.

# /etc/init.d/pdns monitor

Feb 12 17:35:23 Reading random entropy from '/dev/urandom'

Feb 12 17:35:23 Unable to launch, no backends configured for querying

 이 때는 pdns.conf 파일의 모든 라인을 지우고, pdns-dist.conf 의 내용만 복사(Copy/Paste)하여 사용한다.


# vi pdns.conf -- 파일 마지막에 내용 추가, 저장

launch                    =gmysql

gmysql-host            =127.0.0.1

gmysql-user            =pdns

gmysql-password    =password

gmysql-dbname       =pdnsdb

#recursor=a.b.c.d


MySQL 에 root로 접속하여 pdnsdb 데이터베이스를 생성(또는 기존 스키마 사용도 가능)하고 아래의 테이블들을 생성한다.

CREATE TABLE domains (

  ID INT(11) NOT NULL AUTO_INCREMENT,

  NAME VARCHAR(255) NOT NULL,

  MASTER VARCHAR(128) DEFAULT NULL,

  TYPE VARCHAR(6) NOT NULL,

  ACCOUNT VARCHAR(40) DEFAULT NULL,

  LAST_CHECK INT(11) DEFAULT NULL,

  NOTIFIED_SERIAL INT(11) DEFAULT NULL,

  PRIMARY KEY (ID),

  UNIQUE KEY XPKT_DNS_DOMAINS (ID),

  UNIQUE KEY XAK1T_DNS_DOMAINS (NAME)

) Engine=InnoDB;


CREATE TABLE records (

  ID INT(11) NOT NULL AUTO_INCREMENT,

  DOMAIN_ID INT(11) DEFAULT NULL,

  NAME VARCHAR(255) DEFAULT NULL,

  TYPE VARCHAR(6) DEFAULT NULL,

  CONTENT VARCHAR(255) DEFAULT NULL,

  TTL INT(11) DEFAULT NULL,

  PRIO INT(11) DEFAULT NULL,

  CHANGE_DATE INT(11) DEFAULT NULL,

  PRIMARY KEY (ID),

  UNIQUE KEY XPKT_DNS_RECORDS (ID),

  KEY XIE1T_DNS_RECORDS (NAME),

  KEY XIE2T_DNS_RECORDS (NAME,TYPE),

  KEY XIE3T_DNS_RECORDS (DOMAIN_ID)

) Engine=InnoDB;


CREATE TABLE supermasters (

  SUPERMASTERS_SEQ INT(11) NOT NULL AUTO_INCREMENT,

  IP VARCHAR(25) NOT NULL,

  NAMESERVER VARCHAR(255) NOT NULL,

  ACCOUNT VARCHAR(40) DEFAULT NULL,

  PRIMARY KEY (SUPERMASTERS_SEQ),

  UNIQUE KEY XPKT_DNS_SUPERMASTERS (SUPERMASTERS_SEQ)

) Engine=InnoDB;


pdns 계정으로 해당 테이블들을 처리할 수 있도록 권한을 설정한다.

> GRANT SELECT ON supermasters TO pdns;

> GRANT ALL ON domains TO pdns;

> GRANT ALL ON records TO pdns;

> flush privileges;


pdns 정상 설치 확인

# /etc/init.d/pdns monitor

Feb 12 18:22:30 Reading random entropy from '/dev/urandom'

Feb 12 18:22:30 This is a standalone pdns

Feb 12 18:22:30 UDP server bound to 0.0.0.0:53

Feb 12 18:22:30 TCP server bound to 0.0.0.0:53

Feb 12 18:22:30 PowerDNS 3.2 (C) 2001-2013 PowerDNS.COM BV (Feb  8 2013, 16:53:55, gcc 4.6.2) starting up

Feb 12 18:22:30 PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.

Feb 12 18:22:30 Creating backend connection for TCP

% Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 About to create 3 backend threads for UDP

Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 gmysql Connection successful

Feb 12 18:22:30 Done launching threads, ready to distribute questions


위와 같은 메시지를 확인하였다면, ctrl-C로 종료한 후 아래와 같이 pdns 데몬을 시작하고 프로세스를 확인한다.

# /etc/init.d/pdns start

Starting PowerDNS authoritative nameserver: started


# ps -eaf | grep -v grep | grep pdns

root     15998     1  0 18:54 ?        00:00:00 /user/service/powerDNS/sbin/pdns_server --daemon --guardian=yes

root     16000 15998  0 18:54 ?        00:00:00 /user/service/powerDNS/sbin/pdns_server-instance --daemon --guardian=yes



[pdns gui 설치]


1. Apache2 설치, mod_rewrite 모듈 추가

# zypper in -y apache2 apache2-mod_php5 apache2-mod_dnssd apache2-prefork apache2-utils

# chkconfig --add apache2

# chkconfig apache2 on

# service apache2 start


# a2enmod rewrite

# service apache2 restart


2. php5 및 기본 & 추가 패키지 설치

# zypper in -y php5 apache2-mod_php5 php5-bz2 php5-ctype php5-curl php5-devel php5-fpm php5-gettext php5-iconv php5-mcrypt php5-mysql php5-openssl php5-pcntl php5-pdo php5-pear php5-zlib

# zypper in -y php5-pear-MDB2, php5-pear-MDB2_Driver_mysql


3. pdns_gui 다운로드 및 압축 해제, 설치

http://code.google.com/p/pdns-gui 에서 pdns-gui.0.3.3.tgz 다운로드

MYSQL> create database pdns;


# cd /srv/www/htdocs

# tar xvzf DOWNLOADED_DIR/pdns-gui.0.3.3.tgz

# cd pdns-gui.0.3.3/batch

# ./install.sh

DB접속ip(local서버일 경우 localhost가 아닌 127.0.0.1 사용), database명, DB계정/암호 입력


4. apache2 설정 및 pdns_gui 웹 기동

# vi /etc/apache2/default-server.conf

DocumentRoot "/srv/www/htdocs"


<VirtualHost *:8888>

  DocumentRoot /srv/www/htdocs/pdns-gui.0.3.3/web

  DirectoryIndex index.php

  <Directory /srv/www/htdocs/pdns-gui.0.3.3/web>

    AllowOverride All

  </Directory>

</VirtualHost>


# service apache2 restart


http://pdns-gui webserver ip:8888/ 접속


저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들


이전 글에서는 OpenVPN 패키지를 Linux Server에 설치하고 Server Configuration, 인증키 발급/배포, Client Configuration 및 인증키 복사를 통한 수작업에 의한 VPN 설정과 사용에 대해 정리하였다.

이번 Post에서는 OpenVPN-AS 솔루션을 활용해서 지난 시간에 언급하였던 Site-to-Site 접속까지 구현하고 테스트해 본다. 헷갈리지 말 것은 OpenVPN을 서버에서 운영하는 방법은 크게
 - OpenVPN Server
 - OpenVPN Access Server
의 2가지가 있으며, OpenVPN 환경으로 접속할 수 있는 Client측의 접속방법은
 - OpenVPN Community Client(for Windows/Linux)
 - OpenVPN Access Server Client
 - TunnelBlick(for Mac)
의 3가지 있다는 것(다시 강조하지만 Windows나 Linux 에서 자체 제공하는 PPTP, L2TP등의 VPN client는 적용이 되지 않으며, 동일 클라이언트 내에서는 2개의 OpenVPN Client 중에서 한가지만 설치하여 사용한다)

OpenVPN-AS는 OpenVPN을 운영자가 쉽게 설치하고 운영하도록 다음의 4가지 기능을 동시에 모두 제공하는 솔루션이다.
 - OpenVPN Server
 - Admin Web interface
 - Client Web interface
 - OpenVPN Client Downloads(from Client Web interface, pam 인증키, 서버 접속정보, 로그인 계정 자동 포함)

설치 운영 방법은 설치 대상 장비의 종류나 성격에 따라
Linux Distro(RHEL, Ubuntu, Fedora, CentOS, Debian)로 Bare-metal 또는 VM에 직접 설치 또는
Virtual Alliance(VMware, Hyper-V, Windows WHD) 로 OpenVPN.org에서 제공되는 VM image를 생성하여 사용하는 방법이 있다.

* 이 대목에서 질문하신 분이 있었다. 회사내에 OpenVPN-AS를 깔았지만 사무실 전체가 비공인IP를 쓰기때문에 이 방식을 사용할 수가 없는데 방법이 없느냐고...약간 귀찮지만 방법이 없지는 않다. 회사내에 전산실이나 네트워크관리자가 따로 있다면 커피 한잔에 해결해 주실지도 모르겠다.

 방법은, 외부에서 들어오는 인터넨 회선이 요즘은 거의 IP공유기일테니, 여기서 port forwarding을 설정하면 되겠다. 단, Firewall이 내부네트웍을 보호하고 있다면 사용하는 port를 Exception에 추가해 주어야 할 것이다. Port forwarding을 2개를 등록해야 할 텐데, 하나는 AS Client용 Web 접속을 위한 것(예: 외부port 44444->내부   vpnip:943)과, OpenVPN접속을 위한 것(예: 외부port 44445->내부 vpnip:443)을 공유기 설정을 통해 등록하면 된다.

 이 경우 반드시 접속 전에 OpenVPNTech\config 로 찾아들어 가서 ovpn 파일을 열고 remote a.b.c.d 부분의 ip를  공유기의 공인 ip주소로 고쳐놓아야 한다.

본 테스트에서는 실제 Network 환경을 에뮬레이션하기 위해
1대의 서버(A)와 1대의 클라이언트(B) 컴퓨터와 각각에 VMware(VMware7 on Windows7)를 설치한다.
A에는
 - VM1: Ubuntu 9.10(Ram 512, Cpu1, HDD 10G), 2개의 가상 NIC을 만들고, 모두 Bridging 으로 설정
 - VM2.VM3: VM1과 동일한 설정으로 하되 NIC은 한 개만 생성(Bridging)

B에는
 - Remote 테스트용 클라이언트를 설치할 VM을 대충(Windows XP) 만들고 NIC은 한 개(Bridging)를 생성, 클라이언트측 Local 접속 IP 1개를 할당한다.


전체적인 개념을 도식화 하면 위의 그림과 같다.

1. OpenVPN-AS download & 설치
 http://www.openvpn.net/index.php/access-server/download-openvpn-as.html 에서 download
 dpkg -i openvpn-as-1.3.5-Ubuntu9.amd_64.deb
 * Admin web 접속계정은 편의를 위해 root 로 하자
 * 설치시 License Key를 물어오는데 Skip하고 나중에 등록하자

2. 설치 완료 후 https://localhost:943/admin 으로 Firefox 등을 통해 접속한다. 서버인증키 때문에 경고가 뜨는데 무시하고 접속한다(Firefox에서는 Exception으로 등록). 로그인 화면에서 root와 암호를 입력하면, 이후의 모든 설정은 Web을 통하여 관리가 가능하다.



3. OpenVPN 설정
OpenVPN AS 다운로드시 Sign-in을 하였을 것이다. http://www.openvpn.org 에서 로그인하면 License 를 조회 또는 이메일로 받을 수 있다. 여기서 License Key(2 User용 무료 License)를 복사하고, Configuration 메뉴의 License 를 클릭하여 New License Key에 Paste하고 버튼 클릭

서버측 네트워크를 맨 위의 그림을 참조하여 사용 환경에 맞게 설정한 후, User Permissions 메뉴를 선택하여 Client 접속을 위한 계정을 지정한다. 필요하면 Linux 시스템의 account를 추가하고 vpn 전용의 계정을 생성해 두고, Username 에 등록한 후, Allow Auto-login을 적당히 지정해 준다.

VPN Mode는 내부 Routing을 해야 하므로 Layer 3(routing/NAT) 을 선택하고 저장, VPN Setting 메뉴에서는 위의 그림에서 처럼 OpenVPN서버측의 Local network은 10.5.5.0/24 로 설정하고, Client에 제공할 IP 대역은 10.8.0.0/24로 설정한다(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 범위의 RFC1918 비공인IP대역중에서 네트워크 설계시에 적당히 선정해서 사용하자).

Routing 부분에서 VPN 서버측 Local network에 접속가능하게 설정한다.
 - Should VPN client have access to ....  => Yes, using NAT
 - Specify the private subnets to which... => 10.5.5.0/24
 - Should client internet traffic be routed...=> Yes를 선택하면 Client의 모든 인터넷 접속을 VPN 서버측 네트워크로
                                                               포워딩하므로 Client측 보안성이 최대화된다.
 - Should client be allowed to access...  => Yes

Save Setting 하고, Status Overview 메뉴를 클릭하여 OpenVPN을 Start 한다.

4. 클라이언트 PC에서 https://openvpn설치서버의공인ip:943 로 접속한다. 역시 서버인증키 경고가 뜨는데
무시하고 접속한다.


Default 또는 AutoLogin 중에서 하나를 선택하고, OpenVPN_Installer.exe 를 다운로드하여 설치한다(기존에 OpenVPN Server 용 Client가 설치되어 있다면 uninstall 후 진행하여야 한다).

다음, client.ovpn 파일을 다운로드 받는다. OpenVPN Server 버전과 달리 이 ovpn 파일에는 모든 인증키와 접속 정보가 자동으로 저장되어 여러 모로 사용이 편리하다.

이제 OpenVPN Client가 자동으로 접속을 시도하고 아래 그림처럼 접속아이콘이 바뀌면 성공적으로 OpenVPN AS 서버에 접속이 성공한 것이다.


이제 맨위의 그림대로 OpenVPN 서버측에 ping으로 접속 가능 여부를 확인해보자


<End>



저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들


대표적 Open source VPN인 OpenVPN은 point-to-point 접속을 구현하는 SSL VPN 솔루션이다. VPN은 일반적으로 PPTP, L2TP, SSL VPN, IPSec VPN, MPLS VPN 등이 있고, 유명 벤더의 VPN Router 제품도 시중에 나와 있다. 일반적인 상용장비들은 모든 표준들을 준수하며, 100, 1000 user 이상의 접속을 고속으로 처리하도록 VPN전용 OS와 하드웨어를 개발하여 제품화하고 있는 것이다.


요즘 시중의 iptime 기종 같은 인터넷공유기도 pptp VPN 정도는 거의 지원하는데, openvpn이나 windows의 pptp vpn 설정을 통해 VPN을 사용할 수도 있겠다. 한편, 100 user 이내의 Small Office의 경우, 외부에서 방화벽이나 NAT로 차단된 상황에서 사무실 내부로 접속이 필요하다거나, IDC의 특정 서버로 관리를 위한 빈번한 접속이 필요하지만(Point-To-Point), 중/대규모 통신은 그다지 필요하지 않다면, 비용적인 측면에서 OpenVPN을 써 봄이 좋을 듯하다. 나름 단순하면서도 속도도 쓸만 하다고 사람들은 말한다.


Mac OS X 10.3 이상에서는 PPTP, L2TP, IPSec 까지 포함되어 있다고도 하고, Windows 2000 Server 급 이상의 OS에서도 역시 VPN 서버 기능을 제공하고 있다(이건 나중에 알아보기로 하자)

OpenVPN을 설치한 서버에서 iptables로 매스커레이딩을 하거나 라우팅 기능을 이용한다면 상용 장비들이 제공하는 Point-To-Multi 형태의 사용도 가능해지게 된다. 물론 성능면에선...조금 거시기하겠지만 SOHO용이므로 그런대로 쓸만하지 않을까 한다.


개념 정리


개념을 정리해 보자면, VPN solution의 적용 방식은 조합을 해본다면 여러가지가 나오겠지만, 일반적으로 사용목적에 따라 Site-to-site와 Remote Access의 2가지로 나뉘며, 실제 적용 방법은 크게 아래의 4가지 정도로 정리된다.


 - Site-to-site with IPsec
 - Remote Access Using PPTP
 - Remote Access Using L2TP and IPsec
 - Site-to-site and Remote Access Using OpenVPN


주의할 것은, OpenVPN을 SSL VPN으로 오해하는 경우가 간혹 있는데, Open VPN은 OpenSSL의 암호화, 인증방식을 사용하는 것이지, 일반적인 SSL VPN처럼 Web을 통한 VPN 접근/사용 위주의  SSL VPN 솔루션이라는 오해가 없기를 바란다. 또한 OpenVPN 자체는 업계표준의 VPN이 아닌 자체 프로토콜을 적용한, 소위 표준에는 해당되지 않는  별도의 VPN솔루션이라는 점에 유의하자.

여기에서는 OpenVPN의 기본적인 개념과 설치, 설정, 접속을 위한 절차를 정리해 둔다.


1. 요구사항을 요약하면 간단히 아래 그림처럼 표현된다



2. OpenVPN 서버의 설치(Ubuntu 9.10, OpenVPN 2.1.1, openssl 2.0 기준)

OpenVPN Server 다운로드 설치한다. 방법은 

1)  http://www.openvpn.net 에서 타르볼이나 zip으로 된 소스를 다운로드 받고 tar -xvzf...해서 ./configure, make, make install 하여 컴파일해서 빌드하거나 

2) rpm을 다운로드 받아서 dpkg로 설치하거나 

3) apt-get 으로설치한다거나 하는

여러 방법이 있겠지만 ubuntu의 시냅틱관리자에서 간편하게 설치할 수 있으므로 이 방법을 써 보자. 참고로 위의 1번처럼 source를 받아서 자체 빌드를 하기 위해서는 openssl, lzo, pam 과 같은 라이브러리 패키지들이 필요한데, 개발환경에서 서버에 맞게 안정적으로 사용하기 위해서는 이 방법을 쓰는 것이 더 낫다. 자동 provisioning과  발급까지 고려한 솔루션이라면 더욱 더 이 방법을 써야 할 것이다.

여기서는 시냅틱패키관리자를 띄우고 검색에서 openvpn을 치면 패키지가 목록에 뜬다. 체크하고 적용하면 간단히 설치 끝. 예전 버전에서는 설치 후에 tun 또는 tap device를 /dev/net 아래 만들어서 커널에서 지원하도록 별도 설정을 해야 했지만, 지금은 설치하면 자동으로 /dev/net/tun device가 만들어져 있음을 알 수 있다.

설치 후 vpn 기능을 사용하려면 키 파일이 필요한데, 키 생성을 위해서 시냅틱관리자에서 openssl 패키지도 설치해둔다.


3. Root CA 서버 인증키 생성

OpenVPN 용 Root CA 인증서(*.crt)와 키파일(*.key)을 만들기 위해 /usr/share/doc/openvpn/examples/easy-rsa/2.0 으로 간다. 

su - 해서 root 로 수행한다. rpm으로 설치한다면 이 디렉토리가 맞을 것이다.

나중에 패키지 업그레이드 시를 대비한다면
# cp -r /usr/share/doc/openvpn/* /etc/openvpn/ => 원본 디렉토리는 보존하고 복사본으로 설정작업을 한다 여러번 수행할 경우에 대비 vars 파일의 가장 끝 부분을 아래와 같이 수정하자

     export KEY_COUNTRY=KR
     export KEY_PROVINCE=NA
     export KEY_CITY=Seoul
     export KEY_ORG="mydomain.com"
     export KEY_EMAIL=name@mydomain.com

# . ./vars => space 1칸 주의(source ./vars 와 같다)
# source ./clean-all
# ./build-ca => Enter 만 탁탁~

이렇게 하면
./keys 디렉 ca.crt(공개인증서), ca.key(개인키파일), index.txt, serial 파일이 만들어진다


4. 서버키 생성

서버에서 사용할 인증서, 키파일이 위에서 생성한 Root CA를 이용해서 sign되어 아래와 같이 생성한다.
# ./build-key-server server => Enter,... 끝에 Sign the certificate? 부터 2번의 y/n은 y 선택

이렇게 하면 server 라는 common name으로 ./keys 디렉토리에 서버인증서와 키 파일들이 만들어진다.


5. 클라이언트키 생성

클라이언트에서 사용할 인증서, 키파일을 아래와 같이 생성한다.
# ./build-key my-client

이렇게 하면 my-client 라는 common name으로 ./keys 디렉토리에 클라이언트인증서와 키 파일들이 만들어진다.


6. Diffi Hellman 암호화를 위한 pem 파일 생성

# ./build-dh

./keys 디렉토리 내에 dh1024.pem 파일이 생성된다.


7. 키파일 복사 & 보관

나중에 클라이언트에서 사용하기 위해서 방금 생성한 클라이언트 키 파일들을 따로 보관해 둘 필요가 있다.

# mkdir -p /root/client-keys
# cp ./keys/ca.crt ./keys/my-client.* /root/client-keys
# cd /root
# zip my-client-keys.zip client-keys/ca.crt client-keys/my-client.crt client-keys/my-client.key


8. 설정파일, 키파일 복사, 설정 편집, 기동

# cd /usr/share/doc/openvpn/examples/sample-config-files
# gunzip server.conf.gz
# cp server.conf /etc/openvpn
# cd /usr/share/doc/openvpn/examples/easy-rsa/2.0
# cp keys/server.* /etc/openvpn/
# cp keys/dh1024.pem /etc/openvpn/
# cp keys/ca.* /etc/openvpn/

# vi /etc/openvpn/server.conf => 해당 항목을 찾아 수정한다
    server 10.8.0.1 255.255.255.0 => openvpn server subnet 설정
    ; OpenVPN 서버를 gateway로 사용할 경우 10.8.1.0 255.255.255.0 으로 서브넷을 준다
    client-to-client => client 끼리 서로 인식할 수 있게
    duplicate-cn => 동일한 클라이언트 인증서로 여러 클라이언트가 쓰게
    max-clients 100 => 최대 동시 접속자 수
    plugin /usr/lib/openvpn/openvpn-auth-pam.so login => 시스템 계정으로 로그인 되게


* Gateway 설정, 10.8.1.* 대역의 서버들과 외부 클라이언트 사이의 gateway로 설정하고, VPN 클라이언트의 모든 인터넷 접속 요청을 모두 VPN server를 통해서 처리하려면(서버쪽의 보안성을 활용, 클라이언트측 보안성 극대화) 아래와 같이 한다(tun 사용, 즉 routed VPN일 경우)

push "redirect-gateway def1" ==> server.conf 에 추가(또는 un-comment)
다음, linux prompt에서

# echo 1 > /proc/sys/net/ipv4/ip_forward
# echo 'iptables -t nat -A POSTROUTING -s 10.8.1.0/24 -o eth0 -j MASQUERADE' >> /etc/init.d/rc.local ==> 하지 않으면 1회성
# iptables -t nat -A POSTROUTING -s 10.8.1.0/24 -o eth0 -j MASQUERADE
# iptables -t nat -L
# push "dhcp-option DNS 10.8.0.1" ==> VPN서버 자체가 DNS 기능을 가진다면 이와 같이 설정하면 된다.

* 만약 단순히 VPN client가 VPN서버측의 네트워크와 동일한 위치의 나머지 서버들에 접속할 수 있도록 하려면
(이 경우도 역시 tun 사용, 즉 routed VPN일 경우)

push "route 211.150.240.0 255.255.255.0"

==> server.conf에 설정(서버 위치의 네트웍이 211.150.240.0/24 라면)

다음, linux prompt에서
# echo 1 > /proc/sys/net/ipv4/ip_forward ==> ip forwarding 가능하게
# iptables -A INPUT -i tun+ -j ACCEPT
# iptables -A FORWARD -i tun+ -j ACCEPT
으로 설정하여 사용


서버의 설정이 끝났으면 아래와 같이 기동/종료/재시작 할 수 있다.
# /etc/init.d/openvpn start
# /etc/init.d/openvpn stop
# /etc/init.d/openvpn restart


9. 클라이언트 설치, 키 복사 & 접속

linux 클라이언트라면 openvpn 설치 후
# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn
# cd /etc/openvpn
# 위에서 압축해서 보내준 client-keys.zip 파일을 여기에 해제
# vi client.conf => 설정 파일을 편집, 아래 2줄을 추가 편집
    remote 168.126.189.55 1194
    auth-user-pass => server.conf에서 linux등의 시스템 계정으로 plugin(위 설명 참조)을 지정했다면 반드시 이 줄을 추가

# /etc/init.d/openvpn start => 서버쪽으로 접속 시도

windows 클라이언트라면
openvpn-2.x.x-gui-1.x.x-install.exe 을 다운받아서 설치하고 최근 버전은 여기(http://openvpn.se/download.html) 에서 다운받을 수 있다.

위에서 압축해서 보내준 client-keys.zip 파일을 openvpn configuration directory에 풀고(client-keys 내의 키파일들을 이 디렉토리에 복사해야 한다. 클라이언트측 필수 파일은 ca.crt, my-client.crt, my-client.key)

OpenVPN client 가 설치된 디렉토리를 찾아서 ...x86/openvpn/sample-config/client.ovpn 파일을
...x86/openvpn/config 디렉토리로 복사한 후, client.ovpn 파일을 편집기로 열어서(또는 트레이에서 Edit config)


* 중요한 Client 설정 몇가지...

    dev tun => tun/tap 중에서 server측과 맞춘다
    proto udp => tcp/udp 중에서 역시 server측과 맞춘다
    remote 130.5.120.55 1194 => 부분의 ip를 OpenVPN 서버로 접속되도록 대표ip 또는 openvpn 서버의 ip로 지정
    ca ca.crt => 여기부터 아래 3개 cert 항목은, 필요 없는 항목은 반드시 # 로 comment 처리(중요!)
    cert my-client.crt
    key my-client.key
    ns-cert-type server => server 설정에 따라 켜거나 또는 꺼야 한다
    auth-user-pass => server 계정을 사용하여 인증후에 접속해야 하는 경우에 사용

트레이아이콘에서 접속 시도 -> 접속에 성공하면 OpenVPN 서버와 클라이언트 간의 가상 전용회선이 뚫린 것이므로 마음대로 쓰면 된다.



- Barracuda -




저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들

Tag openvpn, VPN