Ansible Role: SWAG (Secure Web Application Gateway)
We've released a new Ansible Role to deploy the SWAG (Secure Web Application Gateway) reverse-proxy server created by linuxserver.io. This role installs the SWAG Docker image on Linux systems running Docker.
Repository: linuxserver/docker-swag
What is SWAG?
SWAG (Secure Web Application Gateway, formerly known as letsencrypt) sets up an Nginx webserver and reverse proxy with PHP support and a built-in certbot client for automated SSL certificate generation and renewal (Let's Encrypt and ZeroSSL). It also includes fail2ban for intrusion prevention.
Certbot Plugins
SWAG includes many Certbot plugins out of the box. If you need a plugin that's not included, use the Universal Package Install Docker Mod:
environment:
DOCKER_MODS: linuxserver/mods:universal-package-install
INSTALL_PIP_PACKAGES: certbot-dns-<plugin>
Set the required credentials in /config/dns-conf/<plugin>.ini
. Test with STAGING=true
first.
Security and Password Protection
- SWAG detects changes to URLs and subdomains, revokes existing certs, and generates new ones on start.
- To password-protect your sites, use htpasswd:
- For additional users, omit the
-c
flag. - LDAP authentication is also supported (see the provided
ldap.conf
and use thelinuxserver/ldap-auth
image).
Site Config and Reverse Proxy
- Default site config:
/config/nginx/site-confs/default.conf
- Add or modify conf files in this directory. Deleting the default will recreate it on container start.
- Preset reverse proxy configs for popular apps are available in
/config/nginx/proxy_confs
. - To hide your site from search engines, add this to your site config:
- To redirect HTTP to HTTPS, expose port 80.
Using Certs in Other Containers
- Mount the SWAG config folder in other containers to use certs:
- Or, mount only the
/etc
subfolder for more security:
Using fail2ban
- SWAG includes fail2ban with 5 default jails.
- To check status:
- To unban an IP:
- See fail2ban commands for more.
Updating Configs
- Config updates are noted in the changelog but not automatically applied.
- If you have modified a config file, review changes and apply manually, or delete and restart the container to regenerate.
- Proxy sample updates are not listed in the changelog. See reverse-proxy-confs commits.
Example Playbook
This example installs Docker and the SWAG reverse proxy container with most defaults. Set swag__url
to your own domain and subdomains as needed.
Note: This playbook uses another role,
bsmeding.docker
, to install Docker. Install it withansible-galaxy role install bsmeding.docker
or install Docker manually and comment out the first task.
---
- name: Install DMZ
hosts: [dmz]
gather_facts: true
become: yes
vars:
swag__port_web: 80
swag__port_ssh: 443
swag__url: 'example.com'
swag__subdomains: 'www'
swag__validation: 'http'
tasks:
- name: Check if docker is installed
ansible.builtin.include_role:
name: bsmeding.docker
- name: Check if SWAG is installed
ansible.builtin.include_role:
name: bsmeding.docker_swag
Subdomain Reverse Proxy Example
To use the reverse proxy, templates are available so you don't have to create Nginx config files yourself. For example, to point https://dash.example.com
to http://192.168.111.241:9090
:
swag__proxy_confs_subdomain:
- server_name: dash.example.com
listen: 443
default_upstream_proto: http
default_upstream_url: 192.168.1.10
default_upstream_port: 9090
Variables
A selection of variables you can use (see the role for full list):
Variable | Default Value | Description |
---|---|---|
swag__name |
swag |
The name of the container. |
swag__image |
lscr.io/linuxserver/swag |
The Docker image to use for SWAG. |
swag__port_web |
80 |
Port for web traffic. |
swag__port_ssh |
443 |
Port for SSH/SSL traffic. |
swag__skip_setup |
false |
Set to true to disable the setup stage of the SWAG image. |
swag__url |
'example.com' |
The base URL for the SWAG setup. |
swag__subdomains |
'www' |
Subdomains for the SWAG setup. |
swag__validation |
'http' |
Method of validation (http or dns ). |
swag__certprovider |
'' (optional) |
Certificate provider (e.g., zerossl ). |
swag__dnsplugin |
'' (optional) |
DNS plugin (e.g., cloudflare ). |
swag__cloudflare_global_email |
'' (optional) |
Cloudflare global email (if using Cloudflare DNS plugin). |
swag__cloudflare_global_api |
'' (optional) |
Cloudflare global API key (if using Cloudflare DNS plugin). |
swag__cloudflare_api_token |
'' (optional) |
Cloudflare API token (if using Cloudflare DNS plugin). |
swag__email |
'mail@example.com' |
Email for certificate provider notifications. |
swag__only_subdomains |
'false' |
Use only subdomains for the SSL certificate. |
swag__extra_domain |
'' |
Additional domains for the SSL certificate. |
swag__staging |
'true' |
Use staging environment (recommended for testing with Let's Encrypt). |
swag__docker_mods |
'linuxserver/mods:swag-cloudflare-real-ip' |
Docker mods to use with SWAG. |
swag__remove_existing_container |
no |
Remove any existing container before creating a new one. |
swag__remove_existing_home_dir |
no |
Removes the home directory (for testing purposes only!). |
swag__pull_image |
yes |
Pull the Docker image if not already pulled. |
swag__network_mode |
'default' |
Network mode for Docker container. |
swag__network_cidr |
'172.16.81.0/26' |
CIDR for network configuration. |
swag__network |
'proxy' |
Network to connect the container to. |
swag__container_networks |
[{'name': 'bridge'}, {'name': swag__network}] |
List of networks for the container to join. |
swag__purge_networks |
no |
Remove all networks upon container removal. |
swag__log_driver |
'json-file' |
Log driver for Docker. |
swag__log_options |
{} |
Additional options for the log driver. |
swag__home |
"/opt/{{ swag__name }}" |
Home directory for SWAG files. |
swag__use_local_directories_instead_of_volumes |
true |
Use mapped folders instead of volumes (volumes not set up). |
swag__directories |
List of directories with paths and permissions | Directories to create with specific permissions. |
swag__ports |
["{{ swag__port_web }}:80", "{{ swag__port_ssh }}:443"] |
Ports to expose for SWAG container. |
swag__directory_volumes |
["{{ swag__home }}/config:/config"] |
Directory volumes for the container. |
swag__file_volumes |
["/var/run/docker.sock:/var/run/docker.sock:ro"] |
File volumes for the container. |
swag__default_env |
Various defaults (see below) | Default environment variables for the SWAG container. |
swag__env |
{} |
Additional environment variables. |
swag__proxy_confs_subdomain |
List of subdomain configuration proxies | Subdomain proxy configurations for different applications. |
Default Environment Variables (swag__default_env
)
TZ
: Time zone for the container (default:Europe/Paris
).PUID
: User ID for Docker (default:1040
).PGID
: Group ID for Docker (default:1001
).URL
: Base URL for SWAG.SUBDOMAINS
: Subdomains to use (default:www
).VALIDATION
: Validation method (default:http
).CERTPROVIDER
: Certificate provider (optional).DNSPLUGIN
: DNS plugin (optional).EMAIL
: Email for certificate notifications.ONLY_SUBDOMAINS
: Use only subdomains (default:false
).EXTRA_DOMAINS
: Extra domains for SSL (optional).STAGING
: Use staging environment for testing (default:false
).DOCKER_MODS
: Docker mods (optional).CF_ZONE_ID
,CF_ACCOUNT_ID
,CF_API_TOKEN
: Cloudflare credentials if using Cloudflare DNS validation.
Proxy Configuration Examples
In swag__proxy_confs_subdomain
, you can configure additional subdomain proxies as follows:
swag__proxy_confs_subdomain:
- server_name: dash.example.com
listen: 443
enable_ldap: false
enable_authelia: true
default_upstream_proto: http
default_upstream_url: dashboard
default_upstream_port: 9090
- server_name: app1.example.com
listen: 443
enable_ldap: false
enable_authelia: false
default_upstream_proto: http
default_upstream_url: 192.168.1.10
default_upstream_port: 8080