Openwrt : Wireguard 설치/설정.

꽃삽질이 되고 말았으나.. 그래도 해결은 했다. 딱 하나 빼고는.
그 딱 하나는 바로, VPN 연결 뒤 공유기에 정의된 호스트명으로 접근이 될 지 여부다. (이 얘긴 뒤에 다시.)

가능한한 Luci 로 설정하고, 때에 따라선 CLI 로 직접 수정한다. uci 도구는 아직 사용법에 익숙지 않아서, 여기선 전혀 언급하지 않는다.


꾸러미 설치

Luci 용까지 해서 총 3개를 설치한다.

** openwrt 21.02.0 이후부터는, 커널 5 를 사용하기 때문에 wireguard 꾸러미는 불필요하다. 커널에서 지원을 하므로 그냥 설정하면 되는 듯은 한데, 혹시 안된다면 kmod-wireguard 꾸러미가 필요할 수도 있겠다. (이전판까지는 wireguard 꾸러미를 설치해야먄 했다.)

opkg update
opkg install luci-proto-wireguard luci-app-wireguard

키 쌍 생성

공개키 쌍을 생성해야 하는데, 방법은 우분투 때와 같다.
다만, /etc/wireguard 디렉토리는 자동 생성되지 않는데, 꼭 여기다 넣어야 할 이유는 없지만, 그냥 다들 그리 하는 듯 하므로.. ‘보관’한다는 생각으로 여기에 넣어 놓는게 좋겠다.

mkdir -p /etc/wireguard
chmod 700 /etc/wireguard
cd /etc/wireguard
wg genkey | tee ./privatekey | wg pubkey > ./publickey

인터페이스 설정

Luci

Luci – Network – Interfaces 로 이동하여, Add New interface 를 실행한다.

이름은 보통 ‘wg0’ 등으로 주는 모양이니 그렇게 하도록 하고, Protocol 을 Wireguard VPN 으로 선택한다.

세부 설정은 다음과 같다.

General Setings(서버 역할)

  • Private Key : 위에서 생성한 Private Key
  • Listen Port : Private Port 영역(49152 ~ 65535)에서 적당하게 선택한다.
  • IP Addresses : 공유기가 속한 LAN IP 대역이 아닌, 클라이언트가 속한 대역도 아닌 새 대역의 IP 로 설정한다. IP/24 형식으로 넣어야 hostname사용할 수 있다. (ex. 10.3.3.1/24 등등)

Advanced Settings, Firewall Settings 는 지금 당장은 건드릴게 없다.

CLI

/etc/config/network 에 다음 내용을 추가한다.

config interface 'wg0'
	option proto 'wireguard'
	list addresses '10.3.3.1/24'
	option private_key '어쩌구 저쩌구..='
	option listen_port '51820' # 또는 적절히 선택.

config interface 뒤의 이름(wg0)은 달리 정해줘도 된다. 그러나, wg0 으로 쓰는게 많이 쓰이는 명명법이다.

Peers(서버에 접속 가능한 클라이언트 목록)

이전 글을 참고하여 클라이언트의 공개키, IP 등등을 넣어준다.

Luci 로는, Luci – Network – Interfaces – wg0 – Peers 로 이동하여 항목을 입력한다.

  • Description : 적당한 이름.
  • Public Key : wg genkey 로 클라이언트를 위해 생성한 공개키.
  • Allowed IPs : 서버에서 설정한 동일한 IP 대역의 다른 주소. (ex. 10.3.3.10 또는 10.3.3.10/32 등) 다만, 여기서는 10.3.3.10/24 는 안되고, 10.3.3.0/24 는 가능하다. (뒤에서 다시 정리)
  • Route Allowed IPs : 선택
  • Endpoint Host : 넣으나 안넣으나 큰 관계없다. 넣으려면, 서버의 주소(공인 IP)를 넣어준다.
  • Endpoint Port : Private Port 구간(49152 ~ 65535)에서 적절히 선택.
  • Persistent Keep Alive : 25 로 하라고 하는데..

CLI 로는, 다음과 같이 할 수 있다.

