홈 서버 만들기 12. VPN: IKEv2 (strongSwan)

May 10, 2018

VPN (Virtual Private Network)은 외부에서 내부 네트워크에 접속할 수 있게 해주는 기능으로, 이 접속은 암호화 되기 때문에 보안성도 뛰어나다. 이를 활용하면 집안에서만 연결할 수 있던 SMB 네트워크 드라이브를 집 밖에서도 연결할 수 있는 등, 내부 네트워크에서만 할 수 있던 모든 일을 외부에서도 할 수 있게 된다. 또한 VPN에 연결하면 외부에서 사용 중인 공인 IP 주소가 홈 서버의 공인 IP 주소로 바뀌게 되므로 여러 가지 보안이 필요한 일에도 활용할 수 있다.

VPN을 구성하는 방식에는 여러 종류가 있는데, 그중에서 보안성이 뛰어난 IKEv2 방식을 선택했다. IKEv2 방식은 윈도우 7 이상, macOS 10.11 (El Capitan) 이상, iOS 9 이상, BlackBerry OS 10 이상에서 운영체제의 기본 기능으로 접속할 수 있고, 안드로이드는 4.0.3 이상의 버전에서 strongSwan VPN Client 앱을 이용해서 접속할 수 있다.

포트 포워딩

VPN은 UDP 500번 포트와 UDP 4500번 포트를 사용한다. 인터넷 공유기를 사용하고 있다면 포트 포워딩 기능을 이용해서 UDP 500, UDP 4500 포트가 홈 서버 컴퓨터로 향하도록 포워딩한다.

서브 도메인 생성

VPN 접속 주소를 별도로 관리 하고 싶다면 서브 도메인을 하나 생성한다. 여기서는 vpn.example.com을 생성한 것으로 가정한다.

SSL/TLS 인증서 발급

IKEv2 방식으로 VPN을 구성하려면 vpn.example.com 도메인에 대한 SSL/TLS 인증서를 발급받아야 하는데, Let’s Encrypt 서비스를 이용하면 무료로 발급받을 수 있다. Let’s Encrypt 인증서 발급 방법은 앞선 글 07. SSL/TLS 인증서를 참고한다. 이 방법으로 인증서를 발급받으면 *.example.com 형태의 와일드카드 서브 도메인에 대한 인증서가 발급되므로 이 인증서를 그대로 vpn.example.com 도메인에 사용할 수 있다.

VPN (IKEv2) 구성

sudo apt-get update
sudo apt-get install strongswan

패키지 저장소 내용을 업데이트하고, IKEv2 방식의 VPN을 구성할 수 있는 strongswan을 설치한다.

sudo ln -f -s /etc/letsencrypt/live/example.com/cert.pem /etc/ipsec.d/certs/cert.pem
sudo ln -f -s /etc/letsencrypt/live/example.com/privkey.pem /etc/ipsec.d/private/privkey.pem
sudo ln -f -s /etc/letsencrypt/live/example.com/chain.pem /etc/ipsec.d/cacerts/chain.pem

앞선 글 07. SSL/TLS 인증서를 참고해서 인증서를 발급받았다면, 발급받은 인증서를 VPN에 사용하기 위해서 심볼릭 링크를 생성한다. example.com 부분을 바꾸는 등 자신의 인증서 경로를 정확히 입력한다.

sudo nano /etc/apparmor.d/local/usr.lib.ipsec.charon

AppArmor의 usr.lib.ipsec.charon 프로필을 nano 편집기로 열어서 인증서를 사용할 수 있도록 아래의 내용을 추가한다.

