¿Qué es un bastión en términos informáticos?
Te estarás preguntando qué es un bastión en términos informáticos, pues básicamente es un servicio, servidor o aplicación, que recibe todo el tráfico web y lo reparte a donde sea necesario.
¿Qué utilidad tiene esto?
Más que utilidad, deberíamos enfocarlo a seguridad.
Supón que tienes un servicio abierto al público dentro de tu servidor y no quieres que se acceda directamente a él.
Tráfico entrante --> servidor Nginx --> contenedores A, B y C
Los contenedores A, B y C están protegidos ya que no se puede acceder a ellos directamente, el tráfico que entra en dichos contenedores está controlado por nuestro bastión nginx. El acceso a las bases de datos solo está permitido directamente por nuestro contenedor A que es la app que necesita de dicho acceso. Si necesitásemos modificar o acceder a dicha base de datos, solo nosotros podríamos hacerlo, accediendo localmente a dicho contenedor. Por lo demás, el acceso desde fuera sería imposible, ya que no tenemos los puertos expuestos al exterior.
¿Cómo hacemos esto con docker?
Vamos a recuperar nuestro fichero docker compose de la publicación que vimos de Jellyfin y Docker.
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
ports:
- 8096:8096 #Puerto HTTP
- 8920:8920 #Puerto HTTPS
volumes:
- ./config:/config
- ./cache:/cache
- ./media/media
restart: unless-stopped
Tal y como está el fichero, tendríamos los puertos expuestos al exterior y esto no es lo que queremos, vamos a cerrarlos:
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
volumes:
- ./config:/config
- ./cache:/cache
- ./media/media
restart: unless-stopped
De esta manera, el servicio sigue escuchando por los mismos puertos (8096 y 8920) pero no se puede acceder desde el exterior, solo localmente.
Configuración bastión nginx
¿Qué faltaría ahora? Nuestro queridísimo bastión nginx. Os dejo la configuración de ejemplo y su explicación con comentarios:
server {
listen 80;
server_name tu-dominio.com; # Cambia esto por tu dominio o IP
location / {
# Redirige todas las solicitudes al contenedor Jellyfin
proxy_pass http://jellyfin:8096; # jellyfin como nombre interno del contenedor
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
De esta manera, estaremos poniendo en práctica nuestro modo bastión nginx con apps en contenedores no expuestas al exterior.
En el caso que queramos aplicar configuración SSL de igual forma sería así:
server {
listen 80;
server_name tu-dominio.com;
# Redirigir todo el tráfico HTTP a HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name tu-dominio.com;
ssl_certificate /ruta/a/tu-certificado.pem;
ssl_certificate_key /ruta/a/tu-clave.key;
ssl_protocols TLSv1.2 TLSv1.3; # Protocolos SSL/TLS a usar
location / {
proxy_pass http://jellyfin:8096;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Ya tendríamos listo nuestro bastión 😉 .
Conclusión
Con esta configuración logramos mantener seguros nuestros contenedores con el objetivo de evitar posibles intrusos innecesarios en nuestros servicios web. Solo se permite acceso a los contenedores mediante nuestro bastión nginx.
Cualquier duda o inquietud que tengas, no dudes en comentar abajo. ¡Nos vemos pronto!