Sistema de copias de seguridad autoalojado para usuarios domésticos y pequeñas empresas. Corre sobre Linux (Debian/Ubuntu/Raspberry Pi OS) y se gestiona desde un panel web sencillo. Los equipos Windows suben sus archivos automáticamente mediante un agente Python que se descarga desde el panel.
Repositorio: https://github.com/Marinettoo/Niddo
Web del proyecto: docs/ (publicada con GitHub Pages)
Niddo/
├── config/
│ ├── db.php # Conexión PDO a MariaDB
│ └── cuotas.php # Cuotas de espacio por disco (gestionado desde el panel)
├── api/
│ ├── .htaccess # Eleva límites de subida a 500 MB
│ ├── auth.php # Login con bloqueo por IP + marca usuario activo
│ ├── backup.php # Recepción de archivos del agente (multipart)
│ ├── download.php # Descarga segura de archivos (con control de acceso)
│ ├── download_carpeta.php # Descarga de carpetas enteras como ZIP
│ └── setup.php # Creación del primer administrador
├── panel/
│ ├── _head.php # Partial: meta, fuentes, CSS
│ ├── _nav.php # Partial: sidebar con visibilidad por rol
│ ├── _session.php # Partial: control de sesión + timeout de 5 min
│ ├── style.css # Sistema de diseño del panel
│ ├── login.php # Login (o setup si no hay usuarios)
│ ├── logout.php # Cierre de sesión
│ ├── dashboard.php # Estadísticas (filtradas por rol)
│ ├── dispositivos.php # Gestión de dispositivos
│ ├── usuarios.php # Gestión de usuarios y roles (solo Admin)
│ ├── eventos.php # Visor de eventos de seguridad (solo Admin)
│ ├── restaurar.php # Descarga de archivos / carpetas
│ ├── discos.php # Montaje/desmontaje + cuotas (solo Admin)
│ └── generar_agente.php # Genera el agente Python personalizado por dispositivo
├── docs/ # Web pública (HTML/CSS) — servida por GitHub Pages
│ ├── index.html
│ ├── about.html
│ ├── service.html
│ ├── gallery.html
│ ├── testimonial.html
│ ├── contact.html
│ ├── css/ js/ fonts/ images/
│ ├── MER.png # Diagrama entidad-relación referenciado por este readme
│ └── .nojekyll # Desactiva el procesamiento Jekyll de GitHub Pages
├── web/ # Imágenes usadas por el panel PHP
│ ├── niddo Logo completo.png
│ ├── niddo Logotipo.png
│ ├── niddo Isólogo.png
│ ├── banner.png
│ └── Dispositivos.png
├── niddo_schema.sql # Esquema completo de BD
├── install.sh # Instalador automático
├── uninstall.sh # Desinstalador (deja el servidor limpio)
└── readme.md # Este archivo
git clone https://github.com/Marinettoo/Niddo
cd Niddo
sudo bash install.sh- Instala Apache2, PHP, MariaDB y extensiones necesarias (
php-mysql,php-mbstring,php-zip). - Arranca y habilita los servicios con
systemctl. - Crea la base de datos
niddoe importaniddo_schema.sql(con los rolesAdminyUsuarioya sembrados). - Crea el usuario MySQL
niddocon permisos solo sobre esa base. - Copia los archivos a
/var/www/html/niddo/. - Actualiza
config/db.phpcon las credenciales reales mediantesed. - Crea
/var/niddo/backups/con permisos dewww-data. - Habilita
mod_rewritey configura Apache para que los.htaccessfuncionen. - Configura sudoers: añade
/etc/sudoers.d/niddopara quewww-datapueda ejecutarmountyumountsin contraseña (necesario para la gestión de discos desde el panel). - Muestra la URL del panel con la IP del servidor.
sudo bash uninstall.shBorra todo: panel, backups, configuración de Apache, base de datos y usuario MySQL, paquetes instalados y la regla de sudoers.
Base MariaDB niddo con las siguientes tablas:
| Tabla | Descripción |
|---|---|
users |
Usuarios (nombre, email, contraseña bcrypt, estado activo/inactivo) |
roles |
Roles del sistema. Solo dos: Admin y Usuario (sembrados al instalar) |
user_roles |
|
devices |
Dispositivos registrados; cada uno con token único y user_id propietario |
device_folders |
Carpetas configuradas por dispositivo para hacer backup |
repositorios |
Repositorios donde se almacenan los backups |
backups |
Cada operación de backup (tamaño, fecha, estado) |
files |
Archivos individuales del backup (con hash SHA-256) |
events |
Eventos de seguridad: logins, fallos, IPs bloqueadas, etc. |
settings |
Configuración global clave-valor |
Modelo entidad-relacion de la base de datos:

Solo existen dos roles:
| Rol | Qué ve y qué puede hacer |
|---|---|
| Admin | Todo: dispositivos, usuarios, eventos, discos. Ve datos de todos los usuarios. |
| Usuario | Solo sus propios dispositivos y sus propios archivos. Sin acceso a Usuarios/Eventos/Discos. |
Administrador principal ( El que su user_id = 1, el primero creado): es el único que puede degradar a otro Admin a Usuario. Cualquier Admin puede promocionar usuarios a Admin.
- Contraseñas con bcrypt (
password_hash/password_verify). Es la manera estándar de manejar contraseñas en PHP. - Tokens de dispositivo de 64 caracteres hex con bin2hex. Permite generar una cadena aleatoria única y segura que actúa como una llave para recordar y autenticar un dispositivo autorizado, sin necesidad de exponer la contraseña real.
- Bloqueo automático de IP tras 5 intentos fallidos consecutivos (consultando la tabla
events). - Sesión con timeout de 5 minutos de inactividad — al expirar, el usuario queda marcado como
inactivoen la BD y se redirige al login. Implementado enpanel/_session.php(incluido por todas las páginas del panel). - Estado de usuario:
activoal iniciar sesión,inactivoal cerrarla o al expirar. - Verificación SHA-256 de cada archivo subido.
- Mini-SOC: la tabla
eventsregistra logins, fallos, bloqueos, copias completadas/erróneas, cambios de configuración…
Maneja dos modos según el $_POST:
- Login de panel: recibe
email+password. Verifica conpassword_verify, comprueba que la IP no esté bloqueada (5 fallos enevents), carga los roles del usuario en$_SESSION['roles'], marca al usuario comoactivo, e inicializa$_SESSION['last_activity']. - Token del agente: recibe
token, busca endevicesy devuelvedevice_iden texto plano.
Solo se ejecuta cuando no hay ningún usuario. Crea al primer admin y le asigna automáticamente el rol Admin.
Recibe del agente: token, archivo ($_FILES) y hash SHA-256. Valida el token, guarda el fichero en /var/niddo/backups/{device_id}/{ruta_relativa}/, registra en backups y files, y responde ok.
El .htaccess de api/ amplía upload_max_filesize y post_max_size a 500 MB y max_execution_time a 300 s.
- Comprueba sesión activa.
- Si el usuario es
Usuario(no Admin), solo puede descargar archivos que pertenezcan a sus propios dispositivos (JOINfiles → backups → devicesfiltrando poruser_id). - Devuelve el archivo con
Content-Disposition: attachment.
Recibe el device_id y la ruta relativa de la carpeta. Misma comprobación de propiedad que download.php. Genera el ZIP al vuelo con ZipArchive de PHP. Que es una clase nativa de php y lo manda como descarga.
Interfaz con nav en el lado. Todas las páginas empiezan con require '_session.php'. Para mantener la sesión siempre activa.
- Admin: 4 tarjetas (dispositivos, backups, usuarios, espacio total), tabla de últimos backups y de últimos eventos.
- Usuario: solo sus propios dispositivos y backups, sin tarjeta de usuarios ni tabla de eventos.
Formulario para registrar un nuevo dispositivo (nombre, SO, repositorio). El token se genera automáticamente. Avisa de que se necesita Python 3 en el cliente con enlace a python.org. Los usuarios no-Admin solo ven sus propios dispositivos.
- Crear usuarios nuevos con email, contraseña y rol.
- Cambiar el rol de cualquier usuario (
Usuario↔Admin). - Solo el administrador principal (
user_id = 1) puede degradar a otro Admin. Cualquier Admin puede promocionar. - El admin principal aparece marcado con
*en la tabla.
Últimos 200 eventos con filtro por tipo. Los eventos *_fallido se muestran en rojo, el resto en verde.
Lista dispositivos (filtrados por usuario si no es Admin). Al seleccionar uno, muestra todos los archivos con opción de descarga individual o descarga de la carpeta completa como ZIP.
Gestión de discos del servidor sin tocar la base de datos:
- Lista discos montados leyendo
df -B1(filtra los archivos de sistema). - Por cada disco: formulario para asignar cuota en GB y botón de desmontaje (
sudo umount). - Al final: formulario para montar un disco nuevo (
sudo mount). - Las cuotas se guardan en
config/cuotas.phpcomo un array PHP. - Funciona gracias a la regla de sudoers que añade el instalador (
www-data ALL=(root) NOPASSWD: /bin/mount, /bin/umount).
Genera al vuelo el script Python configurado para un dispositivo concreto y lo sirve como descarga directa. Usa nowdoc (<<<'PYTHON') para que el código Python no sufra interpolación, e inyecta __TOKEN__, __SERVIDOR__ y __NOMBRE__ con str_replace. La URL del servidor se calcula con $_SERVER['HTTP_HOST'] para que funcione en cualquier red.
Se descarga desde el panel (una vez por dispositivo) y se ejecuta con Python 3 en Windows.
Modos:
python agente.py— abre la ventana tkinter donde el usuario elige carpetas, configura el intervalo y activa el backup automático mediante Task Scheduler (schtasks).python agente.py --auto— modo silencioso usado por Task Scheduler.
Flujo del backup:
- Recorre recursivamente las carpetas seleccionadas.
- Para cada archivo calcula el hash SHA-256 y lo sube por
multipart/form-dataaapi/backup.php. - El servidor valida token, guarda el archivo y registra el resultado.
Configuración persistente: %APPDATA%\Niddo\{nombre_dispositivo}.json.
Solo usa librerías estándar de Python (urllib, hashlib, tkinter, os, json) — sin dependencias externas que instalar.
Sitio HTML/CSS publicado mediante GitHub Pages desde la carpeta /docs de la rama principal. Es una plantilla de codigo abierto (https://plantillashtmlgratis.com/todas-las-plantillas/plantilla/plantilla-web-gratis-limelight/) rellenada. Para presentar el proyecto:
index.html— landing con hero, features, precios.about.html— documentación PASIR completa (RA.1 a RA.4).service.html— funcionalidades del producto.gallery.html— guía de instalación y planes de precios.testimonial.html— capas de seguridad y RGPD.contact.html— créditos del equipo y stack técnico.
Paleta basada en el azul del logo (#1a8fe8 / #1f3f72).
| Capa | Tecnología |
|---|---|
| SO servidor | Debian 12 / Ubuntu 24.04 LTS |
| Servidor web | Apache 2.4 |
| Backend | PHP |
| Base de datos | MariaDB 11.x |
| Frontend panel | HTML5 + CSS3 (sin frameworks) |
| Web pública | HTML5 + CSS + JS |
| Agente cliente | Python3 |
| Automatización | Bash + apt-get |
| Control de ver. | Git + GitHub |
MIT — uso, modificación y distribución libres, incluso comercial, manteniendo el aviso de copyright.
- Jesús Pérez Marinetto — backend, frontend, base de datos, Página web, mantenimiento del repositorio, Documentación
- Nicolás Baya-Casal Sansolini — Documentación
- Ismael Martín Ruiz — Modelo Entidad-Relación de la base de datos
- Iván López García —