svnserve, un servidor personalizado

El programa svnserve es un servidor ligero, capaz de hablar a clientes sobre TCP/IP utilizando un protocolo con estado personalizado. Los clientes contactan un servidor svnserve utilizando URLs que comienzan con el esquema svn:// o svn+ssh://. Esta sección explica las diferentes maneras de ejecutar un svnserve, cómo los clientes se autentican ellos mismos con el servidor, y cómo se configura un control de acceso apropiado a su repositorio.

Invocando el Servidor

Existen unas cuantas maneras diferentes de invocar el programa svnserve. Si se lo invoca sin argumentos, usted no verá nada más que un mensaje de ayuda. No obstante, si planea que inetd dispare el proceso, puede pasar la opción -i (--inetd):

$ svnserve -i
( success ( 1 2 ( ANONYMOUS ) ( edit-pipeline ) ) )

Cuando es invocado con la opción --inetd, svnserve intenta comunicarse con un cliente Subversion a través de stdin y stdout utilizando un protocolo personalizado. Este es un comportamiento estándar de los programas que son ejecutados a través de inetd. El IANA ha reservado el puerto 3690 para el protocolo Subversion, por lo tanto en un sistema tipo Unix usted puede agregar líneas a /etc/services como éstas (si es que no existen todavía):

svn           3690/tcp   # Subversion
svn           3690/udp   # Subversion

Y si su sistema utiliza un demonio inetd tipo Unix clásico, puede agregar esta línea a /etc/inetd.conf:

svn stream tcp nowait svnowner /usr/local/bin/svnserve svnserve -i

Asegúrese que svnowner es un usuario que posee permisos apropiados para acceder a su repositorio. Ahora, cuando una conexión cliente ingrese a su servidor en el puerto 3690, inetd disparará un proceso svnserve para servirlo.

Una segunda opción es ejecutar svnserve un proceso demonio independiente. Para esto, utilice la opción -d:

$ svnserve -d
$               # svnserve is now running, listening on port 3690

Cuando svnserve ejecute en modo demonio, usted puede utilizar las opciones --listen-port= y --listen-host= para personalizar el puerto y nombre exacto en el cual escuchará.

Aún queda una tercera forma de invocar a svnserve, y esa es en modo túnel, con la opción -t. Este modo supone que un programa de servicio remoto tal como RSH o SSH ha autenticado un cliente exitosamente y ahora está invocando un proceso privado svnserve como tal usuario. El programa svnserve se comporta normalmente (comunicándose a través de stdin y stdout), y asume que el tráfico está siendo redirigido automáticamente a través de algún tipo de túnel de vuelta al cliente. Cuando svnserve es invocado por un agente túnel como éste, está seguro que el usuario autenticado posee acceso total de lectura y escritura a los archivos de la base de datos del repositorio. (Ver Servidores y Permisos: Una Palabra de Advertencia.) Esencialmente es lo mismo que un usuario local accediendo al repositorio a través de las URLs file:///.

Una vez el programa svnserve se esté ejecutando, hace que cada repositorio en su sistema se encuentre disponibles a la red. Un cliente necesita especificar una ruta absoluta en la URL del repositorio. Por ejemplo, si un repositorio se encuentra ubicado en /usr/local/repositories/project1, el cliente accederá a través de svn://host.example.com/usr/local/repositories/project1 . Para incrementar la seguridad, usted puede pasar la opción -r a svnserve, que limita a exportar sólo los repositorios debajo de esa ruta:

$ svnserve -d -r /usr/local/repositories
…

En efecto, utilizando la opción -r modifica la ubicación que el programa tratará como raíz del espacio de sistema de archivos remoto. En consecuencia, los clientes utilizarán URLs que tengan la porción que le ha sido removida de la ruta, dejando URLs mucho más cortas (y mucho menos reveladoras):

$ svn checkout svn://host.example.com/project1
…

Autenticación y autorización integradas

Cuando un cliente se conecta a un proceso svnserve, las siguientes cosas suceden:

  • El cliente selecciona un repositorio específico.

  • El servidor procesa el archivo conf/svnserve.conf del repositorio, y comienza a poner en ejecución cualquier política de autenticación y autorización definida en éste.

  • Dependiendo de la situación y las políticas de autorización,

    • se le puede permitir al cliente realizar pedidos de forma anónima, y sin haber recibido la demanda de autenticación, O

    • el cliente puede ser consultado por la autenticación en cualquier momento, O

    • si opera en el modo túnel, el cliente se anuncia a sí mismo que ya ha sido autenticado externamente.

