GitLab con SSL y Frontal web
Además de Subversion, otro de los repositorios de código más utilizados actualmente es Git.
Git, igual que Subversion y otros tantos, permite controlar las versiones del código fuente creando ramas y cambiar entre las diferentes versiones, existen muchos debates en internet sobre si Git es mejor que Subversion, pero yo no entraré dentro de ello ya que una búsqueda rápida da suficiente información como para decantarse por uno y otro, así que me centraré en su instalación, pero concretamente no de Git como tal, sino del proyecto GitLab, este es un conjunto de aplicaciones que proporcionan los servicios de Git junto con gestión de usuarios, permisos, incidencias y otros tantos.
0- Previos
GitLab tiene dos tipos de instalación, la Omnibus que es un paquete que ya contiene todas las dependencias y el script de instalación, pero solo funciona en unos sistemas operativos concretos o la instalación manual. Nunca suelo utilizar los paquetes autoinstalables pero debido a la complejidad de GitLab, como excepción me he decantado por Omnibus, además la documentación para la instalación manual es inexistente, así que no deja muchas opciones.
La aplicación contiene muchas opciones diferentes de configuración y uso, yo solo me centraré en una parte, así que es recomendable mirar bien cada punto del fichero de configuración y/o manuales por si fuera necesario algo más según nuestras necesidades.
He separado la instalación en varios bloques, en los 2 primeros se instalará GitLab junto con el envío de e-mails y el LDAP, esto es suficiente para hacerlo funcionar siendo el resto opciones añadidas, algunas bastante recomendadas.
Seguiré inicialmente los pasos a instalar de la página oficial pero cambiando algunas partes a mi estilo, originalmente las instrucciones están pensadas para un Ubuntu donde no existe el acceso a root de forma estándar pero yo utilizaré OpenSuSE así que utilizaré siempre el usuario root.
1- Instalar GitLab
Seguramente ya tendremos todos los requisitos para instalar (curl y postfix), GitLab tiene configuración propia de envío de e-mails así que no hará falta configurar postfix en relay para él, pero quizás nos interese para otros temas, en cualquier caso, esta es la guía para ello.
El repositorio actual es para OpenSuSE 42.1, así que detectará que tenemos una más nueva y el script original fallará, con lo que añadimos el repositorio manualmente, instalamos, aceptamos los XML autofirmados y lo iniciamos por primera vez.
zypper ar 'https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/config_file.repo?os=opensuse&dist=42.1&source=script'
zypper in gitlab-ce
gitlab-ctl reconfigure
Si hemos abierto el puerto 80, ahora ya podremos acceder utilizando el nombre de máquina como URL, esto nos servirá para confirmar que todo ha ido bien y de paso definir una contraseña para el usuario root.
Toda la configuración se hace desde el mismo fichero, así que empezamos a editarlo.
vi /etc/gitlab/gitlab.rb
URL externa
Lo primero es indicar la URL que tendrá, GitLab asigna los ficheros con ruta absoluta partiendo del nombre de dominio y puerto, así que, si cambia o si accedemos con otro nombre, puede que algunas partes no funcionen. La más fácil de comprobar son las imágenes rotas de los usuarios.
Por ahora empezamos con un acceso HTTP.
external_url 'https://git.domain.cat'
Revisión automática de repositorios con errores
No suele ser necesario, pero no está de más activar la comprobación de repositorios por si alguno de estos se hubiera corrompido.
gitlab_rails['repository_check_worker_cron'] = "20 * * * *"
LDAP
Esta siempre es una parte compleja de la configuración, por defecto está pensado para Active Directory, esta sería la configuración para un Oracle DSEE.
Cabe recordar que los usuarios no serán registrados hasta que inicien sesión por primera vez.
gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
main: # 'main' is the GitLab 'provider ID' of this LDAP server
label: 'LDAP'
host: '_your_ldap_server'
port: 389
uid: 'uid'
method: 'plain' # "tls" or "ssl" or "plain"
bind_dn: 'cn=Directory Manager'
password: '_the_password_of_the_bind_user'
active_directory: false
allow_username_or_email_login: false
block_auto_created_users: false
base: 'dc=domain,dc=cat'
user_filter: ''
attributes:
username: ['uid', 'userid', 'sAMAccountName']
email: ['mail', 'email', 'userPrincipalName']
name: 'cn'
first_name: 'givenName'
last_name: 'sn'
EOS
Carpeta de repositorios
Siempre cambio el directorio de repositorios hacia una carpeta diferente a la propia de GitLab, lo cual permite tener mayor facilidad a la hora de gestionar cualquier copia de seguridad o proceso que necesitemos en un futuro.
git_data_dirs({"default" => "/opt/git-data"})
Para configurar el e-mail necesitaremos los datos del servidor que tengamos, en la web oficial tienen un listado para diferentes tipos de servidores.
Configuramos tanto el servidor como el e-mail y nombre que utilizará para enviarlos.
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.server"
gitlab_rails['smtp_port'] = 25
gitlab_rails['smtp_user_name'] = "smtp user"
gitlab_rails['smtp_password'] = "smtp password"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['gitlab_email_enabled'] = true
gitlab_rails['gitlab_email_from'] = '[email protected]'
gitlab_rails['gitlab_email_display_name'] = 'Example'
gitlab_rails['gitlab_email_reply_to'] = '[email protected]'
Reiniciar y pruebas
Cualquier cambio que realicemos necesitará de reiniciar para que se aplique.
gitlab-ctl reconfigure
Para confirmar que el LDAP se ha configurado correctamente, después de reiniciar lanzamos el comprobante, este deberá mostrar los usuarios del LDAP, si no es así, es que algo ha fallado.
gitlab-rake gitlab:ldap:check
Para el e-mail también existe un proceso de pruebas, para ello accedemos a la consola y, cuando esta se active, indicamos el e-mail a enviar.
gitlab-rails console
Notify.test_email('[email protected]', 'Message Subject', 'Message Body').deliver_now
Si todo ha funcionado, seguimos configurando, pero esta vez desde la administración web.
2- Administración web
Accedemos por web y entramos con el usuario root.
En la parte superior tenemos un icono de llave inglesa, después la rueda de administración y de aquí a Settings.
Esta pantalla nos permite configurar desde la visibilidad por defecto de todo, sistemas de acceso de usuarios, si podrán registrarse, etc.
Yo me centraré a explicar cómo anular todo tipo de acceso o registro que no provenga del LDAP, como también apagaré el acceso de usuarios locales, el usuario root no podrá iniciar sesión, así que es necesario acceder primero con un usuario del LDAP para registrarlo y convertirlo en administrador, en la pantalla inicial veremos el usuario y accediendo a su perfil podemos cambiarlo a administrador.
Al ser un servidor privado, lo primero será apagar Gravatar y los accesos de OAuth, también desconectamos el registro de usuarios deshabilitando Sign-up.
Para impedir el acceso de usuarios locales (como root), apagamos el Sign-in, esto dejará como una entrada el LDAP que hemos configurado.
Una vez guardado ya estará listo para ser utilizado. Si utilizaremos SSL es obligatorio activarlo antes de empezar a usar GitLab.
3- Activar SSL
Lo primero a tener en cuenta antes de activar el SSL, es qué frontal web utilizaremos entre dos opciones que afectaran al external_url del fichero de configuración que hemos cambiado al inicio:
- Nginx: este es el frontal web que viene con GitLab, en el caso de utilizarlo simplemente cambiaremos el valor de external_url añadiendo https.
- Apache: en el caso de tener un Apache (que debe tener SSL activo, explicado aquí), debemos cambiar el external_url hacia https://nombre\_máquina y nuestro servidor de Apache debe ser capaz de resolver ese nombre (ya sea por DNS o modificando el fichero de hosts).
Una vez decidido, volvemos a editar el fichero de configuración, cambiamos la URL y activamos la redirección hacia HTTPS.
external_url 'https://domain_o_nombre_máquina'
nginx['redirect_http_to_https'] = true
Lo siguiente será crear el certificado de SSL.
En los siguientes comandos cambiar git.domain.cat por el valor de external_url (sin https://). Al crear el certificado, es obligatorio que el Common Name sea exactamente el dominio que estamos utilizando.
mkdir -p /etc/gitlab/ssl
cd /etc/gitlab/ssl
openssl req -nodes -newkey rsa:2048 -keyout git.domain.cat.key -out git.domain.cat.csr
cp git.domain.cat.key git.domain.cat.original
openssl rsa -in git.domain.cat.original -out git.domain.cat.key
rm git.domain.cat.original
openssl x509 -req -days 1460 -in git.domain.cat.csr -signkey git.domain.cat.key -out git.domain.cat.crt
rm git.domain.cat.csr
chmod 600 *
Reiniciamos y comprobamos que realmente podemos acceder y que el certificado tiene la URL acorde a nuestro dominio.
Un último detalle, como nuestro certificado es autofirmado, los usuarios tendrán que modificar su cliente de Git para aceptar este tipo de certificados. Este se modifica en el fichero gitconfig que se encuentra en el directorio de instalación del cliente Git, tendremos que añadir el siguiente.
[http]
sslVerify = false
4- Publicar en Apache
Este paso es únicamente en caso de que no usemos en Nginx de GitLab para publicar la web, si no que utilizaremos nuestro Apache como frontal y este llamará internamente a Nginx.
En caso de que utilicemos SSL, el external_url tendrá que ser el de Apache pero los certificados tendrán que tener el nombre de máquina ya que utilizaremos este para acceder internamente a Nginx y si el certificado no coincide con el nombre que utilizamos fallará.
Si no hemos activado el SSL nos servirá igual (siempre que desde Apache utilizamos únicamente HTTP), en este caso también haremos la consulta interna con el nombre de máquina.
Dando por hecho que se conoce como activar un SSL para virtual host (y si no, en este enlace se explica), esta será la configuración que necesitemos, es igual al proceso típico, pero aceptando que el servicio al que llamaremos tiene certificados propios.
<IfDefine SSL>
<IfDefine !NOSSL>
<VirtualHost *:443>
ServerName git.domain.cat
ProxyPass / https://GitLabMachineName/
ProxyPassReverse / https://GitLabMachineName/
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/apache2/ssl.crt/git.domain.cat-server.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/git.domain.cat-server.key
RequestHeader set Front-End-Https "On"
ErrorLog /var/log/apache2/git-error_log
TransferLog /var/log/apache2/git-access_log
CustomLog /var/log/apache2/ssl_request_log ssl_combined
</VirtualHost>
</IfDefine>
</IfDefine>
Antes de reiniciar, tendremos que añadir el módulo de headers para Apache.
a2enmod headers
También es recomendable añadir por HTTP el redirect hacia HTTPS.
Antes de probar, es importante que el nombre de la máquina con GitLab se pueda resolver, si no lo tenemos en las DNS, podemos añadirlo al /etc/hosts directamente, lo importante es que nuestro Apache sepa llegar hasta el GitLab.
5- Copias de seguridad
Es importante mantener copias de seguridad tanto de la configuración /etc/gitlab, como de los repositorios.
La configuración es muy sencilla de mantener copias de seguridad, debido a que es una carpeta, con los procesos que expliqué aquí se puede mantener.
Para los repositorios, GitLab tiene su propia herramienta, así que la activamos e indicamos la ruta donde se guardarán, esta ruta debería ser una carpeta compartida en otro servidor o NAS para aumentar la seguridad. El último indica el tiempo en segundos (7 días en este caso) en que se mantendrán las viejas copias.
gitlab_rails['manage_backup_path'] = true
gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
gitlab_rails['backup_keep_time'] = 604800
Después de reiniciar estará activo con el siguiente comando.
gitlab-rake gitlab:backup:create
Este comando se puede ejecutar desde cron añadiendo el parámetro CRON=1 al final para evitar que escriba por pantalla.
Restaurar copia de repositorio Cada copia tiene un timestamp (por ejemplo: 1490659492_2017_03_28), con los siguientes comandos e indicando el timestamp adecuado podemos restaurar los repositorios, hay que tener en cuenta que esto restaura todos los repositorios, no únicamente uno.
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
gitlab-rake gitlab:backup:restore BACKUP=<timestamp>
gitlab-ctl start
gitlab-rake gitlab:check SANITIZE=true
Final
En este tipo de servicios tan grandes no es fácil llegar hasta el final, e incluso diría que imposible llegar a la primera, pero una vez instalado solo nos tendremos que ir preocupando de revisar que las copias de seguridad siguen creándose sin problemas e ir revisando en la pantalla de administración si hay alguna actualización, estas se pueden ejecutar desde los comandos oficiales y se descargará del repositorio así que el trabajo será mínimo.
Como último detalle recordar que GitLab en Omnibus ya se encarga de crear los servicios de autoarranque, aunque confirmar que funciona nunca está de más.