Cómo desplegar nodos centinela en la red de Archway

lunes, 25 de abril de 2022

Cuando desplegamos un nodo basado en Cosmos SDK como lo es Archway, debemos tener en cuenta que las redes p2p están expuestas al riesgo de sufrir ataques de denegación de servicio, y una forma efectiva de mitigar este tipo de ataques es utilizando nodos centinela.

¿Por qué es importante evitar los ataques de denegación de servicio?

Cuando nuestro nodo está sufriendo un ataque de denegación de servicio que no puede ser mitigado por el proveedor de servidores, es probable que el servidor quede inoperativo durante el tiempo que dure el ataque ya que, al estar saturado, dejará de responder a las peticiones que realizan el resto de nodos de la red.

Si nuestro nodo queda inoperativo, significa que ya no estamos participando en las rondas de consenso, nuestro nodo no estará firmando bloques ni generando recompensas para los delegadores y por lo tanto en pocos minutos el nodo será enjaulado y penalizado.

Además de ser un riesgo para los operadores de nodos debido a las penalizaciones que conlleva ser enjaulado, también lo es para la red, ya que si se realiza un ataque a varios nodos a la vez, la estabilidad y seguridad de la red se verían afectadas.

Redes P2P

Una red p2p (peer-to-peer) como es la red de Archway, es una red donde un conjunto de ordenadores (2, 10 o 130, no importa el número) están interconectados entre sí. A diferencia de lo que ocurre cuando visitamos una página web donde hay un servidor al que realizamos una petición, en una red p2p no hay un servidor central, sino que todas las máquinas son iguales entre ellas y están comunicándose continuamente para realizar la validación de los bloques de la red.

Red p2p

El problema de las redes p2p radica en que para que las diferentes máquinas (nodos) que forman parte de la red puedan comunicarse entre ellas, es necesario un punto de entrada para poder establecer las conexiones; este punto de entrada es la dirección IP y puerto. Conociendo la dirección IP y el puerto p2p de la máquina, el resto de nodos de la red pueden realizar peticiones, y en definitiva, hacerla partícipe de la red p2p, pero también es la puerta de entrada de los ataques de denegación de servicio de un atacante.

Nodos centinelas, ocultando la IP de nuestro validador al mundo

Como hemos comentado antes, cuando exponemos la IP de nuestro nodo validador, el resto de nodos de la red pueden conectarse con nosotros, pero también estamos permitiendo que alguien pueda saturar nuestra máquina.

Utilizar nodos centinelas es una solución para evitar que el resto de la red conozca la IP de nuestro nodo validador, pero permitiendo que nuestro nodo validador siga comunicandose con otros nodos validadores de la red de Archway, ya que si el nodo estuviera 100% aislado, no podría participar en la red y por lo tanto no generaría recompensas para los delegadores.

Un nodo centinela es un puente entre nuestro nodo validador y el resto de la red, de forma que el resto de la red no conozca la IP del nodo validador, pero sí la de los nodos centinelas.

Red p2p con nodos centinelas

Como se puede ver en la imagen anterior, el "Validator node" unicamente está conectado con nuestros nodos centinelas, pero no con el resto de la red. De esta forma, únicamente los nodos centinelas conocerán la IP de nuestro nodo validador.

¿Pueden sufrir los nodos centinela ataques de denegación de servicio?

Sí, pero como son nodos que no están validando transacciones y lo unico que hacen es actuar como puente entre la red y el nodo validador, podríamos desplegar rapidamente nuevos nodos centinela o incluso cambiar la IP del nodo centinela al que se está realizando el ataque.

¿Cuántos nodos centinela puede haber?

Realmente no hay número máximo, cuantos más nodos centinelas tengamos, más resistencia a ataques de denegación de servicio tendrá nuestro nodo validador. Sin embargo, hay que tener en cuenta que cuantos más nodos centinelas tengamos, más complejo será mantener nuestros nodos a la hora de llevar a cabo mantenimientos o actualizaciones, además del aumento del coste en servidores. Al menos se deberían tener dos nodos centinelas y a ser posible tener uno de ellos en un datacenter diferente de donde esté alojado el nodo validador.

¿Dónde deberían estar alojados los nodos centinela?

Si se van a montar dos nodos centinelas, uno de ellos se podría montar en el mismo datacenter donde esté nuestro nodo validador, esto reducirá la latencia entre ambos servidores, y por tanto, la conexión entre ambos servidores será bastante rápida. El otro nodo centinela podría estar ubicado en un datacenter diferente; de esta forma, en caso de que la red del datacenter donde está nuestro nodo validador cayera por algún motivo, siempre tendríamos disponible un nodo con el bloque actual para sincronizar nuestro nodo validador.

Guía paso a paso

Para seguir esta guía, usaremos un nodo creado en la red de testnet torii-1 de Archway. En caso de no haber desplegado el nodo todavía, puedes apoyarte en la documentación oficial de Archway y también en la documentación específica sobre torii-1.

