Configuración de Subversion con Apache en openSUSE

Ya hace tiempo atrás, en el trabajo surgió la necesidad de llevar un mejor control de las versiones del código fuente de los diversos sistemas que se tenían, en aquel entonces no existe ningún control, ya saben, archivos por doquier, 3 copias en una misma máquina, 1 copia de los fuentes en el servidor, otra en la máquina del vecino y así una variedad de backups que al final no sirven para nada porque se desconoce si están completos, actualizados, en fin, así surgió la iniciativa de investigar acerca de este tema.

Como algunos ya sabrán, Subversion es una herramienta que nos permite llevar un control de versiones de cualquier tipo de archivo, en especial de código fuente, ya que permite mantener todo el historial de modificaciones que realicemos a los mismos, además nos permite documentar los cambios agregando comentarios y explicaciones acerca de los motivos de dichos cambios, para aquellos que aún no conocen o no entienden de que se trata este software les recomiendo visitar éste enlace.


Objetivos de la guía

La idea es crear dos repositorios de ejemplo, uno de ellos que exigirá autenticación por parte del usuario tanto para leer el repositorio como para escribir en él, el otro repositorios también exigirá autenticación para la escritura pero permitirá la lectura del repositorio para cualquier usuario sin la necesidad de autenticarse. Esta última configuración es muy interesante si se quiere hacer público un repositorio con un proyecto de desarrollo para que todos los interesados tengan acceso a los fuentes de forma libre, pudiendo luego enviar sus modificaciones o correcciones en forma de parches, para que los encargados del proyecto puedan analizar si las modificaciones enviadas son correctas y necesarias para incorporarlas a una nueva versión del proyecto.

Para poner en marcha este software también es necesario configurar el servicio Apache, mediante este servicio se podrá acceder a los repositorios vía web y dar soporte SSL para que los usuarios puedan conectarse de forma segura a los mismos.


Paquetes necesarios

Los paquetes que deberán ser instalación son los que se citan a continuación:
testsrv:~ # zypper install apache2 apache2-doc apache2-prefork libapr1 libapr-util1 libneon27 subversion subversion-doc subversion-server
Todos los paquetes mencionados se encuentran disponibles en los repositorios oficiales de openSUSE (y también en el CD o DVD de instalación, aunque posiblemente algo desactualizados).


Configuraciones básicas

Creación de usuario y grupo SVN

Luego de instalar los paquetes, la primera tarea que tendremos que hacer es agregar al sistema operativo un usuario de sistema llamado svn y cuyo grupo tiene que ser svn, motivo por el cual antes también tendremos que agregar un nuevo grupo de sistema llamado svn. El usuario svn es necesario para ejecutar el software por primera vez y lamentablemente no se crea automáticamente durante la instalación del paquete, lo podemos agregar mediante los siguientes comandos:
testsrv:~ # groupadd -r svn
testsrv:~ # useradd -r -g svn svn