config wireguard_wg0 'wgclient_1'
	option route_allowed_ips '1'
	option public_key '어쩌고 저쩌고'
	option description '클라이언트#1'
	option persistent_keepalive '25'
	list allowed_ips '10.3.3.0/24'

** Allowed IPs: 단독 주소, 또는 대역 선택?

** 대역이 되긴 됐는데, 또 안될 때도 있다. 그냥, 기기당 하나씩 키쌍을 생성해서 따로 따로 설정을 해주는게 속편한 방법이라고 생각한다.

아래 글은 그냥 참고..


Allowed IPs 에는 구간(10.3.3.0/24 등)을 넣어도 되고, 단독 주소(10.3.3.10/32)를 넣어도 된다. 그런데, 여기에 10.3.3.3/24 를 넣으면 뭔가 오작동을 하기도 한다. (내 실수인지는 모르겠으나..)

‘대역도 가능하다’의 의미는, 공개키쌍을 하나만 만들고, 여러 기기에서 나눠쓸 수 있다는 뜻이 된다.
예를 들어, 같은 공개키 쌍을 전화기에, 랩탑에, 태블릿에 설치해놓고, 각각 IP를 달리 준 뒤 동시에 접속해도 사용이 가능하다.

  • 서버(Openwrt – wg0)의 Allowed IPs : 10.3.3.0/24
  • 전화기 : 10.3.3.2
  • 랩탑 : 10.3.3.3
  • 태블릿 : 10.3.3.4

이러면, 같은 공개키쌍으로 이용할 수 있다. 이 방법이 싫으면, Peer 설정을 그 수만큼 해줘어야만 한다. 즉, 공개키 쌍도 같은 수만큼 만들어야 한다.

** 대역을 선택했다면, Peer 를 추가할 때는 반드시 단독 IP 로.

예를 들어, Peer 가 하나라면 그냥 위와 같이 Allowed IPs 에서 구간을 넣어줘도 된다.
그러나, Peer 가 2개 이상일 때, 두 Peer 에 모두 같은 대역을 넣어주면, Openwrt Router가 패닉에 빠져버린다.

config wireguard_wg0 'wgclient_1'
	option route_allowed_ips '1'
	option public_key '어쩌고 저쩌고'
	option description '클라이언트#1'
	option persistent_keepalive '25'
	list allowed_ips '10.3.3.0/24'

config wireguard_wg0 'wgclient_2'
	option public_key '우짜고 저짜고'
	option description '클라이언트#2'
	list allowed_ips '10.3.3.0/24'
	option route_allowed_ips '1'

이처럼 Peer 가 2개 이상일 때, 두 개 설정에서 Allowed IPs 가 ‘10.0.0.0/24‘ 등으로 동일하게 설정되어 있다면, 공유기가 뭔가 이상한 상태에 빠진다. 다운되지는 않지만, ping 에도 반응하지 않고, ssh 접속, Luci 접속 모두 불가능해진다.

만약 Extroot 를 사용 중이라면 설정이 외부 매체에 저장되므로 공유기를 끄고, 이 매체를 빼서 다른 기기에 연결한 뒤 config/network 파일을 수정하면 되지만, 그렇지 않을 경우는 초기화하는 방법 밖에 없지 않을까. 재수없으면 아예 펌웨어를 다시 심어야할 지도.

내 기기(Gl-iNet BL1300)에서만 이런 현상이 생기는 지는 모르겠지만, 아무튼 이런 상황이 벌어진다.
따라서, Peer 가 2개 이상이고, 한 쪽에서 구간 설정을 해줬다면, 다른 쪽(들)은 단일 IP 로 지정을 해줘야만 한다.

config wireguard_wg0 'wgclient_1'
	option route_allowed_ips '1'
	option public_key '어쩌고 저쩌고'
	option description '클라이언트#1'
	option persistent_keepalive '25'
	list allowed_ips '10.3.3.0/24'

config wireguard_wg0 'wgclient_2'
	option public_key '우짜고 저짜고'
	option description '클라이언트#2'
	list allowed_ips '10.3.3.3'
	option route_allowed_ips '1'

** 대역에 관한 쓸데없는 얘기는 여기까지.


