El título de esta entrada se parece «curiosamente» al título de una película de miedo… Y al principio eso es lo que es, ya que desde el lunes estoy recibiendo esta pantalla en mi chrome cada vez que meto una incidencia en mi redmine:
El caso es que luego le dabas al botón de enviarlo de todas formas y la cosa funcionaba normalmente… Eso si, era sumamente molesto y tenía clientes que accedían a poner sus incidencias y no era plan tener que explicarles a todos que no es que ahora fuésemos menos seguros que antes, sino que chrome había activado una funcionalidad nueva.
Esa funcionalidad, que estaba prevista para chrome 86, pero que se activó con chrome 87 hace que cuando los datos de un formulario se envíen a una página que no tiene https activado se de la advertencia de que cualquiera podría interceptar los datos… Me parece muy buena advertencia, pero ¡Espera! todo el tráfico de mis webs ya va por https, ¿cómo es que recibo esa advertencia?
Según la especificación de chrome esto solo debía pasar si el formulario llevaba a una página no segura, así que revisé las etiquetas form y vi que eran rutas relativas (y si es relativa dentro de una página https debería llevar a una página https), así que decidí revisar el camino completo usando el inspector de chrome donde, efectivamente, vi que la petición se realizaba a una página https pero descubrí que el campo Location que aparecía en los headers de la petición venía como http y no https, ¿cómo podía ser?
Pues resulta, después de mucho buscar, que la gestión del https la estaba haciendo mediante un proxy inverso en apache y, parece ser, que la directiva ProxyPassReverse modifica el host del Location, pero no el protocolo. Por suerte esto tiene fácil solución y basta con incluir esto en el VirtualHost:
RequestHeader set X-Forwarded-Proto "https"
Antes de hacerlo no os olvidéis de añadir el módulo:
sudo a2enmod headers
Con esto ya conseguiremos que el proxy no confunda a chrome y que desaparezca el molesto mensaje…
Una vez que hemos empezado a «dockerizar» aplicaciones, y antes de saltar al siguiente nivel (kubernetes por ejemplo) nos encontramos con la necesidad de pasar a produccion las aplicaciones que vamos desarrollando y, quizá, utilizar un gestor como Kubernetes nos haga más complicado utilizar https. Hay dos soluciones principales que he utilizado para distintos servicios y que os voy a comentar muy brevemente aquí: usar apache como proxy inverso instalado en la máquina host o utilizar un docker con el proxy inverso en nginx.
Para los dos casos vamos a suponer que tenemos un contenedor docker con una aplicación web que tenemos expuesto en el puerto 8080 (por ejemplo).
Método 1: Apache Nativo
Empecemos por el primer sistema, el que primero se me ocurrió y que tiene sus ventajas y sus inconvenientes. Básicamente consiste en instalar de manera nativa el servidor apache, el módulo mod_proxy y hacer que actúe como un proxy inverso para los dominios que necesitemos. Os explico los pasos suponiendo que estáis instalando en una máquina ubuntu recien provisionada:
Llegados a este paso debemos crear un archivo de configuración para la aplicación web y dejarlo en /etc/apache2/sites-available/misitio.conf algo como esto:
Lo relevante es el nombre del sitio y un directorio para las páginas, que no vamos a utilizar, pero que tiene que existir para las validaciones posteriores. En este caso estoy usando también el módulo itk para que se ejecute con un usuario sin privilegos. Posteriormente a esto ejecutamos:
sudo a2ensite misitio
sudo service apache2 restart
Con esto ya tendremos el servicio apache levantado y respondiendo a peticiones, por lo que podemos solicitar el certificado (recuerda que el dns del servicio debe apuntar a la dirección IP del servidor).
sudo certbot
Esto nos preguntará qué dominios queremos proteger y si todo ha ido bien nos generará un archivo midominio-le-ssl.conf que contendrá ya los enlaces a los certificados y configuración asociada. Con lo que ya podrías acceder a https://www.midominio.com
Ahora queda la parte en la que «conectamos» este servidor con nuestro docker que, recordemos, está corriendo en el puerto 8080, para ello modificaremos el archivo de configuración que nos ha creado certbot añadiendo estas líneas:
Reiniciamos apache y ya tenemos enganchado nuestro docker a https.
Método 2: docker que nos lo hace todo
Si el método anterior nos parece un poco pesado o no queremos tener que guardar la configuración particular de una máquina, podemos optar por añadir esto a nuestro archivo docker-compose (teniendo en cuenta que hemos llamado miservicio al servicio que tenemos en el 8080):
Y eso es todo, el servidor al levantarse se encarga de pedir los certificados y guardarlos en el directorio ssl_certs que será el único que tenemos que persistir para evitar tener que pedirlos cada vez que arranque el servidor.
Cada uno de los dos métodos tiene sus pros y sus contras (hacerlo en kubernetes es otra historia y no aplica ninguno de estos métodos), pero básicamente si queremos exponer más de un contenedor (en distintos docker-compose) la única manera es usar el proxy inverso nativo, si todo lo que queréis servir por https está en un solo docker-compose el segundo método es mucho más cómodo.
Después de un tiempo definiendo distintos contenedores docker y coordinando despliegues con docker compose me he encontrado con circunstancias que me obligaban a modificar los archivos de definición cada vez que necesitaba hacer un nuevo despliegue o paso a producción y eso, bueno, eso es un poco molesto. Así que sabiendo que la gente que ha desarrollado todo esto era más lista que yo me puse a buscar cómo proponen que lo hagamos.
Y la respuesta es… Mediante varibles de entorno (al menos una de ellas), así que vamos a ver cómo podemos, como ejercicio, poner el número de versión de nuestro despliegue como varible de entorno..
Como véis el número de versión acompañaba al nombre de la imagen y esto es así para que al construirla ya llevase la etiqueta adecuada para subirla al repositorio privado. El problema era que cada vez que hacíamos una release nueva teníamos que tocar este archivo a mano… Si queremos no tener que tocar el archivo tenemos que poner algo así:
De esta forma solo hay que definir la varible de entorno VERSION al valor que acabamos de generar. Ahora bien, es fácil que nos olvidemos de asignar esta variable de entorno si no está en ningún sitio del repositorio, así que lo más sencillo es incluirla en un archivo .env que será el que docker-compose cargue antes de ejectuar el build… Y quedaría así:
VERSION=1.0.0
En este archivo podemos incluir todas las variables que necesitemos y, lo que es más, podremos pasarselas al Dockerfile si lo necesitamos, eso si, el método es un poco más rebuscado (eso lo veremos un poco más adelante).
Usar docker es sencillo y rápido, pero, como todo, tienes que tener cuidado con todo lo que ocupa espacio ya que los discos y las particiones son finitas… Y los contendores docker ocupan espacio (bastante), así que aquí dejo el método para mover el directorio de datos de la partición por defecto a otra cualquiera que queramos y para la que tengamos espacio de sobra.
Lo primero que hay que saber es que el directorio por defecto donde docker guarda sus imágenes, contenedores y demás cosas que ocupan espacio es:
/var/lib/docker
Que, generalmente, está en la partición raiz (o la que tengamos para var) que no suele ser muy grande. Supongamos que queremos moverla a un disco de datos con capacidad suficiente como este:
/mnt/disks/data/docker
Para ello lo que tendremos que hacer es: parar el servicio docker
sudo service docker stop
Crear un archivo llamado daemon.json en el directorio /etc/docker con este contenido:
{
"graph": "/path/to/your/docker"
}
Copiamos el directorio original al nuevo y lo renombramos por seguridad (ya lo borraremos después)
Reiniciamos el servicio docker y todo debería estar como antes del cambio (podéis comprobar con un docker ps si se ha levantado todo lo que teníais funcionando antes).
sudo service docker start
Después de comprobar que todo está ok, ya podemos borrar el original y habremos terminado con la operación del todo:
Si, esta es una receta muy sencilla y muy rápida. Quizá no sea perfecta, pero en caso de que quieras montar un servidor wordpress sin preocuparte de instalaciones y milongas, este es el método.
Voy a suponer que ya sabes lo que es docker y docker-compose, es más, voy a dar por hecho que los tienes instalados en el servidor donde quieres instalar wordpress, si eso no es así vete disparado a google y búscalo (me lo agradecerás).
Vamos a hacer una instalación donde la base de datos y los archivos de wordpress estén en directorios de la misma máquina y no dentro del contenedor, de manera que podamos reiniciar y actualizar los contenedores preservando los datos. Para ello creamos una estructura haciendo algo similar a esto (pongo como se hace en linux):
mkdir wordpress
cd wordpress
mkdir db
mkdir archivos
mkdir docker
cd docker
Ahora viene lo bueno, creamos dentro del directorio docker el archivo docker-compose.yml con este contenido:
Y con esto ya tenemos todo el pescado vendido. Nos metemos en el directorio docker (donde está el docker-compose.yml) y ejecutamos:
docker-compose up -d
Puedes comprobar que todo está funcionando en cualquier momento con el comando docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
18b4c06458b7 wordpress:latest "docker-entrypoint.s…" 36 seconds ago Up 32 seconds 0.0.0.0:80->80/tcp docker_wordpress_1
211c0832d549 mysql:5.7 "docker-entrypoint.s…" 39 seconds ago Up 35 seconds 3306/tcp, 33060/tcp docker_db_1
Ahora, para instalar, de verdad, el wordpress debemos conectar a http://localhost y podremos comenzar la instalación:
Y después de poner todos los datos tendremos un wordpress funcional en el puerto 80, con el añadido de que para realizar un backup solo tenemos que parar los contenedores y copiar los directorios db y archivos (o llevárnoslos a otro servidor).
Hay muchas mejoras que hacer si queremos que esto esté listo para producción como, por ejemplo, hacer que vaya por https (para eso lo mejor es poner un proxy inverso), pero ya lo veremos un poco más adelante. Por ahora, si queréis parar los servicios solo tenéis que ejecutar, desde el directorio docker la instrucción:
docker-compose stop
Y, lo bueno, es que tu máquina no ha sufrido ningún cambio de configuración ni ha instalado ningún paquete de más… Todo ventajas.
Gestionar el consentimiento de las cookies
Si, es un coñazo, pero tengo que ponerte este aviso sobre las cookies y mi
Funcional
Siempre activo
El almacenamiento o acceso técnico es estrictamente necesario para el propósito legítimo de permitir el uso de un servicio específico explícitamente solicitado por el abonado o usuario, o con el único propósito de llevar a cabo la transmisión de una comunicación a través de una red de comunicaciones electrónicas.
Preferencias
El almacenamiento o acceso técnico es necesario para la finalidad legítima de almacenar preferencias no solicitadas por el abonado o usuario.
Estadísticas
El almacenamiento o acceso técnico que es utilizado exclusivamente con fines estadísticos.El almacenamiento o acceso técnico que se utiliza exclusivamente con fines estadísticos anónimos. Sin un requerimiento, el cumplimiento voluntario por parte de tu Proveedor de servicios de Internet, o los registros adicionales de un tercero, la información almacenada o recuperada sólo para este propósito no se puede utilizar para identificarte.
Marketing
El almacenamiento o acceso técnico es necesario para crear perfiles de usuario para enviar publicidad, o para rastrear al usuario en una web o en varias web con fines de marketing similares.