Initial commit: MeshCentral deployment setup
Some checks failed
deploy-meshcentral / deploy (push) Failing after 1m37s
Some checks failed
deploy-meshcentral / deploy (push) Failing after 1m37s
Configuración completa de MeshCentral con: - Integración OIDC con Authentik - Docker Compose para deployment - Gitea Actions workflow para CI/CD - Traefik labels para routing y SSL - Separación de rutas de usuario y agentes
This commit is contained in:
10
.env.example
Normal file
10
.env.example
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Configuración de la aplicación
|
||||||
|
APP_NAME=meshcentral
|
||||||
|
APP_DOMAIN=mesh.nucleoriofrio.com
|
||||||
|
MESH_PORT=4430
|
||||||
|
|
||||||
|
# Configuración de Authentik OIDC
|
||||||
|
# Obtener estos valores desde Authentik después de crear el Provider
|
||||||
|
AUTHENTIK_ISSUER=https://authentik.nucleoriofrio.com/application/o/meshcentral/
|
||||||
|
AUTHENTIK_CLIENT_ID=your-client-id-here
|
||||||
|
AUTHENTIK_CLIENT_SECRET=your-client-secret-here
|
||||||
111
.gitea/workflows/build-and-deploy.yml
Normal file
111
.gitea/workflows/build-and-deploy.yml
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
name: deploy-meshcentral
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: docker
|
||||||
|
env:
|
||||||
|
APP_NAME: ${{ vars.APP_NAME }}
|
||||||
|
APP_DOMAIN: ${{ vars.APP_DOMAIN }}
|
||||||
|
MESH_PORT: ${{ vars.MESH_PORT }}
|
||||||
|
# Authentik OIDC configuration
|
||||||
|
AUTHENTIK_ISSUER: ${{ vars.AUTHENTIK_ISSUER }}
|
||||||
|
AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }}
|
||||||
|
AUTHENTIK_CLIENT_SECRET: ${{ secrets.AUTHENTIK_CLIENT_SECRET }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Info about deployment
|
||||||
|
run: |
|
||||||
|
echo "ℹ️ Deploying MeshCentral"
|
||||||
|
echo " Domain: ${{ vars.APP_DOMAIN }}"
|
||||||
|
echo " Container: ${{ vars.APP_NAME }}"
|
||||||
|
echo " Network: principal"
|
||||||
|
|
||||||
|
- name: Create required directories
|
||||||
|
run: |
|
||||||
|
mkdir -p meshcentral-data
|
||||||
|
mkdir -p meshcentral-files
|
||||||
|
mkdir -p meshcentral-backup
|
||||||
|
mkdir -p meshcentral-config
|
||||||
|
|
||||||
|
- name: Generate MeshCentral config.json
|
||||||
|
run: |
|
||||||
|
cat > meshcentral-data/config.json <<'EOF'
|
||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"cert": "${{ vars.APP_DOMAIN }}",
|
||||||
|
"port": 4430,
|
||||||
|
"aliasPort": 443,
|
||||||
|
"redirPort": 0,
|
||||||
|
"AgentPong": 300,
|
||||||
|
"TlsOffload": "127.0.0.1",
|
||||||
|
"SelfUpdate": false,
|
||||||
|
"AllowFraming": false,
|
||||||
|
"WebRTC": true,
|
||||||
|
"ClickOnce": false,
|
||||||
|
"AllowHighQualityDesktop": true,
|
||||||
|
"DesktopAspectRatios": "1.33,1.5,1.6,1.7,1.778,2.0"
|
||||||
|
},
|
||||||
|
"domains": {
|
||||||
|
"": {
|
||||||
|
"title": "MeshCentral - Nucleo Rio Frio",
|
||||||
|
"title2": "Remote Management Platform",
|
||||||
|
"newAccounts": false,
|
||||||
|
"certUrl": "https://${{ vars.APP_DOMAIN }}:443/",
|
||||||
|
"geoLocation": true,
|
||||||
|
"cookieIpCheck": false,
|
||||||
|
"allowLoginToken": true,
|
||||||
|
"allowFraming": false,
|
||||||
|
"authStrategies": {
|
||||||
|
"authentik": {
|
||||||
|
"issuer": "${{ vars.AUTHENTIK_ISSUER }}",
|
||||||
|
"clientid": "${{ secrets.AUTHENTIK_CLIENT_ID }}",
|
||||||
|
"clientsecret": "${{ secrets.AUTHENTIK_CLIENT_SECRET }}",
|
||||||
|
"callbackurl": "https://${{ vars.APP_DOMAIN }}/auth-oidc-callback"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passwordRequirements": {
|
||||||
|
"min": 8,
|
||||||
|
"max": 128,
|
||||||
|
"upper": 1,
|
||||||
|
"lower": 1,
|
||||||
|
"numeric": 1,
|
||||||
|
"nonalpha": 1
|
||||||
|
},
|
||||||
|
"agentInviteCodes": false,
|
||||||
|
"userNameIsEmail": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Set correct permissions
|
||||||
|
run: |
|
||||||
|
chmod -R 755 meshcentral-data
|
||||||
|
chmod -R 755 meshcentral-files
|
||||||
|
chmod -R 755 meshcentral-backup
|
||||||
|
chmod -R 755 meshcentral-config
|
||||||
|
|
||||||
|
- name: Pull latest MeshCentral image
|
||||||
|
run: docker pull ghcr.io/ylianst/meshcentral:latest
|
||||||
|
|
||||||
|
- name: Clean up existing stack
|
||||||
|
run: docker compose --project-name $APP_NAME down || true
|
||||||
|
|
||||||
|
- name: Start MeshCentral stack
|
||||||
|
run: docker compose --project-name $APP_NAME up -d --remove-orphans --wait
|
||||||
|
|
||||||
|
- name: Wait for MeshCentral to be ready
|
||||||
|
run: |
|
||||||
|
echo "⏳ Waiting for MeshCentral to start..."
|
||||||
|
sleep 10
|
||||||
|
docker logs ${APP_NAME}
|
||||||
|
|
||||||
|
- name: Deployment complete
|
||||||
|
run: |
|
||||||
|
echo "✅ MeshCentral deployed successfully"
|
||||||
|
echo " Access at: https://${{ vars.APP_DOMAIN }}"
|
||||||
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
|
||||||
|
# MeshCentral data directories (contienen datos sensibles)
|
||||||
|
meshcentral-data/
|
||||||
|
meshcentral-files/
|
||||||
|
meshcentral-backup/
|
||||||
|
meshcentral-config/
|
||||||
|
|
||||||
|
# Node modules
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
191
README.md
Normal file
191
README.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# MeshCentral - Nucleo Rio Frio
|
||||||
|
|
||||||
|
Sistema de gestión remota de dispositivos basado en MeshCentral, integrado con Authentik para autenticación SSO.
|
||||||
|
|
||||||
|
## Características
|
||||||
|
|
||||||
|
- ✅ **Acceso remoto completo**: Terminal, RDP, transferencia de archivos
|
||||||
|
- ✅ **Autenticación SSO**: Integrado con Authentik via OIDC
|
||||||
|
- ✅ **Multi-tenancy**: Gestión de múltiples clientes/grupos
|
||||||
|
- ✅ **Deployment automatizado**: CI/CD con Gitea Actions
|
||||||
|
- ✅ **Seguridad**: Forward Auth de Authentik en rutas de usuario
|
||||||
|
|
||||||
|
## Arquitectura
|
||||||
|
|
||||||
|
```
|
||||||
|
Cliente (PC remota)
|
||||||
|
↓
|
||||||
|
MeshAgent (servicio Windows/Linux)
|
||||||
|
↓
|
||||||
|
Conexión WSS saliente → mesh.nucleoriofrio.com
|
||||||
|
↓
|
||||||
|
Traefik (reverse proxy + SSL)
|
||||||
|
↓
|
||||||
|
MeshCentral (contenedor Docker)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Requisitos previos
|
||||||
|
|
||||||
|
1. **Servidor con Docker** y `docker-compose`
|
||||||
|
2. **Traefik** configurado con:
|
||||||
|
- Red `principal`
|
||||||
|
- Red `traefik-network`
|
||||||
|
- Middleware `authentik-forward-auth@file`
|
||||||
|
3. **Authentik** con Provider OIDC configurado
|
||||||
|
|
||||||
|
### Variables de entorno en Gitea
|
||||||
|
|
||||||
|
Configurar en **Settings > Actions > Secrets and Variables**:
|
||||||
|
|
||||||
|
#### Variables (`vars`):
|
||||||
|
```
|
||||||
|
APP_NAME=meshcentral
|
||||||
|
APP_DOMAIN=mesh.nucleoriofrio.com
|
||||||
|
MESH_PORT=4430
|
||||||
|
AUTHENTIK_ISSUER=https://authentik.nucleoriofrio.com/application/o/meshcentral/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Secrets (`secrets`):
|
||||||
|
```
|
||||||
|
AUTHENTIK_CLIENT_ID=<obtenido de Authentik>
|
||||||
|
AUTHENTIK_CLIENT_SECRET=<obtenido de Authentik>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuración de Authentik
|
||||||
|
|
||||||
|
1. **Crear OAuth2/OIDC Provider**:
|
||||||
|
- Name: `meshcentral-oidc`
|
||||||
|
- Client Type: `Confidential`
|
||||||
|
- Redirect URIs: `https://mesh.nucleoriofrio.com/auth-oidc-callback`
|
||||||
|
- Signing Key: `authentik Self-signed Certificate`
|
||||||
|
|
||||||
|
2. **Crear Application**:
|
||||||
|
- Name: `MeshCentral`
|
||||||
|
- Slug: `meshcentral`
|
||||||
|
- Provider: `meshcentral-oidc`
|
||||||
|
- Launch URL: `https://mesh.nucleoriofrio.com`
|
||||||
|
|
||||||
|
3. **Obtener credenciales**:
|
||||||
|
- Client ID: Copiar desde el Provider
|
||||||
|
- Client Secret: Copiar desde el Provider
|
||||||
|
|
||||||
|
### Deployment automático
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
Gitea Actions se encargará de:
|
||||||
|
1. Generar `config.json` con configuración OIDC
|
||||||
|
2. Crear directorios necesarios
|
||||||
|
3. Bajar el stack anterior (si existe)
|
||||||
|
4. Levantar MeshCentral con docker-compose
|
||||||
|
5. Exponer via Traefik
|
||||||
|
|
||||||
|
### Acceso
|
||||||
|
|
||||||
|
1. **Web UI**: `https://mesh.nucleoriofrio.com`
|
||||||
|
2. **Primer login**: Usar "Login with Authentik"
|
||||||
|
3. **Crear grupos de dispositivos**: Organizar por cliente/ubicación
|
||||||
|
|
||||||
|
## Instalación de agentes
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
1. Ir a `https://mesh.nucleoriofrio.com`
|
||||||
|
2. Login con Authentik
|
||||||
|
3. Click en el grupo de dispositivos
|
||||||
|
4. Click en "Add Agent"
|
||||||
|
5. Descargar el instalador Windows
|
||||||
|
6. Ejecutar en la PC del cliente (requiere admin)
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget -O meshagent https://mesh.nucleoriofrio.com/meshagents?id=XXXX
|
||||||
|
chmod +x meshagent
|
||||||
|
sudo ./meshagent -install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Seguridad
|
||||||
|
|
||||||
|
### Protección con Authentik
|
||||||
|
|
||||||
|
- **Rutas de usuario**: Protegidas con Forward Auth de Authentik
|
||||||
|
- **Rutas de agentes**: Sin autenticación (los agentes usan certificados propios)
|
||||||
|
|
||||||
|
### Rutas protegidas vs. públicas
|
||||||
|
|
||||||
|
**Protegidas** (requieren login en Authentik):
|
||||||
|
- `/` - Panel principal
|
||||||
|
- `/login` - Login (si no se usa OIDC)
|
||||||
|
- `/admin` - Administración
|
||||||
|
- Todo lo demás no especificado abajo
|
||||||
|
|
||||||
|
**Públicas** (para agentes):
|
||||||
|
- `/agent.ashx` - Comunicación de agentes
|
||||||
|
- `/meshrelay.ashx` - Relay P2P
|
||||||
|
- `/devicefile.ashx` - Transferencia de archivos
|
||||||
|
- `/amtactivate` - Activación Intel AMT
|
||||||
|
- `/meshsettings` - Configuración de agentes
|
||||||
|
- `/devicepower.ashx` - Control de energía
|
||||||
|
|
||||||
|
## Mantenimiento
|
||||||
|
|
||||||
|
### Ver logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs meshcentral
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup manual
|
||||||
|
|
||||||
|
Los datos importantes están en:
|
||||||
|
- `./meshcentral-data` - Base de datos y configuración
|
||||||
|
- `./meshcentral-files` - Archivos compartidos
|
||||||
|
- `./meshcentral-backup` - Backups automáticos
|
||||||
|
|
||||||
|
### Reiniciar servicio
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --project-name meshcentral restart
|
||||||
|
```
|
||||||
|
|
||||||
|
### Actualizar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git pull origin main
|
||||||
|
git push origin main # Trigger deployment
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Los agentes no se conectan
|
||||||
|
|
||||||
|
1. Verificar que las rutas de agentes no estén bloqueadas por Authentik
|
||||||
|
2. Revisar prioridad de routers en Traefik (agentes debe ser > 200)
|
||||||
|
3. Verificar certificados SSL
|
||||||
|
|
||||||
|
### Login OIDC no funciona
|
||||||
|
|
||||||
|
1. Verificar `AUTHENTIK_ISSUER` termina con `/`
|
||||||
|
2. Verificar Redirect URI en Authentik coincide exactamente
|
||||||
|
3. Revisar logs: `docker logs meshcentral`
|
||||||
|
|
||||||
|
### No puedo acceder al panel
|
||||||
|
|
||||||
|
1. Verificar Forward Auth de Authentik está configurado
|
||||||
|
2. Verificar DNS apunta correctamente
|
||||||
|
3. Verificar certificados SSL de Traefik
|
||||||
|
|
||||||
|
## Documentación oficial
|
||||||
|
|
||||||
|
- [MeshCentral Docs](https://ylianst.github.io/MeshCentral/)
|
||||||
|
- [MeshCentral GitHub](https://github.com/Ylianst/MeshCentral)
|
||||||
|
- [Authentik Docs](https://docs.goauthentik.io/)
|
||||||
|
|
||||||
|
## Soporte
|
||||||
|
|
||||||
|
Para problemas o consultas: claudeCode0@nucleoriofrio.com
|
||||||
68
docker-compose.yml
Normal file
68
docker-compose.yml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
meshcentral:
|
||||||
|
image: ghcr.io/ylianst/meshcentral:latest
|
||||||
|
container_name: ${APP_NAME:-meshcentral}
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${MESH_PORT:-4430}:4430"
|
||||||
|
volumes:
|
||||||
|
- ./meshcentral-data:/opt/meshcentral/meshcentral-data
|
||||||
|
- ./meshcentral-files:/opt/meshcentral/meshcentral-files
|
||||||
|
- ./meshcentral-backup:/opt/meshcentral/meshcentral-backup
|
||||||
|
- ./meshcentral-config:/opt/meshcentral/meshcentral-config
|
||||||
|
environment:
|
||||||
|
- HOSTNAME=${APP_DOMAIN}
|
||||||
|
- REVERSE_PROXY=traefik
|
||||||
|
- REVERSE_PROXY_TLS_PORT=443
|
||||||
|
- IFRAME=false
|
||||||
|
- ALLOWLOGINTOKEN=true
|
||||||
|
- LOCALSESSIONRECORDING=false
|
||||||
|
- MINIFY=true
|
||||||
|
- WEBRTC=true
|
||||||
|
- CLICKONCE=false
|
||||||
|
- ALLOWHIGHQUALITYDESKTOP=true
|
||||||
|
- DESKTOPASPECTRATIOS=1.33,1.5,1.6,1.7,1.778,2.0
|
||||||
|
- ALLOWFRAMING=false
|
||||||
|
- COOKIEENCODING=hex
|
||||||
|
- SESSIONRECORDINGCHUNKSIZE=1000000
|
||||||
|
networks:
|
||||||
|
- principal
|
||||||
|
- traefik-network
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.docker.network=principal"
|
||||||
|
|
||||||
|
# Service
|
||||||
|
- "traefik.http.services.${APP_NAME}.loadbalancer.server.port=4430"
|
||||||
|
- "traefik.http.services.${APP_NAME}.loadbalancer.server.scheme=https"
|
||||||
|
|
||||||
|
# Router principal con Authentik Forward Auth para rutas de usuario
|
||||||
|
- "traefik.http.routers.${APP_NAME}.rule=Host(`${APP_DOMAIN}`) && !PathPrefix(`/agent.ashx`) && !PathPrefix(`/meshrelay.ashx`) && !PathPrefix(`/devicefile.ashx`) && !PathPrefix(`/amtactivate`) && !PathPrefix(`/meshsettings`) && !PathPrefix(`/devicepower.ashx`)"
|
||||||
|
- "traefik.http.routers.${APP_NAME}.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.${APP_NAME}.tls=true"
|
||||||
|
- "traefik.http.routers.${APP_NAME}.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.routers.${APP_NAME}.service=${APP_NAME}"
|
||||||
|
- "traefik.http.routers.${APP_NAME}.priority=100"
|
||||||
|
- "traefik.http.routers.${APP_NAME}.middlewares=authentik-forward-auth@file,${APP_NAME}-headers"
|
||||||
|
|
||||||
|
# Router para agentes (sin autenticación) - mayor prioridad
|
||||||
|
- "traefik.http.routers.${APP_NAME}-agents.rule=Host(`${APP_DOMAIN}`) && (PathPrefix(`/agent.ashx`) || PathPrefix(`/meshrelay.ashx`) || PathPrefix(`/devicefile.ashx`) || PathPrefix(`/amtactivate`) || PathPrefix(`/meshsettings`) || PathPrefix(`/devicepower.ashx`))"
|
||||||
|
- "traefik.http.routers.${APP_NAME}-agents.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.${APP_NAME}-agents.tls=true"
|
||||||
|
- "traefik.http.routers.${APP_NAME}-agents.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.routers.${APP_NAME}-agents.service=${APP_NAME}"
|
||||||
|
- "traefik.http.routers.${APP_NAME}-agents.priority=200"
|
||||||
|
- "traefik.http.routers.${APP_NAME}-agents.middlewares=${APP_NAME}-headers"
|
||||||
|
|
||||||
|
# Custom headers middleware
|
||||||
|
- "traefik.http.middlewares.${APP_NAME}-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
|
||||||
|
- "traefik.http.middlewares.${APP_NAME}-headers.headers.customrequestheaders.X-Forwarded-Host=${APP_DOMAIN}"
|
||||||
|
- "traefik.http.middlewares.${APP_NAME}-headers.headers.sslredirect=true"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
principal:
|
||||||
|
external: true
|
||||||
|
traefik-network:
|
||||||
|
external: true
|
||||||
Reference in New Issue
Block a user