Interfaces 설정은 끝났다. 클라이언트(다른 기기) 설정은 이 글 맨 마지막에.
이제 Firewall 차례다.

Firewall 설정

포트 열기

Luci – Network – Firewall 로 이동하여, Traffice Rules 탭에서 Add 를 실행한다.

위에서 ‘포트’를 설정했으므로, 그 포트를 열어줘야 한다.

Add 후에 이름은 ‘AllowWireguard’ 등으로 적당히 준 뒤, 다음 항목을 설정한다.

  • Protocal : TCP UDP
  • Source zone : WAN 및 WAN6
  • Destination zone : Device (input)
  • Destination port : 위에서 선택한 포트 번호
  • Action : accept

Zones 설정

Luci – Network – Firewall 로 이동하여, General Settings 탭에서 Add 를 실행한다.

  • Name : wireguard 등으로 적당히.
  • Input/Output/Forward : 모두 accept
  • Masquerading : 선택
  • MSS clamping : 선택
  • Covered Networks : 위에서 만든 wg0

그리고 이제 Zone 간 포워딩 규칙을 설정해줘야 한다.

  • Allow forward to destination zones: lan, wan
  • Allow forward from source zones: lan

서버 설정은 끝. Save & Apply 로 설정을 적용한다.

클라이언트 설정

클라이언트 설정을 하기 위해선, 먼저 서버에서 Peer 설정을 해야 한다.
물론 나중에 해도 되긴 하지만.. 아무튼, 상호에서 서로를 인식할 수 있게끔 해줘야 하는데, 어렵게 얘기하자면, 서로 발행한 공개키를 양쪽 모두에 등록해야만 한다.

나름대로 쓸만한 QR코드 얘기 먼저.

(이 항목의 원래 제목은 ‘쓸데없는..’ 이었다. 헌데, 꼭 쓸데없지는 않더라.)

그/런/데!
Luci – Status – Wireguard Status 를 보면, QR-Code 를 보여주는 항목이 있다.

작은 글씨로 써 있는 내용을 우리말로 옮겨보자면, wg 인터페이스(즉 서버설정)에 따라 작성되고, Peer(클라이언트) 용으로 Private/Public 키를 매번(페이지 새로고침) 생성하여, 그 결과를 QR 코드로 보여준다고 한다.

정리하면 이렇다. Wireguard config 파일 형식에 따라,

  • Interface 항목 : (Peer 용) Private/Public 키를 새로 생성하여, 이 키들을 QR에 첨부.
  • Peer 항목 : 서버의 Publickey 를 첨부. Allowed IPs 로 0.0.0.0/0 추가.

이런 정보를 QR 로 만들어준다. 이걸 스마트기기에서 읽어오면, 해당 정보가 자동 입력이 되는데..

여기에 살짝 문제가 하나 있다. (처음에 이 글을 썼을 때는 ‘큰’ 문제라고 했었다.)

Wireguard 는 Peer to Peer 통신이 기본이므로, 상호 공개키를 서로 등록시켜줘야만 한다. 위 방법은, 클라이언트는 서버의 공개키를 알고 있지만, 서버는 클라이언트의 공개키를 알지 못하는 상황이 된다.

서버에 클라이언트의 공개키를 등록시켜주려면, 위에서 언급했듯, /etc/config/network 에 공개키가 저장되어야만 한다.

config wireguard_wg0 'wgclient_1'
	option route_allowed_ips '1'
	option public_key '어쩌고 저쩌고'
	option description '클라이언트#1'
	option persistent_keepalive '25'
	list allowed_ips '10.3.3.0/24'

‘어쩌고 저쩌고’가 바로 그 공개키인데, 이 공개키는 Luci 의 Show/Hide QR-Code 항목만으로는 생성되기만 할 뿐, openwrt /etc/config/network 에 자동 등록되지는 않는다.
따라서 이 공개키를 등록하려면, 스마트기기에서 QR 코드를 읽어온 후, 거기에 나타난 공개키를 눈으로 보고, 손으로 서버에 추가해주거나, 아니면 그 공개키를 어떤 식으로든 서버로 옮겨서 넣어주는 방법밖에 없다.

