143 lines
4.0 KiB
Markdown
143 lines
4.0 KiB
Markdown
# nginx-proxy + acme-companion
|
|
|
|
Automated reverse proxy with Let's Encrypt SSL certificates.
|
|
|
|
## Setup
|
|
|
|
1. Create the data directories:
|
|
```bash
|
|
sudo mkdir -p /srv/nginx-proxy-acme/{certs,vhost.d,html,conf.d,acme}
|
|
```
|
|
|
|
2. Copy configuration files:
|
|
```bash
|
|
sudo cp conf/conf.d/* /srv/nginx-proxy-acme/conf.d/
|
|
sudo cp conf/vhost.d/* /srv/nginx-proxy-acme/vhost.d/
|
|
```
|
|
|
|
3. Configure environment:
|
|
```bash
|
|
cp .env.example .env
|
|
# Edit .env with your email
|
|
```
|
|
|
|
4. Start the proxy:
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
## Architecture
|
|
|
|
- **nginx-proxy**: Reverse proxy with auto-discovery of Docker containers
|
|
- **acme-companion**: Automatic Let's Encrypt certificate management
|
|
- **static-certs**: Dummy container that triggers cert issuance for non-container backends
|
|
|
|
## Security
|
|
|
|
All hosts receive these security features via `vhost.d/default`:
|
|
- **HSTS**: Strict-Transport-Security header (1 year)
|
|
- **Security headers**: X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy
|
|
- **Block exploits**: WAF rules against SQL injection, XSS, file injection, spam, bad user agents
|
|
|
|
## Access Control
|
|
|
|
### Private Hosts (IP restricted)
|
|
|
|
Private hosts include `vhost.d/private` which restricts access to:
|
|
- 192.168.1.0/24 (local network)
|
|
- 172.16.0.0/12 (Docker networks)
|
|
|
|
To make a new host private, create a vhost.d file:
|
|
```bash
|
|
echo 'include /etc/nginx/vhost.d/private;' | sudo tee /srv/nginx-proxy-acme/vhost.d/myapp.kolpacksoftware.com
|
|
```
|
|
|
|
### Public Hosts
|
|
|
|
Public hosts have no vhost.d file (only `default` applies). They get security headers and block-exploits but no IP restrictions.
|
|
|
|
Current public hosts:
|
|
- chd.kolpacksoftware.com
|
|
- linkding.kolpacksoftware.com
|
|
- organizer.rmstsa.org
|
|
- ridge-resources.org
|
|
- rmstsa.org / www.rmstsa.org
|
|
- share.kolpacksoftware.com
|
|
- vikunja.kolpacksoftware.com
|
|
|
|
## Adding a Proxied Service
|
|
|
|
Add these environment variables to any container:
|
|
|
|
```yaml
|
|
services:
|
|
myapp:
|
|
image: myapp:latest
|
|
environment:
|
|
- VIRTUAL_HOST=myapp.kolpacksoftware.com
|
|
- VIRTUAL_PORT=8080
|
|
- LETSENCRYPT_HOST=myapp.kolpacksoftware.com
|
|
networks:
|
|
- npm-network
|
|
|
|
networks:
|
|
npm-network:
|
|
external: true
|
|
```
|
|
|
|
Then if private, add the vhost.d file as shown above.
|
|
|
|
## Static IP Backends
|
|
|
|
Services running on physical hosts or VMs (not Docker) are configured in `conf.d/static-upstreams.conf`:
|
|
|
|
| Domain | Backend |
|
|
|--------|---------|
|
|
| portainer.kolpacksoftware.com | 172.17.0.1:9443 |
|
|
| btt-cb1.kolpacksoftware.com | 192.168.1.173:80 |
|
|
| hats.kolpacksoftware.com | 192.168.1.66:9999 |
|
|
| pve-nas.kolpacksoftware.com | 192.168.1.245:8006 |
|
|
| unraid.kolpacksoftware.com | 192.168.1.192:80 |
|
|
|
|
All static backends are private (IP restricted).
|
|
|
|
To add a new static backend:
|
|
1. Add server block to `conf.d/static-upstreams.conf`
|
|
2. Add domain to `static-certs` container's VIRTUAL_HOST and LETSENCRYPT_HOST in docker-compose.yaml
|
|
3. Reload: `docker exec nginx-proxy nginx -s reload`
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
/srv/nginx-proxy-acme/
|
|
├── acme/ # acme.sh state (auto-managed)
|
|
├── certs/ # SSL certificates (auto-managed)
|
|
├── conf.d/
|
|
│ ├── block-exploits.conf # WAF rules
|
|
│ └── static-upstreams.conf # Static IP backend server blocks
|
|
├── html/ # ACME challenge files (auto-managed)
|
|
└── vhost.d/
|
|
├── default # Security headers + HSTS + block-exploits (all hosts)
|
|
├── private # IP allowlist (private hosts include this)
|
|
├── docker-registry.* # Special config (auth headers + private)
|
|
└── <hostname> # Per-host includes (usually just 'include private')
|
|
```
|
|
|
|
## Reload Config
|
|
|
|
After changing vhost.d or conf.d files:
|
|
```bash
|
|
docker exec nginx-proxy nginx -s reload
|
|
```
|
|
|
|
## Multiple Domains
|
|
|
|
For multiple domains on one cert:
|
|
```yaml
|
|
environment:
|
|
- VIRTUAL_HOST=example.com,www.example.com
|
|
- LETSENCRYPT_HOST=example.com,www.example.com
|
|
```
|
|
|
|
Create vhost.d entries for each domain if private.
|