Security¶
4-layer model¶
Layer 1: UFW (host firewall)¶
Default-Deny Incoming. Open ports:
| Port | Protocol | Description |
|---|---|---|
| 22 | TCP | SSH |
| 80, 443 | TCP | HTTP/HTTPS (Traefik) |
| 2222 | TCP | SFTP (hosting) |
| 5060 | UDP | SIP |
| 5067 | TCP | SIP/TLS |
| 7443 | TCP | WebRTC WSS |
| 16384-32768 | UDP | RTP Media |
Config:/home/admin/scripts/ufw-setup.sh
Layer 2: CrowdSec (IDS/IPS)¶
- nftables bouncer — IP Level Blocking
- Traefik Plugin— HTTP level blocking
Custom Scenarios:
| Scenario | Ban-duration | Trigger |
|---|---|---|
| SIP-Bruteforce | 24h | 5 failure tests / 5 min |
| SIP scanner | 7d | Scanner batteries detected |
| WSS waste | 1h | Overload on WebSocket |
| Mail-Bruteforce | 24h | 5 failure tests / 5 min |
| Mail spam sender | 24h | 20 mails / 10 min |
Config:/etc/crowdsec/
Layer 3: fail2ban (Legacy)¶
It is gradually replaced by CrowdSec.
4 Jails: sshd, freeswitch, freeswitch-scanner, wss-proxy
Layer 4: Traefik Middleware¶
Per-Request Chain:
ForwardAuth (SSO)¶
Auth-service (auth.xynap.tech) provides services via ForwardAuth:
Traefik → auth-check middleware → GET http://auth-service:8091/verify
→ 200: Zugriff erlaubt (X-Auth-User, X-Auth-Name, X-Auth-Role Header)
→ 302: Redirect zu Login
Cookie domain:.xynap.tech
Excellent documentation
See Access Portalfor user instructions, User Managementfor admin functions and Technical Referencefor deployment and debugging.
Platform API Security¶
- JWTwith configurable Expiry
- TOTP 2FA(Authenticator App)
- Telegram 2FA(code via Bot)
- OAuth2(GitHub, Google)
- RBAC— 5 reels, 30+ permission
- Tenant-Isolation— Customers only see their own data
- Audit-Log— All changes are logged
- Encrypted Credentials— DNS provider/DB passenger with remotely locked
Security-by-design (v2.4, 2026-03-11)¶
Architecture principle: **All data access runs through the API, the API forces RBAC based on roles/rights. **
XSS protection (front end)¶
Allv-htmluses are sanitized withDOMPurify:
| Component | Risk | Mass |
|---|---|---|
SignatureManager.vue |
Email signatures (HTML) | sanitizeHtml()Wrapper |
TextBlock.vue |
CMS user content | sanitizeHtml()Wrapper |
ClientSetupView.vue |
i18n translation | sanitizeHtml()(Defense-in-depth) |
Utility:src/shell/utils/sanitizeHtml.ts— Central DOMPurify wrapper.
Webhook-HMAC verification¶
Payment-Webhooks (Stripe, PayPal) pruefen HMAC-SHA256 signatures:
- Header:
X-Webhook-Signature(Hex digest) - Secret from Settings:
payments.stripe_webhook_secret/payments.paypal_webhook_secret - Without configured Secret: dummy mode (requests are accepted)
- With Secret: Signature becomes erzwungen, unused requests → 403
User preferences via API¶
User preferences (mail handlers, call handlers) are managed via the API:
GET /api/v1/settings/preferences— Read your own referencesPUT /api/v1/settings/preferences— Set own references- Whitelist-Validierung: Only allowed keys (
mail_handler,call_handler) and values (internal,system,ask) - Scope:
userwithscope_id = user.id— RBAC forces that each user can only change their own references - Frontend:
localStorageonly as offline cache, finer source is the API
Contact-Link Sanitation (XContactLink)¶
All clickable contact links are sanitized before use:
| Type | Sanitation |
|---|---|
Tax mark removed,@denounced,javascript:blocked |
|
| Telephone | Only+, digits, spaces, brackets, dashes |
| Website | Onlyhttp:///https://,javascript:/data:/vbscript:blocked |
| Telegram | Handle-Regex ([a-zA-Z0-9_]{3,32}) ort.me-URL |
Only digits and+, minimum margin 5 |
|
| External links | noopener,noreferrerforwindow.open() |
Compose parameter sanitation¶
URL parameters (?to=,?cc=,?subject=,?body=) in the webmailer are validated:
- E-mail addresses: taxmarks removed,
@denounced - Subject: Max 200 characters, remote control
- Body: Max 2000 characters, HTML escaped (no
v-html)
Network security¶
- Hetzner MAC-Filtering on Bridge-Level
- VM routing without NAT (transparent IPs)
- IPv6 via ndppd (NDP proxy)
- Network Watchdog monitors bridge status