이런 불편함이 있긴 하지만, 뭐 그런대로 쓸만은 하다고 할 수 있겠다.
Gl-iNet BL1300 공식 펌웨어(Openwrt 이전 판 기반)에서는 이 기능을 좀 더 지능화시켜서, 서버에서 Peer 추가, 그에 따른 QR 코드 생성이 연동되어 작동하게끔 설계했다.

이 방식은, 스마트 기기를 변경하거나 분실하여 Wireguard 를 해당 기기에서 재설치한 후, 공개키쌍을 다시 생성하여 등록하고자 할 때 유용하다. QR 코드로 해당 정보를 입력받은 후, 생성된 공개키를 서버(Openwrt)의 /etc/config/network 에서 수정/등록만 해주면 된다.

하지만, 아예 처음부터 시작할 때는 그냥 수동으로 만드는 게 더 나은 방법이라 생각된다.

진짜 설정

클라이언트를 위한 공개키/개인키는 미리 만든다.

wg genkey | tee privatekey | wg pubkey > publickey

위 키 중 공개키는 서버의 Peers 항목에 등록시켜준다.
나머지 개인키로 설정 파일을 만든다. 스마트 기기에 등록한다는 전제하에 파일명은 아무거나(config-openwrt 라 가정). 그리고 이런 식으로 설정한다.

[Interface]
Address = (서버와 같은 대역으로, 맘대로 정한다.) (ex. 10.3.3.5/3)
PrivateKey = <이 클라이언트의 개인키>
DNS = <서버의 LAN IP> (ex. 192.168.1.1)

[Peer]
PublicKey = <서버의 공개키>
AllowedIPs = <VPN ID 대역>, <서버 LAN IP 대역> (ex. 10.3.3.0/24, 192.168.1.0/24)
Endpoint = <서버 주소>:서버 포트(서버 설정에서 ListenPort 로 설정한)

[Peer] 의 AllowedIPs 는 다음과 같이 두가지 방식 중 하나를 택할 수 있다.

  • <서버 LAN IP 대역> (ex. 10.3.3.0/24, 192.168.1.0/24)
  • 0.0.0.0/0

상위 설정을 따르면, VPN 연결한 후 기기의 공인 IP 가 원래 자신의 공인 IP 그대로 고정되며, 하위 설정, 즉 0.0.0.0/0 을 택하면 서버의 공인 IP 설정을 따라간다.
필요에 따라 적절히 선택해주면 된다.

[Interface] 에서 DNS 항목은 넣어줄 수도 안해줄 수도 있지만, Openwrt 공유기의 Hostnames 를 사용하려면, 반드시 공유기 LAN 주소를 DNS 로 넣어줘야 한다.

이제 다 만들어진 텍스트 파일을, QR 코드로 변환한다.

qrencode -t utf8 < config-openwrt

그러면 QR 코드가 터미널 상에 보이는데, 이걸 스마트기기에서 인식시키면 된다.

끝!!

Author: 아무도안