/etc/letsencrypt/archive/example.com/* r,

example.com 부분을 자신의 것으로 바꿔서 작성하고, 작성을 마쳤으면 Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다.

sudo cp /etc/ipsec.conf /etc/ipsec.conf.original

/etc/ipsec.conf 파일에서 VPN의 세부 사항을 설정하는데, /etc/ipsec.conf 파일 내용을 새로 작성할 것이므로 원본 파일을 ipsec.conf.original 파일명으로 백업해둔다.

echo '' | sudo tee /etc/ipsec.conf

/etc/ipsec.conf 파일 내용을 삭제한다.

sudo nano /etc/ipsec.conf

nano 편집기로 /etc/ipsec.conf 파일을 열어서 아래 내용을 작성한다.

config setup
    strictcrlpolicy=yes
    uniqueids=never

conn ikev2-vpn
    auto=add
    compress=no
    type=tunnel
    keyexchange=ikev2
    fragmentation=yes
    forceencaps=yes
    ike=aes256gcm16-sha256-ecp521,aes256-sha256-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024!
    esp=aes256gcm16-sha256,aes256gcm16-ecp384,aes256-sha256,aes256-sha1!
    dpdaction=clear
    dpddelay=300s
    rekey=no
    left=%any
    leftid=*.example.com
    leftcert=/etc/ipsec.d/certs/cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightauth=eap-mschapv2
    eap_identity=%identity
    rightsourceip=10.10.10.0/24
    rightdns=168.126.63.1,168.126.63.2
    rightsendcert=never

확인해야 할 주요 옵션은 아래와 같다:

leftid=  → 접속 주소로 vpn.example.com 등의 서브 도메인을 사용한다면 인증서의 와일드카드 서브 도메인 *.example.com을 입력한다.
leftcert=  → cert.pem 인증서 파일의 심볼릭 링크 경로를 입력한다.
rightsourceip=  → VPN에 접속한 클라이언트가 부여받을 내부(사설) IP 주소의 범위인데, 보통 192.168.x.x 범위의 내부 IP 주소는 인터넷 공유기 하단의 각 디바이스에게 할당되므로 VPN으로 접속한 외부의 디바이스에게는 10.x.x.x 범위의 내부 IP 주소를 할당하면 IP 간섭을 없앨 수 있다.
rightdns=  → 사용할 DNS 서버의 IP 주소를 기록하는데, 보통 홈 서버 컴퓨터에 연결된 인터넷 회선의 DNS IP 주소를 입력하면 된다. 위에 예시로 든 168.126.63.1,168.126.63.2는 KT 인터넷 회선의 DNS IP 주소이다. 만일 구글이 제공하는 DNS IP 주소를 사용하려면 8.8.8.8,8.8.4.4를 입력한다.

그밖의 옵션은 위의 예시를 그대로 입력해도 되는데, 자세한 내용은 strongSwan 웹사이트의 설명을 참고한다.

작성을 끝냈으면 Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다.

sudo nano /etc/ipsec.secrets

VPN에 접속할 계정을 설정하기 위해 /etc/ipsec.secrets 파일을 nano 편집기로 연다.

*.example.com : RSA "/etc/ipsec.d/private/privkey.pem"
사용자명 %any : EAP "비밀번호"

빨간색 부분을 자신의 것으로 바꿔서 위의 형식대로 /etc/ipsec.secrets 파일의 끝부분에 기록한다. 앞서 leftid=에 설정한 도메인, privkey.pem 파일의 심볼릭 링크 경로, VPN에 접속할 때 사용할 사용자명과 비밀번호를 결정해서 위의 형식대로 입력한다. 오른편 항목에는 양 끝에 " " 가 있음을 유의하고, 비밀번호에 “가 포함되지 않도록 선택한다. 작성을 끝냈으면 Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다.

sudo iptables -A INPUT -p udp -m udp --dport 500 -j ACCEPT
sudo iptables -A INPUT -p udp -m udp --dport 4500 -j ACCEPT

iptables 방화벽에서 VPN이 사용하는 UDP 500, UDP 4500번 포트를 허용한다. (기본적인 방화벽 세팅은 03. 우분투 서버 18.04 LTS 기본 설정에서 완료했다.)

sudo iptables -A FORWARD -s 10.10.10.0/24 -m policy --dir in --pol ipsec --proto esp -j ACCEPT
sudo iptables -A FORWARD -d 10.10.10.0/24 -m policy --dir out --pol ipsec --proto esp -j ACCEPT

iptables 방화벽에서 ESP 트래픽을 포워딩하는 규칙을 생성한다. 만약 앞 단계의 /etc/ipsec.conf 설정에서 10.10.10.0/24 IP 주소 범위를 다른 범위로 바꿨다면 여기서도 10.10.10.0/24 대신에 바꾼 범위로 입력해야 한다.

networkctl status

이제 홈 서버 컴퓨터의 이더넷 인터페이스(랜 카드)를 지칭하는 이름을 확인해야 하는데, 위 명령을 실행하면 출력되는 메시지 중에서 Address: 123.123.123.123 on ens33 이런 항목에서 이름이 ens33 인 것을 확인할 수 있다. ens33 은 시스템에 따라 enp3s2 등의 다른 형태가 될 수도 있다.

sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens33 -m policy --dir out --pol ipsec -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens33 -j MASQUERADE

VPN에 접속한 클라이언트가 인터넷을 사용할 수 있도록 iptables 방화벽에 규칙을 추가한다. ens33을 자신의 이더넷 인터페이스 이름으로 바꿔서 입력해야 한다. 만약 앞 단계의 /etc/ipsec.conf 설정에서 10.10.10.0/24 IP 주소 범위를 다른 범위로 바꿨다면 여기서도 10.10.10.0/24 대신에 바꾼 범위로 입력해야 한다.

sudo iptables -t mangle -A FORWARD -s 10.10.10.0/24 -o ens33 -p tcp -m policy --dir in --pol ipsec -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360

VPN 접속 안정성을 높이기 위해서 패킷 사이즈를 조절하는 규칙을 iptables 방화벽에 추가한다. ens33을 자신의 이더넷 인터페이스 이름으로 바꿔서 입력해야 한다. 만약 앞 단계의 /etc/ipsec.conf 설정에서 10.10.10.0/24 IP 주소 범위를 다른 범위로 바꿨다면 여기서도 10.10.10.0/24 대신에 바꾼 범위로 입력해야 한다.

sudo netfilter-persistent save
sudo netfilter-persistent reload

iptables 방화벽 설정을 저장하고 리로드한다. (iptables-persistent는 03. 우분투 서버 18.04 LTS 기본 설정에서 설치했다.)

sudo nano /etc/sysctl.conf

nano 편집기로 /etc/sysctl.conf 파일을 열고 아래의 항목을 찾아서 패킷 포워딩 설정을 마무리한다.

net.ipv4.conf.all.rp_filter=1
net.ipv4.ip_forward=1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.ip_no_pmtu_disc = 1

위 항목을 찾아서 주석 #을 제거하고 위의 값으로 설정한다. 마지막 net.ipv4.ip_no_pmtu_disc = 1은 /etc/sysctl.conf에 없는 항목이므로 끝부분에 직접 추가해준다.

sudo reboot

홈 서버 컴퓨터를 한 번 재시작해서 모든 설정을 온전히 작동시키면 VPN 접속이 가능해진다.

클라이언트에서 VPN 접속

각 클라이언트 디바이스마다 용어를 조금씩 다르게 사용하긴 하지만 입력하는 내용은 같다. VPN 유형을 선택하는 항목에 IKEv2, 서버 주소 항목에 vpn.example.com, 원격ID 항목에 vpn.example.com, 로컬ID 항목은 비워두고, 인증 유형은 “사용자 이름”으로 선택하고, 사용자명과 비밀번호 항목에는 앞서 /etc/ipsec.secrets 에 설정한 사용자명과 비밀번호를 넣고 접속하면 된다. 접속되었으면 외부에서도 마치 내부 네트워크에 있는 것처럼 내부 IP 주소의 SMB 네트워크 드라이브를 연결하는 등, 여러 가지로 활용할 수 있다.

 

 

홈 서버 만들기 목차 
https://varins.com/category/server

01. 하드웨어 구성과 전기 요금
02. 우분투 서버 18.04 LTS 설치
03. 우분투 서버 18.04 LTS 기본 설정
04. 파일 복원: Btrfs 스냅샷
05. 네트워크 파일 공유: Samba (SMB)
06. Dynamic DNS: 구글 도메인 + ddclient
07. SSL/TLS 인증서: Let's Encrypt (Wildcard)
08. 웹 서버: Nginx, 서버 블록, https 보안연결
09. 웹사이트: php + MariaDB + WordPress
10. 서버 모니터링: Monitorix + Nginx Proxy
11. FTPS: vsftpd
12. VPN: IKEv2 (strongSwan)
13. Torrent: Transmission
14. 클라우드 스토리지: Nextcloud (Nginx, MariaDB)
15. 온라인 오피스: 온리오피스 (Docker, Nginx)
16. 트랜스코딩: Plex
17. VNC RDP 클라이언트: Guacamole (Docker, Nginx)
18. 가상 머신: QEMU-KVM + libvirt + virt-install
19. 시스템 업그레이드: i3 8300T, 970 EVO 전력 사용량
20. 서버 모니터링: netdata + Nginx Proxy
Prev Post Next Post