Defguard VPN 部署指南

I. Defguard 简介

A. Defguard:现代安全远程访问方法

Defguard 是一种开源的零信任企业 VPN 解决方案,它将多重身份验证 (MFA) 等高级安全特性直接集成到 WireGuard® 协议中 。它不仅仅是一个 VPN 工具,更是一个全面的安全平台,整合了 VPN、基于 OpenID 的身份管理 (SSO) 以及账户生命周期管理功能 。这种集成化的设计使其能够满足现代企业对安全远程访问的复杂需求。对于寻求通过用户名/密码结合验证码(通常指 TOTP MFA)方式进行客户端登录的场景,Defguard 的内置身份和访问管理能力提供了原生的支持。

B. 与本次部署相关的关键特性

Defguard 之所以成为本次部署的理想选择,得益于其多项关键特性:

  • Docker 部署的灵活性:Defguard 支持通过 Docker 进行部署,这大大简化了安装和管理过程,并允许在各种环境中快速启动实例 。

  • 强大的 WireGuard® 基础:Defguard 构建于高性能且安全的 WireGuard® VPN 协议之上,确保了 VPN 连接的效率和可靠性 。

  • 原生 MFA 集成:Defguard 的一个核心优势是其将 MFA 直接集成到 WireGuard® 协议本身,而非仅仅在客户端应用层面进行验证 。这意味着每一次 VPN 连接尝试都需要通过 MFA 验证,显著增强了安全性。许多其他解决方案仅在用户登录客户端应用程序时要求 MFA,而 VPN 隧道的建立本身可能并不直接与此 MFA 过程绑定。Defguard 的方法确保了即使客户端凭据被泄露,攻击者也无法在没有通过针对连接尝试的 MFA 质询的情况下建立 VPN 连接。这种深度集成是其“零信任”架构主张的核心体现。

  • 适用于本地部署和私有云:Defguard 专为本地(On-premise)或私有云部署而设计,允许组织对其数据拥有完全主权 。这与用户提供特定公网 IP 进行部署的需求高度契合。

C. 报告目标与结构

本报告旨在提供一个详尽的、步骤清晰的指南,指导技术人员如何在拥有公网 IP,使用 Docker 部署 Defguard 服务。Defguard Core 服务将通过 https://dafguard.aaa.team,而注册服务将通过https://enroll.aaa.team。报告将重点阐述如何配置 Defguard 以实现客户端使用用户名/密码结合基于时间的一次性密码 (TOTP) 验证码进行登录。内容将涵盖从环境准备、组件理解、Docker 安装配置、证书与密钥管理、NGINX 反向代理配置、网络与防火墙设置,到初始设置、MFA 配置、客户端使用以及基本故障排除等各个方面。

II. Defguard 部署先决条件

A. 服务器要求

在开始部署 Defguard 之前,确保服务器满足以下最低硬件和软件要求:

  • 硬件

  • CPU:1 GHz

  • 内存 (RAM):2 GB(主要用于 PostgreSQL 数据库)

  • 磁盘空间:2 GB

  • 架构:x86_64 或 ARM64 值得注意的是,Defguard 的所有组件资源消耗都非常低,因为它们都是用 Rust 编写的单个二进制文件 。

  • 软件

  • 操作系统:一个兼容的 Linux 发行版(例如 Debian/Ubuntu )。

  • Docker Engine:建议安装官方最新稳定版的 Docker Engine 。

  • docker-compose:建议安装官方最新稳定版的 docker-compose 工具(通常作为 Docker Desktop 的一部分或单独安装的 Docker Compose V2) 。

  • NGINX:用于配置反向代理 。

  • OpenSSL:用于生成密钥和证书。

B. 公网 IP 地址与 DNS 注意事项

本次部署的服务器公网 IP 地址为 35.229.186.127。您需要确保域名enroll.aaa.team和dafguard.aaa.team 已正确解析到服务器的公网 IP 35.229.186.127 。

使用域名并配合 NGINX 反向代理具有以下显著优势:

  • SSL/TLS 证书管理:使用域名可以方便地通过 Let's Encrypt 等服务获取和管理受信任的 SSL/TLS 证书,实现自动化证书签发和续期。这对于保障 Web UI 和 API 通信的安全性至关重要 。

  • 用户友好性:域名比 IP 地址更易于记忆和使用。

