484 lines
13 KiB
Markdown
484 lines
13 KiB
Markdown
|
|
# Documentacion Servidor tzzr.net
|
||
|
|
|
||
|
|
## Resumen Ejecutivo
|
||
|
|
|
||
|
|
Servidor self-hosted con email, base de datos, gestor de archivos, acortador de URLs, alias de correo y gestor de contrasenas.
|
||
|
|
|
||
|
|
**IP**: 72.62.1.113
|
||
|
|
**Hostname**: box.tzzr.net
|
||
|
|
**OS**: Ubuntu (Mail-in-a-Box)
|
||
|
|
**Dominio principal**: tzzr.net
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Arquitectura
|
||
|
|
|
||
|
|
```
|
||
|
|
[Cloudflare DNS]
|
||
|
|
|
|
||
|
|
[72.62.1.113]
|
||
|
|
|
|
||
|
|
+-----------------+-----------------+
|
||
|
|
| |
|
||
|
|
[Mail-in-a-Box] [Docker Stack]
|
||
|
|
Puerto 25,443 Puertos internos
|
||
|
|
| |
|
||
|
|
+----+----+ +---------------+---------------+
|
||
|
|
| | | | | | |
|
||
|
|
Email Nextcloud Postgres NocoDB Shlink Addy Vaultwarden
|
||
|
|
| |
|
||
|
|
FileBrowser Redis
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Servicios Activos
|
||
|
|
|
||
|
|
### Mail-in-a-Box (Nativo)
|
||
|
|
|
||
|
|
| Componente | URL/Puerto | Descripcion |
|
||
|
|
|------------|------------|-------------|
|
||
|
|
| Webmail | https://box.tzzr.net/mail | Roundcube |
|
||
|
|
| Admin Panel | https://box.tzzr.net/admin | Gestion usuarios/DNS |
|
||
|
|
| Nextcloud | https://box.tzzr.net/cloud | Archivos/Calendario |
|
||
|
|
| SMTP | Puerto 25, 587 | Envio de correo |
|
||
|
|
| IMAP | Puerto 993 | Recepcion de correo |
|
||
|
|
|
||
|
|
### Docker Stack (/opt/services)
|
||
|
|
|
||
|
|
| Servicio | Puerto Interno | URL Publica | Descripcion |
|
||
|
|
|----------|---------------|-------------|-------------|
|
||
|
|
| PostgreSQL | 5432 | - | Base de datos compartida |
|
||
|
|
| Redis | 6379 | - | Cache para Addy.io |
|
||
|
|
| NocoDB | 8081 | https://db.tzzr.net | Airtable self-hosted |
|
||
|
|
| FileBrowser | 8082 | https://files.tzzr.net | Explorador de archivos |
|
||
|
|
| Shlink | 8083 | https://s.tzzr.net | Acortador de URLs |
|
||
|
|
| Addy.io | 8084 | https://alias.tzzr.net | Alias de email |
|
||
|
|
| Vaultwarden | 8085 | https://pass.tzzr.net | Gestor de contrasenas |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Credenciales
|
||
|
|
|
||
|
|
### Mail-in-a-Box
|
||
|
|
- **Admin**: admin@tzzr.net
|
||
|
|
- **Password**: (configurada durante instalacion)
|
||
|
|
|
||
|
|
### PostgreSQL
|
||
|
|
- **Host**: postgres (interno) / 127.0.0.1:5432
|
||
|
|
- **Usuario**: tzzr
|
||
|
|
- **Password**: TzzrDB-2024-Secure
|
||
|
|
- **Base de datos**: tzzr
|
||
|
|
|
||
|
|
### NocoDB
|
||
|
|
- **URL**: https://db.tzzr.net
|
||
|
|
- **JWT Secret**: TzzrNocoDB-JWT-2024-SecureKey
|
||
|
|
- **Primer usuario**: se crea en primer acceso
|
||
|
|
|
||
|
|
### FileBrowser
|
||
|
|
- **URL**: https://files.tzzr.net
|
||
|
|
- **Usuario inicial**: admin
|
||
|
|
- **Password inicial**: admin (cambiar inmediatamente)
|
||
|
|
|
||
|
|
### Shlink
|
||
|
|
- **URL**: https://s.tzzr.net
|
||
|
|
- **API**: usar `shlink api-key:generate` en el contenedor
|
||
|
|
|
||
|
|
### Addy.io
|
||
|
|
- **URL**: https://alias.tzzr.net
|
||
|
|
- **App Key**: base64:TzzrAddyAppKey2024SecureBase64KeyHere==
|
||
|
|
- **Secret**: TzzrAddySecret2024Secure
|
||
|
|
|
||
|
|
### Vaultwarden
|
||
|
|
- **URL**: https://pass.tzzr.net
|
||
|
|
- **Admin Panel**: https://pass.tzzr.net/admin
|
||
|
|
- **Admin Token**: TzzrVault-Admin-2024-SuperSecureToken
|
||
|
|
- **Registros publicos**: Desactivados
|
||
|
|
- **Invitaciones**: Activadas (via admin panel)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Configuracion DNS (Cloudflare)
|
||
|
|
|
||
|
|
| Tipo | Nombre | Contenido | Proxy | TTL |
|
||
|
|
|------|--------|-----------|-------|-----|
|
||
|
|
| A | @ | 72.62.1.113 | OFF | Auto |
|
||
|
|
| A | box | 72.62.1.113 | OFF | Auto |
|
||
|
|
| A | db | 72.62.1.113 | ON | Auto |
|
||
|
|
| A | files | 72.62.1.113 | ON | Auto |
|
||
|
|
| A | s | 72.62.1.113 | ON | Auto |
|
||
|
|
| A | alias | 72.62.1.113 | ON | Auto |
|
||
|
|
| A | pass | 72.62.1.113 | ON | Auto |
|
||
|
|
| MX | @ | box.tzzr.net | - | Auto |
|
||
|
|
| TXT | @ | v=spf1 mx -all | - | Auto |
|
||
|
|
| TXT | _dmarc | v=DMARC1; p=quarantine... | - | Auto |
|
||
|
|
|
||
|
|
**Importante**: Los registros MX y el dominio raiz (@, box) deben tener proxy OFF para que funcione el email.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Estructura de Archivos
|
||
|
|
|
||
|
|
```
|
||
|
|
/opt/services/
|
||
|
|
├── docker-compose.yml # Definicion de servicios
|
||
|
|
├── init.sql # Schema inicial PostgreSQL
|
||
|
|
├── backup.sh # Script de backups
|
||
|
|
└── backups/ # Directorio de backups
|
||
|
|
|
||
|
|
/home/user-data/ # Datos de Mail-in-a-Box
|
||
|
|
├── mail/ # Buzones de correo
|
||
|
|
├── ssl/ # Certificados SSL
|
||
|
|
├── backup/ # Backups automaticos MiaB
|
||
|
|
└── www/ # Archivos web estaticos
|
||
|
|
|
||
|
|
/etc/nginx/conf.d/
|
||
|
|
└── services.conf # Reverse proxy para Docker
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Backups
|
||
|
|
|
||
|
|
### Automaticos (Mail-in-a-Box)
|
||
|
|
- **Ubicacion**: /home/user-data/backup/
|
||
|
|
- **Incluye**: Email, Nextcloud, certificados, configuracion
|
||
|
|
- **Frecuencia**: Diaria
|
||
|
|
|
||
|
|
### Script personalizado (/opt/services/backup.sh)
|
||
|
|
- **Frecuencia**: Diaria a las 3:00 AM
|
||
|
|
- **Retencion**: 7 dias
|
||
|
|
- **Incluye**:
|
||
|
|
- Dump de PostgreSQL
|
||
|
|
- Volumenes Docker
|
||
|
|
- **Ubicacion**: /opt/services/backups/
|
||
|
|
|
||
|
|
### Cron job
|
||
|
|
```
|
||
|
|
0 3 * * * /opt/services/backup.sh >> /var/log/tzzr-backup.log 2>&1
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Decisiones Tecnicas
|
||
|
|
|
||
|
|
### Por que Mail-in-a-Box?
|
||
|
|
- Solucion todo-en-uno para email self-hosted
|
||
|
|
- Incluye Nextcloud, DNS, certificados SSL automaticos
|
||
|
|
- Panel de administracion simple
|
||
|
|
- Backups integrados
|
||
|
|
|
||
|
|
### Por que PostgreSQL compartido?
|
||
|
|
- Reduce uso de RAM (vs multiples instancias)
|
||
|
|
- Facilita backups centralizados
|
||
|
|
- NocoDB, Shlink y Addy.io lo soportan nativamente
|
||
|
|
|
||
|
|
### Por que puertos solo en 127.0.0.1?
|
||
|
|
- Seguridad: servicios no expuestos directamente
|
||
|
|
- Todo el trafico pasa por nginx con SSL
|
||
|
|
- Mail-in-a-Box maneja los certificados
|
||
|
|
|
||
|
|
### Por que Vaultwarden en lugar de Bitwarden oficial?
|
||
|
|
- Menor consumo de recursos (escrito en Rust)
|
||
|
|
- Compatible 100% con apps de Bitwarden
|
||
|
|
- Ideal para uso personal/pequenos equipos
|
||
|
|
- Una sola imagen Docker vs multiple contenedores
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Comandos Utiles
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Ver estado de contenedores
|
||
|
|
docker ps
|
||
|
|
|
||
|
|
# Ver logs de un servicio
|
||
|
|
docker logs -f nocodb
|
||
|
|
|
||
|
|
# Reiniciar stack completo
|
||
|
|
cd /opt/services && docker compose restart
|
||
|
|
|
||
|
|
# Backup manual de PostgreSQL
|
||
|
|
docker exec postgres pg_dump -U tzzr tzzr > backup.sql
|
||
|
|
|
||
|
|
# Reiniciar nginx
|
||
|
|
systemctl restart nginx
|
||
|
|
|
||
|
|
# Ver certificados SSL
|
||
|
|
certbot certificates
|
||
|
|
|
||
|
|
# Estado de Mail-in-a-Box
|
||
|
|
mailinabox
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# Plan de Clonacion para Nuevos Usuarios
|
||
|
|
|
||
|
|
## Estrategia de Dominios para la Organizacion
|
||
|
|
|
||
|
|
### Arquitectura Multi-Tenant
|
||
|
|
|
||
|
|
```
|
||
|
|
[Dominio Principal]
|
||
|
|
juntis.com
|
||
|
|
|
|
||
|
|
Email principal para TODOS los usuarios
|
||
|
|
usuario@juntis.com
|
||
|
|
|
|
||
|
|
+-------------------+-------------------+
|
||
|
|
| | |
|
||
|
|
[Servidor 1] [Servidor 2] [Servidor N]
|
||
|
|
tzzr.net otro.net nuevo.net
|
||
|
|
| | |
|
||
|
|
Alias propios Alias propios Alias propios
|
||
|
|
*@tzzr.net *@otro.net *@nuevo.net
|
||
|
|
```
|
||
|
|
|
||
|
|
### Justificacion
|
||
|
|
|
||
|
|
1. **Email principal centralizado** (juntis.com):
|
||
|
|
- Identidad corporativa unificada
|
||
|
|
- Todos los usuarios tienen @juntis.com
|
||
|
|
- Facilita comunicacion interna
|
||
|
|
- Un solo servidor de mail principal
|
||
|
|
|
||
|
|
2. **Dominios de alias separados** (tzzr.net, otro.net, etc.):
|
||
|
|
- Cada persona/servidor tiene su propio dominio
|
||
|
|
- Evita colisiones de alias (dos personas no crearan el mismo alias)
|
||
|
|
- Privacidad: cada quien gestiona sus alias
|
||
|
|
- Escalabilidad: agregar nuevos usuarios = nuevo dominio
|
||
|
|
|
||
|
|
### Ejemplo Practico
|
||
|
|
|
||
|
|
| Usuario | Email Principal | Dominio Alias | Ejemplos de Alias |
|
||
|
|
|---------|-----------------|---------------|-------------------|
|
||
|
|
| Pablo | pablo@juntis.com | tzzr.net | amazon@tzzr.net, netflix@tzzr.net |
|
||
|
|
| Maria | maria@juntis.com | maria.net | amazon@maria.net, spotify@maria.net |
|
||
|
|
| Juan | juan@juntis.com | juan.net | amazon@juan.net, github@juan.net |
|
||
|
|
|
||
|
|
Todos reciben email en @juntis.com, pero cada uno tiene alias unicos en su dominio.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Checklist de Clonacion
|
||
|
|
|
||
|
|
### Prerequisitos
|
||
|
|
- [ ] VPS nuevo (minimo 2GB RAM, 20GB disco)
|
||
|
|
- [ ] Dominio nuevo registrado (ej: nuevo-usuario.net)
|
||
|
|
- [ ] Acceso a Cloudflare (o DNS del dominio)
|
||
|
|
- [ ] IP publica del nuevo servidor
|
||
|
|
|
||
|
|
### Paso 1: Preparar el Servidor Base
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Conectar al nuevo servidor
|
||
|
|
ssh root@NUEVA_IP
|
||
|
|
|
||
|
|
# Actualizar sistema
|
||
|
|
apt update && apt upgrade -y
|
||
|
|
|
||
|
|
# Configurar hostname
|
||
|
|
hostnamectl set-hostname box.NUEVO-DOMINIO.net
|
||
|
|
```
|
||
|
|
|
||
|
|
### Paso 2: Instalar Mail-in-a-Box
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Instalar MiaB
|
||
|
|
curl -s https://mailinabox.email/setup.sh | sudo bash
|
||
|
|
```
|
||
|
|
|
||
|
|
Durante la instalacion:
|
||
|
|
- **Hostname**: box.NUEVO-DOMINIO.net
|
||
|
|
- **Email admin**: admin@NUEVO-DOMINIO.net (temporal, luego se configura el principal)
|
||
|
|
|
||
|
|
### Paso 3: Configurar DNS en Cloudflare
|
||
|
|
|
||
|
|
Crear estos registros para NUEVO-DOMINIO.net:
|
||
|
|
|
||
|
|
| Tipo | Nombre | Contenido | Proxy |
|
||
|
|
|------|--------|-----------|-------|
|
||
|
|
| A | @ | NUEVA_IP | OFF |
|
||
|
|
| A | box | NUEVA_IP | OFF |
|
||
|
|
| A | db | NUEVA_IP | ON |
|
||
|
|
| A | files | NUEVA_IP | ON |
|
||
|
|
| A | s | NUEVA_IP | ON |
|
||
|
|
| A | alias | NUEVA_IP | ON |
|
||
|
|
| A | pass | NUEVA_IP | ON |
|
||
|
|
| MX | @ | box.NUEVO-DOMINIO.net | - |
|
||
|
|
| TXT | @ | v=spf1 mx -all | - |
|
||
|
|
|
||
|
|
### Paso 4: Instalar Docker
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -fsSL https://get.docker.com | sh
|
||
|
|
```
|
||
|
|
|
||
|
|
### Paso 5: Crear Estructura de Directorios
|
||
|
|
|
||
|
|
```bash
|
||
|
|
mkdir -p /opt/services/backups
|
||
|
|
cd /opt/services
|
||
|
|
```
|
||
|
|
|
||
|
|
### Paso 6: Configurar docker-compose.yml
|
||
|
|
|
||
|
|
Copiar el archivo base y modificar:
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# Cambiar estas variables por cada servidor:
|
||
|
|
# - Passwords de PostgreSQL
|
||
|
|
# - JWT secrets
|
||
|
|
# - Dominios (s.DOMINIO, alias.DOMINIO, pass.DOMINIO)
|
||
|
|
# - App keys
|
||
|
|
```
|
||
|
|
|
||
|
|
**Variables a personalizar por servidor**:
|
||
|
|
|
||
|
|
| Variable | Descripcion | Ejemplo |
|
||
|
|
|----------|-------------|---------|
|
||
|
|
| POSTGRES_PASSWORD | Password de DB | NuevoUsuario-DB-2024 |
|
||
|
|
| NC_AUTH_JWT_SECRET | JWT de NocoDB | NuevoUsuario-JWT-Secret |
|
||
|
|
| DEFAULT_DOMAIN | Dominio Shlink | s.nuevo-usuario.net |
|
||
|
|
| ANONADDY_DOMAIN | Dominio alias | nuevo-usuario.net |
|
||
|
|
| APP_KEY | Key de Addy | base64:NuevoKeyAqui... |
|
||
|
|
| DOMAIN (Vaultwarden) | URL Vaultwarden | https://pass.nuevo-usuario.net |
|
||
|
|
| ADMIN_TOKEN | Token admin Vault | NuevoUsuario-Vault-Token |
|
||
|
|
|
||
|
|
### Paso 7: Configurar Nginx
|
||
|
|
|
||
|
|
Copiar /etc/nginx/conf.d/services.conf y reemplazar:
|
||
|
|
- Todos los `tzzr.net` por `NUEVO-DOMINIO.net`
|
||
|
|
- Verificar que los puertos coincidan
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Recargar nginx
|
||
|
|
nginx -t && systemctl reload nginx
|
||
|
|
```
|
||
|
|
|
||
|
|
### Paso 8: Iniciar Servicios
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd /opt/services
|
||
|
|
docker compose up -d
|
||
|
|
```
|
||
|
|
|
||
|
|
### Paso 9: Configurar Email Principal
|
||
|
|
|
||
|
|
Si el email principal es juntis.com (servidor central):
|
||
|
|
|
||
|
|
1. En el servidor central (juntis.com), crear cuenta: usuario@juntis.com
|
||
|
|
2. En Addy.io del nuevo servidor, configurar el reenvio a usuario@juntis.com
|
||
|
|
3. Los alias de NUEVO-DOMINIO.net reenviaran a usuario@juntis.com
|
||
|
|
|
||
|
|
### Paso 10: Verificacion Final
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Verificar contenedores
|
||
|
|
docker ps
|
||
|
|
|
||
|
|
# Probar cada servicio
|
||
|
|
curl -I https://db.NUEVO-DOMINIO.net
|
||
|
|
curl -I https://files.NUEVO-DOMINIO.net
|
||
|
|
curl -I https://s.NUEVO-DOMINIO.net
|
||
|
|
curl -I https://alias.NUEVO-DOMINIO.net
|
||
|
|
curl -I https://pass.NUEVO-DOMINIO.net
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Script de Clonacion Automatizada
|
||
|
|
|
||
|
|
Para facilitar el proceso, se puede crear un script interactivo:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
#!/bin/bash
|
||
|
|
# clone-server.sh - Script de clonacion de servidor tzzr
|
||
|
|
|
||
|
|
echo "=== Clonacion de Servidor ==="
|
||
|
|
read -p "Nuevo dominio (ej: nuevo-usuario.net): " DOMAIN
|
||
|
|
read -p "IP del servidor: " SERVER_IP
|
||
|
|
read -p "Email admin: " ADMIN_EMAIL
|
||
|
|
|
||
|
|
# Generar passwords aleatorios
|
||
|
|
DB_PASS=$(openssl rand -base64 16)
|
||
|
|
JWT_SECRET=$(openssl rand -base64 32)
|
||
|
|
APP_KEY=$(openssl rand -base64 32)
|
||
|
|
VAULT_TOKEN=$(openssl rand -base64 32)
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo "=== Configuracion Generada ==="
|
||
|
|
echo "Dominio: $DOMAIN"
|
||
|
|
echo "IP: $SERVER_IP"
|
||
|
|
echo "DB Password: $DB_PASS"
|
||
|
|
echo "JWT Secret: $JWT_SECRET"
|
||
|
|
echo "Vault Token: $VAULT_TOKEN"
|
||
|
|
echo ""
|
||
|
|
echo "Guarda estas credenciales en un lugar seguro!"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Mantenimiento Post-Clonacion
|
||
|
|
|
||
|
|
### Tareas Semanales
|
||
|
|
- Verificar que backups se ejecutan
|
||
|
|
- Revisar logs de errores
|
||
|
|
- Actualizar contenedores si hay parches de seguridad
|
||
|
|
|
||
|
|
### Tareas Mensuales
|
||
|
|
- Renovar certificados SSL (automatico con MiaB)
|
||
|
|
- Revisar uso de disco
|
||
|
|
- Actualizar sistema operativo
|
||
|
|
|
||
|
|
### Actualizacion de Contenedores
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd /opt/services
|
||
|
|
docker compose pull
|
||
|
|
docker compose up -d
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Resolucion de Problemas Comunes
|
||
|
|
|
||
|
|
### SSL no funciona
|
||
|
|
1. Verificar que DNS apunta correctamente
|
||
|
|
2. Esperar propagacion (hasta 24h)
|
||
|
|
3. Ejecutar: `mailinabox` para regenerar certificados
|
||
|
|
|
||
|
|
### Contenedor no inicia
|
||
|
|
```bash
|
||
|
|
docker logs NOMBRE_CONTENEDOR
|
||
|
|
# Verificar si es problema de dependencias o configuracion
|
||
|
|
```
|
||
|
|
|
||
|
|
### Email no llega
|
||
|
|
1. Verificar registros MX en DNS
|
||
|
|
2. Revisar logs: `docker logs postfix` o `/var/log/mail.log`
|
||
|
|
3. Verificar que puerto 25 no esta bloqueado
|
||
|
|
|
||
|
|
### Base de datos llena
|
||
|
|
```bash
|
||
|
|
# Ver espacio
|
||
|
|
docker exec postgres psql -U tzzr -c "SELECT pg_size_pretty(pg_database_size('tzzr'));"
|
||
|
|
|
||
|
|
# Limpiar si es necesario
|
||
|
|
docker exec postgres vacuumdb -U tzzr -d tzzr -f
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Contacto y Soporte
|
||
|
|
|
||
|
|
- **Repositorio**: (agregar si se crea)
|
||
|
|
- **Documentacion Mail-in-a-Box**: https://mailinabox.email/guide.html
|
||
|
|
- **Documentacion Vaultwarden**: https://github.com/dani-garcia/vaultwarden/wiki
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
*Documento generado: Diciembre 2024*
|
||
|
|
*Ultima actualizacion: Incluye Vaultwarden y plan de clonacion*
|