JUDLEX

Guía técnica: preparar el servidor del despacho

Para quien administra el servidor del despacho. Qué hace JUDLEX por WebDAV, S3 y SFTP, qué permisos necesita y cómo dejarlo bien configurado.

Esta página es para el técnico de sistemas que prepara el almacenamiento del despacho. Si usted es quien usa JUDLEX y no administra el servidor, le basta con Si el servidor lo lleva un informático, qué pedirle.

Aquí se cuenta qué hace JUDLEX en el servidor, qué necesita de él y cómo dejarlo configurado para que funcione sin sorpresas. Todo lo que sigue vale para los tres tipos de conexión salvo donde se dice lo contrario.

Lo común a los tres

Red

  • JUDLEX solo abre conexiones salientes desde el ordenador del despacho hacia el servidor. No hace falta abrir ningún puerto hacia los ordenadores.

  • WebDAV y S3 van siempre por HTTPS. Con http:// solo se conecta a un servidor en el mismo ordenador (localhost, 127.0.0.1 o ::1); una dirección de la red local por http:// se rechaza.

  • No sigue redirecciones. Si el servidor contesta con un 3xx, JUDLEX no envía nada a la dirección nueva: le dice al usuario cuál es, para que la escriba. La única excepción es una redirección dentro del mismo servidor que solo añade o quita la barra final de una carpeta WebDAV. Por eso conviene dar la dirección definitiva (con su https://, su puerto y su ruta) y no una que redirija.

  • Las credenciales nunca van dentro de la dirección (https://usuario:clave@… se rechaza).

  • Tiempos: 20 segundos para conectar y 120 para cada respuesta normal. Una subida no tiene tiempo máximo mientras avance; se da por perdida si pasan 120 segundos sin enviar nada, o si tras el último byte el servidor no contesta en 5 minutos más un segundo por MiB (como mucho 30 minutos). Un proxy delante del servidor tiene que aguantar esos tiempos.

  • Reintenta solo lo pasajero (errores de red, 429, 503, 423 y los 5xx salvo el 501), hasta cinco veces con esperas de 1, 2, 4 y 8 segundos, o lo que diga Retry-After en segundos, con un máximo de 60.

Certificados

  • WebDAV y S3 comprueban el certificado contra los certificados de confianza del sistema operativo. Con un certificado de una autoridad reconocida (Let's Encrypt, por ejemplo) no hay que hacer nada.

  • Con un certificado propio (un NAS que se lo firma a sí mismo, o el acceso por IP), el usuario puede fijar la huella SHA-256 del certificado del servidor (el de la hoja, no el de la autoridad): JUDLEX confía en ese certificado exacto y en ningún otro, sin mirar el nombre ni las fechas. Si el certificado cambia (también al renovarlo), deja de conectar hasta que el usuario compare y fije la huella nueva. Dele al despacho esa huella para que la compare con la que le enseña JUDLEX (da igual con o sin dos puntos, en mayúsculas o minúsculas). En Linux se ve con openssl x509 -in cert.pem -noout -fingerprint -sha256.

  • TLS 1.2 o 1.3. No se usan certificados de cliente.

  • SFTP no usa TLS: se fija la llave del servidor (ver más abajo).

Lo que JUDLEX crea en el servidor

Dentro de la carpeta que se le da (la dirección WebDAV, el bucket y su prefijo, o la carpeta SFTP), JUDLEX trabaja solo en una subcarpeta JUDLEX, y en la carpeta del despacho si se usa para compartir:

<carpeta de la conexión>/
├── JUDLEX/
│   ├── probe/                 ficheros de prueba de «Probar», se borran al momento
│   ├── backup/<linaje>/       la copia de seguridad de cada ordenador
│   └── outbox/                lo compartido por enlace (cifrado), caduca a los 14 días (7 en S3)
└── JUDLEX-despacho/           solo si se comparte por la carpeta del despacho
    ├── packages/  inbox/  done/  presence/
  • Los nombres solo usan letras sin tildes, números, ., - y _, de 200 bytes como mucho.

  • Cada ordenador tiene su propio linaje de copia (backup/<32 cifras hexadecimales> si va cifrada, backup/plain-<…> si no). Varios ordenadores pueden usar la misma conexión sin pisarse.

  • Copia cifrada: en el servidor solo hay ficheros con nombres sin sentido y tamaños redondeados. No se puede saber qué hay dentro.

  • Copia sin cifrar (lo que viene de fábrica, salvo que el despacho elija cifrarla): en files/ están los documentos con sus carpetas y sus nombres, en snapshots/ la base de datos de JUDLEX tal cual y una lista con la huella de cada fichero. Quien pueda leer esa carpeta puede leer los expedientes. Dé acceso a ella solo a JUDLEX y protéjala como protegería el propio despacho.

  • Lo que se comparte con un compañero va siempre cifrado.

  • Las contraseñas, claves y llaves no se guardan nunca en el servidor: se quedan en el ordenador.

Cuánto y cuándo escribe

  • La copia se hace sola cuando hay cambios, tras 10 minutos sin tocar nada y como mucho una vez por hora, y al menos una vez al día. En cada copia se sube la base de datos entera (un fichero) y solo los documentos nuevos o cambiados.

  • Se guardan la última copia de cada uno de los últimos 30 días y la última de cada uno de los últimos 12 meses. JUDLEX borra lo que ya no hace falta, y nada más.

  • La carpeta del despacho se mira cada 5 minutos (cada ordenador ajusta su intervalo). Si el servidor rechaza la contraseña, JUDLEX deja de mirarla hasta que el usuario cambia los datos, y la copia lo vuelve a intentar como mucho una vez por hora: no provocará bloqueos de fail2ban ni del control de ataques de Nextcloud.

  • «Probar» escribe un fichero de prueba en JUDLEX/probe/, lo lee, lista la carpeta, lo borra y comprueba que se ha borrado. Si falta el permiso de listar o de borrar, la prueba lo dice. Quitar la conexión en JUDLEX no borra nada del servidor.

  • Restos de subidas cortadas: los ficheros temporales de más de un día se borran solos (en WebDAV y SFTP, al listar su carpeta; en S3, las subidas multiparte a medias se abortan).

WebDAV

Lo que necesita el servidor

  • Autenticación Basic sobre HTTPS. Digest, NTLM y Negotiate no están soportadas: si el servidor solo ofrece esas, JUDLEX lo dice.

  • PROPFIND con Depth: 0 y Depth: 1 que conteste 207 Multi-Status. Depth: infinity no se usa.

  • MKCOL, PUT con Content-Length, GET y DELETE de carpetas con su contenido.

  • Recomendado: MOVE con Destination absoluto y Overwrite, y que acepte nombres que empiezan por punto. JUDLEX sube cada fichero a un temporal oculto (.jlx-tmp-…) y lo renombra después, para que nunca quede un fichero a medias con su nombre. Si el servidor no lo permite, sube directamente.

  • LOCK, COPY y PROPPATCH no se usan.

  • En los registros verá respuestas 405 a MKCOL: es JUDLEX comprobando que la carpeta ya existe. Son normales.

Detrás de un proxy (nginx, Apache, un balanceador)

  • Deje pasar los métodos PROPFIND, MKCOL, MOVE, PUT, GET y DELETE, y las cabeceras Depth, Destination y Overwrite.

  • Destination llega con la dirección absoluta que ve JUDLEX: si el proxy cambia el prefijo de las rutas, tiene que reescribirla también. JUDLEX comprueba el primer MOVE y deja de usarlo si el fichero no aparece donde debía.

  • Tamaño: fuera de Nextcloud, cada fichero va en un solo PUT, del tamaño que tenga. Ajuste el límite del cuerpo de la petición (client_max_body_size en nginx, LimitRequestBody en Apache) al documento más grande que pueda tener el despacho, o quítelo para esa ruta. Si el servidor devuelve 413, JUDLEX le dice al usuario que el servidor no acepta ficheros tan grandes.

  • Tiempos: tras recibir un fichero grande, el servidor puede tardar en contestar. Deje al menos 5 minutos de espera de respuesta (proxy_read_timeout) y no corte por lentitud del envío.

  • No redirija http a https contando con que JUDLEX lo siga: dele directamente la dirección https://.

Nextcloud y ownCloud

  • La dirección tiene que ser la de los ficheros del usuario: https://<servidor>/remote.php/dav/files/<usuario>/<carpeta> (o la antigua …/remote.php/webdav/<carpeta>). Con …/remote.php/dav/ a secas, sin files/<usuario>, JUDLEX la rechaza.

  • Use una contraseña de aplicación solo para JUDLEX.

  • En estos servidores no se usa el temporal con MOVE (Nextcloud ya escribe de forma atómica). Los ficheros de más de 64 MiB se suben en trozos de 32 MiB por el sistema de subidas por partes de Nextcloud (/remote.php/dav/uploads/<usuario>/…), si el servidor lo anuncia en sus capacidades.

  • Enlaces para compartir: JUDLEX crea enlaces públicos de solo lectura por la API de compartir de Nextcloud (/ocs/v2.php/…), con caducidad (14 días, o menos si el servidor obliga a menos) y sin contraseña: el contenido va cifrado y solo lo abren los ordenadores a los que va dirigido. Si el servidor obliga a poner contraseña a los enlaces o los tiene desactivados, JUDLEX lo dice y no los ofrece. Para que funcionen: Ajustes de administración → Compartir, enlaces públicos permitidos, sin contraseña obligatoria. El servidor tiene que ser accesible desde internet con un certificado reconocido: el compañero lo abre sin la huella fijada. Con una dirección de la red local, JUDLEX no ofrece enlaces.

  • El error 507 (sin espacio) y el 423 (fichero bloqueado, por ejemplo durante el antivirus) se entienden: el primero se le dice al usuario como espacio lleno; el segundo se reintenta.

S3 compatible

Cómo habla con el servidor

  • Firma SigV4 en la dirección de cada petición, válida una hora. El reloj del ordenador tiene que estar en hora: si no, el servidor lo rechaza y JUDLEX le dice al usuario que lo ponga en hora.

  • Direcciones de estilo virtual host (<bucket>.<servidor>) por defecto, y de estilo ruta (<servidor>/<bucket>) si se marca la opción o si hace falta: con una IP, con localhost, o con un bucket que lleva puntos, mayúsculas o _. Para MinIO, Garage o SeaweedFS detrás de un solo nombre, marque estilo ruta.

  • La región se deduce de la dirección en los proveedores conocidos; si no, us-east-1. Si el bucket está en otra región, JUDLEX le dice al usuario cuál, si el servidor la da.

  • El bucket tiene que existir: JUDLEX no lo crea ni consulta su configuración.

  • Una ruta en la dirección del servicio se conserva (un proxy en /s3/, por ejemplo), pero …/<bucket>/carpeta se rechaza: la carpeta va en su campo.

Operaciones que usa

ListObjectsV2 (con delimiter=/ y paginación; si el servidor no da continuation-token, usa start-after o marker), HeadObject, GetObject, PutObject hasta 16 MiB, subida multiparte por encima (CreateMultipartUpload, UploadPart de una en una, CompleteMultipartUpload, AbortMultipartUpload), ListMultipartUploads para abortar las subidas a medias de más de 24 horas, y DeleteObjects por lotes de 1.000 (si no está, borra de uno en uno). Para compartir por enlace, una URL firmada de GetObject válida 7 días como mucho.

  • Las partes miden 8 MiB, o más si el fichero necesitaría más de 10.000 partes.

  • Para no sobrescribir lo que ya existe, envía If-None-Match: * al crear. Si el servidor no lo admite, deja de usarlo y comprueba antes con HeadObject.

  • No crea objetos de carpeta: las carpetas son prefijos.

  • Versionado y bloqueo de objetos: JUDLEX no los gestiona. Con el versionado activado, lo que borra JUDLEX (copias viejas, temporales) se queda como versión antigua ocupando espacio; si lo activa, añada una regla de ciclo de vida que caduque las versiones no actuales. Con bloqueo de objetos, los borrados fallarán.

La política de acceso mínima

Una clave solo para JUDLEX y solo para ese bucket. En AWS IAM (en otros proveedores, el equivalente):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:ListBucketMultipartUploads"],
      "Resource": "arn:aws:s3:::judlex-despacho"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:AbortMultipartUpload"],
      "Resource": "arn:aws:s3:::judlex-despacho/*"
    }
  ]
}
  • Si el bucket se comparte con otras cosas y JUDLEX trabaja bajo un prefijo, puede limitar los objetos a judlex-despacho/<prefijo>/* y s3:ListBucket con la condición s3:prefix.

  • s3:ListBucket es imprescindible: sin él, preguntar por un fichero que no existe da 403 en lugar de 404, y la prueba falla.

  • s3:ListBucketMultipartUploads es opcional (sin él no se limpian las subidas a medias; ponga entonces una regla de ciclo de vida que las aborte).

  • No hace falta ningún permiso sobre la configuración del bucket.

SFTP

Conexión SSH

  • Algoritmos modernos por delante: intercambio de claves curve25519-sha256 (y mlkem768x25519-sha256), cifrados chacha20-poly1305 y AES-GCM/CTR, MAC hmac-sha2-256/512. Como último recurso, para servidores antiguos, también ecdh-sha2-nistp*, diffie-hellman-group14-sha1, AES-CBC y hmac-sha1. No se ofrecen diffie-hellman-group1-sha1, 3des-cbc ni llaves DSA, ni compresión. Si no hay nada en común, JUDLEX le dice al usuario qué ofrece el servidor.

  • La llave del servidor se fija siempre: huella SHA256 (como la da ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub) y tipo (ed25519, ecdsa o rsa). Si cambia, JUDLEX no conecta. Si reinstala el servidor o cambia sus llaves, avise al despacho y deles la huella nueva.

  • Mantiene la conexión con keepalive cada 30 segundos y la cierra a los 10 minutos sin uso. Si se corta, vuelve a conectar una vez sin que el usuario lo note.

Cómo entra

  • Con llave (recomendado). JUDLEX genera una llave Ed25519 en el ordenador y le da al usuario la línea pública para el authorized_keys. También puede usar una llave que usted le dé: OpenSSH (Ed25519, ECDSA o RSA), PEM, PKCS#8 o PuTTY, con o sin frase de paso (si la tiene, JUDLEX la abre con ella y la guarda en ese ordenador sin frase). Darle una llave suya es lo cómodo si el despacho va a recuperar la copia en otro ordenador: allí se usa la misma llave y no hay que tocar el servidor.

  • Con contraseña, por password o, si el servidor solo ofrece eso, por keyboard-interactive con una sola pregunta.

  • No admite un segundo factor (un código, o llave y contraseña a la vez: AuthenticationMethods publickey,password). Para el usuario de JUDLEX, deje un solo método.

  • Las llaves RSA firman con rsa-sha2-512 o rsa-sha2-256; ssh-rsa (SHA-1) solo si el servidor no anuncia otra cosa.

Lo que necesita el servidor

  • El subsistema sftp activo para ese usuario (Subsystem sftp internal-sftp o el sftp-server del sistema). SFTP versión 3.

  • Que el inicio de sesión no escriba nada. Un echo en el .bashrc o un mensaje de bienvenida del shell rompen SFTP; JUDLEX lo detecta y se lo dice al usuario. Con internal-sftp y ForceCommand internal-sftp no pasa.

  • Extensiones de OpenSSH que aprovecha si están: posix-rename@openssh.com (sustituir un fichero de forma atómica), fsync@openssh.com (asegurar en disco antes de renombrar), statvfs@openssh.com (mirar el espacio libre antes de subir un fichero de 8 MiB o más) y limits@openssh.com (tamaño de cada bloque, hasta 64 KiB). Sin ellas funciona igual, con menos garantías.

  • Cada fichero se sube a un temporal oculto (.jt- y diez cifras) en la misma carpeta y luego se renombra. Los temporales de más de un día se borran solos.

La carpeta

  • Vacía: la carpeta personal del usuario (en un chroot, la carpeta donde empieza).

  • Sin barra delante (copias): relativa a la personal. Con barra (/despacho): absoluta; dentro de un chroot, absoluta dentro del chroot.

  • Tiene que existir ya (salvo la personal). JUDLEX no la crea, para que una errata no acabe guardando en otro sitio; dentro crea su carpeta JUDLEX.

Permisos de lo que crea

  • De fábrica, privados: carpetas 0700 y ficheros 0600. Solo el usuario de JUDLEX puede leerlos.

  • En una carpeta de equipo: si la carpeta de la conexión tiene permiso de escritura para su grupo, JUDLEX entiende que es una carpeta compartida por el despacho y crea lo suyo como 0770 y 0660, conservando el bit setgid de la carpeta para que el grupo se herede. Así, varios compañeros que entran con usuarios distintos del mismo grupo pueden usar la misma carpeta (la carpeta del despacho, o una copia que otro ordenador tenga que leer). Lo vuelve a aplicar tras crear cada fichero, aunque el umask del servidor sea 022.

  • Una carpeta que el grupo solo puede leer (0750, 0755) no cuenta como compartida.

  • Tenga en cuenta que con la copia sin cifrar, todo el grupo podrá leer los documentos.

Por ejemplo, para una carpeta de equipo en un servidor Linux:

groupadd despacho
usermod -aG despacho ana
usermod -aG despacho luis
mkdir -p /srv/despacho
chgrp despacho /srv/despacho
chmod 2770 /srv/despacho

Y en JUDLEX, como Carpeta, /srv/despacho.

Un usuario solo para SFTP, encerrado en su carpeta

Match User judlex
    ChrootDirectory /srv/sftp/judlex
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    PasswordAuthentication no

/srv/sftp/judlex tiene que ser de root y no escribible por nadie más (lo exige OpenSSH). Cree dentro una carpeta del usuario, por ejemplo /srv/sftp/judlex/copias con dueño judlex, y en JUDLEX ponga como Carpeta /copias. La llave pública va en el authorized_keys del usuario, fuera del chroot (~judlex/.ssh/authorized_keys, o donde diga AuthorizedKeysFile).

Espacio

  • Con statvfs@openssh.com, antes de subir un fichero grande JUDLEX comprueba que cabe, y si el disco se llena lo dice como «espacio lleno».

  • Una cuota por usuario no se puede consultar por SFTP, y OpenSSH contesta a una cuota agotada con un fallo sin explicación. Cuando eso pasa con espacio libre en el disco, JUDLEX le dice al usuario que lo más probable es que su usuario haya llegado a su límite de espacio. Si pone cuotas, deje margen para las copias de 30 días y 12 meses.

Lista de comprobación

  • Dirección definitiva por https:// (o servidor SFTP con su puerto), sin redirecciones.

  • Certificado reconocido, o la huella SHA-256 del certificado para el despacho.

  • Un usuario o una clave solo para JUDLEX, con acceso solo a su carpeta o su bucket.

  • Permiso para listar, leer, escribir y borrar en esa carpeta.

  • El bucket (S3) o la carpeta (SFTP) ya creados.

  • Proxy: métodos WebDAV permitidos, sin límite de tamaño corto y con tiempos de espera amplios.

  • SFTP: la huella de la llave del servidor para el despacho, un solo método de entrada y un inicio de sesión que no escriba nada.

  • Si la copia va sin cifrar: que nadie más pueda leer esa carpeta.

  • Pulsar Probar en JUDLEX y comprobar que pasa.

¿Te ha servido esta página?