C. 基本工具与权限

部署过程中,需要确保操作人员拥有以下工具和权限:

  • 服务器的 root 用户权限或 sudo 权限,用于执行 Docker 命令、安装软件包、配置 NGINX 和防火墙。

  • 一个文本编辑器(如 nano, vim 等),用于创建和修改配置文件。

  • openssl 命令行工具,用于生成各种安全密钥和证书 。

III. 理解 Defguard 组件

Defguard 采用模块化架构,由多个协同工作的核心组件构成。理解每个组件的角色和功能对于成功部署和维护至关重要。其分布式设计旨在通过将核心组件部署在安全网络段(仅可通过内部网络或 VPN 访问)来增强安全性,而需要公共访问的操作(如用户引导、注册、密码重置等)则通过安全代理进行 。

以下是 Defguard 的主要组件:

A. Core 服务 (Core Service)

Core 服务是 Defguard 的大脑和控制中心 。它承载了主要的 Web 用户界面 (UI),并作为数据库的接口。其核心职责包括:

  • 处理与 PostgreSQL 数据库的连接,存储所有配置数据、用户信息、VPN 设置等。它是唯一具有持久数据存储的组件 。

  • 管理与 LDAP 服务器(如果配置)和 Gateway 服务的通信 。

  • 负责用户认证和授权 。

  • 通过 REST API 和 gRPC 服务暴露其功能,供前端和其他服务调用 。

B. Proxy 服务 (Proxy Service)

Proxy 服务充当一个安全的公共网关,用于暴露 Defguard Core 服务的一部分特定功能,而无需直接将 Core 服务暴露在公网上 。这符合安全最佳实践,减少了核心系统的攻击面。Proxy 服务处理的关键公共操作包括:

  • 用户引导和注册流程 。

  • 桌面客户端的自动配置 。

  • 密码重置请求 。

C. Gateway 服务 (Gateway Service)

Gateway 服务是实际处理 VPN 流量的组件,可以看作是 Defguard 的“肌肉” 。它是一个轻量级的命令行 gRPC 客户端,通常部署在网络边缘或需要建立 VPN 隧道的服务器上 。其主要功能包括:

  • 从 Core 服务检索 VPN 网络配置 。

  • 在所在服务器上配置和管理 WireGuard® VPN 接口 。

  • 向 Core 服务发送网络统计数据,如流量、连接状态等 。

  • 根据 Core 服务下发的消息应用网络配置变更 。

D. 数据库 (PostgreSQL) (Database (PostgreSQL))

Defguard Core 服务使用 PostgreSQL 作为其持久化数据存储后端 。所有关键数据,包括用户账户、用户组、VPN 位置配置、设备信息、MFA 设置等,都存储在 PostgreSQL 数据库中。因此,数据库的可用性、完整性和安全性至关重要,定期备份数据库是维护 Defguard 系统稳定运行的关键措施。

E. (可选) YubiBridge ((Optional) YubiBridge)

YubiBridge 是一个客户端服务,主要用于在组织内简化 YubiKey硬件密钥的配置和管理,例如生成 GPG/PGP 签名密钥和 SSH 等身份验证密钥 。虽然本次部署的核心需求是 TOTP MFA,但了解 YubiBridge 的存在对于未来可能考虑引入硬件令牌 MFA 的组织是有益的。

Defguard 组件交互与通信安全考量 Defguard 的分布式架构(Core、Proxy、Gateway)虽然在安全性和可扩展性方面具有优势,但也引入了对组件间可靠且安全通信的依赖,这主要通过 gRPC 实现 。Core 服务与 Gateway 服务之间,以及 Core 服务与 Proxy 服务之间(如果 Proxy 用于某些回调或高级功能)都可能涉及 gRPC 通信。