En el momento de escribir estas líneas, el servidor sólo sabe cómo realizar la autenticación por CRAM-MD5 [29]. En esencia, el servidor envía unos pocos datos al cliente. El cliente usa el algoritmo hash MD5 para crear una huella digital de los datos y la palabra clave combinados, y envía la huella digital como respuesta. El servidor realiza el mismo cálculo con la palabra clave almacenada para verificar que el resultado es idéntico. En ningún momento el password real viaja a través de la red.

También es posible, por supuesto, que el cliente se autentifique externamente vía agente de túnel , como por ejemplo SSH. En este caso, el servidor simplemente examina el usuario bajo el cual se está ejecutando, y lo usa durante la autenticación.

Tal y como habrá imaginado, el fichero svnserve.conf es el mecanismo central de un repositorio para controlar las políticas de autenticación y autorización. El fichero sigue el mismo formato que otros ficheros de configuración (vea “Área de configuración de parámetros de ejecución”): los nombres de sección están enmarcados por corchetes ([ y ]), los comentarios comienzan con almohadillas (#), y cada sección contiene variables específicas que pueden ser modificadas (variable = valor). Démonos un paseo por este fichero para aprender a usarlas.

Crear un fichero 'users' y realm

Por ahora, la sección [general] de svnserve.conf tiene todas las variables que usted necesita. Comencemos definiendo un fichero que contenga nombres de usuario y palabras clave, y una realm de autenticación:

[general]
password-db = userfile
realm = example realm

El nombre realm es algo que define usted. Le dice a los clientes a qué tipo de espacio de nombres de autenticación se están conectando; el cliente de Subversion lo muestra durante las preguntas de autenticación, y lo usa como palabra clave (junto con el nombre y puerto del servidor) para cachear las credenciales en disco (vea “Client Credentials Caching”.) La variable password-db apunta a un fichero separado que contiene una lista de nombres de usuario y claves, usando el mismo formato familiar. Por ejemplo:

[users]
harry = foopassword
sally = barpassword

El valor de password-db puede ser una ruta absoluta o relativa al fichero de usuarios. Para muchos administradores, es sencillo guardar el fichero justo en el área conf/ del repositorio, junto a svnserve.conf. Por otra parte, es posible querer compartir el mismo fichero de usuarios entre dos o más repositorios; en este caso, el fichero probablemente debería ubicarse en un lugar más público. Los repositorios que compartan el fichero de usuarios también deberían estar configurados para usar la misma realm, dado que la lista de usuarios define esencialmente un realm de autenticación. Esté donde esté el fichero, asegúrese de ajustar apropiadamente los permisos de lectura y escritura. Si sabe bajo qué usuario(s) se ejecutará svnserve, restrinja el acceso de lectura al fichero correspondientemente.

Activar control de acceso

Hay dos variables más en el fichero svnserve.conf: determinan qué pueden hacer los usuarios autenticados y sin autenticar (anónimos). Las variables anon-access y auth-access pueden tener los valores none, read, o write. Poner el valor a none restringe el acceso de todo tipo; read permite únicamente el acceso de sólo lectura al repositorio, y write permite acceso completo de lectura y escritura. Por ejemplo:

[general]
password-db = userfile
realm = example realm

# anonymous users can only read the repository
anon-access = read

# authenticated users can both read and write
auth-access = write

Los parámetros del ejemplo, son de hecho los valores por defecto de las variables, en caso de que olvide definirlas. Si desea ser aun más conservativo, puede bloquear el acceso anónimo completamente:

[general]
password-db = userfile
realm = example realm

# anonymous users aren't allowed
anon-access = none

# authenticated users can both read and write
auth-access = write

Fíjese que svnserve sólo entiende de control de acceso básico. Un usuario tiene acceso universal de lectura escritura, acceso universal de lectura, o ningún tipo de acceso. No hay control detallado del acceso a rutas específicas dentro del repositorio. Para muchos proyectos y equipos, este nivel de control de acceso es más que suficiente. No obstante, si necesita control de acceso por directorio, tendrá que usar Apache en lugar de svnserve como su proceso servidor.

Autenticación y autorización SSH

La autenticación de serie de svnserve puede ser muy útil, porque evita tener que crear cuentas de sistema reales. Por otro lado, algunos administradores ya tienen entornos de autenticación SSH bien establecidos y funcionando. En estas situaciones, todos los usuarios del proyecto tienen cuentas en el sistema y la habilidad para conectarse con SSH a la máquina servidora.

Es fácil usar SSH junto con svnserve. El cliente simplemente usa el esquema de URL svn+ssh:// para conectar:

$ whoami
harry

$ svn list svn+ssh://host.example.com/repos/project
harry@host.example.com's password:  *****

foo
bar
baz
…

Lo que sucede en esta situación es que el cliente de Subversion invoca el proceso local ssh, conectándolo con host.example.com, autenticándose como el usuario juan, y entonces lanzando un proceso svnserve privado en la máquina remota, que se ejecuta como el usuario juan. El comando svnserve se invoca en modo túnel (-t) y todo el protocolo de red es canalizado a través tunneled de la conexión cifrada por ssh, el agente del túnel. svnserve se da cuenta de que se está ejecutando como el usuario juan, y si el cliente realiza cambios en el repositorio, el nombre de usuario autenticado será usado para atribuir la autoría de la nueva revisión.

Cuando se usa un túnel, la autorización es principalmente controlada por los permisos del sistema operativo a los ficheros de la base de datos del repositorio; es casi igual que si Juan estuviese accediendo al repositorio directamente vía URL file:///. Si necesita que múltiples usuarios del sistema accedan al repositorio directamente, podría ponerlos en un mismo grupo, y ajustar cuidadosamente sus umasks. (Asegúrese de haber leído “Ofrecer múltiples métodos de acceso al repositorio”.) Pero incluso en el caso de usar túneles, el fichero svnserve.conf todavía puede ser usado para bloquear el acceso, simplemente usando auth-access = read o auth-access = none.

Podría pensar que la historia del túnel por SSH acabaría aquí, pero no lo hace. Subversion le permite personalizar el comportamiento de los túneles en su fichero de configuración config (vea “Área de configuración de parámetros de ejecución”.) Por ejemplo, supongamos que desea usar RSH en lugar de SSH. En la sección [tunnels] de su fichero config, defina lo siguiente:

[tunnels]
rsh = rsh

Y ahora, usted puede usar esta nueva definición de túnel usando un esquema URL que concuerde con el nombre de su nueva variable: svn+rsh://host/path. Cuando use el nuevo esquema URL, el cliente Subversion estará ejecutando realmente el comando rsh host svnserve -t tras las cortinas. Si incluye un nombre de usuario en la URL (por ejemplo, svn+rsh://nombreusuario@host/path) el cliente también lo incluirá en su comando (rsh nombreusuario@host svnserve -t.) Pero puede definir nuevos esquemas de túneles mucho más elaborados que eso:

[tunnels]
joessh = $JOESSH /opt/alternate/ssh -p 29934

Este ejemplo muestra varias cosas. Primero, enseña cómo hacer que el cliente de Subversion lance un binario de túnel muy específico (uno ubicado en /opt/alternate/ssh) con opciones específicas. En este caso, acceder a la URL svn+joessh:// invocaría este particular binario de SSH con -p 29934 como parámetro—útil si desea que el programa de túnel se conecte a un puerto no estándar.

Segundo, enseña cómo definir una nueva variable de entorno personalizada que puede reemplazar el nombre de un programa de túnel. Modificar la variable de entorno SVN_SSH es un modo conveniente de reemplazar el agente de túneles SSH por defecto. Pero si necesita tener diferentes reemplazos para servidores diferentes, cada uno de ellos conectando quizás a un puerto diferente o usando un conjunto diferente de opciones, puede usar el mecanismo demostrado en este ejemplo. Ahora, si fuese a crear la variable de entorno JOESSH, su valor reemplazaría el valor completo de la variable del túnel—se ejecutaría $JOESSH en lugar de /opt/alternate/ssh -p 29934.



[29] Vea el RFC 2195.