Configuración de Apache

  1. La forma más recomendable de utilizar subversion es publicando los repositorios a través del servicio http mediante Apache sobre el protocolo de red WebDAV/DeltaV, siendo esto posible gracias a los módulos que permiten su integración, así que lo primero que debemos hacer es dirigirnos al directorio /etc/sysconfig y editar el archivo apache2:
    testsrv:~ # vi /etc/sysconfig/apache2
    Una vez en el archivo nos tenemos que dirigir a la sección APACHE_MODULES para agregar al final los módulos dav y dav_svn:
    APACHE_MODULES="actions alias auth_basic authn_file authz_host authz_groupfile authz_default authz_user autoindex cgi dir env expires include log_config mime negotiation setenvif ssl userdir php5 reqtimeout dav dav_svn"
  2. El siguiente paso consiste en crear las carpetas en donde irán los repositorios de subversion mediante los siguientes comandos:
    testsrv:~ # mkdir -p /srv/svn/repos
    testsrv:~ # mkdir /srv/svn/user_access
    testsrv:~ # mkdir /srv/svn/html

  3. Creadas las carpetas pasamos a editar el archivo /etc/apache2/conf.d/subversion.conf previa copia de seguridad, para definir los repositorios a los cuales se tendrá acceso mediante Apache y configurar sus respectivos métodos de autenticación.
    testsrv:~ # cp /etc/apache2/conf.d/subversion.conf /etc/apache2/conf.d/subversion.conf.bkp
    testsrv:~ # vi /etc/apache2/conf.d/subversion.conf

    La configuración que debe ir en el archivo subversion.conf se detalla a continuación:
    ## Ejemplo de configuración para un repositorio de Subversion.
    ## Documentación completa disponible en /usr/share/doc/packages/subversion.

    <IfModule mod_dav_svn.c>
    ##
    ## project related HTML files
    ##

    <IfModule mod_alias.c>
    Alias /repos /srv/svn/html
    </IfModule>
    <Directory /srv/svn/html>
    Options +Indexes +Multiviews -FollowSymLinks
    IndexOptions FancyIndexing \
    ScanHTMLTitles \
    NameWidth=* \
    DescriptionWidth=* \
    SuppressLastModified \
    SuppressSize
    order allow,deny
    allow from all
    </Directory>

    ## Configuración para el repositorio “proyecto1” que requiere
    ## autenticación tanto para la lectura como para escritura
    ## en el repositorio.

    <Location /repos/proyecto1>
    DAV svn
    ## Directorio en donde se encontrará el proyecto
    SVNPath /srv/svn/repos/proyecto1

    ## Configuración del tipo de autenticación de usuario
    ## y definición de la ruta de los archivos que contienen
    ## la lista de usuarios autorizados y sus respectivas claves.

    AuthType Basic
    AuthName "Authorization for proyecto1 required"
    AuthUserFile /srv/svn/user_access/proyecto1_passwdfile
    AuthGroupFile /srv/svn/user_access/proyecto1_groupfile

    ## Definición de los grupos a los cuales los usuarios del programa
    ## van asociados según sus operaciones que pueden realizar
    ## en el repositorio.
    ## Esto queda más claro a medida que se finaliza con la configuración.

    <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require group proyecto1_committers
    </LimitExcept>
    <Limit GET PROPFIND OPTIONS REPORT>
    Require group proyecto1_committers
    Require group proyecto1_readers
    </Limit>
    </Location>

    ## Configuración para el Repositorio “proyecto2”, su característica
    ## es que la lectura del repositorio para usuarios anónimos está
    ## permitida, pero para realizar cambios en el mismo el usuario
    ## debe autenticarse.

    <Location /repos/proyecto2>
    DAV svn
    ## Directorio en donde se encontrará el proyecto
    SVNPath /srv/svn/repos/proyecto2

    ## Configuración del tipo de autenticación de usuario
    ## y definición de la ruta del archivo que contiene
    ## la lista de usuarios autorizados y sus respectivas claves.

    <LimitExcept GET PROPFIND OPTIONS REPORT>
    AuthType Basic
    AuthName "Authorization for proyecto2 required"
    AuthUserFile /srv/svn/user_access/proyecto2_passwdfile
    Require valid-user
    </LimitExcept>
    </Location>

    </IfModule>
  4. El siguiente paso consiste en dirigirnos al directorio /srv/svn/repos para comenzar a crear los repositorios con el comando svnadmin.
    testsrv:~ # cd /srv/svn/repos/
    testsrv:/srv/svn/repos # svnadmin create proyecto1
    testsrv:/srv/svn/repos # svnadmin create proyecto2

  5. Nos aseguramos que dentro de cada proyecto exista la carpeta dav:
    testsrv:/srv/svn/repos # mkdir proyecto1/dav
    testsrv:/srv/svn/repos # mkdir proyecto2/dav

  6. Finalmente se le asigna un dueño:grupo a las carpetas dav, db y locks de cada proyecto:
    testsrv:/srv/svn/repos # chown -R wwwrun:www proyecto1/{dav,db,locks}
    testsrv:/srv/svn/repos # chown -R wwwrun:www proyecto2/{dav,db,locks}

  7. Una vez culminado con la creación de los repositorios reiniciamos el servidor http con el siguiente comando:
    testsrv:~ # service apache2 restart
  8. No hay que olvidarse de autorizar los puertos correspondientes del servicio apache2 (http y de paso https) en el Firewall de openSUSE, en el caso de que el mismo se encuentre activo. Para ello editamos el archivo SuSEfirewall2 del directorio /etc/sysconfig,
    testsrv:~ # vi /etc/sysconfig/SuSEfirewall2
    y le asignamos el servicio apache2 y apache2-ssl a la directiva FW_CONFIGURATIONS_EXT si tenemos nuestra interfaz de red asignada a la zona externa, quedaría como se muestra a continuación:
    FW_CONFIGURATIONS_EXT="sshd apache2 apache2-ssl"
    Guardamos los cambios del archivo y reiniciamos el firewall con lo que el servicio ya quedará disponible:
    testsrv:~ # rcSuSEfirewall2 restart
    Starting Firewall Initialization (phase 2 of 2) SuSEfirewall2: Warning: no default firewall zone defined, assuming 'ext'
    done
    testsrv:~ #


