DEV Community

Jorge Eψ=Ĥψ
Jorge Eψ=Ĥψ

Posted on • Originally published at jorge.aguilera.soy on

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-skeletony/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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

| 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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

| 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 nginxy 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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

<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

Discussion (0)