Hace unos días comenté cómo fui/estoy intentando mejorar procesos a través de cambios metodológicos y técnicos.
Una de las primeras herramientas que adopté de como parte de este proceso fue Jenkins, con la seria intención de tener a un real asistente en los distintos procesos que esperaba/espero mejorar.
Hace unos años, cuando hice mi primera instalación, la hice de forma manual. Es decir, descargando el .war y llevándolo a un servidor. Esto funcionó, pero resultaba tedioso mantenerlo actualizado (no tanto por el proceso que es realmente sencillo sino por tenía que estar muy encima para mi gusto).
Con la excusa de este post, levanté una instancia nueva en un Debian 10, de esta manera.
Ya dentro del servidor, vamos a configurar correctamente el timezone.
dpkg-reconfigure tzdata
Actualizamos paquetes de la distro.
apt-get update && apt-get dist-upgrade -y
Soy algo así como vieja escuela y la mayoría de mis scripts son con aptitude, así que como paso totalmente opcional:
apt-get install aptitude
Primero, seguridad:
aptitude install ufw
Y bloqueamos el tráfico entrante.
ufw default deny incoming
Y habilitamos el tráfico saliente de forma explícita.
ufw default allow outgoing
Vamos a permitir conexión SSH.
ufw allow 22/tcp
Y ahora activamos el firewall.
ufw enable
Si quieren ver las reglas actuales, pueden hacerlo con:
ufw status numbered
Verán este output:
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 22/tcp (v6) ALLOW IN Anywhere (v6)
Ahora ya podemos seguir.
Instalamos alguna herramienta para monitoreo local mínimo (parte del abc).
aptitude install htop nmon logwatch unattended-upgrades
Agrego un usuario sin privilegios.
adduser MI_NUEVO_USUARIO_SIN_PRIVILEGIOS
Ahora vamos a modificar la configuración del SSH.
vi /etc/ssh/sshd_config
No vamos a permitir que root se pueda loguear, así que cambiamos PermitRootLogin yes a no. Guardamos pero aún no reiniciamos. Editemos el nombre del servidor.
vi /etc/hostname
Ahora si, reiniciamos.
reboot
Una vez que el servidor haya vuelto a la vida (me conecté al servidor con mi usuario sin privilegios y cambié a root para continuar la instalación) vamos a proceder con la instalación de Jenkins. Como se necesita Java, vamos a seguir por ahí.
Nos fijamos primero qué versión (de Java) tenemos disponible:
aptitude search openjdk
En mi caso es la 11 así que voy a instalar eso y gnupg que lo voy a necesitar también luego.
aptitude install openjdk-11-jdk gnupg
Podemos confirmar ahora que la instalación de Java fue correcta.
java -version
Obtengo:
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Debian-1deb10u1, mixed mode, sharing)
Listo, finalmente vamos a Jenkins.
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | apt-key add -
sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > \
/etc/apt/sources.list.d/jenkins.list'
aptitude update
aptitude install jenkins
Una vez que haya concluido, Jenkins debería estar disponible en el puerto 8080 de nuestro servidor.
Deshabilitamos el firewall o habilitemos el puerto de forma temporal. Ahora ingresamos a esa IP y seguimos las instrucciones.
Si abrimos /var/lib/jenkins/secrets/initialAdminPassword veremos un string/contraseña a ingresar.
Seguimos los pasos (fui por la opción standard en este caso), no hay nada raro, hasta que finalmente tenemos nuestro Jenkins instalado.
Aún no está listo para funcionar (como yo quiero, aunque si está accesible en el puerto 8080) y hay algunos detalles mínimos que voy a preferir resolver en cuanto al servidor y seguridad.
Algunos de esos detalles son:
- Configurar Logwatch.
- Configurar unattended-upgrades.
- Instalar Fail2Ban (para que Josevi nos apruebe con un 10)
- No permitir login al servidor si no es con llaves (no permitir el login remoto con contraseña).
Una vez que hayamos ajustado esos parámetros vamos a lo más específico, poner a funcionar Jenkins pero sobre HTTPS.
Si bien es posible, la forma más fácil, para mi, es poner Jenkins detrás de un Webserver. Yo voy a usar Apache como Proxy Reverso.
aptitude install apache2
Y habilito el módulo proxy.
a2enmod proxy_http
Para estar seguros, si accedemos a la misma IP en la que probamos Jenkins al comienzo, pero en el puerto 80, deberíamos ver:
Ahora editemos el host por algo como esto.
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName jenkins.example.com
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPreservehost on
ProxyPass / http://localhost:8080/
</VirtualHost>
Restart del servicio y vamos al dominio que definimos, en puerto 80.
Ahora tenemos en puerto 80 nuestro Jenkins, aunque también escucha en el 8080 y es público (aunque ya lo vamos a solucionar).
Instalemos ahora Certbot.
aptitude install certbot python-certbot-apache
Y ahora voy a crear e instalar el certificado.
certbot --apache
Una vez que haya terminado, tendríamos que poder acceder a nuestra instancia de Jenkins bajo SSL.
Ajustemos la URL que usará Jenkins:
Ahora levantamos el firewall nuevamente. Aquí podría elegir si abrir el puerto 80 (que hará redirect) o sólo el 443. Para habilitar estos puertos:
ufw allow 80/tcp
ufw allow 443/tcp
Finalmente, la versión mínima de nuestra instancia de Jenkins (que actualmente no hace nada pero pronto vamos a darle propósito), está funcionando.
Sigue en marcha el plan para mejorar mis procesos. Todavía estoy en el mismo punto:
Probablemente en el siguiente paso, con la incorporación de alguna herramienta adicional, pueda empezar a obtener alguna mejora.