Creación de archivos de autorización

En esta sección procederemos a crear los archivos que contendrán los nombres de usuarios y sus respectivas contraseñas para acceder a cada uno de los repositorios que creamos en el punto anterior.

Accesos para el repositorio Proyecto1

  1. El repositorio proyecto1, como se había especificado en el archivo subversion.conf, exigirá autenticación tanto para la lectura del repositorio como también para la escritura en el mismo, así que primeramente creamos un archivo que contendrá a los usuarios que tendrán acceso al repositorio proyecto1 y sus respectivos passwords, a este archivo se le asignará un dueño:grupo y permisos seguros para evitar que cualquiera tenga acceso:
    testsrv:~ # touch /srv/svn/user_access/proyecto1_passwdfile
    testsrv:~ # chown root:www /srv/svn/user_access/proyecto1_passwdfile
    testsrv:~ # chmod 640 /srv/svn/user_access/proyecto1_passwdfile
  2. Una vez culminado con el paso anterior, pasamos a agregar al archivo los usuario y sus respectivas contraseñas mediante el comando htpasswd2:
    testsrv:~ # htpasswd2 /srv/svn/user_access/proyecto1_passwdfile gabriel
    testsrv:~ # htpasswd2 /srv/svn/user_access/proyecto1_passwdfile luis
  3. Pero esto aún no termina para el repositorio proyecto1, creamos un archivo que ya contiene los usuarios y ahora aún nos falta crear un nuevo archivo donde vamos a agrupar a los usuarios según las operaciones que pueden realizar:
    testsrv:~ # touch /srv/svn/user_access/proyecto1_groupfile
    testsrv:~ # chown root:www /srv/svn/user_access/proyecto1_groupfile
    testsrv:~ # chmod 640 /srv/svn/user_access/proyecto1_groupfile

    editamos el archivo proyecto1_groupfile,
    testsrv:~ # vi /srv/svn/user_access/proyecto1_groupfile
    y le agregamos las dos líneas que siguen a continuación:
    proyecto1_committers: gabriel
    proyecto1_readers: gabriel luis
    lo que significa que el usuario gabriel tendrá autorización para leer el repositorio como también para escribir en él, sin embargo, el usuario luis solo podrá leer el repositorio.

