티스토리 뷰

Security/System&Tools

Wireguard

Jacob_baek 2020. 7. 2. 17:21

개념

wireguard는 임베디드 인터페이스와 슈퍼컴퓨터에서 모두 실행하기 위해 설계된 사용이 매우 간단하면서 빠른 현대의 VPN이다.

NOTE
wireguard의 장점을 faster, secure 등으로 언급하고 있는데
이에 대한 근거를 아래 링크를 통해 일부 해소할수 있다.

구성

wireguard 는 다음과 같이 구성된다.

  • Server 가 존재하며 private,public key를 생성하여 wireguard를 구동시킨다.
  • Client 는 Server의 public key를 기반으로 client가 자체로 private,public key를 생성하여 암호화를 위한 터널 생성을 수행한다.

생각보다 Simple 하다.

운영 환경

다음과 같은 환경에서 wireguard 구성을 하고 vpn 연결을 수행해보자.

  • Server : Centos 8
  • Client : Ubuntu 20.04

설치 및 사용법

wireguard server

wireguard를 설치하기 위해 epel 패키지를 설치하고 wireguard 도구와 모듈을 설치한다.

sudo dnf install epel-release elrepo-release -y
sudo dnf install kmod-wireguard wireguard-tools -y

wireguard는 ssh처럼 암호화 키를 통해 통신을 암복호화 하기 때문에 관련된 키를 생성해야 한다.

wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey

생성된 키를 사용하여 wireguard interface 생성한다.

[root@wireguard wireguard]# cat jacob-wg.conf
[Interface]
Address = 10.99.99.1/24
SaveConfig = true
PostUp = firewall-cmd --zone=public --add-port 51820/udp && firewall-cmd --zone=public --add-masquerade
PostDown = firewall-cmd --zone=public --remove-port 51820/udp && firewall-cmd --zone=public --remove-masquerade
ListenPort = 51820
PrivateKey = ## private_key (앞서 생성한 /etc/wireguard/privatekey 의 내용)
  • Address
  • PostUp/Down 의 경우 ListenPort에 대한 통신을 제어할것을 고려하여 사전에 방화벽에 allow 시켜줘야 하기 때문에 firewalld / iptables 등의 명령을 해당 라인에 추가한다.

file permission 변경한다.

[root@wireguard wireguard]# chmod 600 /etc/wireguard/{privatekey,jacob-wg.conf}

이제 wireguard 서버 설정은 완료되었다.
서버를 구동해보자.

