베지밀
[VPN 프로젝트] 리눅스 서버 간 WireGuard VPN 구성 본문
WireGuard란?
WireGuard는 최근 등장한 새로운 VPN 프로토콜로, 기존 VPN과 달리 코드 라인 수가 4000줄 정도로 간결하다는 특징이 있다.
WireGuard의 특징?
- 암호화 프로토콜은 ChaCha20, Poly1305, Curve25519로 고정되어있다.
사전 공유키 방식을 사용하며, 최신 암호화 프로토콜로 안전하고 빠른 암/복호화가 가능하다. - UDP에서만 동작하며, IPv6도 지원이 가능하다.
UDP를 사용하기 때문에 가볍고 빠르다는 장점이 있다. - 사전 공유키 방식을 활용한 단순한 키 교환 프로세스를 사용한다.
기존 VPN과 달리 단 한 번의 요청/응답으로 키를 교환할 수 있다. - 커널 수준에서 작동하기 때문에 높은 성능과 효율성을 가진다.
- 관리가 용이하다.
SSO 인증 없이 공개키로 Peer를 증명하기 때문에 사용성이 좋다.
이제 동일 호스트 내에서 리눅스 가상머신 2대를 띄워 WireGuard 통신 설정을 해보자.
환경 구성
> 서버(왼) : 우분투 10.10.10.10 / VPN IP 192.168.10.1
> 클라이언트(오) : 우분투 10.10.10.13 / VPN IP 192.168.10.2
0. WireGuard 설치
서버/클라이언트 간 다음 명령을 통해 WireGuard를 설치한다.
sudo apt update
sudo apt install wireguard
1. 키 생성
서버
umask 077
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
# 생성된 키 확인
root@server:/etc/wireguard# cat private.key
wN+x3PUvRvVZeQd4cmICBajU1LzH24gx3tZaDEFvXW4=
root@server:/etc/wireguard# cat public.key
vxP5k8DH032NlDdJaWZZVgMhplDfYx+E0+J/rA8SASI=
클라이언트
umask 077
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
# 생성된 키 확인
root@client:/etc/wireguard# cat private.key
GITuyew7XWuDKpJ3ZjRHoW1RiLxqbgm1GDb0MCMtpno=
root@client:/etc/wireguard# cat public.key
KLb8N1dqlxTZOzJLBEyJp9xmdv9W7E6PooZkPMH+nUM=
📌umask 077을 하는 이유?
- umask는 파일 생성 시 기본 권한에서 특정 권한을 제거하는 마스크값
- 디렉터리 777과 파일 666의 기본 권한에서 077을 하면 사용자 이외의 권한(그룹/기타 사용자)를 없앨 수 있다.
- umask를 적용하면 경로와 무관하게 적용 후 생성되는 모든 파일과 디렉토리에 권한이 적용된다.
- WireGuard에서 비밀키는 절대 알려져선 안된다!
- 비밀키가 유출되면 VPN 서버/클라이언트에 대한 접근 권한을 잃어버림
- 따라서 umask 077을 통해 파일을 생성해서 다른 사용자가 접근하지 못하도록 제한해야 함
2. 설정 파일 구성 (/etc/wireguard/wg0.conf)
[Interface] : 호스트의 IP 주소, 비밀키, 수신 대기 포트를 설정한다.
이 때, Address는 VPN에 사용할 가상 ip 주소로, 사설 ip 대역 중 임의로 설정한다.
iptables를 통해 wg0 인터페이스 활성화 시 포워딩을 위해 필요한 NAT 설정을 해준다.
eth0, enp0s3, ens33 등 호스트가 vpn 통신에 사용할 인터페이스 이름을 입력한다.
[Peer]는 상대방과의 연결 정보에 대해 설정하는 부분이다. 상대방의 공개키와 ip를 입력한다.
서버
[Interface]
Address = 192.168.10.1/24 # 서버의 VPN IP 주소
SaveConfig = true # WireGuard 종료 시 설정을 저장 (선택 사항)
PrivateKey = wN+x3PUvRvVZeQd4cmICBajU1LzH24gx3tZaDEFvXW4= # 서버의 비밀키 (wg genkey로 생성)
ListenPort = 51820 # 서버가 수신 대기할 포트
# NAT 설정 및 트래픽 포워딩을 위한 iptables 규칙
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens33 -j MASQUERADE
[Peer]
PublicKey = KLb8N1dqlxTZOzJLBEyJp9xmdv9W7E6PooZkPMH+nUM= # 클라이언트의 공개키
AllowedIPs = 192.168.10.2/32 # 클라이언트의 VPN IP 주소
클라이언트
[Interface]
Address = 192.168.10.2/24 # 클라이언트의 VPN IP 주소
PrivateKey = GITuyew7XWuDKpJ3ZjRHoW1RiLxqbgm1GDb0MCMtpno= # 클라이언트의 비밀키 (wg genkey로 생성)
DNS = 8.8.8.8 # (선택 사항) VPN 연결 시 사용할 DNS 서버 주소
[Peer]
PublicKey = vxP5k8DH032NlDdJaWZZVgMhplDfYx+E0+J/rA8SASI= # 서버의 공개키
Endpoint = 10.10.10.10:51820 # 서버의 IP 주소 및 포트 번호
AllowedIPs = 0.0.0.0/0, ::/0 # 전체 트래픽을 VPN을 통해 전송 (라우팅 설정)
PersistentKeepalive = 25 # 연결이 유지되도록 keepalive 설정 (NAT 환경에서 유용)
3. 설정 파일 적용
서버/클라이언트 모두 다음 명령을 통해 wg 서비스를 적용한다.
sudo wg-quick up wg0
sudo wg show
sudo wg show 결과, 2번에서 설정한 파일 내용이 보이면 성공
4. 방화벽 설정
wireguard 포트를 방화벽에서 허용해야 클라이언트가 서버에 접근할 수 있다.
서버-클라이언트 구조로 테스트할 것이므로 서버에만 설정해도 좋다.
sudo ufw allow 51820/udp
sudo ufw reload
51820/udp로의 연결을 허용하고 방화벽을 재실행했다.