NAS & ODROID/NAS, ODROID

OpenVPN - VPN 개념, 서버 구축 가이드

awesometic 2017. 11. 1. 14:45
반응형

VPN

VPN (Virtual Private Network, 가상 사설망) 은, 저도 처음엔 의미를 이해하기 어려웠지만 사실 간단했어요. 정말 구라로 사설망을 만드는 거였어요.

위키에서 퍼온 이미지예요. Head-office에 VPN 서버를 설치했고, Remote는 외부에서 저희가 사용할 장치들이라고 생각하면 돼요.

VPN 서버가 연결되면 Remote 에서 보내는 모든 패킷이 인터넷을 건너 Head-office에 도착해요. 그리고 다시 Head-office에서 목적지로 향하는 거예요.

이게 가능하기 위해선 Remote와 Head-office 사이에 바로 패킷이 이동할 터널이 하나 있어야 해요. 터널링이라고 하고, 내부적으론 패킷을 두 번 캡슐화해 보내는 거죠. 캡슐화된 패킷의 바깥쪽 헤더는 Head-office에서만 알아보면 되니 모든 패킷은 캡슐화될 때 암호화가 될 수 있어요. 따라서 VPN을 사용하면 어떤 패킷이든 전부 암호화돼 VPN 서버에 먼저 도착합니다. 미심쩍은 카페나 식당에서 아무 와이파이를 써도 될 수 있게 안전해져요.

또한 터널링이 될 때, 터널링을 위해 사설 IP 대역을 하나 더 만들어요. 기존에 공유기가 192.168.0.0 대역을 사용한다면, VPN 서버 설치 시 tap이나 tun 등 가상 네트워크 드라이버를 통해 (기본값, A클래스) 10.8.0.0 대역이 하나가 더 생겨요. 서버는 게이트웨이이자 클라이언트니 10.8.0.1, 2를 갖고, 나머지 장치들이 접속할 때마다 DHCP를 통해 10.8.0.3, 4, .. 이렇게 할당받아 사용하겠죠. 이래서 가상 사설망이에요.

그런데 모든 패킷이 VPN 서버를 거친다는 점에서, 이것 저것 단점도 생겨요. 만약 직접 구축하지 않고 다른 인증되지 않은 VPN 서버를 사용한다면 모든 활동 내용이 동의 없이 저장될 수 있고, VPN 서버가 외국에 있으면 속도가 엄청나게 느리겠죠.

대충 이런 개념인데, 딱 이 개념대로의 VPN 서버 구축을 위해선 PPTP (Point-to-Point Tunneling Protocol) 기술을 활용할 수 있지만 암호화 수준이 낮아서 요샌 사용하지 않아요. 대신 암호화가 간단하기 때문에 빨라요. 요샌 이것을 대체해 설치가 (그나마) 간단, 성능, 보안도 좋은 오픈 소스 기반의 OpenVPN 을 사용해요. 다른 프로토콜들은 잘 모르겠네요. 원래 네트워크쪽은 잘 몰라요.

이 정도 개념이면 충분하다고 생각해요 :)


OpenVPN - CA 빌드

필요한 패키지들을 다운받고,

sudo apt update
sudo apt install openvpn easy-rsa

CA (Certificate Authority) 디렉토리를 생성해요. 굉장히 중요한 인증 키들을 갖고 있기 때문에 root/소유자 권한이 없으면 구경할 수도 없어요.

make-cadir ~/openvpn-ca
cd ~/openvpn-ca

각 키들에 서버에 관한 각종 정보가 입력돼 있어야 해요. 그 정보를 미리 입력해두기 위해 vars 파일을 변경해요.

vi vars

아래 부분을 찾아 변경해주세요.

export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

export KEY_NAME="server"

이메일만 바꿔도 상관 없지만, 맞게끔 써주는 게 제일 깔끔할 것 같아요. 이제 키를 생성하기 위해 CA를 빌드해요.

ln -s openssl-1.0.0.cnf openssl.cnf
. ./vars

# results
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/sammy/openvpn-ca/keys

./clean-all
./build-ca

묻는 질문에는 미리 설정해둔 기본값을 사용하기 위해 전부 엔터만 입력하세요.


OpenVPN - 서버 키 생성

먼저 서버 키를 생성해요.

./build-key-server server

묻는 말엔 전부 엔터 / y. challenge password에선 입력하지 마시고 그냥 엔터로 넘겨주세요. 그리고 DH(Diffie-Hellman) 키를 생성해요. 얜 조금 오래걸려요.

./build-dh

마지막으로 HMAC(Hash-based Message Authentication Code) 키를 생성해요.

openvpn --genkey --secret keys/ta.key

OpenVPN - 서버 설정

이제 OpenVPN 서버를 설정해야 해요. 생성한 키들을 /etc/openvpn 아래로 옮겨요.

cd ~/openvpn-ca/keys
sudo cp ca.crt server.crt server.key ta.key dh2048.pem /etc/openvpn
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf

server.conf 를 변경해야 해요.

sudo vi /etc/openvpn/server.conf

잘 따라가주세요.

##### 주석 해제 항목 #####
proto tcp # udp 는 주석 처리

push "redirect-gateway def1 bypass-dhcp"

push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

tls-auth ta.key 0

cipher AES-128-CBC

user nobody
group nogroup

##### 파일 마지막에 내용 추가 #####
key-direction 0
auth SHA256

OpenVPN - 서버 네트워크 설정

서버에서 해야할 설정이 몇 가지 있어요.

sudo vi /etc/sysctl.conf

# 아래 항목 주석 해제
net.ipv4.ip_forward=1

sudo sysctl -p

내부 포트포워딩 관련 작업으로,

sudo iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE

현재 iptables 정책을 매 부팅 시마다 자동으로 먹이기 위해 iptables-persistent 패키지를 설치해주세요. 현재 규칙을 저장하겠냔 말에 모두 Yes 해주세요.

sudo apt install iptables-persistent

그리고 공유기에서 서버로 1194 포트를 포트포워딩 해주세요.


OpenVPN - 서버 실행

이제 OpenVPN 서비스를 실행해요. 그리고 부팅 시 자동으로 시작되도록 등록해줘요.

sudo systemctl start openvpn@server

활성화가 됐나 보려면,

sudo systemctl status openvpn@server
● openvpn@server.service - OpenVPN connection to server
   Loaded: loaded (/lib/systemd/system/openvpn@.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2017-11-01 11:25:52 KST; 1h 6min ago
     Docs: man:openvpn(8)
           https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
           https://community.openvpn.net/openvpn/wiki/HOWTO
  Process: 680 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid 
 Main PID: 683 (openvpn)
   CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
           └─683 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --write

Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: GID set to nogroup
Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: UID set to nobody
Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: UDPv4 link local (bound): [undef]
Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: UDPv4 link remote: [undef]
Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: MULTI: multi_init called, r=256 v=256
Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: IFCONFIG POOL LIST
Nov 01 11:25:52 odroid-xu4q-main ovpn-server[683]: Initialization Sequence Completed
Nov 01 11:25:52 odroid-xu4q-main systemd[1]: Started OpenVPN connection to server.
Nov 01 12:31:55 odroid-xu4q-main systemd[1]: Started OpenVPN connection to server.

ip addr show tun0
3: tun0:  mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none 
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::6f7b:6f15:f38c:df4/64 scope link flags 800 
       valid_lft forever preferred_lft forever

tun 가상 네트워크 드라이버가 제대로 작동하네요. 이제 서비스 등록할게요.

sudo systemctl enable openvpn@server

OpenVPN - 클라이언트 키 생성

OpenVPN에 접속할 사용자들을 위한 키를 따로 생성해야 해요. vars 파일을 통해 환경 변수들을 설정한 다음 클라이언트 키를 생성해요.

cd ~/openvpn-ca
. ./vars
./build-key client1

예제니까 client1로 했는데, 사용자들의 이름이나 닉네임을 쓰시면 될 것 같아요.


OpenVPN - 클라이언트 인증서 생성

클라이언트 인증서를 관리할 디렉토리를 생성해요. 그리고 root/소유자 외엔 접근할 수 없도록 조치할게요.

mkdir -p ~/client-configs/files
chmod 700 ~/client-configs/files

클라이언트 설정 샘플 파일을 가져와 수정해요. 이 파일의 정보를 토대로 클라이언트 인증서들이 생성돼요.

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
vi ~/client-configs/base.conf
##### 서버의 공인 IP 또는 도메인으로 변경 #####
remote your-public-address-here 1194

##### 주석 해제 #####
proto tcp # udp 는 주석 처리
nobody
nogroup

##### 주석화 #####
#ca ca.crt
#cert client.crt
#key client.key

##### 파일 마지막에 내용 추가 #####
key-direction 1
cipher AES-128-CBC
auth SHA256

##### 클라이언트가 리눅스고, /etc/openvpn/update-resolv-conf 파일이 있을 경우에만 해당 주석 제거 #####
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf

이제 간단하게 클라이언트 인증서 생성을 위한 스크립트 파일을 만들어줘요.

vi ~/client-configs/make_config.sh

아래 내용을 복붙해주세요.

#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn
chmod 700 ~/client-configs/make_config.sh

인증서를 생성해요. 아까 만든 클라이언트 키에 해당하는 이름을 적어주세요. 여기선 예시로 client1.

~/client-configs/make_config.sh client1

생성이 완료되면 아래 명령어를 통해 방금 생성된 확장자가 .ovpn 인 인증서들을 볼 수 있어요.

ls ~/client-configs/files

# results
client1.ovpn

이 인증서 파일을 적당한 클라이언트 장치로 보내 사용하면 돼요.

누구나 이 인증서 파일만 있으면 내부 네트워크에 들어올 수 있으니 꼭 주의해주세요!


참고


반응형