우분투 서버에 WireGuard VPN 구축하는 방법
1. 새 파일 생성
명령어 1 ▶ nano install-wireguard.sh
2. 아래 내용 중에 WG_ENDPOINT 만 여러분들의 도메인 또는 공인 IP주소로 바꿔서 복사 붙여넣기 하시면 됩니다. 그냥 두시면 알아서 공인IP 찾아서 넣어줌
#-------------------------------------------------------------------------------------------------
#!/usr/bin/env bash
set -euo pipefail
WG_ENDPOINT="${WG_ENDPOINT:-}" # 도메인(또는 공인IP). 비우면 자동 감지하여 공인IP 넣어줌.
WG_NET_CIDR="${WG_NET_CIDR:-10.7.0.0/24}" # VPN 서브넷
WG_SVR_IP_V4="${WG_SVR_IP_V4:-10.7.0.1}" # 서버 VPN IP
WG_PORT="${WG_PORT:-51820}" # 리슨 포트(UDP)
WG_DNS="${WG_DNS:-1.1.1.1, 1.0.0.1}" # 클라이언트 DNS
WG_DIR="/etc/wireguard"
WG_KEYS_DIR="$WG_DIR/keys"
CLIENTS_DIR="$WG_DIR/clients"
need_root() {
if [[ $EUID -ne 0 ]]; then
echo "[!] root 권한이 필요합니다. sudo로 다시 실행하세요."
exit 1
fi
}
detect_wan_if() {
# 기본 게이트웨이 인터페이스 추론
ip route | awk '/default/ {print $5; exit}'
}
install_packages() {
apt update
# wireguard-tools에 wg, wg-quick 포함. qrencode는 QR 출력용(선택)
apt install -y wireguard-tools qrencode curl
}
enable_ip_forward() {
# 일시 적용
sysctl -w net.ipv4.ip_forward=1 >/dev/null
sysctl -w net.ipv6.conf.all.forwarding=1 >/dev/null || true
# 영구 반영
sed -i 's/^#\?net.ipv4.ip_forward=.*/net.ipv4.ip_forward=1/' /etc/sysctl.conf
if grep -q '^net.ipv6.conf.all.forwarding' /etc/sysctl.conf; then
sed -i 's/^#\?net.ipv6.conf.all.forwarding=.*/net.ipv6.conf.all.forwarding=1/' /etc/sysctl.conf
else
echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.conf
fi
sysctl -p >/dev/null
}
gen_keys_if_missing() {
mkdir -p "$WG_KEYS_DIR"
chmod 700 "$WG_KEYS_DIR"
if [[ ! -f "$WG_KEYS_DIR/server_private.key" ]]; then
umask 077
wg genkey | tee "$WG_KEYS_DIR/server_private.key" | wg pubkey > "$WG_KEYS_DIR/server_public.key"
fi
}
ensure_endpoint() {
if [[ -z "$WG_ENDPOINT" ]]; then
# 공인 IP 자동 감지 (도메인이 있으면 WG_ENDPOINT=your.domain.com 형태로 미리 넘겨도 됨)
WG_ENDPOINT="$(curl -fsSL https://ipv4.icanhazip.com || true)"
WG_ENDPOINT="${WG_ENDPOINT//$'\n'/}"
if [[ -z "$WG_ENDPOINT" ]]; then
echo "[!] 공인 IP 자동감지 실패. WG_ENDPOINT 환경변수로 도메인 또는 IP를 지정해 재실행하세요."
exit 1
fi
fi
}
write_server_conf() {
local wan_if="$1"
mkdir -p "$WG_DIR"
chmod 700 "$WG_DIR"
local sv_priv sv_pub
sv_priv="$(cat "$WG_KEYS_DIR/server_private.key")"
sv_pub="$(cat "$WG_KEYS_DIR/server_public.key")"
# NAT 및 포워딩 규칙(PostUp/Down). iptables(호환) 사용.
cat > "$WG_DIR/wg0.conf" <<EOF
[Interface]
Address = ${WG_SVR_IP_V4}/24
ListenPort = ${WG_PORT}
PrivateKey = ${sv_priv}
# IPv4 NAT
PostUp = iptables -t nat -A POSTROUTING -s ${WG_NET_CIDR} -o ${wan_if} -j MASQUERADE; iptables -A FORWARD -i ${wan_if} -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -o ${wan_if} -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -s ${WG_NET_CIDR} -o ${wan_if} -j MASQUERADE; iptables -D FORWARD -i ${wan_if} -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -o ${wan_if} -j ACCEPT
EOF
chmod 600 "$WG_DIR/wg0.conf"
}
start_service() {
systemctl enable --now wg-quick@wg0
}
open_ufw_if_exists() {
if command -v ufw >/dev/null 2>&1; then
ufw allow "${WG_PORT}/udp" || true
ufw reload || true
fi
}
# --- 클라이언트 관리 ---
next_client_ip() {
# WG_NET_CIDR에서 앞 3옥텟 추출 (예: 10.7.0.0/24 -> 10.7.0)
local base o1 o2 o3 prefix ip
base=$(echo "$WG_NET_CIDR" | cut -d/ -f1)
IFS=. read -r o1 o2 o3 _ <<<"$base"
prefix="${o1}.${o2}.${o3}"
# .2 ~ .254 중에서 wg0.conf/clients 디렉터리에 아직 없는 IP를 선택
for i in $(seq 2 254); do
ip="${prefix}.${i}"
if ! grep -qE "AllowedIPs *= *${ip}/32" "$WG_DIR/wg0.conf" 2>/dev/null \
&& ! grep -Rqs "Address *= *${ip}/32" "$CLIENTS_DIR" 2>/dev/null; then
echo "$ip"
return 0
fi
done
echo "[!] ${WG_NET_CIDR} 안에서 할당 가능한 IP가 더 없습니다." >&2
exit 1
}
add_client() {
local name="$1"
mkdir -p "$CLIENTS_DIR"
chmod 700 "$CLIENTS_DIR"
# 키 생성
umask 077
wg genkey | tee "${CLIENTS_DIR}/${name}.key" | wg pubkey > "${CLIENTS_DIR}/${name}.pub"
wg genpsk > "${CLIENTS_DIR}/${name}.psk"
local cli_priv cli_pub cli_psk sv_pub cli_ip
cli_priv="$(cat "${CLIENTS_DIR}/${name}.key")"
cli_pub="$(cat "${CLIENTS_DIR}/${name}.pub")"
cli_psk="$(cat "${CLIENTS_DIR}/${name}.psk")"
sv_pub="$(cat "$WG_KEYS_DIR/server_public.key")"
cli_ip="$(next_client_ip)"
# 서버에 Peer 추가
cat >> "$WG_DIR/wg0.conf" <<EOF
# --- ${name} ---
[Peer]
PublicKey = ${cli_pub}
PresharedKey = ${cli_psk}
AllowedIPs = ${cli_ip}/32
EOF
# 클라이언트 설정 파일 생성
cat > "${CLIENTS_DIR}/${name}.conf" <<EOF
[Interface]
PrivateKey = ${cli_priv}
Address = ${cli_ip}/32
DNS = ${WG_DNS}
[Peer]
PublicKey = ${sv_pub}
PresharedKey = ${cli_psk}
Endpoint = ${WG_ENDPOINT}:${WG_PORT}
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF
chmod 600 "${CLIENTS_DIR}/${name}.conf"
# 즉시 반영
wg syncconf wg0 <(wg-quick strip wg0)
echo "[+] 생성 완료: ${CLIENTS_DIR}/${name}.conf"
if command -v qrencode >/dev/null 2>&1; then
echo "[QR] 휴대폰 앱에서 아래 QR 스캔:"
qrencode -t ansiutf8 < "${CLIENTS_DIR}/${name}.conf"
fi
}
print_summary() {
echo
echo "========== 요약 =========="
echo "Endpoint : ${WG_ENDPOINT}:${WG_PORT}"
echo "Server VPN IP: ${WG_SVR_IP_V4}"
echo "Config : ${WG_DIR}/wg0.conf"
echo "Clients dir : ${CLIENTS_DIR}"
echo "예시 명령어:"
echo " 추가 클라이언트 : sudo $0 add laptop"
echo " 상태 확인 : sudo wg show"
echo " 서비스 재시작 : sudo systemctl restart wg-quick@wg0"
echo "=========================="
echo
}
main_install() {
need_root
local wan_if
wan_if="$(detect_wan_if)"
echo "[*] WAN 인터페이스: ${wan_if}"
install_packages
enable_ip_forward
gen_keys_if_missing
ensure_endpoint
write_server_conf "${wan_if}"
open_ufw_if_exists
start_service
# 기본 클라이언트 1개 생성
add_client "client1"
# 리슨 확인
echo "[*] 리슨 포트 확인:"
ss -lunp | grep -E ":${WG_PORT}\s" || true
print_summary
}
main_add() {
need_root
if [[ $# -lt 1 ]]; then
echo "사용법: $0 add <client_name>"
exit 1
fi
ensure_endpoint
add_client "$1"
}
case "${1:-install}" in
install) main_install ;;
add) shift; main_add "$@" ;;
*)
echo "사용법:"
echo " $0 # 설치(기본)"
echo " $0 install # 설치"
echo " $0 add <name> # 클라이언트 추가"
exit 1
;;
esac
#-------------------------------------------------------------------------------------------------
3. 실행 권한 주기
명령어 1 ▶ chmod +x install-wireguard.sh
4. wireguard 설치 실행
처음 wireguard 설치 이후에는 add mobile, add table 등을 붙여서 간단하게 클라이언트를 추가할 수 있습니다.
명령어 1 ▶ sudo ./install-wireguard.sh (최초 설치 필수 )
※ 명령어 1 실행하여 wireguard 설치 이후에는 아래 코드처럼 각 기기별로 간단하게 클라이언트 추가 가능
명령어 2 ▶ sudo ./install-wireguard.sh add 클라이언트이름 (아무 이름이나 가능)
예시)
모바일 : sudo ./install-wireguard.sh add mobile
태블릿 : sudo ./install-wireguard.sh add tablet
컴퓨터 : sudo ./install-wireguard.sh add laptop
※ 명령어 실행 시 준비한 모든 명령어가 자동으로 실행되고, 마지막에 QR코드 화면에 보여줌.
5. PC의 경우 설정 파일 WireGuard VPN 프로그램 설정하는 방법
명령어 1 ▶ sudo cat /etc/wireguard/clients/laptop.conf
※ 해당 명령어 입력하면 Wireguard 설정 텍스트 파일이 화면에 표시되는데 그대로 복사해서 WireGuard VPN 프로그램에 붙여넣기 하면 됩니다.
공개 마지막 업데이트: 2025-09-20 03:14:42 AM
