Proteger con password un site estático

En este post voy a centrarme en un site generado con Antora pero puedes extenderlo a cualquier otro site tipo Gatsby, Hugo, etc o incluso a un simple html
Puedes descargar un repo de ejemplo en https://gitlab.com/puravida-asciidoctor/antora-skeleton y/o acceder al ejemplo en https://antora-password-protected.herokuapp.com/ con el usuario test/test

Una vez que tienes tu contenido generado en HTML, una de las preguntas que te surge es cómo puedo restringuir su acceso a sólo algunos usuarios.

En este post vamos a ver alguna de las alternativas que podrías usar dependiende de si los lectores serían internos (por ejemplo otros equipos en la intranet de la empresa) o externos y en este caso si cuentas con infraestructura propia o quieres usar un proveedor externo. Así mismo puedes plantearte si lo que quieres es proteger una simple página o todo un site

Simple página HTML

Preparando este post encontré un script en node, staticrypt, que encripta una página html con una password que le proporcionas generando así un html con un interface para pedir la password y poder desencriptar la página

Digamos que tienes un Asciidoctor donde tienes documentado un API y quieres publicarlo pero que sólo lo puedan leer los que tengan la clave:

= My API

this is my api
blablablab

Generamos el html:

$asciidoctor api.adoc

y obtenemos api.html

Lo encriptamos con staticrypt

$staticrypt api.html la_clave_para_desencriptar -o api.html

y ya tenemos un fichero api.html protegido que se puede publicar en Gitlab Pages, Github, etc

Sin embargo esta solución no funciona cuando tu documentación contiene varios ficheros porque, aunque puedes encriptar todos los ficheros, el usuario tendrá que proporcionar la página en cada una. Así que necesitamos algo que mantenga la sesión

Site alojado en S3

Como existe mucha documentación tanto de AWS como tutoriales sobre cómo crear un Bucket de S3 y proteger su contenido no voy a explicarlo aquí. Simplemente lo menciono por si no lo habías tenido en cuenta

Site alojado en Bucket GGP

Lo mismo para un bucket de Google Cloud Platform, y en realidad por extensión a todos los compatibles con estos

Site alojado por nuestros medios

Una de las formas de proteger un site web es usando un fichero .htpasswd que puede ser manejado por Apache o por Nginx. En este post vamos a usar este último pues es mucho más fácil y ligero que Apache

Para crear el fichero seguiremos cualquier tutorial de Internet pero básicamente es ejecutar un comando tipo httpass o usar una de las muchas páginas online que lo generan

Siguiendo cualquiera de las dos opciones, vamos a crear el usuario test con password test

httpasswd
test:$apr1$yofaxwjl$xw.u6dmKy2qYiayuEnWW1. (1)
1 Obviamente puedes crear tantos usuarios como quieras, uno por cada linea
WARNING

El fichero esperado es con un punto al inicio pero yo lo uso sin punto para que me aparezca cuando listo el directorio y luego lo copio al contenedor con el nombre esperado

Site interno con NGINX

Supongamos que en nuestra empresa contamos con una infraestructura y disponemos de al menos un servidor con espacio y con Docker instalado (obviamente Docker es opcional pero así podemos aislar aplicaciones unas de otras).

Supongamos que hemos creado nuestro site Antora pero no queremos que cualquier usuario pueda acceder a ello (yo que sé porqué) sino sólo aquellos que dispongan del usuario y password creados anteriormente.

En nuestro proyecto Antora, crearemos un directorio nginx y ubicaremos en él el fichero htpasswd

Así mismo crearemos en este directorio un fichero mínimo de configuración de Nginx

default.conf
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        auth_basic "Restricted Content";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }
}

y en el root de nuestro proyecto crearemos un docker-compose similar a

docker-compose.yml
version: "3"

services:

  antora:
    image: "ggrossetie/antora-lunr:2.3.4"
    volumes:
      - .:/antora
    entrypoint: /bin/ash
    command: /antora/custom-antora.sh (1)

  nginx:
    image: "nginx"
    volumes:
     - ./nginx/.htpasswd:/etc/nginx/.htpasswd
     - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
     - ./public:/usr/share/nginx/html
    ports:
     - "9080:80"
1 El contenido de este fichero escapa a este post pero basicamente construye un site antora

Con este docker-compose podemos generar el site mediante docker-compose run antora lo cual nos genera la documentaacion en public

Una vez generada y revisada en local podemos compartirla vía nginx con docker-compose up -d nginx y nuestros usuarios internos podrán acceder a ella vía el puerto 9080

Site publico con Heroku

Usando la capa gratuita de Heroku podemos desplegar nuestro site junto con el servicio Nginx anterior de tal forma que podríamos publicarlo en Internet y protegido mediante usuario/password de la misma forma

Para este paso necesitas tener una cuenta gratuita en Heroku y el comando de consola instalado , así como haber hecho login con el mismo.

La idea es muy similar y lo que vamos a aprovechar es la capacidad de poder subir una imagen a Heroku construida por nosotros y correr una instancia de la misma. En la capa gratuita, Heroku para los containers transcurrido un tiempo (creo que 30 minutos) y lo vuelve a levantar ante una petición. Como nuestro servicio es realmente ligero, este tiempo de espera es casi inmediato para el usuario

Uno de los requisitos de Heroku es que él nos indica en tiempo de arranque el puerto en el que va a escuchar el contenedor por lo que el fichero nginx anterior no nos sirve. Usaremos para ello este otro

change.default.conf
server {
    listen       $PORT;
    listen  [::]:$PORT;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        auth_basic "Restricted Content";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }
}

Junto con este Dockerfile

Dockerfile
FROM nginx

COPY nginx/htpasswd /etc/nginx/.htpasswd
COPY nginx/change.default.conf /etc/nginx/conf.d/default.conf
COPY public /usr/share/nginx/html

CMD /bin/bash -c "envsubst '\$PORT' < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf" && cat /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;' (1)

<1>Es una sóla linea muy larga, supongo que se puede partir en varias pero no lo he investigado

Básicamente vamos a construir una imagen de nginx cambiando en el arranque la configuracion del puerto antes de ejecutar el servicio

Con todo ello preparamos nuestra aplicación en Heroku

heroku container:push web -a TU-APPLICATION

Y si todo ha ido bien, la desplegamos

heroku container:release web -a TU-APPLICATION

y eso es todo. Ahora tu documentación estaría expuesta en Internet pero protegida por usuario/password

Conclusión

Obviamente no es la forma más robusta y completa de desplegar una documentación, pero es sencilla, barata y si lo automatizas puedes incluso ir rotando los usuarios y/o sus claves de una forma sencilla

Follow comments at Telegram group Or subscribe to the Channel Telegram channel

2019 - 2021 | Mixed with Bootstrap | Baked with JBake v2.6.7