[root@wireguard wireguard]# wg-quick up jacob-wg
[#] ip link add jacob-wg type wireguard
[#] wg setconf jacob-wg /dev/fd/63
[#] ip -4 address add 10.99.99.1/24 dev jacob-wg
[#] ip link set mtu 1420 up dev jacob-wg
[#] firewall-cmd --zone=public --add-port 51820/udp && firewall-cmd --zone=public --add-masquerade
success
success

NOTE
위 설정중 firewall-cmd 혹은 iptables에 대한 postup, postdown에 대한 명령어가 정상적으로 반영되었는지 확인한다.
만약 이 설정이 제대로 들어가지 않는 경우 통신이 되지 않는다.

정상적으로 동작되는지 확인해보자.

[root@wireguard wireguard]# wg show jacob-wg
interface: jacob-wg
  public key: XXXXXX9eqnqnXXXXXXTM0FjoVGo6oqmpW4oXXXXXXXX=
  private key: (hidden)
  listening port: 51820
[root@wireguard wireguard]# netstat -unlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
udp        0      0 0.0.0.0:111             0.0.0.0:*                           1/systemd           
udp        0      0 127.0.0.1:323           0.0.0.0:*                           1025/chronyd        
udp        0      0 0.0.0.0:51820           0.0.0.0:*                           -                   
udp6       0      0 :::111                  :::*                                1/systemd           
udp6       0      0 ::1:323                 :::*                                1025/chronyd        
udp6       0      0 :::51820                :::*                                -                   

만약, 해당 인터페이스를 변경해야 해서 제거 혹은 수정해야 한다면
다음과 같이 wireguard interface를 down 시킨다.

[root@wireguard wireguard]# wg-quick down jacob-wg
..
[root@wireguard wireguard]# wg-quick up jacob-wg

재부팅시도 정상적으로 동작시키기 위해 아래와 같은 systemctl을 통해 서비스 등록을 해놓는다.

systemctl start wg-quick@jacob-wg

wireguard client

이제부터는 사용자 입장에서 vpn client 연결하는 작업을 해보도록 하겠다.
서버에서와 같이 wireguard 통신에 사용될 key를 생성한다.

wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey

다음과 같은 interface 설정 파일을 추가한다.

root@jacob-laptop:/etc/wireguard# vim /etc/wireguard/jacob-wg.conf
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY   # <==== Client 에서 생성한 PRIVATE_KEY
Address = 10.99.99.2/24           # <==== Client 에서 사용할 IP

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_IP_ADDRESS:51820
AllowedIPs = 10.99.99.1/32, 172.16.0.0/18
  • 여기서 참고해야 할것은 AllowedIPs에 추가해야 할 ip 주소정보이다. 만약 해당 주소를 추가해 놓지 않는다면 별도의 routing이 이루어지지 않아 vpn 연결의 의미가 없어진다.

NOTE
아래 작업은 wireguard server에서 수행해주어야 한다.

이제 client에서 생성한 pubkey를 이용해서 server에서 해당 ip를 허용하는 과정을 수행한다.
Wireguard server에 client의 public key를 등록해 놓아야 vpn 연결이 성공적으로 이루어진다.
(또한 IP는 앞서 wireguard에서 지정했던 네트워크 대역내에 IP를 중복되지 않게 설정해야 한다.)

[root@wireguard wireguard]# wg set jacob-wg peer XXXXXXlJhCv7lQPQ059XXXXXXBd7ChbDyZGDhXXXXXX= allowed-ips 10.99.99.2

이제 정상적으로 Wireguard Server에 등록되었는지 아래 명령어를 통해 확인해보자.

[root@wireguard wireguard]# wg 
interface: jacob-wg
  public key: XXXXXX9eqnXXXXXXxeTM0FjoVGo6oqmpW4otEXXXXXX=
  private key: (hidden)
  listening port: 51820

peer: XXXXXXXXXXXXXXPQ059FDZXMDBXXXXXXyZGDhXXXXXX=
  allowed ips: 10.99.99.2/32

NOTE
다시 client 에서 작업

다시 Client로 돌아와 아래 명령을 통해 확인해보면 wireguard가 연결되었음을 확인할 수 있다.

root@jacob-laptop:/etc/wireguard# wg-quick up jacob-wg
root@jacob-laptop:/etc/wireguard# wg
interface: jacob-wg
  public key: XXXXXXXXXXXXXXPQ059FDZXMDBXXXXXXyZGDhXXXXXX=
  private key: (hidden)
  listening port: 49284
  fwmark: 0xca6c

peer: XXXXXXXXXXqnJKkqxeTXXXXXXXXXXqmpW4otEatypjo=
  endpoint: SERVER_IP_ADDRESS:51820
  allowed ips: 0.0.0.0/0
  transfer: 0 B received, 296 B sent

routing table을 확인해보면 다음과 같이 추가된 network이 확인된다.

root@jacob-laptop:/etc/wireguard# ip route
default via 192.168.0.1 dev wlp0s20f3 proto dhcp metric 600 
10.99.99.0/24 dev jacob-wg proto kernel scope link src 10.99.99.2 
169.254.0.0/16 dev virbr1 scope link metric 1000 linkdown 
172.16.0.0/18 dev jacob-wg scope link 

wireguard의 재부팅 혹은 서비스 재시작시 각 peer의 pubkey가 초기화 될수 있다.
이를 방지하기 위해서는 앞서 서버에서 설정했던 jacob-wg.conf 파일에 각 peer의 정보를 아래와 같이 추가한다.

[root@wireguard wireguard]# cat jacob-wg.conf
[Interface]
Address = 10.99.99.1/24
SaveConfig = true
PostUp = firewall-cmd --zone=public --add-port 51820/udp && firewall-cmd --zone=public --add-masquerade
PostDown = firewall-cmd --zone=public --remove-port 51820/udp && firewall-cmd --zone=public --remove-masquerade
ListenPort = 51820
PrivateKey = ## private_key (앞서 생성한 /etc/wireguard/privatekey 의 내용)

[peer]
# user01
PublicKey = [user01_PublicKey]
AllowedIPs = 172.16.0.0/18, 10.99.99.1/32

[peer]
# user02
PublicKey = [user02_PublicKey]
AllowedIPs = 172.16.0.0/18, 10.99.99.1/32

아래와 같은 script을 통해 추가될 Public Key 및 IP를 추가할수도 있다.

#!/bin/bash
# $1 : pubkey , $2: ip addr

if [ "$#" -ne 2 ]; then
    echo "Please enter the argument public key and ip address"
    exit
fi

KEYCHECK=`grep $1 /etc/wireguard/jacob-wg.conf | wc -l`
IPCHECK=`grep "10.99.99."$2 /etc/wireguard/jacob-wg.conf | wc -l`

if expr $KEYCHECK > 0; then
    echo "Public Key is already used"
elif expr $IPCHECK > 0; then
    echo "IP address is already used"
else
    wg set hanu-wg peer $1 allowed-ips 10.99.99.$2
    wg | grep -A1 $1
    echo "Added wg peer at the wireguard"

    cp /etc/wireguard/jacob-wg.conf /etc/wireguard/jacob-wg.conf.bak
    echo "" >> /etc/wireguard/jacob-wg.conf
    echo "[Peer]" >> /etc/wireguard/jacob-wg.conf
    echo "PublicKey = $1" >> /etc/wireguard/jacob-wg.conf
    echo "AllowedIPs = 10.99.99.$2/32" >> /etc/wireguard/jacob-wg.conf
    echo "Added publickey at /etc/wireguard/jacob-wg.conf"
fi

또한 vpn 서버가 firewall과 동일한 서버위에서 동작중이 아니라면 firewall에서 앞서 설정한 network(10.99.99.x/24)에 대한
routing table이 추가되어야 한다. 그렇지 않으면 vpn 서버를 경유해서 전달된 packet이 돌아오지 못하는 현상이 발생될 수 있다.

## Example
root@firewall ~]# ip route add 10.99.99.0/24 via 172.16.0.253

혹은 wireguard vpn내에 iptables nat rule을 추가해서 nat 형태로 전달될수 있도록 해야 한다.

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 여기서 eth0는 wireguard를 통해 접속할 사내 네트워크가 연결된 interface

참고사이트

'Security > System&Tools' 카테고리의 다른 글

how to check certificate with openssl  (0) 2023.11.29
Teleport  (0) 2021.08.10
Grafana login using Keycloak OAuth  (0) 2021.06.15
metasploit  (0) 2013.06.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함