torrust-tracker-deployer 0.1.0

Torrust Tracker Deployer - Deployment Infrastructure with Ansible and OpenTofu
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# Security Guide

This guide covers security considerations and best practices when deploying Torrust Tracker using the deployer.

## Overview

Security is a critical aspect of production deployments. The Torrust Tracker Deployer implements several security measures automatically during the deployment process, with additional considerations for production environments.

## Firewall Configuration

### Layered Security Approach

**CRITICAL**: The deployer uses a **layered security approach** combining UFW firewall and Docker networking to protect your deployment. Understanding how these layers work together is essential for secure deployments.

#### Security Architecture

The deployer implements security at two levels:

1. **Instance-Level Security (UFW)** - Protects the VM itself
   - Denies all incoming traffic by default
   - Allows only SSH access for administration
   - **Does NOT control Docker container ports** (Docker bypasses UFW)

2. **Service-Level Security (Docker)** - Controls service exposure
   - Public services have explicit port bindings (Tracker, Grafana)
   - Internal services have NO port bindings (MySQL)
   - Localhost-only services bind to `127.0.0.1` (Prometheus)
   - Docker network segmentation isolates service communication

#### Why UFW Cannot Protect Docker Ports

**Important**: Docker manipulates iptables directly and **bypasses UFW rules** for published container ports. This is documented behavior (see [Docker documentation](https://docs.docker.com/engine/network/packet-filtering-firewalls/)).

```yaml
# This port binding BYPASSES UFW firewall rules
services:
  mysql:
    ports:
      - "3306:3306" # ⚠️ PUBLICLY ACCESSIBLE despite UFW rules!
```

Docker routes container traffic in the NAT table, meaning packets are diverted before reaching the INPUT and OUTPUT chains that UFW uses. Therefore:

- ✅ UFW protects the VM and SSH access
- ❌ UFW **does not** protect Docker-published ports
- ✅ Docker port bindings control service exposure

### Automatic Firewall Setup

During the `configure` command, the deployer:

1. **Installs UFW** - Ensures the firewall is available
2. **Sets restrictive policies** - Denies all incoming traffic by default
3. **Allows SSH access** - Preserves SSH connectivity (configured port)
4. **Enables the firewall** - Activates rules to protect SSH access

**Note**: UFW only controls SSH access. Application ports are controlled by Docker port bindings in the docker-compose configuration.

### Service Exposure Strategy

The Docker Compose configuration (`templates/docker-compose/docker-compose.yml.tera`) controls which services are accessible from the internet through **explicit port bindings**:

**Service Exposure Levels**:

```yaml
services:
  # ✅ PUBLIC SERVICES - Explicit port bindings
  tracker:
    ports:
      - "6969:6969/udp" # Public - UDP tracker
      - "7070:7070" # Public - HTTP tracker
      - "1212:1212" # Public - REST API

  grafana:
    ports:
      - "3000:3000" # Public - Monitoring UI (authenticated)

  # 🔒 LOCALHOST-ONLY SERVICES - Bound to 127.0.0.1
  prometheus:
    ports:
      - "127.0.0.1:9090:9090" # Accessible only from VM host

  # 🔒 INTERNAL-ONLY SERVICES - No port bindings
  mysql:
    # No ports section - completely internal
    # Accessed via Docker network: mysql:3306
```

**Security Properties**:

- **Public Services** - Have `ports:` section binding to `0.0.0.0` (accessible externally)
- **Localhost Services** - Bind to `127.0.0.1` (accessible only from VM host via SSH)
- **Internal Services** - No port bindings (accessible only via Docker internal networks)

### Network Segmentation

The deployer implements **three isolated Docker networks** for defense-in-depth security:

```yaml
networks:
  database_network: # Tracker ↔ MySQL only
  metrics_network: # Tracker ↔ Prometheus only
  visualization_network: # Prometheus ↔ Grafana only

services:
  tracker:
    networks:
      - database_network # Can access MySQL
      - metrics_network # Can be scraped by Prometheus

  mysql:
    networks:
      - database_network # Isolated - only Tracker can access

  prometheus:
    networks:
      - metrics_network # Can scrape Tracker metrics
      - visualization_network # Can be queried by Grafana

  grafana:
    networks:
      - visualization_network # Can query Prometheus only
```

**Security Benefits**:

1. **Reduced Attack Surface**: MySQL accessible from 1 service (Tracker) instead of 3 services
2. **Lateral Movement Prevention**: Compromised Grafana cannot access MySQL or Tracker
3. **Principle of Least Privilege**: Services can only communicate where necessary
4. **Compliance**: Aligns with PCI DSS, NIST 800-53, CIS Docker Benchmark

### Security Comparison

**Without proper configuration** ⚠️:

```yaml
# INSECURE - All services on one network with public port bindings
services:
  mysql:
    ports:
      - "3306:3306" # ⚠️ MySQL publicly accessible!
    networks:
      - backend_network
```

- ❌ Internal services exposed to internet
- ❌ All services can communicate (no segmentation)
- ❌ Docker bypasses UFW firewall rules
- ❌ High attack surface

**With deployer configuration** ✅:

```yaml
# SECURE - Network segmentation + no public port bindings
services:
  mysql:
    # No ports section - internal only
    networks:
      - database_network # Only Tracker can access
```

- ✅ Internal services not publicly accessible
- ✅ Network segmentation limits lateral movement
- ✅ UFW protects SSH access
- ✅ Reduced attack surface

### E2E Testing vs Production

**E2E Testing (Docker Containers)**:

- Uses Docker containers for faster test execution
- Firewall **not configured** inside containers (container isolation sufficient)
- Services may be exposed for testing purposes
- ⚠️ **NOT production-grade security**

**Production Deployments (Virtual Machines)**:

- Uses real VMs (LXD, cloud providers)
- UFW **configured automatically** for SSH protection
- Docker port bindings control service exposure
- Network segmentation isolates services
- ✅ **Production-ready security**

### Firewall Rules Applied

The deployer configures these UFW firewall rules during `configure`:

```bash
# SSH Access (required for administration)
ufw allow <ssh-port>/tcp

# Default policies
ufw default deny incoming   # Block all incoming traffic
ufw default allow outgoing  # Allow outbound connections
ufw enable                  # Activate firewall
```

**Note**: Application ports (Tracker, Grafana, Prometheus, MySQL) are **not** managed by UFW. They are controlled by Docker port bindings in the docker-compose.yml configuration.

### Security Best Practices

**DO**:

- ✅ Use the deployer's default docker-compose template (network segmentation included)
- ✅ Review port bindings before deploying (`build/{env}/docker-compose/docker-compose.yml`)
- ✅ Keep internal services without port bindings (MySQL)
- ✅ Use `127.0.0.1` bindings for localhost-only access (Prometheus)
- ✅ Apply security updates to the VM regularly
- ✅ Use strong SSH keys and disable password authentication
- ✅ Monitor logs for suspicious activity

**DON'T**:

- ❌ Add port bindings to internal services (e.g., `3306:3306` for MySQL)
- ❌ Disable UFW firewall on production VMs
- ❌ Remove network segmentation from docker-compose.yml
- ❌ Assume UFW protects Docker-published ports
- ❌ Expose Prometheus/MySQL publicly
- ❌ Use default passwords for services

### Verifying Firewall Configuration

After running the `configure` command, verify firewall rules:

```bash
# SSH into your VM
INSTANCE_IP=$(cat data/<env-name>/environment.json | jq -r '.Configured.context.runtime_outputs.instance_ip')
ssh -i <private-key> <username>@$INSTANCE_IP

# Check UFW status
sudo ufw status numbered

# Expected output shows:
# - SSH port allowed
# - Tracker ports allowed (UDP/HTTP/API)
# - Default deny incoming policy
# - All other ports blocked
```

**Example output**:

```text
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 6969/udp                   ALLOW IN    Anywhere
[ 3] 7070/tcp                   ALLOW IN    Anywhere
[ 4] 1212/tcp                   ALLOW IN    Anywhere
```

Note that ports 9090 (Prometheus) and 3306 (MySQL) are **not** in this list, meaning they are blocked from external access.

## SSH Security

### SSH Key Authentication

The deployer requires SSH key-based authentication for VM access:

**Best Practices**:

1. **Use strong SSH keys** - Generate RSA keys with at least 4096 bits:

   ```bash
   ssh-keygen -t rsa -b 4096 -f ~/.ssh/torrust_deploy
   ```

2. **Protect private keys** - Set restrictive permissions:

   ```bash
   chmod 600 ~/.ssh/torrust_deploy
   ```

3. **Use dedicated keys** - Don't reuse personal SSH keys for deployments

4. **Rotate keys regularly** - Update SSH keys periodically

### SSH Port Configuration

The default SSH port (22) is commonly targeted by automated attacks. Consider using a custom port:

```json
{
  "ssh_credentials": {
    "port": 2222 // Custom SSH port
  }
}
```

**Trade-offs**:

- ✅ Reduces automated attack attempts
- ✅ Adds minimal security through obscurity
- ⚠️ Must remember custom port for manual access
- ⚠️ Not a substitute for strong authentication

## Docker Security Considerations

### Container Isolation

Services run in isolated Docker containers with:

- **Network isolation** - Backend network for inter-container communication
- **Volume mounts** - Limited filesystem access with `:Z` SELinux labels
- **Resource limits** - Logging limits prevent disk exhaustion
- **Restart policies** - Automatic recovery from failures

### Image Security

**Current Images**:

- `torrust/tracker:develop` - Torrust Tracker (development tag)
- `prom/prometheus:v3.0.1` - Prometheus (pinned version)
- `mysql:8.0` - MySQL (major version pinned)

**Recommendations**:

1. **Pin specific versions** - Use exact version tags in production
2. **Scan images regularly** - Check for known vulnerabilities
3. **Update periodically** - Apply security patches
4. **Use official images** - Prefer official/verified images

### Environment Variables

Sensitive configuration is managed via `.env` files on the VM:

**Best Practices**:

1. **Strong passwords** - Use complex, randomly generated passwords
2. **Unique credentials** - Different passwords per environment
3. **Secure storage** - Never commit `.env` files to version control
4. **Rotation policy** - Update passwords periodically

**Example** (DO NOT use these values):

```bash
# Bad - Weak passwords
MYSQL_ROOT_PASSWORD=password123
MYSQL_PASSWORD=tracker

# Good - Strong, unique passwords
MYSQL_ROOT_PASSWORD=7k#mP9$vL2@qX5nR8jW
MYSQL_PASSWORD=xF4!hT6@dN9$sK2mQ7wE
```

## Network Security

### Service Exposure

The deployer follows the principle of least exposure:

**Public Services** (accessible externally):

- UDP Tracker - Required for BitTorrent protocol
- HTTP Tracker - Required for HTTP-based tracker operations
- HTTP API - Required for tracker management and metrics

**Internal Services** (blocked by firewall):

- Prometheus UI - Metrics collection (internal monitoring only)
- MySQL Database - Data storage (internal access only)

### Internal Communication

Services communicate via Docker's `backend_network`:

- Container-to-container communication allowed
- Isolated from host network by default
- DNS resolution via container names (e.g., `tracker`, `mysql`, `prometheus`)

## Production Security Checklist

Before deploying to production, verify:

### Infrastructure Security

- [ ] **Virtual machines used** (not Docker containers for testing)
- [ ] **Firewall configured** (`configure` command completed successfully)
- [ ] **SSH key authentication** (password authentication disabled)
- [ ] **Custom SSH port** (optional but recommended)
- [ ] **Firewall rules verified** (`ufw status` shows expected rules)

### Credential Security

- [ ] **Strong SSH keys** (4096-bit RSA minimum)
- [ ] **Strong database passwords** (randomly generated, complex)
- [ ] **Unique API tokens** (per environment, rotated regularly)
- [ ] **No credentials in git** (`.env` files gitignored)
- [ ] **Secure key storage** (restricted permissions on private keys)

### Application Security

- [ ] **Pinned image versions** (not using `latest` or `develop` tags)
- [ ] **Image scanning enabled** (vulnerability checks in CI/CD)
- [ ] **Logging configured** (audit trail and debugging)
- [ ] **Resource limits set** (prevent resource exhaustion)
- [ ] **Regular updates scheduled** (security patches applied)

### Monitoring Security

- [ ] **Prometheus UI not exposed** (firewall blocks port 9090)
- [ ] **Database not exposed** (firewall blocks port 3306)
- [ ] **Access logs reviewed** (regular security audits)
- [ ] **Metrics monitored** (unusual patterns detected)

## Security Incident Response

If you suspect a security breach:

1. **Isolate the system** - Disable network access if necessary
2. **Check logs** - Review `data/logs/log.txt` and container logs
3. **Review firewall rules** - Verify UFW configuration hasn't changed
4. **Rotate credentials** - Update all passwords and keys immediately
5. **Update software** - Apply latest security patches
6. **Report vulnerabilities** - Contact maintainers for Torrust Tracker issues

## Future Security Enhancements

Planned improvements for future releases:

- **TLS/SSL support** - HTTPS for HTTP tracker and API
- **Certificate management** - Automated Let's Encrypt integration
- **Rate limiting** - Protection against abuse
- **Fail2ban integration** - Automated IP blocking for failed attempts
- **Security scanning** - Automated vulnerability detection in CI/CD
- **Audit logging** - Detailed access logs for compliance

## Additional Resources

### Related Documentation

- **[User Guide]README.md** - Main deployment guide
- **[Configuration Guide]configuration/** - Environment configuration details
- **[Services Guide]services/** - Service-specific security considerations

### External Resources

- **[UFW Documentation]https://help.ubuntu.com/community/UFW** - Firewall configuration
- **[Docker Security Best Practices]https://docs.docker.com/engine/security/** - Container security
- **[SSH Hardening Guide]https://www.ssh.com/academy/ssh/security** - SSH security best practices
- **[OWASP Top 10]https://owasp.org/www-project-top-ten/** - Web application security risks

## Questions or Concerns?

Security is an ongoing process. If you have questions or discover security issues:

- **Security Issues** - Report privately to maintainers (do not open public issues)
- **General Questions** - [GitHub Discussions]https://github.com/torrust/torrust-tracker-deployer/discussions
- **Feature Requests** - [GitHub Issues]https://github.com/torrust/torrust-tracker-deployer/issues

Stay secure! 🔒