Creando los nodos centinelas

Una vez que hayamos contratado los dos servidores de los nodos centinelas y tengamos las IP de acceso, deberemos realizar la misma instalación que realizaríamos como si fuera un nodo validador en ambos servidores.

🚀 Tip: Si utilizas MobaXterm, puedes utilizar la opción MultiExec para realizar los mismos comandos en los dos servidores a la vez.

En primer lugar, necesitaremos descargar y compilar el binario de archway.

git clone https://github.com/archway-network/archway
cd archway
git checkout main

Nota: es posible que en el futuro, la rama main no sea la más adecuada y sea necesario descargar la versión que esté publicada en la documentación oficial de Archway. En cualquier caso, la versión deberá ser la misma que tenemos en nuestro nodo validador.

Una vez descargado, procederemos a compilar el binario:

make install

Será necesario también inicializar el nodo para que se cree el directorio .archway, para ello podemos utilizar los siguientes comandos, cada uno en el servidor correspondiente:

  • En el nodo centinela A:
archwayd init "Stakely.io - Sentry A" --chain-id torii-1
  • En el nodo centinela B:
archwayd init "Stakely.io - Sentry B" --chain-id torii-1

Una vez realizado el paso anterior, ya existirá la carpeta .archway, con lo que podemos descargar el archivo genesis.json:

curl -s https://raw.githubusercontent.com/archway-network/testnets/main/torii-1/genesis.json > ~/.archway/config/genesis.json

Por último, realizaremos la configuración del servicio de archway:

sudo nano /etc/systemd/system/archway.service

Con el siguiente contenido, recuerda sustituir el usuario que estés utilizando donde ponga <usuario aquí>.

[Unit]
Description=Archway Daemon
After=network-online.target

[Service]
User=<usuario aquí>
ExecStart=/home/<usuario aquí>/go/bin/archwayd start --p2p.laddr tcp://0.0.0.0:26656 --home /home/<usuario aquí>/.archway
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target

Una vez que hayamos terminado de editar, habilitaremos el servicio:

sudo systemctl enable archway

Configuración base de los nodos centinelas

Por ahora no hemos realizado nada distinto a lo que haríamos al montar un nodo validador, aunque sí que hemos dejado de hacer varias cosas, como la creación de la wallet o ejecutar el comando de creación del validador "tx staking create-validator", ya que no queremos crear nodos validadores, unicamente nodos que se sincronicen con el resto de nodos de la red y podamos utilizar para sincronizar nuestro nodo validador de manera segura sin exponer nuestra IP al resto de la red.

Los nodos centinela (ambos), deben tener peers para estar sincronizados en todo momento, añadiremos los siguientes peers al archivo config.toml dentro de la carpeta config.

persistent_peers = "[email protected]:26656,[email protected]:46656,[email protected]:26656,[email protected]:26756,[email protected]:30273,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26686"

Nota: los peers fueron obtenidos de Discord en el canal de torii-1.

También sería aconsejable añadir como persistent peer a los propios nodos centinelas entre ellos. Es decir, que el nodo centinela B sea persistent peer del nodo centinela A, de la misma forma que el nodo centinela A sea persistent peer del nodo centinela B; esto nos hará tener mayor redundancia.

En el archivo config.toml de la carpeta config de los nodos centinelas (ambos), es necesario espeficicar la id del nodo validador en el parametro private_peer_ids. Esto es para que nuestros nodos centinelas nunca compartan con el resto de peers de la red la existencia de nuestro nodo validador.

private_peer_ids = "nodo validador"

La apariencia debería ser similar a esto:

pares privados

Si no sabes cómo obtener la id de tu nodo validador, puedes obtenerla con el siguiente comando:

archwayd tendermint show-node-id

Nota: a la id recibida, deberemos concatenar la ip y el puerto p2p tal y como se muestra en la imagen anterior.

En el mismo archivo de configuración, también encontraremos el parámetro unconditional-peer-ids al que deberemos añadir obligatoriamente nuestro nodo validador tal y como hicimos con el parámetro private_peer_ids. Es necesario realizar este paso debido a que los nodos tienen limitado el número de peers a los que pueden conectarse.

Para evitar el riesgo de dejar incomunicado a nuestro nodo validador, estableciendo su id en el parámetro unconditional-peer-ids, haremos que los nodos centinelas siempre estén conectados al nodo validador aunque se haya superado el límite de peers a los que pueden estar conectados. Opcionalmente también podemos añadir en este mismo parámetro (separando por comas) al nodo centinela homólogo para garantizar que los nodos centinelas siempre vayan a estar conectados entre ellos.

unconditional-peer-ids = "nodo validador, nodo centinela homologo"

Nota: con nodo centinela homólogo nos referimos a que si estás configurado el nodo centinela A, el homólogo sería el B, y en el caso de estar editando el nodo centinela B, el homólogo sería el nodo centinela A.