Accesos para el repositorio Proyecto2

  1. El repositorio proyecto2 permitirá a cualquier usuario anónimos la lectura del contenido del repositorio, pero la escritura en el repositorios solo estará permitida a los usuarios específicamente definidos en su correspondiente archivo de acceso. Así que para este repositorio también creamos un archivo que tendrá los usuarios autorizados, al mismo se le asigna un dueño:grupo y los permisos correspondientes,
    testsrv:~ # touch /srv/svn/user_access/proyecto2_passwdfile
    testsrv:~ # chown root:www /srv/svn/user_access/proyecto2_passwdfile
    testsrv:~ # chmod 640 /srv/svn/user_access/proyecto2_passwdfile

  2. Por último se le agrega los usuarios a los cuales les queremos dar permiso de escritura para el repositorio.
    testsrv:~ # htpasswd2 /srv/svn/user_access/proyecto2_passwdfile gabriel
Llegando a este punto ya podemos acceder e importar nuestros archivos a los dos repositorios con cualquier cliente para subversion, entre los cuales he probado los clientes gráficos TortoiseSVN para Windows (muy bueno) y eSvn o kdesvn para distribuciones basadas en Linux, estos dos últimos se encuentran disponibles en los repositorios de paquetes de openSUSE.

Las siguientes URL's nos permiten realizar el checkout de los dos repositorios de ejemplo configurados anteriormente:
http://ip_o_dominio_servidor/repos/proyecto1
http://ip_o_dominio_servidor/repos/proyecto2

OBS: Cuando se trata de acceder a un repositorio de subversion mediante un servidor proxy es posible que se presenten inconvenientes, esto es a causa de que los servidores proxy no suelen interpretar o soportar todos los métodos que ofrece WebDAV, sobre este caso, en la página oficial de subversion tratan este tema en el siguiente enlace: http://subversion.apache.org/faq.html#proxy

Conexiones http seguras mediante SSL

Subversion puede aprovechar los beneficios que ofrece Apache y uno de ellos es el acceso seguro mediante el protocolo https que implementa SSL para establecer las conexiones.
  1. Lo primero que tendremos que hacer es editar el archivo /etc/sysconfig/apache2,
    testsrv:~ # vi /etc/sysconfig/apache2
    Una vez adentro tendremos que verificar que el módulo ssl esté definido en la directiva APACHE_MODULES:
    APACHE_MODULES="actions alias auth_basic authn_file authz_host authz_groupfile authz_default authz_user autoindex cgi dir env expires include log_config mime negotiation setenvif ssl userdir php5 reqtimeout dav dav_svn"
    En el mismo archivo también tenemos que verificar que la directiva APACHE_SERVER_FLAGS sea igual a SSL como se muestra a continuación:
    APACHE_SERVER_FLAGS="SSL"
  2. También tenemos que verificar que Apache esté atendiendo las conexiones seguras en el puerto indicado (443), para ello editamos el archivo /etc/apache2/listen.conf,
    testsrv:~ # vi /etc/apache2/listen.conf
    y nos dirigimos a la siguiente sección cuyo contenido debería ser similar al que sigue:
    <IfDefine SSL>
    <IfDefine !NOSSL>
    <IfModule mod_ssl.c>

    Listen 443

    </IfModule>
    </IfDefine>
    </IfDefine>

Generación del certificado SSL

  1. Varias formas existen para generar un certificado, el método más simple es generar uno automáticamente sin especificarle información alguna, para ello hay que ejecutar el siguiente comando:
    testsrv:~ # gensslcert
    Este comando sobre escribirá los siguientes archivos:
    /etc/apache2/ssl.crt/ca.crt
    /etc/apache2/ssl.key/server.key
    /etc/apache2/ssl.crt/server.crt
    /etc/apache2/ssl.csr/server.csr
    También creará un nuevo archivo CA.crt en el directorio /srv/www/htdocs/ para ser descargado por los clientes que se conectan bajo el protocolo https.

  2. Luego hay que crear una copiar del archivo /etc/apache2/vhosts.d/vhost-ssl.template y renombrarlo a vhost-ssl.conf.
    testsrv:~ # cd /etc/apache2/vhosts.d
    testsrv:/etc/apache2/vhosts.d # cp vhost-ssl.template vhost-ssl.conf
  3. Con esto hemos creado un host virtual exclusivo para las conexiones seguras, reiniciamos el servidor apache con el comando service apache2 restart y verificamos la configuración de nuestro virtual host con el comando httpd2 -S -DSSL:
    testsrv:~ # service apache2 restart
    testsrv:~ # httpd2 -S -DSSL

  4. Eso ha sido todo para un certificado básico, la generación de un certificado con información relevante se trata en el siguiente punto.

