Enable both TURN and TURNS protocols for coturn, add Ansible tags

- Enable both TURN (port 3478) and TURNS (port 5349) for maximum client compatibility
- Add recommended coturn settings: stale-nonce, unlimited quotas
- Remove deprecated 'warn' parameter from shell task
- Add comprehensive tags to all roles in site.yml for selective deployment
- Remove redundant update playbooks (replaced by tags functionality)
- Update README with detailed tags documentation and common workflows
- Update coturn documentation with correct Nextcloud configuration
- Add coturn_static_secret and wireguard server keys to vault example
This commit is contained in:
okhsunrog 2025-12-12 19:15:10 +03:00
parent 4b3e939891
commit 379f1a2782
10 changed files with 246 additions and 68 deletions

182
README.md
View file

@ -126,20 +126,130 @@ awg genkey | tee private.key | awg pubkey > public.key
### Full Deployment
```bash
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml
```
### Update VPN Users Only
Note: Vault password is configured in `ansible.cfg` to use `~/.vault_pass` file. If not using vault password file, add `--ask-vault-pass`.
## Working with Tags
Tags allow you to run specific parts of the playbook without deploying everything.
### List Available Tags
```bash
ansible-playbook update_vpn_users.yml --ask-vault-pass # OpenConnect
ansible-playbook update_amneziawg_users.yml --ask-vault-pass # AmneziaWG
ansible-playbook site.yml --list-tags
```
### Lint and Validation
### Update Specific Services
**VPN Services:**
```bash
ansible-playbook --syntax-check site.yml
ansible-playbook --check --diff site.yml
ansible-lint site.yml
ansible-playbook site.yml --tags ocserv # OpenConnect VPN
ansible-playbook site.yml --tags wireguard # WireGuard VPN
ansible-playbook site.yml --tags amneziawg # AmneziaWG VPN
ansible-playbook site.yml --tags vpn # All VPN services
```
**Web Services:**
```bash
ansible-playbook site.yml --tags nginx # Nginx reverse proxy
ansible-playbook site.yml --tags haproxy # HAProxy load balancer
ansible-playbook site.yml --tags proxy # Both nginx and haproxy
```
**TURN/STUN Server:**
```bash
ansible-playbook site.yml --tags coturn # Coturn server
ansible-playbook site.yml --tags coturn,network # Coturn + firewall rules
```
**Certificates:**
```bash
ansible-playbook site.yml --tags certificates # SSL/TLS certificates
ansible-playbook site.yml --tags certbot # Just certbot
```
**Security:**
```bash
ansible-playbook site.yml --tags network # Firewall rules
ansible-playbook site.yml --tags fail2ban # Intrusion prevention
ansible-playbook site.yml --tags security # fail2ban
```
**Other:**
```bash
ansible-playbook site.yml --tags base # Base system config
ansible-playbook site.yml --tags blog # Blog deployment user
```
### Available Tags Reference
| Tag | Roles/Tasks | Description |
|-----|-------------|-------------|
| `base`, `system` | base_system | Base system configuration |
| `wireguard`, `vpn` | wireguard | WireGuard VPN |
| `amneziawg`, `vpn` | amneziawg | AmneziaWG VPN |
| `ocserv`, `vpn` | ocserv | OpenConnect VPN |
| `coturn`, `turn` | coturn | TURN/STUN for WebRTC |
| `certbot`, `certificates` | certbot, certbot_renewal_config | SSL certificates |
| `haproxy`, `proxy` | haproxy | Load balancer |
| `nginx`, `proxy` | nginx | Reverse proxy |
| `blog`, `deploy` | blog_deploy | Blog deployment |
| `network`, `firewall` | network | iptables firewall |
| `fail2ban`, `security` | fail2ban | IPS |
| `reboot`, `never` | post_tasks | Server reboot (never runs by default) |
### Skip Specific Roles
```bash
ansible-playbook site.yml --skip-tags vpn
ansible-playbook site.yml --skip-tags reboot
```
### Useful Ansible Commands
**Dry run (check what would change):**
```bash
ansible-playbook site.yml --check
ansible-playbook site.yml --tags nginx --check
```
**Verbose output:**
```bash
ansible-playbook site.yml -v # verbose
ansible-playbook site.yml -vvv # very verbose
```
**List tasks:**
```bash
ansible-playbook site.yml --list-tasks
ansible-playbook site.yml --tags nginx --list-tasks
```
**Check syntax:**
```bash
ansible-playbook site.yml --syntax-check
```
**Test connectivity:**
```bash
ansible vps -m ping
```
## Ansible Vault Management
**Edit encrypted variables:**
```bash
ansible-vault edit group_vars/all/vault.yml
```
**View encrypted variables:**
```bash
ansible-vault view group_vars/all/vault.yml
```
**Change vault password:**
```bash
ansible-vault rekey group_vars/all/vault.yml
```
## File Structure
@ -161,7 +271,7 @@ ansible-lint site.yml
│ ├── certbot/ # Let's Encrypt certificates
│ ├── network/ # Firewall and routing
│ └── fail2ban/ # Intrusion prevention
└── update_*.yml # User management playbooks
└── docs/ # Documentation
```
## Client Configuration
@ -186,11 +296,63 @@ scp root@server:/etc/amnezia/amneziawg/clients/client.conf ./
### Modifying SSL Domains
1. Update `domains` section in `vars.yml`
2. Run `ansible-playbook site.yml --tags certbot,nginx`
2. Run `ansible-playbook site.yml --tags certificates,nginx`
### Network Isolation
The configuration includes network isolation between VPN networks. Friends VPN network is blocked from accessing other VPN subnets by default.
## Common Workflows
### Add a New VPN User
1. Edit the vault:
```bash
ansible-vault edit group_vars/all/vault.yml
```
2. Add user to appropriate VPN section (wireguard_peers, ocserv_users, etc.)
3. Update the VPN service:
```bash
ansible-playbook site.yml --tags ocserv
# or
ansible-playbook site.yml --tags wireguard
```
### Add a New Domain
1. Add DNS A record pointing to your VPS IP
2. Edit `group_vars/all/vars.yml` and add the domain
3. Deploy certificates and web configuration:
```bash
ansible-playbook site.yml --tags certificates,nginx
```
### Update Coturn (TURN/STUN Server)
1. Edit coturn variables in `group_vars/all/vars.yml` or vault
2. Deploy changes:
```bash
ansible-playbook site.yml --tags coturn,network
```
See [docs/coturn-setup.md](docs/coturn-setup.md) for complete Coturn setup guide.
### Update Only Firewall Rules
After changing port configuration:
```bash
ansible-playbook site.yml --tags network
```
## Documentation
- [Coturn TURN/STUN Setup](docs/coturn-setup.md) - Complete guide for Nextcloud Talk WebRTC
- [Documentation Index](docs/README.md) - All available documentation
## Troubleshooting
### AmneziaWG DKMS Issues (Ubuntu 24.04)

View file

@ -14,17 +14,21 @@ Coturn provides TURN/STUN services required for Nextcloud Talk to work properly,
The Coturn setup integrates with your existing infrastructure:
- **Domain**: `turn.okhsunrog.dev`
- **Listening Port**: `3478` (TCP/UDP) - STUN/TURN
- **Relay Ports**: `49152-49252` (UDP) - 100 concurrent sessions
- **Listening Ports**:
- `3478` (TCP/UDP) - STUN/TURN (unencrypted)
- `5349` (TCP/UDP) - TURNS (TLS-encrypted)
- **Relay Ports**: `49152-49252` (UDP) - Unlimited concurrent sessions
- **SSL/TLS**: Let's Encrypt certificates (auto-managed)
- **Authentication**: Static auth secret (secure method for Nextcloud)
Both TURN and TURNS protocols are enabled for maximum client compatibility as recommended by Nextcloud.
## Prerequisites
Before deploying, ensure:
1. ✅ DNS A record pointing `turn.okhsunrog.dev` to your VPS IP
2. ✅ Ports `3478` (TCP/UDP) and `49152-49252` (UDP) allowed through any upstream firewalls
2. ✅ Ports `3478` (TCP/UDP), `5349` (TCP/UDP), and `49152-49252` (UDP) allowed through any upstream firewalls
3. ✅ Ansible vault password configured at `~/.vault_pass`
## Configuration Steps
@ -105,6 +109,7 @@ You can test your TURN server using online tools:
- https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
- Add STUN server: `stun:turn.okhsunrog.dev:3478`
- Add TURN server: `turn:turn.okhsunrog.dev:3478`
- Add TURNS server: `turns:turn.okhsunrog.dev:5349`
- Use your static secret for authentication
## Nextcloud Talk Configuration
@ -116,17 +121,15 @@ You can test your TURN server using online tools:
### Configure TURN/STUN Servers
Add the following configuration:
**Important:** Enter only the domain (e.g., `turn.okhsunrog.dev`), without port number, `http://`, `turn://`, or `turns://` prefixes.
#### STUN Server:
#### TURN server URL:
```
turn.okhsunrog.dev:3478
turn.okhsunrog.dev
```
#### TURN Server:
```
turn.okhsunrog.dev:3478
```
#### Protocol dropdown:
Select **`turn: and turns:`** (this enables both protocols automatically)
#### TURN Secret:
```
@ -135,8 +138,9 @@ your-coturn-static-secret
(Use the same secret from your vault)
#### Protocols:
- ✅ UDP
- ✅ TCP
- ✅ UDP and TCP
**Note:** The combined "turn: and turns:" option automatically uses both port 3478 (unencrypted TURN) and port 5349 (TLS-encrypted TURNS) for maximum client compatibility. TURNS provides TLS encryption and works better through restrictive firewalls.
### Save Configuration
@ -153,7 +157,10 @@ ports:
external:
coturn:
port: 3478
type: both # TCP and UDP
type: both # TCP and UDP (TURN)
coturn_tls:
port: 5349
type: both # TCP and UDP (TURNS)
coturn_relay_min:
port: 49152
type: udp
@ -170,32 +177,35 @@ domains:
File: `roles/coturn/templates/turnserver.conf.j2`
Key settings:
- **Listening port**: 3478
- **Listening ports**: 3478 (TURN), 5349 (TURNS)
- **Realm**: turn.okhsunrog.dev
- **SSL/TLS**: Let's Encrypt certificates
- **Auth method**: Static auth secret
- **Relay ports**: 49152-49252
- **User quota**: 100 concurrent sessions
- **Total quota**: 1000 concurrent sessions
- **User quota**: 100 concurrent sessions per user
- **Total quota**: 0 (unlimited)
- **Bandwidth capacity**: 0 (unlimited)
## Troubleshooting
### Check if Coturn is listening
```bash
ss -tulnp | grep 3478
ss -tulnp | grep -E '(3478|5349)'
```
Expected output:
```
udp UNCONN 0 0 0.0.0.0:3478 0.0.0.0:* users:(("turnserver",pid=...))
tcp LISTEN 0 5 0.0.0.0:3478 0.0.0.0:* users:(("turnserver",pid=...))
udp UNCONN 0 0 0.0.0.0:5349 0.0.0.0:* users:(("turnserver",pid=...))
tcp LISTEN 0 5 0.0.0.0:5349 0.0.0.0:* users:(("turnserver",pid=...))
```
### Check firewall rules
```bash
iptables -L INPUT -n -v | grep 3478
iptables -L INPUT -n -v | grep -E '(3478|5349)'
```
### Certificate issues

View file

@ -26,9 +26,9 @@ ports:
ocserv_personal:
port: 443
type: udp
# coturn:
# port: 3478
# type: both # UDP and TCP (TURN - disabled, using TURNS only)
coturn:
port: 3478
type: both # UDP and TCP (TURN)
coturn_tls:
port: 5349
type: both # UDP and TCP (TURNS)

View file

@ -16,6 +16,10 @@ ocserv_users:
- username: "sneg"
password: "5231"
# WireGuard server keys (persist across rebuilds)
wireguard_server_private_key: "server_private_key_generated_by_wg_genkey"
wireguard_server_public_key: "server_public_key_generated_by_wg_pubkey"
wireguard_peers:
- name: "husky"
private_key: "key"
@ -39,4 +43,6 @@ amneziawg_peers:
private_key: "private_key_generated_by_awg_genkey"
public_key: "public_key_generated_by_awg_pubkey"
ip: "10.65.65.10"
# Coturn TURN/STUN server secret (generate with: openssl rand -hex 32)
coturn_static_secret: "your_generated_secret_here"

View file

@ -1,4 +1,4 @@
# coturn_listening_port: "{{ ports.external.coturn.port }}" # Disabled - using TURNS only
coturn_listening_port: "{{ ports.external.coturn.port }}"
coturn_relay_min_port: "{{ ports.external.coturn_relay_min.port }}"
coturn_relay_max_port: "{{ ports.external.coturn_relay_max.port }}"
coturn_realm: "{{ domains.coturn }}"

View file

@ -57,8 +57,6 @@
- name: Fix private key permissions for coturn
shell: |
find /etc/letsencrypt/archive/{{ coturn_realm }}/ -name 'privkey*.pem' -exec chgrp ssl-cert {} \; -exec chmod 640 {} \;
args:
warn: false
changed_when: false
- name: Enable and start coturn service

View file

@ -1,8 +1,8 @@
# Coturn TURN/STUN server configuration for Nextcloud Talk
# {{ ansible_managed }}
# Listening port for STUN/TURN (disabled - using TURNS only)
# listening-port=3478
# Listening port for STUN/TURN (both TURN and TURNS recommended by Nextcloud)
listening-port=3478
# Listening IP (0.0.0.0 for all interfaces)
listening-ip=0.0.0.0
@ -58,11 +58,17 @@ fingerprint
# No multicast peers
no-multicast-peers
# Prevent stale nonce attacks
stale-nonce
# User quota (max 100 concurrent sessions per user)
user-quota=100
# Total quota (max 1000 concurrent sessions)
total-quota=1000
# Total quota (0 = unlimited, recommended by Nextcloud)
total-quota=0
# Bandwidth capacity (0 = unlimited)
bps-capacity=0
# Disable CLI
no-cli

View file

@ -18,18 +18,30 @@
ansible_facts['distribution_version'] not in ['22.04', '24.04']
roles:
- base_system
- wireguard
- amneziawg
- certbot
- haproxy
- nginx
- blog_deploy
- ocserv
- coturn
- certbot_renewal_config
- network
- fail2ban
- role: base_system
tags: [base, system]
- role: wireguard
tags: [wireguard, vpn]
- role: amneziawg
tags: [amneziawg, vpn]
- role: certbot
tags: [certbot, certificates]
- role: haproxy
tags: [haproxy, proxy]
- role: nginx
tags: [nginx, proxy]
- role: blog_deploy
tags: [blog, deploy]
- role: ocserv
tags: [ocserv, vpn]
- role: coturn
tags: [coturn, turn]
- role: certbot_renewal_config
tags: [certbot, certificates]
- role: network
tags: [network, firewall]
- role: fail2ban
tags: [fail2ban, security]
post_tasks:
- name: Reboot server
@ -39,3 +51,4 @@
reboot_timeout: 300
pre_reboot_delay: 0
post_reboot_delay: 30
tags: [reboot, never]

View file

@ -1,8 +0,0 @@
---
- name: Update AmneziaWG Users
hosts: vps
become: true
gather_facts: true
roles:
- amneziawg

View file

@ -1,9 +0,0 @@
---
- name: Update VPN Users
hosts: vps
become: true
gather_facts: true
roles:
# - wireguard
- ocserv