Llegados a este punto, podríamos iniciar nuestros nodos centinelas y dejar que se sincronicen y sean descubiertos por el resto de la red. Para eso utilizaremos el siguiente comando:

sudo systemctl start archway

Si hemos realizado todos los pasos correctamente, deberíamos ver cómo ambos nodos centinelas se están sincronizando:

nodo sincronizándose

Configuración del nodo validador

Una vez que los nodos centinela se haya sincronizado, podemos configurar el nodo validador con toda seguridad de que el nodo validador no va a dejar de estar sincronizado. Tendremos que editar el archivo config.toml de la carpeta config, donde encontraremos las siguientes líneas:

# Comma separated list of nodes to keep persistent connections to
# Do not add private peers to this list if you don't want them advertised
persistent_peers =[list of sentry nodes]

En persistent_peers añadiremos unicamente las id de los nodos centinelas, es decir que si el nodo ya estaba montado con anterioridad, deberemos borrar el contenido de este campo antes de añadir nuestros nodos centinelas.

La apariencia debería ser similar a la siguiente:

peers nodo validador

En el mismo archivo de configuración encontraremos el parámetro pex, que debemos establecer en "false". Este parámetro lo que hace es no descubrir otros peers, unicamente utilizará los establecidos en el parámetro persistent_peers.

pex = false

Si el validador ya había estado expuesto a la red, podemos borrar el address book para que unicamente "conozca" a los nodos centinelas; si es un validador que nunca se ha arrancado, no hará falta realizar este paso. Estando dentro de la carpeta config y con el nodo detenido, realizaremos el siguiente comando:

rm addrbook.json

Llegados a este punto, podemos iniciar el nodo y se sincronizará utilizando unicamente los nodos centinela.

Para verificar que de verdad estemos conectados unicamente a dos pares y estos sean los nodos centinela, podemos escribir el siguiente comando en nuestro nodo validado; la salida es un JSON donde nos mostrará el número y qué pares son a los que estamos conectados, donde el número debería ser dos y los pares deberían ser nuestros nodos centinela.

curl -s localhost:26657/net_info

Aquí se puede ver la cantidad de pares a los que está conectado nuestro nodo validador, en este caso es dos, lo que es correcto.

pares conectados

Y en el objeto JSON, si seguimos observando, veremos que los dos peers que tenemos se tratan de "Sentry A" y "Sentry B".

Extra: Protegiendo el nodo validador a través de firewall

Ahora mismo el puerto p2p de nuestro nodo validador está abierto y cualquiera puede establecer conexión. Si acabamos de montar el nodo validador, con las configuraciones realizadas, nadie tendría que encontrar nuestro nodo validador, sin embargo, para añadir un plus de seguridad es recomendable cerrar el puerto p2p y permitir solamente tráfico a las IP's de nuestros nodos centinela.

Hay varias formas de hacerlo, es posible que tu proveedor de servidores permita hacerlo a través de una interfaz gráfica. Ufw es una alternativa sencilla de usar, puedes leer más sobre ufw aquí.

Los comandos a utilizar con ufw son los siguientes:

sudo ufw allow from <ip sentry A> proto tcp to any port 26656
sudo ufw allow from <ip sentry B> proto tcp to any port 26656

Extra: Redes privadas

Una posibilidad que tenemos cuando nuestro nodo validador está en el mismo datacenter que alguno de los nodos centinelas, sería utilizar direccionamiento privado.

En caso de querer utilizar direccionamiento privado, tendremos que editar el parametro addr-book-strict del archivo config.toml y establecerlo a false tanto en el nodo validador como en el nodo centinela que se estén comunicando bajo direccionamiento privado. Este parámetro, cuando está establecido en "true", unicamente añadirá direcciones enrutables al libro de direcciones, las direcciones privadas definidas en el RFC-1918 no son enrutables, por ello, no se añadirían al libro de direcciones, con lo que tendremos que cambiarlo a false para poder utilizar direcciones IP de los rangos privados.

addr-book-strict: boolean. Por defecto, los nodos con una dirección enrutable serán considerados para la conexión. Si esta configuración está desactivada (false), las direcciones IP no enrutables, como las direcciones de una red privada, pueden añadirse a la libreta de direcciones.
Fuente: https://docs.tendermint.com/master/nodes/validators.html

Conclusiones

Disponer de nodos centinelas, no solo nos ayudará a que nuestro nodo validador no sea víctima de un ataque de denegación de servicio, sino que además estaremos haciendo la red de Archway sea más robusta. La instalación de los nodos centinelas no difiere demasiado a la de un nodo validador, y las configuraciones adicionales que hay que realizar son muy sencillas e intuitivas.

Ahora que Archway está realizando la testnet de torii-1, es un buen momento para probar a montar nodos centinela y una vez se lance la mainnet, poder replicarlo con la experiencia de haberlo podido probar en torii-1. Si ya tienes tu nodo en torii-1, ¿a qué esperas para montar tus nodos centinela y protegerte de ataques indeseados?

Escrito por