确保这些 gRPC 通道的安全至关重要。文档强烈建议使用自定义 SSL 证书颁发机构 (CA) 来保护 gRPC 通信,或者至少通过反向代理进行 SSL 终止,并配合严格的防火墙规则来限制对 gRPC 端口的访问 。如果 gRPC 通信配置不当(例如,证书错误、防火墙阻止、组件间网络问题),将可能导致 Defguard 功能瘫痪。例如,Gateway 可能无法获取最新的 VPN 配置,Proxy 可能无法处理用户注册请求。因此,在部署过程中,必须仔细配置和验证 gRPC 通信的安全性与连通性,这与保护单个组件本身同等重要。

下表总结了 Defguard 主要组件及其功能:

表 1: Defguard 组件概览

组件名称

主要功能

关键交互

Docker 镜像 ()

数据持久性

Core 服务

主 Web UI,数据库接口,用户授权,VPN 配置管理,连接数据库、LDAP、Gateway

与数据库、Gateway、Proxy、前端 UI 通信

ghcr.io/defguard/defguard:latest

是 (PostgreSQL)

Proxy 服务

安全暴露部分公共功能(注册、客户端配置、密码重置)

与 Core 服务通信,处理来自公网的特定请求

ghcr.io/defguard/defguard-proxy:latest

Gateway 服务

从 Core 获取配置,配置 WireGuard VPN 接口,发送网络统计数据给 Core

与 Core 服务通过 gRPC 通信,管理 WireGuard 接口

ghcr.io/defguard/gateway:latest

否 (配置来自 Core)

数据库 (PostgreSQL)

为 Core 服务提供持久化数据存储

被 Core 服务访问

postgres:17-alpine (或类似版本)

IV. 通过 Docker Compose 安装与配置 Defguard

本章节将详细介绍如何使用 Docker Compose 在具有公网 IP 35.229.186.127 的服务器上安装和配置 Defguard,并通过 NGINX 反向代理使用域名 dafguard.aaa.team。我们将采用手动创建 docker-compose.yml.env 文件的方式,以便更好地理解和控制各项参数。

A. 准备目录结构

在服务器上选择一个合适的目录用于存放 Defguard 的配置文件和密钥,例如 /opt/defguard。创建该目录及子目录:

Bash

sudo mkdir -p /opt/defguard/keys
sudo mkdir -p /opt/defguard/ca
cd /opt/defguard
  • /opt/defguard/docker-compose.yml:定义 Defguard 服务及其依赖的 Docker Compose 文件。

  • /opt/defguard/.env:存储所有环境变量,用于配置各个服务。

  • /opt/defguard/keys/:用于存放 OIDC RSA 密钥等。

  • /opt/defguard/ca/:用于存放自定义 CA 证书和 gRPC 服务证书。

B. 配置环境变量 (.env 文件)

.env 文件用于集中管理所有 Defguard 服务所需的环境变量 。在

/opt/defguard 目录下创建 .env 文件。

表 2: Defguard 设置关键环境变量 (.env)

变量名

用途/描述

示例值 (针对域名 dafguard.aaa.team)

参考

DEFGUARD_URL

Defguard Core 服务的主要公共访问 URL。将通过 NGINX 代理到 https://dafguard.aaa.team/dafguard/

https://dafguard.aaa.team

DEFGUARD_ENROLLMENT_URL

Defguard Proxy/Enrollment 服务的公共访问 URL。将通过 NGINX 代理到 https://dafguard.aaa.team/enroll/

https://enroll.aaa.team

DEFGUARD_WEBAUTHN_RP_ID

(可选但推荐) WebAuthn (FIDO2) 的信赖方 ID。必须是 DEFGUARD_URL 的有效域名。

dafguard.aaa.team

DEFGUARD_SECRET_KEY

加密私有 Cookie 的 JWT 密钥 (至少 64 字符)。

使用 openssl rand -base64 64 | tr -dc 'a-zA-Z' | head -c 64

DEFGUARD_AUTH_SECRET

加密用户令牌的 JWT 密钥。

openssl rand -base64 64 | tr -dc 'a-zA-Z' | head -c 64

DEFGUARD_GATEWAY_SECRET

加密 Gateway 令牌的 JWT 密钥。

openssl rand -base64 64 | tr -dc 'a-zA-Z' | head -c 64

DEFGUARD_OPENID_KEY

(推荐) OIDC RSA 私钥文件在容器内的路径。

/keys/rsakey.pem

DEFGUARD_DB_HOST

