▶︎ VPN ?
VPN(Virtual Private Network)는 인터넷을 통해 디바이스 간에 사설 네트워크 연결을 생성해요.
VPN은 네트워크를 통해 데이터를 안전하게 익명으로 전송하는데 사용되며, 사용자 IP 주소를 마스킹하고 데이터를 암호화하여 수신 권한이 없는 사람은 읽을 수 없도록 해줍니다.
그렇다면 VPN을 설치했을 때는 어떤 장점이 있을까요?
- 안전한 퍼블릭 인터넷 접근 가능
- 검색 기록을 프라이빗으로 유지
등의 장점이 존재합니다.
현재도 많은 사용자들이 VPN을 활발히 사용하고 있기 때문에,
VPN 제공사들 또한 성능에 제한을 걸어두기 위해 여러 유료 요금제를 도입하고 있습니다.
매달 내야하는 유료 요금제가 부담스럽다면 무료 VPN을 찾아야 하지만 매번 새로운 무료 VPN을 찾아다니는 것도 쉬운 일은 아니겠죠.
만약, 이런 상황에서 자신만의 VPN 서버를 구축해볼 수 있다면 요금제 부담도 덜고 좋지 않을까요?
이번 포스팅은 도커를 통해 Wireguard를 구축해 볼 것입니다.
▶︎ Wireguard ?
WireGuard는 오픈 소스 기반의 VPN 프로토콜 입니다.
같은 맥락의 오픈 소스 기반 OpenVPN 보다 더 나은 성능을 목표로 개발되었고 GPL v2
라이센스로 배포되었습니다.
Wireguard의 경우 Peer to Peer
(P2P) 기반 VPN으로 구축하고 싶은 환경에 따라 다양하게 구성이 가능합니다.
그 외에 서버/클라이언트
, Mesh VPN
, Site to Site
방식 또한 가능합니다.
Wireguard는 리눅스 커널 5.6 버전부터 포함되어 동작하며 UDP 기반이며, IPv4, IPv6 모두에 대해 Layer 3로 지원합니다.
‣ 특징
특징 | 설명 |
---|---|
암호화 알고리즘 | 최신 암호화 알고리즘을 적용하여 안전하면서도 빠른 데이터 암호화 |
편의성 | 자체적인 Client app 또는 프로그램을 개발하여 다른 3rd party app을 고려할 필요가 없게 되었음 Client에게 암호화 키를 배포하기 위한 QRCode 제공됨 쉬운 연결성 |
▶︎ 서버 구축
‣ 사전 준비
- 마운트 디렉토리 생성
- 도커 및 도커 컴포즈가 설치되어 있어야 함.
- 포트포워딩
- 서브 도메인 (선택)
도커 설치 전에 Wireguard 컨테이너에 생성된 QRCode나 설정 파일(.conf
)를 외부에서 접근 가능하도록
1. 호스트에 설정 파일용 디렉토리 생성해줍시다.
mkdir -p ~/WireGuard/composes
위 명령을 실행하면 WireGuard
디렉토리 및 WireGuard
디렉토리 하위에 composes
디렉토리가 생성됩니다.
2. 사용중인 공유기에서 VPN 포트(51820/UDP
)를 허용해줘요.
3. 서브 도메인 생성 및 NPM(Nginx Proxy Manager) 리버스 프록시 설정 (선택)
해당 부분은 서브 도메인을 설정하여 특정 서브 도메인 주소로 트래픽 요청이 들어왔을 때,
지정한 서버로 트래픽을 전달하기 위한 설정입니다.
예시를 들면
wireguard.waytothem.store
로 접근 요청이 들어왔을 시, NPM에서 192.168.219.114:51821
로 트래픽을 전송합니다.
해당 부분은 선택사항이므로 꼭 설정할 필요는 없습니다.
저의 경우 외부에서도 웹 UI 페이지에 접근할 수 있도록 하기 위해서 별도로 설정한 부분입니다.
도메인의 경우 가비아에서 구매하여 아래와 같이 설정하였습니다.
NPM 설정은 아래와 같습니다.
‣ Compose 작성
도커를 이용하면 매우 간단하게 WireGuard 설치가 가능합니다.
설치 방법의 경우 시간이 지남에 따라 조금씩 변경될 수 있으므로,
설치 도중 에러 발생 시 위 깃허브 주소로 가서 최신 설치 방법을 참고해주세요.
먼저 저는 Docker Compose v2.20(docker desktop v4.22)부터 추가된 include
속성을 사용하여 Wireguard를 배포해보도록 하겠습니다.
설치 방법이니 만큼 YAML에 작성된 속성 값이나 문법은 넘어가도록 하겠습니다.
먼저 뼈대가 되는 docker-compose.yaml
을 아래와 같이 작성해줍니다.
docker-compose.yaml
include:
- "composes/wireguard.yaml"
volumes:
etc_wireguard: {}
networks:
wireguard-net:
driver: bridge
external: false
version
속성의 경우 obsolete 되었으므로 생략하겠습니다.(version-top-level-element-optional)
wireguard.yaml
파일을 작성합니다.
composes/wireguard.yaml
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
environment:
- LANG=ko
- WG_HOST=wireguard.waytothem.store
# Optional:
# - PASSWORD_HASH=$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG (needs double $$, hash of 'foobar123'; see "How_to_generate_an_bcrypt_hash.md" for generate the hash)
# - PASSWORD=
# - PORT=51821
# - WG_PORT=51820
# - WG_CONFIG_PORT=92820
# - WG_DEFAULT_ADDRESS=10.8.0.x
# - WG_DEFAULT_DNS=1.1.1.1
# - WG_MTU=1420
# - WG_ALLOWED_IPS=192.168.15.0/24, 10.0.1.0/24
# - WG_PERSISTENT_KEEPALIVE=25
# - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt
# - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt
# - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt
# - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt
# - UI_TRAFFIC_STATS=true
# - UI_CHART_TYPE=0 # (0 Charts disabled, 1 # Line chart, 2 # Area chart, 3 # Bar chart)
# - WG_ENABLE_ONE_TIME_LINKS=true
# - UI_ENABLE_SORT_CLIENTS=true
# - WG_ENABLE_EXPIRES_TIME=true
# - ENABLE_PROMETHEUS_METRICS=false
# - PROMETHEUS_METRICS_PASSWORD=$$2a$$12$$vkvKpeEAHD78gasyawIod.1leBMKg8sBwKW.pQyNsq78bXV3INf2G # (needs double $$, hash of 'prometheus_password'; see "How_to_generate_an_bcrypt_hash.md" for generate the hash)
volumes:
- type: volume
source: etc_wireguard
target: /etc/wireguard
- etc_wireguard:/etc/wireguard
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
# - NET_RAW # ⚠️ Uncomment if using Podman
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
volumes:
etc_wireguard:
속성 | 설명 |
---|---|
WG_HOST |
외부 IP 혹은 외부 도메인 지정(WAN IP(공인 IP) or 도메인 주소) |
PASSWORD |
해당 Web UI에 접속할 관리자 페이지의 비밀번호 |
WG_ALLOWED_IPS |
해당 VPN으로 패킷을 보낼 IP 대역 리스트, 콤마(, )로 여러 대역 표현이 가능합니다.만일 모든 패킷을 VPN으로 보내고 싶다면 0.0.0.0/0 으로 입력합니다.예를들어 192.168.15.0/24 라고 적으신다면 192.168.15.3과 통신할때는 VPN을 타겠지만 일반 Naver , google 등의 외부 트래픽을 사용할 때에는 VPN을 사용하지않습니다.모든 트래픽에 VPN을 적용하시려면 0.0.0.0/0으로 설정하시면 됩니다. |
WG_PERSISTENT_KEEPALIVE |
WireGuard VPN 터널을 유지하기 위해 정기적으로 keepalive 패킷을 보내는 기능 |
51820/udp |
WireGuard VPN 통신 포트 |
51821/tcp |
WireGuard 설정을 위한 관리 페이지(Web UI) 포트 해당 포트는 포트포워딩으로 노출하지 않는 것을 권장합니다. |
WG_DEFAULT_DNS=8.8.8.8 |
VPN 연결 시 사용할 DNS 주소 입니다. |
WG_DEFAULT_ADDRESS=10.8.0.x |
VPN 연결 시 할당받을 IP 대역 (사용자 기호에 맞게 설정해주세요.) |
더 자세한 설정은 위 깃허브를 참고해주세요.
아래 사진은 제가 설정한 wireguard.yaml
파일 내용입니다.
‣ 관리 방법
관리페이지(http://[서버주소]:51821
) 접속 후 PASSWORD를 입력하여 들어가면
+ New
버튼으로 사용자를 추가할 수 있습니다.
이후 사용자명을 적고 Create
버튼을 클릭하면 아래와 같이 사용자 추가가 완료됩니다.
생성된 유저의 오른쪽 목록을 보면 QR Code 및 설정 파일을 다운로드 받을 수 있는 버튼이 존재합니다.
설정 파일의 경우 데스크탑 환경에서 접속할 때 필요합니다.
데스크탑 환경에서 접속한다면 해당 설정 파일을 다운로드 받고 공유 디렉토리 또는 안전한 클라우드 플랫폼에 저장해주세요.
‣ 접속 방법
이후 WireGuard 클라이언트를 다운로드하여 설치를 진행합시다.
본인의 경우 Mac OS를 사용 중이기에 앱 스토어에서 설치를 하였습니다.
사용자 OS에 맞는 클라이언트를 설치해주시면 됩니다.
외부 PC에서 다운로드 받은 설정 파일을 Import 해주겠습니다.
정상적으로 import 되었습니다.
이제 외부 PC에서 내부 VPN 서버를 통해 정상적으로 터널링이 되는지 테스트 해봅시다.
정상적으로 터널링 되어 외부에서 내부 VPN 망과 통신이 가능해졌습니다.