Generación de certificado SSL con información adicional

  1. Si queremos agregar un certificado personalizado que muestre información adicional de nuestra organización o empresa, ejecutamos nuevamente la aplicación gensslcert pero seguido de una serie de argumentos como se muestra a continuación:
    testsrv:~ # gensslcert -C "tormentadebits" -N "Este es un Certificado de Ejemplo" -c PY -s It -l "BV" -o "Gabriel-Corp." -u "Unidad Informatica" -n "www.tormentadebits.com" -e "contacto@tormentadebits.com" -y 60
  2. Al ejecutar el comando se crearán una serie de archivos inicialmente llamados en este ejemplo con el nombre tormentadebits-, los mismos se encuentran en los siguientes directorios:
    /etc/apache2/ssl.crt/tormentadebits-ca.crt
    /etc/apache2/ssl.crt/tormentadebits-server.crt
    /etc/apache2/ssl.csr/tormentadebits-server.csr
    /etc/apache2/ssl.key/tormentadebits-ca.key
    /etc/apache2/ssl.key/tormentadebits-server.key
    /srv/www/htdocs/TORMENTADEBITS-CA.crt

  3. Si queremos que éste sea el certificado utilizado para la autenticación tendremos que editar el archivo vhost-ssl.conf en el directorio /etc/apache2/vhosts.d/
    testsrv:~ # vi /etc/apache2/vhosts.d/vhost-ssl.conf
    y modificar las directivas que se citan a continuación con los nuevos nombres de los certificados mencionados anteriormente:
    SSLCertificateFile /etc/apache2/ssl.crt/tormentadebits-server.crt
    SSLCertificateKeyFile /etc/apache2/ssl.key/tormentadebits-server.key

  4. Por último debemos reiniciar el servicio Apache para que los cambios tengan efecto, y el nuevo certificado pueda entrar en funcionamiento.
    testsrv:~ # service apache2 restart
    Con estos cambios, en el detalle del nuevo certificado aparecerá entre otros la siguiente información del emisor:
    Asunto https://ip_o_dominio_servidor:443
    Host www.tormentadebits.com
    Válido de Thu, 08 Mar 2012 02:53:33 GMT
    Válido hasta Mon, 07 May 2012 02:53:33 GMT
    Nombre del emisor CA, Gabriel-Corp., BV, It, PY
No hay que olvidarse de reemplazar el protocolo http por https para realizar el checkout seguro vía SSL de los dos repositorio de ejemplo configurados anteriormente, las URL's quedarían como sigue:
https://ip_o_dominio_servidor/repos/proyecto1
https://ip_o_dominio_servidor/repos/proyecto2

Y esto ha sido todo, con estas configuraciones ya tenemos un servidor de Subversion seguro y funcional.

Comentarios

  1. Enhorabuena por el tutorial

    ResponderEliminar
    Respuestas
    1. Hola, gracias por tu comentario. En el blog hay otros artículos sobre subversion que los podrás ver en éste enlace.

      De los mismos te quisiera recomendar los artículos Herramientas web USVN y WebSVN para Subversion en openSUSE y Instalación y configuración de Redmine en openSUSE, que abarcan no solo el sistema de control de versiones, si no que también incluyen herramientas administrativas y de análisis que facilitan la gestión de repositorios, de usuarios, de proyectos, etc.

      Saludos.

      Eliminar
  2. muchas gracias!!!!!! me fue de gran ayuda

    ResponderEliminar

Publicar un comentario