PostgreSQL 数据库主机名。

db

DEFGUARD_DB_PORT

PostgreSQL 数据库端口。

5432

DEFGUARD_DB_USER

Defguard Core 连接数据库的用户名。

defguard

DEFGUARD_DB_PASSWORD

Defguard Core 连接数据库的密码。

生成一个强密码

DEFGUARD_DB_NAME

Defguard Core 使用的数据库名称。

defguard

POSTGRES_USER

PostgreSQL 容器初始化用户。与 DEFGUARD_DB_USER 匹配。

defguard

POSTGRES_PASSWORD

PostgreSQL 容器初始化密码。与 DEFGUARD_DB_PASSWORD 匹配。

DEFGUARD_DB_PASSWORD 相同

POSTGRES_DB

PostgreSQL 容器初始化数据库名。与 DEFGUARD_DB_NAME 匹配。

defguard

DEFGUARD_DEFAULT_ADMIN_PASSWORD

初始管理员密码。

pass123 (强烈建议修改)

DEFGUARD_LOG_LEVEL

Defguard Core 日志级别。

info

DEFGUARD_GRPC_CERT

(推荐,用于 Core gRPC) Core gRPC 服务证书在容器内的路径。

/certs/core.crt

DEFGUARD_GRPC_KEY

(推荐,用于 Core gRPC) Core gRPC 服务私钥在容器内的路径。

/certs/core.key

DEFGUARD_PROXY_URL

(可选) Proxy gRPC 端点 URL (Core 连接 Proxy)。

grpcs://defguard-proxy:50051 (假设 Proxy gRPC 也用 TLS)

DEFGUARD_PROXY_GRPC_CA

(可选) Core 连接 Proxy gRPC 时信任的 CA 证书路径。

/certs/ca.crt

DEFGUARD_COOKIE_INSECURE

允许非 HTTPS Cookie (仅开发)。生产严禁 true

false

生成安全密钥:DEFGUARD_SECRET_KEYDEFGUARD_AUTH_SECRETDEFGUARD_GATEWAY_SECRET 和数据库密码生成强随机字符串。

DEFGUARD_URL=https://defguard.aaa.team/
DEFGUARD_ENROLLMENT_URL=https://enroll.aaa.team/
DEFGUARD_WEBAUTHN_RP_ID=defguard.aaa.team
DEFGUARD_SECRET_KEY=y4cXvejTjuzN3LPkl3PyiFJT4egZkuUvsJE2SCkilVrkazJyOJjlbllgmywZtbs7jbGevJKSA
DEFGUARD_AUTH_SECRET=uVIUcUygvvQb8HQBU9cfzncZh9VkaWEKi2SPVvqvSGEWIYnEFQpiwxvfOauvX8oAccHklvEYQ
DEFGUARD_GATEWAY_SECRET=XdDZvVlpDB8so05ecUHYnUvZCLgv2ddI07gFImtWn1e4nXNi7JylWNpOd1NI5GdljGnZeDbw
DEFGUARD_OPENID_KEY=/keys/rsakey.pem
DEFGUARD_DB_HOST=db
DEFGUARD_DB_PORT=5432
DEFGUARD_DB_USER=defguard
DEFGUARD_DB_PASSWORD=Ksfnshdngf
DEFGUARD_DB_NAME=defguard
POSTGRES_USER=defguard
POSTGRES_PASSWORD=Ksfnshdngf
POSTGRES_DB=defguard
DEFGUARD_DEFAULT_ADMIN_PASSWORD=kdgsidfn
DEFGUARD_LOG_LEVEL=info
DEFGUARD_GRPC_CERT=/certs/core.crt
DEFGUARD_GRPC_KEY=/certs/core.key
DEFGUARD_PROXY_GRPC_CA=/certs/ca.crt
DEFGUARD_PROXY_URL=grpcs://defguard-proxy:50051
DEFGUARD_COOKIE_INSECURE=false

C. 编写 docker-compose.yml 文件

/opt/defguard 目录下创建 docker-compose.yml 文件 。

YAML

