# Welcome

{% hint style="danger" %}
This documentation refers to Defguard version 1.4.0. If you are using a different version, please switch to the corresponding documentation for that release.
{% endhint %}

Welcome to the Defguard documentation. Here, you'll learn how to explore the full capabilities of the platform, set up a quick demo instance, configure a production-ready deployment, and get your client application up and running.

### How is this documentation organized?

* [About](/1.4/about/about-defguard)\
  Briefly describes Defguard and its features.
* [Getting started](/1.4/getting-started/one-line-install)\
  Lets you quickly set up your own Defguard instance to explore its features and user interface.
* [Features and configuration](/1.4/features/overview)\
  Helps you, as a future Defguard administrator, get familiar with all of Defguard's features and how to configure them to suit your needs.
* [Deployment strategies](/1.4/deployment-strategies/setting-up-your-instance)\
  Walks you through the most common deployment strategies to help you set up your Defguard instance as a production-grade solution.
* [Enterprise](/1.4/enterprise/enterprise-features)\
  Outlines the benefits, terms, and purchasing process for the Defguard Enterprise license.
* [Using Defguard (for end users)](/1.4/using-defguard-for-end-users/overwiew)\
  Helps you, as a Defguard end user, get familiar with the client applications and their features so you can quickly connect to your Defguard instance.
* [Tutorials](/1.4/tutorials/step-by-step-setting-up-a-vpn-server)\
  A collection of step-by-step guides with clear examples and helpful screenshots to make the setup process smooth and enjoyable.
* [In depth](/1.4/in-depth/architecture-decision-records)\
  In-depth information about the platform and its development, reflecting our commitment to transparency.
* [For developers](/1.4/for-developers/contributing)\
  All the information you need to become a Defguard contributor — join us in building a better solution.
* [Resources](/1.4/resources/troubleshooting)\
  A collection of essential resources, including troubleshooting guides, API documentation, and more.


# Getting help

## Troubleshooting guide

We developed a comprehensive [troubleshooting guide](/1.4/resources/troubleshooting) to help resolve your issue. We've put significant effort into ensuring it's current and thorough.

## Community support (for all plans)

Having trouble with Defguard deployment or configuration? Reach out to our community for help.&#x20;

Support is provided both by the community and by us (the Defguard authors) using GitHub Discussions. Create a new discussion using this [form](https://github.com/DefGuard/defguard/discussions/new/choose).

## Email Support (for paid plans only)

If you have bought a [Business or Enterprise license](https://defguard.net/pricing/), you can reach us at our support email <support@defguard.net>.

{% hint style="warning" %}
Please remember to send your support request from the same domain used when purchasing the license. If you contact us from a different domain, your request will be redirected to our community support.
{% endhint %}

## Found a bug? Need a feature?

* Here you can submit [a bug](https://github.com/DefGuard/defguard/issues/new?assignees=\&labels=bug\&projects=\&template=bug_report.md\&title=)
* And here you can submit [a feature request](https://github.com/DefGuard/defguard/issues/new?assignees=\&labels=feature\&projects=\&template=feature_request.md\&title=)

## Reporting a security vulnerability

{% hint style="danger" %}
Please do not report security vulnerabilities via GitHub issues. Dedicated reporting channels are listed below.
{% endhint %}

To report a security vulnerability open a [security advisory](https://github.com/defguard/defguard/security/advisories/new).

You can also send us an encrypted email message according to instructions in our [Vulnerability Disclosure Policy](https://defguard.net/security/#VDP-title).


# About Defguard

{% embed url="<https://www.youtube.com/watch?v=4PF7edMGBwk>" %}

## What is Defguard?

Defguard is a **comprehensive Remote Access Management solution** incorporating in one solution:

* True Zero-Trust [WireGuard® VPN with 2FA/Multi-Factor Authentication](/1.4/features/wireguard),
* Identity Management with [SSO based on OpenID Identity Provider](/1.4/features/openid-connect),
* Account Lifecycle management with [secure remote account onboarding](/1.4/using-defguard-for-end-users/enrollment).

***

<mark style="color:purple;">**Our primary focus at Defguard is on prioritizing security. Then, we aim to make this challenging topic both useful and as easy to navigate as possible.**</mark>

***

Defguard is a true Zero-Trust [WireGuard® VPN with 2FA/Multi-Factor Authentication](/1.4/features/wireguard), as each connection requires MFA (and not only when logging in into the client application like other solutions):

<figure><img src="/files/oUFdbV2DSSqNfnJHZecr" alt=""><figcaption></figcaption></figure>

Having said that, this security platform is for building **secure** and **privacy-aware organizations,** as we put great effort not only on functionality but first and foremost on secure code, architecture and testing (application and security).

### Basic security concept

The main architecture concept is that **all critical data should be in the internal (Intranet) network and not exposed in the public Internet** (contrary to typical and common cloud approach) and only services that need to be exposed to the Internet - should be exposed in a controled (DMZ) network segments:

<figure><img src="/files/luaylwwaECz7Fx99QAyD" alt=""><figcaption><p>Internet, DMZ &#x26; Internal network segments</p></figcaption></figure>

This approach is **vastly different from most (if not all) VPN/IdP solutions**, which are a simple or monolithic applications focus on functionalities and most of the time is publicly available in the Internet for any attacker to exploit.

Of course you can deploy Defguard in a typical scenario (all services on one server and even all publicly available) - but that should be **for you to decide!**

### Incorporating IdP and VPN in one solution

Incorporating IDM, ALM, VPN has also other advantages:

1. Internal IdP with 2FA/MFA enables us to provide [**real VPN 2FA/MFA**](/1.4/in-depth/architecture/architecture) - and not like most applications just 2FA when opening the app (and not during the connection process). Even if you use [external OIDC](/1.4/features/external-openid-providers) (Google/Microsoft/Custom - which Defguard supports), we still use our internal IdP for 2FA/MFA.
2. Your organization may use just **one account** (login) for access control to all your applications as well as VPN.
3. It simplifies deployment, maintenance, audits.

More about [defguard's architecture and security can be found here](/1.4/in-depth/architecture).

## Pentested!

**Checked by professional security researchers** (see [comprehensive security report](https://defguard.net/pdf/isec-defguard.pdf))


# Features overview

### Remote Access with WireGuard® VPN 2FA/MFA:

* [**Multi-Factor Authentication**](/1.4/features/wireguard/multi-factor-authentication-mfa-2fa) using our [desktop client](https://defguard.net/client)
* **Multiple VPN Locations** (networks/sites) - with defined access (all users or only Admin group)
* Multiple [Gateways](https://github.com/DefGuard/gateway) for each VPN Location ([**high availability/failover**](/1.4/deployment-strategies/high-availability-and-failover)) - supported on a cluster of routers/firewalls for Linux, FreeBSD/PFSense/OPNSense
* Import your current WireGuard server configuration (with a wizard!)
* *Easy* device setup by users themselves (self-service)
* Automatic IP allocation
* Kernel (Linux, FreeBSD/OPNSense/PFSense) & userspace WireGuard support
* [Dashboard and statistics overview](/1.4/features/wireguard/network-overview) of connected users/devices for admins

*Defguard is not an official WireGuard project, and WireGuard is a registered trademark of Jason A. Donenfeld.*

### [*Activity & Audit Logs*](/1.4/features/activity-log)

* User event logging with detailed metadata
* Advanced filtering and search by user, module, event type and time range
* Role-based visibility - users can see only their events
* Grouped logs by modules (Defguard, enrollment, VPN)
* Real-time [log streaming](/1.4/features/activity-log/activity-log-streaming) to SIEM tools (Enterprise feature)

### OpenID Connect

* Defguard is an internal OIDC provider for [Single Sign-On](/1.4/features/openid-connect).
* Supports [external OpenID](/1.4/features/external-openid-providers) providers for user authentication.

### [Access Control List](/1.4/features/access-control-list)

* Access rules for VPN locations
* Allow or deny access based on users or groups
* Changes are applied in **real time**

### Identity Management:

* #### [OpenID Connect](https://openid.net/developers/how-connect-works/) based SSO
* External [OpenID providers for login/account creation (Google/Microsoft/Custom)](/1.4/features/external-openid-providers)
* LDAP (tested on [OpenLDAP](https://www.openldap.org/)) synchronization
* Nice UI to manage users
* Users **self-service** (besides typical data management, users can revoke access to granted apps, MFA, WireGuard, etc.)

### [Multi-Factor/2FA](https://en.wikipedia.org/wiki/Multi-factor_authentication) Authentication

* [Time-based One-Time Password Algorithm](https://en.wikipedia.org/wiki/Time-based_one-time_password) (TOTP - e.g. Google Authenticator)
* WebAuthn / FIDO2 - for hardware key authentication support (e.g. YubiKey, Face ID, Touch ID, ...)
* Email tokens

### Account Lifecycle Management:

* Secure remote (over the internet) [user enrollment](https://defguard.gitbook.io/defguard/help/remote-user-enrollment)
* User [onboarding after enrollment](https://defguard.gitbook.io/defguard/help/remote-user-enrollment/user-onboarding-after-enrollment)
* Self-service for password reset

### Notifications

* [Email notifications ](/1.4/features/notifications/setting-up-smtp-for-email-notifications)via SMTP
* [Gateway disconnect/reconnect](/1.4/features/notifications/gateway-notifications) notifications
* [New version](/1.4/features/notifications/new-version-notifications) notifications

### YubiKey Provisioning

[YubiKey hardware keys](https://www.yubico.com/) provisioning for users with *one click*

### Integrations

[Webhooks](/1.4/features/integrations/webhooks) & [REST API](/1.4/features/integrations/api-tokens)

Build with [Rust](https://www.rust-lang.org/) for portability, security, and speed


# One-line install script

Welcome to getting started with Defguard! In this section, you'll be guided through setting up your simplified instance of Defguard that allows you to get familiar with the solution's features.

{% hint style="info" %}
The instance deployed by the script is meant to serve as a starting point and makes some tradeoffs to enable automated setup. Most importantly, it assumes that your Web UI is available publicly (to generate SSL certificates with Caddy). In general, it's not recommended for production, and we strongly encourage you to customise this setup to work better within your own infrastructure using more [advanced deployment strategies](/1.4/deployment-strategies/setting-up-your-instance).
{% endhint %}

To simplify the setup and enable automated deployment, we prepared a script which will deploy a complete Defguard instance, including an enrollment proxy and VPN gateway.

Just by launching this one command, there will be an interactive configuration and setup that will guide you step by step and deploy a full Defguard instance based on Docker Compose setup:

<figure><img src="/files/v5GhdSxB3SZru2oLLTLI" alt=""><figcaption></figcaption></figure>

Just copy and paste this command and [secure the setup afterwards](#securing-the-setup):

### Production Release (most stable)

```shell
curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh -O && bash setup.sh
```

### Pre-release (latest alpha/beta/release candidate)

```bash
curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh -O && bash setup.sh --pre-release
```

If you used the installation script before and would like to upgrade to the pre-release version, you can update your `.env` file (it should be located next to the docker-compose.yml file created by the script) like this:

```
CORE_IMAGE_TAG=pre-release
PROXY_IMAGE_TAG=pre-release
GATEWAY_IMAGE_TAG=pre-release
```

{% hint style="warning" %}
Downgrading to the production release may not be trivial afterwards because of the changes made to the database during the upgrade.
{% endhint %}

### Latest development builds

```bash
curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh -O && bash setup.sh --dev
```

If you used the installation script before and would like to upgrade to the development version, you can update your `.env` file (it should be located next to the docker-compose.yml file created by the script) like this:

```
CORE_IMAGE_TAG=dev
PROXY_IMAGE_TAG=dev
GATEWAY_IMAGE_TAG=dev
```

{% hint style="warning" %}
Downgrading to the production release may not be trivial afterwards because of the changes made to the database during the upgrade.
{% endhint %}

If you provide all required configuration options after the script finishes, you should have a fully functional Defguard instance with an enrollment proxy and VPN gateway to connect WireGuard clients to.

Of course, if you feel rightly uneasy about running random shell scripts from the internet, feel free to inspect the [source code](https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh).

The script does the following:

* Reads configuration from environment variables, `.env` file or user input
* Prepares a docker-compose file
* Prepares an `.env` file for the compose stack
* Creates a `.volumes` directory for persistent storage
* Generates secret keys and certificates
* Sets up an initial VPN location and VPN gateway
* Starts the compose stack

## Prerequisites

In order to work, the script requires some specific tools to be available and also some infrastructure-level settings to be pre-configured.

### Tools

* `bash`
* `openssl`
* `curl`
* `sed`
* `grep`
* `docker` - **we recommend official** [**docker engine packages**](https://docs.docker.com/engine/install/) (not packages shipped with distros)
* `docker-compose` - not necessary if using newer Docker versions (20.10+) which include the `docker compose` command

### Environment setup

{% hint style="danger" %}
This setup should be deployed on a bare-metal or a virtual (VM) server - it will **not run on a LXC container.**
{% endhint %}

* Server has a public IP address
* Public DNS records for your chosen domain
* Allow Docker to bind on host ports 80 and 443; sometimes this requires setting the `net.ipv4.ip_unprivileged_port_start` sysctl variable to 80
* Enable IP forwarding (`sysctl -w net.ipv4.ip_forward=1`)
* Firewall rules
  * allow incoming traffic on chosen WireGuard port and port 443
  * enable `MASQUERADE` for VPN traffic (for example `iptables -t nat -I POSTROUTING 1 -s {vpn_subnet} -o {internet_interface} -j MASQUERADE`)

## Configuration

There are several options that can be configured to customise your Defguard instance. They can be provided to the script in the following ways:

* By setting environment variables in your shell
* By providing an `.env` file in the working directory
* By running the script manually and setting CLI options
* By providing user input

### Environment variables

* `DEFGUARD_DOMAIN` - domain for your Defguard web UI (e.g. `id.example.com`)
* `DEFGUARD_ENROLLMENT_DOMAIN` - (optional) domain for the enrollment service; if not set, the service will not be deployed
* `DEFGUARD_USE_HTTPS` - (optional) set to any value if you want Caddy to generate SSL certificates and use HTTPS
* `DEFGUARD_VPN_NAME`- (optional) name of initial VPN location to create; if not provided, the script will not set up the VPN gateway
* `DEFGUARD_VPN_IP`- (optional if VPN name not set) gateway address within the VPN network (e.g. `10.0.50.1/24`)
* `DEFGUARD_VPN_GATEWAY_IP`- (optional if VPN name not set) gateway public IP
* `DEFGUARD_VPN_GATEWAY_PORT`- (optional if VPN name not set) gateway public port
* `CORE_IMAGE_TAG`- (optional) tag to use for `defguard` Docker image
* `PROXY_IMAGE_TAG`- (optional) tag to use for `defguard-proxy` Docker image
* `GATEWAY_IMAGE_TAG`- (optional) tag to use for `defguard-gateway` Docker image

### CLI options

```
Defguard deployment setup script v1.1.0
Copyright (C) 2023 teonite <https://teonite.com>

Usage:  [options]

Available options:

        --help                         this help message
        --non-interactive              run in non-interactive mode (no user input)
        --domain <domain>              domain where Defguard web UI will be available
        --enrollment-domain <domain>   domain where enrollment service will be available
        --use-https                    configure reverse proxy to use HTTPS
        --vpn-name <name>              VPN location name
        --vpn-ip <address>             VPN server address & netmask (e.g. 10.0.50.1/24)
        --vpn-gateway-ip <ip>          VPN gateway external IP
        --vpn-gateway-port <port>      VPN gateway external port
        --dev                          use development docker images
        --pre-release                  use pre-release docker images
```

## Securing the setup

After the installation, please make sure that **only the following ports are open on the server firewall:**

* HTTPS port for the proxy (and/or the Defguard core if you want it to be public)
* VPN server port (eg. WireGuard port)

{% hint style="danger" %}
**DO NOT EXPOSE PUBLICLY THE gRPC ports of the core gateway and proxy, which are:**

* 50052
* 50055
  {% endhint %}

Also, this setup provides only communication encryption between Defguard components, if you additionally like for core/proxy and gateway to have authorization - [please set up a custom SSL CA](/1.4/deployment-strategies/grpc-ssl-communication#custom-ssl-ca-and-certificates).

## Advanced deployment strategies

For more advanced deployment strategies, go to our [deployment strategies section](/1.4/deployment-strategies/setting-up-your-instance).


# Overview

## Welcome to Defguard admin documentation

This documentation walks you through all the administrative features of Defguard and how to configure them.

We recommend setting up your own example instance using our [one-line install script](/1.4/getting-started/one-line-install) to explore these features firsthand. As you follow along, you can adjust the configuration directly within your instance to better understand each feature in action.

### What you’ll learn

As a future Defguard administrator, this documentation will help you:

* Be aware of all the possibilities you have with Defguard.
* How to configure them to your needs.

If you're more interested in different deployment strategies after using our [one-line install script](/1.4/getting-started/one-line-install), go to the [deployment strategies](https://github.com/DefGuard/docs/blob/docs/admin-and-features/broken-reference/README.md) section.


# Zero-Trust VPN with 2FA/MFA

## Defguard is based on WireGuard®

WireGuard® compared to any other VPN solution on the market provides:

* Faster VPN Speeds: WireGuard® is \~10x faster then OpenVPN - since it’s on kernel and protocol level and not application level (like OpenVPN) and significantly faster then IPSec.
* Seamless Roaming: WireGuard® is designed to handle network changes (like switching from Wi-Fi to cellular) more gracefully than any other VPN, maintaining the connection without interruption - whereas OpenVPN and IPSec looses connections on network change.
* Lower VPN Latency: WireGuard® has far lower latency due to its lightweight design.
* Instant Connectivity: WireGuard’s handshakes are very fast, allowing near-instantaneous connections, unlike OpenVPN or IPSec, which can take a few seconds to establish a connection.

## Zero-Trust with 2FA/MFA

Defguard introduces unique Multi-Factor Authentication (MFA) for the WireGuard® VPN protocol, ensuring every connection requires authorization with MFA (human factor + session keys) enhancing security with an added layer of user verification to support compliance with GDPR, HIPAA, PCI DSS, NIST, FISMA, and CMMC standards.


# Create/Manage VPN Location

A VPN location is a VPN network to which users can connect to. Every location has a [dedicated gateway](/1.4/deployment-strategies/gateway) (or [multiple gateways if you deploy a high-availability solution](/1.4/deployment-strategies/high-availability-and-failover#gateway-high-availability)).

{% hint style="success" %}
Defguard supports **multiple locations**, for each location to work you need to configure it and deploy a dedicated gateway.
{% endhint %}

{% hint style="info" %}
If you are looking for MFA settings, go [here](#multi-factor-authentication-for-a-location).
{% endhint %}

When creating a new VPN location, you can choose if you want to **create it from scratch (Manual Configuration)** or **import your current WireGuard configuration**:

<figure><img src="/files/C2rioVqGY8Z8vSbwoFhG" alt=""><figcaption></figcaption></figure>

## VPN Location settings

Next step is configuring the location settings:

<figure><img src="/files/1Df7TCrgPkj2ISUv0quq" alt=""><figcaption></figcaption></figure>

### Location name

It's a name that will be visible both on the UI, but also in the desktop client for all the users. For example, if you name your location *Monaco Office*, the desktop client will show:

<figure><img src="/files/4kFELkxpWGtPHX2mvnrp" alt="" width="375"><figcaption></figcaption></figure>

### Gateway VPN IP addresses and masks

By providing the VPN IPs/masks, you are configuring both: **the VPN internal networks and VPN server IPs**. Every gateway will bind to these addresses, and Defguard will also generate and assign IP addresses for devices in this location from these networks.

This field can contain multiple IP addresses (both IPv4 and IPv6), separated by a comma (e.g. `10.10.20.1/24,fc00::abcd:0:1/96`).

{% hint style="info" %}

### Dual-stack VPN networks

Defguard supports dual-stack VPN networks, allowing simultaneous assignment of both IPv4 and IPv6 addresses to clients. Each VPN network can include multiple IPv4 and IPv6 subnets, and connected clients will automatically receive one address from each defined subnet. This enables seamless communication over both IP versions within a single VPN session.
{% endhint %}

{% hint style="warning" %}
Defguard assigns IP addresses to clients by sequentially scanning each defined subnet and selecting the first available address. If no free address is found in any of the configured networks, the client will not receive an IP assignment. In such cases, you’ll need to adjust the network configuration - such as expanding the address pool by decreasing the netmask - to accommodate additional clients.
{% endhint %}

#### Examples

1. 10.11.0.1/8
   1. internal VPN network will be: 10.11.0.0 with netmask 255.0.0.0
   2. VPN gateway internal IP address will be: 10.11.0.1
2. 192.168.8.1/24,fc00::1/112
   1. internal VPN networks will be: `192.168.8.0` with netmask `255.255.255.0` and `fc00::0` with netmask FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:0000
   2. VPN gateway internal IP addresses will be: 192.168.8.1 and fc00::1

### Gateway address

It's the **public IP address** or **DNS domain** to which the remote peer's/users will connect to. This address is **will be shared in the configuration** for the clients, but Defguard gateways do **not bind to this address**.

{% hint style="info" %}
**Defguard gateways bind to all IP addresses and the port defined below.**

This is very handy if you are setting up a **high availability active-active** solution with multiple gateways - then this public IP needs to be exposed and controled by load-balancers or any other solution that will forward this to gateways.
{% endhint %}

{% hint style="success" %}
DNS domain is **very useful** for example is a setup uses Dynamic DNS (DDNS).
{% endhint %}

### Gateway port

Defguard **gateways bind to this port**, and this port is shared in configuration to any client.

### Allowed IPs

Defines the IP ranges a device is allowed to route or communicate with.

It supports multiple networks separated with comma, e.g. 10.11.1.0/0, 192.168.1.0/24

{% hint style="danger" %}
Right now Defguard only manages routing of Allowed IPs (adding to routing table the networks defined in Allowed IPs).

If you want the *All Traffic* to work in the desktop client you need to also configure MASQUARED/NAT for the VPN interface. [Example of that here.](/1.4/tutorials/step-by-step-setting-up-a-vpn-server#enabling-to-access-internet-through-your-vpn)
{% endhint %}

### DNS

This specifies DNS resolvers and search domains. Supported format is by comma separation, e.g.:

`IP, IP, search.domain.net, second.search.domain.com`

### Allowed groups

Here, you can specify **what groups (users assigned to those groups) have access to this VPN Location.**

{% hint style="warning" %}
By default (if no group is chosen) **all users will have access to this location.**

By defining a group, assigning users to that group and then choosing this group(s) you can restrict access to VPN Locations.
{% endhint %}

### Multi-Factor Authentication for a Location

#### Require MFA for this location

By enabling this setting, this location **will require Multi-Factor Authentication** on each connection to this location.

{% hint style="danger" %}
This feature is only supported in [**Defguard Desktop Client**](/1.4/using-defguard-for-end-users/desktop-client)**.**
{% endhint %}

Each connection in the client:

1. Will require the user to provide either TOTP token or Email code.
2. After authorizing, Defguardwill do a key exchange and set up a pre-shared session key unique for this connection.

{% hint style="warning" %}
For this feature to work, the user must:

1. configure their [TOTP settings in the profile](/1.4/using-defguard-for-end-users/setting-up-2fa-mfa#one-time-password)
2. [SMTP settings needs to be set up](/1.4/features/notifications/setting-up-smtp-for-email-notifications) and the user must enable Email tokens in their profile.
   {% endhint %}

#### Keep alive interval

Configurable time interval (in seconds) used to send periodic packets to ensure that the connection remains active. This is particularly useful in environments like NAT (Network Address Translation) or firewalls that may close idle connections.

**Peer disconnect threshold**

Since Multi-Factor Authentication (MFA) is used to enforce zero-trust security, a peer (user) that remains inactive for a specified time interval (defined in seconds within the settings) will be disconnected. Additionally, the session configuration will be removed from the gateway. This ensures that when the peer reconnects, they must complete the MFA process again.

{% hint style="warning" %}
Minimal value for this setting is 120 (2 minutes).

Recommended is more then 300.
{% endhint %}

#### Multi-Factor Authentication with external OIDC/SSO (Google/Microsoft/Okta/...)

{% hint style="info" %}
This feature is currently available in pre-release version 1.5
{% endhint %}


# Network overview

Once your gateway service is up and users start connecting to the VPN, upload/download summary data is stored and can be displayed in "overview" tab of Defguard web application. See [architecture overview](/1.4/in-depth/architecture) for details of core-gateway interaction.

On the overview page, you'll see who is currently connected and how much data each connected user transferred. You'll also see overall network transfer charts.

Since **version 1.4**, Defguard dashboard allows administrators to see:

* Current amount of active users / network devices
* Active users / network devices during time period
* Network usage
* Gateway status

### Dashboard

To access this dashboard, go to **VPN Overview** tab.

<figure><img src="/files/dy1ojYuZGPTPHj5UayeS" alt=""><figcaption></figcaption></figure>

Dashboard looks like this, if you want to see more details about location, proceed to [this section.](#detailed-location-overview)

<figure><img src="/files/878UiojBCY72HDquxG8Y" alt=""><figcaption></figcaption></figure>

### Detailed location overview

To access a dashboard with detailed information, you can:

* Select location at the top of the page

<figure><img src="/files/XdFkDKutrOjgVB7frUoo" alt=""><figcaption></figcaption></figure>

* Click **See Location Details** next to location

<figure><img src="/files/KsAo4x9Acgdanmo7BPaE" alt=""><figcaption></figcaption></figure>

***

In this view, you can see individual users and network devices using this specific location.

<figure><img src="/files/AwqFkM8bqE5qPDtGt3ar" alt=""><figcaption></figcaption></figure>

To access detailed information about a specific user, click the blue icon located next to the username.

<figure><img src="/files/JoKvzUpMmPcZzRX8nBJq" alt=""><figcaption></figcaption></figure>

After expanding, you will see devices which are currently being used by the user.

<figure><img src="/files/VPIBA8Aay6t248J7oMmg" alt=""><figcaption></figcaption></figure>


# Multi-Factor Authentication (MFA/2FA)

Defguard is the sole VPN solution that genuinely implements Multi-Factor Authentication (MFA) before a WireGuard® VPN connection is established, significantly enhancing security against cyberattacks.

## TL;DR;&#x20;

* MFA (Multi-Factor Authentication) is a method of securing IT systems that requires the user to confirm their identity using at least two or more independent verification factors.
* MFA during a VPN connection requires the user to authenticate in the VPN client with two or more factors **before the connection can be established**.
* Defguard is the **only solution that enables MFA for WireGuard® VPN connections**.
* MFA is a widely overused marketing term for many (if not all) WireGuard®-based VPN solutions. In most other cases, it simply refers to **2FA for accessing the configuration panel or performing the initial client setup, and no MFA during connection stage.**

## What Multi-Factor Authentication actually is?

MFA (Multi-Factor Authentication) is a method of securing IT systems that requires the user to confirm their identity using at least two or more independent verification factors.

There are three main categories of MFA:

* Something a user knows: e.g., password, PIN, or answer to a security question.
* Something a user has: a physical token, smartphone, authenticator app generating one-time codes, or a security key.
* Something a user is: biometric data such as a fingerprint, face scan, or voice recognition

IT systems build authentication methods using those three areas and leverage them to secure operations done on the system (logging in into the system, establishing a connection, etc.).

## How Defguard handles MFA?

Defguard is a unique VPN solution that can be configured to use either:

1. **internal - built-in IdP/SSO** - where users in Defguard profile manage their MFA methods and then use them to establish a VPN connection,
2. **external - using cloud IdP/SSO providers** such as [Google](/1.4/features/external-openid-providers/google), [Microsoft](/1.4/features/external-openid-providers/microsoft), [Okta](/1.4/features/external-openid-providers/okta), [Jumpcloud](/1.4/features/external-openid-providers/jumpcloud) (and others) to authorize each connection using those providers in Defguard desktop/mobile before the connection can be established - [<mark style="color:$warning;">from 1.5 version - see 1.5 docs</mark>](/1.4/features/wireguard/multi-factor-authentication-mfa-2fa)<mark style="color:$warning;">.</mark>

In addition, when establishing a VPN connection, **Defguard enforces extra security measures** (including additional MFA steps in the user has category). It first securely establishes session keys (WireGuard® pre-shared keys), and only then configures the VPN location (our VPN gateway). The connection is possible to establish only with a device that has successfully passed the full authorization flow, enabling it to connect using its WireGuard® private/public keys and session keys.

Defguard also supports **multiple VPN locations (multiple VPNs), each of which can be configured independently to use either internal or external MFA (also** [<mark style="color:$warning;">**from 1.5 version - see 1.5 docs**</mark>](/1.4/features/wireguard/multi-factor-authentication-mfa-2fa)<mark style="color:$warning;">**).**</mark>

### Multi device MFA

{% hint style="warning" %}
This is supported from[ 1.5 version. See  1.5 docs. ](/1.4/features/wireguard/multi-factor-authentication-mfa-2fa)
{% endhint %}

Some of Defguard’s MFA methods are even more sophisticated, such as establishing a VPN connection using mobile biometric authentication in the desktop client. This method requires:

User prerequisites (something a user has in terms of MFA terminology):

* A private WireGuard® key corresponding to the public key configured during the Defguard enrollment session.
* A mobile device successfully enrolled and added to the user profile (as a second VPN device).
* Private keys in the mobile device’s secure key store, generated during the mobile device enrollment process, which are accessible only via the device’s biometric authentication.<br>

Extended MFA flow using two devices:

1. Scan the QR code displayed in the desktop app using the enrolled mobile device.
2. Perform MFA using the biometric authentication and private/public key pair, which is only accessible after successful biometric verification.
3. Only after these steps can the remaining Defguard flow, as described above, proceed.

## Why MFA for each connection Is not only Important but necessary

The main purpose of MFA is to strengthen security by acting as a highly effective barrier against cyberattacks such as phishing or brute-force attacks. With an effective MFA implementation, even if an attacker gains access to a user’s basic credentials (in WireGuard®’s case, typically the private key stored on the device), they will still be unable to connect to the VPN without the additional factor(s). This prevents access to critical private network resources and applications, blocking further exploitation and greatly reducing the risk of unauthorized access.

<mark style="color:$danger;">This means that relying on external SSO only for the initial device configuration is not sufficient to provide security in today’s environment. Even worse, marketing a VPN solution as providing MFA under these circumstances is highly misleading and potentially harmful to user security.</mark>

\ <br>


# Internal SSO based MFA

## Internal MFA

Enabling Internal MFA for a desired VPN Location is done by:

1. Going into Defguard to **VPN Overview**
2. Selecting the VPN Location from the dropdown list, and pressing the **Edit Location** button in the top right corner of the page
3. Check the "**Require MFA for this Location**" checkbox under the Location Configuration section
4. Set **peer disconnect threshold**, we recommend it to be min. 300 (5 min) - see chapter [below](#peer-disconnect-threshold).
5. And **save changes**.

<figure><img src="/files/VTCsNGakoPzrDjg2nTrr" alt=""><figcaption><p>Example MFA Location configuration</p></figcaption></figure>

### Peer disconnect **threshold**

When MFA is enabled on a location, Defguard periodically (currently every **1 minute**) checks statistics if a client is connected and if the period of inactivity (defined in Peer disconnect threshold option) is met, a client is disconnected.

Thus, the gateway needs to be configured to send statistics in that period.

We recommend to set:

* gateway to send statistics every 30sec
* Peer disconnect threshold we recommend it to be min. 300 (5 min)

### Client update after enabling MFA

{% hint style="warning" %}
When MFA configuration is changed, all clients must do an [Instance Update](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration#updating-instance).
{% endhint %}

### Testing MFA on Defguard client

If a VPN has MFA enabled, before connecting you will be asked to complete the authentication step first:

<figure><img src="/files/CbTvoH4Ruf0ViYJ80Bhf" alt=""><figcaption><p>MFA in Defguard desktop client</p></figcaption></figure>

### Supported MFA methods

For now, MFA is only available with the following methods:

* [TOTP - Time-based one-time password](/1.4/using-defguard-for-end-users/setting-up-2fa-mfa#one-time-password)
* Email - requires [SMTP to be configured](/1.4/features/notifications/setting-up-smtp-for-email-notifications)

{% hint style="warning" %}
Please remember to configure TOTP on you user account and/or SMTP settings for MFA on the desktop client to work..
{% endhint %}

### User MFA setup

After enabling MFA for a given VPN, users will need to enable MFA for their accounts to be able to connect. This process is described in [Setting up 2FA/MFA](/1.4/using-defguard-for-end-users/setting-up-2fa-mfa). For simplicity & security, the desktop client uses the same MFA methods as the Defguard server.

An error message will be shown if users attempt to select an MFA method that has not been enabled for their accounts:

<figure><img src="/files/rJVK2FK7orXUMi9ywyk4" alt=""><figcaption><p>Attempting to use an MFA method that has not been enabled on the user's account.</p></figcaption></figure>

### Successful authentication

If authentication succeeds, the VPN two-factor authentication modal will be closed and connection to the selected VPN will be attempted. Users will be asked to authenticate on every connection to a VPN with MFA enabled.


# External SSO based MFA

{% hint style="warning" %}
Since [version 1.5.0 ](/1.5/features/wireguard/multi-factor-authentication-mfa-2fa)we support MFA based on external OIDC/SSO.
{% endhint %}

You can use [Internal OIDC/SSO](/1.4/features/openid-connect) - called [Internal MFA ](#internal-mfa)- to force Desktop & Mobile clients to authenticate with **TOTP & Email codes** and after that with **session keys based on WireGuard Pre-Shared Keys** (PSK). For more details about this, please refer to the [architecture section](/1.4/in-depth/architecture/architecture).


# Remote desktop client configuration

How to manually generate token for user as an administrator.

This process enables system **administrators** to create and distribute desktop **activation tokens to users facing access issues to the Defguard instance**. It's handy if a user is already enrolled (has an account) but has not configured the desktop client and doesn't have access to Defguard (is outside the internal network and can't access Defguard).

{% hint style="info" %}
Users can activate / configure their desktop client themselves - for that documentation please go to: [Adding an instance in the client documentation](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration).
{% endhint %}

Navigate to the user's list page.

<figure><img src="/files/8kXnD2GkeyENIxjH6v0W" alt=""><figcaption></figcaption></figure>

Select "Configure Desktop Client" from the action menu.

{% hint style="info" %}
This option is only available if the instance has at least one localization, and the user is 'active'. For users that require enrollment, you can choose the option 'Start enrollment' and that token will also work with the client.
{% endhint %}

<figure><img src="/files/ALXU0nPla2Ubcz6LSQBZ" alt=""><figcaption></figcaption></figure>

You will be presented with a choice to send an activation token via email or you can choose to just display the token and deliver it through other methods.

<figure><img src="/files/rsDoOdJ6JKYkMI14o34v" alt=""><figcaption></figcaption></figure>

After receiving the token, the user will need to follow the activation process in the client. You can find out more about it in [Instance configuration](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration#adding-instance).

This token also allows for updating information, read more about it in [Instance configuration](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration#updating-instance).


# VPN & Client behaviour customization

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

After purchasing the Enterprise License the *Enterprise features* **tab will be activated**, enabling the administrator to configure additional features:

<figure><img src="/files/S2shAErZfMgf9Mp88EBw" alt=""><figcaption><p>Additional Enterprise Features</p></figcaption></figure>

### Disable for users to manage their devices

When this option is enabled, **only users in the Admin group can manage devices in user profile**, for any other users adding/editing/removing their VPN devices is disabled.

### Disable ability to configure other VPN clients then Defguard desktop client

If '*Disable users' ability to manually configure WireGuard client*' option is **enabled**, then any user **has only possibility to configure Defguard desktop client.**

This option will not be available for users:

<figure><img src="/files/49mwNosfgAQZd4ZQlLxd" alt=""><figcaption></figcaption></figure>

### Disable *All Traffic* option in the desktop client

One of Defguard desktop client unique features is the possibility for the user to automatically route **All network traffic** from their device **through the connected VPN Location**, when the user checks *All traffic* optio&#x6E;***:***

![](/files/YE32qw6NeqXJcJ6Ezvsb)

But there are scenarios that administrator would like that users have only access to the **predefined traffic** (meaning Allowed IPs in the Network VPN configuration) and the possibility to access all networks disabled.

When enabling this option, users will only have *predefined traffic* available in their desktop client and the *all traffic* option disabled.

{% hint style="warning" %}
Please note that this option is only client-side enforced, meaning the user may manually modify Wireguard interface to force all traffic to go through the VPN.
{% endhint %}


# DNS and domains

To change / add DNS settings or a DNS search domain:

* Go to Location overview
* Click \*Edit location settings\* (right top corner)
* In the DNS section enter the IP addresses of DNS servers (separated by commas ",") and a search domain

For example:

<figure><img src="/files/RWHhqHAuaNs6XFlBp4fs" alt=""><figcaption></figcaption></figure>


# Executing custom gateway commands

Defguard gateway has ability to execute custom commands before and after the WireGuard tunnel us up or down.

{% hint style="warning" %}
If you want to run a shell script, you should pass it's path to your shell, for example:

`/bin/sh -c /path/to/script`
{% endhint %}

You can use this functionality in various ways:

#### ENV Variables

* `PRE_UP` - Command to run before bringing up the interface.
* `POST_UP` - Command to run after bringing up the interface.
* `PRE_DOWN` - Command to run before bringing down the interface.
* `POST_DOWN` - Command to run after bringing down the interface.

#### Command line arguments

* `--pre-up` - Command to run before bringing up the interface.
* `--post-up` - Command to run after bringing up the interface.
* `--pre-down` - Command to run before bringing down the interface.
* `--post-down` - Command to run after bringing down the interface.

#### /etc/defguard/gateway.toml - configuration file entries

* `pre-up` - Command to run before bringing up the interface.
* `post-up` - Command to run after bringing up the interface.
* `pre-down` - Command to run before bringing down the interface.
* `post-down` - Command to run after bringing down the interface.


# Remote user enrollment

By design **Defguard core** is meant to be deployed **securely** within your infrastructure and only accessible from within the internal network or by VPN.

This introduces an issue with onboarding **new users** and forces the admin to choose an initial password, setup a VPN device for them, and pass on those details to the end user using possibly **insecure** channels.

To avoid this issue you can deploy a **public** [Defguard proxy](https://github.com/DefGuard/proxy) which enables a **secure enrollment process:**

<figure><img src="https://raw.githubusercontent.com/DefGuard/docs/docs/releases/0.7/enrollment.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The proxy is included when using the default [deployment instructions](/1.4/deployment-strategies/setting-up-your-instance).

Please also see the relevant configuration options for [core](/1.4/deployment-strategies/configuration#enrollment-configuration) and the [proxy itself](/1.4/deployment-strategies/configuration#enrollment-service).
{% endhint %}

## Enrollment settings

{% hint style="warning" %}
In order for the enrollment process to function correctly you must also [set up an SMTP server](/1.4/features/notifications/setting-up-smtp-for-email-notifications) for delivering email notifications.
{% endhint %}

As an admin, you can configure enrollment-related settings on the **Enrollment** page. This includes:

* Making the VPN device step optional or mandatory in the enrollment wizard
* Customizing the user [onboarding messages](/1.4/features/remote-user-enrollment/user-onboarding-after-enrollment).

#### Message template tags

There are several **template tags** (similar to [Jinja2](https://jinja.palletsprojects.com/en/3.1.x/) tags) that you can use in the onboarding messages to insert some dynamic content:

* `{{ first_name }}` - newly created user first name
* `{{ last_name }}` - newly created user last name
* `{{ username }}` - newly created user username/login
* `{{ admin_first_name }}` - first name of the administrator who initiated the enrollment process
* `{{ admin_last_name }}` - last name of the administrator who initiated the enrollment process
* `{{ admin_phone }}`- phone number of the administrator who initiated the enrollment process
* `{{ admin_email }}`- email of the administrator who initiated the enrollment process
* `{{ defguard_url }}`- internal Defguard URL (your Defguard instance address)
* `{{ defguard_version }}`

## Remote enrollment process

### Starting remote enrollment (as an admin)

* Go to **Users** page
* Click **Add new** user button
* Within the modal that appears fill in the new user's data as usual, but instead of entering a password check the **Use enrollment process** checkbox
* Click the **Add user** button
* In the next modal choose whether you want to **Send token by email** or **Deliver token yourself**
* If you choose to deliver the enrollment token by email provide an email address to which a notification will be sent

{% hint style="info" %}
The email address you specify for delivering the enrollment token can be any email available to the user. It **does not** have to be the same one used when creating an account as we assume that a new user does not yet have access to their official company email account.
{% endhint %}

* Click **Start enrollment**
* If you choose to deliver the token yourself you'll be shown a URL and token that you can copy and pass to the user

### Restarting enrollment manually

If there are any issues with the enrollment process (failed notification delivery, a lost token etc) you can restart it:

* Go to **Users** page
* Find the relevant user and click on the **Action** button on the right
* A **Start enrollment** option should be available in the pop-over menu
* Clicking it will open the same **Start enrollment** modal where you can choose how to deliver the enrollment token

### Performing remote enrollment (as a user)

As a new user, after an admin starts the enrollment process, you will receive your enrollment token.

If you receive an **email notification**, just click the link, and you'll be redirected to the enrollment wizard.

If the admin decides to deliver your token through some other secure means, you'll have to go the specified enrollment page and enter the token **manually**.

By following the **enrollment wizard,** you'll be able to do the following:

* verify that your data is correct
* activate your user account
* choose your password
* add an initial device for VPN access

After completing the wizard, you should be able to connect to the VPN and access the main Defguard web UI.


# User onboarding after enrollment

After the [enrollment](/1.4/features/remote-user-enrollment) process is done, you can easily share with new users **any relevant company information, links to company systems, security guidelines**, etc. In the [enrollment module](/1.4/features/remote-user-enrollment#enrollment-settings), you can write **custom messages** using Markdown that will be shown on the last step of the enrollment process and/or sent to the user via email:

<figure><img src="https://github.com/DefGuard/docs/raw/docs/releases/0.7/enrollment_msg.png?raw=true" alt=""><figcaption><p>Example user onboarding message</p></figcaption></figure>

What is unique about this process, is that you can also use [custom template tags](/1.4/features/remote-user-enrollment#enrollment-settings) that contain newly created user data, the admin (that has invoked the remote enrollment) data and others.


# Automatic (real time) desktop client configuration & sync

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

When initially configuring Defguard desktop client, all available locations for the user (with all location settings) are automatically configured (which is one of Defguard's unique functionalities).

In the course of time: new locations can be added by administrators, existing ones may change the configuration (DNS, network, etc.) or a user will be assigned to a new group (which for example doesn't have access to some locations any more).

In order to reconfigure a user's desktop client, the administrator has two possibilities:

1. If using the **Open Source Open Core** - the administrator needs to send a new configuration token to each user affected, and the user needs to [update the instance](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration#updating-instance) in the desktop client with the new obtained token.
2. Obtain the **Enterprise License**, then each user desktop client (and all Locations) are **reconfigured automatically in real time** (propagation takes around 30 seconds to 1 minute) whenever any VPN Location is reconfigured or the user is assigned to a different group.

{% hint style="warning" %}
If you have been using Defguard prior to version 1.0.0, upgraded and have Enterprise License, to take advantage of the real-time config sync on an already configured desktop client, [please refer to Upgrade notes documentation.](/1.4/deployment-strategies/upgrading#desktop-client-real-time-sync)
{% endhint %}


# Internal SSO (OpenID Connect Provider)

## OpenID Connect

### What is OpenID Connect?

OpenID Connect is an identity layer built on top of OAuth2, it allows third-party applications to get basic information about your profile and verify your identity. Its purpose is to give you one login for multiple sites. You're probably familiar with it if you used **Login with Google**. For example, if you click Login with Google you'll be redirected to the Google page with verify form that you allow some website to get information from your profile for example email, name, etc.

### Defguard as an OpenID Connect Provider

Defguard is a full-featured OIDC provider enabling SSO (Single Sign-On) across third-party applications. Apps can authenticate users through Defguard identity system using standard [OIDC flow](#defguard-openid-flow). &#x20;

Example:

<figure><img src="/files/x5A7jQeLmYYaO5Ns0SS6" alt=""><figcaption></figcaption></figure>

### How Defguard implements OpenID?

As an identity provider, one of our core features is Login with Defguard which allows you to log into other websites using your Defguard account so you don't have to care about multiple passwords and leaks. At this point you may have concern and ask is it safe? Yes, it's completely safe cause all information third party app will receive is the information that you allowed on the redirect page. This information then are sent to third party app as IDToken which is basically JSON Web Token with additional claims like first name or email. Your password isn't sent in any step of this.

### Defguard OpenID flow

![OpenID flow](/files/EmTy1R9zHY3q5ThM4DaB)

### How to enable login with Defguard using OpenID?

#### Client creation

To enable login with other app first you need to add it as new OpenID client. To do it, navigate to OpenID Apps on the left side navigation, then click Add new button.

![OpenID add client form](/files/95UX1VB2WEHRi7WsSzZe)

Here are explained inputs

**Name** of your client **Redirect URI** URL to which user will be redirected with generated PKCE code example("<https://myapp.com/redirect\\_uri>") **Scopes** which your client will be using

After creating your client, you can click on it on the list and be redirected to a detailed client page with it unique Client ID and Client secret codes.

**Client ID** is a public identifier for apps. Something like unique login so we can verify app URL matches its Client ID. **Client Secret** Only known for authorization server(Defguard) and the applications as we are using

Setup on authorization app if you want to log in with Defguard.

### OpenID endpoints

#### Discovery endpoint

OpenID Connect defines a discovery mechanism, called OpenID Connect Discovery, where an OpenID server publishes its metadata at a well-known URL, typically. This URL returns a JSON listing of the OpenID/OAuth endpoints, supported scopes and claims, public keys used to sign the tokens, and other details. The clients can use this information to construct a request to the OpenID server. **Note** For this endpoint to work correctly you have to set env variable named `DEFGUARD_URL` with URL of your Defguard instance.

`https://defguard.company.net/.well-known/openid-configuration`

#### Authorization

`https://defguard.company.net/api/v1/oauth/authorize`

#### Token

`https://defguard.company.net/api/v1/oauth/token`

#### Userinfo

`https://defguard.company.net/api/v1/oauth/userinfo`

#### Authentication request

Set up your login with Defguard button to redirect to authorization endpoint, which is `https://defguard.company.net/openid/authorize?`

Below is a sample authentication request which your app should do on Login with Defguard button

```
http://defguard.company.net/api/v1/openid/authorize?
client_id=<YOUR_CLIENT_ID> // Generated by Defguard available on app detail page
&redirect_uri=<YOUR_REDIRECT_URI>  //Url on which user with code will be redirected
&scope=openid%20profile%20phone%20email // available scopes
&response_type=code // Currently only supported response is code
&state=<YOUR_STATE> // State to returned on redirect uri to verify request comes with Defguard
```

**Notes:**

1. Client id and secret is generated by Defguard after creating your app, you can see it on app detail page
2. **Scope** must contain OpenID
3. Available scopes are profile (all available info from user profile) phone and email
4. Currently, only supported **response\_type** is **code**.
5. Redirect URI is URL on which user will be redirected with generated PKCE code (Redirect URI must match URI declared on client creation otherwise error will be returned)

**Successful authentication response**

```
HTTP/1.1 302 Found

Location: <YOUR_REDIRECT_URI>?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
```

#### Exchange code for ID Token

After receiving code from previous step, you need to exchange it for token on token endpoint `defguard.company.net/api/v1/openid/token`

Request Header and URL:

```
Content-Type: application/x-www-form-urlencoded
POST defguard.company.net/api/v1/openid/token
```

Request body: Need to be form encoded

```
grant_type=authorization_code
&redirect_uri=<YOUR_REDIRECT_URI>
&code=<CODE_RECEIVED_IN_PREVIOUS_STEP>
```

**Note:**

1. Currently, only supported **grant\_type** is authorization\_code
2. Code is your PKCE code received in previous step

**Successful Token Response**

```
  HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-store
  Pragma: no-cache

  {
   "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
     yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
     NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
     fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
     AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
     Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
     NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
     QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
     K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
     XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
  }
```

**Note:**

1. As we are using HS256 algorithm, ID Token is signed using your app Client Secret

**Authorized apps:**

Every user that used Login with Defguard option can see in his profile name of every authorized app. If you revoke app, then you will have to click allow on the form with permissions again.

## OpenID clients

Below, you can find tutorials on how to configure OpenID for:

{% content-ref url="/pages/mGZRfYUFcHvgYojT29wA" %}
[Portainer](/1.4/features/openid-connect/portainer)
{% endcontent-ref %}

{% content-ref url="/pages/hj7qo8bMwAMZ6SOQfkr2" %}
[Grafana setup](/1.4/features/openid-connect/grafana-setup)
{% endcontent-ref %}

{% content-ref url="/pages/QjeZ65t4xZhppBAcWXKF" %}
[Proxmox](/1.4/features/openid-connect/proxmox)
{% endcontent-ref %}

{% content-ref url="/pages/DjsTf6MvZ2kJ2epXInBK" %}
[Django](/1.4/features/openid-connect/django)
{% endcontent-ref %}

{% content-ref url="/pages/hBhF1Hdx9Atm456FenE3" %}
[Matrix / Synapse](/1.4/features/openid-connect/proxmox-1)
{% endcontent-ref %}

{% content-ref url="/pages/T4IzC2B1dsc4soY1YLuH" %}
[MinIO](/1.4/features/openid-connect/minio)
{% endcontent-ref %}

{% content-ref url="/pages/iZT6pAop5CvCN8e7BVnq" %}
[Vault](/1.4/features/openid-connect/vault)
{% endcontent-ref %}


# Portainer

## Add Portainer app in Defguard

First, go to the Defguard OpenID tab and click add new app button.

1. Add the name `Portainer`
2. Redirect Url add `https://yourportainer.com` where yourpotainer.com is the address of your portainer instance.
3. Select the below scopes

* OpenID
* Profile
* Email

Then add your app. After successfully adding your app you can see it in the OpenID apps list. When you click on it you will be redirected to the client details page. From this page copy Client ID and Client secret values for later.

## Portainer configuration

When you login to portainer go to **Settings -> Authentication**

On this page select: Authentication method: OAuth

**Provider**

Select **Custom**

**OAuth Configuration**

* **Client ID** -> Client ID from Defguard available on client details page.
* **Client secret** -> Client secret from Defguard available on client details page.
* **Authorization URL** -> https\://\<YOUR\_DEFGUARD\_INSTANCE>/api/v1/oauth/authorize
* **Access token URL** -> https\://\<YOUR\_DEFGUARD\_INSTANCE>/api/v1/oauth/token
* **Resource URL** -> https\://\<YOUR\_DEFGUARD\_INSTANCE>/api/v1/oauth/userinfo
* **Redirect URL** -> https\://\<YOUR\_PORTAINER\_URL>
* **User identifier** -> sub
* **Scopes** -> `openid email profile` **Note** must be spaces separated as in this example


# Grafana setup

#### Add grafana app on defguard

First, go to the Defguard OpenID tab and click add new app button.

1. Add the name Grafana
2. Redirect Url add `https://<grafana domain>/login/generic_oauth` where is the address of your grafana instance.
3. Select the below scopes

* OpenID
* Profile
* Email Then add your app. After successfully adding your app you can see it in the OpenID apps list. When you click on it you will be redirected to the client details page. From this page copy Client ID and Client secret values for later.

#### Grafana setup

1. Open your [grafana config](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#config-file-locations) which is located in `/etc/grafana/grafana.ini` if you're using linux if you're using other operating system see link above.
2. In auth section of your configuration file append the template from below and fill it with corresponding values.

```
#################################### Auth Defguard ##########################
[auth.generic_oauth]
name = Defguard
icon = signin
enabled = true
client_id = <YOUR_APP_CLIENT_ID>  # from Defguard page
client_secret = <YOUR_APP_CLIENT_SECRET> # from Defguard page
scopes = openid profile email
empty_scopes = false
auth_url = https://<your_defguards_instance>/api/v1/oauth/authorize
token_url = https://<your_defguard_instance>/api/v1/oauth/token
api_url = https://<your_defguard_instance>/api/v1/oauth/userinfo
allow_sign_up = true
```

1. Restart your grafana server using `systemctl restart grafana-server`
2. Then on login, you'll see the `Sign-in Defguard button`


# Proxmox

{% hint style="warning" %}
For Proxmox OIDC to work you'll have to run Defguard with [RSA signing key](/1.4/deployment-strategies/docker-compose#openid-rsa-setup).
{% endhint %}

## Add Proxmox app to Defguard

First, go to the Defguard OpenID tab and click add new app button.

1. Add the name `Proxmox`
2. Add your proxmox address as redirect URL (e.g. `https://yourproxmox.com`)
3. Select scopes:

* OpenID
* Profile
* Email
* Phone

4. Submit the form.

After successfully adding your app you can see it in the OpenID apps list. When you click on it you will be redirected to the client details page. From this page copy Client ID and Client secret values for later.

## Proxmox configuration

1. Log into your proxmox instance.
2. Select `Datacenter`
3. Select `Permissions -> Realms`

![Proxmox Realm Settings](/files/NtMsUurXPUyyZhbiHHya)

4. Select `Add -> OpenID Connect Server`
5. Fill in the form:

* Issuer URL: Your Defguard instance URL (e.g. <https://defguard.mycompany.com>)
* Realm: Name for the realm, internal for Proxmox, (e.g. `Defguard`)
* Client ID: Client ID you copied after creating Defguard OpenID app
* Client Key: Client secret you copied after creating Defguard OpenID app
* Default: leave unchecked
* Comment: leave empty
* Autocreate users: check

{% hint style="warning" %}
Without `Autocreate users` option Proxmox won't be able to create new users, only log in existing ones.
{% endhint %}

* Username claim: subject
* Scopes: openid
* Prompt: Auth-Provider Default

![Proxmox OIDC Form](/files/cR5UwZ5eTKMVWa9W7J4u)

6. Save the form.

After logging out of Proxmox you should now be able to select your new realm and login with Defguard using OpenID Connect.


# Matrix / Synapse

{% hint style="warning" %}
For Synapse OIDC to work you'll have to run Defguard with [RSA signing key](/1.4/deployment-strategies/docker-compose#openid-rsa-setup).
{% endhint %}

## Add Synapse app to Defguard

First, go to the Defguard OpenID tab and click add new app button.

1. Add the name `Matrix`
2. Add your matrix address as redirect URL (e.g. `https://matrix.com/_synapse/client/oidc/callback`)
3. Select scopes:

* OpenID
* Profile
* Email
* Phone

4. Submit the form.

After successfully adding your app you can see it in the OpenID apps list. When you click on it you will be redirected to the client details page. From this page copy Client ID and Client secret values for later.

## Matrix configuration

1. Open your homeserver.yaml configuration file.
2. Paste below configuration with appropriate values

```yaml
# OpenID Connect provider settings
oidc_providers:
  - idp_id: Defguard
    idp_name: "Defguard"
    discover: false
    issuer: "https://yourdefguard.com/"
    client_id: "CLIENT_ID_FROM_DEFGUARD"  
    client_secret: "CLIENT_SECRET_FROM_DEFGUARD"  
    scopes: ["openid", "profile", "email", "phone"]
    authorization_endpoint: "https://yourdefguard.com/api/v1/oauth/authorize"
    token_endpoint: "https://yourdefguard.com/api/v1/oauth/token"
    userinfo_endpoint: "https://yourdefguard.com/api/v1/oauth/userinfo"
    jwks_uri: "https://yourdefguard.com/api/v1/oauth/discovery/keys"
    user_mapping_provider:
      config:
        localpart_template: "{{ user.email.split('@')[0] }}"
        display_name_template: "{{ user.first_name }} {{ user.last_name }}"
        email_template: "{{ user.email }}"
```

After logging out of your Matrix client of choice you should now be able to select your new realm and login with Defguard using OpenID Connect.


# Django

This article aims to show the basic integration of authenticating users through **Defguard** via **OpenID Connect**. So you can have a solid start to adjust it for your own use case.

## The Setup

### Domain

This guide assumes both **Defguard** and **Django** are running on **localhost**.

### Defguard

We will run Defguard instance on default port <mark style="color:blue;">8000</mark>.

{% hint style="info" %}
You can learn how to launch your Defguard instance in the following article: [Overview](/1.4/deployment-strategies/setting-up-your-instance)
{% endhint %}

#### Configuration

For our example to work on localhost we will need to change the following variables in Defguard:

| Variable                   | Value                   |
| -------------------------- | ----------------------- |
| DEFGUARD\_URL              | <http://localhost:8000> |
| DEFGUARD\_COOKIE\_DOMAIN   | localhost               |
| DEFGUARD\_COOKIE\_INSECURE | true                    |

{% hint style="danger" %}
Because we use **localhost** domain we need to set cookies to insecure, **DON'T** do this in a production environment.
{% endhint %}

Next, we need to configure the OpenID module to use RSA key instead of the default HMAC, this is due to Authlib being incompatible with HMAC.

Generate RSA key with the following command:

```bash
openssl genpkey -out rsakey.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048
```

Now we need to set **DEFGUARD\_OPENID\_KEY** variable to path pointing to that *<mark style="color:purple;">rsakey.pem</mark>* file.

When starting Defguard now you should be able to see the following info log:

```log
INFO defguard: Using RSA OpenID signing key
```

### Django

This section will explain how to setup a fresh Django example project.

We will use [poetry](https://python-poetry.org/) as a package manager but [pip](https://pip.pypa.io/en/stable/) will also work fine.

#### Project

Setup a new project with poetry, we will name it *django-project*.

```bash
poetry new django-project && cd ./django-project
```

Delete the generated ***django\_project*** directory, we don't need it.

```bash
rm -rd ./django_project/
```

#### Packages

Install the following Python packages:

* django
* django-jazzmin
* Authlib
* requests

```bash
poetry add django django-jazzmin Authlib requests
```

#### Django

Now we will make Django project and add **oauth** app.

```bash
poetry run django-admin startproject example .
```

```
poetry run ./manage.py startapp oauth
```

With this, we should have a directory structure close to this:

```
├── example
│   ├── asgi.py
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── oauth
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── poetry.lock
├── pyproject.toml
└── README.md
```

## Register OpenID App

We need to register our Django application as an OpenID client in Defguard.

To do that, navigate to OpenID panel and add new client as shown below.

<figure><img src="/files/uOsqExOxEcwB3Lz1n2Tr" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/WtRH7VLFx3HmMc11My1r" alt=""><figcaption></figcaption></figure>

Redirect URL should point to **<http://localhost:9000/oauth/redirect>**

Scopes should include at least **OpenID**, **Profile,** and **Email**.

## Authentication app setup

### Register app in Django

We will use the created **oauth** Django app to handle our authentication.

Register oauth app in ***settings.py*** file.

```python
INSTALLED_APPS = [
    # ...rest of your apps
    'oauth.apps.OauthConfig',
]
```

### Views

Modify *<mark style="color:purple;">oauth/views.py</mark> file.*

```python
from authlib.integrations.django_client import OAuth
from os import getenv

from django.contrib import auth
from django.contrib.auth.models import User
from django.shortcuts import redirect

oauth = OAuth()

defguard = oauth.register(
    name="defguard",
    client_id=getenv("DEFGUARD_CLIENT_ID"),
    client_secret=getenv("DEFGUARD_CLIENT_SECRET"),
    access_token_url=getenv("DEFGUARD_ACCESS_TOKEN_URL", "http://localhost:8000/api/v1/oauth/token"),
    access_token_params=None,
    authorize_url=getenv("DEFGUARD_AUTHORIZE_URL", "http://localhost:8000/api/v1/oauth/authorize"),
    api_base_url=getenv("DEFGUARD_API_BASE_URL", "http://localhost:8000/api/v1/oauth/userinfo"),
    client_kwargs={"scope": getenv("DEFGUARD_SCOPE", "openid email profile")},
    server_metadata_url=getenv("DEFGUARD_METADATA_URL", "http://localhost:8000/.well-known/openid-configuration"),
)

REDIRECT_URL = getenv("DEFGUARD_REDIRECT_URL")

def defguard_login(request):
    redirect_uri = request.build_absolute_uri(REDIRECT_URL)
    return oauth.defguard.authorize_redirect(request, redirect_uri)

def defguard_authorize(request):

    token = oauth.defguard.authorize_access_token(request)

    resp = oauth.defguard.get("userinfo", token=token)

    resp.raise_for_status()
    profile = resp.json()
    user = None
    user_exists = User.objects.filter(username=profile["sub"]).exists()
    if not user_exists:
        user = User(
            is_active=True,
            is_staff=True,
            is_superuser=True,
            username=profile["sub"],
            email=profile["email"],
            first_name=profile["given_name"],
            last_name=profile["family_name"],
        )
        user.save()
    else:
        user = User.objects.get(username=profile["sub"])
    auth.login(request, user)
    return redirect("/admin")
```

With the provided example, you will need to fill out only **DEFGUARD\_CLIENT\_ID** and **DEFGUARD\_CLIENT\_SECRET**.

Either provide them as environment variables or modify the views file and pass them as strings to oauth register function.

Both Client **ID** and **Secret** can be found on OpenID apps page in Defguard, **click** our Django app **row** on the list and you will be able to copy needed values from the opened modal.

<figure><img src="/files/3m4XX1q5Z0Yn6BXhPmVa" alt=""><figcaption></figcaption></figure>

### URLS

We will need to add our views to *<mark style="color:purple;">**oauth/urls.py**</mark>*.

```python
from django.urls import path
from oauth.views import defguard_authorize, defguard_login

urlpatterns = [
    path("defguard-login", defguard_login),
    path("redirect", defguard_authorize),
]
```

Modify *<mark style="color:purple;">**example/urls.py**</mark>* file, so it includes oauth app urls:

```python
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth.models import Group

admin.site.unregister(Group)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('oauth/', include('oauth.urls')),
]

```

## Custom admin login template

With use of [Jazzmin](https://django-jazzmin.readthedocs.io/) admin theme we will modify login template and add an additional button to login with Defguard.

### Register Jazzmin app

Modify *<mark style="color:purple;">**example/settings.py**</mark>*

```python
INSTALLED_APPS = [
    'jazzmin',
    'django.contrib.admin',
    # rest of the apps
]

# rest of config

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / "templates"],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```

{% hint style="warning" %}
jazzmin app **needs** to be registered **before** django.contrib.admin
{% endhint %}

### Add template file

Make *<mark style="color:purple;">**templates/admin/auth/login.html**</mark>* file:

```django
{% extends "registration/base.html" %}

{% load i18n jazzmin %}
{% get_jazzmin_settings request as jazzmin_settings %}
{% get_jazzmin_ui_tweaks as jazzmin_ui %}

{% block content %}
    <p class="login-box-msg">{{ jazzmin_settings.welcome_sign }}</p>
    <form action="{{ app_path }}" method="post">
        {% csrf_token %}
        {% if user.is_authenticated %}
            <p class="errornote">
                <div class="callout callout-danger">
                    <p>
                        {% blocktrans trimmed %}
                            You are authenticated as {{ username }}, but are not authorized to
                            access this page. Would you like to login to a different account?
                        {% endblocktrans %}
                    </p>
                </div>
            </p>
        {% endif %}
        {% if form.errors %}
            {% if form.username.errors %}
                <div class="callout callout-danger">
                    <p>{{ form.username.label }}: {{ form.username.errors|join:', ' }}</p>
                </div>
            {% endif %}
            {% if form.password.errors %}
                <div class="callout callout-danger">
                    <p>{{ form.password.label }}: {{ form.password.errors|join:', ' }}</p>
                </div>
            {% endif %}
            {% if form.non_field_errors %}
                <div class="callout callout-danger">
                    {% for error in form.non_field_errors %}
                        <p>{{ error }}</p>
                    {% endfor %}
                </div>
            {% endif %}
        {% endif %}
        <div class="input-group mb-3">
            <input type="text" name="username" class="form-control" placeholder="{{ form.username.label }}" required>
            <div class="input-group-append">
                <div class="input-group-text">
                    <span class="fas fa-user"></span>
                </div>
            </div>
        </div>
        <div class="input-group mb-3">
            <input type="password" name="password" class="form-control" placeholder="{{ form.password.label }}" required>
            <div class="input-group-append">
                <div class="input-group-text">
                    <span class="fas fa-lock"></span>
                </div>
            </div>
        </div>
        {% url 'admin_password_reset' as password_reset_url %}
        {% if password_reset_url %}
            <div class="mb-3">
                <div class="password-reset-link" style="text-align: center;">
                    <a href="{{ password_reset_url }}">
                        {% trans 'Forgotten your password or username?' %}
                    </a>
                </div>
            </div>
        {% endif %}
        <div class="row">
            <div class="col-12">
                <button type="submit" class="btn {{ jazzmin_ui.button_classes.primary }} btn-block">
                    {% trans "Log in" %}
                </button>
            </div>
        </div>
    </form>
    <div class="row" style="padding-top: 8px">
        <div class="col-12">
            <button class="btn {{ jazzmin_ui.button_classes.secondary }} btn-block"
                    onclick="window.location.href = '/oauth/defguard-login'">
              Login with Defguard
            </button>
        </div>
    </div>
{% endblock %}


```

### Register login route

Modify *<mark style="color:purple;">**example/urls.py**</mark>*

```python
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth.models import User, Group
from django.contrib.auth.views import LoginView

admin.site.unregister(Group)

urlpatterns = [
    path('admin/login/', LoginView.as_view(template_name="admin/auth/login.html"), name="admin_login"),
    path('admin/', admin.site.urls),
    path('oauth/', include('oauth.urls')),
]

```

## Conclusion

Now we need to start our Django server.

{% hint style="warning" %}
If you started a fresh project don't forget to make migrations!

**`poetry run ./manage.py migrate`**
{% endhint %}

```bash
poetry run ./manage.py runserver 0.0.0.0:9000
```

After accessing *<http://localhost:9000/admin> we should see our custom login page*

Button "*Login with Defguard*" should redirect us to our Defguard instance. Depending on if Defguard session is active or not we should be able to see app authorization page or login page.

<figure><img src="/files/7k38tyC8bGeE2YEVL2Tm" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/TdcAvSjI0JoBl5fZtMuU" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/bdYVk87J7tWJIUg6fIWm" alt=""><figcaption></figcaption></figure>

When we authorize Django App to our Defguard account we are redirected back to our Django admin and logged in with a user from Defguard.


# MinIO

MinIO has OpenID Connect functionality out of the box. We will use it to authenticate users from Defguard to MinIO.

## RSA Setup

MinIO, like Django, requires Defguard to use RSA key instead of our default HMAC. This is due to the different response schema that MinIO expects.

Generate RSA key file if you don't have one :

```bash
openssl genpkey -out rsakey.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048
```

Now we need to set **DEFGUARD\_OPENID\_KEY** variable to path pointing to that *<mark style="color:purple;">rsakey.pem</mark>* file.

When starting Defguard now you should be able to see the following info log:

```log
INFO defguard: Using RSA OpenID signing key
```

## Add MinIO OpenID Client

Navigate to the OpenID page in Defguard and add MinIO to the client's list. Redirect URL need to point to your MinIO console root domain and path should be /oauth\_callback like:

```
http://localhost:9001/oauth_callback
```

<figure><img src="/files/SRFic7gTWwHjphszEtgn" alt=""><figcaption></figcaption></figure>

## MinIO Configuration

In this example, we will use the environment variables.

Reference MinIO docs for more detailed explanation: <https://min.io/docs/minio/linux/reference/minio-server/minio-server.html#environment-variables>

The table below assumes MinIO console exists on minio.example and Defguard exists on defguard.example

| Variable                                | Example Value                                              | Description                                                                                                                                                                                                            |
| --------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MINIO\_IDENTITY\_OPENID\_CLIENT\_ID     | client\_id\_from\_defguard                                 | Click on Minio app row in OpenID page, copy from opened modal                                                                                                                                                          |
| MINIO\_IDENTITY\_OPENID\_CLIENT\_SECRET | client\_secret\_from\_defguard                             | Click on Minio app row in OpenID page, copy from opened modal                                                                                                                                                          |
| MINIO\_IDENTITY\_OPENID\_CONFIG\_URL    | <http://defguard.example/.well-known/openid-configuration> |                                                                                                                                                                                                                        |
| MINIO\_IDENTITY\_OPENID\_DISPLAY\_NAME  | Defguard                                                   | This will be displayed in minio login page.                                                                                                                                                                            |
| MINIO\_IDENTITY\_OPENID\_SCOPES         | openid,email,profile                                       | Scopes that Minio will ask access to                                                                                                                                                                                   |
| MINIO\_BROWSER\_REDIRECT\_URL           | <http://minio.example>                                     | This should point to valid minio console domain. Check docs for more info.                                                                                                                                             |
| MINIO\_IDENTITY\_OPENID\_ROLE\_POLICY   | consoleAdmin                                               | MinIO policy that will be granted to all users authneticated via OpenID Connect. This can be custom policy set by you or one of default ones like in this example every Defguard user will be regared as consoleAdmin. |


# Vault

## Example setup

This configuration is an example, which shows how you can connect OpenID Connect with Hashicorp Vault.

Create `vault.json` with the following content:

```json
{
   "backend":{
      "file":{
         "path":"/vault/file"
      }
   },
   "listener":{
      "tcp":{
         "address":"0.0.0.0:8200",
         "tls_disable":1
      }
   },
   "default_lease_ttl":"168h",
   "max_lease_ttl":"168h",
   "ui":true,
   "log_level":"Debug"
}
```

Create `docker-compose.yaml` with the following content:

```yaml
services:
  vault:
    image: vault:latest
    container_name: vault
    environment:
      VAULT_ADDR: http://127.0.0.1:8200
    ports:
      - "8200:8200"
    volumes:
      - ./volumes/vault:/vault/file:rw
      - ./vault.json:/vault/config/vault.json:rw
    cap_add:
      - IPC_LOCK
    entrypoint: vault server -config=/vault/config/vault.json -dev
```

Run it using `docker-compose up` command.

Create root token using `docker exec -it vault vault operator init -n 1 -t 1`, write down the root token and unseal key.

## Defguard configuration

1. Go to **OpenID Apps** and click **Add new** button.
2. Use Scopes: `openid email profile`
3. Use `http://127.0.0.1:8200/ui/vault/auth/oidc/oidc/callback` as **Redirect URI**
4. Copy and save **Client ID** and **Client secret**, we will need them later.

## Vault configuration

1. Unseal vault by accessing `http://127.0.0.1:8200/ui` and using unseal key.
2. Login into Vault using method `TOKEN` and using root token.
3. Navigate to **Access -> Auth Methods** and click **Enable new method** button.
4. Enable **OIDC** method.
5. Use values below: `OIDC discovery URL: https://defguard.company.net/` `OIDC client ID: <YOUR_CLIENT_ID>` `OIDC secret ID: <YOUR_CLIENT_SECRET>`

## Creating role in vault

1. Login into vault CLI using root token: `docker exec -it vault vault login <ROOT_TOKEN>`
2. To create role `reader` use command below:

```bash
docker exec -it vault vault write auth/oidc/role/reader \
    bound_audiences="<YOUR_CLIENT_ID>" \
    allowed_redirect_uris="http://127.0.0.1:8200/ui/vault/auth/oidc/oidc/callback" \
    user_claim="sub" \
    token_policies="default"
```

Now you can login into vault using Defguard. Use `OIDC` as login method and role `reader`. Please note this role will only allow you to login, to add permissions you need to create policy and assign it to role.


# External SSO/OpenID providers

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

Defguard, [apart from being an identity provider itself](/1.4/features/openid-connect), supports logging in through external OpenID providers. All providers that support standard and common **code authorization flow should work.**

Here are dedicated tutorials for most common SSO providers:

* [Google](/1.4/features/external-openid-providers/google)
* [Microsoft](/1.4/features/external-openid-providers/microsoft)
* [Zitadel](/1.4/features/external-openid-providers/zitadel)
* [Keycloak](/1.4/features/external-openid-providers/keycloak)
* [Okta](/1.4/features/external-openid-providers/okta)
* [JumpCloud](/1.4/features/external-openid-providers/jumpcloud)
* Tested by our users and confirmed: Authentik, Authelia.

## Prerequisites

In order to configure this feature, the following information is needed to be obtained from a provider of choice:

* Client ID
* Client secret
* (for custom provider) Your provider's base URL
* (for Microsoft as provider) Tenant ID

If you don't know where to find those values, go to the [Examples](#examples) section, where you will find an example setup for the built-in providers.

### Base URL

The base URL is used to discover all the necessary provider's endpoints which will be used during the authorization flow. Usually, all required information resides at `<PROVIDER_BASE_URL>/.well-known/openid-configuration`. Hence, in order for Defguard to discover the endpoints, you need to provide it with only the base URL value, and the rest (the *well-known* part) is appended automatically. The base URL should be provided without the trailing slash, some examples:

* `https://accounts.google.com`
* `https:://login.microsoftonline.com/<TENANT_ID>/v2.0`
* `http://<KEYCLOAK_ADDRESS>/realms/<REALM>` (in the case of Keycloak)

### Tenant ID

This is an optional value, required only if you are using Microsoft as your provider. Insert it in the `BASE_URL` field by replacing the `<TENANT_ID>` placeholder.

### Redirect URI

In almost any provider's configuration, you will need to define a set of allowed redirect URIs. Those URIs are the URIs to which the user will be redirected after completing the login on the provider's site. In our case, the user should be redirected back to Defguard, hence, those URIs depend on your Defguard domains and have the following form:

* `<DEFGUARD_DASHBOARD_URL>/auth/callback`
* `<DEFGUARD_ENROLLMENT_URL>/openid/callback`
* `<DEFGUARD_ENROLLMENT_URL>/openid/mfa/callback`

For example, if your Defguard main dashboard is accessible at `https://defguard.my-domain.net` and your users perform the enrollment through a proxy accessible at `https://enrollment.my-domain.net` you would need to enter the following URIs:

* `https://defguard.my-domain.net/auth/callback`
* `https://enrollment.my-domain.net/openid/callback`
* `https://enrollment.my-domain.net/openid/mfa/callback`

These URIs will need to be provided in your provider's configuration. See [#examples](#examples "mention") to learn more.

## Configuration and setup

In order to configure the external OpenID provider login, go to the settings in the Defguard admin dashboard.

<figure><img src="/files/6rjqNYIHTIXlPXyTGgwQ" alt=""><figcaption></figcaption></figure>

Everything related to the external OpenID configuration can be found in the OpenID tab of the settings page. The first thing to do here would be to pick your provider using the dropdown menu under the "Provider" label. Next, fill out the required information with values acquired from your provider. If you picked "Microsoft" or "Custom", make sure to also make corresponding changes in the "Base URL" field. After you are done, click "Save changes" to keep your changes.

You may have also noticed the checkbox option on the right. By default, when a new user (i.e. a user of whom Defguard has no record) logs in for the first time using the external OpenID feature, its account is created automatically, based on the personal details (first name, last name, email) received from the external provider. If you'd like to manually manage such users, uncheck the checkbox. Now, users will need to be manually created in Defguard first in order to log in through the external provider.

### OpenID enrollment

When you configure your provider, the proxy will automatically allow enrolling users through it. See [With external SSO (Google/Microsoft/Custom)](/1.4/using-defguard-for-end-users/enrollment/with-external-sso-google-microsoft-custom) for the process from the user's point of view.

For this to work, make sure you have the following two things set:

* Additional allowed redirect URI in your provider's configuration (see [#redirect-url](#redirect-url "mention"))
* A `DEFGUARD_PROXY_URL` environment variable set correctly for your proxy (not core). This variable needs to be set for your proxy and should be equal to the URL where users perform the enrollment process. This should be set automatically if you are using the one-line deployment script version `1.2.1` or above. E.g. if your enrollment URL is `https://enrollment.my-domain.net`, set `DEFGUARD_PROXY_URL` to `https://enrollment.my-domain.net`.

#### Disabling automatic account creation

<figure><img src="/files/VQ0SK7jLyUdvkPSEsV1C" alt=""><figcaption></figcaption></figure>

If you disable the option above, new users won't be able to automatically go through the enrollment. You will need to create their accounts by hand (with the same email address as the one they have set on your OIDC provider's side) and only then they will have an option to activate it by logging through the provider.

### Directory synchronization

{% hint style="info" %}
This feature is available only in Defguard v1.2.0 and above
{% endhint %}

Defguard supports synchronizing users' and groups' states based on the state of the external provider directory. The following things can be synchronized:

* **User Groups**: Automatically create and assign user groups in Defguard to reflect them in Google Workspace.
* **User Deletion**: Removing a user from the provider's directory can also remove them from Defguard.
* **User Status**: Disabling users in the provider's directory will disable them in Defguard.

Defguard doesn't automatically create users based on the users in your provider's directory. They will have to manually log in to Defguard through your provider for their Defguard accounts to be created. Defguard is responsible only for synchronizing their later state.

#### General configuration

The menu can be found in Defguard settings by navigating to the "OpenID" tab.

<figure><img src="/files/xB5q1wuWF4d5XGwjv6H6" alt=""><figcaption></figcaption></figure>

The following configuration options are currently available in the directory synchronization menu for all providers:

* **Synchronize (All/User/Group):** What to synchronize.
  * **All** - synchronize both user state (disabled/enabled), their deletion, and groups
  * **User** - synchronize only user state (disabled/enabled) and whether they've been deleted
  * **Group** - synchronize only user groups
* **Synchronization interval (600s by default):** How often to synchronize with your provider. Very low values may cause issues with the provider API. The user state is also synchronized on login.

{% hint style="danger" %}
If you want to delete your users based on the state of your provider we recommend trying out the "disable" behavior first to make sure everything works as expected. Always back up your database regularly.
{% endhint %}

* **User behaviour (Keep, Disable, Delete):** What to do with Defguard users who are absent from your provider's directory.
* **Admin behaviour (Keep, Disable, Delete):** What to do with Defguard users with admin status (in Defguard) who are absent from your provider's directory.

#### Currently supported providers

* [Google](/1.4/features/external-openid-providers/google#directory-synchronization)
* Microsoft

## Known issues

### JumpCloud

When setting up JumpCloud you can encounter an error when attempting to log in with a message `Failed to parse payload JSON: Error(\\\"invalid type: string...`. This is because JumpCloud is returning a token that doesn't conform fully to the OpenID standard. You can try working around this issue by removing the `email_verified` field in your SSO application configuration in JumpCloud. In order to do this, edit your SSO Application and **deselect** the email scope:

<figure><img src="/files/wQfBPD1YChy2Bie28yl4" alt=""><figcaption></figcaption></figure>

Then, add the email below by hand:

<figure><img src="/files/SBC1jInvLeCC8Fgqd6sg" alt=""><figcaption></figcaption></figure>

Double check that the `email_verified` field is gone from the constant attributes section. The issue should be gone now.


# Google

{% hint style="info" %}
Here is [full Google documentation](https://developers.google.com/identity/openid-connect/openid-connect) about this process.
{% endhint %}

1. The Google OpenID Connect can be configured in the [Google Cloud Console](https://console.cloud.google.com)
2. If you don't have any project setup already (or you want to create a new one for this purpose), create it by clicking the dropdown menu here:

   <figure><img src="/files/AhahxK4yrwpJFe8rVUIe" alt="" width="312"><figcaption></figcaption></figure>

   If you already have project, make sure to select it in the above dropdown menu.
3. Now, navigate to [`APIs & Services`](https://console.cloud.google.com/apis)
4. We will focus on the consent screen first, select `OAuth consent screen`
5. Pick the User Type according to your needs, this example will focus on the internal type

   <figure><img src="/files/3PThkTn9XWWfj12Gbkfx" alt=""><figcaption></figcaption></figure>
6. Fill in all required details. Make sure to fill the correct domain. This should be the top domain under which your Defguard dashboard can be accessed, not the subdomain (e.g. `defguard.example.com` -> `example.com`).
7. On the scopes config screen, click `ADD OR REMOVE SCOPES`, Defguard requires at least the following scopes:

   <figure><img src="/files/FMhzPTSlc6NPo2X6HDOy" alt=""><figcaption></figcaption></figure>
8. Proceed until the end and return to the OAuth consent screen dashboard.
9. Now, go to [`Credentials`](https://console.cloud.google.com/apis/credentials), click `CREATE CREDENTIALS` and choose `OAuth client ID`

   <figure><img src="/files/8hRtZKN1sycw4PbgmpNW" alt=""><figcaption></figcaption></figure>
10. On the next screen, fill out all required information:

    <figure><img src="/files/JKNS1Wo6vjD4bo0XNgEH" alt=""><figcaption></figcaption></figure>

    Make sure to select "Web application" as the application type. The other thing to note here is the redirect URI. It is the URI to which the user will be redirected from the external provider's authorization. This URI is in the form of `<DEFGUARD_DASHBOARD_URL>/auth/callback`. Replace `<DEFGUARD_DASHBOARD_URL>` with the URL under which your dashboard is accessible, e.g. `https://defguard.example.com`. If you'd like to use OpenID enrollment through proxy, make sure to enter an additional URI here in the form of `<DEFGUARD_ENROLLMENT_URL>/openid/callback`.
11. After you proceed further, you will be presented with a popup containing your `Client ID` and `Client Secret`, copy them and paste on the Defguard OpenID configuration page.

    <figure><img src="/files/xKM83oQW5NknsbArNdaV" alt=""><figcaption></figcaption></figure>

### Directory synchronization

{% hint style="warning" %}
This feature is currently technically limited to 10000 members or groups. High user or group counts may still trigger your provider API limits even below this threshold. If you have many users (200+), we recommend you test this feature first before you decide to turn on automatic user deletion.
{% endhint %}

{% hint style="info" %}
This feature is available only in Defguard v1.2.0 and above
{% endhint %}

This documentation concerns only the Google directory synchronization. For more general information, see the [general directory synchronization guide](/1.4/features/external-openid-providers#directory-synchronization).

#### Directory synchronization configuration menu

The menu can be found in Defguard settings by navigating to the "OpenID" tab.

<figure><img src="/files/0oQ9ne50IAHGnI88NLjg" alt=""><figcaption></figcaption></figure>

The following configuration options are currently available in the directory synchronization menu specifically for the Google provider:

* **Admin email:** The email of the Google Workspace admin user on whose behalf Defguard will call the Google API
* **Service account in use:** The email of the Google service account that is currently used

To learn more about the rest of the configuration options, see the [general directory synchronization guide](/1.4/features/external-openid-providers#directory-synchronization).

#### Directory synchronization setup

1. Navigate to [Service Accounts](https://console.cloud.google.com/iam-admin/serviceaccounts) in the Google Cloud console<br>

   <figure><img src="/files/x7NnPePsSViVBoWR5hxS" alt=""><figcaption></figcaption></figure>

2. Click "Create service account"

3. Give your service account a descriptive name<br>

   <figure><img src="/files/9tTKJQwNhUE1roflJLXk" alt=""><figcaption></figcaption></figure>

4. Skip step 2 and 3 if you are not sure what to configure there.

5. Go to your newly created service account and add a new key in the "KEYS" tab.<br>

   <figure><img src="/files/cZTamc2eBM17LPUasjoN" alt=""><figcaption></figcaption></figure>

6. A JSON file will be downloaded after you click "CREATE". Store it securely as it may grant access to your Google Workspace directory.

7. Next, navigate to the "DETAILS" tab and copy the unique ID of your service account.

8. Open the Advanced settings and under Domain-wide delegation click "View google workspace admin console"

9. Now in the admin console, navigate to [API controls](https://admin.google.com/u/1/ac/owl)<br>

   <figure><img src="/files/1nDVVyJqMR6Ld2BkTbE3" alt=""><figcaption></figcaption></figure>

10. In the API controls, click "Manage domain wide delegation"

11. On the next screen, add a new API client<br>

    <figure><img src="/files/UaxsIqqfHsFpHelhZEgH" alt=""><figcaption></figcaption></figure>

    Specify the following scopes for your client:\
    `openid, email, profile, https://www.googleapis.com/auth/admin.directory.customer.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly, https://www.googleapis.com/auth/admin.directory.user.readonly`

12. Navigate to the Defguard settings and upload the JSON file you obtained previously. Make sure to also input the email of the account on which behalf the API calls will be made. This account should have access to users and their groups (e.g. email of your account as an admin).

13. Test if you properly set everything up by clicking the "Test connection" button.


# Microsoft

1. Go to [https://portal.azure.com/](https://portal.azure.com)
2. Navigate to Microsoft Entra ID
3. In the Microsoft Entra ID, click Manage and select App registrations from the menu on the left.

   <figure><img src="/files/UkcIGM4uCHWXZsZMOSkr" alt=""><figcaption></figcaption></figure>
4. Click "Make new registration"
5. Fill out the form, like in the example:

   <figure><img src="/files/AEI5kG4vMjFohMd9I9RQ" alt=""><figcaption></figcaption></figure>

Make sure the Redirect URL you insert here is correct. Replace `defguard.example.com` with the domain you use for your Defguard dashboard. If you'd like to use OpenID enrollment through proxy, make sure to enter an additional URI here in the form of `<DEFGUARD_ENROLLMENT_URL>/openid/callback`.

6. You should be now on the registered application's management screen. You can copy the client's ID and the tenant ID from here, as you need to provide them on the Defguard settings' page.

   <figure><img src="/files/263Fp2omSohIubuvV6q2" alt=""><figcaption></figcaption></figure>
7. Go to Defguard settings, click the OpenID tab and paste the copied client ID. The tenant ID should be inserted instead of the `<TENANT_ID>` placeholder in the base URL field.
8. Now back in Microsoft Entra ID, still in your newly created application, go to **Certificates & Secrets**

   <figure><img src="/files/SL84PrfFumQOTi9yzBVo" alt=""><figcaption></figcaption></figure>
9. Click Client secrets and create a new client secret. Copy its **value** and paste it in your Defguard OpenID settings.
10. Go to Token configuration (in the menu on the left) and add a new optional token claim.
11. Make sure to select the ID token type and the following claims:

    <figure><img src="/files/Srua6oTjqgAfP0TGBA1g" alt=""><figcaption></figcaption></figure>
12. Accept the popup or configure the API permissions manually.

<figure><img src="/files/L5EIqsAEDsRB0MLH5tfz" alt=""><figcaption></figcaption></figure>

13. Now you should be good to go. A new login button should appear on the login screen.

### Directory synchronization

{% hint style="info" %}
This feature is available only in Defguard 1.2.1 and above
{% endhint %}

{% hint style="warning" %}
This feature is currently technically limited to 10000 members or groups. High user or group counts may still trigger your provider API limits even below this threshold. If you have many users (200+), we recommend you test this feature first before you decide to turn on automatic user deletion.
{% endhint %}

Defguard supports synchronizing groups' and users' states based on your Microsoft directory.

Make sure to check the [general guide to directory synchronization](/1.4/features/external-openid-providers#directory-synchronization) to learn more about the available configuration options.

#### Setup

1. Go back to your app registrations in Microsoft Entra ID and select the app you registered during the provider setup.

2. Navigate to API permissions<br>

   <figure><img src="/files/Udo2VebMe3vNGfGOpnJO" alt=""><figcaption></figcaption></figure>

3. Click "Add a permission", then select "Microsoft Graph"<br>

   <figure><img src="/files/Spg6f8U8JlshvbTeh83W" alt=""><figcaption></figcaption></figure>

4. Select "Application permissions", as Defguard will perform the synchronization in the background.<br>

   <figure><img src="/files/zPNWWo6AiPfWMl12VAtz" alt=""><figcaption></figcaption></figure>

5. Assign the following permissions:
   * `GroupMember.Read.All`
   * `Group.Read.All`
   * `User.Read.All`

6. Now grant admin consent for the permissions using the "Grant admin consent for" button<br>

   <figure><img src="/files/JUdZY5BzeQEgvtTigtqd" alt=""><figcaption></figcaption></figure>

7. You should be good to go now. Navigate to the directory sync settings in Defguard and try to test your setup using the test connection button.


# Okta

1. First, navigate in your Okta dashboard to "Applications" and create a new app integration here:

<figure><img src="/files/FykeJhaC8aDlksi38BRb" alt=""><figcaption></figcaption></figure>

2. Next, select following options like so:

<figure><img src="/files/vU3Q8P6MlfqGbYxj97MB" alt=""><figcaption></figcaption></figure>

3. On the next page, configure the application. Make sure to set the correct Sign-in URIs, those will take the form of `<DEFGUARD_DASHBOARD_URL>/auth/callback` (dashboard login) and `<DEFGUARD_ENROLLMENT_URL>/openid/callback` (if you want to perform new user enrollment using Okta). Replace `<DEFGUARD_DASHBOARD_URL>` and `<DEFGUARD_ENROLLMENT_URL>` with the URLs of your Defguard dashboard and enrollment page (proxy) accordingly. If you access your Defguard dashboard at e.g. `https://defguard.example.net` your redirect URI will be `https://defguard.example.net/auth/callback`. If you want to use Okta as the MFA provider, also add `<DEFGUARD_ENROLLMENT_URL>/openid/mfa/callback` to the redirect URIs.

<figure><img src="/files/YRJIRq0VnS6wEoos64F7" alt=""><figcaption></figcaption></figure>

4. Next, select the assignment according to your needs, we will select the option that allows every directory member to login:

<figure><img src="/files/iULkQIYVjvm3XVZndoHP" alt=""><figcaption></figcaption></figure>

5. Now, copy your client ID and secret, as you will need to paste it in your Defguard's settings.

<figure><img src="/files/7BgEAk9sTHyvL9AZWmX9" alt=""><figcaption></figcaption></figure>

6. Go to your Defguard settings, and fill all the required information, pasting the Client ID and Client secret from Okta:

<figure><img src="/files/ceIjMUP3slQpukrWF77k" alt=""><figcaption></figcaption></figure>

The base URL will be based on your Okta domain. In the case of this example, the `-admin` part of the URL had to be additionally removed. To additionally verify if your Base URL is correct, you can navigate to `<YOUR_OKTA_DOMAIN>/.well-known/openid-configuration`. The issuer field here should be the same as the Base URL.

### Directory synchronization

{% hint style="info" %}
This feature is available only in Defguard v1.2.3 and above
{% endhint %}

This documentation concerns only the Okta directory synchronization. For more general information, see the [general directory synchronization guide](/1.4/features/external-openid-providers#directory-synchronization).

#### Directory synchronization configuration menu

The menu can be found in Defguard settings by navigating to the "OpenID" tab.

<figure><img src="/files/HBLGOq5SzBNHJytKPlvt" alt=""><figcaption></figcaption></figure>

The following configuration options are currently available in the directory synchronization menu specifically for the Okta provider:

* **Directory Sync Client ID:** The client ID of the Okta directory synchronization app
* **Directory Sync Client Private Key:** The private key of the Okta directory synchronization app

To learn more about the rest of the configuration options, see the [general directory synchronization guide](/1.4/features/external-openid-providers#directory-synchronization).

#### Directory synchronization setup

{% hint style="warning" %}
This feature is currently technically limited to 10000 members or groups. High user or group counts may still trigger your provider API limits even below this threshold. If you have many users (200+), we recommend you test this feature first before you decide to turn on automatic user deletion.
{% endhint %}

1. Go to the Okta admin dashboard and navigate to the Applications menu\\

   <figure><img src="/files/lrtbk9jN1SaXSeGM0neT" alt=""><figcaption></figcaption></figure>
2. Make a completely new app integration by clicking "Create App Integration". This app will be solely responsible for communicating with Okta API.
3. Select "API services"\\

   <figure><img src="/files/pKSye8OF61l9bCXZsexr" alt=""><figcaption></figcaption></figure>
4. Name your app integration, e.g. "Defguard directory sync"
5. Go to your newly created app integration settings and change the client authentication to "Public key / Private key"\\

   <figure><img src="/files/uiObxjyNx9yN95D72vMD" alt=""><figcaption></figcaption></figure>
6. Next, click "Add key" and generate a new key pair.
7. Copy the generated private key in the JSON format to your clipboard
8. Paste the copied key in the Defguard Okta directory sync settings in the "Directory Sync Private Key" field.
9. Go back to Okta again. Save your new Okta configuration along with the newly generated keys. Now, copy the app integration's client ID. Paste it in the "Directory Sync Client ID" field in Defguard Okta directory sync settings. Save your Defguard settings.
10. Return to Okta and under "General settings" turn off the "Require Demonstrating Proof of Possession (DPoP) header in token requests" option. Save your changes.\\

    <figure><img src="/files/sXcoZAPXIEjC1qUGCAmT" alt=""><figcaption></figcaption></figure>
11. Now, navigate to the Okta API scopes tab.\\

    <figure><img src="/files/2LcAzmlVRqynX7Fcflkv" alt=""><figcaption></figcaption></figure>
12. Grant the `okta.groups.read` and `okta.users.read` scopes.
13. Everything should be set now. Try testing your provider connection in Defguard directory synchronization settings.


# JumpCloud

1. Login to your JumpCloud admin account.
2. Navigate to SSO Applications\\

   <figure><img src="/files/eCp9HFr0O1oXxkYTy9yq" alt=""><figcaption></figcaption></figure>
3. Add a new SSO Application
4. Select "Custom" on this screen.

   <figure><img src="/files/L5kgm495VmxWwN7LhWvJ" alt=""><figcaption></figcaption></figure>
5. Select "Configure SSO with OIDC".

   <figure><img src="/files/YhhUoFI4XZlEIVTAiozz" alt=""><figcaption></figcaption></figure>
6. Fill the app's display label in the next form.\\

   <figure><img src="/files/LypqNUT2YUwYx8eCqJQV" alt=""><figcaption></figcaption></figure>
7. After finishing this configuration, you will be redirected to your newly created SSO Application's settings. Go to the "SSO" tab first.

   <figure><img src="/files/wBUbJ3bNIGVKbz8QKcxf" alt=""><figcaption></figcaption></figure>
8. Configure as following:

   <figure><img src="/files/cjrVYl7zeJ7XzmDKNl3E" alt=""><figcaption></figcaption></figure>

   Make sure to set the correct Redirect URI and Login URL that will reflect your Defguard's setup. If you access your Defguard dashboard at e.g. `https://defguard.example.net` your redirect URI will be `https://defguard.example.net/auth/callback` and the login URL `https://defguard.example.net/auth/login`. Additionally, if you are using a Defguard proxy to enrol users, you can also add another redirect URI in the form of `<DEFGUARD_ENROLLMENT_URL>/openid/callback`, where the `<DEFGUARD_ENROLLMENT_URL>` is the address at which your proxy enrollment page is accessible.
9. Next, select the profile scope and add an `email` user attribute mapping by hand, like so:

   <figure><img src="/files/z3xFHkxgABI8kG6K6CXK" alt=""><figcaption></figcaption></figure>

   It's important **not** to select the email standard scope checkbox, as it will automatically add a constant `email_verified` field which doesn't conform to the OpenID standard and doesn't work with Defguard. You can see the following section for more information: [External SSO/OpenID providers](/1.4/features/external-openid-providers#jumpcloud).
10. Click "Activate". You will be presented with a client ID and a secret. Copy both of them, as you will need to insert them in Defguard's settings.
11. Go to Defguard settings, OpenID tab, select a `Custom` provider tab and paste the copied values:

    <figure><img src="/files/arTN1gyyONh0YhXS5T0a" alt=""><figcaption></figcaption></figure>

    Set the base URL to `https://oauth.id.jumpcloud.com/`. The display name may be whatever you want.
12. Back in JumpCloud, make sure your users have access to the SSO Application. You can enable it by navigating to the `User groups` menu and selecting the group you want to enable logging in through JumpCloud for. Only users from this group will be able to log in to Defguard with JumpCloud. In this example, we will select the `All users` group, which is a dynamic group containing every user.
13. Now in the group settings menu, select the `Applications` tab and select the checkbox next to your newly created app, this will enable the app for that group. Click `Save group` when you finish.

    <figure><img src="/files/rQ01mxqY7iYQTyoSL4hV" alt=""><figcaption></figcaption></figure>
14. Now you should be able to log in to Defguard with JumpCloud.


# Keycloak

A basic guide about securing applications using Keycloack can be found [here](https://www.keycloak.org/getting-started/getting-started-docker#_secure_the_first_application).


# Zitadel

{% hint style="info" %}
Refer to [Zitadel's documentation](https://zitadel.com/docs) on how to install it.
{% endhint %}

1. Log in to Zitadel's web interface.
2. Create a project.
3. Add a new application within the project.
4. Select **Web** for application type.

   <figure><img src="/files/J4Nqobx08Hi9aEwDI0CO" alt=""><figcaption></figcaption></figure>
5. Choose **Code** for authorization method.

   <figure><img src="/files/ltoxFF1bNnPdaCy9mf3J" alt=""><figcaption></figcaption></figure>
6. Enter a redirect URI for your Defguard instance. The URI is in the form `<DEFGUARD_DASHBOARD_URL>/auth/callback`, for example `https://defguard.example.com/auth/callback`. (If Defguard has been launched on the *localhost*, select **Development Mode** and enter `http://localhost:8000/auth/callback`). If you'd like to use OpenID enrollment through proxy, make sure to enter an additional URI here in the form of `<DEFGUARD_ENROLLMENT_URL>/openid/callback`.

   <figure><img src="/files/yIsOvE8Iiqd5oDO4D0RM" alt=""><figcaption></figcaption></figure>
7. **Create** the application.
8. Copy the provided **Client ID** and **Client Secret** and enter these in the Defguard's OpenID settings.
9. Finally, in the **Token Settings**, enable **User Info inside ID Token**.

   <figure><img src="/files/LFiP9qWGDAdhSPgkaFvt" alt=""><figcaption></figcaption></figure>


# Custom

{% hint style="warning" %}
Defguard supports custom providers that allow a **code** response type in the OpenID authorization flow.
{% endhint %}

You can also configure a custom OpenID provider. The key thing here is setting up the **Base URL** correctly. This URL is used to discover all the endpoints required for the authorization flow.

The easiest way of obtaining the Base URL is to find out what is the OpenID `.well-known` URL of your provider. For example, for Google it's `https://accounts.google.com/.well-known/openid-configuration`, in this case, the Base URL would be `https://accounts.google.com` (note the lack of a trailing slash). The part starting with `/.well-known` is added automatically, so it should be omitted from the Base URL. This is explained in more detail in the [Base URL](#base-url) section.

In order to get the **Client ID** and **Client Secret** values, refer to the documentation of your custom provider of choice.

When configuring your external OpenID provider, at some point you will need to provide a callback URL, which will redirect the user back to Defguard. This URL is in form of `<DEFGUARD_DASHBOARD_URL>/auth/callback`. Replace `<DEFGUARD_DASHBOARD_URL>` with the URL under which your dashboard is accessible, e.g. `https://defguard.example.com`. If you'd like to use OpenID enrollment through proxy too, make sure to enter an additional URI in the form of `<DEFGUARD_ENROLLMENT_URL>/openid/callback`.

If you're having issues with your custom provider's base URL, check Defguard's (core) logs. It should say what URL it expected.


# External OIDC secure enrollment

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

When [External OIDC is enabled,](/1.4/features/external-openid-providers) users have the possibility to [securely enroll (automatically create a Defguard account) and very easily configure their desktop client](/1.4/using-defguard-for-end-users/enrollment/with-external-sso-google-microsoft-custom) just by logging in with the SSO provider:

<figure><img src="/files/3mXAClb2TP9dC3AVrpDK" alt=""><figcaption></figcaption></figure>

For this to work, see [External SSO/OpenID providers](/1.4/features/external-openid-providers#openid-enrollment).


# LDAP and Active Directory integration

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

Defguard supports integration with LDAP and Microsoft Active Directory (AD), enabling seamless connectivity with your existing directory infrastructure. This integration allows organizations to centralize user management, streamline authentication processes, and synchronize user and group data between Defguard and external directory services.

This chapter covers all aspects of LDAP and AD integration, including:

* **Connection Configuration**: How to connect Defguard to your directory server.
* **Settings Overview**: A detailed breakdown of each LDAP configuration option and how it affects synchronization and user mapping.
* **Two-Way Sync**: How Defguard synchronizes data both from and to the directory, including how to handle conflicts, deletion policies, and attribute mappings.


# Configuration

How to configure connection between Defguard instance and LDAP.

{% hint style="warning" %}
Active Directory support is available in Defguard ≥ v1.3.0
{% endhint %}

{% hint style="warning" %}
If you are using the integration across multiple nested organizational units, please read the [#multiple-nested-ous](#multiple-nested-ous "mention") section.
{% endhint %}

## Setup

First, navigate to the settings page and select the LDAP tab.

<figure><img src="/files/J9VIdMKQRlaofhSB71Do" alt=""><figcaption></figcaption></figure>

Now change fields according to your LDAP instance.

For an LDAP server with TLS/SSL you may want to configure one of the options related to TLS. Check "Use StartTLS" if your LDAP server uses StartTLS for encrypted connections, alternatively you may also use `ldaps` in the URL field. If you don't want to provide Defguard with your LDAP server's certificate, you may also disable checking it here.

If you are trying to connect to Active Directory, check "LDAP server is Active Directory". Make sure to read [#example-active-directory-configuration](#example-active-directory-configuration "mention") for a working example.

{% hint style="info" %}
You can find more brief explanations for these settings on this [page](/1.4/features/ldap-and-active-directory-integration/settings-table).
{% endhint %}

After you save your LDAP settings, you can check if your Defguard instance can connect and authenticate to your LDAP server via the "Test" button.

{% hint style="warning" %}
Testing your connection doesn't mean the whole configuration is correct. Currently, Defguard only verifies if a connection can be made and the provided credentials are correct.
{% endhint %}

After enabling the LDAP integration, you will gain the ability to log in to Defguard through LDAP. Additionally, all your Defguard user changes after you enable the integration will be propagated to LDAP. This is a simple one-way synchronization. If you are interested in synchronizing LDAP and Defguard both ways, check [Two-way LDAP and Active Directory synchronization](/1.4/features/ldap-and-active-directory-integration/two-way-ldap-and-active-directory-synchronization).

## Example configurations

### Example Active Directory configuration

<figure><img src="/files/4gFIGMVDkWPZdxj9vXVz" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/AjozKY409u7WVhehYowZ" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/zvWdZ9pDGJzNBZxESFM0" alt=""><figcaption></figcaption></figure>

This is an example configuration for a default Active Directory setup on a Windows Server 2022. The most important aspect is setting the "LDAP server is Active Directory" setting, as AD support won't work otherwise. Additionally, `ldaps` has been configured as AD requires an encrypted connection in order for Defguard to be allowed to send user passwords, which is critical if you expect to create users/set passwords through Defguard.

The "cn" attribute has been configured as the user's RDN as that's what used in the user's DN in our example setup (`cn=user1,cn=users,dc=ad,dc=example,dc=com`). This is different from the username attribute, which will be mapped directly to the Defguard username.

### Example OpenLDAP configuration

<figure><img src="/files/c80YMcHvBQ2E5MdlkQ6N" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Ar4uOopNKJ9YejQLwDQj" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/16w0eSitx9iTSLfcfuoF" alt=""><figcaption></figcaption></figure>

This is an example configuration for an OpenLDAP server integrated with Samba (hence `sambaSamAccount` object class). The `inetOrgPerson` has been set as the user structural class which adds attributes to the LDAP user like `email` or `mobile`. `simpleSecurityObject` class has been added for the ability to set passwords in LDAP.

## Known issues

### Multiple nested OUs

Multiple nested organizational units are supported in Defguard 1.4.0 and above.

If you are using an older version of Defguard, using the integration with multiple nested organizational units may currently lead to some unexpected behavior. The following issues are known to occur:

* If you have duplicate user RDNs across multiple OUs a database error may occur: `Duplicate key violates unique constraint 'unique_ldap_rdn'` , causing issues with two-way synchronization. This would happen in the following scenario:
  * `CN=user1,OU=ou1,OU=ou,DC=example`
  * `CN=user1,OU=ou2,OU=ou,DC=example`
* Limiting synchronization to selected groups may not work if your user's DN doesn't match the user search base:

  * Search base: `OU=ou,DC=example`
  * User's DN: `CN=user1,OU=ou1,OU=ou,DC=example`&#x20;

  In this example, the user's DN has deeper nesting than the search base, preventing matching them during the group members lookup.

To fix this problem, you should limit the search base to one organizational unit only, if possible.


# Settings table

List with description of settings for LDAP found in settings page.

{% hint style="warning" %}
Ensure that the letter casing in your Defguard settings matches exactly with your LDAP configuration. For instance, if your LDAP uses 'CN', be sure to enter it as 'CN' in the settings, not 'cn'.
{% endhint %}

| Field                                 | Description                                                                                                                                         | Default                                   |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| URL                                   | URL that points to your LDAP server.                                                                                                                | Empty                                     |
| Bind Username                         | Bind DN used for authentication.                                                                                                                    | cn=admin,dc=example,dc=org                |
| Bind Password                         | Password used for authentication.                                                                                                                   | Empty                                     |
| Member Attribute                      | Naming attribute for group membership.                                                                                                              | memberOf                                  |
| Username Attribute                    | The attribute which will be used as the user's username.                                                                                            | cn                                        |
| User Search Base                      | Relative Distinguished Name (RDN) of your user entries.                                                                                             | ou=users,dc=example,dc=org                |
| User Object Class                     | Object class used for user entries.                                                                                                                 | inetOrgPerson                             |
| Additional User Object Classes        | Auxiliary classes for user entries                                                                                                                  | simpleSecurityObject, sambaSamAccount     |
| Groupname Attribute                   | Naming attribute for groups.                                                                                                                        | cn                                        |
| Group Object Class                    | Object class used for group entries.                                                                                                                | groupOfUniqueNames                        |
| Group Member Attribute                | Naming attribute for group membership.                                                                                                              | uniqueMember                              |
| Group Search Base                     | Relative Distinguished Name (RDN) of your group entries.                                                                                            | ou=groups,dc=example,dc=org               |
| User RDN attribute                    | The attribute which is a part of the user's DN (the leftmost component of the DN).                                                                  | Empty, defaults to the username attribute |
| Limit synchronization to these groups | Limits all LDAP actions only to users belonging to one of the specified groups, both ways. Values should be provided as a list separated by commas. | Empty                                     |

## Settings in depth

There are a few settings that may be not so obvious:

* `Additional User Object Classes`: User object classes that will be assigned to a user and will also define assigned attributes. For example, `simpleSecurityObject` will make users posses the `userPassword`attribute.
* `User Object Class`: The structural class of your users. Just like the additional user object classes, it will define the added attributes but also will be used during user search. Defguard will only consider entries with this class as users.

{% hint style="danger" %}
Changing the RDN attribute may cause your users to be re-added to Defguard, causing potential loss of Defguard-specific user data, e.g. their device information.
{% endhint %}

* `User RDN attribute`: The attribute used in your user's DN. It will be used to link users between LDAP and Defguard. Depending on your setup, it may be different from the attribute used for usernames. If left empty, your username attribute will be used instead. For example:\
  Given a user DN of `cn=user1,cn=users,dc=ad,dc=example,dc=com` you would set the RDN attribute to `cn`.
* `Username attribute`: The username attribute, which will be used to set the username of a Defguard user. The following restrictions apply:
  * Only alphanumeric characters except for  <kbd>.</kbd>, <kbd>-</kbd> or <kbd>\_</kbd>
  * At least 1 and at most 64 characters
  * Must be unique across all users

{% hint style="danger" %}
To use this feature, your LDAP user entries must posses the "memberOf" attribute (or it's equivalent, defined using the member attribute), which may not be available by default on your LDAP server. This may require enabling an appropriate module.&#x20;
{% endhint %}

* `Limit synchronization to these groups`: limits the synchronization scope to only the members of the selected groups, this works both ways:
  * Changes in Defguard will be propagated to LDAP only if a user belongs to a given group in Defguard.
  * If the two-way synchronization is enabled, only the users belonging to the specified groups will be fetched from the LDAP server.
  * Adding a user to one of the synchronization groups in Defguard will automatically create that user in LDAP if they don't exist yet. If they already exist, their LDAP data (e.g. the email address) will be overwritten with the data in Defguard if only the one way synchronization (Defguard -> LDAP) is enabled. Otherwise, if the two-way synchronization is enabled, the selected authority server will be respected.


# Two-way LDAP and Active Directory synchronization

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

{% hint style="warning" %}
This feature is available in Defguard version ≥ v1.3.0
{% endhint %}

{% hint style="danger" %}
Make sure to be aware of the mechanisms described in [#authority-and-full-synchronization](#authority-and-full-synchronization "mention") and [#first-synchronization](#first-synchronization "mention") before enabling this feature.\
\
We recommend testing the integration first in a non-production environment, as improper configuration may cause loss of user data.
{% endhint %}

The LDAP synchronization allows for synchronizing users and groups between Defguard and your LDAP server.

This feature has been mainly tested with OpenLDAP and Active Directory.

## Requirements

* An LDAP server
* One of the following user object classes set for your LDAP users: `user`, `inetOrgPerson`
* The following attributes set for users you want to sync: username attribute (e.g. `sAMAccountName` or `cn`), `sn`, `givenName`, `mail` - those are required by Defguard
* Username attribute must conform to the restrictions specified in [Settings table](/1.4/features/ldap-and-active-directory-integration/settings-table)

For Active Directory:

* 128-bit encrypted TLS/SSL connection to the AD server. You can read more about it in the [official guide](https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/enable-ldap-over-ssl-3rd-certification-authority) or this step by step [instructions](https://gist.github.com/magnetikonline/0ccdabfec58eb1929c997d22e7341e45).

For OpenLDAP:

* SHA1 as the hashing algorithm and `simpleSecurityObject` user object class

## Setup

First, you will need to configure your LDAP connection. Refer to [Configuration](/1.4/features/ldap-and-active-directory-integration/configuration) for instructions. Here is an example configuration for an OpenLDAP server without SSL/TLS:

<figure><img src="/files/K7PbAAwuzcdHc9tQChTI" alt=""><figcaption></figcaption></figure>

Make sure you selected "Enable LDAP integration" as without it, the two-way synchronization won't work. After you fill out all the fields, test your configuration using the <img src="/files/baL0OwNEoYYyOkuPQr8N" alt="" data-size="line"> button.&#x20;

The LDAP two-way synchronization has the following options available:

<figure><img src="/files/QBb5cnt2cBT4xiITvgaQ" alt=""><figcaption></figcaption></figure>

* **Enable LDAP two-way synchronization** - enables the two-way synchronization. Check it if you want to pull changes from LDAP.
* **Consider the following source as the authority** - makes the selected server the source of truth. See [#authority-and-full-synchronization](#authority-and-full-synchronization "mention") for more details.
* **Synchronization interval** - how often (in seconds) to pull LDAP changes

If you enabled the LDAP integration but not the two-way synchronization, your changes in Defguard will be propagated to LDAP but not the other way around.

### Selecting which users to synchronize

{% hint style="warning" %}
Before enabling this feature, check if you meet requirements described in [Settings table](/1.4/features/ldap-and-active-directory-integration/settings-table)
{% endhint %}

If you want to synchronize only selected users, you can specify the groups of which members should be synchronized.

<figure><img src="/files/BuTnWWptrm3Es03mdhOO" alt=""><figcaption></figcaption></figure>

This can be useful if you have a lot of users in your LDAP server and want to synchronize/pull only users belonging to a given group, e.g. `defguard-sync`.

Another use case would be if you want to have some Defguard users that you don't want to synchronize with LDAP. If those users are not members of the synchronization groups, they won't be touched (and deleted) by the integration.

This setting is described in more depth in [Settings table](/1.4/features/ldap-and-active-directory-integration/settings-table) and affects both LDAP → Defguard and Defguard → LDAP synchronizations.

After specifying synchronization groups, only members of those groups will be kept in sync.

#### Pruning users after changing the synchronization groups

{% hint style="info" %}
The following advice should be applied only when you are using LDAP as the authoritative server.
{% endhint %}

After you change your synchronization groups, users not belonging to the new groups won't be automatically deleted. This may be an issue if you first used the two-way synchronization without any synchronization groups, effectively synchronizing everyone and decided later to narrow the scope of synchronization. This can result in many redundant, not synchronized user records in your Defguard instance lying around. If you want to prune your Defguard users to only those who are in your synchronization group, you can follow these steps (assuming you have already set your synchronization groups):

1. Wait for a two-way periodic synchronization to complete, you can recognize it by the `LDAP sync completed` log message.
2. Temporarily disable the whole LDAP integration in the settings ![](/files/fd4VvJmZZ4fSblPZpOtd)
3. In the Defguard user's list, bulk assign all users one of your synchronization groups, to bring them into the scope of synchronization. You may want to leave out all users which you don't want to be ever touched by the LDAP integration, e.g. the default admin user or other users you want to keep only in Defguard.
4. Enable the LDAP integration in the settings <img src="/files/DP9hAQzfxOYLYAEprlR7" alt="" data-size="line">
5. Now, the next two-way synchronization will remove all users from Defguard who have the synchronization group you just assigned in Defguard but don't have it in LDAP, effectively leaving you only with users that have the group in both sources.

## Synchronization mechanism overview

The goal of the LDAP two-way synchronization is to make the two data sources (LDAP and Defguard) equal. To achieve this, two variants of synchronization are used: synchronous and asynchronous.

#### Synchronous synchronization

Synchronous synchronization happens every time a change occurs in Defguard, e.g. when a user is modified, added or removed. In this case a respective change is immediately sent to the LDAP server. This synchronization always happens if you select "Enable LDAP integration". It's part of the so called "incremental synchronization".

#### Asynchronous synchronization

Asynchronous synchronization happens periodically in the background and it happens only when you enable the two-way synchronization. This synchronization pulls changes from your LDAP server to be applied in Defguard. The interval of this synchronization may be configured using the "Synchronization interval" setting in the LDAP settings. It's part of the "incremental synchronization".

#### Authority and full synchronization

Authority is the setting allowing you to set which source will be considered as more important or where a change is most likely to occur. You can select the authority based on the following:

* If you are most likely to manage your users in the LDAP server with occasional changes in Defguard, select the LDAP server as the authority.
* If you are most likely to manage users in Defguard, leave Defguard as the authority

The selected authority is used during a full synchronization. This type of synchronization may occur when Defguard assumes that the two sources may have diverged and regular synchronization won't be possible. This can happen in the following scenarios:

* First synchronization after enabling two-way synchronization will always be a full synchronization, since Defguard can't gracefully merge changes that were made before.
* Some issue prevented Defguard from synchronously sending a change to the LDAP server
* You switched the authority or disabled LDAP integration

The full synchronization takes both sources, compares them and produces changes in regard to the given authority. For example, given the following sources:

* **LDAP users**: `user1`, `user2`
* **Defguard** **users**: `user2`, `user3`

With LDAP authority:

* `user3` will be removed from Defguard (since he is not in LDAP),&#x20;
* `user1` will be added to Defguard (since he is not in there but is in LDAP)

With Defguard authority:

* `user1` will be removed from LDAP (since he is not in Defguard)
* `user3` will be added to LDAP (since he is not there but is in Defguard)

This can be summed up as: authority indicates the most likely place where a change occurred, which is the reason of the current state. If the LDAP server is set as the authority, we assume that any difference between Defguard is caused by some change in LDAP which hasn't been reflected yet, so we must perform some actions in Defguard to make it equal.

### First synchronization

The first synchronization will replace all your records with the records of the other source, so it's important to select the direction correctly. This is done by setting the authority, discussed in [#authority-and-full-synchronization](#authority-and-full-synchronization "mention"). In short:

* LDAP → Defguard: If you want to replace all Defguard users with LDAP users, set LDAP as the authority
* Defguard → LDAP: If you want to replace all LDAP users with Defguard users, set Defguard as the authority

### Logging in and passwords

As passwords are stored as hashes with possibly incompatible hashing algorithm between sources, Defguard doesn't synchronize passwords both ways.

#### Defguard → LDAP

Passwords are set in LDAP only on Defguard user account creation, enrollment, password change or reset. Basically when the password is explicitly provided by the user with the intent to set or change it.&#x20;

This means that if you want to import to LDAP all Defguard users who were created before enabling LDAP integration, they will have to change their passwords in Defguard in order for it to be propagated and set in LDAP.&#x20;

Because some LDAP implementations will require password on user creation, Defguard will set a temporary, long, random text as the LDAP user password until it's not changed/set/reset by the user in Defguard.

#### LDAP → Defguard

Defguard doesn't pull passwords from LDAP in any form. Instead, when user tries to login to Defguard, if the LDAP integration is enabled, test login attempt will be made to the LDAP server (bind) with the provided credentials. If the test login attempt succeeds, Defguard will authenticate the user just as during a regular login.

## Known issues and other unexpected behavior

### General

#### Groups are not being synced from LDAP

Only non-empty groups are currently synchronized, groups that don't have any syncable members won't be created in Defguard.

#### A user is not being synced

Your user may be missing one of the required attributes. Check [#requirements](#requirements "mention") for a full list. User without one of those attributes will be skipped.

#### Defguard users are losing their groups (e.g. "admin" group)

Your LDAP server may have silently refused creating a Defguard admin group. A common cause may be a DN conflict, e.g. when the DN for your groups and users has the same structure (`cn=<NAME>,cn=users,dc=example,dc=com` both for users and groups). To solve this, create a new group with a name that won't conflict with any other DN.

Otherwise, report it on our GitHub along with any appropriate logs.

#### Something wasn't updated in LDAP

If you notice that your Defguard change isn't propagated properly to LDAP, run Defguard with debug logs enabled (`DEFGUARD_LOG_LEVEL=debug` environment variable).  Some LDAP errors may be not reported as errors by the LDAP server but most of the operations outputs are logged in the debug logs to help you narrow down the issue.

#### Defguard logs suggest that it uses LDAP authority during synchronization despite setting something different in the settings

Incremental synchronization (as opposed to the full synchronization) internally uses LDAP as the authority. This is only an implementation detail to pull and apply changes from LDAP. The authoritative source you picked in settings is only used during full synchronization.

### Active Directory

#### SysErr: DSID-031A1262, problem 22 (Invalid argument)

You are trying to synchronize a Defguard user with username longer than 20 characters, which [AD doesn't support](https://learn.microsoft.com/en-us/windows/win32/adschema/a-samaccountname?redirectedfrom=MSDN).


# Access Control List

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

{% hint style="warning" %}
Access Control List feature is available in Defguard Core v1.3.0 and Defguard Gateway v1.3.0.

Defguard Gateway v1.3.0 supports Linux machines with [NFTables](https://nftables.org/).\
Defguard Gateway v1.4.0 supports FreeBSD, NetBSD, and macOS machines with Packet Filter (PF).
{% endhint %}

The ACL (Access Control List) functionality in Defguard allows administrators to define and manage who can access specific network resources. It provides a clear and centralized way to control access based on users, groups, or devices, ensuring that only authorized entities can reach sensitive systems or services.

### How to enable Access Control List functionality

Access Control can be enabled for each location individually. To enable it:

1. Navigate to **VPN Overview** > **Edit Location settings**
2. In **Location configuration** section, select **Enable ACL for this location**.
3. Click on **Save changes**.

<figure><img src="/files/HPXSYvEocSJkbglzZGcQ" alt=""><figcaption></figcaption></figure>

**You should also set the default ACL policy for the location** (see below).

## Default Access Control List Policy

Default policy defines how to treat network traffic (with regard to resources) that was not explicitly specified in ACL rules:

* **Allow** - users and devices connected to a location will be able to access all resources within the network, if the resource access is not modified by one of ACL rules.
* **Deny** - all traffic to network resources that is not regulated by one of the ACL rules will be blocked.

### How to define Default ACL Policy

Make sure ACL has been enabled (see above), otherwise the policy setting will not be inactive.

1. Navigate to **VPN Overview** > **Edit Location settings**
2. In **Location configuration,** choose the desired option under **Default ACL Policy**.
3. Click on **Save changes**.

<figure><img src="/files/HPXSYvEocSJkbglzZGcQ" alt=""><figcaption></figcaption></figure>

## List of ACL rules

<figure><img src="/files/Y1jKKyF9utIoBmmuOB2c" alt=""><figcaption></figcaption></figure>

**Access Control List** view displays all the rules defined in your system. The list is split into two sections.

**Deployed Rules** section displays the rules that have already been applied. Those rules should be in effect on relevant locations if the Gateway–Core connection is intact.

{% hint style="warning" %}
Defguard does not track rule application status per location. In the event of network connectivity issues between Gateway and Core components, rule propagation is not immediate. The system guarantees **eventual consistency**, meaning rules will be applied once the connection is restored.
{% endhint %}

**Pending Changes** section displays all the rules that have not yet been applied to locations. This includes:

* new rules
* modified rules
* deleted rules

Use the **Deploy pending changes** button to apply all the rules from **Pending Changes** section.

{% hint style="info" %}

#### Batch rule application

Defguard’s ACL functionality is designed to allow users to apply access control rules in batches. This approach minimizes the risk of transient network issues that could occur when deploying rules individually. By grouping changes and deploying them together, the system reduces the likelihood of connectivity hiccups or firewall disruptions.
{% endhint %}

The ACL list view also allows rule filtering by name, locations, and other attributes

<figure><img src="/files/jcc64gw2p0u7PBhC0cE5" alt=""><figcaption></figcaption></figure>

## How to add and modify ACL rules

To create a new rule, use the ![](/files/hf5eNRfS29vTylJ8Eva0) button in the [ACL List View](#list-of-acl-rules).

You can edit an existing rule by using the ![](/files/JDsSWVDhgNyoOPoTEYqN) context menu and selecting **"Edit"** in the [ACL List View](#list-of-acl-rules)**.**

<figure><img src="/files/NpKobLllcdP7Vx4qlpn7" alt=""><figcaption><p>Rule context menu</p></figcaption></figure>

### Anatomy of an ACL rule

<figure><img src="/files/Yvl4yZuAdTWyt0kNRRmU" alt=""><figcaption></figcaption></figure>

The ACL form consists of three main sections:

#### Basic rule configuration

* rule name
* locations where the rule should be applied
* enabling / disabling of the rule

{% hint style="info" %}
Each rule in Defguard can be **enabled** or **disabled** individually. When a rule is disabled, it remains stored in the system but is not applied to any locations, meaning it has no effect on access control until re-enabled. This allows administrators to temporarily deactivate rules without deleting them, making it easy to toggle access policies as needed.
{% endhint %}

#### Destination

This section is meant to define the resource to which access should be granted or restricted. Think of this section as the **destination** part of a firewall rule.

* IP addresses (IPv4 or IPv6) of the resources for which access will be granted or restricted. The addresses can be specified individually, by CIDR addresses (with a mask) or as a range. You can specify multiple comma-separated addresses. Examples of valid values for this field include:
  * `10.1.1.10, 10.1.2.0/24`
  * `10.2.1.10-10.2.2.100, fd00:1000::/64, fd00:1000::f0`
  * etc.
* Ports - TCP/UDP ports and port ranges
* Protocols that will be affected by the rule. All by default. Defguard ACL currently supports TCP, UDP and ICMP protocols.

#### Allowed and Denied sources

This section lets you define which traffic sources should be granted or denied access - essentially the **"source"** side of a firewall rule.

In Defguard, sources can be defined as one of three object types:

* Users
* User Groups
* Network Devices

Each ACL rule in Defguard is intended to fully define access to a specific resource, you must therefore always include at least one allowed source.

{% hint style="warning" %}
This setting is independent of the default location-level [**Allowed groups**](/1.4/features/wireguard/create-your-vpn-network#allowed-groups) configuration.

If you give a user access to some resource through an ACL rule, but they do not have access to a given location, they still won't be able to access it, because they'll be unable to establish a VPN connection with the gateway.
{% endhint %}

### How to define your ACL ruleset

Access Control List (ACL) rules in Defguard are used to manage **who can access specific resources** across your network. Think of each rule as a clear instruction that says: *These users or devices are allowed to reach this resource – and, optionally, these others are not.*

#### Key Concepts:

* Each rule connects **who** (users, groups, or devices) to **what** (a resource address).
* At least one "allowed" source must always be specified - this defines who gets access.
* Optionally, you can **exclude** specific users, groups, or devices using the "denied" section.
* You can use this combination to create flexible rules, such as:\
  \&#xNAN;*Allow everyone in the “Remote Workers” group except a few individuals to access a specific office network.*

This setup helps control access clearly and safely without worrying about lower-level network and firewall behaviour.

#### Details

* ACL rules are **self-contained** – they fully define access for their target resource, are interpreted identically across all Gateways and are unaffected by the **default policy** location setting.
* **Default policy setting** at location level does not affect traffic covered by ACL rules. It applies only to traffic targeting addresses not matched by any ACL rule.
* A **destination address** is required in each rule – specifying only ports and/or protocols that are not allowed.
* **Ports and protocols** are optional. If specified, traffic is allowed *only* on those ports/protocols; everything else is blocked.
* Each ACL results in two firewall rules:
  * An **ALLOW** rule for the allowed sources.
  * A **DENY** rule to block all other traffic to that destination.

### Examples

#### Allowing access for specific users

In this scenario, we will allow specific users to access the 10.1.1.0/24 network, assuming the users connect through *Office-Berlin* location.

To do this, the following new rules have to be added:

* Navigate to **Access Control**.
* Click on **Add new** button.
* Name the rule under **Rule Name**: *Staff access, Berlin*.
* Select *Office-Berlin* in the **Locations** input.
* Under **Manual Input** > **IPv4/v6 CIDR range or address**, enter: *10.1.1.0/24*.
* Add desired users in the **"Allowed Users/Groups/Devices** > **Users**.
* Click on the **Submit** button.

<figure><img src="/files/41qUNCm0LMwFLBCQyDRx" alt=""><figcaption></figcaption></figure>

You will be redirected back to the [ACL List View,](#list-of-acl-rules) and the new rule should now be in the **Pending Changes** section.

<figure><img src="/files/bzongwubFdxbEwyRblar" alt=""><figcaption></figcaption></figure>

Now, click on **Deploy pending changes (1)** button. After that, the rule should be applied on the *Office-Berlin* location.

<figure><img src="/files/8MUoLxFFoMax74RaWzhE" alt=""><figcaption></figcaption></figure>

(See [Implementation Details](https://github.com/DefGuard/docs/blob/docs/enterprise/all-enteprise-features/access-control-list/firewall-internals.md) documentation to understand integration with system packet filtering.)

#### Adding access exceptions for specific users

Let's build on the last example. The example defined a single rule that grants network access for two users. In this example, we will block access for one specific user. But first, let's rethink our approach.

It may be tempting to specify the access for each user individually, like we did while constructing the first rule. This may work at first, or if your users don't change too often. But what if you have a constant influx of new users? This might get tedious pretty fast.

So what we will do is:

* Define two groups:
  * *Staff-Berlin*
  * *Externals*
* Add all the users that work in our *Berlin* office to *Staff-Berlin* group
* Add all users we collaborate with in *Berlin*, but are not our direct employees, to the *Externals* group
* Allow all users in *Staff-Berlin* group access to the network
* Add an exception for the users in *Externals* group so that they are not allowed to access the network

Once you have created appropriate groups and assigned the users, let's update the ACL rule. The rule should now:

* Still be assigned to the *Office-Berlin* location
* Still define the destination resource address as `10.1.1.0/24`
* Instead of specific users in the **Allowed Users** input, we now select the *Staff-Berlin* group in the **Allowed Groups** input
* In **Denied Groups** input we should now select the *Externals* group

<figure><img src="/files/Do5Orba5c9NrEM2Sljt6" alt=""><figcaption></figcaption></figure>


# ACL Aliases

ACL alias functionality allows administrators to create reusable elements which can then be used when defining a destination in multiple ACL rules.

For example, you can define aliases for commonly used ports (e.g. 22 for SSH) or for services within your infrastructure (e.g. 1.2.3.4:5432 for a particular PostgreSQL server).

{% hint style="warning" %}
Access Control is an [enterprise feature](/1.4/enterprise/license). To use it you'll need to [purchase a license](/1.4/enterprise/license#purchasing-the-license) or ensure your deployment does not [exceed the limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).

Access Control is available in Defguard version ≥ 1.3.0 and Gateway version ≥ 1.3.0
{% endhint %}

## Alias management

All the aliases defined in your systems are displayed in the second tab of the **Access Control List** page.

### List of aliases

<figure><img src="/files/aVGyt9fW5Sfu60MCSO0M" alt=""><figcaption><p>ACL alias list</p></figcaption></figure>

Similarly to ACL rules themselves, the list is split into two sections:

* **Deployed Aliases** – aliases that are active and can be used by ACL rules.
* **Pending Changes** – aliases that have been modified and have not yet been deployed.

To deploy pending changes, use the **Deploy pending changes** button. It will deploy selected or all pending changes.

{% hint style="warning" %}
When the alias changes are deployed, firewall rules will be updated for all affected locations.
{% endhint %}

### How to add and modify aliases

To create a new rule, use the **Add new** button on the list view.

You can edit an existing rule by using the ![](/files/JDsSWVDhgNyoOPoTEYqN) context menu and selecting **Edit** in the list view.

<figure><img src="/files/QZU8Qdbz68rqWXWN5aT1" alt=""><figcaption><p>Alias creation form</p></figcaption></figure>

In the ACL alias form, you can specify alias name and [type](/1.4/features/access-control-list#alias-types).

Below in the **Destination** section, you can enter the same resource configuration as in the [ACL rule Destination](/1.4/features/access-control-list#destination):

* IP addresses
* Ports or port ranges
* Protocols

{% hint style="info" %}
Unlike ACL rules, newly created aliases have **Applied** status, since they do not alter any traffic unless used by a rule.
{% endhint %}

### Removing aliases

To remove an alias, select the **Delete alias** option from the context menu.

<figure><img src="/files/D5DFPSxBeo8mrpVrDIHa" alt=""><figcaption></figcaption></figure>

Unlike with ACL rules, alias deletion is not tracked as a modification. You cannot delete an alias if it's being used by any rules and deleting unused aliases is immediate, not requiring changes to be deployed.

<figure><img src="/files/soZOTePiysQxiXt9BOM2" alt=""><figcaption><p>You cannot delete aliases used by ACL rules</p></figcaption></figure>

## Using aliases in ACL rules

Aliases can be used to define an ACL rule destination by selecting them in the input within the **Destination** section:

<figure><img src="/files/btMpE8fBGvsSbYYfRWaO" alt=""><figcaption><p>ACL rule Destination section with Aliases field</p></figcaption></figure>

<figure><img src="/files/PMB2mMvgqixd5MFUcc86" alt=""><figcaption><p>Alias select modal</p></figcaption></figure>

## Alias types

Aliases are divided into two distinct types to handle various use-cases:

* **Destination** alias – defines a complete [ACL destination](/1.4/features/access-control-list#destination); it will be translated into a separate set of firewall rules.
* **Component** alias – defines a part of [ACL destination](/1.4/features/access-control-list#destination); it will be merged with destination manually configured in a given ACL rule when generating firewall rules.

### Examples

Let's start with an ACL rule that defines a following destination:

<figure><img src="/files/8lQCUsiTNsIvItQHfEyA" alt=""><figcaption></figcaption></figure>

By itself, this rule allows specified users to access **all ports** and **all protocols** on the specified IP.

#### Component alias

Consider an **SSH** alias with a following definition:

<figure><img src="/files/Qohp70RSTNIKDzn5mf5n" alt=""><figcaption><p>SSH component alias definition</p></figcaption></figure>

When used in the previously created ACL rule, port 22 will be added to manual inputs defined in the rule itself.

In effect the rule will now grant access **only** to port 22 on 10.2.0.5, just like if we entered the port number in the rule's **Manual Input** section.

#### Destination alias

Now consider the following alias:

<figure><img src="/files/oPxJDR3sFJCNhbjwkV4g" alt=""><figcaption><p>Postgres server destination alias</p></figcaption></figure>

When used in the previously defined ACL rule it will have the following effects:

* the rule will still grant access to **all ports** and **all protocols** on 10.2.0.5
* it will also independently grant access to port 5432 in 10.2.0.38

In effect this is like if the rule has two separate destination inputs.

Underneath this is achieved by creating a separate set of firewall rules (one ALLOW and one DENY) for each destination alias.


# Implementation Details

{% hint style="info" %}
See Examples section in [Access Control List](/1.4/features/access-control-list) documentation as they relate to details described below.
{% endhint %}

## Firewall Interaction

Defguard Gateway does **not** take control of the entire firewall. Instead, dedicated chains (in NFTables) and anchors (in PF) are used as not to interfere with other rules on the firewall.

## NFTables (Linux)

All applied rules are deployed to Defguard Gateway. This means that the firewall on the Gateway that handles the *Office-Berlin* location should contain appropriate [NFTables](https://nftables.org/) rules that implement the specified requirements. Let's see how this looks like in practice. Typing `nftables list ruleset` in the Terminal on a machine running Defguard Gateway should display something like the following:

```
...
table inet DEFGUARD {
        chain FORWARD {
                type filter hook forward priority filter; policy drop;
                ct state established,related counter packets 0 bytes 0 accept
                ip saddr { 10.100.200.155-10.100.200.156 } ip daddr { 10.1.1.0/24 } counter packets 0 bytes 0 accept comment "ACL 132 - Staff access Berlin ALLOW"
                ip daddr { 10.1.1.0/24 } counter packets 0 bytes 0 drop comment "ACL 132 - Staff access Berlin DENY"
        }
}
...
```

As you can see, Defguard has created a new table of type *inet* (the one that handles both IP v4 and v6 addresses). This is to make sure Defguard's configuration won't interfere with your existing NFTables entries.

The FORWARD chain specifies our rules. First you can see the `policy drop` default, which is a result of setting the **Default Deny** policy in the location settings. Then the `established,related` line to skip re-evaluation of established connections.

Finally, the two lines that directly deal with our requirement to allow the two users into the network.

```
ip saddr { 10.100.200.155-10.100.200.156 } ip daddr { 10.1.1.0/24 } counter packets 0 bytes 0 accept comment "ACL 132 - Staff access Berlin ALLOW"
```

This rule specifies two addresses as the **Traffic Source –** `10.100.200.155` and `10.100.200.156`. Those happen to be device addresses of our two users in the WireGuard VPN network that Defguard Gateway manages for this location. The destination address `10.1.1.0/24` is exactly the network address we specified in the rule. And finally the `accept` verdict. All together, this rule allows the traffic specified in the UI to the network.

You may also notice that Defguard added a comment to the rule. The comment includes rule's name so that it is easy for you to find the corresponding rule using tools like `grep`.

Finally, the last line:

```
ip daddr { 10.1.1.0/24 } counter packets 0 bytes 0 drop comment "ACL 132 - Staff access Berlin DENY"
```

This line effectively blocks all other traffic to the 10.1.1.0/24 network. As mentioned earlier, the ACL rules in Defguard are self-contained and fully define access for their target resource. This set of rules can now be deployed to any gateway, no regardless of the **Default Policy** setting, and they will effectively do the same thing.

## Gateway deployment with ACL

Under the hood, Access Control functionality uses [NFTables](https://wiki.nftables.org/wiki-nftables/index.php/What_is_nftables%3F) to interact with the firewall and implement the rules. This means you'll need kernel version ≥ 5.10 to enable all kernel features required for proper operation.

### IP Forwarding

For traffic to flow between your network interfaces on Linux you may also need to enable IP forwarding, if you haven't done it already. This can be achieved by setting the following variable with the following commands:

```
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1
```

If the change should be persistent, edit the sysctl configuration file `/etc/sysctl.conf` and add the following lines to it:

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

To load your changes from `sysctl.conf`, use `sysctl -p`.

### Masquerade

Masquerading between network interfaces falls outside the scope of Defguard’s responsibilities and must be handled by the system administrator. If your environment doesn’t already provide proper routing between the gateway’s interfaces, you may need to enable masquerading to ensure seamless communication.

As a shortcut, Defguard Gateway offers the `--masquerade` flag (or the `DEFGUARD_MASQUERADE=true` environment variable), which applies source NAT between all interfaces automatically, saving you from manually configuring masquerade rules at the system level. It results in this masquerade nftables rule:

```
    chain POSTROUTING {
            ...
            oifname != "lo" counter packets 4 bytes 240 masquerade
    }
```

{% hint style="warning" %}
The `--masquerade` option applies masquerading between **all** interfaces on the gateway, which may be more permissive than necessary in some environments. While convenient, this broad behavior might not align with more restrictive or segmented network designs. For greater control and tighter security, we recommend that administrators configure masquerading manually between only the interfaces that require it.
{% endhint %}

### Forward chain priority

Defguard creates a forward chain in its namespace to control which forwarded packets are being allowed or blocked. This may interfere with your other nftables rules and chains.

```
chain FORWARD {
	type filter hook forward priority filter; policy deny;
	ct state established,related counter packets 119 bytes 13404 accept
}
```

By default this chain has the priority of `filter` (0). You can edit the priority by setting the `DEFGUARD_FW_PRIORITY` environment variable (or `fw_priority` config option) to chosen number, e.g. 1. The higher the priority, the later the chain runs in regard to your other forward chains.

## Packet Filter (FreeBSD, NetBSD, macOS)

Packet filter (PF) firewall, is a BSD-licensed stateful packet filtering software originally developed for OpenBSD and now ported to other BSD-based systems like FreeBSD, NetBSD, and macOS.

{% hint style="info" %}
Defguard Gateway supports Packet Filter (PF) firewall since version 1.4.0.
{% endhint %}

### Anchors

To avoid interference, Defguard Gateway uses custom anchors to add firewall rules. All rules controlled by Defguard are stored in *defguard* anchor, and inside it, there are anchors dedicated to particular network interfaces.

To see all anchor created by Defguard Gateway, enter:

```
pfctl -a defguard -sA
```

To display all rules created for interface *wg0*, enter:

```
pfctl -a defguard/wg0 -sr
```

#### How to enable Defguard rules in PF

Currently, Defguard Gateway does not include its anchor in the general PF rules. This has be done explicitly, using one of the following methods:

1. In PF configuration file */etc/pf.conf*, which should include a line like the following (see pf.conf(5) manual page for details):

```
anchor "defguard/*" all
```

2. Manually in Terminal, but this will remove all existing top-level rules:

```
echo 'anchor "defguard/*" all' |pfctl -f -
```

{% hint style="info" %}
This is not required for OPNsense plug-in for Defguard Gateway as it automatically creates top-level PF rule to include the appropriate rules.
{% endhint %}

### Rules

To display PF rules for network interface *wg0*, type the following command:

```
pfctl -a defguard/wg0 -sr
```

Rules create in *Office-Berlin* example should correspond to something like:

```
block drop in log on wg0 all flags S/SA keep state
pass in log quick on wg0 inet from 10.100.200.155 to 10.1.1.0/24 flags S/SA label "ACL 132 - Staff access Berlin DENY"
pass in log quick on wg0 inet from 10.100.200.156 to 10.1.1.0/24 flags S/SA label "ACL 132 - Staff access Berlin DENY"
```

## Merging destination IP addresses

Destination IPs for a given ACL can be configured in multiple ways:

* Single IP
* Range of IPs
* IP subnet using CIDR notation
* List containing arbitrary combination of the above
* Destination aliases
* Component aliases

It is therefore possible to configure some overlapping destinations, for example a 10.0.20.0/24 subnet and then a specific IP like 10.0.20.17 in some alias.&#x20;

When generating firewall rules, we have to be mindful of the following limitations regarding our specific implementation:

* `nft` rejects overlapping destinations
* `pf` does not handle IP ranges, so each IP in range is put in a separate rule

To avoid those issues when creating firewall rules, we pre-process destination addresses in a following way:

* Combine all destinations - manually configured, aliases, ranges etc into a single list
* Convert all types of destination (single IPs, ranges, subnets) into IP ranges
* Merge all those ranges into the smallest possible list of non-overlapping ranges
* Extract all possible subnets (with at least 2 IPs) from ranges

This means that our approach is biased towards finding subnets, so the destinations you see in the firewall rules on the gateway itself might differ significantly (in notation, not the content itself) from those you configured in your ACLs.


# Network devices

Network devices are like regular user devices but can only be managed by admins and have access to only one network. They are designed to be used with the [Defguard CLI client](/1.4/using-defguard-for-end-users/cli-client).

### Adding a new network device

In order to add a new network device, navigate to the network device menu (select it from the menu bar at the left).

While in the network device menu, click the "Add new" button. You will be presented with a popup prompting you to select your method of setting up the network device.

* **Defguard Command Line Client -** choose it to automatically configure your device with the [Defguard CLI client](/1.4/using-defguard-for-end-users/cli-client)
* **Manual WireGuard Client** - choose it if you don't want to use the Defguard CLI client. You will need to configure your network device manually with a WireGuard config file.

#### Using the Defguard CLI client

After selecting the first option you will be presented with the initial setup screen.

<figure><img src="/files/mBp6UdiFn51pmrirlN2A" alt=""><figcaption></figcaption></figure>

You can specify here the following settings:

* **Device name** - the name used to identify the device, keep it unique in regard to other network devices. This name will be displayed on the network device list,
* **Location** - the network to which the device should have access,
* **Assigned IP Address** - automatically suggested IP address, you may change it as needed,
* **Description** - the description to help you identify the device, it will be displayed in the device list.

After you've finished setting those values, proceed to the next step. You will be presented with an enrollment command. Learn more about further steps from the [CLI client documentation](/1.4/using-defguard-for-end-users/cli-client).

#### Using the Manual WireGuard client

The screen here is similar to that of the CLI client configuration, except for the additional public key field.

<figure><img src="/files/hl5nSCg3nfi5yP1UgWqm" alt=""><figcaption></figcaption></figure>

The fields are as follows:

* **Device name** - the name used to identify the device, keep it unique in regard to other network devices. This name will be displayed on the network device list,
* **Location** - the network to which the device should have access,
* **Assigned IP Address** - automatically suggested IP address, you may change it as needed,
* **Description** - the description to help you identify the device, it will be displayed in the device list.

If you already have a public key for your device, insert it into the public key field. Otherwise, select the option to generate the key pair.

On the next screen you will be presented with the WireGuard configuration file. Copy, download or scan it to import it to your WireGuard client.

### Displaying network device configuration and enrollment token

After you've configured your network device, you can display its enrollment token again,  by interacting with the following menu:

<figure><img src="/files/Cjhl8sWMBZPOU1hoytYJ" alt=""><figcaption></figcaption></figure>

* Selecting "Generate auth token" will re-generate the enrollment token and will allow you to enroll your CLI client again. Use it if you want to manually pull the newest network configuration for your client.
* Selecting the "View config" option will display the WireGuard configuration file (without the private key, as Defguard doesn't store it).


# Activity & Audit logs

The Activity Log provides a comprehensive view of user interactions within your Defguard instance. This allows you to monitor user behaviour, troubleshoot issues, and maintain an audit trail of important activities.

## Viewing Activity log events

Activity log is available as a dedicated page in Defguard core Web UI that's used to manage your instance.

To access it, click the `Activity log` button in the navbar.

<figure><img src="/files/gL4UAJ81kYtdY8JddLvS" alt=""><figcaption><p>Activity log page</p></figcaption></figure>

### Overview

Activity log page displays a chronological list of user-initiated events. By default, most recent events are on top.

Each entry in the list contains following fields:

* **Date** - timestamp of when an event has occurred
* **User** - which user triggered the event
* **IP** - location from which the action was performed
* **Event** - brief description of the event
* **Module** - which module given event belongs to
* **Device** - device (or more specifically user agent) from which the action was performed

### Modules

Events are grouped into modules based on the part of the system they are related to.

Currently, there are four modules:

* **Defguard** - operations performed in the core Web UI (e.g. adding users, modifying devices, managing groups etc.)
* **Client** - actions performed by desktop client applications
* **Enrollment** - events related to the [user enrollment](/1.4/using-defguard-for-end-users/enrollment) process
* **VPN -** events related to VPN clients (e.g. client connecting to a location)

### Filtering

<figure><img src="/files/dahiBHuOXCZpqxPxY8Si" alt=""><figcaption><p>Event filter modal</p></figcaption></figure>

By clicking the `Filter` button above the list you can narrow down the displayed events based on following criteria:

* Event
* Module
* Users

For each of those you can select multiple options.

Filtering by date can be done by clicking the `Time range` button above the list.

<figure><img src="/files/SLi56nT2PPzSdyulIRcw" alt=""><figcaption><p>Time range filter modal</p></figcaption></figure>

### Sorting

By default the Activity log is sorted in reverse chronological order (most recent event on top).

To change the order you can click on the header of the `Date` column.

### Search

You can also use the `Search` input above the list to look for specific events.

You can search by:

* **Username**
* **Module**
* **Event**
* **Device**

The search is case-insensitive and will match partial text.

Note that filtering & searching are composable operations, so if you've already applied some filters the search will be performed only among those filtered events.

## Permissions

Access to the Activity log is controlled by user permissions.

Each user can always view their own activities (events triggered by themselves).

Additionally administrators can view events related to all users.

## Events tracked in Activity Log

At the moment following events are tracked in the Activity log:

* **Defguard** module
  * UserLogin
  * UserLoginFailed
  * UserLogout
  * UserMfaLogin
  * UserMfaLoginFailed
  * RecoveryCodeUsed
  * PasswordChangedByAdmin
  * PasswordChanged
  * PasswordReset
  * MfaDisabled
  * UserMfaDisabled
  * MfaTotpDisabled
  * MfaTotpEnabled
  * MfaEmailDisabled
  * MfaEmailEnabled
  * MfaSecurityKeyAdded
  * MfaSecurityKeyRemoved
  * UserAdded
  * UserRemoved
  * UserModified
  * UserGroupsModified
  * UserDeviceAdded
  * UserDeviceRemoved
  * UserDeviceModified
  * NetworkDeviceAdded
  * NetworkDeviceRemoved
  * NetworkDeviceModified
  * ActivityLogStreamCreated
  * ActivityLogStreamModified
  * ActivityLogStreamRemoved
  * VpnLocationAdded
  * VpnLocationRemoved
  * VpnLocationModified
  * ApiTokenAdded
  * ApiTokenRemoved
  * ApiTokenRenamed
  * OpenIdAppAdded
  * OpenIdAppRemoved
  * OpenIdAppModified
  * OpenIdAppStateChanged
  * OpenIdProviderModified
  * OpenIdProviderRemoved
  * SettingsUpdated
  * SettingsUpdatedPartial
  * SettingsDefaultBrandingRestored
  * GroupsBulkAssigned
  * GroupAdded
  * GroupModified
  * GroupRemoved
  * GroupMemberAdded
  * GroupMemberRemoved
  * GroupMembersModified
  * WebHookAdded
  * WebHookModified
  * WebHookRemoved
  * WebHookStateChanged
  * AuthenticationKeyAdded
  * AuthenticationKeyRemoved
  * AuthenticationKeyRenamed
  * ClientConfigurationTokenAdded
  * UserSnatBindingAdded
  * UserSnatBindingRemoved
  * UserSnatBindingModified
* **Enrollment** module
  * EnrollmentStarted
  * EnrollmentDeviceAdded
  * EnrollmentCompleted
  * PasswordResetRequested
  * PasswordResetStarted
  * PasswordResetCompleted
  * TokenAdded
* **VPN** module
  * ConnectedToMfaLocation
  * DisconnectedFromMfaLocation
  * MfaFailed
  * ConnectedToLocation
  * DisconnectedFromLocation

## Streaming to external SIEM systems

Please note, that enterprise version supports streaming of audit logs to [external SIEM systems. More on this topic in dedicated documentation section](/1.4/features/activity-log/activity-log-streaming).


# Audit Log Streaming to SIEM systems

This feature is designed to help teams centralize visibility into user actions, security events, and system behavior by integrating with tools they already use for monitoring and incident response.

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

{% hint style="info" %}
This feature is available starting from version 1.4
{% endhint %}

**Activity Log Streaming** allows you to forward real-time activity logs from your system to external SIEM (Security Information and Event Management) platforms.

### Supported integrations

Check full list of where activity log can be seen here [Supported SIEM systems integrations](/1.4/features/activity-log/activity-log-streaming/activity-log-integrations).


# Supported SIEM systems integrations

List of supported services to stream activity logs into.

{% hint style="info" %}
We're actively working to expand support for additional SIEM and log management platforms. If your organization uses a tool that's not currently supported, we welcome your feedback—user requests help us prioritize future integrations.
{% endhint %}

The activity log can currently be sent to the following tools:

* [Vector ](/1.4/features/activity-log/activity-log-streaming/activity-log-integrations/vector-integration-guide)- A lightweight tool for building observability pipelines.
* [Logstash ](/1.4/features/activity-log/activity-log-streaming/activity-log-integrations/logstash-integration-guide)- An open-source server-side pipeline that ingests, transforms, and forwards data for logging and analysis.


# Vector integration guide

How to stream activity logs to vector.

[Vector ](https://vector.dev/)serves as a flexible log pipeline, allowing activity events to be collected, processed, and forwarded to a wide range of SIEM systems. By using Vector, you can transform and route logs as needed, making it easier to integrate with your existing observability tools and adapt to future changes in your logging infrastructure.

\
The goal is to connect Defguard as [HTTP Source](https://vector.dev/docs/reference/configuration/sinks/http/) in Vector service. This guide uses an example Vector service running in Docker, configured via Docker Compose.

### Setup Vector

For the sake of this example we will follow simple Docker deployment of Vector via Docker Compose, but you most likely want to follow Vector's guide to [deploy ](https://vector.dev/docs/setup/deployment/)it in your infrastructure.

### Vector configuration

Save the following configuration to **vector.yaml**

```yaml
sources:
  defguard:
    type: http_server
    address: 0.0.0.0:8001
    encoding: ndjson

sinks:
  console:
    type: console
    inputs:
    - defguard
    target: stdout
    encoding:
      codec: json

```

This basic configuration adds an HTTP source named `defguard` and a console sink, which forwards all logs received from `defguard` to standard output.

Next, add vector service to your **docker-compose.yaml** file.

```yaml
  vector:
    image: timberio/vector:latest-alpine
    container_name: vector
    volumes:
      - ./vector.yaml:/etc/vector/vector.yaml:ro
    command: ["--config", "/etc/vector/vector.yaml"]
    ports:
      - "8001:8001"
```

Make sure that new `vector` service is up, and it loaded the configuration, it should print it in stdout:

```
INFO vector::app: Loading configs. paths=["/etc/vector/vector.toml"]
```

### Add Vector destination

In Defguard UI with an administrator account, go into settings page and choose `Activity log streaming`.

Click `Add new` and choose `Vector` destination.

<figure><img src="/files/z37Evi5qnYDIKjED9Oq2" alt=""><figcaption></figcaption></figure>

Fill out `Name` and `Url` of the form and click `Submit`.

If your `defguard` instance is running in the same Docker Compose network as Vector, use `http://vector:8001` as the URL instead of `http://127.0.0.1`, since services in the same Compose network communicate by container name.

<figure><img src="/files/BptGlMLnIgWpr0JP0y55" alt=""><figcaption></figcaption></figure>

That's it! Defguard should now be sending activity events to Vector, and you should see them printed to `stdout` in the running Vector container.

To verify that everything is working, try logging in or out of `defguard` and check if the events appear in the Vector stdout.

### Basic Authentication

Basic Authentication is a simple HTTP authentication method that includes a username and password in the `Authorization` header of each request.\
To enable Basic Authentication for incoming log data, update your Vector configuration as follows:

```yaml
sources:
  defguard:
    type: http_server
    address: 0.0.0.0:8001
    encoding: ndjson
    auth:
      strategy: basic
      password: strongPassword
      username: vector
```

Next, add the configured `username` and `password` in Defguard settings to the Vector destination.

<figure><img src="/files/CW7ZLA7AE5THKjHk3ech" alt=""><figcaption></figcaption></figure>

### TLS

To send logs to a Vector destination over HTTPS, you first need to generate a TLS certificate. The following command uses OpenSSL to create a self-signed certificate for testing purposes:

```
openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365 -subj "/CN=localhost"
```

The command above generates two files: `key.pem` (private key) and `cert.pem` (certificate).\
To use them with Vector, mount both files into the container by updating your Docker Compose configuration:

```yaml
  vector:
    image: timberio/vector:latest-alpine
    container_name: vector
    volumes:
      - ./vector.yaml:/etc/vector/vector.yaml:ro
      - ./key.pem:/etc/vector/key.pem:ro
      - ./cert.pem:/etc/vector/cert.pem:ro
    command: ["--config", "/etc/vector/vector.yaml"]
    ports:
      - "8001:8001"
```

Next, update Vector config:

```yaml
sources:
  defguard:
    type: http_server
    address: 0.0.0.0:8001
    encoding: ndjson
    auth:
      strategy: basic
      password: strongPassword
      username: vector
    tls:
      enabled: true
      ca_file: /etc/vector/cert.pem
      key_file: /etc/vector/key.pem
```

Next, copy the contents of `cert.pem` into the **Certificate** field in the Vector destination settings. Then, update the **URL** field to use the `https` scheme instead of `http`.

<figure><img src="/files/xPPpO8NTCyaCUGX8Yu2b" alt=""><figcaption></figcaption></figure>

### Vector integration configuration

<table data-full-width="true"><thead><tr><th>Name</th><th width="203.7999267578125">Example value</th><th width="111.199951171875" data-type="checkbox">Required</th><th width="179">Vector related configuration</th><th>Description</th></tr></thead><tbody><tr><td>Name</td><td>Vector</td><td>true</td><td></td><td>Assigned name for the destination.</td></tr><tr><td>Url</td><td>http(s)://127.0.0.1:8001</td><td>true</td><td><a href="https://vector.dev/docs/reference/configuration/sources/http_server/#address">address</a></td><td>Address of running vector HTTP source.</td></tr><tr><td>Username</td><td>vector</td><td>false</td><td><a href="https://vector.dev/docs/reference/configuration/sources/http_server/#auth.username">auth.username</a></td><td>username for Basic Authentication</td></tr><tr><td>Password</td><td>strongPassword</td><td>false</td><td><a href="https://vector.dev/docs/reference/configuration/sources/http_server/#auth.password">auth.password</a></td><td>password for Basic Authentication</td></tr><tr><td>Cert</td><td>contents of cert.pem</td><td>false</td><td><a href="https://vector.dev/docs/reference/configuration/sources/http_server/#tls">tls</a></td><td>Used for TLS connection</td></tr></tbody></table>


# Logstash integration guide

How to stream activity logs to vector.

[Logstash ](https://www.elastic.co/logstash)serves as a versatile data processing pipeline that ingests, transforms, and forwards logs from various sources to your preferred observability or SIEM tools. With its modular plugin architecture, Logstash enables flexible configuration of inputs, filters, and outputs—making it ideal for adapting log flows to fit evolving infrastructure needs.

This guide demonstrates how to configure a Logstash service running in Docker using Docker Compose to accept HTTP events from Defguard and forward them for further processing or storage.

### Setup Logstash

Save the following config to `logstash.conf` . This will set up http input for Logstash on port 8002 and output the incoming data into stdout.

```
input {
  http {
    port => 8002
    codec => json_lines {
      target => "activity_data"
    }
  }
}
output {
  stdout { codec => rubydebug }
}

```

Add Logstash service to the `docker-compose.yaml` and start it.

```yaml
  logstash:
    image: docker.elastic.co/logstash/logstash:8.14.0
    ports:
      - "8002:8002"
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro
```

### Add Logstash destination

In Defguard UI with an administrator account, go into settings page and choose `Activity log streaming`.

Click `Add new` and choose `Vector` destination.

<figure><img src="/files/bLS14VsiqIL5iyoanGq9" alt=""><figcaption></figcaption></figure>

Fill out `Name` and `Url` fields and click **Submit**.

<figure><img src="/files/OWT5LpSmiXMnd7G6gpKN" alt=""><figcaption></figcaption></figure>

That's it! Defguard should now be sending activity events to Logstash, and you should see them printed to `stdout` in the running Logstash container.

To verify that everything is working, try logging in or out of `defguard` and check if the events appear in the Logstash stdout.

### Basic Authentication

Basic Authentication is a simple HTTP authentication method that includes a username and password in the `Authorization` header of each request.\
To enable Basic Authentication for incoming log data, update your Logstash configuration as follows:

```
input {
  http {
    port => 8002
    codec => json_lines {
      target => "activity_data"
    }
    user => "logstash"
    password => "strongPassword"
  }
}
output {
  stdout { codec => rubydebug }
}

```

Modify Logstash destination in settings and fill`username` and `password` in settings.

<figure><img src="/files/8bQnXT4r6spZucuKmoQA" alt=""><figcaption></figcaption></figure>

### Logstash integration configuration

<table data-full-width="true"><thead><tr><th>Name</th><th width="203.7999267578125">Example value</th><th width="111.199951171875" data-type="checkbox">Required</th><th width="230">Logstash related configuration</th><th>Description</th></tr></thead><tbody><tr><td>Name</td><td>Logstash</td><td>true</td><td></td><td>Assigned name for the destination.</td></tr><tr><td>Url</td><td>http(s)://127.0.0.1:8002</td><td>true</td><td><a href="https://www.elastic.co/docs/reference/logstash/plugins/plugins-inputs-http#plugins-inputs-http-host">host</a>, <a href="https://www.elastic.co/docs/reference/logstash/plugins/plugins-inputs-http#plugins-inputs-http-port">port</a></td><td>Address of running vector HTTP source.</td></tr><tr><td>Username</td><td>logstash</td><td>false</td><td><a href="https://www.elastic.co/docs/reference/logstash/plugins/plugins-inputs-http#plugins-inputs-http-user">user</a></td><td>username for Basic Authentication</td></tr><tr><td>Password</td><td>strongPassword</td><td>false</td><td><a href="https://www.elastic.co/docs/reference/logstash/plugins/plugins-inputs-http#plugins-inputs-http-password">password</a></td><td>password for Basic Authentication</td></tr><tr><td>Cert</td><td>contents of cert.pem</td><td>false</td><td><a href="https://www.elastic.co/docs/reference/logstash/plugins/plugins-inputs-http#plugins-inputs-http-ssl_certificate">ssl_certificate</a></td><td>Used for TLS connection</td></tr></tbody></table>


# Notifications


# Email notifications

In **Settings > SMTP** tab you can setup a connection to an SMTP server.

This enables your Defguard instance to send **email notifications** to users and admins.

After you fill in all the relevant fields you can use the **Send test email** form at the bottom to test if your configuration is correct.


# Gateway notifications

You can configure automatic e-mail notifications when one of your gateways disconnects.&#x20;

### Requirements

* SMTP server configured in Defguard (SMTP tab in settings)

### Configuration

In order to configure the notifications, navigate to the "Gateway notifications" settings tab.

<figure><img src="/files/WFP9UTdMMD1Oliel867n" alt=""><figcaption></figcaption></figure>

The configuration options are as follows:

* **Enable gateway disconnect notifications** - whether the notifications should be enabled
* **Gateway inactivity time** - the time for which the gateway needs to stay disconnected in order to trigger the notification
* **Enable gateway reconnect notifications** - whether to send the notification when the gateway connects again after


# New version notifications

Defguard will periodically (every 6 hours) check for a new version, If there is one that is newer than the current one, a toast will be displayed in the admin dashboard.

<figure><img src="/files/eyf1Pk8VDdpE0UgYryga" alt=""><figcaption></figcaption></figure>

You can display the release notes by clicking "See what's new".

<figure><img src="/files/ayqClFkmAawRbClSrpSo" alt=""><figcaption></figcaption></figure>

If the update is considered critical (e.g. fixes a vulnerability) it will have the "critical update" badge.

If you dismiss the update, it won't be shown again for that version for the&#x20;


# Integrations


# Webhooks

## Basic idea

The basic idea of webhooks is to send user data to external systems in order to automate certain tasks like for example sending welcome email to a newly created user.

## Setup

On the left side of Defguard navigation, you'll find webhooks page

![New webhook form](/files/mvASUGLcdXZOFxVGeDHh)

On the form above, you'll see inputs like URL description token and triggers

* **URL** is a URL on which data will be sent after certain triggers
* **Description** short description of your webhook to remember its use case
* **Secret token** is a token sent with request in authorization header, **Note** if receiver didn't implement any token check it'll do nothing
* **Triggers** are events which will trigger the webhook

## Sample requests

Below is a list of all triggering actions with their request header and sample JSON body which will be sent on URL given at webhook creation.

**Note** all requests are using `GET` method and sends data in body of request in JSON format.

### New user created

Triggered after creating user

Header with name of trigger

`X-Defguard-Event: user_created`

Body example:

```json
{
"email":"janedoe@email.pl",
"first_name":"jane",
"last_name":"doe",
"groups":[],
"is_admin":false,
"pgp_cert_id":"",
"pgp_key":"",
"phone":"123456789",
"ssh_key":"",
"username":"jdoe"
}
```

### User modified

Triggered after modifying user

Webhook will be triggered on new user deletion sample request:

Header

`X-Defguard-Event: user_modified`

Request body example:

```json
{
"email":"janedoe@email.pl",
"first_name":"jane",
"last_name":"doe",
"groups":["admin"],
"is_admin":false,
"pgp_cert_id":"",
"pgp_key":"",
"phone":"123456789",
"ssh_key":"",
"username":"jdoe"
}
```

### User Deleted

Triggered on deleting user

Header

`X-Defguard-Event: user_deleted`

Request body example:

`{ username: "jdoe"}`

### User YubiKey Provision

Triggered after successfully provisioning YubiKey

Header

`X-Defguard-Event: user_keys`

request body example:

```json
{
"email":"janedoe@email.pl",
"first_name":"jane",
"last_name":"doe",
"groups":["admin"],
"is_admin":false,
"pgp_cert_id":"",
"pgp_key":"",
"phone":"123456789",
"ssh_key":"",
"username":"jdoe"
}
```

**Note**


# REST API

{% hint style="warning" %}
This is an enterprise feature. To use it, purchase our [enterprise license](/1.4/enterprise/license) or ensure that your deployment does not exceed the [usage limits](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
{% endhint %}

{% hint style="warning" %}
API functionality:

1. requires Defguard version 1.2.4+
2. is also **available without enterprise license**, if your instance does not exceed the limits [described here](/1.4/enterprise/license#enterprise-is-free-up-to-certain-limits).
   {% endhint %}

## REST API documentation

You can explore the Defguard REST API using [Swagger UI](https://swagger.io/tools/swagger-ui/) by going to `<YOUR_DEFGUARD_URL>/api-docs`.

API specification JSON in OpenAPI format can also be fetched from `<YOUR_DEFGUARD_URL>/api/v1/api-docs`.

Admin users can generate API tokens to enable request authentication for custom external tools which use Defguard REST API.

Tokens retain the same access permissions as their owner, so be careful when sharing them with others.

## Generating API token

## Setup

To generate a new API token, go to your profile page and click the `Add new API Token` button:

<figure><img src="/files/11EIIaaeO4xp3sVu2JON" alt=""><figcaption></figcaption></figure>

Fill in your chosen token name and submit form:

<figure><img src="/files/9a7snW2tbm02DHpc9and" alt=""><figcaption></figcaption></figure>

Copy generated token. This is the only time the token will be available in plain text form. If you lose it you will have to generate a new one.

<figure><img src="/files/FJfrOXP00lNcBYmZOVtY" alt=""><figcaption></figcaption></figure>

In the API token list you can later rename or delete a token:

<figure><img src="/files/MkBkLJJLFQxCJZXjkeIT" alt=""><figcaption></figcaption></figure>

## Usage

Defguard API uses a standard **Bearer token authentication** scheme.

This means that an API token can be passed in the `Authorization` header to authenticate a given request instead of a session cookie used by the web UI:

```bash
Authorization: Bearer <token>
```

Example GET request:

```bash
curl -H "Authorization: Bearer <token>" <YOUR_DEFGUARD_URL>/api/v1/me
```

## Swagger UI

### Using API token in Swagger

After opening Swagger UI you can add your `API token` and try out available endpoints.

1. Open Swagger UI and click **Authorize** button.

<figure><img src="/files/dd1wHUwLC91eDbO4mmZQ" alt=""><figcaption></figcaption></figure>

2. Paste your `API token.`

<figure><img src="/files/HaASc7DRu4ae4J1Ou1Vd" alt=""><figcaption></figcaption></figure>

3. Click on endpoint and select **Try it out** option.

<figure><img src="/files/rAPJgLMKkh4v5TPXSxR5" alt=""><figcaption></figcaption></figure>

4. If endpoint requires a path or request body, enter it.

<figure><img src="/files/Lvi5eeMc2lJkhwVSBILT" alt=""><figcaption></figcaption></figure>

5. Click **Execute** and scroll down, you will see response body.

<figure><img src="/files/WPT1E7hYVFXXwXK5XHNy" alt=""><figcaption></figcaption></figure>

### Schemas

If you are looking for definitions of types, you can scroll down to **Schemas** section.&#x20;

<figure><img src="/files/SKuC9evNrCwYgmNiGZlt" alt=""><figcaption></figcaption></figure>


# OPSense Configuartion

[OPNsense®](https://opnsense.org/) is an open source, feature rich firewall and routing platform, offering cutting-edge network protection.

## Defguard Gateway Configuration

This instruction helps configure Defguard Gateway in OPNsense. This is based on [WireGuard Road Warrior Setup](https://docs.opnsense.org/manual/how-tos/wireguard-client.html) from OPNsense documentation.

### Configure Defguard Gateway plugin

1. Go to **VPN → Defguard Gateway**
2. Fill out the appropriate values in the form. You can read more about the available configuration options here: [Configuration](/1.4/deployment-strategies/configuration#gateway-configuration)
3. Eventually, **Start/Restart** the service.

<figure><img src="/files/3BLwWdtocrFSSnMkVLgd" alt="OPNSense plugin"><figcaption></figcaption></figure>

### Assign a network interface to Defguard

1. Go to **Interfaces → Assignments**
2. Under **Assign a new interface**, select the Defguard Gateway network interface (e.g. *wg0*)
3. Add a description, for example *ParisOfficeVPN*
4. Click **Add**

<figure><img src="/files/EBZ4iojfoc6qUyeQSyhs" alt="Interface Assignments"><figcaption></figcaption></figure>

5. Select the newly create interface by clicking on its name (in this example *\[ParisOfficeVPN]*).
6. Select **Enable Interface**
7. Select **Prevent interface removal**
8. Click **Save**, and then **Apply changes**

### Create an outbound NAT rule

1. Go to **Firewall → NAT → Outbound**
2. Make sure the selected **Mode** is **Hybrid outbound NAT rule generation**; if it wasn't selected, click **Save** and then **Apply changes**
3. Under **Manual rules**, add a new rule by clicking **+**.
4. Select **Interface** – this should be either WAN or LAN, depending on the needs.
5. Select **TCP/IP version** – either IPv4 or IPv6.
6. Select **Source address** – this should be interface name assigned above plus *net*, e.g. *ParisOfficeVPN net*.
7. Click **Save**, and then **Apply changes**

<figure><img src="/files/BJ0zJaN7Q4MS6WX905Ha" alt="Outbound NAT rule"><figcaption></figcaption></figure>

### Add firewall rules to allow WireGuard traffic in

1. Go to **Firewall → Rules → WAN**
2. Click **+** (plus) to add a new rule
3. The rule should *Pass* the traffic *in* with *quick* option enabled
4. Select **WAN** interface
5. Choose **TCP/IP version** of your desire
6. Select **UDP** protocol.
7. Set **Destination** to **WAN address** and port to the port number provided in Defguard Core: *Location configuration → Gateway port*
8. Click **Save**, and then **Apply changes**

<figure><img src="/files/Tm4aGV0cGLVAzJ288Hxp" alt="Firewall rule"><figcaption></figcaption></figure>


# SSH Authentication

## Overview

Defguard allows you to configure SSH authentication on your servers to use public SSH keys stored in your instance's database. This is possible by using the [AuthorizedKeysCommand option](http://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/sshd_config.5#AuthorizedKeysCommand) in OpenSSH daemon configuration file.

{% hint style="info" %}
Each user can manage their public SSH (and GPG keys) in their user profile.

Also, when provisioning YubiKeys - those keys are also available in user profile (with info on which YK they are stored):

<img src="/files/4UavtgB5pPamMUgpdT3O" alt="" data-size="original">
{% endhint %}

The specific API endpoint used for this is `/api/v1/ssh_authorized_keys`. It returns a list of public keys, each in a new line. It allows you to filter you query by specifying a username, a group or a combination of both.

## Setup

There's no specific configuration to be performed in Defguard itself (aside from adding SSH keys for users of course), all the steps below are performed on the server you want to SSH into using defguard-supplied public keys:

1. Add a script which fetches SSH keys from your Defguard instance

```bash
#!/bin/sh

curl defguard.example.com/api/v1/ssh_authorized_keys?username="${1}"
```

2. Make it executable, set correct ownership and permissions

```sh
sudo chown root:root /usr/local/bin/get_ssh_keys.sh
sudo chmod 0755 /usr/local/bin/get_ssh_keys.sh
```

3. Update OpenSSH daemon config (`/etc/ssh/sshd_config`) to include following lines

```
AuthorizedKeysCommand /usr/local/bin/get_ssh_keys.sh
AuthorizedKeysCommandUser nobody
```

4. Restart OpenSSH daemon

With this setup when a user `someuser` tries to log in with SSH to your server the script will make a `GET` request to your Defguard instance and fetch a list of keys assigned to `someuser` (if such a user exists). This list is then used to verify keys presented by the client.

### Other examples

Other script examples which can be useful in different server setups:

* only allow users in the `admin` group to log in with SSH

```bash
#!/bin/sh

curl defguard.example.com/api/v1/ssh_authorized_keys?group=admin&username="${1}"
```

* allow all users in `admin` group to log in, but only to `adminuser` account

```bash
#!/bin/sh

test $# -ne 1 -o "${1}" != 'adminuser' && exit 1

curl defguard.example.com/api/v1/ssh_authorized_keys?group=admin
```


# Forward auth

Defguard supports [forward auth](https://app.gitbook.com/o/Z3mGSAbEj9iLdZ7cNFlL/s/hM5HQk0xXl585Dm4YMUV/~/changes/48/features/forward-auth) integration with popular reverse proxies (tested with [traefik](https://doc.traefik.io/traefik/) and [caddy](https://caddyserver.com/)). This allows you to use Defguard to secure services which don't provide their own authorization or OAuth integration.

{% hint style="warning" %}
In order for forward auth to work the services you are trying to protect must be available at URLs within the same base domain as your Defguard instance.

For example if you are serving your Defguard UI at `id.yourdomain.com`, then your services must use other subdomains of `yourdomain.com`, e.g. ``app1.yourdomain.com, `service.yourdomain.com` etc``.

Additionally you have to update your [Defguard config](/1.4/deployment-strategies/configuration#auth-cookies-configuration) to set the cookies domain to `yourdomain.com`.
{% endhint %}

## Example configurations

For brevity, all of the examples below assume you are hosting your Defguard instance at `defguard.yourdomain.com`.

We'll use a basic [whoami](https://github.com/traefik/whoami) container as an example service, which will be available at `whoami.yourdomain.com`.

### Traefik

#### docker-compose.yml

```yaml
version: "3"

services:
  traefik:
    image: traefik:v2.9
    command: --api.insecure=true --providers.docker
    ports:
      - "80:80" # HTTP port
      - "8080:8080" # Web UI port
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
  whoami:
    image: traefik/whoami
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.com`)"
      - "traefik.http.middlewares.defguardauth.forwardauth.address=http://defguard.yourdomain.com/api/v1/forward_auth"
      - "traefik.http.routers.whoami.middlewares=defguardauth"
```

### Caddy

#### Caddyfile

```
# Disable HTTPS for this example (WARNING: Do not use in production)
{
    auto_https off
    https_port 80
}

whoami.yourdomain.com {
    forward_auth defguard.yourdomain.com {
      uri /api/v1/forward_auth
    }
    reverse_proxy whoami:80
}
```

#### docker-compose.yml

```yaml
version: "3"

services:
  caddy:
    image: caddy:2.6.4-alpine
    ports:
      - "80:80" # HTTP port
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
  whoami:
    image: traefik/whoami
```


# YubiKey Provisioning

Provisioner repository: https\://github.com/DefGuard/YubiKey-Provision

### Compatibility

Some Yubikey's will not be compatible with this feature.

{% hint style="danger" %}
This feature was tested only on Yubikey series 5, we don't support older series ( some still might work).
{% endhint %}

Conditions below needs to be met:

* YubiKey needs to return serial number via `ykman list`
* YubiKey needs to have available and active OpenPGP application. You can check out your series capabilities on yubico [website](https://support.yubico.com/hc/en-us/articles/360013790259-Using-Your-YubiKey-with-OpenPGP).
* YubiKey needs to support RSA 4096, older series can have problem with this, especially with older firmware versions.

## Overview

Our provisioning service (installed on a computer that has USB access and securely communicating with Defguard) allows you to easily create and populate the **SSH and GPG/OpenPGP** keys on a YubiKey hardware key, and share its public information inside Defguard - which can be [used for example to authenticate to servers using defguard](/1.4/features/ssh-authentication).

{% hint style="info" %}
Defguard allows also of uploading/managing any GPG/SSH keys in the user profile.
{% endhint %}

It's completely safe, Defguard does not store private keys. Every key is provisioned inside an encapsulated session so any **gpg-related files are deleted right after the process ends successfully or not**. Only public PGP and SSH keys are sent to Defguard so you can access them at any time.

{% hint style="warning" %}
**GPG keys warning!**

That also means that the **master key** is deleted and only sub-keys are stored - so you will not be able for example to edit the GPG key and add additional emails, etc - as that requires the **master key** to be imported to GPG.

As we do not want to store any private keys for security reasons, we have some ideas and plans for **optional master-key** storage based on **HSM encryption**, but we want to see if any actual companies/users need that, as there is always a way just to overwrite the existing YK and provision with new data.
{% endhint %}

### Prerequisites

If you want to use solutions other than docker, the provisioning station needs to have both gpg2 and [ykman](https://docs.yubico.com/software/yubikey/tools/ykman/Install_ykman.html) programs on the provisioning machine.

## Installation of provisioning service

{% hint style="info" %}
The provisioning service is required as we need physical access to the USB and to the YK device.

It's good for example to prepare a *provisioning station* in your organization that will be available for just plugging in new YK's and provisioning them with ease..
{% endhint %}

Currently, we provide Linux .rpm and .deb packages alongside Docker image, but provisioning clients can also be compiled and run under Windows and macOS.

Note that if you decide to use Docker make sure your container has access to host machine devices, otherwise, you will encounter `No keys detected` error.

## Configuration

All of the available options are described in the help:

```bash
yubikey-provision -h
```

### CLI options and configuration

Configuration can be provided in CLI with options, in environment variables, or via `.env` file.

<table><thead><tr><th>Name</th><th>Description</th><th data-type="checkbox">Required</th><th>CLI option</th><th>Environment variable</th><th>Default value</th></tr></thead><tbody><tr><td>Provisioner ID</td><td>Shown in Defguard UI</td><td>true</td><td>--id</td><td>WORKER_ID</td><td>YubikeyProvisioner</td></tr><tr><td>Log level</td><td>Sets logging level</td><td>false</td><td>--log-level</td><td>LOG_LEVEL</td><td>info</td></tr><tr><td>GRPC Endpoint</td><td>Url of your Defguard instance GRPC endpoint. Make sure you include <strong><code>http</code></strong> or <strong><code>https</code></strong> !</td><td>true</td><td>--grpc</td><td>GRPC_URL</td><td><a href="http://127.0.0.1:50055">http://127.0.0.1:50055</a></td></tr><tr><td>GRPC CA File</td><td>Path to CA file. Needed if you want GRPC to use TLS.<br><br>You don't need to change http in endpoint if this is present.</td><td>false</td><td>--ca-file</td><td>GRPC_CA</td><td></td></tr><tr><td>Authorization Token</td><td>Authorization Token found in Defguard UI on Provisioners page.</td><td>true</td><td>--token</td><td>DEFGUARD_TOKEN</td><td></td></tr><tr><td>Detection retries</td><td>How many times provisioner will check for YubiKey presence in system before abandoning the process.</td><td>false</td><td>--smartcard-retries</td><td>YUBIKEY_RETRIES</td><td>1</td></tr><tr><td>Retry interval</td><td>How long between retries provisioner will wait ( in seconds )</td><td>false</td><td>--smartcard-retry-interval</td><td>YUBIKEY_RETRY_INTERVAL</td><td>15</td></tr><tr><td>GPG debug level</td><td>Sets debug level for gpg command during gpg operations</td><td>false</td><td>--gpg-debug-level</td><td>GPG_DEBUG_LEVEL</td><td>none</td></tr></tbody></table>

## Example command

Example of working command to run a provisioner.

This will run the provisioner with an id of "example" for instance with GRPC endpoint on 50055.

```bash
yubikey-provision --id example --token <TOKEN> --grpc http://localhost:50055
```

## Client access token

To register a new provisioning client you will need an access token provided by your instance. You can find it in the info card on the "Provisioners" page.\\

## Example of use

{% hint style="info" %}
This path describes how the admin can provision a key for a user, but the same provisioning modal is also available to the users on the user profile if any workers are available on the instance.
{% endhint %}

You can see available clients in Defguard web-application under "provisioners" tab.

<figure><img src="/files/t08qUUtwY1otVgZFO7ho" alt=""><figcaption></figcaption></figure>

To provision the key:

1. Select the user from "Users" page in Defguard web application (or go to "My Profile" if you're provisioning a key for yourself)\\
2. Insert a YubiKey to machine that is running the provisioner client.
3. Select "Add YubiKey" from the actions menu for a User in the list.

   <figure><img src="/files/jnpTUIL4DNImlQgewy65" alt="" width="301"><figcaption></figcaption></figure>
4. Select your provisioner and click the "Provision YubiKey" button.

   <figure><img src="/files/cdw3c4WZXGRKxPRKjYoN" alt=""><figcaption></figcaption></figure>

The service will take a short moment to prepare and provision your keys. Once the process is done, the modal will close, and you will see a notification in the corner of the screen.

After provisioning a YK with serial number and all keys details will be visible in your profile:

<figure><img src="/files/4UavtgB5pPamMUgpdT3O" alt="" width="375"><figcaption></figcaption></figure>

## Common problems

#### YubiKey is not detected by the client

If the client will not detect your YubiKey, it may work if you unplug and plug it back into your machine. If you are running on Linux, try to restart the pcscd service. If you are using a docker image, make sure the container has access to your host devices.

#### Provisioning failed / IO Error in logs

This is very similar to Yubikey not detected issue. If run under VM with no direct access to host USB devices, the provisioner or rather gpg program itself can have trouble with sending proper commands to YubiKey smartcard. In this case, ensure that gpg can access the smartcard and write into it from VM without problems, for testing this, follow this [guide](https://support.yubico.com/hc/en-us/articles/360013790259-Using-Your-YubiKey-with-OpenPGP) from Yubico.

#### Failed to register worker

This error is most commonly caused by your provisioner having problems making a connection to the Defguard GRPC endpoint. Make sure to:

* Include `http://` in your GRPC URL.
* Run docker on the host network with the `--privileged` option. If you are using a docker container.
* The host that runs the provisioner can connect to the Defguard GRPC endpoint.


# User SNAT bindings

## Please check [documentation of Defguard 1.5.0](/1.5/features/user-snat-bindings)


# Overview

Welcome to the deployment strategies section of Defguard documentation. This guide covers the different ways you can deploy Defguard in your environment, from quick options using packages or Docker to more advanced setups with Kubernetes or Terraform. Whether you're running a small instance or preparing for a more complex production environment, this section will help you choose the deployment method that best fits your needs.

## Components

Defguard comes with four main components:

* **Core service** - main web UI and database
* **Proxy service** - used to safely expose a subset of public functionalities
* **VPN gateway server** - retrieves configuration from core and configures VPN interfaces on the gateway server
* **Provisioning station** - client application which can be started on any pc to auto-generate PGP keys for YubiKey

There is one external component required: PostgreSQL database.

## Hardware requirements

All Defguard components are **very low resource-consuming**. All of them are written in [Rust](https://www.rust-lang.org) and are single binaries. As minimum setup as follows should be more than enough:

| Resource     | Minimum requirements         |
| ------------ | ---------------------------- |
| CPU          | 1 GHz                        |
| RAM          | 2 GB (mostly for PostgreSQL) |
| Disk         | 2 GB                         |
| Architecture | x86\_64, ARM64               |

## Quick start

The easiest way to run your own Defguard instance is to use Docker and our [one-line install script](/1.4/getting-started/one-line-install).

Just run the command below in your shell and follow the prompts:

```bash
curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh -O && bash setup.sh
```

To learn more about the script and available options, please see the [documentation](/1.4/getting-started/one-line-install).

## Manual deployment

If you prefer to configure and deploy Defguard manually, see the examples below:

* [Docker Compose](/1.4/deployment-strategies/docker-compose)
* [Kubernetes](/1.4/deployment-strategies/kubernetes)

Client services

* [Gateway](/1.4/deployment-strategies/gateway)
* [YubiBridge](/1.4/features/yubikey-provisioning)

{% hint style="info" %}
On initial startup a new `admin` user will be created with a password which can be configured by the `DEFGUARD_DEFAULT_ADMIN_PASSWORD` environment variable (by default it's `pass123`). Use those credentials to log in and start exploring the system.
{% endhint %}

### Tips

See our [Configuration](/1.4/deployment-strategies/configuration) document to check all configurable things before you start. And learn about our Architecture [here](/1.4/in-depth/architecture) to see how it works.

## Updates

All services within the Defguard architecture can be updated independently, although it's recommended to always use newest version of services and update them all together to avoid situations like Core expecting some not existing feature in Gateway.\
Check the GitHub repositories for each service to find their newest releases and release notes.

* Docker - For Docker and Kubernetes based setup just change docker image version for service you want to update.
* Packages(DEB, RPM, etc.) - Currently we don't have any package repository so if you want to update your service installed as package you have to download new version from service repository.

**GitHub Repositories:**

* [Defguard Core](https://github.com/DefGuard/defguard/releases)
* [Defguard Proxy](https://github.com/DefGuard/proxy/releases)
* [Defguard Gateway](https://github.com/DefGuard/gateway/releases)
* [Defguard YubiBridge](https://github.com/DefGuard/YubiKey-Provision/releases)

## Backup

[Core service](https://github.com/DefGuard/defguard) is the only service which uses persistent data storage, which is PostgreSQL database. Every SQL migration is applied automatically while bringing up core server and we try our best not to break anything in the process. It's recommended to do database, configuration and Settings(SMTP, Branding) backup before every update in case of some unexpected failure.

\
Example database backup:

```bash
docker exec {container_name} pg_dump -U {user_name} > {backup_file_name}
```

## Failover/HA/Clustering

For now the [Gateway](/1.4/deployment-strategies/gateway) can be deployed on multiple servers/firewall/routers for failover and HA - even if the connection to the Core will be lost, gateways will operate with their local cache/data and the VPN will be working. Same works the other way around if gateway don't work or is not available other features from Core like OpenID will be working.


# Hardware, OS, network and firewall recommendations

Before Defguard can be deployed please get familiar with the following recommendations

## Server & environment requirements

Defguard can be deployed on multiple servers (physical or virtual) or on a single server (which is not recommended).

Recommended setup:

1. **Dedicated server or Virtual Machine for Core (control plane)** - that is in the Intranet network segment, not exposed in the public Internet in any way. Core needs to be accessible from the local (secure) network and VPN (to access Defguard securely). Recommended hardware parameters:
   1. CPU: min. 1 CPU/vCPU per location - eg. if Defguard handles 2 VPN locations recommended is min. 2 CPU/vCPU
   2. RAM: min. 1GB per location
   3. Disk: min 8GB and more (since statistics will be gathered)
2. **Dedicated server or Virtual Machine for Proxy (external and public enrollment service)** - this server/VM needs to be deployed in DMZ/public/external systems network segment - as this service will be exposed and must be available publicly from the Internet. Recommended hardware parameters:
   1. CPU: min. 1 CPU/vCPU per location
   2. RAM: min. 1GB
   3. Disk: min 1GB
3. **Dedicated server or Virtual Machine for Gateway -** this server/VM needs to be deployed in:
   1. DMZ/public/external systems network segment - as this service will be exposed and must be available publicly from the Internet.
   2. Has access on Internal network interfaces to all network segments that will be exposed from VPN for users.
   3. Recommended hardware parameters:
      1. CPU: min. 1 CPU/vCPU per location
      2. RAM: min. 1GB
      3. Disk: min 4GB (mostly for logs)

### Operating system and software requirements

#### Package based installation

Package based install requires Debian GNU/Linux min. 13.x or Ubuntu Linux min. 24.04.x

#### Docker based installation

Docker deployment requires the system to have [official Docker Engine installation](https://docs.docker.com/engine/install/) (not distribution based packages).

## Network IP & DNS setup

### Gateway server - where WireGuard VPN tunnels itself will be launched

* **must have a public IP assigned on which the WireGuard port will be exposed in the Internet**
* must have all networks on internal interfaces addresses configured, that should be accessible from VPN
* **Recommended:** to have a public domain assigned to this IP for VPN server, eg. *vpn.company.com*

### Proxy - public web service for enrollment & desktop client configuration

* **must have a public IP assigned on which the enrollment domain will be configured and HTTPS server will be exposed**
* **must have a public enrollment domain assigned to this IP,&#x20;*****eg. enrollment.company.com (or vpn-config.company.com, etc..*****)**

### Core & database server

* should be internal / private IP addresses accessible only from Intranet and VPN
* must have internal domain name assigned in the local network DNS server, eg. *defguard.company.com*

## Firewall settings

### Gateway

1. Please open the public port you wish the VPN to be working on - eg. 50555

* Please open on the firewall: local network access **from the Gateway server/VM** → **to Defguard Core gRPC port - more info here:** [**https://docs.defguard.net/deployment-strategies/configuration#grpc-server-configuration**](https://docs.defguard.net/deployment-strategies/configuration#grpc-server-configuration)

### Proxy

1. please open the public 443 port on the server (recommended to rewrite port 80 to redirect to 443)
2. please open gRPC port on the internal network - so that the **Defguard Core can connect to this port - more details here:** [**https://docs.defguard.net/1.5/deployment-strategies/configuration#proxy-service**](https://docs.defguard.net/1.5/deployment-strategies/configuration#proxy-service)

### Core

1. please open 443 port for web interface accessible only from local/VPN network
2. please open a gRPC port **for the gateway server to connect to this port - more info here:** [**https://docs.defguard.net/deployment-strategies/configuration#grpc-server-configuration**](https://docs.defguard.net/deployment-strategies/configuration#grpc-server-configuration)


# Standalone package based installation

## Introduction

This guide will walk you through the process of installing and running Debian packages (.deb) for **core, gateway, proxy** services on one server - as a **simple example**.

{% hint style="warning" %}
For production deployment we would recommend to divide services to multiple servers, e.g.:

* Defguard Proxy (used for remote enrollment, onboarding and configuring desktop clients) should be on a DMZ node that is exposed in the Internet
* Defguard Gateway should be on your firewall/router
* Defguard Core (the main control plain panel) - should be in internal network (intranet) and available only by intranet or VPN itself.
  {% endhint %}

We will cover system requirements, additional dependencies, installation steps, and examples of configuration files and step by step running all services. In this example we will use nginx for a web server (proxy) exposing and securing web based services.

Examples will be made by using [**Debian 12**](https://www.debian.org/releases/stable/releasenotes) **and Ubuntu based system.**

{% hint style="info" %}
We also provide **RPM packages** - the procedure is similar to the one for installing DEB packages. If you need help installing RPM packages[ this guide offers help.](https://phoenixnap.com/kb/how-to-install-rpm-file-centos-linux)
{% endhint %}

Please also remember to [secure the setup after installation](#securing-the-setup).

### Hardware Requirements

All Defguard components are **very low resource-consuming**. All of them are written in [Rust](https://www.rust-lang.org) and are single binaries. As minimum setup as follows should be more then enough:

| Resource     | Minimum requirements         |
| ------------ | ---------------------------- |
| CPU          | 1 GHz                        |
| RAM          | 2 GB (mostly for PostgreSQL) |
| Disk         | 2 GB                         |
| Architecture | x86\_64, ARM64               |

### System Requirements

Before proceeding with the installation, ensure your system meets the following requirements:

* Debian-based operating system (Debian, Ubuntu, etc.).
* Administrative (sudo) privileges.
* A server with a public IP address (and you know what that IP address is and to which interface it's assigned) - in this example we use: 185.33.37.51.
* You have a domain name and know how to assign IP and manage subdomains, in our example: Defguard main url will be *my-server.defguard.net* (and the subdomain is pointed to 185.33.37.51).
* Defguard [enrollment service](https://defguard.gitbook.io/defguard/help/enrollment) (run by proxy) that will enable [remote onboarding, enrollment](https://defguard.gitbook.io/defguard/help/enrollment) and [easy configuration for our Desktop Clients (by adding Defguard instances)](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration#adding-instance) with instance URL and one simple token - in this tutorial we use: *enroll.defguard.net* (this subdomain also points to 185.33.37.51).
* If you have a **firewall**, we assume you have **open port 443** in order to expose both Defguard and enrollment service, but also to automatically issue for these domains SSL Certificates. Port 444 (used for internal GRPC communication) **should not be exposed public.**
* System clock is synchronized using Network Time Protocol (NTP). This is important for time-based one-time password (TOTP) codes.

### Prerequisites

#### PostgreSQL

Defguard Core uses [PostgreSQL](https://www.postgresql.org) database, so if you do not have installed and configured yet, you can do it in this section. For this tutorial we need to create **a user with superuser privileges and database**.

First of all, install PostgreSQL package:

```
apt install postgresql
```

Now you can launch a default user and create a new superuser for your database. We create user, password and database with name `defguard`, beacuse this is by default in `/etc/defguard/core.conf`, you can change whatever you want.

```
# su -c /usr/bin/psql postgres
postgres=# CREATE USER defguard WITH SUPERUSER PASSWORD 'defguard';
postgres=# CREATE DATABASE defguard;
```

After creating a user and database we can connect our new user to this database. To make it easier to connect now and then, we could try to add auth file

```
# echo 'localhost:5432:defguard:defguard:defguard' >> ~/.pgpass
# chmod 600 ~/.pgpass
# psql -d defguard -h localhost -U defguard
defguard=# exit
```

* we created `.pgpass` file that consist of `<hostname>:<port>:<database>:<user>:<password>`
* we connected into the `defguard` database to verify `defguard` user can communicate with the database

#### NGINX

To expose our services in the server we need to configure a reverse proxy server. For this we will use nginx web server with ssl certificates for enabling https protocol.

To get started, we need to install:

```
apt install nginx certbot
```

Enable nginx service

```
systemctl enable nginx.service
systemctl start nginx.service
```

Disable all default domains:

```
unlink /etc/nginx/sites-enabled/default
```

## Installing packages

### Core service

Navigate to [core repository release](https://github.com/DefGuard/defguard/releases) and choose version of core package that you want to obtain that has debian package and then swap `<version>` in the following command:

```
wget https://github.com/DefGuard/defguard/releases/download/<version>/defguard-<version>-x86_64-unknown-linux-gnu.deb
```

Example:

```
wget https://github.com/DefGuard/defguard/releases/download/v0.11.0/defguard-0.11.0-x86_64-unknown-linux-gnu.deb
```

You can also download directly from the Github realse page, but please note that you should know the path where this could be storead after downloading. Once the package is downloaded, install it using dpkg:

```
dpkg -i <path_to_package>/defguard-<version>-x86_64-unknown-linux-gnu.deb
```

Example:

```
dpkg -i defguard-0.11.0-x86_64-unknown-linux-gnu.deb
```

You can check is core installed properly:

```
# defguard -V
defguard 0.11.0
```

### Gateway service

Navigate to [gateway repository release](https://github.com/DefGuard/gateway/releases) and choose version of core package that you want to obtain that has debian package and then swap `<version>` in the following command:

```
# wget https://github.com/DefGuard/gateway/releases/download/<version>/defguard-gateway_<version>_x86_64-unknown-linux-gnu.deb
```

Example:

```
# wget https://github.com/DefGuard/gateway/releases/download/v0.7.0/defguard-gateway_0.7.0_x86_64-unknown-linux-gnu.deb
```

You can also download directly from the Github realse page, but please note that you should know the path where this could be storead after downloading. Once the package is downloaded, install it using dpkg:

```
dpkg -i <path_to_package>/defguard-gateway_<version>_x86_64-unknown-linux-gnu.deb
```

Example:

```
dpkg -i defguard-gateway_0.7.0_x86_64-unknown-linux-gnu.deb
```

You can check is core installed properly:

```
# defguard-gateway -V
defguard-gateway 0.7.0
```

### Proxy service

Navigate to [proxy repository release](https://github.com/DefGuard/proxy/releases) and choose version of core package that you want to obtain that has debian package and then swap `<version>` in the following command:

```
wget https://github.com/DefGuard/proxy/releases/download/<version>>/defguard-proxy-<version>-x86_64-unknown-linux-gnu.deb
```

Example:

```
wget https://github.com/DefGuard/proxy/releases/download/v0.5.0/defguard-proxy-0.5.0-x86_64-unknown-linux-gnu.deb
```

You can also download directly from the Github realse page, but please note that you should know the path where this could be storead after downloading. Once the package is downloaded, install it using dpkg:

```
dpkg -i <path_to_package>/defguard-proxy-<version>-x86_64-unknown-linux-gnu.deb
```

Example:

```
dpkg -i defguard-proxy-0.5.0-x86_64-unknown-linux-gnu.deb
```

You can check is core installed properly:

```
# defguard-proxy -V
defguard-proxy 0.5.0
```

## Running Defguard

### Generating SSL Certificates with Let'sEncrypt

Before we run Defguard and configure the reverse proxy, first let's prepare SSL certificates that will be used by the NGINX service. We will generate a certificate for two domains we use in this example: *my-service.defguard.net* and *enroll.defguard.net*:

```
certbot certonly --non-interactive --agree-tos --standalone --email admin@teonite.com -d my-server.defguard.net -d enroll.defgurd.net
```

Certbot will generate certificate in fullchain.pem and privkey.pem in path:

`/etc/letsencrypt/live/my-server.defguard.net`

`/etc/letsencrypt/live/enrolldefguard.net`

### Core - the control plain

To run core service we need to configure `/etc/defguard/core.conf`.

{% hint style="info" %}
To generate any secret (which **we recommend to be 64 chars)**, use the following command:

`openssl rand -base64 55 | tr -d "=+/" | tr -d '\n' | cut -c1-64`
{% endhint %}

As previously mentioned, in this tutorial we wil use server domain `my-server.defguard.net`.

Example `/etc/defguard/core.conf`:

```
### Core configuration ###

#
# Generate secrets
#
DEFGUARD_AUTH_SECRET=defguard-auth-secret
DEFGUARD_GATEWAY_SECRET=defguard-gateway-secret
DEFGUARD_YUBIBRIDGE_SECRET=defguard-yubibridge-secret
DEFGUARD_SECRET_KEY=9oZqdHRCN0TWIyMhjYOAYwgzVz9IfOqz62PzUvjvyMzqLICGSM3b0pRMdDH300CQ

# Define the URL under which Defguard is running:
DEFGUARD_URL=https://my-server.defguard.net

# How long auth session lives in seconds
DEFGUARD_AUTH_SESSION_LIFETIME=604800

# Optional. Generated based on DEFGUARD_URL if not provided.
# DEFGUARD_WEBAUTHN_RP_ID=localhost

DEFGUARD_ADMIN_GROUPNAME=admin
DEFGUARD_DEFAULT_ADMIN_PASSWORD=pass123

# This will be displayed in the network settings when editing/adding a new location:
DEFGUARD_GRPC_URL=https://my-server.defguard.net:444

### Proxy configuration ###
# Proxy is optional - if you would like to use the remote enrollment
# and onboarding service, as well as easy desktop client configuration
# proxy must be enabled.
# For now we leave it uncofigured, will configure it in next step.
# DEFGUARD_PROXY_URL=http://localhost:50051

### LDAP configuration ###
# DEFGUARD_LDAP_URL=ldap://localhost:389
# DEFGUARD_LDAP_SERVICE_PASSWORD=adminpassword
# DEFGUARD_LDAP_USER_SEARCH_BASE="ou=users,dc=example,dc=org"
# DEFGUARD_LDAP_GROUP_SEARCH_BASE="ou=groups,dc=example,dc=org"
# DEFGUARD_LDAP_DEVICE_SEARCH_BASE="ou=devices,dc=example,dc=org"

### DB configuration ###
DEFGUARD_DB_HOST="localhost"
DEFGUARD_DB_PORT=5432
DEFGUARD_DB_NAME="defguard"
DEFGUARD_DB_USER="defguard"
DEFGUARD_DB_PASSWORD="defguard"
# for SQLX CLI
DATABASE_URL="postgresql://defguard:defguard@localhost/defguard"
```

**If you have configured your postgres with different names than in** [**PostgreSQL guide**](#postgresql)**, you can change it in DB configuration part. LDAP configuration is not part of this tutorial, you can also commented those lines.**

**We will back to this configuration to connect Defguard core with proxy in the** [**Run proxy**](#run-proxy) **section. For now `DEFGUARD_PROXY_URL` is commented.**

After changes, you can simply enable and start your Defguard core service:

```
systemctl enable defguard.service
systemctl start defguard.service
```

To see logs, type journalctl command:

```
# journalctl -u defguard.service | tail -n 50
Jul 29 13:57:15 defguard-testing systemd[1]: Started defguard.service - Defguard core service.
Jul 29 13:57:15 defguard-testing defguard[2776504]: 2024-07-29T11:57:15.738420Z  INFO defguard: Starting defguard
Jul 29 13:57:15 defguard-testing defguard[2776504]: 2024-07-29T11:57:15.743079Z  INFO defguard::db: Initializing DB pool
Jul 29 13:57:16 defguard-testing defguard[2776504]: 2024-07-29T11:57:16.297407Z  INFO defguard: Using HMAC OpenID signing key
Jul 29 13:57:19 defguard-testing defguard[2776504]: 2024-07-29T11:57:19.156559Z  INFO defguard::db::models::user: Initializing admin user
Jul 29 13:57:19 defguard-testing defguard[2776504]: 2024-07-29T11:57:19.595218Z  INFO defguard::db::models::user: New admin user has been created, adding to Admin group...
Jul 29 13:57:19 defguard-testing defguard[2776504]: 2024-07-29T11:57:19.747717Z  INFO defguard::db::models::settings: Initializing default settings
Jul 29 13:57:19 defguard-testing defguard[2776504]: 2024-07-29T11:57:19.780563Z  INFO defguard: Started web services
```

#### Configuring NGINX reverse proxy with SSL

Now, we are able to create our first nginx config for Defguard core service with *my-server.defguard.net*.

Create config file `/etc/nginx/site-available/my-server.defguard.net.conf`, example config file for *my-server.defguard.ent* should look like this:

```
upstream defguard {
	server 127.0.0.1:8000;
}

upstream defguard-grpc {
	server 127.0.0.1:50055;
}

server {
	listen 443 ssl http2;
	server_name my-server.defguard.net;
	access_log /var/log/nginx/defguard.log;
	error_log /var/log/nginx/defguard.e.log;

	ssl_certificate /etc/letsencrypt/live/my-server.defguard.net/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/my-server.defguard.net/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/my-server.defguard.net/fullchain.pem;

	client_max_body_size 128M;

	location / {
		proxy_pass		http://defguard;
		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_http_version	1.1;
		proxy_set_header	Upgrade		$http_upgrade;
		proxy_set_header	Connection	"upgrade";
	}
}

server {
	listen 444 ssl http2;
	server_name my-server.defguard.net;
	access_log /var/log/nginx/defguard-grpc.log;
	error_log /var/log/nginx/defguard-grpc.e.log;

	ssl_certificate /etc/letsencrypt/live/my-server.defguard.net/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/my-server.defguard.net/privkey.pem;

	client_max_body_size 200m;

	location / {
		grpc_pass grpc://defguard-grpc;
	}
}
```

Link it to `/etc/nginx/site-available/`

```
ln -s /etc/nginx/sites-available/my-server.defguard.net.conf /etc/nginx/sites-enabled/my-server.defguard.net.conf
```

Restart nginx.service to activate changes:

```
systemctl reload nginx.service
```

Test your domain on another terminal tab

```
$ curl https://my-server.defguard.net/api/v1/health
alive
```

Success! We can move on to the next service.

{% hint style="danger" %}
If you use this simple setup and run all services on one server, you can use [NGINX access restrictions](https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-tcp/) for securing core and allowing to access the *my-server.defguard.net* only to selected networks - blocking the direct access from the Internet.
{% endhint %}

### Gateway - the WireGuard VPN service

To run gateway, we should do two things:

* setup our first location on <https://my-server.defguard.net> page to get `token` and `grpc_url` for gateway service,
* configure `/etc/defguard/gateway.toml`.

#### Setup location for gateway

Now, after setting up core service you should go to the website that you set on `DEFGUARD_URL`. The link should redirect you to login page. To log in type these credentials from `/etc/defguard/core.conf`

* login: admin
* password: `DEFGUARD_DEFAULT_ADMIN_PASSWORD` (by default: pass123)

Now we can configure our first location. Depends on what is more convenient for you, choose configuration from Wireguard file or do it manually.

<figure><img src="/files/o7BxhbRHQYG5OFnp7ctB" alt=""><figcaption><p>Location wizard</p></figcaption></figure>

<figure><img src="/files/xIUoiRyZ5bwOieiIA4Lk" alt=""><figcaption><p>Location configuration</p></figcaption></figure>

After saving configuration for location you should be redirect to Location overview page, where at the top right corner is `Edit Locations Settings` button, click on it.

<figure><img src="/files/N1e8bxxHY2jY9Rw6Fg1L" alt=""><figcaption><p>Manual configuration</p></figcaption></figure>

In `Gateway server setup` copy two variables: `DEFGUARD_TOKEN` and `DEFGUARD_GRPC_URL`

<figure><img src="/files/FgxB23PoFItwymQj1Nf2" alt=""><figcaption><p>Gateway server setup</p></figcaption></figure>

#### Create config file

After getting `DEFGUARD_TOKEN` and `DEFGUARD_GRPC_URL` variables, we can configure our gateway service. Create config.toml file and swap `<your_gateway_token>` and `<defguard_grpc_url>` with your values that you copied.

Template for configure gateway service looks like below:

```
# This is an example config file for Defguard VPN gateway
# To use it fill in actual values for your deployment below

# Required: secret token generated by defguard
# NOTE: must replace default with actual value
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJEZWZHdWFyZCIsInN1YiI6IkRFRkdVQVJELU5FVFdPUkstMSIsImNsaWVudF9pZCI6IjEiLCJleHAiOjYwMTczODM0MjQsIm5iZiI6MTcyMjQxNjEyOX0.HP-9ArvdXuyeBxRdQ6S_wJb3rBTq73J0sVyfwuPM-vY"
# Required: Defguard server gRPC endpoint URL
# NOTE: must replace default with actual value
grpc_url = "https://my-server.defguard.net:444/"
# Optional: gateway name which will be displayed in Defguard web UI
name = "Gateway A"
# Required: use userspace WireGuard implementation (e.g. wireguard-go)
userspace = false
# Optional: path to TLS cert file
# grpc_ca = cert.pem
# Required: how often should interface stat updates be sent to Defguard server (in seconds)
stats_period = 60
# Required: name of WireGuard interface
ifname = "wg0"
# Optional: write PID to this file
# pidfile = defguard-gateway.pid
# Required: enable logging to syslog
use_syslog = false
# Required: which syslog facility to use
syslog_facility = "LOG_USER"
# Required: which socket to use for logging
syslog_socket = "/var/run/log"

# Optional: Command which will be run before bringing interface up
# Example: Allow all traffic through WireGuard interface:
#pre_up = "/path/to/iptables -A INPUT -i wg0 -j ACCEPT
# example with multiple commands - add them to a shell script
#pre_up = "/path/to/shell /path/to/script"

# Optional: Command which will be run after bringing interface up
# Example: Add a default route after WireGuard interface is up:
#post_up = "/path/to/ip route add default via 192.168.1.1 dev wg0"


# Optional: Command which will be run before bringing interface down
# Example: Remove WireGuard-related firewall rules before interface is taken down:
#pre_down = "/path/to/iptables -D INPUT -i wg0 -j ACCEPT"

# Optional: Command which will be run after bringing interface down
# Example: Remove the default route after WireGuard interface is down:
#post_down = "/pat/to/ip route del default via 192.168.1.1 dev wg0"

# A HTTP port that will expose the REST HTTP gateway health status
# STATUS CODES:
# 200 - Gateway is working and is connected to CORE
# 503 - gateway works but is not connected to CORE
#health_port = 55003
```

Now we can run gateway service with configuration above:

```
# systemctl enable defguard-gateway.service
# systemctl start defguard-gateway.service
# journalctl -u defguard-gateway.service | tail -n 50
[2024-07-27T16:37:56Z INFO  defguard_gateway::gateway] Starting defguard gateway version 0.7.0 with configuration: Config { token: "***", name: Some("Gateway on server X"), grpc_url: "https://my-server.defguard.net:444/", userspace: false, grpc_ca: None, stats_period: 60, ifname: "wg0", pidfile: None, use_syslog: false, syslog_facility: "LOG_USER", syslog_socket: "/var/run/log", config_path: None, pre_up: None, post_up: None, pre_down: None, post_down: None, health_port: None }
[2024-07-27T16:37:56Z INFO  defguard_gateway::gateway] gRPC server connection setup done.
[2024-07-27T16:37:56Z INFO  defguard_wireguard_rs::wgapi_linux] Creating interface wg0
[2024-07-27T16:37:56Z INFO  defguard_wireguard_rs::wgapi_linux] Configuring interface wg0 with config: InterfaceConfiguration { name: "Szczecin", address: "10.22.33.1/24", port: 50051, peers: [], mtu: None, .. }
[2024-07-27T16:37:56Z WARN  netlink_packet_route::link::buffer_tool] Specified IFLA_INET6_STATS NLA attribute holds more(most likely new kernel) data which is unknown to netlink-packet-route crate, expecting 288, got 296
[2024-07-27T16:37:56Z WARN  netlink_packet_route::link::buffer_tool] Specified IFLA_INET6_STATS NLA attribute holds more(most likely new kernel) data which is unknown to netlink-packet-route crate, expecting 288, got 296
[2024-07-27T16:37:56Z INFO  defguard_gateway::gateway] Reconfigured WireGuard interface Szczecin (address: 10.0.0.1/24)
[2024-07-27T16:37:56Z INFO  defguard_gateway::gateway] Stats thread spawned.
[2024-07-27T16:37:56Z INFO  defguard_gateway::gateway] Connected to defguard gRPC endpoint: https://my-server.defguard.net:444/
```

On the other side, core service should print those informations:

```
2024-07-27T16:37:56.379227Z  INFO defguard::grpc: Adding gateway user with to gateway map for network 1
2024-07-27T16:37:56.385951Z  INFO defguard::grpc::gateway: Configuration sent to gateway client, network [ID 1] Szczecin.
2024-07-27T16:37:56.388651Z  INFO defguard::grpc::gateway: New client connected to updates stream: user, network [ID 1] Szczecin
2024-07-27T16:37:56.388695Z  INFO defguard::grpc: Gateway user connected in network 1
2024-07-27T16:37:56.388810Z  INFO defguard::grpc::gateway: Starting update stream to gateway: user, network [ID 1] Szczecin
```

### Proxy - enrollment, onboardin and desktop configuration service

To run proxy service (for [remote onboarding & enrollment](/1.4/using-defguard-for-end-users/enrollment)), we can do it by:

```
# systemctl enable defguard-proxy.service
# systemctl start defguard-proxy.service
# journalctl -u defguard-proxy.service | tail -n 50
2024-07-27T16:53:58.584154Z INFO defguard_proxy::tracing: Tracing initialized
2024-07-27T16:53:58.584233Z INFO defguard_proxy::http: Starting Defguard proxy server
2024-07-27T16:53:58.584371Z INFO defguard_proxy::http: Skipping rate limiter setup
2024-07-27T16:53:58.584438Z INFO defguard_proxy::http: gRPC server is listening on 0.0.0.0:50051
2024-07-27T16:53:58.585125Z INFO defguard_proxy::http: Defguard proxy server initialization complete
2024-07-27T16:53:58.585262Z INFO defguard_proxy::http: API web server is listening on 0.0.0.0:8080
```

#### Configuring NGiNX reverse proxy for enrollment

{% hint style="info" %}
Please note that [we already have issued the enrollemnt domain SSL certificate](#generating-ssl-certificates).
{% endhint %}

Create config file `/etc/nginx/sites-available/enroll.defguard.net.conf`, example config file for *enroll.defguard.net* should look like this:

```
upstream defguard-proxy {
	server 127.0.0.1:8080;
}

upstream proxy-grpc {
	server 127.0.0.1:50051;
}

server {
	listen 443 ssl http2;
	server_name enroll.defguard.net;
	access_log /var/log/nginx/enroll.log;
	error_log /var/log/nginx/enroll.e.log;

	ssl_certificate /etc/letsencrypt/live/my-server.defguard.net/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/my-server.defguard.net/privkey.pem;

	client_max_body_size 200m;

	location / {
		proxy_pass 		http://defguard-proxy;
		proxy_set_header	Host		$host;
		proxy_set_header	X-Real-IP	$remote_addr;
		proxy_set_header	X-Forwarded-For	$proxy_add_x_forwarded_for;
	}
}

server {
	listen 444 ssl http2;
	server_name enroll.defguard.net;
	access_log /var/log/nginx/enroll.log;
	error_log /var/log/nginx/enroll.e.log;

	ssl_certificate /etc/letsencrypt/live/my-server.defguard.net/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/my-server.defguard.net/privkey.pem;

	client_max_body_size 200m;

	location / {
		grpc_pass grpc://proxy-grpc;
		grpc_socket_keepalive on;
		grpc_read_timeout 3000s;
		grpc_send_timeout 3000s;
		grpc_next_upstream_timeout 0;

		proxy_request_buffering off;
		proxy_buffering off;
		proxy_connect_timeout 3000s;
		proxy_send_timeout 3000s;
		proxy_read_timeout 3000s;
		proxy_socket_keepalive on;

		keepalive_timeout 90s;
		send_timeout 90s;

		client_body_timeout 3000s;
	}
}
```

Enable configuration and restart nginx:

```
ln -s /etc/nginx/sites-available/enroll.defguard.conf /etc/nginx/sites-enabled/enroll.defguard.conf
systemctl restart nginx.service
```

#### Enabling Proxy service in the Core

Now, we can update our **core configuration** in `/etc/defguard/core.conf` by uncommenting `DEFGUARD_PROXY_URL`

```
# Proxy connection configuration
DEFGUARD_PROXY_URL=https://enroll.defguard.net:444
```

Full `/etc/defguard/core.conf`:

```
### Core configuration ###

#
# Generate secrets
#
DEFGUARD_AUTH_SECRET=defguard-auth-secret
DEFGUARD_GATEWAY_SECRET=defguard-gateway-secret
DEFGUARD_YUBIBRIDGE_SECRET=defguard-yubibridge-secret
DEFGUARD_SECRET_KEY=9oZqdHRCN0TWIyMhjYOAYwgzVz9IfOqz62PzUvjvyMzqLICGSM3b0pRMdDH300CQ

# Define the URL under which Defguard is running:
DEFGUARD_URL=https://my-server.defguard.net

# How long auth session lives in seconds
DEFGUARD_AUTH_SESSION_LIFETIME=604800

# Optional. Generated based on DEFGUARD_URL if not provided.
# DEFGUARD_WEBAUTHN_RP_ID=localhost

DEFGUARD_ADMIN_GROUPNAME=admin
DEFGUARD_DEFAULT_ADMIN_PASSWORD=pass123

# This will be displayed in the network settings when editing/adding a new location:
DEFGUARD_GRPC_URL=https://my-server.defguard.net:444

### Proxy configuration ###
# Proxy is optional - if you would like to use the remote enrollment
# and onboarding service, as well as easy desktop client configuration
# proxy must be enabled.

# PROXY configuration:
DEFGUARD_PROXY_URL=https://enroll.defguard.net:444 # add this line to your config file

### LDAP configuration ###
# DEFGUARD_LDAP_URL=ldap://localhost:389
# DEFGUARD_LDAP_SERVICE_PASSWORD=adminpassword
# DEFGUARD_LDAP_USER_SEARCH_BASE="ou=users,dc=example,dc=org"
# DEFGUARD_LDAP_GROUP_SEARCH_BASE="ou=groups,dc=example,dc=org"
# DEFGUARD_LDAP_DEVICE_SEARCH_BASE="ou=devices,dc=example,dc=org"

### DB configuration ###
DEFGUARD_DB_HOST="localhost"
DEFGUARD_DB_PORT=5432
DEFGUARD_DB_NAME="defguard"
DEFGUARD_DB_USER="defguard"
DEFGUARD_DB_PASSWORD="defguard"
# for SQLX CLI
DATABASE_URL="postgresql://defguard:defguard@localhost/defguard"
```

Reload changes in `/etc/defguarc/core.conf`

```
systemctl restart defguard.service
```

{% hint style="success" %}
Now you have full working Defguard services 🥳
{% endhint %}

You can [configure your desktop client using the enrollment](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration#adding-instance) service and use your VPN.

If you would like to use the feature in the desktop client to route **All traffic** through the VPN please configure your firewall to enable Internet access through your VPN - [here you can find exaples how to do it](https://defguard.gitbook.io/defguard/tutorials/step-by-step-setting-up-a-vpn-server#enabling-to-access-internet-through-your-vpn).

## Securing the setup

After the installation please make sure that **only the following ports are open on the server firewall:**

* HTTPS port for the proxy (and/or the Defguard core if you want it to be public)
* VPN server port (eg. WireGuard port)

{% hint style="danger" %}
**DO NOT EXPOSE PUBLICLY THE gRPC ports of the core gateway and proxy, which are:**

* 444
* 50051
* 50055
  {% endhint %}

Also this setup provides only communication encryption between Defguard components, if you additionally like for core/proxy and gateway to have authorization - [please setup a custom SSL CA](/1.4/deployment-strategies/grpc-ssl-communication#custom-ssl-ca-and-certificates).


# Docker images and tags

All docker images for gateway, core, and proxy have these additional tags:

* `latest` - this tag is for the latest production release - aka `vX.Y.Z` from the `main` branch
* `pre-release`- this tag is for the latest pre-production release - aka `vX.Y.Z-alpha/beta/rcX` from the `main` branch
* `dev` - this tag is for the latest development release from the `dev` branch.


# Docker Compose

Here are basic and simple docker-compose configuration files that will enable you to quickly deploy your own instance manually. We also assume in this example, that all services will be deployed on dedicated servers/VMs - separating them physically, thus each compose is for a separate service.

{% hint style="success" %}
Please not that we also offer docker-compose deployment with [*one-line quick deployment*](/1.4/getting-started/one-line-install)*,* but this method is recommended for PoC/quick deployment as **it launches everything on one server and all services in one docker compose**.
{% endhint %}

We use "latest" (latest production images) tags in the examples below, but you can use others - [more info here](/1.4/deployment-strategies/docker-images-and-tags).

## Core

Here is the docker-compose.yaml for the core and database. Configuration is split to the `.env` file (see below):

```
services:
  core:
    image: ghcr.io/defguard/defguard:latest
    restart: always
    container_name: "defguard"
    env_file: .env
    ports:
      # HTTP port - open on localhost, should be secured by reverse-proxy
      - "127.0.0.1:8000:8000"
      # gRPC port for gateway to connect to
      # open on all interfaces/IPs - whould be secured with custom CA (see .env)
      - "50055:50055"
    depends_on:
      - db
    volumes:
      # more info here:
      # https://docs.defguard.net/deployment-strategies/openid-rsa-key
      - ./rsakey.pem:/keys/rsakey.pem
      # more info about custom CA here:
      # https://docs.defguard.net/deployment-strategies/grpc-ssl-communication#custom-ssl-ca-and-certificates
      - ./ca.pem:/keys/ca.pem

  db:
    image: postgres:17-alpine
    container_name: "defguard-db"
    env_file: .env
    volumes:
      - db:/var/lib/postgresql/data
```

#### NGINX reverse-proxy

Now that you have core running, here is an example NGINX configuration to provide SSL termination:

```
upstream  defguard {
    server 127.0.0.1:8000;
}

server {
    listen 443 ssl http2;

    # your domain
    server_name defguard.secure-internal.net;

    access_log /var/log/nginx/defguard.log;
    error_log /var/log/nginx/defguard.error.log;

    ssl on;
    # we assume you already have Let'sEncrypt SSL certificates
    # for your domain
    ssl_certificate /etc/letsencrypt/live/secure-internal.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/secure-internal.net/privkey.pem;

    client_max_body_size 20m;

    location / {
        proxy_connect_timeout 300;
        proxy_pass http://defguard;
        proxy_set_header Connection "upgrade";
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Forwarded-for $remote_addr;
    }
}
```

### The configuration

Here is the `.env` file with all configuration variables:

```
# please generate each secret with:
# openssl rand -base64 55 | tr -d "=+/" | tr -d '\n' | cut -c1-63
DEFGUARD_SECRET_KEY=
DEFGUARD_AUTH_SECRET=
DEFGUARD_GATEWAY_SECRET=
DEFGUARD_YUBIBRIDGE_SECRET=

# if you plan to reverse-proxy defguard, please provide a full URL
# this URL will be shared in emails, enrollement messages, etc.:
DEFGUARD_URL=https://defguard.secure-internal.net
# Must be an effective domain of DEFGUARD_URL
# Changing DEFGUARD_WEBAUTHN_RP_ID will potentially break all your existing
# Webauthn credentials.
DEFGUARD_WEBAUTHN_RP_ID=defguard.secure-internal.net

# accepted: info/debug/warning/error
DEFGUARD_LOG_LEVEL=info

# more info about custom CA here:
# https://docs.defguard.net/deployment-strategies/grpc-ssl-communication#custom-ssl-ca-and-certificates
DEFGUARD_PROXY_GRPC_CA=/keys/ca.pem
# gRPC URL of proxy (see proxy config)
DEFGUARD_PROXY_URL=https://proxy.host:50051
# more details about RSA key here:
# https://docs.defguard.net/deployment-strategies/openid-rsa-key
DEFGUARD_OPENID_KEY=rsakey.pem

# the URL of your proxy - will be displayed during enrollment, email
# messages or desktop client configuration
DEFGUARD_ENROLLMENT_URL=https://enrollment.public.net

# PostgreSQL database configuration for core
DEFGUARD_DB_HOST=db
DEFGUARD_DB_PORT=5432
DEFGUARD_DB_USER=defguard
# please generate password:
# openssl rand -base64 55 | tr -d "=+/" | tr -d '\n' | cut -c1-63
DEFGUARD_DB_PASSWORD=
DEFGUARD_DB_NAME=defguard

# database configuration for "db" container
# must be same as above
# database will be initialized with these values (the user/pass set here)
POSTGRES_DB=defguard
POSTGRES_USER=defguard
POSTGRES_PASSWORD=!SAME_AS-GENERATED-DEFGUARD_DB_PASSWORD!
```

## Proxy

Here is the docker-compose.yaml for the public proxy (enrollment service as well as desktop client configuration service).

To secure the gRPC communication, please generate the proxy CA and certificate, [more info here](/1.4/deployment-strategies/grpc-ssl-communication#custom-ssl-ca-and-certificates).

```
proxy:
  image: ghcr.io/defguard/defguard-proxy:latest
  restart: unless-stopped
  ports:
     # HTTP port - should be secured by reverse proxy
     - "127.0.0.1:8080:8080"
     - "50051:50051"
  environment:
     # path in the volume to custom proxy cert & key
     - DEFGUARD_PROXY_GRPC_CERT=ca/proxy.crt
     - DEFGUARD_PROXY_GRPC_KEY=ca/proxy.key     
  volumes:
     - ./ca/proxy.crt:ca/proxy.crt
     - ./ca/proxy.key:ca/proxy.key
  
```

#### NGINX reverse-proxy

Now that you have proxy running, here is an example NGINX configuration to provide SSL termination:

```
upstream  defguard-proxy  {
	server   127.0.0.1:8080;
}

server {
	listen 443 http2;
	server_name enrollment.public.net;
	access_log /var/log/nginx/defguard-proxy.log;
	error_log /var/log/nginx/defguard-proxy.error.log;

        # we assume you already have Let'sEncrypt SSL certificates
        # for your domain
	ssl_certificate /etc/letsencrypt/live/public.net/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/public.net/privkey.pem;

	client_max_body_size 20m;

        location / {
            proxy_pass         http://defguard-proxy;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
}

```

## Gateway

For gateway to control the WireGuard kernel as well as network, it's recommended to run in the *host* network mode as well as there are needed some docker CAPs:

```
services:
  gateway: 
    image: ghcr.io/defguard/gateway:latest 
    restart: unless-stopped 
    network_mode: "host" 
    environment: 
      - DEFGUARD_GRPC_URL=https://core-ip:50055
      - DEFGUARD_GRPC_CA=/ca.pem
      - DEFGUARD_STATS_PERIOD=30
      # to get the token add a VPN location and get the token
      - DEFGUARD_TOKEN=tokenFromCoreLocation
      - DEFGUARD_GATEWAY_NAME=willBeVisibleInDefguardAsGWName
    volumes:
      # more info about custom CA here:
      # https://docs.defguard.net/deployment-strategies/grpc-ssl-communication#custom-ssl-ca-and-certificates
      - ./ca.pem:/ca.pem
    cap_add: 
      - NET_ADMIN 
```


# Kubernetes

## Prerequisites

To deploy and use Defguard on your cluster, you'll need:

* A [Kubernetes cluster](https://kubernetes.io/docs/setup/)
* Kubernetes CLI [kubectl](https://kubernetes.io/docs/reference/kubectl/) installed on your machine
* Helm binary <https://github.com/helm/helm/releases/latest>

{% hint style="warning" %}
Our helm charts currently support only **Traefik ingress - which is relevant and affects exposing GRPC services (see below** `ingress.hosts.grpc`**`).`**
{% endhint %}

## Deployment

We prepared a [git repository](https://github.com/DefGuard/deployment) with Kubernetes configuration, clone it with:

```
git clone https://github.com/DefGuard/deployment.git && cd deployment/charts
```

Then create a namespace for Defguard on your cluster:

```
kubectl create namespace defguard
```

Copy and fill in values file:

```
cp defguard/values.yaml ./
```

Required values (the rest should work if left as-is):

* `ingress.hosts.grpc`: GRPC ingress address - GRPC clients like Defguard **gateway**, yubi-bridge

{% hint style="warning" %}
If you are configuring your gateway or yubi-bridge - please use this GRPC URL for communication.

If you have other ingress controller than traefik - you need to configure GRPC ingress manually with corresponding to your setup.
{% endhint %}

* `ingress.hosts.web`: Web ingress address - Defguard web app will be available here.
* `publicUrl`: Public URL your Defguard will be available under. Usually the same as ingress.hosts.web, but differs depending on your load balancer and/or reverse-proxy setup.

If you want to deploy the enrollment service along with your Defguard instance, you also need to configure values related to the `defguard-proxy`subchart:

* `defguard-proxy.enabled`: enable the enrollment service
* `proxyUrl`: proxy gRPC endpoint URL (based on `defguard-proxy.ingress.grpc.host`)
* `defguard-proxy.publicUrl`: public URL of the enrollment service
* `defguard-proxy.ingress.web.host`: enrollment service web ingress address (the enrollment website)
* `defguard-proxy.ingress.grpc.host`: enrollment service gRPC ingress address (for communicating with core)

And finally, install the Helm chart in the namespace:

```
helm install --wait=true --namespace defguard defguard defguard -f values.yaml
```


# Terraform

{% hint style="info" %}
Terraform deployment works with Defguard Core version 1.3.2-alpha2 and later.
{% endhint %}

{% hint style="info" %}
We've recently introduced this deployment method and are still actively improving it. If you encounter any issues or have suggestions, please open an issue in the [Defguard deployment repository](https://github.com/DefGuard/deployment/issues).
{% endhint %}

## AWS

To deploy Defguard using Terraform on AWS, you can use the Terraform configuration provided in the [Defguard deployment repository](https://github.com/DefGuard/deployment/tree/main).

The terraform configuration includes the necessary resources to setup all components of Defguard.

We recommend reading on the architecture of Defguard before proceeding with the deployment. You can find the documentation on the [Defguard architecture page](https://docs.defguard.net/in-depth/architecture). When configuring the networking, the most important thing is to keep in mind the following rules:

* Defguard Core web UI should be accessible only from the internal network or through a secure VPN connection.
* Defguard Proxy web UI should be publicly accessible, as it is used to securely pass messages to core from clients that are not connected to the VPN.
* Defguard Gateway UDP port should be publicly accessible, as clients use it to connect to the VPN.
* All gRPC traffic must stay internal. gRPC ports should only be available for the two parties that communicate with each other, e.g. core and proxy, or core and gateway.

### Using the Modules

To use the provided Terraform modules in your terraform configuration, you can use the following source:

```hcl
module "<MODULE_NAME>" {
  source = "github.com/DefGuard/deployment//terraform/modules/<MODULE>?ref=<REF>"

  # Rest of the module configuration goes here
  # ...
}
```

Where:

* `<MODULE_NAME>` is the name you want to give to the module in your configuration.
* `<MODULE>` is one of `core`, `proxy`, or `gateway`, depending on which module you want to use.
* `<REF>` is the commit hash, tag or branch name of the Defguard deployment repository. You can use the `main` branch for the latest stable version.

### Configuring modules

There are three Defguard modules available for deployment: `core`, `proxy` and `gateway`.

The modules can be found in the modules [directory](https://github.com/DefGuard/deployment/tree/main/terraform/modules) in the Defguard deployment repository.

#### Common configuration options for all modules

All components have common configuration options that may be configured in their respective blocks in the `main.tf` file:

* `instance_type`: The instance type to use. The default is `t3.micro`. You can adjust this based on your performance needs.
* `ami`: The base AMI to use for the Defguard instance. We recommend using the Ubuntu Server 24.04 LTS (64-bit) AMI, which is the default in the example configurations. You may change this to a different AMI if needed. Your AMI must meet the requirements defined in [AMI requirements](#ami-requirements).
* `package_version`: The version of the Defguard component package to be installed. This must be an existing Defguard debian package released on the Defguard releases page (e.g. Defguard Core packages are available [here](https://github.com/DefGuard/defguard/releases)). Example: `1.4.0`, `1.3.2-alpha2`.
* `arch`: The architecture of the Defguard Core package to be installed. This can be set to `x86_64` or `aarch64`. The default is `x86_64`.
* `log_level`: The log level to use for the Defguard component. This can be set to `trace`, `debug`, `info`, `warn`, or `error`. The default is `info`. Note that setting the log level to `debug` will produce a lot of logs, which may be useful for debugging, but may also fill up your disk space quickly.

#### Core module

The core module is responsible for setting up Defguard Core.

It accepts the following variables:

* `core_url`: The URL at which Defguard web UI will be accessible.
* `grpc_port`: The gRPC port for Defguard Core to communicate with gateways.
* `http_port`: The HTTP port on which the Defguard Core web server will listen. Note that setting port to `80` is not possible out of the box, as the Defguard service would require root privileges on the host machine, which it does not have by default.
* `cookie_insecure`: Set to `true` if you are using HTTP instead of HTTPS. This is not recommended for production environments.
* `default_admin_password`: The default password for the admin user. This should be changed after the first login.
* `proxy_grpc_port`: The gRPC port for Defguard Core to connect to the proxy. This must match the `grpc_port` variable in the proxy module.
* `proxy_url`: The URL at which Defguard Proxy will be accessible. This must match the `proxy_url` variable in the proxy module. This will be displayed to the user in the web UI when adding a new device.
* `vpn_networks`: A list of VPN networks that should be created. For every network, a new gateway will be created. See the [VPN networks configuration](#vpn-networks-configuration) section for more details on how to configure the VPN networks.
* `db_details`: A map containing the database configuration. It must contain the following:
  * `name`: The name of the PostgreSQL database to be created for Defguard.
  * `username`: The username for the PostgreSQL database.
  * `password`: The password for the PostgreSQL database user.
  * `port`: The port on which the PostgreSQL database will listen.
* `proxy_address`: The IP address of the Defguard Proxy instance. Ideally this should be a private address, as it will be used for internal communication between the core and proxy components.
* `gateway_secret`: The secret used to authenticate the gateways with the core. This should be a random string of 64 characters. It is used to ensure that only authorized gateways can connect to the core instance. This secret must match the secret provided in the `gateway_secret` variable in the gateway module.
* `network_interface_id`: The ID of the network interface that should be attached to the Defguard Core instance. This is used to ensure that the core instance has a private IP address in the same VPC as the proxy and gateways.

#### Proxy module

The proxy module is responsible for setting up the Defguard Proxy.

It accepts the following variables:

* `url`: The URL at which Defguard Proxy will be accessible.
* `grpc_port`: The gRPC port for Defguard Proxy to communicate with core. This is used only for internal communication.
* `http_port`: The HTTP port on which the Defguard Proxy web server will listen. Note that setting port to `80` is not possible out of the box, as the Defguard service would require root privileges on the host machine, which it does not have by default.

#### Gateway module

The gateway module is responsible for setting up the Defguard VPN gateways.

It accepts the following variables:

* `core_grpc_port`: The gRPC port of Defguard Core for the internal communication. This must match the `grpc_port` variable in the core module.
* `nat`: Whether to enable NAT for the VPN network. This will add a masquerading rule to the gateway's host and enable IP forwarding. For example, this allows:
  * VPN clients to access the internet through the gateway.
  * VPN clients to access other networks/hosts in your infrastructure, such as the Defguard Core.
* `network_id`: The ID of the VPN network. This must match the `id` field in the `vpn_networks` variable in the core module.
* `core_address`: The IP address of the Defguard Core instance. This should be core's private address, as it will be used for internal communication between the gateway and core components. See the `basic` example for the configuration of this variable.
* `gateway_secret`: The secret used to authenticate the gateway with the core. This should be a random string of 64 characters. It is used to ensure that only authorized gateways can connect to the core instance. This secret must match the secret provided in the `gateway_secret` variable in the core module.
* `network_interface_id`: The ID of the network interface that should be attached to the Defguard Gateway instance. This is used to ensure that the gateway instance has a private IP address in the same VPC as the core and proxy components.

#### VPN networks configuration

* `vpn_networks`: A list of VPN networks that should be created. For every network, a new gateway will be created.\
  Each network is defined as a map with the following keys:
  * `id`: The id of the network. Must start with 1 and increment for each new network. This is used to identify the network in the database and allows for applying modifications to the network configuration later.
  * `name`: The name of the VPN network. This will be used to identify the network in the Defguard web UI and displayed to the users.
  * `address`: The internal address of the VPN network in the form of `x.x.x.x/x`. This is the address that will be assigned to the VPN clients when they connect to the VPN. It must be a valid CIDR notation.
  * `port`: The port on which the VPN gateway will listen for incoming VPN connections. Default is `50051`, which is the standard port for WireGuard VPN. You may change this to a different port if needed.
  * `nat`: Whether to enable NAT for the VPN network. This will add a masquerading rule to the gateway's host and enable IP forwarding. For example, this allows:
    * VPN clients to access the internet through the gateway.
    * VPN clients to access other networks/hosts in your infrastructure, such as the Defguard Core

#### AMI requirements

If you wish to use a different AMI for the Defguard components, it must meet the following requirements:

* Must allow for running systemd services.
* Must use the APT package manager.

If you are not meeting these requirements, you will need to modify the corresponding `setup.sh` scripts, which are responsible for installing and configuring the Defguard components. The scripts can be found in `terraform/modules/<COMPONENT>/setup.sh`, where `<COMPONENT>` is one of `core`, `gateway`, or `proxy`.

### Examples

The example configurations can be downloaded from the Defguard deployment repository. They are located in the `terraform/examples` directory: (<https://github.com/DefGuard/deployment/tree/main/terraform)\\[https://github.com/DefGuard/deployment/tree/main/terraform>]

If you wish, you can also clone the whole repository using the following command:

```bash
git clone https://github.com/DefGuard/deployment.git
```

And then navigate to the `terraform/examples` directory to find the example configurations.

```bash
cd deployment/terraform
```

To use any of the examples, you can copy or download the `main.tf.example` file and rename it to `main.tf`. Note that the file contains both the module definitions, variables and outputs. This is to make it easier to download the example. You can also split the file into separate files, such as `main.tf`, `variables.tf`, and `outputs.tf`, if you prefer to keep the configuration more organized.

To run the examples, use the following commands:

```bash
# To initialize all the modules and providers, run:
terraform init

# To preview the changes that will be made, run:
terraform plan -var="aws_access_key=<YOUR_ACCESS_KEY>" -var="aws_secret_key=<YOUR_SECRET_KEY>"

# To apply the changes, run:
terraform apply -var="aws_access_key=<YOUR_ACCESS_KEY>" -var="aws_secret_key=<YOUR_SECRET_KEY>"
```

or if using OpenTofu:

```bash
# To initialize all the modules and providers, run:
tofu init

# To preview the changes that will be made, run:
tofu plan -var="aws_access_key=<YOUR_ACCESS_KEY>" -var="aws_secret_key=<YOUR_SECRET_KEY>"

# To apply the changes, run:
tofu apply -var="aws_access_key=<YOUR_ACCESS_KEY>" -var="aws_secret_key=<YOUR_SECRET_KEY>"
```

After running these commands, Terraform will create the necessary resources in your AWS account and deploy Defguard. The output will include the public and private addresses for Core, Proxy and gateway components:

```bash
Apply complete! Resources: 35 added, 0 changed, 0 destroyed.

Outputs:

defguard_core_private_address = "10.0.1.x"
defguard_core_public_address = "x.x.x.x"
defguard_proxy_private_address = "10.0.1.x"
defguard_proxy_public_address = "x.x.x.x"
defguard_gateway_private_addresses = [
  "10.0.1.226",
]
defguard_gateway_public_addresses = [
  "x.x.x.x",
]
```

Note that running the examples will put some sensitive details into your `.tfstate` file, most notably: the database password, gateway secret and the initial admin password. Those details are not ephemeral in the terraform configuration as they must be passed to the Defguard components during their setup. If you want to secure those details, we recommend following the official guidelines on [how to secure your Terraform state file](https://developer.hashicorp.com/terraform/language/state/sensitive-data).

#### `basic`

The `basic` example can be directly downloaded using the following link: [basic/main.tf.example](https://raw.githubusercontent.com/DefGuard/deployment/refs/heads/main/terraform/examples/basic/main.tf.example).

The example is a basic configuration that sets up all the components and a network that allows them to communicate with each other. It includes the following:

* Defguard Core instance
* Defguard Proxy instance
* Defguard Gateway instance
* A database instance (RDS) for Defguard Core.
* A single VPC for all components.

You can use this example as a starting point for your own deployment.

To modify the network configuration, edit one of the sections in the `main.tf` file, such as "Core network configuration", "Gateway network configuration", or "Proxy network configuration".

For example, to allow SSH access to Defguard Core instance, you can uncomment the following block in the "Core network configuration" section:

```hcl
ingress {
  from_port   = 22
  to_port     = 22
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
}
```

Note that this will grant SSH access from any IP address, you may want to restrict it further by editing the `cidr_blocks` field.

By default, the configuration allows access to Defguard Core web UI only from connected VPN clients, which is the recommended approach:

```hcl
ingress {
  from_port = local.core_http_port
  to_port   = local.core_http_port
  protocol  = "tcp"
  cidr_blocks = [
    for eip in aws_eip.defguard_gateway_endpoint : "${eip.public_ip}/32"
  ]
}
```

If you want to run Core web UI behind a reverse proxy (e.g. to enable HTTPS), you would need to do the following:

1. Prevent direct access to the services by removing their ingress rules:

```hcl
# This is in the Core security group block
[...]
ingress {
  from_port = local.core_http_port
  to_port   = local.core_http_port
  protocol  = "tcp"
  cidr_blocks = [
    for eip in aws_eip.defguard_gateway_endpoint : "${eip.public_ip}/32"
  ]
}

# This is in the Proxy security group block
[...]
ingress {
  from_port   = local.proxy_http_port
  to_port     = local.proxy_http_port
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
}
```

2. Add a second public subnet (load balancers require it):

```hcl
vpc_public_subnets = ["10.0.1.0/24", "10.0.4.0/24"]
```

3. Add the load balancer configuration

```hcl
###########################################################################
###################### Load Balancer Configuration #######################
###########################################################################

# Load balancer security groups
resource "aws_security_group" "defguard_alb_sg" {
  name        = "defguard-alb-sg"
  description = "Access to the Application Load Balancer"
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "HTTPS access from internet"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "defguard-alb-sg"
  }
}

resource "aws_security_group" "defguard_internal_alb_sg" {
  name        = "defguard-internal-alb-sg"
  description = "Access to the Internal Application Load Balancer"
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = [local.vpc_cidr]
    description = "HTTPS access from internal VPC network"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "defguard-internal-alb-sg"
  }
}

# Public Application Load Balancer
resource "aws_lb" "defguard_public_alb" {
  name               = "defguard-public-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.defguard_alb_sg.id]
  subnets            = module.vpc.public_subnets

  enable_deletion_protection = false

  tags = {
    Name = "defguard-public-alb"
  }
}

# Internal Application Load Balancer
resource "aws_lb" "defguard_internal_alb" {
  name               = "defguard-internal-alb"
  internal           = true
  load_balancer_type = "application"
  security_groups    = [aws_security_group.defguard_internal_alb_sg.id]
  subnets            = module.vpc.private_subnets

  enable_deletion_protection = false

  tags = {
    Name = "defguard-internal-alb"
  }
}

# Target Groups
resource "aws_lb_target_group" "defguard_core_tg" {
  name     = "defguard-core-tg"
  port     = local.core_http_port
  protocol = "HTTP"
  vpc_id   = module.vpc.vpc_id

  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30
    matcher             = "200"
    path                = "/api/v1/health"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = 5
    unhealthy_threshold = 3
  }

  tags = {
    Name = "defguard-core-tg"
  }
}

resource "aws_lb_target_group" "defguard_proxy_tg" {
  name     = "defguard-proxy-tg"
  port     = local.proxy_http_port
  protocol = "HTTP"
  vpc_id   = module.vpc.vpc_id

  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30
    matcher             = "200"
    path                = "/api/v1/health"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = 5
    unhealthy_threshold = 3
  }

  tags = {
    Name = "defguard-proxy-tg"
  }
}

# Target Group Attachments
resource "aws_lb_target_group_attachment" "defguard_core_attachment" {
  target_group_arn = aws_lb_target_group.defguard_core_tg.arn
  target_id        = module.defguard_core.instance_id
  port             = local.core_http_port
}

resource "aws_lb_target_group_attachment" "defguard_proxy_attachment" {
  target_group_arn = aws_lb_target_group.defguard_proxy_tg.arn
  target_id        = module.defguard_proxy.instance_id
  port             = local.proxy_http_port
}

# Listeners
resource "aws_lb_listener" "defguard_public_alb_listener" {
  load_balancer_arn = aws_lb.defguard_public_alb.arn
  port              = "443"
  protocol          = "HTTPS"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.defguard_proxy_tg.arn
  }
}

resource "aws_lb_listener" "defguard_internal_alb_listener" {
  load_balancer_arn = aws_lb.defguard_internal_alb.arn
  port              = "443"
  protocol          = "HTTPS"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.defguard_core_tg.arn
  }
}

# Listener Rules
resource "aws_lb_listener_rule" "defguard_proxy_rule" {
  listener_arn = aws_lb_listener.defguard_public_alb_listener.arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.defguard_proxy_tg.arn
  }

  condition {
    host_header {
      values = [replace(local.proxy_url, "https://", "")]
    }
  }
}

resource "aws_lb_listener_rule" "defguard_core_rule" {
  listener_arn = aws_lb_listener.defguard_internal_alb_listener.arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.defguard_core_tg.arn
  }

  condition {
    host_header {
      values = [replace(local.core_url, "https://", "")]
    }
  }
}

```

4. Add load balancer ingress rules to your existing Proxy and Core groups:

```hcl
# HTTP access from internal load balancer (Core)
ingress {
  from_port       = local.core_http_port
  to_port         = local.core_http_port
  protocol        = "tcp"
  security_groups = [aws_security_group.defguard_internal_alb_sg.id]
  description     = "HTTP access from internal load balancer"
}

# HTTP access from public load balancer (Proxy)
ingress {
  from_port       = local.proxy_http_port
  to_port         = local.proxy_http_port
  protocol        = "tcp"
  security_groups = [aws_security_group.defguard_alb_sg.id]
  description     = "HTTP access from public load balancer"
}

```

5. Finally, you can add the load balancer domain name to the output:

```hcl
output "defguard_public_alb_dns" {
  description = "The DNS name of the Public Application Load Balancer"
  value       = aws_lb.defguard_public_alb.dns_name
}

output "defguard_internal_alb_dns" {
  description = "The DNS name of the Internal Application Load Balancer"
  value       = aws_lb.defguard_internal_alb.dns_name
}
```

This setup will create two load balancers: one internal and one external. Both will act as a reverse proxy, routing the HTTPS traffic matching your domains to the backend servers (Proxy, Core). The next step would be to point your actual domains to the domain names generated by the load balancers in the output (CNAME) and to setup SSL certificates (e.g. via the AWS certificate manager).

### Troubleshooting and common issues

#### Checking status of any component

You can check the status of any Defguard component by SSHing into the corresponding EC2 instance and running the following command:

```bash
sudo systemctl status <component>
```

Where `<component>` is one of `defguard`, `defguard-gateway`, or `defguard-proxy`. This will show you the status of the service.

#### Checking logs of any component

To display the logs of the service, SSH into the corresponding EC2 instance and run the following command:

```bash
sudo journalctl -u <component>
```

Where `<component>` is one of `defguard`, `defguard-gateway`, or `defguard-proxy`. This will show you the logs of the service.

#### Checking setup logs

Before any of the components becomes available, a `setup.sh` script is run, which performs its initial setup (package download, configuration). The logs of this script are stored in `/var/log/defguard.log` on a corresponding EC2 instance. You can check this log file to see if there were any issues during the setup.


# AMIs and AWS CloudFormation

## Please check documentation v1.5.0


# High Availability and Failover

## Gateway - High Availability

We support running multiple gateways for a single VPN instance or location, enabling active-passive configurations. Active-active configurations should also be possible but come with some caveats. Since our gateway uses a vanilla kernel WireGuard®, there are multiple approaches for implementation.

{% hint style="info" %}
Please also see documentation of [Creating a New VPN location](/1.4/features/wireguard/create-your-vpn-network) where each [location setting has information regarding high-availability](/1.4/features/wireguard/create-your-vpn-network#vpn-location-settings).
{% endhint %}

#### Deploying multiple gateways for one location

To have a multi-gateway setup for a given location, you  will need to [deploy the gateway on each one of your servers](/1.4/deployment-strategies/gateway) under the same location.

If you already have a gateway deployed and want to add another one for the location, go to *VPN Overview* -> Click: *Edit Location Settings (in the top right corner)*, then choose the location you want to add the new gateway to, and follow the deployment instructions:

<figure><img src="/files/sw0srY8JCWhpD8ODH0j1" alt=""><figcaption></figcaption></figure>

Each gateway deployed for a given location will receive the same network configuration and will **bind to the defined port** in the location's *Gateway Port.*

The only thing left to do is to point your traffic to those gateways, which can be accomplished in several ways:

* Floating public IP - if you choose this scenario, please remember that the IP must be the IP specified in the Location *Gateway Address.* In this scenario, the floating IP switches between your gateway servers, directing the traffic to one of the two gateways.
* Proxy/load balancing - also remember that the proxy must be configured with the *Gateway Address and Gateway Port.* In this scenario, your clients connect to the proxy/load balancer, which direct the VPN traffic (UDP) to one of your gateway backend&#x73;*.*

#### Active-active setups

Active-active setups should also be possible but come with some caveats. Here are the currently known issues with such configurations:

* Multiple running gateways bound to one location with network traffic distributed between them may produce invalid network usage statistics, making the network usage graphs and displays on the dashboard unreliable. Related issue: <https://github.com/DefGuard/defguard/issues/1022>

### Determining if multiple gateways are running

All gateways that are successfully connected for the location are displayed under the Location in VPN Overview, here is an example for two gateways:

<figure><img src="/files/7Ufvi6s1NQFUa4hwnLYH" alt=""><figcaption></figcaption></figure>

### What is the gateway peers persistence (if core/proxy services fail)

1. For **VPN Locations without MFA** - it's persistent until the system reboot - *even if the gateway will not work* - as the gateway configures WireGuard "in kernel".
2. For **VPN Locations with MFA**, this depends on the *Peer Disconnect Threshold (seconds)* setting in the VPN Location settings. This setting specifies that if the peer is inactive for *(defined seconds)*, the gateway should remove it from the configuration. Therefore, if the proxy/core is not operational, MFA authentication will fail, and the peer will not be added if it is disconnected.

## Core / Proxy - Failover

The core service handles gateway states as well as core connects ***to the proxy***. Since proxy serves HTTP based protocol communication and should be in the public Internet, it needs to be secure, thus core connects to the proxy.

This way **core can be in an Intranet network segment and proxy can be in DMZ, making Core completely cut-off on firewall from the Internet** (you only can have only outgoing firewall rules from Intranet allowing only for core to connect to proxy).

So **High Availability for core and proxy** gets complicated, with multiple proxies core needs to manage those connections. We already have most of the code for that ready, but it's not yet production ready.

#### How to bullet-proof proxy & core with failover?

We recommend to deploy them on a failover solution - like on a kubernetes cluster (even small one - like mini-kube) . This way, Kubernetes manages: healthchecks and does failover. You can have cluster N-nodes and if any VM/node with Core/Proxy goes offline or health checks fail - it's migrated to a new node.


# Upgrading

Notes on upgrading Defguard and its components

{% hint style="warning" %}
Before doing any updates please remember to **backup your database.**
{% endhint %}

## Any release <= 1.3 -> 1.4

1.4 release introduces changes related to multiple client IP addresses. To ensure compatibility, **all components must be updated** to v1.4 or higher:

* **Core**
* **Proxy**
* **Gateway**
* **Desktop Clients**

Running outdated versions may result in errors due to incompatible data formats.

### Core

We've made a small update to the LDAP integration to support more complex user nesting within the LDAP tree ([related issue](https://github.com/DefGuard/defguard/issues/1242)).

If you were already using the integration, you shouldn't notice any changes. However, we **strongly recommend backing up your database before the upgrade and afterwards verifying** the following to ensure everything continues to work as expected:

* Your Defguard user list and user devices remain unchanged
* All users can still log in without issues

If you encounter any problems, please report them on our [GitHub](https://github.com/DefGuard/defguard/issues).

## Any previous release → 1.4.0-alpha3

We've introduced some changes to the LDAP integration. We recommend reading [the above section](#core) before upgrading.

## Any previous release → 1.3.0

* The LDAP integration has become an enterprise feature. You will need to purchase the enterprise license if you exceed the free limits. See [License](/1.4/enterprise/license) for more information regarding the license.
* If you used the LDAP integration previously, it will be off by default after upgrading. You will have to manually enable it in the settings in the LDAP tab:\\

  <figure><img src="/files/Y2Z487hfqmvaV1EUYMId" alt=""><figcaption></figcaption></figure>

## Any previous 1.3.0 alpha → 1.3.0 alpha 4

### Core

LDAP integration received a major overhaul of how users are mapped to Defguard users when the two-way synchronization is enabled. Now, users are always identified by their leftmost DN value.

A new synchronization may cause some of your users to be re-added, which in turn may cause the loss of some of their Defguard specific data (e.g. their devices). This will happen if your leftmost DN component's attribute (referred to as RDN) is not the same as your current username attribute. This issue is only related to the two-way synchronization mechanism and occurs only if you used one of the previous alphas of 1.3.0. Upgrading from any previous release to alpha 4 (skipping the alphas before) should not result in this happening.

Before an upgrade, turn off the two-way synchronization. After upgrading, you will have access to a new option, the RDN user attribute:

<figure><img src="/files/NACZ9JEoNyhXzcVQEmjf" alt=""><figcaption></figcaption></figure>

Set it according to your LDAP server setup. This should be the DN's leftmost component attribute, e.g. in the case of `cn=user1,cn=users,dc=ad,dc=example,dc=com` this would be "cn". This attribute is needed to properly identify users in your LDAP server. The username attribute will be mapped to Defguard usernames. Read [Settings table](/1.4/features/ldap-and-active-directory-integration/settings-table) for a description of those settings options. After you configured this value, you can re-enable the two-way synchronization.

## Any previous core release -> core 1.1.4

### Core

{% hint style="danger" %}
In Core 1.1.4, we've made email addresses case insensitive, as this is a standard for many major providers. Because the emails were case sensitive up to this point, you may end up with users with the same email addresses from core's point of view.
{% endhint %}

All email addresses must be unique case-insensitively, meaning that a user with an address `address@email.com` can't coexist with another user with an address `ADDRESS@email.com`. Before upgrading, make sure you don't have any users with the same email addresses given the above. If you do, please change those addresses or remove the users altogether. Remember to check it case-insensitively. If you have users with duplicate email addresses, the migrations will fail, and you won't be able to upgrade.

You can use the following SQL query to locate users with duplicate emails in the database:

```sql
select id, username, email from "user" where lower(email) in (
	select lower(email) from "user" group by lower(email) having count(*) > 1
)
```

## 1.0.0 -> 1.1.0

### Proxy

There is a new setting:

* ENV Variable: DEFGUARD\_PROXY\_URL
* command line argument `--url`
* /etc/defguard/proxy.toml: `url =`

**Which should be set to the same value as in core `DEFGUARD_ENROLLMENT_URL`**

## Any release -> 1.0.0

### Core

When upgrading core to 1.0.0 (even to a 1.0.0 pre-release) make sure that your users **have unique email addresses** as we've introduced a constraint requiring email addresses to be unique among users.

{% hint style="danger" %}
If you have duplicate emails in your database, the migrations during the upgrade process will simply fail.
{% endhint %}

You will need to change a duplicate email address before the upgrade by hand via the Defguard dashboard or by accessing the database.

### Desktop Client Real Time Sync

From 1.0.0 we have introduced [Enterprise features](https://github.com/DefGuard/docs/blob/docs/deployment-strategies/broken-reference/README.md), and one of them is [automatic and real-time desktop client configuration synchronization](/1.4/features/remote-user-enrollment/automatic-real-time-desktop-client-configuration).

To enable this on an **already configured desktop client,** one must perform one time instance update, which will generate necessary tokens on the client to perform from now on automatic updates. In details:

1. The admin must generate a new token for the client -[ more details here](/1.4/features/wireguard/remote-desktop-activation) (token can be sent over email or shared in any other secret way).
2. The user must perform the [Instance Update - more details here](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration#updating-instance).

{% hint style="warning" %}
Any client that is configured from scratch has this done automatically and no actions needed to be done.
{% endhint %}

## Core 0.8.x -> 0.9.x with Proxy 0.2.x -> 0.3.x

In this release, we have **hardened the security architecture**, and since the Proxy component is open for HTTP commands and is frequently communicating with Core we have reversed the communication and now **Core is connecting to Proxy (Proxy is a gRPC server and Core is the client).**

This way if Core is in a secure network segment (like Intranet) and Proxy in a DMZ segment (where Internet traffic is allowed) you don't need to open on your firewall rules for Proxy from DMZ to connect to Intranet (no packet for New Connections from DMZ->Intranet).

This change requires a few changes if you are upgrading:

#### Proxy deployment configuration

1. Remove `DEFGUARD_PROXY_UPSTREAM_GRPC_URL` variable - since Proxy does not connect to Defguard Core any more.
2. Proxy is now the server to which Defguard Core connects, so you may want to:
   1. Optional: configure non-default Proxy gRPC port with `DEFGUARD_PROXY_GRPC_PORT -` default value is **50051**
   2. If you have a Proxy in a different network segment - eg. have a custom installation (not with one-line install/docker compose all on one server) - you may also consider exposing the gRPC port and reverse-proxy (nginx/treafik/...) the port with SSL/TLS.
      1. (Optional) If you want to use SSL with Proxy gRPC server without revers-proxy (nginx/etc) configure `DEFGUARD_PROXY_GRPC_CERT` and `DEFGUARD_PROXY_GRPC_KEY` following the [SSL setup guide](/1.4/deployment-strategies/docker-compose#grpc-ssl-setup).
   3. Also adjust your firewall config to open new Docker port mapping etc. Make sure Proxy gRPC server **can be reached from Core**.

#### Core deployment configuration

1. Add `DEFGUARD_PROXY_URL` variable to point to your Proxy gRPC server endpoint, for example `http://proxy:50051` when using Docker Compose - or any gRPC URL you have configured with your reverse proxy.
2. (Optional) If using SSL configure `DEFGUARD_PROXY_GRPC_CA`

#### Upgrade process

1. Update Core & Proxy images/binaries and restart services.
2. You should see in the logs that Proxy is awaiting a gRPC connection - example docker logs:

```
Attaching to defguard_proxy_1
proxy_1  | 2024-01-24T14:05:41.365035Z  INFO defguard_proxy::server: Starting Defguard proxy server
proxy_1  | 2024-01-24T14:05:41.365069Z DEBUG defguard_proxy::server: Setting up API server
proxy_1  | 2024-01-24T14:05:41.365130Z  INFO defguard_proxy::server: gRPC server is listening on 0.0.0.0:50051
proxy_1  | 2024-01-24T14:05:41.365333Z  INFO defguard_proxy::server: Web server is listening on 0.0.0.0:8080
```

3. Core should be attempting to establish a gRPC connection with Proxy (and retrying every 10s if unable to successfully connect), like this:

```
defguard | 2024-01-24T14:17:47.815294Z  INFO defguard::grpc: Connecting to proxy
```

4. After Defguard connects successfully to proxy, you should see in proxy logs:

```
proxy_1  | 2024-01-24T14:17:47.819504Z  INFO defguard_proxy: RPC client connected from: 10.123.123.2:35916
```

## Desktop Client 0.1.x -> 0.2.0

With this release we have added Multi-Factor Authentication to the desktop client. Unfortunately desktop client database has change significantly as well as business logic (for example endpoints to proxy for MFA handshake). We have not stored them previously in the database - thus they cannot be recovered/updated automatically.

{% hint style="warning" %}
That unfortunately means you have to remove all your instances before upgrading (or just remove any desktop client configuration files, including the database) and start the enrollment (adding new instance) again after upgrading - just by adding a new device (you can remove the old one).
{% endhint %}


# Pre-production and development releases

To test any pre-production or development release:

### One-line install

The simplest way to test the latest development or pre-release version is to use one line installation method with the appropriate argument. More on that in [the one-line install documentation](/1.4/getting-started/one-line-install).

### Binaries and packages

Each GitHub repository ([core](https://github.com/DefGuard/defguard/releases), [gateway](https://github.com/DefGuard/gateway/releases), [proxy](https://github.com/DefGuard/proxy/releases), and [client](https://github.com/DefGuard/client/releases)) has its **pre-release versions** available on the GitHub release page. This is where you can download binaries or packages with the pre-release, e.g.:

<figure><img src="/files/D3kG8P6lSkOOhXwuAV8J" alt=""><figcaption></figcaption></figure>

### Docker images

Each Docker image for [core](https://github.com/DefGuard/defguard/pkgs/container/defguard), [gateway](https://github.com/DefGuard/gateway/pkgs/container/gateway) and [proxy](https://github.com/DefGuard/proxy/pkgs/container/defguard-proxy) has the following tags:

* `pre-release` – this tag is for the **latest pre-production release** - which also contains a version in form of `vX.Y.Z-alpha/beta/rcX` from the `main` branch
* `dev` – this tag is for the latest development release from the `dev` branch.

#### Docker compose

Please change the Docker compose file to match the version or tags as stated above.


# Gateway

{% hint style="info" %}
If you are looking for [gateway High Availability, go to this document.](/1.4/deployment-strategies/high-availability-and-failover#gateway-high-availability)
{% endhint %}

## Pre-requirements

{% hint style="warning" %}
Please remember that **one gateway corresponds to one VPN location.**

You can also deploy multiple gateways for one location for High Availability.
{% endhint %}

To deploy the gateway you need to have Defguard core running and know it's [gRPC url](/1.4/deployment-strategies/configuration#core-configuration) (meaning what is the **host/ip** where the core is running and the **gRPC port** defined in core by DEFGUARD\_GRPC\_PORT configuration variabl&#x65;**)** and a **token.**

**Token** can be obtained when you go to *VPN Locations -> Edit location settings (in top right corner) -> Select the desired location* -> the right panel describes how to deploy the gateway for the location as well as lists the gateway authentication token:

<figure><img src="/files/B4ldnX8vleXhupAE4FNN" alt=""><figcaption></figcaption></figure>

Also, if core has a custom SSL CA to secure gRPC communication, [you need the CA certificate (more here).](/1.4/deployment-strategies/grpc-ssl-communication#custom-ssl-ca-and-certificates)

## Package Install

1. On the [release page](https://github.com/DefGuard/gateway/releases) find and download a correct software package for your system (currently DEB, RPM and TXZ are available).
2. Install the package using relevant system tools:

   **Ubuntu/Debian:**

   ```bash
   sudo dpkg -i <path_to_deb_package>
   ```

   **Fedora/Red Hat Linux/SUSE:**

   ```bash
   sudo rpm -i <path_to_rpm_package>
   ```

   **FreeBSD:**

   ```bash
   pkg add <path_to_txz_package>
   ```
3. Fill in the default configuration file (`/etc/defguard/gateway.toml`) with values corresponding to your Defguard installation (token and gRPC endpoint URL).
4. On systems with [systemd](https://systemd.io/), enable and start the **systemd** service:

   ```bash
   sudo systemctl enable defguard-gateway.service
   sudo systemctl start defguard-gateway.service
   ```

On systems with rc.d (like FreeBSD, NetBSD), start the service. For example, on OPNsense:

```bash
sudo /usr/local/etc/rc.d/defguard_gateway start
```

## Package Upgrade

### FreeBSD/OPNsense

1. Uninstall the current version.

   ```bash
   pkg delete defguard-gateway
   ```
2. Install a newer version (as described above in [Package Install](#package-install)).

   ```bash
   pkg add <path_to_txz_package>
   ```
3. Restart Defguard Gateway service.

   ```bash
   sudo /usr/local/etc/rc.d/defguard_gateway restart
   ```

## Docker Compose

To start Defguard Gateway using [Docker Compose](https://docs.docker.com/compose/):

1. We prepared a [git repository](https://github.com/DefGuard/deployment) with Docker Compose configuration, clone it:

```
git clone --recursive https://github.com/DefGuard/deployment.git && cd deployment/gateway
```

2. Copy and fill in the .env file:

```bash
cp .env.template .env
```

3. Finally, run the service with Docker Compose:

```bash
docker compose up
```

If everything went well, Defguard Gateway should be connected to Defguard Core and you can start [adding new devices to your network](/1.4/features/network-devices#adding-a-new-network-device).

## OPNsense plugin

[OPNsense®](https://opnsense.org/) is an open source, feature rich firewall and routing platform, offering cutting-edge network protection.

To start Defguard Gateway as OPNsense plugin:

1. On the [release page](https://github.com/DefGuard/gateway/releases) find and download OPNsense package which will be named:\
   `defguard-gateway_VERSION_x86_64-unknown-opnsense.pkg` – this package **includes both Defguard Gateway and OPNsense plugin.**
2. Install the package:

```bash
pkg add defguard-gateway_VERSION_x86_64-unknown-opnsense.pkg
```

3. Refresh your OPNsense UI by running command below:

```bash
opnsense-patch
```

4. Go to your OPNsense UI and navigate to **VPN** > **Defguard Gateway**.

<figure><img src="/files/3BLwWdtocrFSSnMkVLgd" alt=""><figcaption></figcaption></figure>

5. Fill out the form with appropriate values, click **Save**, and then click **Start/Restart.**

{% hint style="info" %}
You can find detailed description of all fields [here](/1.4/deployment-strategies/configuration#gateway-configuration).
{% endhint %}

If everything went well, Defguard Gateway should be connected to Defguard Core and you can start [adding new devices to your network](/1.4/features/wireguard/remote-desktop-activation).

See also: [how to configure Defguard in OPNsense](/1.4/features/gateway)

## Binary Install

1. Checkout Gateway releases [here](https://github.com/DefGuard/gateway/releases) and download compatible binary from GitHub page.
2. Decompress and move to bin directory

```sh
tar xcf ./gateway.tar.gz
sudo chmod +x gateway
sudo mv gateway /usr/bin/
```

3. Start gateway `gateway -g <CORE_GRPC_URL:GRPC_PORT> -t <DEFGUARD_TOKEN>`

## Using a userspace implementation

Gateway currently supports using `wireguard-go`, a userspace WireGuard implementation. This approach is not recommended on platforms where a native support exists (e.g. Linux).&#x20;

You can enable the userspace implementation by setting the `userspace` config option or a corresponding `DEFGUARD_USERSPACE` environment variable to `true`.

Because `wireguard-go` is not bundled by default with Defguard, it must be installed separately. The `wireguard-go` binary/command must be available on the host machine for it to function properly. On Docker, this currently requires building a custom image, as the base gateway images also don't come with `wireguard-go` pre-installed. This can be achieved as follows:

```docker
FROM golang:1.24.6-alpine AS builder
RUN apk add --no-cache git make

RUN git clone https://git.zx2c4.com/wireguard-go /src/wireguard-go \
 && cd /src/wireguard-go \
 && make

# Specify the desired Gateway's version here
FROM ghcr.io/defguard/gateway:latest

COPY --from=builder /src/wireguard-go/wireguard-go /usr/local/bin/wireguard-go

RUN chmod +x /usr/local/bin/wireguard-go
```

Note that when running the Docker container with a userspace implementation on a Linux host, the container requires a `NET_ADMIN` capability and access to `/dev/net/tun`, this can be set in a Docker compose:

```yaml
# Docker compose
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
```

Or via the command line:

```bash
docker run --cap-add=NET_ADMIN --device=/dev/net/tun [...]
```


# Running gateway on MikroTik routers

By leveraging the ability of some MikroTik routers to run Docker containers, it is possible to deploy the gateway directly on your router.

{% hint style="warning" %}
Proceed with extra caution when working with your core infrastructure. All official [RouterOS containers warnings](https://help.mikrotik.com/docs/display/ROS/Container#Container-Disclaimer) still apply.
{% endhint %}

{% hint style="danger" %}
Running the gateway on a MikroTik router is not fully supported.

Due to custom RouterOS kernel incompatibility this kind of deployment does not support [Access Control List](/1.4/features/access-control-list) functionality.

To run the gateway you must explicitly disable firewall management using the [`DEFGUARD_DISABLE_FW_MGMT` option](/1.4/deployment-strategies/configuration#gateway-configuration).
{% endhint %}

## Prerequisites

* RouterOS device with ARM or ARM64 architecture (popular home lab choices include RB4011 or RB5009)
* `Container` package installed and enabled
* Running Defguard core instance with a WireGuard location configured
* (optional) Self-signed certificate generated by following [gRPC SSL setup guide](/1.4/deployment-strategies/grpc-ssl-communication)

## Setup

{% hint style="warning" %}
This guide assumes you do not have other Docker containers deployed on your router yet. If this is not the case adjust accordingly.

The same applies if you have some more specific network configuration requirements.
{% endhint %}

{% hint style="info" %}
For brevity we'll be using RouterOS terminal commands, but everything can also be accomplished through WinBox GUI.
{% endhint %}

### Prepare network to install Docker container

* First create a bridge interface for Docker containers and assign it an IP address in a dedicated Docker subnet (`172.17.0.0/24` in our example):

```
/interface/bridge/add name=docker
/ip/address/add address=172.17.0.1/24 interface=docker
```

* Each container must have a dedicated VETH interface; create a `veth1` interface and assign it an IP address in the chosen Docker subnet:

```
/interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1
```

* Add the virtual interface to the Docker bridge:

```
/interface/bridge/port add bridge=docker interface=veth1
```

### Setup firewall rules

* Set up NAT for outgoing traffic from containers:

```
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24
```

* Add port forwarding rule to send UDP traffic from the public WireGuard port to the gateway container:

```
/ip/firewall/nat/add chain=dstnat protocol=udp dst-address=<YOUR PUBLIC IP> dst-port=<YOUR PUBLIC WG PORT> action=dst-nat to-addresses=172.17.0.2 to-ports=<YOUR PUBLIC WG PORT>
```

{% hint style="warning" %}
Container port being forwarded to must match your public WireGuard port.
{% endhint %}

* Add routing for your chosen WireGuard subnet configured in Defguard UI location settings:

```
/ip/route/add dst-address=<YOUR WG SUBNET> gateway=172.17.0.2
```

### Run gateway container

* Configure environment variables for the gateway container:

```
/container/envs/add name=defguard_env key=DEFGUARD_TOKEN value=<YOUR TOKEN>
/container/envs/add name=defguard_env key=DEFGUARD_GRPC_URL value=<YOUR DEFGUARD GRPC URL>
/container/envs/add name=defguard_env key=DEFGUARD_DISABLE_FW_MGMT value=true
```

* (optional) To use SSL for communication between the gateway and your Defguard instance copy the root certificate to your router's filesystem and add a following mount and environment variable:

```
/container/mounts/add name=defguard_cert src=<PATH TO CERT DIR> dst=/certs
/container/envs/add name=defguard_env key=DEFGUARD_GRPC_CA value=/certs/myCA.pem
```

{% hint style="warning" %}
Put the root certificate in a directory and mount the whole directory. Trying to mount a specific file can cause unexpected issues.
{% endhint %}

* Add GitHub container registry to config:

```
/container/config/set registry-url=https://ghcr.io
```

* Finally, create the actual container:

```
/container/add remote-image=ghcr.io/defguard/gateway:latest interface=veth1 envlist=defguard_env
```

At this point you should see that the gateway is connected in your Defguard instance's web UI.


# Securing gRPC communication

Defguard Core has two main communication endpoints:

1. gRPC port for communicating with Defguard Gateways,
2. gRPC port for communicating with Defguard Core.

{% hint style="danger" %}
It is **critical** that:

1. Defguard Core's gRPC port is open on a firewall only for IP addresses of Defguard Gateway nodes.
2. Defguard Proxy's gRPC port is open on a firewall only for the IP address of Defguard Core.
3. If you want an additional layer of security, then you should create a **custom SSL Certificate Authority (CA)**, and provide Core, Proxy and Gateway Certificates from that CA so **any other connections to the gRPC services will not be accepted.**
4. Even if you have secured the network ports/firewall and do not want to create a custom SSL CA, please secure gRPC traffic with SSL and a reverse proxy.
   {% endhint %}

## Custom SSL CA and certificates

To secure not only with firewall communication between all Defguard gRPC components, a custom SSL chain of certificates should be used. This way the trust will be ensured on the Transport Layer Security (TLS) level.

It is important to embed a correct domain name into the certificate as *X509v3 Subject Alternative Name*. The domain name must match the one under which a service is being hosted.

### Quick setup

To quickly generate a set of SSL certificates using [OpenSSL](https://openssl-library.org) or [LibreSSL](https://www.libressl.org), use the following:

* Generate Certificate Authority (CA) certificate and key for domain *example.local*

```sh
openssl req -x509 -noenc -subj '/CN=example.local' -newkey rsa:4096 -keyout ca.key -out ca.crt
```

* Generate private key and Certificate Signing Request (CSR)

```sh
openssl req -noenc -newkey rsa:4096 -keyout core.key -out core.csr -subj '/CN=example.local' -addext subjectAltName=DNS:example.local
```

* Generate certificate by signing the CSR, valid for 365 days

```sh
openssl x509 -req -in core.csr -CA ca.crt -CAkey ca.key -days 365 -out core.crt -copy_extensions copy
```

{% hint style="info" %}
Repeat the last two steps for other services (e.g. change core.csr, core.crt, and core.key to gateway.csr, gateway.crt, gateway.key), just change the domain name accordingly.
{% endhint %}

To display certificate file contents:

```sh
openssl x509 -noout -text -in core.crt
```

### Defguard configuration

#### Defguard Core

Using command line arguments

```sh
defguard --grpc-cert path/to/core.crt \
         --grpc-key path/to/core.key \
         --proxy-grpc-ca path/to/ca.crt
```

Using environment variables

```sh
env DEFGUARD_GRPC_CERT=path/to/core.crt \
    DEFGUARD_GRPC_KEY=path/to/core.key \
    DEFGUARD_PROXY_GRPC_CA=path/to/ca.crt \
    defguard
```

#### Defguard Proxy

Using command line arguments

```sh
defguard-proxy --grpc-cert path/to/proxy.crt \
               --grpc-key path/to/proxy.key
```

Using environment variables

```sh
env DEFGUARD_PROXY_GRPC_CERT=path/to/proxy.crt \
    DEFGUARD_PROXY_GRPC_KEY=path/to/proxy.key
    defguard-proxy
```

### Defguard Gateway

Using command line arguments

```sh
defguard-gateway --grpc-ca path/to/ca.crt
```

Using environment variables

```sh
env DEFGUARD_GRPC_CA=path/to/ca.crt \
    defguard-gateway
```

Using configuration file

```toml
grpc_ca = "path/to/ca.crt"
```

## Trusted CA (eg. Let'sEncrypt or others)

Often (like in the standalone package based installation tutorial) gRPC communication can be secured by a reverse proxy (NGINX, Caddy, Traefik, etc.) that handles SSL termination. It's common to use typical trusted CA (that is used for typical HTTPS traffic) like Let'sEncrypt or others.

{% hint style="danger" %}
While this secures the transport layer and encrypts communication between Defguard components - it does not provide authorization between gRPC components like Custom CA does.

Thus, this type of SSL termination should only be done if you trust your network and have secured gRPC ports on firewall.
{% endhint %}

If Defguard Core or Defguard Proxy are using reverse proxy with SSL termination, then only you need to configure CA certificate paths for:

* Defguard Gateway – in *gateway.toml* add path to CA certificate file (in PEM format); for example, when using standard Let'sEncrypt installation ([Certbot](https://certbot.eff.org)), you configure the CA path like this:
  * `grpc_ca = "/etc/letsencrypt/live/domain.name/chain.pem"`
* Defguard Core – similarily, you need to configure Proxy CA certificate file using **DEFGUARD\_PROXY\_GRPC\_CA** environment variable:
  * `DEFGUARD_PROXY_GRPC_CA: /etc/letsencrypt/live/domain.name/chain.pem`


# OpenID RSA key

By default, Defguard uses [HMAC](https://en.wikipedia.org/wiki/HMAC) algorithm for OIDC token validation and the. If you want to use [RSA](https://en.wikipedia.org/wiki/RSA_\(cryptosystem\)), you'll have to configure the Defguard core `DEFGUARD_OPENID_KEY` configuration variable with the path to the RSA private key.

You can generate the RSA key with:

```
openssl genpkey -out /path/to/rsakey.pem -algorithm RSA -pkeyopt rsa_keygen_bits:4096
```


# Health check

## Core & Proxy

### Rest API

[Core](https://github.com/defguard/defguard) and [Proxy](https://github.com/defguard/proxy) provides health endpoint at  `GET /api/v1/health` which checks whether the application server is running.

Example request:

```bash
curl "https://defguard.example.com/api/v1/health" 
```

Example response:

```
alive
```

### gRPC status health

#### Proxy (available from v0.6.0)

To verify gRPC services for **Proxy** are alive, there is endpoint at `GET /api/v1/health-grpc` that verify it.

Example request:

```bash
curl "https://enroll.example.com/api/v1/health-grpc"
```

Possible responses:

```
200 - Proxy is working and is connected to CORE
503 - Proxy works but is not connected to CORE
```

#### Core (available from v1.0.0)

To check if core gRCP service is alive, we recommend to use community tools like [grpc\_health\_probe](https://github.com/grpc-ecosystem/grpc-health-probe).

Example request for core:

```sh
./grpc_health_probe -addr=defguard.example.com:50055
```

Example response for core:

```
status: SERVING
```

## Gateway

You can enable in gateway config ([example config](https://github.com/DefGuard/gateway/blob/main/example-config.toml)) a health check port, by adding the following line:

```
health_port = 55003
```

In this example, gateway will open an additional HTTP port number 55003 and will return the following HTTP status codes:

* <pre><code><strong>200 - Gateway is working and is connected to CORE
  </strong></code></pre>
* ```
  503 - gateway works but is not connected to CORE
  ```

By default no healthcheck ports are open.


# Configuration

Here you can find a list of all configurable things through environmental variables, options or configuration files for all Defguard components (each top-level section for a specific component):

* [Core config](#core)
* [Proxy config](#proxy-service)
* [Gateway config](#gateway-configuration)
* [YubiBridge config](#yubibridge-configuration)

{% hint style="info" %}
If you are using [one-line installation](/1.4/getting-started/one-line-install), everything is generated and configured automatically.
{% endhint %}

## Core

### Secrets configuration

Defguard core requires a random secret strings to properly generate tokens for authentication or generating JWT tokens.

{% hint style="info" %}
You can generate random strings for secrets with e.g.:

`openssl rand -base64 55 | tr -d "=+/" | tr -d '\n' | cut -c1-64`
{% endhint %}

* `DEFGUARD_AUTH_SECRET`: JWT secret key for encrypting user tokens, default: `DEFGUARD_AUTH_SECRET`
* `DEFGUARD_SECRET_KEY`: JWT secret key for encrypting private cookies; must be at least 64 characters long
* `DEFGUARD_GATEWAY_SECRET`: JWT secret key for encrypting Gateway tokens, default: `DEFGUARD_GATEWAY_SECRET`
* `DEFGUARD_YUBIBRIDGE_SECRET`: JWT secret key for encrypting YubiBridge tokens, default: `DEFGUARD_YUBIBRIDGE_SECRET`
* `DEFGUARD_OPENID_KEY`: this is optional if you want to use [HMAC](https://en.wikipedia.org/wiki/HMAC) algorithm for OIDC token validation, if you want to use [RSA](https://en.wikipedia.org/wiki/RSA_\(cryptosystem\)) please provide a path to a private key file used for OAuth2/OpenID, [more here](https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#openid-rsa-setup).

### General configuration

* `DEFGUARD_URL`: URL of your server instance, default `http://localhost:8000. This is the address at which the Web UI you use to administer your instance and the REST API endpoints are available (both of those are served by Defguard core on port 8000 by default; port can be configured with DEFGUARD_HTTP_PORT env variable).`This URL is needed to be exact since it's needed for OpenID discovery endpoint to work correctly, so if you have a reverse-proxy, custom domain, please provide an actual URL for Defguard core.
* `DEFGUARD_GATEWAY_DISCONNECTION_NOTIFICATION_TIMEOUT`: If gateway is disconnected for this long, send email notification, default: `10m` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))
* `DEFGUARD_WEBAUTHN_RP_ID` (optional): Relying party ID and relying party origin for WebAuthn used for MFA. By default, it's generated by using a base domain of `DEFGUARD_URL` (for example <https://defguard.example.com> is converted to defguard.example.com).

{% hint style="warning" %}
`DEFGUARD_WEBAUTHN_RP_ID`must be an effective domain of DEFGUARD\_URL (for example if hosting at `https://idm.example.com`, rp\_id must be `idm.example.com`, `example.com` or `com`). Changing `DEFGUARD_WEBAUTHN_RP_ID will potentially break all your existing Webauthn credentials.`
{% endhint %}

* `DEFGUARD_ADMIN_GROUPNAME`: Name of the administrator group, default: `admin`
* `DEFGUARD_USERADMIN_GROUPNAME`: Name of the user administrator group, default: `useradmin`
* `DEFGUARD_VPN_GROUPNAME`: Name of the vpn group, default: `vpn`
* `DEFGUARD_DEFAULT_ADMIN_PASSWORD`: Password for the default `admin` user, default: `pass123`
* `DEFGUARD_LOG_LEVEL`: [Logger](https://crates.io/crates/log) log level, default: `info`, supported: `debug`, `warn`, `error`
* `DEFGUARD_HTTP_PORT`: Core server port, default: `8000`
* `DEFGUARD_LOG_FILE`: Log file path
* `DEFGUARD_AUTH_COOKIE_TIMEOUT`: Cookie lifetime period, default: `7d` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))
* `DEFGUARD_MFA_CODE_TIMEOUT`: Email code lifetime period, default: `60s` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))
* `DEFGUARD_SESSION_TIMEOUT`: Session lifetime period, default: `7d` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))

### Database configuration

Following env variables can be used to setup your database access:

* `DEFGUARD_DB_HOST`
* `DEFGUARD_DB_PORT`
* `DEFGUARD_DB_NAME`
* `DEFGUARD_DB_USER`
* `DEFGUARD_DB_PASSWORD`

### Auth cookies configuration

{% hint style="warning" %}
If you want to access your Defguard instance without TLS (using an `http://` URL) you MUST enable insecure cookies by setting `DEFGUARD_COOKIE_INSECURE` to `true`.

This is of course not recommended in production but can be useful when testing without a full reverse proxy setup.
{% endhint %}

* `DEFGUARD_COOKIE_INSECURE`: set cookies without the `Secure` flag; use only in dev environments when serving Defguard without HTTPS
* `DEFGUARD_COOKIE_DOMAIN` (optional): set the domain for auth cookies. By default, it's the domain from `DEFGUARD_URL`. Must be changed to base URL if you want to use [forward auth](/1.4/features/forward-auth).

### Stats cleanup configuration

* `DEFGUARD_DISABLE_STATS_PURGE`: disable periodic cleanup of old Wireguard stats
* `DEFGUARD_STATS_PURGE_FREQUENCY`: how often should the cleanup process be performed, default `24h` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))
* `DEFGUARD_STATS_PURGE_THRESHOLD`: age threshold for stats removal, default `30d` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))

### Enrollment configuration

* `DEFGUARD_ENROLLMENT_URL`: external URL of the enrollment proxy server, default `http://localhost:8080` - this URL is sent in enrollment emails as well as displayed when configuring the desktop client - thus must be to the actual URL you have configured the proxy Web UI to be accessible at, otherwise the enrollment or desktop client configuration will not work.
* `DEFGUARD_ENROLLMENT_TOKEN_TIMEOUT`: how long is the enrollment token valid for use, default: `24h` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))
* `DEFGUARD_ENROLLMENT_SESSION_TIMEOUT`: how long in the enrollment session valid after a user uses the token to start the enrollment process, default: `10m` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))

### Password reset configuration

* `DEFGUARD_PASSWORD_RESET_TOKEN_TIMEOUT`: how long is the password reset token valid for use, default: `24h` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))
* `DEFGUARD_PASSWORD_RESET_SESSION_TIMEOUT`: how long in the password reset session valid after a user uses the token to start the enrollment process, default: `10m` ([Humantime documentation](https://docs.rs/humantime/latest/humantime/struct.Duration.html))

### gRPC server configuration

[More on that in this help page.](/1.4/deployment-strategies/grpc-ssl-communication)

* `DEFGUARD_GRPC_PORT`: the port on which the gRPC server should listen, default is `50055`. This port is used by Defguard Gateways to connect to your Core instance.
* `DEFGUARD_GRPC_CERT` (optional): path to TLS certificate file
* `DEFGUARD_GRPC_KEY`(optional): path to TLS key file
* `DEFGUARD_GRPC_URL`: external URL of your instance's gRPC server, default `http://localhost:50055`; used for generating example VPN gateway startup command in Web UI

### Proxy connection configuration

* `DEFGUARD_PROXY_URL` (optional): proxy service gRPC endpoint URL
* `DEFGUARD_PROXY_GRPC_CA`(optional): path to TLS root certificate file, required if connecting to proxy gRPC service with a custom CA ([More on that in this help page.](/1.4/deployment-strategies/grpc-ssl-communication))

## Proxy service

Here are proxy ENV variables. gRPC configuration is described more [on this help page.](/1.4/deployment-strategies/grpc-ssl-communication)

* `DEFGUARD_PROXY_HTTP_PORT`: port the proxy API server and Web UI will listen on, default `8080`
* `DEFGUARD_PROXY_GRPC_PORT`: port the gRPCS server will listen on, default `50051`
* `DEFGUARD_PROXY_GRPC_CERT` (optional): path to TLS certificate file
* `DEFGUARD_PROXY_GRPC_KEY`(optional): path to TLS key file. [More on that in this help page.](/1.4/deployment-strategies/grpc-ssl-communication)
* `DEFGUARD_PROXY_URL` - if you wish to use External OIDC enrollment/desktop client configuration, please set this value to the same as `DEFGUARD_ENROLLMENT_URL` in core. This is the address at which the proxy Web UI is available.
* `DEFGUARD_PROXY_LOG_LEVEL` : [Logger](https://crates.io/crates/log) log level, default: `info`, supported: `debug`, `warn`, `error`
* `DEFGUARD_PROXY_RATELIMIT_PERSECOND` - The (average) number of requests per second made without being eventually rate limited&#x20;
* `DEFGUARD_PROXY_RATELIMIT_BURST` - The number of requests allowed to be made in a short amount of time before being rate limited

## Gateway Configuration

### Environmental variables / Arguments

If you're using docker image you can pass this value as environmental variables or on binary you can pass them as arguments

* `DEFGUARD_GRPC_URL` , `-g <URL>` - Defguard Core gRPC endpoint URL. This is used by the gateway to connect to your Defguard Core instance. If you configured the `DEFGUARD_GRPC_URL` variable on your Core instance before (as described in the [#grpc-server-configuration](#grpc-server-configuration "mention") section), use the same value here. Otherwise, provide an URL that will allow the Gateway to reach your Core instance, e.g. `http://localhost:50055` if both Core and Gateway are running on the same host.&#x20;
* `DEFGUARD_TOKEN` ,`-t <TOKEN>` - Token displayed in the Defguard Core web UI after completing the network wizard. It can be copied from the "Authentication Token" section on the Location Settings page.

  <figure><img src="/files/stJDPtQdjiyfLXYAhsc4" alt=""><figcaption></figcaption></figure>
* `DEFGUARD_USERSPACE` , `-u` - Use userspace wireguard implementation, useful on systems without native wireguard support
* `DEFGUARD_GRPC_CA - path to ca file` more on this topic can be found [on this help page.](/1.4/deployment-strategies/grpc-ssl-communication)
* `DEFGUARD_STATS_PERIOD` ,`-p <SECONDS>` - Defines how often (seconds) should interface statistics be sent to the Defguard server
* `DEFGUARD_GATEWAY_NAME`, `--name <NAME>` - (optional) human-readable gateway name that will be displayed in Defguard webapp
* `-s, --use-syslog` - enable logging to syslog
* `RUST_LOG` : Logger log level, default: `info`, supported: `debug`, `warn`, `error`
* `DEFGUARD_MASQUERADE` - controls whether the gateway automatically applies masquerade NAT firewall rule; defaults to `false`
* `DEFGUARD_IFNAME` - The network interface that will be created and used for the VPN traffic
* `DEFGUARD_FW_PRIORITY` - The NFT forward chain priority, which handles traffic filtering when ACLs are configured. Defaults to 0. Useful if the Defguard's forward chain conflicts with other chains.
* `DEFGUARD_DISABLE_FW_MGMT` - disables all firewall management by the gateway; this overrides `DEFGUARD_MASQUERADE` setting; defaults to `false`&#x20;

{% hint style="info" %}
`DEFGUARD_DISABLE_FW_MGMT` is meant as a workaround for running in incompatible environments, where our [default firewall integration](/1.4/features/access-control-list/firewall-internals) is not supported.

As a consequence, enabling this option disables [ACL functionality](/1.4/features/access-control-list) on a given gateway.
{% endhint %}

#### Executing custom commands on VPN up/down

The following env variables or gateway arguments define which commands gateway will run before / after it will bring up / down the VPN.

It's usefull for example to use those commands to launch custom firewall commands or scripts that do various operations needed to be done on those occasions.

{% hint style="danger" %}
Defguard is built with highest security standards in mind, thus the options below **accept only a full path to one command and it's arguments.**

If you would like to have **multiple commands run,** you can create a shell script which will define the acceptable and preferred shell you would like to use and then all the commands you like to execute.
{% endhint %}

`PRE_UP` , `--pre-up`, - Command to run before bringing up the interface. If you want to run a shell script, you should pass its path to your shell, for example: `/bin/sh -c /path/to/script`

`POST_UP` , `--post-up`, - Command to run after bringing up the interface.

`PRE_DOWN` , `--pre-down`, - Command to run before bringing down the interface.

`POST_DOWN` , `--post-down`, - Command to run after bringing down the interface.

{% hint style="info" %}
If logging to syslog please remember to configure your syslog daemon accordingly, so that a dedicated logfile is created or the messages are included in the main system log.
{% endhint %}

### Config file

Gateway configuration can also be read from a file by using a `--config` CLI option. Example file contents:

```toml
# This is an example config file for Defguard VPN gateway
# To use it fill in actual values for your deployment below

# Required: secret token generated by Defguard
# NOTE: must replace default with actual value
token = "<your_gateway_token>"
# Required: Defguard server gRPC endpoint URL
# NOTE: must replace default with actual value
grpc_url = "<defguard_grpc_url>"
# Optional: gateway name which will be displayed in Defguard web UI
name = "Gateway on server X"
# Required: use userspace Wireguard implementation (e.g. wireguard-go)
userspace = false
# Optional: path to TLS cert file - more in gRPC SSL communication help page
# in our documentation.
# grpc_ca = cert.pem
# Required: how often should interface stat updates be sent to Defguard server (in seconds)
stats_period = 60
# Required: name of Wireguard interface
ifname = "wg0"
# Optional: write PID to this file
# pidfile = defguard-gateway.pid
# Required: enable logging to syslog
use_syslog = false
# Required: which syslog facility to use
syslog_facility = "LOG_USER"
# Required: which socket to use for logging
syslog_socket = "/var/run/log"

# Optional: Command which will be run before bringing interface up
#pre_up = "/path/to/script.sh"

# Optional: Command which will be run after bringing interface up
#post_up = "ip route add default via 192.168.1.1 dev wg0

# Optional: Command which will be run before bringing interface down
# Example: Remove WireGuard-related firewall rules before interface is taken down:
#pre_down = "iptables -D INPUT -i wg0 -j ACCEPT"

# Optional: Command which will be run after bringing interface down
# Example: Remove the default route after WireGuard interface is down:
#post_down = "ip route del default via 192.168.1.1 dev wg0"

```

## YubiBridge configuration

### Environmental variables

* `LOG_LEVEL`: Log messages level, default: `INFO`, available levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`
* `WORKER_ID`: Name of your YubiBridge displayed on Defguard website, default: `YubiBridge`
* `DEFGUARD_TOKEN`: - Secret worker token to secure gRPC communication, available on provisioners page
* `SMARTCARD_RETRIES`: Number of retries in case provisioning failed, default: `1`
* `JOB_INTERVAL`: Defines how often(seconds) YubiBridge checks Defguard for new jobs, default: `2`
* `SMARTCARD_RETRY_INTERVAL`: Defines the number of seconds between trying to provision YubiKey again, default `15`

### CLI arguments:

* `-h` , `--help`: Display help message
* `-g <URL>`, `--grpc <URL>`: Connect to gRPC server at the given URL
* `-i <ID>` , `--id <ID>`: WorkerID, default `YubiBridge`
* `-d` , `--debug`: Enable debug mode
* `-t <TMPDIR>` , `--tmpdir <TMPDIR>`: GnuPG home directory, default: `tmp`
* `-p <first_name> <last_name> <email>` , `--provision <first_name> <last_name> <email>`: Provision YubiKey with the following data
* `-w <token>` , `--worker-token <token>`: Secret worker token to secure gRPC communication, available on provisioners page
* `-c <command>` , `--command <command>`: Run command after provisioning and pass created keys as arguments


# License

Defguard Enterprise offers a lot of functionalities that are not offered in the Open Source Open Core, like external OpenID Connect/SSO support, automatic\&real time desktop client synchronization and configuration, and much more (go to [All Enterprise Features](/1.4/enterprise/enterprise-features) to see more).

### Enterprise is free up to certain limits

{% hint style="info" %}
From release 1.1.0 **all enterprise features up to the following limits are free and no license is required:**

* 5 active users
* 10 devices
* 1 location
  {% endhint %}

Those limits should be more than enough for small businesses, home-labs or just to test out Enterprise features before committing.

{% hint style="info" %}
At the moment your instance exceeds any of the limits, you will receive a relevant notification in the interface. Defguard will remain fully operational, and all Open Source functionalities will be available. Only the enterprise functionalities will be disabled until you activate the license.
{% endhint %}

### Purchasing the license

If you would like to purchase a license, we offer two types of licenses:

1. **Subscription** that can be bought on <https://defguard.net/pricing/>
2. **Offline (which will not contact our license server) with a defined custom period** can be bought directly, please contact: sales @ defguard.net

#### Subscription

You can buy a monthly (soon yearly) subscription on our website: <https://defguard.net/pricing/>.

After purchasing:

1. The license will be emailed to you on the email defined in the purchase form. Also there will be a second email with the invoice.
2. Each month (on the date the license expires) **Defguard core will contact our licensing server** and if the monthly payment was successful, our licensing server will **automatically issue a new license and the enterprise plan will be extended to new date.**

{% hint style="warning" %}
If your setup / firewall / network policy **doesn't allow that Defguard will contact our licensing server, please contact us for the** [**Offline license**](#offline-license)**.**
{% endhint %}

#### Offline license

Defguard is build with the highest security architecture in mind, thus there may be scenarios where you don't want any of the components to contact external services (eg. Defguard core will have no access to Internet).

Offline license can be also issued for any period of time, so another scenario is that you can buy the enterprise license for any duration you wish.

To obtain an offline Enterprise License please contact our sales at: **sales \[ a t ] defguard.net** and provide:

* the period for which you would like to obtain the license
* your company data and contact email address (for billing and license sharing)
* preferred payment method: bank wire transfer or card payment link

### Configuring Defguard with obtained license

To configure Defguard with the received license, please go to **Settings** -> enter the license in the Enterprise License configuration window -> Click Save.

The license will be validated and detailed information about the license will be displayed (validity period and the license type):

<figure><img src="/files/7VG0AoBFEPLagC08WB25" alt=""><figcaption><p>Defguard enterprise license settings</p></figcaption></figure>


# Enterprise features

Here is a list of all Enterprise features:

* [Ability to use external OIDC](/1.4/features/external-openid-providers) (Google/Microsoft/Okta/JumpCloud/Custom) to login or create Defguard account.
  * Do Multi-Factor Authentication on selected VPN locations with External SSO on Desktop and Mobile clients (from version 1.5).
* [Two-way LDAP & Active Directory synchronization](/1.4/features/ldap-and-active-directory-integration/two-way-ldap-and-active-directory-synchronization)
* [Real time sync for client configurations](/1.4/features/remote-user-enrollment/automatic-real-time-desktop-client-configuration)! **First WireGuard client to support this feature!**
* Ability to define and enforce [Access Control List rules](/1.4/features/access-control-list) / firewall management
* Ability to [stream the Activity & Audit logs to external SIEM systems](/1.4/features/activity-log/activity-log-streaming)
* Ability to use [external OIDC for secure remote enrollment and Desktop client configuration](/1.4/features/external-openid-providers/external-oidc-secure-enrollment)
* Ability to [disable for users to manage their devices](/1.4/features/wireguard/behavior-customization#disable-for-users-to-manage-their-devices) (just admin will have this possibility).
* Ability to [disable for users to configure WireGuard clients other then Defguard desktop client](/1.4/features/wireguard/behavior-customization#disable-ability-to-configure-other-vpn-clients-then-defguard-desktop-client).
* Ability to [disable "All traffic" in the desktop client ](/1.4/features/wireguard/behavior-customization#disable-all-traffic-option-in-the-desktop-client)- just "predefined" traffic by admins.
* Ability to integrate with external tooling using [REST API](/1.4/features/integrations/api-tokens).


# Overview

## Welcome to Defguard end-user documentation

This section guides you through the key features of Defguard designed for everyday users and how to make the most of them.

Whether you're installing the desktop or CLI client, configuring your VPN access, or setting up secure authentication with 2FA/MFA, this section will walk you through each step clearly. It also covers how to reset your password, complete enrollment, and onboard into your organization’s setup smoothly.

### What you’ll learn

As a Defguard user, this documentation will help you:

* Understand how to access and use Defguard on your device.
* Configure VPN and authentication settings securely.
* Successfully enroll, onboard, and manage your credentials.


# Mobile Client

## Please check [documentation of Defguard 1.5.0](/1.5/using-defguard-for-end-users/mobile-client)


# Desktop Client

### Overview

Desktop client provides an easy way to access VPN locations of multiple Defguard instances via user-friendly UI.

Download latest release here: <https://defguard.net/download/>

For development/pre-releases, go to GitHub: <https://github.com/DefGuard/client/releases>

Guides:

* [Instance configuration](/1.4/using-defguard-for-end-users/desktop-client/instance-configuration)
* [Using Multi-Factor Authentication](/1.4/using-defguard-for-end-users/desktop-client/using-multi-factor-authentication-mfa)

### Windows

Our desktop client has **bundled** official WireGuard client - as we use **wg.exe** to manage the WireGuard tunnels.

{% hint style="danger" %}
If you have the official WireGuard client installed - Defguard client installation may fail.
{% endhint %}

### MacOS

Has no external requirements and we have wireguard-go bundled.

### Linux

{% hint style="warning" %}
On Linux the desktop client uses `resolvconf` to manage DNS servers. On newer distributions it should be a symbolic link to `resolvectl`, more details can be found on the [troubleshooting](https://github.com/DefGuard/docs/blob/docs/help/broken-reference/README.md) page.
{% endhint %}

### Ubuntu

#### Ubuntu 24

The libwebkit2gtk-4.0 library which our client depends on is not available in the default apt package repositories on Ubuntu 24.04 (there is only libwebkit2gtk-4.1 which doesn't work with current client). Client installation is still possible, but requires using some workarounds:

To safely install a package from Ubuntu Jammy repositories without breaking your system:

1. **Add Jammy Repo:**
   * Open `/etc/apt/sources.list`:

     ```bash
     sudo nano /etc/apt/sources.list
     ```
   * Add the Jammy repository with `[arch=amd64]` for your architecture:

     ```
     deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main universe
     ```
   * Save and exit.
2. **Pin the Jammy Repo with low priority:**
   * Create `/etc/apt/preferences.d/jammy.pref`:

     ```bash
     sudo nano /etc/apt/preferences.d/jammy.pref
     ```
   * Add the following:

     ```
     Package: *
     Pin: release n=jammy
     Pin-Priority: -10
     ```
   * Save and exit.
3. **Install the Specific Package:**

   ```bash
   sudo apt update
   sudo apt install -t jammy libwebkit2gtk-4.0
   ```
4. **Optionally: Remove Jammy Repo After Use:**\
   Delete or comment out the Jammy entry in `/etc/apt/sources.list`.

#### ArchLinux

There is an [AUR package](https://aur.archlinux.org/packages/defguard-client)[: defguard-client](https://aur.archlinux.org/packages/defguard-client).

If you don't know how to install AUR packages, please follow these guidelines:

* Manual install: <https://wiki.archlinux.org/title/Arch_User_Repository>
* Installation through PARU (AUR Helper): <https://owlhowto.com/how-to-install-paru-on-arch-linux/>

### Client update

Defguard Client regularly checks for updates and in order to do so operating system name and installed application version are sent to the Defguard update service.

This functionality can be turned off in the Client settings under Updates section so that no data is sent.

<figure><img src="/files/ukf2GFiIT9PfRQRVSqm9" alt=""><figcaption><p>"Check for updates" setting</p></figcaption></figure>

If a new version is available, a notification with a download button will be shown near the bottom of the menu.

<figure><img src="/files/x9VeGCh2qJmjY7qzxvKO" alt=""><figcaption><p>New Desktop Client version available for download</p></figcaption></figure>


# Instance configuration

In this guide, you will learn how to add, remove and update Instance in Defguard desktop client.

{% hint style="warning" %}
Defguard Desktop Client is required if you want to use Multi-Factor Authentication, as any other WireGuard client doesn't support this functionality.
{% endhint %}

### Obtaining URL and Token

{% hint style="info" %}
If you are looking for how to generate tokens for your users as an Administrator, look here:

[Remote desktop client configuration](/1.4/features/wireguard/remote-desktop-activation)
{% endhint %}

1. Log in to your Defguard account.
2. Go to **My Profile** tab.
3. Click **Add new device** button inside **User Devices** list.

<figure><img src="/files/03WWJ67LMj8MHFZhMmht" alt="" width="50%"><figcaption></figcaption></figure>

4. Select **Remote Device Activation** and click **Next**.

<figure><img src="/files/Pt2e4vin8EYu409orWQB" alt="" width="50%"><figcaption></figcaption></figure>

5. After that you will see URL, Token and QR Code. **Copy URL and Token.**

<figure><img src="/files/iQXgNMvHXLP2U6vZb0Wh" alt="" width="50%"><figcaption></figcaption></figure>

### Adding Instance

1. Open Defguard client
2. Click **Add Instance**.

<figure><img src="/files/GkRooEyd5lJNS53N3EWn" alt=""><figcaption></figcaption></figure>

3. Enter URL and Token, then click **Add Instance**. (If you don't have it, check out [this section](#obtaining-url-and-token))

<figure><img src="/files/J6zguuNJ3H8MWdaaa9tD" alt=""><figcaption></figcaption></figure>

### Connecting to Instance

1. Select your Instance from menu

<figure><img src="/files/AUd3Z2T73yTu1eoeMunP" alt=""><figcaption></figcaption></figure>

2. Select your location, allowed traffic then click **Connect.**

{% hint style="info" %}

* **Predefined traffic** will only route traffic specified by your administrator.
* **All traffic** will route everything through VPN tunnel.
  {% endhint %}

<figure><img src="/files/XR8YulEpl9xpOWblDxlD" alt=""><figcaption></figcaption></figure>

### Disconnecting from Instance

Click **Disconnect** next to the location you are currently connected to.

<figure><img src="/files/Savgj1i1W9WXCmKDdLpW" alt=""><figcaption></figcaption></figure>

### Updating Instance

If you want to update your instance manually:

1. Go to your Instance and click **Edit Instance**

<figure><img src="/files/ylYM4UuTAyNmfIIX7ADY" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Only tokens issued from that specific instance will work in that modal.
{% endhint %}

2. Enter Token provided by your administrator, or generate it [on your own](#obtaining-url-and-token). Then click **Update Instance**

<figure><img src="/files/7QrPwZOvS9elYdnUAvZI" alt=""><figcaption></figcaption></figure>

Your Instance will update immediately.

### Why do instances need updates?

Defguard Desktop stores all information locally and doesn't communicate with Defguard outside the registration process. This means that information about instances are snapshots of the moment you registered them in the desktop client, and you might want to update that, for example when some new locations are added or removed.

{% hint style="success" %}
If you have an Enterprise License, all desktop clients and all instances are [synchronized automatically and in real-time.](/1.4/features/remote-user-enrollment/automatic-real-time-desktop-client-configuration)
{% endhint %}

### Removing Instance

1. Go to your Instance and click **Edit Instance**

<figure><img src="/files/ylYM4UuTAyNmfIIX7ADY" alt=""><figcaption></figcaption></figure>

2. Click **Remove Instance**

<figure><img src="/files/DCKPOpItvzcWJ3LMsdRL" alt=""><figcaption></figcaption></figure>

Your Instance will be removed immediately.


# Using Multi-Factor Authentication (MFA)

{% hint style="danger" %}
Connecting to location with required **external** MFA is possible in the desktop client since [**version 1.5.0**](/1.5/using-defguard-for-end-users/desktop-client/using-multi-factor-authentication-mfa#external-mfa)**.**
{% endhint %}

## Internal MFA

1. Open Defguard client, select your Instance and click **Connect** next to location with required MFA

<figure><img src="/files/5LqwWZ2n6EcksvjkTvuJ" alt=""><figcaption></figcaption></figure>

2. Choose method configured for your account, and click **Connect**.
   * If you're using "Email" method, please enter the code sent to your email.
   * If you're using "Authenticator App", please enter code generated within your authenticator app.

{% hint style="info" %}
If you don't know how to setup or use your **Authenticator App** please check [this article](/1.4/using-defguard-for-end-users/setting-up-2fa-mfa#setting-up-2famfa) for detailed information.
{% endhint %}

<figure><img src="/files/4WYicNzPUamK19ZTNIND" alt="" width="563"><figcaption></figcaption></figure>

3. After entering code, click **Verify**

<figure><img src="/files/xN09CAhZX5SRNw4foENT" alt=""><figcaption></figcaption></figure>

Your connection will be established immediately after this step.


# CLI Client

### Downloading

Latest release page: <https://github.com/DefGuard/client/releases/tag/v1.2.0>

#### Linux (AMD64)

Deb: <https://github.com/DefGuard/client/releases/download/v1.2.0/dg-linux-x86_64-v1.2.0-dg.deb>

RPM: <https://github.com/DefGuard/client/releases/download/v1.2.0/dg-linux-x86_64-v1.2.0-dg.rpm>

Binary: <https://github.com/DefGuard/client/releases/download/v1.2.0/dg-linux-x86_64-v1.2.0-dg.tar.gz>

#### Linux (ARM64)

Deb: <https://github.com/DefGuard/client/releases/download/v1.2.0/dg-linux-aarch64-v1.2.0-dg.deb>

RPM: <https://github.com/DefGuard/client/releases/download/v1.2.0/dg-linux-aarch64-v1.2.0-dg.rpm>

Binary: <https://github.com/DefGuard/client/releases/download/v1.2.0/dg-linux-aarch64-v1.2.0-dg.tar.gz>

### Requirements

* Root access on a given machine
* Defguard proxy running and accessible from the machine the CLI will be installed on
* `resolvconf` and `ip` commands available

### Installation

Installation is straightforward. As a root, install it as any other package of a given type (deb/rpm).

#### Deb archive

```bash
apt install ./dg-linux-x86_64-v1.2.0-dg.deb
```

#### RPM

```bash
rpm -i ./dg-linux-x86_64-v1.2.0-dg.rpm
```

#### Post install

After installing the CLI, you should gain access to the `dg` command and a new `dg` service should've been created. You can interact with the client using the `dg` command alone or use the service to run it in background. You can test if the installation succeeded by trying to print the command's help:

```bash
dg --help
```

### Usage

#### Defguard Core setup

Defguard CLI works only with [network devices](/1.4/features/network-devices), so to use it, you will need to first add a new network device. Refer to the network device documentation to learn more.

After you've configured your network device on Defguard core, you will be presented with the following command:

```bash
dg enroll -u <ENROLLMENT_URL> -t <TOKEN>
```

Copy the command and proceed with [enrollment](#enrollment).

**Important**: The machine on which the `dg` command is executed must have its clock set to current date and time (possibly using Network Time Protocol). This is required to store web cookies correctly.

#### Enrollment

Execute the command obtained in the previous step to configure Defguard CLI on the machine of your choice. The enrollment command will pull all the information required to establish a connection from your Defguard instance (through the Defguard proxy, so make sure it can be accessed) and will save it in a configuration file. Run the `enroll` command only when you need to retrieve your network configuration and apply it to the CLI Client. If you have access to the enterprise features, the CLI should automatically handle this when running.

#### Connecting

After completing the enrollment, you can connect to the given network by running the following command as root:

```bash
dg
```

After executing the command you should see a message stating that you have been connected to your network of choice.

#### Automatic config fetching (polling)

If you have access to the enterprise features, CLI will periodically fetch the latest network config and apply it if it has changed. This is useful because when you edit your network configuration in Defguard core, you won't have to manually re-configure every network device.

#### Running in the background (service)

After installing the CLI, a systemd service will be automatically setup. The service won't be running at first as the manual [enrollment](#enrollment) is needed beforehand. After you've completed the enrollment, you can start the service, e.g. by doing:

```bash
systemctl start dg
```

You can configure the service and set the log verbosity by editing `/etc/defguard/dg.conf`.

### Debugging and troubleshooting

It may be easier to identify a problem by passing one of the following flags, which control the logging verbosity level:

```bash
--debug 
--verbose
```

Those flags can be passed to any command to display more detailed information about the given process.

#### Common issues and messages

```
Specified IFLA_INET6_STATS NLA attribute holds more(most likely new kernel) data which is unknown to netlink-packet-route crate
```

This shouldn't affect anything and can be ignored in most cases.


# Other WireGuard® Clients

## Installing Wireguard/VPN client

First, you have to install Wireguard application. On this [site](https://www.wireguard.com/install/) you can find information on how to download Wireguard for any operating system.

{% hint style="warning" %}
Please note that <mark style="color:red;">WireGuard clients other than</mark> [Defguard Desktop Client](/1.4/using-defguard-for-end-users/desktop-client) <mark style="color:red;">do not work with Multi-Factor Authentication</mark> <mark style="color:red;">**and they can only be used for Locations without MFA**</mark> - as the only client supporting this feature is our desktop client.
{% endhint %}

## Adding a device to connect to VPN

1. Go to **your profile** (*My Profile -* which you'll find on the navigation on the left side of the screen)
2. Click on *Add new device*

<figure><img src="/files/wpydEJ3Nfl6PwYUXNWZM" alt=""><figcaption></figcaption></figure>

3. Now you can **name your device (like Laptop, Phone, whatever you like)** and then you have two options:

<figure><img src="/files/VD8ltVOWSXYLtBliYlXv" alt=""><figcaption></figcaption></figure>

a. **Generate key pair** - if you are a new user, just select this option - it will generate a secure key pair (private and public key) - **securly in you browser (Defguard doesn't store user private keys)**

{% hint style="info" %}
Choosing this option - when you download your configuration (or use QR Code to configure Wireguard on your mobile device) - **the private key will be included in your configuration and there will be noting else you need to do**
{% endhint %}

b. **Use my own public key** - if you are an advanced user and know how to generate a key pair yourself - you can choose this option and enter **your own public key (keeping your private key to yourself)**

{% hint style="warning" %}
Choosing this option - **you will need to change PrivateKey (insert the private key you hold)** in the configuration file you download
{% endhint %}

4. Now you can **download/configure your Wireguard/VPN client by:**
   1. **downloading** the configuration
   2. **Copy** configuration to Clipboard
   3. Use Wireguard feature to configure by scanning the **QR Code**

<figure><img src="/files/Mt6Oqv9qpHBhwc51AP9M" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you have **multiple VPN locations** - you can choose to download configuration for **each of the location - by selecting the location as shown**
{% endhint %}


# Configuring a device for new VPN Location manually

If you (or your Defguard administrator) have added a new VPN Location and you would like to connect to that location from your **existing device** (for which you have downloaded configuration for any previous locations), you need to:

1. Go to **your profile** (*My Profile -* which you'll find on the navigation on the left side of the screen)
2. Click on the **gear icon on the device you want to download Location configuration** - a menu for that device will apear:

<figure><img src="/files/U65vIWnXYtn4nfyCOXL9" alt=""><figcaption></figcaption></figure>

3. Choose **Show configuration**

The same configuration screen will popup as you were adding this device, but now you can choose a new location:

<figure><img src="/files/1GoItTchPAYofxJhO4R1" alt=""><figcaption></figcaption></figure>

4. **Download and configure your Wireguard VPN** exactly the same way you did it during the [adding device process](/1.4/using-defguard-for-end-users/adding-wireguard-devices).

The configuration will be named **LocationName-device.conf** - just add a new configuration to Wireguard client.

5. **Replacing the PrivateKey**

{% hint style="danger" %}
**Defguard doesn't store any user devices' private keys - you need to provide them**
{% endhint %}

Since Defguard doesn't have access to your private keys - **but has your public key stored for that device** - you need to replace the **PrivateKey value** in the new configuration location.

{% hint style="warning" %}
**Where to find the private key for that device?**

Yon can just **copy the whole line** from any other configurations from any other working locations for that device.
{% endhint %}


# Password change / Reset

## Resetting your password

If you don't have access to Defguard you can reset your password with a link that will be sent to you on your email. Can be done in two ways:

#### Enrollment public page

The same URL you have used to do your remote enrollment & onboarding has the functionality of password reset:

<figure><img src="/files/49kyTb7FW5ySuu84ct6V" alt=""><figcaption><p>Password reset in enrollment service</p></figcaption></figure>

{% hint style="info" %}
The enrollemnt service URL should be avaialbe in the onboarding email you have received when finishing the [onboarding\&enrollment process.](/1.4/using-defguard-for-end-users/enrollment)
{% endhint %}

#### By admin

Ask your administrator to send you the password reset link.

{% hint style="info" %}
You should have you admin contact data on the onboarding message that was sent automatically after you have finished the [onboarding\&enrollment process.](/1.4/using-defguard-for-end-users/enrollment)
{% endhint %}

## Changing your password in Defguard

Go to *My Profile* and click *Edit:*

<figure><img src="/files/NQcuVe3aQlUsa5Jw0aZF" alt=""><figcaption></figcaption></figure>

Then scroll down and choose *Change Password:*

<figure><img src="/files/7IvxjJ3c8Mo5u88BPKev" alt=""><figcaption></figcaption></figure>

Set up a new secure password according to the password rules and click *Save new password*

<figure><img src="/files/a4H9sVTN8dksmz9vm55g" alt=""><figcaption></figcaption></figure>


# Enrollment & Onboarding

The enrollment process depends on your configuration:

1. If you are using[ internal Defguard's SSO](/1.4/using-defguard-for-end-users/enrollment/with-internal-defguard-sso) - then most probably Defguard is also the SSO for all your application access, meaning with Defguard's account you not only access/configure VPN but also log in to other applications. Then the process includes setting up your account as well as configuring VPN. [More details here.](/1.4/using-defguard-for-end-users/enrollment/with-internal-defguard-sso)
2. If you are using an [external SSO to login to Defguard](/1.4/using-defguard-for-end-users/enrollment/with-external-sso-google-microsoft-custom) (Google/Microsoft/Custom), then Defguard only is responsible for the VPN, and only VPN client is configured. [More details here.](/1.4/using-defguard-for-end-users/enrollment/with-external-sso-google-microsoft-custom)


# With internal Defguard SSO

Defguard provides **a secure remote enrollment process (remote registration and account activation)**, during which the user can:

* Double-check their data
* Setup their password
* Add their initial device to access VPN as a nice wizard!
* See admin (that has added this user) **contact details**

This process includes account setup and/or VPN configuration, since Defguard is used as an SSO for:

* Accessing all your applications, meaning with Defguard's account you not only access/configure VPN but also log in to other applications.
* And accessing the VPN.

All done by a nice wizard:

<figure><img src="https://github.com/DefGuard/docs/raw/docs/releases/0.7/enrollment.png?raw=true" alt=""><figcaption></figcaption></figure>

This can be done in **two ways** - either in the **browser** (web based) or by using a **Defguard desktop client**. For both ways, there is an email that is sent to the user with explanation and relevant URLs/tokens.

{% hint style="warning" %}
When starting the enrollment process - a user will have only **10 minutes** to complete the process.

The **enrollment token is valid for 24 hours.**
{% endhint %}

### Enrollment using desktop client

In the desktop client, **when adding an instance** - the enrollment & onboarding process takes place.

What is great about this is that after the enrollment process is done - the desktop client is **automatically configured with all available VPN locations for the user.**

### **Web/browser based enrollment**

When accessing the enrollment service in the browser, the process is extended with the possibility to configure the **initial VPN device/access manually.**

{% hint style="info" %}
Even if the user will do enrollment in the browser - the desktop client can be configured later by using: [Remote desktop client activation.](/1.4/features/wireguard/remote-desktop-activation)
{% endhint %}

## User onboarding after enrollment

After the enrollment process, new users are provided with **any relevant company information, links to company systems, security guidelines**, etc.

The onboarding messages will be shown on the **last step of the enrollment process and sent to the user via email**:

<figure><img src="https://github.com/DefGuard/docs/raw/docs/releases/0.7/enrollment_msg.png?raw=true" alt=""><figcaption><p>Onboarding process</p></figcaption></figure>


# With external SSO (Google/Microsoft/Custom)

In this scenario, Defguard is only the VPN system and enrollment is used just to obtain credentials to configure the [Defguard Desktop Client](/1.4/using-defguard-for-end-users/desktop-client).

Please go to the enrollment URL, like: <https://enrollment.company.com> and choose Enrollment:

<figure><img src="/files/HTUnRI7UChszN0Bl3KPm" alt="" width="563"><figcaption></figcaption></figure>

Then all you have to do is click on your SSO login - the button name depends on the SSO you have configured:

<figure><img src="/files/c43On2daq7t9OGN9LI96" alt=""><figcaption></figcaption></figure>

Now log in with your SSO and after successful login process, you will receive information how to configure your desktop client:

<figure><img src="/files/Gnh5WOUabwRANTNIAhHk" alt=""><figcaption></figcaption></figure>

Download the [Defguard desktop client](https://defguard.net/download/), and [enter *Instance URL* and *token* shown on this screen - more details here](broken://pages/Pvsv731zze0GmV33wtUl#automatic-with-defguard-client).


# Setting up 2FA/MFA

Go to *My Profile* and click *Edit:*

<figure><img src="/files/NQcuVe3aQlUsa5Jw0aZF" alt=""><figcaption></figcaption></figure>

Then scroll down to the section *Two-factor methods* and choose which one you want to activate.

{% hint style="info" %}
Whatever the method you will choose to configure next, please be prepared to do backup of your **Recovery backup codes** - as those are generated during the initial/first setup.
{% endhint %}

### One time password

This method is based on time-based codes (TOTP), generated by an app.

Before you start to configure this step, you need to choose an app for generating your TOTP codes. Most popular are:

* [Google Authenticator for Android/iPhone/iPad](https://support.google.com/accounts/answer/1066447)
* [Bitwarden](https://bitwarden.com/help/authenticator-keys/) - which is a password manager which can help you to store/generate a secure password for your Defguard login but also setup TOTP

In this example, we will set up using Google Authenticator.

Click on the *gear* icon for *One time password* and ***Enable**:*

<figure><img src="/files/EfK7rxsjQr7dLEL65TVn" alt=""><figcaption></figcaption></figure>

A set up screen will show up with a QR Code:

<figure><img src="/files/aK9Gu2OpalK8gd1Gjp6E" alt=""><figcaption></figcaption></figure>

Now open *Authenticator* mobile app, and click: ***Add a code -> Scan a QR code*****&#x20;and scan the QR Code with the app**.

After doing that, a new screen will show on the *Authenticator* app, that will generate codes for Defguard:

<figure><img src="/files/HNrt5AYucUrfhclrbtHX" alt="" width="188"><figcaption></figcaption></figure>

**Enter the code you see on the mobile app**, to confirm, that the process has been done correctly (Defguard will now validate the code).

After the code has been validated, either:

* you are all set, the method is enabled, and you will be logged out to log in again using MFA
* or you [will need to create a backup of your recovery codes](#backing-up-recovery-codes) - and after that you will be logged out as well.

### Backing up recovery codes

If you are configuring the 2FA/MFA for the first time with any selected method, at the end of the process you will be asked to create a backup of your recovery codes:

<figure><img src="/files/h5pZesI2FlB39jMphNGV" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
Please backup those codes in a safe place, if you will not be able to login with your 2FA method (eg. you lost your phone or YubiKey hardware key) - the only method to login will be to use one of the **recovery codes.**
{% endhint %}


# Step by step setting up a VPN server

### Introduction

This tutorial aims to show how quick and easy it is to deploy your VPN server using Defguard.

This tutorial is also available as a video:

{% embed url="<https://www.youtube.com/watch?v=MqlE6ZTn0bg>" %}

We assume you have:

* a **server with a public IP** (and you know what that IP address is and to which interface it's assigned) - in this example it's: *185.33.37.51*
* you have a **domain name** and know how to assign IP and manage subdomains, in our example:
  * Defguard main URL will be *my-server.defguard.net* (and the subdomain is pointed to *185.33.37.51*)
  * Defguard enrollment service that will enable to easily configure Desktop Clients just with one token is: *enroll.defguard.net* (this subdomain also points to *185.33.37.51*)
* server is Debian/Ubuntu-based
* have installed the [official Docker Engine](https://docs.docker.com/engine/install/debian/#install-using-the-repository) and [docker-compose](https://docs.docker.com/compose/install/standalone/#on-linux) (from our experience it's better to use the official Docker Engine then docker shipped with distro packages - but this should also work with distro packages) and have
* VPN network will be: 10.22.33.0/24 - but you can assign [any private network address](https://en.wikipedia.org/wiki/Private_network) and use it in this tutorial - we will name it *Example*
* If you have a **firewall**, we assume you have **open ports** (if not, below we will show you how to enable and secure your server):
  * 443 - in order to expose both Defguard & enrollment service - but also to automatically issue for these domains SSL Certificates (which the installer script does)
  * 50555 - on this port, the WireGuard VPN server will be listening for incoming connections from clients

### Deploying your VPN server

Deployment is really easy and will be done automatically if you follow these steps.

There are multiple ways to install Defguard tailored to your network & infrastructure - in fact, Defguard as a VPN server is one of the few to support secure deployments with network segmentation and secure communication, but for the purpose of this tutorial we will do the **easiest setup** and install all components on this server using docker & docker-compose. The installation process will also **automatically configure and deploy all your services and issue SSL certificates.**

To do so, just execute by **root** this simple command and follow the instructions:

```
curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh -O && bash setup.sh
```

In this example, we are answering the questions with the following answers:

```
Enter Defguard domain [default: ]: my-server.defguard.net
Enter enrollment domain [default: ]: enroll.defguard.net
Use HTTPS [default: false]: true
Enter VPN location name [default: ]: Example
Enter VPN server address and subnet (e.g. 10.0.60.1/24) [default: ]: 10.22.33.1/24
Enter VPN gateway public IP [default: ]: 185.33.37.51
Enter VPN gateway public port [default: ]: 50555
```

When finished, you should see the following message:

```
Defguard setup finished successfully
If your DNS configuration is correct, your Defguard instance should be available at:

	Web UI: https://my-server.defguard.net
	Enrollment service: https://enroll.defguard.net

You can log into the UI using the default admin user:

	username: admin
	password: bQ63RSp4o5ZAnIkv
```

<mark style="color:blue;">**And voilà! It was that easy!**</mark>

When you log in to your instance with user admin and the password that was generated for you, you should see that the VPN gateway is connected:

<figure><img src="/files/a2MZelFtGVCE5gyjGtju" alt=""><figcaption><p>Defguard live status of WireGuard VPN gateway</p></figcaption></figure>

### Connecting to your VPN using Defguard desktop client

Download the latest client from: <https://github.com/DefGuard/client/releases> and install it - which is (during writing this article) version 0.1.1.

Now, go to **Defguard** Web UI (in this example: *<https://my-server.defguard.net>*) and go to *My Profile* and click on *Add Device:*

<figure><img src="/files/bvf8WqUfC0fw63P7Z4a1" alt=""><figcaption><p>Adding a new device/desktop client in Defguard user profile</p></figcaption></figure>

Then choose *Defguard Client Remote Desktop Activation* - which will easily configure your Desktop client:

<figure><img src="/files/jXwjwKqun0c7qLekxfME" alt=""><figcaption><p>Defguard supports both desktop client and configuring any WireGuard Client</p></figcaption></figure>

Defguard will show what **URL** (which is - as you see - your enrollment service URL) and **token** to paste to your desktop client:

<figure><img src="/files/McMsS8akP0QUIMryzxgl" alt=""><figcaption><p>Just by simply providing URL &#x26; token, your client will be automatically configured</p></figcaption></figure>

You can easily copy those with buttons provided in Defguard, and paste to your desktop client.

In desktop client, click on \_**+ Add instance** \_ and provide the URL and token:

<figure><img src="/files/KVJwS62cBkjq9vhkgXO4" alt=""><figcaption><p>Configuring the client with a new instance</p></figcaption></figure>

After that, the client will ask you to name your device (however you like), after that click finish:

<figure><img src="/files/lqOybOxbMIqxRAfWBYgp" alt=""><figcaption><p>Naming your device</p></figcaption></figure>

The client will instantly show your Defguard instance and the VPN (we named *Example):*

<figure><img src="/files/kWTAeWp4EVQq3bAVfCRs" alt=""><figcaption><p>Client after successfully adding a new instance</p></figcaption></figure>

Also, you should see in your profile, that the client is configured and visible (for now - no details of IPs, etc - will automatically show details when you connect with your client):

<figure><img src="/files/4xLU4pcfFjgbQAvrxfxh" alt=""><figcaption><p>Defguard showing the newly configured client in user profile</p></figcaption></figure>

Now let's click ***Connect*** and see if the VPN works, the best way to do so, is to open a terminal app and **ping** the VPN server address. Also to see nice statistics, choose in the client menu from *Grid view* (which is nice if you have multiple VPNs) the option *Detailed view:*

<figure><img src="/files/npbSS3HsZkNmmCvcFL4u" alt=""><figcaption><p>Nice statistics in Defguard client</p></figcaption></figure>

Now let's test if the VPN network is accessible. To do so, let's ping the VPN gateway internal IP: *10.22.33.1*

<figure><img src="/files/iual94ZRm0PUgltjimWX" alt=""><figcaption><p>VPN gateway responding to ping after connecting to VPN</p></figcaption></figure>

As an administrator, you will probably be happy to see this - Defguard VPN dashboard:

<figure><img src="/files/2pZj0WOvBlGJcqzInyiu" alt=""><figcaption><p>Defguard VPN dashboard</p></figcaption></figure>

{% hint style="info" %}
This completes your VPN setup - both server and client.

But if you would like to configure your VPN server to allow accessing Internet through the VPN gateway, please read the chapter below.
{% endhint %}

### Adding new location

If you would like to have multiple VPN locations - [please read this tutorial how to add another location in this setup.](/1.4/tutorials/step-by-step-setting-up-a-vpn-server/adding-additional-vpn-locations)

### Enabling to access Internet through your VPN

The most common purpose to set up your own VPN is to provide you (and your users - Defguard supports multiple users!) **anonymity and privacy** when accessing public internet.

It's great for everyday use (if you want to *hide* your real IP/location) or for example to encrypt **all your traffic when you are in a public location -** like being on Wi-Fi in a coffee shop, hotels, etc. - since **most if not all those places do not provide encrypted Wi-Fi (just open hotspots).**

So Defguard as a VPN service is one thing, but we need to do a few commands on the server, to enable routing all traffic through this server and your VPN. For your convenience, those we will explain in detail.

First of all we need a simple and easy way to manage firewall. In order to do so on Debian, install UFW (it's automatically installed on Ubuntu):

```
root@server# apt install ufw
```

Now let's enable on the firewall rules that provide packet forwarding (from your VPN to the Internet and vice versa).

Edit the /etc/default/ufw file to enable default policies for packet forwarding to ACCEPT

```
root@server:~# vi /etc/default/ufw
# line 19 : change
DEFAULT_FORWARD_POLICY="ACCEPT"

# reload
root@server:~# ufw reload
```

Edit the /etc/sysctl.conf file to enable pocket forwarding in the kernel:

```
root@server:~# vi /etc/sysctl.conf
# line 28 : uncomment
net.ipv4.ip_forward=1

# reload settings
root@server:~# sysctl -p
```

Now we need to configure firewall [NAT](https://en.wikipedia.org/wiki/Network_address_translation), so that the server will "*translate/masq*" VPN traffic behind its public IP. In order to do that, we need to add rules to MASQUERADE VPN network behind the public interface of the server.

{% hint style="info" %}
From version 1.3.0, gateway can automatically apply masquerade to traffic on all interfaces without the need for manual configuration. Refer to [Access Control List](/1.4/features/access-control-list#masquerade) for details. If you use this feature, you can skip the following manual masquerade setup step.
{% endhint %}

We know that VPN network is 10.22.33.0/24 now we need to be sure what interface has the public IP (in our case: 185.33.37.51) - let's figure it out with this command:

```
root@server:~# ip a | grep 185.33.37.51
    inet 185.33.37.51/24 brd 185.33.37.255 scope global ens18
```

So, our public interface is: **ens18**

Now just add the following to /etc/ufw/before.rules **just before the filter rules**:

```
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]

# Forward VPN network traffic through ens18 - Change to match your egress interface
-A POSTROUTING -s 10.22.33.0/24 -o ens18 -j MASQUERADE

# don't delete the 'COMMIT' line or these NAT table rules won't
# be processed
COMMIT
```

A typical ufw configuration is that INPUT traffic is disabled, so we need to open ports for our WEB and WireGuard gateway:

```
# allow HTTPS to access defguard
root@server# ufw allow https

# allow WireGuard VPN which is on port 50555 with UDP protocol
root@server# ufw allow 50555/udp

# for the time being, you might also consider to allow SSH management
# until you learn how to allow traffic to SSH from VPN
root@server# ufw allow ssh
```

On Ubuntu, UFW is enabled by default, but on Debian it has to be enabled manually:

<pre><code><strong>root@server# ufw enable
</strong>Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
</code></pre>

On Ubuntu, we need to reload the configuration:

<pre><code><strong>root@server# ufw reload
</strong></code></pre>

Let's check the UFW configuration, should look like this:

```
root@server# ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
50555/udp                  ALLOW IN    Anywhere
22/tcp                     ALLOW IN    Anywhere
443                        ALLOW IN    Anywhere
50555/udp (v6)             ALLOW IN    Anywhere (v6)
22/tcp (v6)                ALLOW IN    Anywhere (v6)
443 (v6)                   ALLOW IN    Anywhere (v6)
```

#### Testing your configuration with Defguard client

Defguard is the only (known to us) WireGuard client that during connection provides a choice to **route all your traffic through the VPN.** Just (before connecting) choose the option: **Allow all traffic** and click connect!

<figure><img src="/files/l8BosdlGax2Tmak6aAPs" alt=""><figcaption><p>Choosing to forward all traffic through VPN</p></figcaption></figure>

This is very useful, since some times you just want to be connected to your VPN to have the server/VPN networks accessible, and sometimes (like in the scenarios mentioned before) you want to hide and encrypt your traffic.

In order to check if everything works, let's visit a website <https://ifconfig.co> - that will show our public IP. If everything went smoothly, you should see **your VPN server public IP** (which in our example is: *185.33.37.51*):

<figure><img src="/files/ooAuGkhw0ImhMGhQg22i" alt=""><figcaption><p>Success! Defguard is AWESOME!</p></figcaption></figure>

## Final thoughts

We put a lot of effort in development, testing, and documentation - to make difficult things like security, VPN easy and good-looking. So for now, we kindly ask you to:

* star us on GitHub: <https://github.com/defguard/defguard>
* and spread the word about Defguard however you like!

Thank you from the whole [Defguard team.](https://teonite.com)


# Adding additional VPN locations

If you have used our one-line install setup (for example [described in this tutorial](/1.4/tutorials/step-by-step-setting-up-a-vpn-server)) one VPN location (one gateway instance) is done automatically.

There is often a need to launch additional locations (e.g. to separate groups of users or clients), to do this you need to add another location (and launch another gateway controlling this location).

Here is a step-by-step way to do so:

### Adding a new Location

In Defguard interface in VPN Location, please click: **Edit location settings** (button in the top right corner):

<figure><img src="/files/mqEbTIgzE23Rnri7nf6K" alt=""><figcaption></figcaption></figure>

Then ***Add new location*** and configure the new VPN location.

{% hint style="danger" %}
Without specified DNS field desktop client may be unable to use "All traffic" connection for the location.
{% endhint %}

{% hint style="warning" %}
Remeber that the:

* VPN IP address needs to be different then in the first location
* Gateway address should be the same (same public IP)
* Gateway port **must be different - and** remember that gateway port **must be open on firewall** (this is the new VPN location WireGuard port)
  {% endhint %}

After configuring the location, please:

* copy the gateway token
* and note that the gateway is disconnected

<figure><img src="/files/r6ZWPC93VhTK1TZvmDlU" alt=""><figcaption></figcaption></figure>

### Adding new gateway in docker

Now go to the server and open the docker-compose.yml file, and scroll to the gateway section, it should look like this:

<figure><img src="/files/UzmsE1PwiJyMVYxaFIIK" alt=""><figcaption></figcaption></figure>

Now copy the **whole gateway section and:**

* **name it in a uniqe way,** eg. *gateway-customer2*
* in the enviroment variable `DEFGUARD_TOKEN`: add the token you have copied from the new location
* **add the following line below the&#x20;*****image*****&#x20;-** to change the second gateway WireGuard interface:

```yaml
    command: ["-i", "wg1"]
```

{% hint style="danger" %}
**If you will not add the command line, both gateways will use by default the wg0 and both will not work.**
{% endhint %}

The configuration should like so:

<figure><img src="/files/gFXtgQvRXojLo8nUefPW" alt=""><figcaption></figcaption></figure>

Now you need to launch the new gateway, just by the following command:

```
docker compose up -d gateway-customer2
```

<figure><img src="/files/spVdSemCXPTXTbrnqvph" alt=""><figcaption></figcaption></figure>

Now if you go back to the location settings you will see **instantly that the new gateway has connected for that location:**

<figure><img src="/files/5UjactdONnJJ6I7wjNPp" alt=""><figcaption></figcaption></figure>

And that's it, you have a new VPN location ready.


# Architecture Decision Records

What are Defguard's Architecture Decision Records?

[Architecture Decision Records](https://github.com/joelparkerhenderson/architecture-decision-record) (ADRs) are concise documents that capture important architectural decisions made during the lifecycle of a software system.

Each ADR focuses on a single decision, detailing the context, the decision itself, the alternatives considered, and the consequences of the chosen approach. They are critical for maintaining architectural clarity, especially in complex or long-lived projects where decisions can outlast the original developers.

By documenting the rationale behind architectural choices, ADRs promote transparency, enable easier onboarding of new team members, and help avoid repeating past mistakes. They also support better communication across teams by providing a lightweight, structured way to preserve architectural knowledge over time.


# 1.4

## 2025-06-01 Assign all IP addresses to clients

Up to this point, only the first network IP address was assigned to devices, as described in \[ADR]\(<https://docs.defguard.net/in-depth/architecture-decision-records/pre-1.3#id-2025-01-03-multiple-ip-addresses>). This was an artificial limitation, and many customers were interested in being able to assign multiple addresses (IPv4 and IPv6) to user devices. v1.4 introduces changes to user device model as well as desktop client code that allows assignment of all network IPs.


# 1.3

## 2025-04-24 ACL alias types

We decided to introduce two ACL alias types to explicitly define how to handle them when generating firewall rules:

* Destination aliases - define a complete destination (like an ACL itself) and are translated into a dedicated set of firewall rules; in effect those work like pre-defined destinations
* Component aliases - define a part of a destination (IPs, ports, protocols or any combination of those) and are combined with the inputs configured manually for an ACL - IPs are added to ACL IPs etc.


# Pre-1.3

## 2025-01-03 – Multiple IP addresses

WireGuard network interface can be assigned multiple IP addresses (both IPv4 and IPv6). The first address (leftmost on the interface configuration) is the primary address, and this one will be used for IP address assignment for devices. The other IP addresses are auxiliary and are not managed by Defguard.

## 2024-11-14 – Use Authorization Code flow for external OpenID

Abandon Implicit flow, which is not recommended.

## 2024-11-11 – Require User-Agent HTTP header for login

User-Agent header is set by all HTTP clients, including [Curl](https://curl.se), so there is no point to make it optional. That also simplifies the code.

## 2024-09-07 - Typestate pattern to make working with optional ids easier

* There is a recurring issue with optional ids for database objects. Until such object is saved to database, it’s id is none. Because of this it is necessary to check for id presence whenever such objects are used, even if we know that those objects come from database and must have ids. This leads to unnecessary `.expect() / .unwrap()`s.
* Typical object with optional Id looks like this:

```
#[derive(Debug)]
pub struct WireguardKeys {
    pub id: Option<i64>,
    pub instance_id: i64,
    pub pubkey: String,
    pub prvkey: String,
}
```

* To fix this we introduce a generic type \<I> that defines type of id field
* The generic type can take one of two variants
* We split impl blocks into \<Id> and \<NoId> appropriately - the idea is that objects coming from database are \<Id>, methods like `new()` return \<NoId>

```
// Id variants
pub type Id = i64;
pub struct NoId;

// Generic id type used in the structure
#[derive(Debug)]
pub struct WireguardKeys<I = NoId> {
    pub id: I,
    pub instance_id: i64,
    pub pubkey: String,
    pub prvkey: String,
}

// Impl blocks split between the variants
impl WireguardKeys<Id> {
    pub async fn find_by_instance_id<'e, E>(
        executor: E,
        instance_id: i64,
    ) -> Result<Option<Self>, SqlxError>
        where
            E: sqlx::Executor<'e, Database = sqlx::Sqlite>,
    {
        query_as!(
            Self,
            "SELECT id \"id: _\", instance_id, pubkey, prvkey \
            FROM wireguard_keys WHERE instance_id = $1;",
            instance_id
        )
        .fetch_optional(executor)
        .await
    }
}

impl WireguardKeys<NoId> {
    #[must_use]
    pub fn new(instance_id: i64, pubkey: String, prvkey: String) -> Self {
        WireguardKeys {
            id: NoId,
            instance_id,
            pubkey,
            prvkey,
        }
    }
}
```

## 2024-09-06 – External OpenID login

* Currently our OpenID login implementation matches the user by email. This is not a standard practice, as most services use the “sub” field (a guaranteed unique identifier) to identify the user (e.g. matrix/element). Our approach may be problematic when the email changes on the provider’s side (it may be unlikely in the case of google or Microsoft but may happen in the case of keycloak).
* To prevent such scenario and to standardize our approach, we could add a “sub” field to the user and perform OpenID login on its basis. Additionally, if we’d like to link existing Defguard accounts with the external provider, we could try to also match by email on first user login and then use the sub field only on subsequent login attempts. This doesn’t seem to require a massive rework of already existing code.

## 2024-09-02 – Client configuration updates

* Since client <→ proxy communication is REST, easiest way to implement client config updates (“make it work, make it right, make it fast”, “good enough”) is with HTTP polling requests
* As a consequence, updates are not immediate, worst case scenario update arrives at client after full polling interval
* Objects that DON’T need to be updated in the client database:
  * WireGuard keys - since client does not implement key management features, updating public key in client db guarantees that the client won’t be able to connect to the gateway (public-private keys don’t match)
  * only way to update keys at this point is using standard enrollment procedure
  * Instances - effectively only the `name` field may change, we can deal with it later maybe
* Objects that need to be updated in client DB:
  * Instance locations - those contain all the necessary configuration that make connecting to the gateway possible and define parameters like `allowed_ips`, `dns` etc.
* We can’t simply update the locations whenever they change, client may be connected to one of the locations that get removed in the update and we end up in invalid state.
* Solution:
  * After detecting changes in the configuration, polling mechanism checks if there are any active connections for given instance
  * If there are no active connections, update the database
  * If there are active connections, display the message “Configuration updated for instance \<name>, disconnect all locations to apply changes”
  * On each disconnect trigger the polling mechanism


# Architecture

By design **Defguard core (the main component) is meant to be deployed in your secure network segments** (available only from an internal network or by VPN) and operations that require public access (like user onboarding, enrollment, password reset, etc.) **are done using a secure proxy:**

<figure><img src="/files/S6e2EFeZeMpSWKlXSOuU" alt=""><figcaption><p>Defguard architecture</p></figcaption></figure>

This approach is vastly different from most (if not all) VPN/IdP solutions, which are a simple or monolithic application focus on functionalities (like generating configs, managing users, etc.) and most of the time is publicly available on the Internet for any attacker.

If you want full privacy, Defguard only exposes publicly **components designed for this purpose:**

* WireGuard® gateway - to enable VPN access
* Public Proxy for secure remote processes like:
  * [User enrollment and onboarding](/1.4/features/remote-user-enrollment)
  * [Desktop Client configuration](/1.4/features/remote-user-enrollment/automatic-real-time-desktop-client-configuration)

## C4 component model

Below you can see Defguard architecture in [C4 model](https://c4model.com/) divided into context, containers and components.

## Context

![Context look at Defguard architecture](/files/Hkd3y5EsNbORNoTuWL25)

## Containers

![Containers look at Defguard architecture](/files/QFPT5rJV8w6eirjlP3Tf)

## Components

![Components look at Defguard architecture](/files/4swQ64iO1EYeqDFerDwX)

### Basics

Core is a Rust web server which is exposed as REST API and gRPC web server with typescript and rust clients, it handles connection to database, LDAP server and gateway. Core also handles user authorization via LDAP account. It's configurable using Environmental Variables which you can find [here](/1.4/deployment-strategies/configuration).

Gateway is a small CLI gRPC client written in Rust which sends network statistics to Core server and apply network configuration changes on message from core.\
Our frontend is React app written in Typescript which allows handling all API calls via Web UI.\
See detailed gRPC docs [here](https://google.com).

### Example setup flow

After creating your network in our wizard and running our gateway program core will message it with network data. Gateway after receiving data will set up your network using WireGuard commands you can think of it like a wrapper on WireGuard commands which also sends network information through gRPC. After successfully setting up your network gateway will start sending your networks stats in period given as argument on gateway program start or if not provided at default which is 60 seconds. You can see all of your network statistics, connected users, bandwidth, user devices on the overview page.




---

[Next Page](/llms-full.txt/1)

