본문으로 건너뛰기

WireGuard 기본 안내

WireGuard

WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.

WireGuard는 최첨단 암호화 기술을 활용한 매우 단순하고 빠르며 현대적인 VPN입니다.

서버와 클라이언트 모두 네트워크 인터페이스를 생성하며 이를 위한 설정 파일이 있습니다. wg0라는 네트워크 인터페이스를 설정하려면 /etc/wireguard/wg0.conf 파일을 생성하여 설정하면 됩니다.

Cryptokey Routing Table

서버의 설정파일 예시는 아래와 같습니다.

/etc/wireguard/wg0.conf
[Interface]
PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
ListenPort = 51820

# Peer1
[Peer]
PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
AllowedIPs = 10.192.122.3/32, 10.192.124.1/24

# Peer2
[Peer]
PublicKey = TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=
AllowedIPs = 10.192.122.4/32, 192.168.0.0/16

# Peer3
[Peer]
PublicKey = gN65BkIKy1eCE9pP1wdc8ROUtkHLF2PfAqYdyYBz6EA=
AllowedIPs = 10.10.10.230/32

패킷이 Peer -> Interface 방향으로 전달되면 PrivateKey로 패킷을 복호화합니다. 그리고 source IP가 해당 피어의 AllowedIPs에 포함되어 있다면 네트워크 인터페이스로 보내고 아니면 버립니다. 예를 들어 Peer1이 패킷을 보냈을때, source IP가 10.192.122.3이었다면 이 패킷을 허용하고 아니면 삭제합니다.

패킷이 Interface -> Peer 방향으로 전달되면 destination IP를 확인하여 피어 목록에서 해당 IP를 AllowedIPs로 가진 피어를 찾습니다. 피어를 찾았다면 패킷을 해당 피어의 PublicKey로 암호화하여 해당 피어의 가장 최근 엔드포인트로 보냅니다. 예를 들어 destination IP가 10.10.10.230이었다면 Peer3에게 패킷을 보냅니다.

패킷 라우팅 방식

직접 연결

한 피어가 로컬 네트워크에 있는 경우

피어들이 각자 다른 로컬 네트워크에 있는 경우

또는

설치 및 사전준비

sudo apt install wireguard

패킷 암호화/복호화에 사용될 키를 생성합니다.

umask 077 && wg genkey | sudo tee /etc/wireguard/private.key \
| wg pubkey | sudo tee /etc/wireguard/public.key > /dev/null

포워딩이 필요한 경우 ip_forward를 허용하도록 설정합니다.

echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf > /dev/null \
&& sudo sysctl -p /etc/sysctl.d/99-wireguard.conf

설정

/etc/wireguard/<interface>.conf
[Interface]
# 주석
# <option>
PrivateKey = ODBloDgfiVacBrsz0x5b2X0fvvFLy8/p2ckwHhIUa2E=
ListenPort = 51820
Address = 10.1.2.3/24
SaveConfig = true

[Peer]
PublicKey = MkodccJF0RADc4JN4+eKgmAITpIsNUMA2XO/CaDsQnE=
AllowedIPs = 10.1.2.4/32
AllowedIPs = 172.16.1.0/24
Endpoint = 172.16.1.2:12345
  • [Interface]
    • <option>
      • wg 옵션
        • PrivateKey = <key>
          • 복호화에 사용될 개인키입니다.
        • ListenPort = <port>
          • WireGuard가 사용할 UDP 포트입니다.
          • 선언하지 않으면 임의의 포트가 할당됩니다.
      • wg-quick 옵션
        • Address = <ip>/<cidr>[,<ip>/<cidr> ...]
          • WireGuard 인터페이스에 할당할 IP 주소 목록입니다.
          • IP4와 IP6을 지정할 수 있습니다.
          • 여러번 선언될 수 있습니다.
        • DNS = <ip|host>[,<ip|host>]
          • 인터페이스의 DNS 주소 목록입니다.
          • IP4, IP6, hostname을 지정할 수 있습니다.
          • 여러번 선언될 수 있습니다.
        • PreUp|PostUp|PreDown|PostDown = <script>
          • wg-quick up|down <intreface> 명령을 실행하기 전/후에 실행할 bash 스크립트입니다.
          • %i<interface>로 치환됩니다.
          • 여러번 선언될 수 있습니다.
        • SaveConfig = true|false
          • true로 설정한 경우 <interface>가 제거되기 전 변경된 사항이 있다면 /etc/wireguard/<interface>.conf에 반영됩니다.
  • [Peer]
    • 여러번 선언할 수 있습니다.
    • <option>
      • wg 옵션
        • PublicKey = <key>
          • 암호화에 사용될 공개키입니다.
        • AllowedIPs = <ip>/<cidr>[,<ip>/<cidr> ...]
          • 라우팅에 사용될 IP 주소 목록입니다.
          • IP4와 IP6를 지정할 수 있습니다.
          • 여러번 선언될 수 있습니다.
        • Endpoint = <ip|host>:<port>
          • 엔드포인트 정보가 없을 때 사용되는 기본값입니다.
          • 기본적으로 WireGuard는 다른 피어로부터 패킷을 받을 때 해당 피어의 엔드포인트 정보를 갱신합니다.
          • 최초 통신 시 또는 통신이 끊어진 후 일정 시간이 지나면 해당 피어의 엔드포인트를 알 수 없습니다.
        • PersistentKeepalive = <seconds>
          • 피어에게 ping을 보내는 주기입니다.
          • 기본값은 0으로 ping을 보내지 않습니다.
          • ping을 받은 피어는 보낸 피어의 엔드포인트 정보를 갱신합니다.
          • 25로 설정하는 것이 합리적입니다.(https://www.wireguard.com/quickstart/)

wg, wg-quick 커맨드

실행

sudo wg-quick up <interface>
정보

서비스에 등록하면 컴퓨터가 재부팅되어도 자동으로 실행됩니다.

sudo systemctl enable wg-quick@<interface>
sudo systemctl start wg-quick@<interface>

설정 업데이트

sudo wg set <interface> <option> [<option> ...]
  • <option>
    • listen-port <port>
    • private-key <key>
    • peer <pubKey> <option> [<option> ...]
      • <option>
        • remove
        • endpoint <ip>:<port>
        • persistent-keepalive <seconds>
        • allowed-ips <ip>/<cidr>[,<ip>/<cidr> ...]
sudo wg [show [<interface> [<field>]]]
정보

peer를 추가한 경우 allowed-ips에 대한 라우팅 테이블 수정이 필요합니다. (Interface.Address 선언 시 CIDR에 해당하는 IP는 자동으로 라우팅 테이블에 추가됩니다.)

sudo ip route add|del <ip>/<cidr> dev <interface>

중지

sudo wg-quick down <interface>