services:
  db:
    image: postgres:17-alpine
    container_name: defguard-db
    restart: always
    env_file: .env
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - defguard_network

  core:
    image: ghcr.io/defguard/defguard:latest
    container_name: defguard-core
    restart: always
    env_file: .env
    ports:
      - "127.0.0.1:8000:8000" # HTTP, NGINX 代理
      - "0.0.0.0:50055:50055" # gRPC, Gateway 连接
    depends_on:
      - db
    volumes:
      - ./keys/rsakey.pem:/keys/rsakey.pem:ro # OIDC RSA 私钥
      - ./ca/ca.crt:/certs/ca.crt:ro         # 自定义 CA 证书 (如果 Proxy gRPC 使用, 或 Gateway 验证 Core gRPC)
      - ./ca/core.crt:/certs/core.crt:ro     # Core gRPC 服务证书
      - ./ca/core.key:/certs/core.key:ro     # Core gRPC 服务私钥
    networks:
      - defguard_network

  proxy:
    image: ghcr.io/defguard/defguard-proxy:latest
    container_name: defguard-proxy
    restart: unless-stopped
    env_file: .env
    ports:
      - "127.0.0.1:8080:8080" # HTTP, NGINX 代理
      - "0.0.0.0:50051:50051" # Proxy gRPC 端口 (如果 Core 连接 Proxy gRPC)
    volumes:
      - ./ca/ca.crt:/certs/ca.crt:ro            # 自定义 CA (如果 Proxy gRPC 使用)
      - ./ca/proxy.crt:/certs/proxy.crt:ro      # Proxy gRPC 服务证书
      - ./ca/proxy.key:/certs/proxy.key:ro      # Proxy gRPC 服务私钥
    networks:
      - defguard_network

  gateway:
    image: ghcr.io/defguard/gateway:latest
    container_name: defguard-gateway
    restart: unless-stopped
    network_mode: "host"
    cap_add:
      - NET_ADMIN
    environment:
      # Gateway 连接 Core gRPC (推荐使用 TLS)
      - DEFGUARD_GRPC_URL=https://127.0.0.1:50055 # Core gRPC 服务地址
      - DEFGUARD_GRPC_CA=/ca/ca.crt # Gateway 信任的 CA 证书 (用于验证 Core gRPC 证书)
      - DEFGUARD_STATS_PERIOD=30
      - DEFGUARD_TOKEN= # 在 Core 中创建 VPN Location 后填写
      - DEFGUARD_GATEWAY_NAME=main-gateway #gateway网关名字,在web界面创建网关时需要与这个名字一致
      - DEFGUARD_LOG_LEVEL=info
    volumes:
      - ./ca/ca.crt:/ca/ca.crt:ro # 挂载 CA 证书供 Gateway 使用

volumes:
  db_data:

networks:
  defguard_network:
    driver: bridge

关于 Gateway 的 network_mode: "host"cap_add: - NET_ADMIN 此配置简化了 WireGuard 内核集成,但降低了容器网络隔离性 。

D. 启动 Defguard 服务

  1. 确保 .envdocker-compose.yml 已创建。确保必要的密钥和证书文件已按后续 V 章节说明生成并放置在 ./keys./ca 目录。

导航到 /opt/defguard 目录,执行:

  1. Bash

sudo docker-compose -f docker-compose.yml --env-file.env up -d
  1. 检查服务状态:sudo docker-compose pssudo docker-compose logs -f core

V. 高级配置:证书与密钥管理

正确的证书和密钥管理对于安全的 Defguard 部署至关重要。

A. Web 服务器 SSL/TLS 证书 (NGINX)

NGINX 将处理 dafguard.aaa.team 的 HTTPS 流量。强烈建议使用 Let's Encrypt (通过 Certbot) 自动获取和续订 SSL/TLS 证书 。这将在后续 NGINX 配置章节中详细说明。这些证书确保用户浏览器与您的 Defguard Web UI/Proxy 之间的通信加密。

B. OpenID Connect (OIDC) 签名密钥 (DEFGUARD_OPENID_KEY)

Defguard Core 使用此密钥签署 OIDC ID 令牌。推荐使用 RSA 密钥对 。

生成 RSA 私钥: 在您的宿主机上,于 /opt/defguard/keys/ 目录下生成 rsakey.pem

  1. Bash

