Soy Fernando Muñoz, Cloud Engineer en Platzi, certificado en GitHub Actions y AWS Solutions Architect Associate. Hoy quiero que descubras cómo puedes transformar tu flujo de trabajo al utilizar Cloudflare Tunnels, una tecnología que proporciona una forma simple y segura de interconectar redes.
En este blog, te guiaré paso a paso para conectar GitHub Actions a redes privadas de AWS de manera segura y eficiente. Sin embargo, los Tunnels de Cloudflare van mucho más allá y no se limitan a estos dos únicos proveedores, ya que te permiten conectar prácticamente con cualquier proveedor de la nube actual e incluso puedes conectar con tu red local.
Para aprovechar al máximo el contenido de este blog, es importante contar con conocimientos en las siguientes áreas:
Si aún no dominas estos temas, te recomiendo explorar los siguientes cursos para fortalecer tus habilidades:
Estos cursos te proporcionarán una base sólida para seguir adelante con confianza y sacar el máximo provecho de las tecnologías que exploraremos en este blog.
Hicimos una versión en video del blog por si prefieres escuchar la explicación o usarlo como podcast.
Déjame darte una breve introducción:
Es una solución de software que protege tus servidores web de ataques directos al crear un túnel cifrado entre tu servidor de origen y el centro de datos más cercano de Cloudflare, sin necesidad de abrir puertos públicos.
Esto asegura que las direcciones IP de tus servidores permanezcan ocultas, bloqueando ataques DDoS y brechas de datos. A diferencia de métodos tradicionales como las listas de control de acceso (ACLs) o los túneles GRE, Cloudflare Tunnel es más rápido, seguro y fácil de configurar, proporcionando una protección integral y eficiente para aplicaciones en cualquier infraestructura, ya sea en la nube pública, privada o incluso en dispositivos locales.
Tunnel | Zero Trust App Connector | Cloudflare
Imagina dos mundos separados: por un lado, la red donde operan los GitHub Actions Runners, y por otro, nuestra red privada en AWS. Estos dos mundos no se conocen ni tienen un camino para comunicarse. Nuestra misión es crear un puente, o mejor dicho, un túnel que permita a los Runners de GitHub interactuar con los recursos privados de AWS.
Para ser más claros, en AWS tengo dos instancias de EC2 dentro de subredes privadas, donde, por ejemplo, no tengo IP pública, sino solo IP privada. Y además en AWS, tengo un EKS.
Si yo intentara hacer ping o SSH a esa máquina en este momento, fallaría porque no hay nada que permita conectarlas entre sí. Debería aparecer un mensaje de error del tipo Connection timed out
o similar.
O, por ejemplo, ¿qué pasa si tenemos un EKS desplegado y queremos interactuar con él desde GitHub Actions?
Como vemos, en ambos casos los Actions nos devuelven un error debido a que no pueden alcanzar esa red privada.
Ahora, podrías preguntarte: ‘Fernando, ¿por qué no simplemente usar GitHub Self-Hosted Runners?’ Y… es una opción válida. Sin embargo, como en todo en ingeniería de software, la elección depende de tus necesidades específicas.
Aquí te explico por qué Cloudflare Tunnel puede ser una opción más ventajosa:
Nuestro objetivo es claro:
Para lograrlo, introduciremos dos conceptos clave:
Entonces, procederemos a:
¡Manos a la obra! Primero haremos todas las configuraciones necesarias en nuestra cuenta de Cloudflare.
Ahora, vamos a crear el Tunnel y dejarlo listo para recibir conexiones.
Dentro de la sección de Zero Trust de tu cuenta de Cloudflare, nos dirigiremos a la parte de Networks/Tunnels
y haremos clic en Add Tunnel
.
En Tunnel type
, seleccionaremos cloudflared
, le pondremos el nombre de nuestra preferencia al túnel y haremos clic en el botón “Save tunnel”.
En esta sección configuraremos ¿Quién?
y ¿Cómo?
pueden conectarse a nuestra cuenta de Cloudflare.
Zero Trust
de nuestra cuenta de Cloudflare, nos dirigimos al apartado de Access/Service Auth
y hacemos clic en Create Service Token
."Header and client ID
y un Header and client secret
. Estos datos son muy sensibles, por lo cual debes resguardarlos en lugares muy seguros. Hacemos clic en el botón Save. Se nos mostrará el resumen de todos los tokens de nuestra cuenta.Define group criteria
seleccionaremos en el Selector el valor de Service Token y en su Value buscaremos el nombre del Service Token
que acabamos de crear. Haremos clic en el botón Save.En esta sección nos centraremos en cómo alguien o algo puede unirse a nuestra cuenta de Cloudflare mediante el cliente WARP.
Settings
y buscaremos la opción de WARP Client
. Luego, haremos clic en el botón Manage
en la sección de Device enrollment
.En esta sección nos centraremos en la creación de un perfil para el cliente WARP y en asegurarnos de que todos los usuarios que cumplan los criterios utilicen el túnel y realicen el split del tráfico indicado.
Zero Trust
de Cloudflare, nos dirigiremos a Settings
y buscaremos la opción WARP Client
.Split Tunnels
, por defecto esta en Exclude IPs and domains
, daremos click en Manage
.Por cierto es más fácil usar el modo Include IPs and domaians
, pero te dejo de tarea investigar como se utiliza esta opción.
Exclude
, aparecerá una lista previa de direcciones que el cliente WARP evitará para no generar conflictos con otras aplicaciones y, de esta manera, garantizar que solamente el tráfico legítimo que queremos que viaje por el cliente WARP y, por ende, por nuestro túnel de Cloudflare, lo haga.Es importante leer esta documentación de Cloudflare para entender cómo funciona: Change Split Tunnels mode by Cloudflare
En mi caso, mi VPC tiene el CIDR como 10.0.0.0/16 y mis subredes se ven así:
3 subnets privadas:
3 subnets públicas:
Dato geek: el bloque 10.0.0.0 (prefijo 10/8) es un bloque de direcciones IP privadas definido por la RFC 1918, que abarca desde 10.0.0.0 hasta 10.255.255.255. Es uno de los rangos de IPs comúnmente utilizado en redes privadas. https://www.rfc-es.org/rfc/rfc1918-es.txt
Entonces, dado que nuestra VPC utiliza el rango 10.0.0.0/16, vamos a eliminar el rango 10.0.0.0/8 que ya estaba agregado previamente en nuestro Split Tunnel
.
Ahora, excluiremos los rangos que no estamos utilizando explícitamente en nuestras subredes. Esto es para evitar que ese tráfico viaje por nuestro WARP y así no afecte a servicios o aplicaciones que no deberían pasar por aquí.
En mi caso serían:
10.0.96.0/1910.0.128.0/17
¿Cómo calculamos esto?
a. Identificar el rango total de la VPC; en mi caso, 10.0.0.0/16, con IPs disponibles desde 10.0.0.0 hasta 10.0.255.255.
b. Ordenar las subredes por su dirección de inicio.
10.0.0.0/20 (10.0.0.0 - 10.0.15.255)
10.0.16.0/20 (10.0.16.0 - 10.0.31.255)
10.0.32.0/20 (10.0.32.0 - 10.0.47.255)
10.0.48.0/20 (10.0.48.0 - 10.0.63.255)
10.0.64.0/20 (10.0.64.0 - 10.0.79.255)
10.0.80.0/20 (10.0.80.0 - 10.0.95.255)
c. Identificar si tenemos huecos, que en este caso no tenemos. Pero un hueco sería, por ejemplo, tener una subred 10.0.0.0/20
que cubre de 10.0.0.0 a 10.0.15.255 y que nuestra siguiente subred sea 10.0.32.0/20
, que cubre de 10.0.32.0 a 10.0.47.255, entonces no tenemos ninguna subred que cubra de 10.0.16.0 a 10.0.31.255.
d. Todos esos huecos son los rangos que no utilizamos; los transformamos a notación CIDR y obtendríamos 10.0.16.0/20
.
e. En mi caso, no estoy usando el rango de 10.0.96.0 a 10.0.255.255, de ahí es donde aparecen los CIDR 10.0.96.0/19
y 10.0.128.0/17
.
¡De momento, felicidades! Hemos terminado de configurar todo lo necesario dentro de nuestra cuenta de Cloudflare. Ahora solo nos falta configurar el cloudflared
en una instancia dentro de nuestra cuenta de AWS y configurar el warp-cli
en GitHub Actions.
cloudflared
en nuestra VPC de AWScloudflared
.cloudflared
en esta instancia privada. En mi caso, para las EC2 con Amazon Linux, los comandos son los siguientes: curl -fsSL https://pkg.cloudflare.com/cloudflared-ascii.repo | sudo tee /etc/yum.repos.d/cloudflared.repo
sudo yum update
sudo yum install cloudflared
If you already have cloudflared installed on your machine
.Bien, ahora por fin vamos a ver el resultado de todo nuestro trabajo. Como último paso en las ejecuciones de GitHub Actions, tenemos que configurar el warp-cli
para que nuestro Runner pueda interactuar con los recursos privados de AWS. Primero desglosaré por partes el action para explicar algunas cosas.
- name: Install CF WARP
run: |
curl https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
sudo apt-getupdate && sudo apt-getinstall cloudflare-warp
Generamos un archivo mdm.xml
dentro del directorio /var/lib/cloudflare-warp
, con el contenido que nos generó el Service Token que creamos al inicio. Donde:
organization
corresponde al nombre de nuestra organización en Zero Trust.auth_client_id
es el CF-Access-Client-Id que nos generó el Service Token.auth_client_secret
es el CF-Access-Client-Secret que nos generó el Service Token.Guardé esos valores dentro de GitHub como secretos.
- name: Generate mdm.xml file in /var/lib/cloudflare-warprun: |
sudo mkdir -p /var/lib/cloudflare-warp
echo '
organization ${{ secrets.ORGANIZATION }} auth_client_id ${{ secrets.AUTH_CLIENT_ID }} auth_client_secret ${{ secrets.AUTH_CLIENT_SECRET }} ' | sudo tee /var/lib/cloudflare-warp/mdm.xml
sudo chmod 777 /var/lib/cloudflare-warp/mdm.xml
- name: Restart cloudflare-warp service
run: sudo systemctl restart warp-svc.service && sleep 5
- name: warp-cli connect
run: warp-cli --accept-tos connect && sleep20
- name: Set route ip run: sudo ip route add CIDR_DE_TU_VPC dev CloudflareWARP
- name: warp-cli disconnect
if: always()
run: warp-cli --accept-tos disconnect
- name: Delete cloudflare-warp folder
if: always()
run: |
sudo rm -rf /var/lib/cloudflare-warp
Hemos terminado y me gustaría darte los puntos concretos de lo que hemos logrado:
cloudflared
en una instancia privada para darle acceso al túnel a una red privada.Sigue al pendiente del blog de Platzi; próximamente habrá un nuevo artículo como este de Engineering by Platzi. Pero mientras tanto, también puedes leer este otro blog: Cloudflare Pages: Cómo construimos una librería para hacer despliegues
Comparte el artículo si te pareció útil y crees que a alguien más le podría servir; y por supuesto, nos encantaría leerte en los comentarios.