5 thoughts on “Openwrt : Wireguard 설치/설정.

  1. 안녕하세요? 글 잘 읽었습니다. 아직 다 이해하지는 못 했지만 벌써 많이 도움이 되었습니다.

    질문이 있는데 이 부분에 관한 것입니다: “상위 설정을 따르면, VPN 연결한 후 기기의 공인 IP 가 원래 자신의 공인 IP 그대로로 고정되며, 하위 설정, 즉 0.0.0.0/0 을 택하면 서버의 공인 IP 설정을 따라간다.”

    질문
    1. 위 말씀을 이렇게 이해해도 되나요?
    (a) 10.3.3.0/24, 192.168.1.0/24 설정이면 클라이언트 기기는 서버 LAN 에 속한 기기에 VPN 을 통하여 접속 그러나 인터넷은 VPN 을 통하지 않고 접속.
    (b) 0.0.0.0/0 설정이면 클라이언트 기기는 서버 LAN과 인터넷을 모두 VPN 통하여 접속.

    0.0.0.0/0 이 서버 LAN 에 속한 서버 외 기기에 접속을 가능하게 해준다면, 그건 Wireguard 서버 앱이 공유기에 설치되었을 때나 그렇겠죠?
    0.0.0.0/0 설정의 경우 클라이언트 기기는 자신의 (진짜) LAN 에 아직 접속이 가능한가요?
    위 (a)와 반대로 인터넷만 VPN 을 통하게 할 수도 있나요? 우선 클라이언트 기기의 AllowedIPs 설정으로 그럴 수 있는지에 대한 질문입니다. 0.0.0.0/0 에서 서버 기기의 LAN 을 제외하는 개념일 텐데, 그럼 서버 기기도 제외되겠네요. AllowedIPs 설정으로 Internet-only VPN 을 만들 수 없다면, 어떤 다른 설정을 써야 하나요?

    우다닥 많을 질문을 드려서 죄송합니다. 제 IP 주소가 미국으로 뜰 것 같은데, 저는 한국에 있습니다. 감사합니다.

    1. 제가 전문가가 아니고, 그저 고군분투하면서 얻은 내용을 기록으로 남겨둔 것 뿐이기에, 질문하신 내용에 원하시는 답변을 드릴 수는 없겠습니다. (그럴 능력이 안됩니다.)
      이 글은 openwrt 에서 wireguard 를 설정하는 내용을 간단히 정리했는데, 이 글 말고, wireguard 전반에 대해 정리한 다른 글이 있으니 그 글을 읽어보시길 바랍니다. 간단판도 있긴 합니다만, 원 글이 좀 더 나을 듯 합니다. (다만, 두서없이 쓴 글이라 읽으시기가 좀 난해하실 듯은 합니다만.)

      Wireguard 를 설치한다는 의미는, 가상 네트웍 카드가 하나 더 만들어진다는 뜻이 됩니다. 그 네트웍카드에 부여된 IP 에 따라, 적절한 네트워킹이 이뤄지게 됩니다.

      한가지만 말씀을 드리자면, 0.0.0.0/0 으로 설정했다고 해도, 클라이언트가 속한 원래 LAN 영역에 접근이 당연히 되어야 할텐데, 위에 언급한 제 글의 덧글에서, 어떤 분이 안된다고 말씀하신 적이 있었습니다. 저는 저런 상황에서 사용해 본 적이 없는지라 뭐라 말씀은 못드리겠습니다만, 적어도 제 지식 선에선 ‘안될 이유가 없다’고 주장(?)하겠습니다. 위에서 말씀드렸듯, 가상으로 네트웍카드가 하나 더 생긴 셈이기 때문에, 원래 IP 는 그대로 남아있고, 따라서 클라이언트 LAN 에는 계속 접속이 돼야 합니다.

  2. 답변해주셔서 감사합니다. 고군분투하시는 모습에서 많이 배웁니다. 제겐 OpenWrt 가 쉽지는 않더군요. (저도 이쪽 일을 하는 사람이 아니라.) 예컨대 Firewall 세팅을 좀 이해해 보려구 하니 chain, target, filter 같은 iptables 용어/개념이 먼저 필요하더군요. 그냥 아무 것도 안 건드리고 딱 필요한 Traffic Rules 만 더하면서 쓰는 수도 있게지만, 그러자니 “내 공유기”가 뭘 하고 있는지도 모르고 쓰는게 되어서 좀 불안하네요. 가끔 들려 보겠습니다.

  3. 안녕하세요? 전에 질문 드렸던 것 중 Internet-only VPN 부분에 대한 답을 찾은 것 같아서 링크합니다. (여기에 다른 분들도 많이 오실 것도 같아서.) 단 OpenWrt 환경에서 Wireguard config 을 통하여 iptables 규칙을 직접 맏느는 것은 좋은 방법이 아니라고 하네요. 링크의 내용에서 원리만 취해서 그걸 OpenWrt firewall rules 로 구현하는 게 좋다고 합니다.

    https://gist.github.com/qdm12/4e0e4f9d1a34db9cf63ebb0997827d0d

    1. 다시 찾아주셔서 고맙습니다.
      여기 오는 사람은 거의 없긴 하지만.. 누군가에게라도 도움이 될 수 있겠죠. ^^

Leave a Reply to 아무도안Cancel reply