sudo openssl genpkey -algorithm RSA -out /opt/defguard/keys/rsakey.pem -pkeyopt rsa_keygen_bits:2048
  1. 配置 .env: 确保 .env 文件中有 DEFGUARD_OPENID_KEY=/keys/rsakey.pem

  2. 配置 docker-compose.yml: 确保 core 服务的 volumes 部分包含 -./keys/rsakey.pem:/keys/rsakey.pem:ro

如果遇到 file not found 错误,请仔细检查:

  • rsakey.pem 文件是否已在宿主机的 /opt/defguard/keys/ 目录下正确生成。

  • .env 文件中的 DEFGUARD_OPENID_KEY 路径是否与容器内路径匹配。

  • docker-compose.yml 中的卷挂载是否正确。

如果您暂时不想配置 OIDC RSA 密钥,可以从 .env 文件中注释掉或移除 DEFGUARD_OPENID_KEY 变量。Defguard 可能会回退到使用 HMAC 算法或其他默认机制 。

C. Securing gRPC Communication (Core, Proxy, Gateway)

组件间的 gRPC 通信(如 Gateway 与 Core)应使用 TLS 加密。推荐使用自定义 CA 。

创建自定义证书颁发机构 (CA): 在宿主机的 /opt/defguard/ca/ 目录下操作 :

  1. Bash

# 生成 CA 私钥
sudo openssl genpkey -algorithm RSA -out /opt/defguard/ca/ca.key -pkeyopt rsa_keygen_bits:4096
# 生成 CA 根证书 (ca.crt)
sudo openssl req -x509 -new -nodes -key /opt/defguard/ca/ca.key -sha256 -days 1825 -out /opt/defguard/ca/ca.crt -subj "/CN=DefguardInternalCA"

为 Defguard Core gRPC 服务生成证书 (由自定义 CA 签署): Core 服务监听在 50055 端口的 gRPC 服务需要服务器证书 。

  1. Bash

# 生成 Core gRPC 服务私钥
sudo openssl genpkey -algorithm RSA -out /opt/defguard/ca/core.key -pkeyopt rsa_keygen_bits:2048
# 生成 Core gRPC 服务证书签名请求 (CSR)
# CN 应为 Gateway 连接 Core 时使用的主机名/IP。由于 Gateway 在 host 网络模式下通过 127.0.0.1 连接 Core,
# 且 Core 的 gRPC 端口 50055 绑定在 0.0.0.0,CN=localhost 或 CN=127.0.0.1 适用。
sudo openssl req -new -key /opt/defguard/ca/core.key -out /opt/defguard/ca/core.csr -subj "/CN=localhost"
# 签署 Core gRPC 服务证书 (core.crt)
sudo openssl x509 -req -in /opt/defguard/ca/core.csr -CA /opt/defguard/ca/ca.crt -CAkey /opt/defguard/ca/ca.key -CAcreateserial -out /opt/defguard/ca/core.crt -days 730 -sha256 -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1")

重启服务:完成证书生成和配置后,重启 Docker Compose 服务。 sudo docker-compose down && sudo docker-compose -f docker-compose.yml --env-file.env up -d

VI. NGINX 反向代理配置

grafana 反向代理

location ^~ / {
    proxy_pass http://127.0.0.1:8001;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_http_version 1.1;
    add_header X-Cache $upstream_cache_status;
    add_header Cache-Control no-cache;
    proxy_ssl_server_name off;
    proxy_ssl_name $proxy_host;

enroll反向代理

location ^~ / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_http_version 1.1;
    add_header X-Cache $upstream_cache_status;
    add_header Cache-Control no-cache;
    proxy_ssl_server_name off;
    proxy_ssl_name $proxy_host;

VII. 网络与防火墙配置

A. Defguard 所需端口 (使用 NGINX)

公网需开放:

表 3: Defguard 网络端口 (使用 NGINX)

端口

协议

服务/组件

用途

暴露方式

443

TCP

NGINX

Defguard Web UI , 静态资源 (at /assets/), 和注册服务 的 HTTPS 访问。

公网

50051

UDP

Defguard Gateway (WireGuard)

WireGuard VPN 客户端连接的监听端口 。

公网

80

TCP

NGINX

HTTP 到 HTTPS 的重定向。

公网

B. 配置服务器防火墙 (UFW)

允许端口 :

  1. Bash

sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
sudo ufw allow 50555/udp
  1. 启用 UFW: sudo ufw enable

  2. 检查状态: sudo ufw status verbose

VIII. Defguard 初始化设置与 VPN 位置创建

A. 访问 Defguard Web UI

浏览器访问 https://dafguard.aaa.team/

B. 使用默认管理员账户登录

  • 用户名:admin

  • 密码:.envDEFGUARD_DEFAULT_ADMIN_PASSWORD 的值。

立即修改管理员密码。

C. 创建第一个 VPN 位置 (网络)

  1. 登录后,导航到 "VPN Overview"。

  2. 点击 "Create Location",选择“手动配置” 。

  3. 填写信息 :

Name:对应docker-compose.yml配置中的

DEFGUARD_GATEWAY_NAME=main-gateway

Gateway VPN IP addresses and masks:例如 10.0.10.1/24

Gateway address (Public Endpoint):服务器公网 IP 35.229.186.127

Listen port:默认为 50555

Allowed IPs:例如 0.0.0.0/0, ::/0

DNS Servers (可选):例如 8.8.8.8, 1.1.1.1

  1. 保存。

D. 获取 Gateway Token

创建 VPN 位置后,复制生成的 Token 。

  1. 编辑 /opt/defguard/docker-compose.yml,更新 gateway 服务的 DEFGUARD_TOKEN

  2. 保存并重启 gateway 服务:sudo docker-compose restart gateway

  3. 检查日志:sudo docker-compose logs -f gateway

IX. 配置客户端登录:用户名/密码 + TOTP (验证码)

A. 管理员:为 VPN 位置启用 MFA

  1. 登录 Defguard Web UI (https://dafguard.aaa.team/)。

  2. "VPN Overview" -> 选择并编辑 VPN 位置。

  3. 勾选 "Require MFA for this Location" 。

  4. 配置 "Peer disconnect threshold (seconds)" (推荐至少 300 秒) 。

  5. 保存。

B. 用户:在其 Defguard 用户配置文件中设置 TOTP (验证码)

  1. 用户登录 Defguard Web UI (https://dafguard.aaa.team/)。

  2. "My Profile" -> "Edit"。

  3. "Two-factor methods" -> "One time password" (TOTP) -> "Enable" 。

  4. 使用身份验证器应用扫描二维码 。

  5. 输入验证码确认 。

  6. 备份恢复代码

C. 用户:下载并安装 Defguard 桌面客户端

从 Defguard 官方 GitHub Releases 下载 。

D. 用户:配置客户端并连接到 VPN

  1. 配置 Defguard 实例 (Enrollment)

  • 打开客户端。

  • 输入注册 URL:https://dafguard.aaa.team/ (DEFGUARD_ENROLLMENT_URL) 。

  • 可能需用户名/密码验证。

  1. 连接到 VPN 位置

  • 选择 VPN 位置。

  • 输入用户名/密码。

  • 输入 TOTP 验证码 。

  1. 连接成功。

X. 安装后使用与基本管理

A. Defguard 仪表板概览

管理员登录后 (https://dafguard.aaa.team/dafguard/),仪表板显示连接、状态、统计等 。

B. 通过 VPN 启用互联网访问 (NAT/Masquerade)

若 "Allowed IPs" 为 0.0.0.0/0, ::/0,需在 Gateway 服务器 (Docker 主机) 配置 NAT 。

Linux 配置 NAT/Masquerade

查看网卡名

ip route get 8.8.8.8 | awk '{print $5; exit}'
# 允許從 wg0 介面傳入的所有流量被轉發
sudo iptables -I FORWARD -i wg0 -j ACCEPT
# 允許已建立的連線從任何地方返回到 wg0 介面
sudo iptables -I FORWARD -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
apt-get install iptables-persistent -y
sudo iptables-save | sudo tee /etc/iptables/rules.v4

启用内核 IP 转发

/etc/sysctl.conf

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

sudo sysctl -p

-----------------------------------

Linux Centos配置NAT/Masquerade:

# 允許從 wg0 介面傳入的所有流量被轉發
sudo iptables -I FORWARD -i wg0 -j ACCEPT
# 允許已建立的連線從任何地方返回到 wg0 介面
sudo iptables -I FORWARD -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
yum install iptables-services -y
service iptables save

C. 基本用户管理

管理员可在 Web UI 进行用户添加、组管理等 。

XI. 常见问题故障排除

A. 连接问题

  • 客户端无法连接 VPN Gateway:检查防火墙 (UDP 50555),Gateway 服务/Token,Core gRPC 可达性 (https://127.0.0.1:50055,检查 Gateway 的 DEFGUARD_GRPC_CA 和 Core 的 gRPC 证书)。

  • 无法访问 Web UI/注册页/静态资源 (CSS, JS) 返回 404

  • 检查防火墙 (TCP 443/80)。

  • NGINX 配置:确认 NGINX 配置正确,特别是 location /dafguard/location /enroll/ 和新增的 location /assets/ 块。确保 rewrite 规则和 proxy_pass 指令正确无误。检查 NGINX 服务状态和错误日志 (/var/log/nginx/dafguard.aaa.team.error.log)。

  • Core/Proxy 服务日志:检查 defguard-coredefguard-proxy Docker 容器的日志,看是否有内部错误。

  • .env URL 配置:确认 DEFGUARD_URLDEFGUARD_ENROLLMENT_URL 与 NGINX 配置和实际访问地址一致。

  • 客户端报错 "Can't reach proxy":通常指无法访问 DEFGUARD_ENROLLMENT_URL。检查 NGINX 代理。可能是 TLS 版本问题 (客户端最高 TLS 1.2) 。

  • Core 容器报错 "file not found" for keys/certs

  • 确认密钥/证书文件已在宿主机指定路径 (e.g., /opt/defguard/keys/, /opt/defguard/ca/) 生成。

  • 检查 .env 文件中相关路径变量 (e.g., DEFGUARD_OPENID_KEY, DEFGUARD_GRPC_CERT) 是否正确指向容器内路径。

  • 验证 docker-compose.yml 中对应服务的 volumes 挂载是否正确。

B. MFA 问题

  • TOTP 验证码无效:确保服务器和客户端时间准确同步 (NTP) 。

  • 未提示输入 TOTP:确认 VPN 位置启用 MFA 且用户已设置 TOTP 。

  • MFA 启用后不活动断开:预期行为,由 "Peer Disconnect Threshold" 控制 。

C. 客户端错误

  • Linux 客户端 "failed to configure DNS":可能与 resolvconfsystemd-resolved 有关。尝试 sudo ln -s /usr/bin/resolvectl /usr/sbin/resolvconf (Ubuntu 22.04) 。

D. Docker 与服务日志

查看容器日志是关键:

Bash

sudo docker-compose logs -f core
sudo docker-compose logs -f proxy
sudo docker-compose logs -f gateway
sudo docker-compose logs -f db

CLI 客户端可使用 --debug--verbose

XII. 总结与后续步骤

A. 设置回顾

本报告详述了如何使用 Docker, Docker Compose, NGINX 反向代理及自定义证书在公网 IP 35.229.186.127 服务器上部署 Defguard VPN。服务通过域名 dafguard.aaa.team (Core 在 /dafguard/, Proxy 在 /enroll/, 静态资源通过 /assets/ 访问) 访问,并配置了用户名/密码 + TOTP MFA。

B. 安全最佳实践提醒

  • 定期更新:保持所有组件最新 。

  • 数据备份:定期备份 PostgreSQL 数据库 。

  • 强密码与 MFA

  • 日志审计与防火墙强化

C. 进一步探索

  • 其他 MFA 方法:如 WebAuthn/FIDO2 。

  • LDAP / Active Directory 集成

  • 访问控制列表 (ACL)

  • 高可用性 (HA) 与多网关

  • API 与 Webhooks 集成

持续学习和探索 Defguard 的功能,将有助于最大限度地发挥其作为现代零信任 VPN 和身份管理平台的潜力。


Defguard VPN 部署指南
https://www.hechunyu.com/archives/defguard-vpn-bu-shu-zhi-nan
作者
chunyu
发布于
2025年07月21日
许可协议