<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://leonca.st/atom.xml" rel="self" type="application/atom+xml" /><link href="https://leonca.st/" rel="alternate" type="text/html" hreflang="en-US" /><updated>2026-05-14T20:12:52+02:00</updated><id>https://leonca.st/atom.xml</id><title type="html">Leonca.st’s blog</title><subtitle>Cybersecurity and Computer Science</subtitle><author><name>León Castillejos</name></author><entry><title type="html">España en el gran apagón de 2025: Una perspectiva de Site Reliability Engineering</title><link href="https://leonca.st/2025/05/01/espa-a-en-el-gran-apag-n-de.html" rel="alternate" type="text/html" title="España en el gran apagón de 2025: Una perspectiva de Site Reliability Engineering" /><published>2025-05-01T00:00:00+02:00</published><updated>2025-05-01T00:00:00+02:00</updated><id>https://leonca.st/2025/05/01/espa-a-en-el-gran-apag-n-de</id><content type="html" xml:base="https://leonca.st/2025/05/01/espa-a-en-el-gran-apag-n-de.html"><![CDATA[<p>Escribo esta publicación en español porque considero que es un tema más interesante para españoles e hispanohablantes, pero la traduciré a inglés más adelante.</p>

<p>Aspectos a tener en cuenta con respecto a esta publicación:</p>

<ul>
  <li>No voy a especular. No sé si esto han sido hackers rusos, aliens, o condiciones atmosféricas, porque no tengo datos a favor ni en contra y por tanto, las razones reales serán descubiertas cuando las investigaciones pertinentes concluyan por un grupo designado de expertos en la materia</li>
  <li>No es un asunto político, esta publicación es estrictamente objetiva y basada en hechos</li>
  <li>No pretendo buscar (personas) culpables, pero quiero recoger cuestiones y preguntas que algunos españoles me han transmitido</li>
  <li>Es una publicación desde una perspectiva de Site Reliability Engineering en la que intento brindar la máxima objetividad y claridad a través de mis experiencias en mi empleo con Booking.com, pero es totalmente independiente de mi ocupación y no pretendo escribir ninguna opinión oficial o detalles técnicos de Booking.com</li>
</ul>

<h2 id="los-nueves">Los “nueves”</h2>

<p>Los “nueves” son un concepto de SRE. Con este indicador, medimos la fiabilidad de un sistema o software.</p>

<p>Según los principios de Site Reliability Engineering, entendemos que siempre puede haber fallos. Según la complejidad de un sistema informatizado aumenta, la probabilidad de fallos también aumenta. Los Site Reliability Engineers nos encargamos de que este servicio esté garantizado hasta cierto nivel.</p>

<h3 id="por-qué-no-se-puede-garantizar-fiabilidad-al-100">¿Por qué no se puede garantizar fiabilidad al 100%?</h3>

<p>Si lo piensas detenidamente, en cualquier punto de un sistema suficientemente complejo pueden aparecer fallos y situaciones inesperadas. Por ejemplo: Si tienes tu página web hospedada en un servidor en tu casa, y se va la luz, tu servidor naturalmente va a dejar de funcionar correctamente. También puedes perder el servicio de internet, o incluso puedes sufrir un incendio. No importa lo poco probable que sea el fallo, estas situaciones pueden darse.</p>

<p>La tarea del SRE consiste en mitigar estas situaciones inesperadas hasta un cierto nivel que llamamos SLA (Service-Level Agreement), en el que determinamos cuál es el nivel de “nueves” que tiene un sistema.</p>

<p>Un nueve significa 90%. Es decir, día a día, mes a mes y año a año, tu sistema puede caerse durante un 10% del tiempo. Generalmente, esta cantidad de nueves no inspira demasiada confianza en tu sistema.</p>

<p>Dos nueves es 99%. Es un poco mejor, pero generalmente los SREs buscamos fiabilidades alrededor de los cuatro nueves. Esto significa que tu sistema estará disponible durante el 99.99% del tiempo.</p>

<p><a href="https://availability.sre.xyz/">Esta calculadora</a> puede ayudarte a entender un poco cómo funciona este sistema de los nueves.</p>

<p>Por ejemplo, un sistema de cuatro nueves sólo puede dejar de responder durante 52.59 minutos a lo largo del año. En otras palabras, garantizamos el funcionamiento del servicio con un nivel máximo de incertidumbre alrededor de una hora.</p>

<p>Como puedes observar, diferentes sistemas tienen diferentes niveles de fiabilidad. Por ejemplo, los hospitales continuaron funcionando durante el apagón gracias a generadores integrados. De esta manera, pueden continuar atendiendo emergencias médicas en situaciones como esta. Sin embargo, el metro de Madrid no tiene sistemas de baterías o generadores porque se considera que el transporte público tiene menor importancia que los hospitales o los cuerpos de seguridad del estado.</p>

<h3 id="cómo-incrementar-los-nueves">Cómo incrementar los nueves</h3>

<p>Toda fiabilidad añadida incrementa los costes. Por ejemplo: Si volvemos a la página web hospedada en tu casa, y la mueves a AWS con 3 AZ (Availability Zones), esto significa, que incluso en el poco probable caso de que una zona de AWS se pierda debido a fallo eléctrico, inundación, o desastre natural, tu sitio web puede continuar funcionando. Digamos, por ejemplo, que tienes un servidor en Madrid, otro en Londres, y el último en San Francisco.</p>

<p>En esta situación del apagón, habrías perdido el servidor de Madrid, pero los de Londres y San Francisco continuarían funcionando y sirviendo tráfico. La contrapartida es que ahora estás generando el triple de gastos de lo que gastarías en una situación sin una infraestructura distribuida. Además de eso, tienes que coordinar y sincronizar los tres servidores, cosa que a menudo no es sencilla, y asegurarte de que cualquiera de los tres puede responder con capacidad suficiente a la pérdida de las otras zonas.</p>

<p>En esta situación, si tienes un blog personal como este, tener triple redundancia es muy baja prioridad. Pero si tu infraestructura web es Amazon, PC Componentes, perder una AZ podría provocar serios daños financieros.</p>

<p>Según <a href="https://www.junglescout.com/blog/how-much-does-amazon-make-in-a-year/">esta página web</a>, Amazon genera sesenta y cuatro millones de dólares (64.000.000) cada hora, y por lo tanto, una caída de apenas 10 minutos provocaría daños millonarios que continúan mientras no se solucione el problema.</p>

<h2 id="por-qué-mis-paneles-solares-no-suministran-energía-en-un-apagón">¿Por qué mis paneles solares no suministran energía en un apagón?</h2>

<p>El sistema de suministro eléctrico mundial consiste en corriente alterna. Diferentes países tienen diferentes voltajes y frecuencias, pero lo importante es que todos los generadores, plantas nucleares, hidroeléctricas, y demás estén en perfecta sincronía. En España, la frecuencia debe oscilar a 50 hercios, y además se debe sincronizar los picos y valles con respecto a la señal de “referencia” del sistema eléctrico.</p>

<p>Si la red eléctrica se cae, tus paneles solares se desactivan automáticamente como sistema de protección. Si tus paneles solares continúan funcionando tras el apagón, existe una posibilidad de que se salieran de la sincronización con la red eléctrica, y esto puede provocar serios problemas, desde sobrecargas de transformadores y subestaciones hasta incendios eléctricos, o podrían electrocutar a un operario que estuviera trabajando en la zona y piense que no hay suministro eléctrico.</p>

<p>Para que tu casa funcione con electricidad solar, necesitas dos cosas: Un requisito imprescindible es poder funcionar aislado de la red (modo isla), de manera que sólo suministres energía a tu casa. El otro requisito es disponer de baterías. Las baterías son importantes porque la energía solar fluctúa según la intensidad del sol. Aunque sea un día especialmente soleado, la más mínima nube podría obstruir el suministro, y si tú comienzas a utilizar más energía, por ejemplo, usando el horno, o el aire acondicionado, los inversores de los paneles solares se desconectan por seguridad ya que la demanda excede el suministro disponible.</p>

<p>En este vídeo podéis ver este asunto de una forma más detallada:</p>

<div class="embed-responsive embed-responsive-16by9">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/05wC0Oz7plU"></iframe>
</div>

<h2 id="la-cultura-sin-culpables">La cultura “sin culpables”</h2>

<p>Blameless, en inglés. Los SRE trabajamos en entornos “blameless”. Buscar los culpables de un incidente no es productivo por varias razones:</p>

<ol>
  <li>Si intentas buscar a culpables y pones en riesgo su empleo, cualquier persona involucrada estará menos incentivada en ser honesta y priorizará proteger su puesto de trabajo.</li>
  <li>El problema nunca es de un individuo. En otras palabras, si tu sistema puede fracasar debido a las acciones de un único individuo, tu sistema es frágil y está mal diseñado.</li>
  <li>Durante un incidente, la prioridad es solucionar la situación, y no tanto buscar al culpable.</li>
  <li>Tras un incidente, los informes y las investigaciones deben estar centradas en por qué los sistemas fallaron de esta manera, y por qué los sistemas secundarios, backups, mecanismos de control y protección no actuaron como es debido</li>
</ol>

<p>Dicho en otras palabras: En un sistema robusto, se espera que las acciones potencialmente catastróficas de un único individuo están fuertemente controladas, auditadas y limitadas. En ingeniería de software podemos ver esto en aspectos como CI/CD y comprobaciones sobre el código fuente que se ejecutan y podrían impedir el lanzamiento de una nueva versión de software si no pasa la batería de pruebas.</p>

<p>Los sistemas complejos como los sistemas informáticos o las redes de electricidad pueden fallar de muchas formas diferentes. En la mayoría de los casos no existen manuales para tipos de fallos específicos, y desafortunadamente se tienen que desplegar soluciones tras fallos de un sistema que se llevan la vida de personas. Un ejemplo que muchos recordamos es el Titanic, que no tenía botes salvavidas para todos los ocupantes: Hoy en día, las normativas y regulaciones exigen que un barco pueda evacuar a todas las personas a bordo a través de sistemas de emergencia. Otras catástrofes como incendios o terremotos han brindado otro tipo de recomendaciones técnicas que también han ayudado a que en el futuro, los impactos del suceso sean menos graves.</p>

<h2 id="los-documentos-post-mortem">Los documentos post-mortem</h2>

<p>Otra gran responsabilidad de SREs es la elaboración de documentos técnicos llamados “post-mortem” que investigan, analizan, y explican las causas de fallos en un sistema, y además investigan, analizan y explican qué mecanismos se deben implementar para prevenir que se repita un suceso como este.</p>

<h2 id="todo-depende-de-la-electricidad">Todo depende de la electricidad</h2>

<p>Este suceso también pone de manifiesto que hoy en día, en la sociedad moderna, la grandísima mayoría de actividades dependen de la electricidad. Algunos ejemplos</p>

<ul>
  <li>Los comercios que utilizan persianas con motores no pudieron cerrarlas al finalizar la jornada.</li>
  <li>La red ferroviaria se detuvo completamente a nivel nacional ya que la mayoría de trenes utilizan propulsión eléctrica, y los pocos trenes que aún utilizan diésel dependen de señalización y sistemas de control eléctricos en las vías.</li>
  <li>Edificios como rascacielos no tenían agua en los pisos más altos.</li>
  <li>Las antenas de telefonía a menudo utilizan baterías y generadores, pero aquellas que no cuentan con sistemas redundantes dejaron incomunicados a municipios y ciudades enteras.</li>
</ul>

<h3 id="el-dinero-en-efectivo-y-los-coches-de-combustión-interna">El dinero en efectivo y los coches de combustión interna</h3>

<p>Algunos individuos se apresuraron a apuntar que el dinero en efectivo y los coches de combustión interna (gasolina, gasóleo) siempre funcionarían, sin reparar en asuntos como:</p>

<ul>
  <li>Los escáneres de los supermercados son electrónicos.</li>
  <li>Las cajas registradoras utilizan electricidad.</li>
  <li>Las bombas de gasóleo y gasolina en las gasolineras utilizan electricidad para proporcionar el combustible a la manguera.</li>
  <li>Las puertas de los garajes a menudo utilizan motores para moverse.</li>
  <li>Los semáforos funcionan con electricidad, por lo que se tuvo que desplegar a agentes de tráfico en calles muy concurridas.</li>
</ul>

<h2 id="cuándo-sabremos-qué-sucedió">¿Cuándo sabremos qué sucedió?</h2>

<p>Esto es el documento “post-mortem” que comentaba antes. Un fallo eléctrico a nivel nacional (España y Portugal) es un asunto extremadamente delicado, y con gran visibilidad.</p>

<p>España tiene los suficientes expertos, ingenieros, científicos, y personal cualificado para investigar las causas, y analizar los hechos con una resolución de milisegundos.</p>

<p>Sin embargo, en un incidente de esta magnitud, es muy importante dejar a los profesionales trabajar, y darles el suficiente espacio y tiempo para determinar las causas reales del suceso. Durante la elaboración de un documento “post-mortem”, se discuten cientos de escenarios, hipótesis, y teorías. Estas situaciones se contrastan con datos reales recogidos durante el incidente, y se confirman o descartan con rigurosos principios científicos.</p>

<p>Es normal ser escéptico con respecto a las opiniones oficiales de los oficiales del gobierno, pero lo que no parece razonable es fiarse de tweets y publicaciones aleatorias de individuos que nada han tenido que ver con el incidente, o cuya autoridad no se puede determinar. Por lo tanto, hay que ejercer un buen criterio.</p>

<h2 id="es-inaceptable-que-en-españa-en-2025-sucedan-estas-cosas">Es inaceptable que en España en 2025 sucedan estas cosas</h2>

<p>Es una posición tentadora correr a decir que esta clase de incidentes no deben suceder. Y sin duda, el apagón de 2025 fue una situación sin precedentes.</p>

<p>No obstante, es muy importante tener en cuenta que nada es seguro. Los aviones, a pesar de ser el sistema de transporte más seguro con diferencia, pueden experimentar fallos durante el vuelo que pueden, en algunos casos, incluso acabar con el fallecimiento de decenas o cientos de pasajeros. Esto es terrible, y a pesar de que los aviones cuentan con múltiples sistemas redundantes, nunca existirá la fiabilidad al 100%. Todavía más impactante, quizá, es saber que la probabilidad de morir en un accidente de tráfico es significativamente más alta que en un accidente aéreo.</p>

<p>Naturalmente, el sistema de suministro de energía nacional es uno de los sistemas más críticos del país, pero que sea crítico no significa que sea completamente invulnerable.</p>

<h2 id="pedro-sánchez-aseguró-que-no-habría-apagones">Pedro Sánchez aseguró que no habría apagones</h2>

<p>Algunos individuos sin escrúpulos, desafortunadamente, están corriendo bulos como por ejemplo que “Pedro Sánchez aseguró que no habría apagones” fuera de contexto.</p>

<p>Un ejemplo muy citado es el siguiente vídeo:</p>

<div class="embed-responsive embed-responsive-16by9">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/YhTbTouSVps"></iframe>
</div>

<p>Si bien es cierto que en el vídeo Pedro Sánchez dice, efectivamente, que no habría apagones, este vídeo de 2022 tenía un contexto muy específico con respecto a la guerra de Ucrania y el corte de gas desde Rusia a Europa.</p>

<p>Pedro Sánchez indicaría en otras ocasiones cosas parecidas, pero es muy importante tener el contexto en cuenta. Sin duda, Pedro Sánchez no debería haber asegurado que no habría apagones, porque hacer afirmaciones en términos absolutos es muy peligroso. Pero decir que hay “un 99.99999999% de probabilidades de que España no sufra apagones” no suena políticamente sencillo de explicar a la ciudadanía.</p>

<p>En definitiva, no existe la seguridad absoluta. Aunque nuestras calles son seguras, siempre existe la posibilidad de que te atraquen. Aunque los aviones sean seguros, pueden colisionar y causar víctimas mortales. Aunque los ordenadores son fiables, puede haber fallos de corrupción de datos y brechas de seguridad.</p>

<p>El trabajo de un ingeniero es medir, y estimar estos peligros, y aplicar las medidas adecuadas para minimizar el riesgo lo máximo posible teniendo en cuenta la criticalidad del sistema, así como los recursos económicos de los que se dispone.</p>

<p>Nadie pensaba que España iba a sufrir un apagón generalizado, y muchos ahora podrían pensar que España es un país de segunda con mala infraestructura y baja fiabilidad. Sin embargo, si el trabajo de investigación se desarrolla como debe llevarse a cabo, se toman las medidas oportunas, y se implementan recomendaciones de la Unión Europea, esto hará el sistema eléctrico español más fiable. Esta catástrofe energética nos brinda la posibilidad de hacer un buen documento post-mortem y mejorar la fiabilidad de los sistemas eléctricos españoles, e incluso los sistemas del resto de la Unión Europea.</p>

<p>Quiero también recalcar el gran trabajo de profesionales españoles. Técnicos de centrales de generación, ingenieros civiles, y otros profesionales de la electricidad y los sistemas eléctricos. El sistema de electricidad español se recuperó al 100% en menos de 12 horas. En 2021, <a href="https://en.wikipedia.org/wiki/2021_Texas_power_crisis">Texas sufrió un apagón de magnitud similar</a> y <strong>Texas tardó más de dos semanas en recuperar el servicio eléctrico completo</strong>.</p>

<h2 id="qué-es-site-reliability-engineering">¿Qué es Site Reliability Engineering?</h2>

<p>Si has leído esto hasta el final, quizá te interesa saber qué es SRE.</p>

<p>SRE empezó con <a href="https://sre.google/">una iniciativa de Google</a>. Los sistemas informáticos de Google llegaban a ser tan complejos, y necesitaban tan alto nivel de servicio que Google decidió introducir el título de SRE.</p>

<p>Un Site Reliability Engineer generalmente tiene un fuerte conocimiento de programación, y utiliza esta experiencia para la gestión de sistemas informáticos en masa.</p>

<p>Hasta muy recientemente, existían dos grandes clases distinguidas de ingeniero experto en sistemas: ingeniero de software (software engineer), y administrador de sistemas (system administration). En entornos corporativos grandes también podría haber clasificaciones como ingeniero de redes, ingeniero de sistemas, arquitectos de sistemas y demás, que son especializaciones más específicas.</p>

<p>Site Reliability Engineering pretende unir las capacidades lógicas y de programación de un ingeniero de software y la capacidad de pensar a gran escala y con un foco en la seguridad de un administrador de sistemas.</p>

<p>Donde hace 15 años se iniciaba sesión en sistemas a través de consolas remotas, y se aplicaban cambios manuales, hoy en día los SRE efectúan cambios a través de programas y código. Los SRE también son responsables de observabilidad (observability) y a menudo hacen recomendaciones de diseño e infraestructura.</p>]]></content><author><name>León Castillejos</name></author><category term="sre" /><category term="spain" /><category term="spanish" /><summary type="html"><![CDATA[Escribo esta publicación en español porque considero que es un tema más interesante para españoles e hispanohablantes, pero la traduciré a inglés más adelante.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2025-05-01-espa-a-en-el-gran-apag-n-de/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2025-05-01-espa-a-en-el-gran-apag-n-de/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Set up your own Telegram proxy</title><link href="https://leonca.st/2024/03/24/set-up-your-own-telegram-proxy.html" rel="alternate" type="text/html" title="Set up your own Telegram proxy" /><published>2024-03-24T00:00:00+01:00</published><updated>2024-03-24T00:00:00+01:00</updated><id>https://leonca.st/2024/03/24/set-up-your-own-telegram-proxy</id><content type="html" xml:base="https://leonca.st/2024/03/24/set-up-your-own-telegram-proxy.html"><![CDATA[<p>Set up a Telegram MTProto proxy on a Raspberry Pi using Alpine Linux and Docker in a few minutes and communicate freely.</p>

<p>You will need:</p>

<ul>
  <li>A Raspberry Pi, I’m using a 3B+, but you can choose the release appropriate for the hardware</li>
  <li>A 2 GB microSD card (minimum)</li>
  <li>microSD card reader</li>
  <li>USB keyboard</li>
  <li>An HDMI cable to connect your RPi to your monitor</li>
  <li>An appropriate power supply</li>
  <li>Ethernet cable to connect to the router (WiFi is not recommended)</li>
</ul>

<p>Before we begin, a few important notes and disclaimers:</p>

<ul>
  <li>If your <strong>country blocks Telegram</strong>, setting up an MTProto Proxy using your home Internet connection with a Raspberry Pi is not going to let you access Telegram. This guide is intended to be followed by people living in countries where Telegram is not restricted. Although it is possible to set up your Raspberry Pi to use a VPN, I’m not going to go into details on how to do that in this guide.</li>
  <li>A Raspberry Pi is <strong>not a powerful device</strong>, and it is relatively easy to take it offline with a DDoS, especially if you publish your IP and port online. It is a better idea to only share your MTProto proxy details with trusted friends and family members.</li>
  <li>I am using a Raspberry Pi 3 Model B+, but instructions are fairly similar for other ARM devices, including Orange Pi or Banana Pi, or newer Raspberry Pi models, and also for Intel-based NUCs. For a small proxy to be used by 5-10 people, you don’t need a powerful computer. Anything manufactured in the last 10 years with at least 1 GB of RAM should be sufficient. Including old office computers or laptops with damaged screens (you can connect them to an external monitor).</li>
  <li>These instructions are with <strong>Alpine Linux</strong>. I think it is much simpler, faster to install, and more efficient to use Alpine Linux for this purpose. With other distributions like Ubuntu or Debian, network configuration, and Docker installation is a bit different, so consult the respective installation manuals if you choose to use a different distribution.</li>
  <li>You need to know <strong>how to open ports</strong> with your ISP. Instructions vary, but generally, you can Google something like “How to open ports <your ISP="" name="">”. Sometimes, instructions also differ based on your router model. If your ISP provides access to the router web interface, googling the manual of the specific model of your port will usually work. This also assumes your connection is not behind a [CGNAT](https://en.wikipedia.org/wiki/Carrier-grade_NAT), where opening ports is a much more complicated process.</your></li>
  <li>In addition to opening ports, most home ISPs work with <strong>dynamic IP assignment</strong>. This means your IP might change every time you reboot your router, or it could change every few days too. The link you will generate later in the article will no longer work if your IP changes. A way to resolve this is to use a <strong>dynamic DNS service</strong> like no-ip or Dyn. This will create a hostname that points to your current IP. It is your responsibility to keep this hostname up to date when your IP changes, so consult their documentation for more information.</li>
</ul>

<h2 id="preparation">Preparation</h2>

<p>Grab an Alpine Linux image for Raspberry Pi from <a href="https://www.alpinelinux.org/downloads/">https://www.alpinelinux.org/downloads/</a>. I selected the aarch64 architecture edition in the img.gz format for my Raspberry Pi 3B+.</p>

<p>Insert an microSD card into your computer’s microSD reader. The easiest method to flash the microSD card is to use Raspberry Pi Imager: <a href="https://www.raspberrypi.com/software/">https://www.raspberrypi.com/software/</a>. There are downloads for macOS, Windows, and Ubuntu. On many Linux-based operating systems that support Flatpak, like Fedora, you can find it in your software center by searching “raspberry”.</p>

<p><img src="https://leonca.st/assets/images/2024-03-24-set-up-your-own-telegram-proxy/rpi_software.png" alt="Software center screenshot" /></p>

<ol>
  <li>
    <p>Select your model, the image you have downloaded (note the Raspberry Pi Imager software does not provide Alpine Linux for easy download, but you can simply choose your <code class="language-plaintext highlighter-rouge">.img.gz</code> regardless), and the microSD card to write it to.</p>
  </li>
  <li>
    <p>When asked to customise the OS settings like username or network details, <strong>skip this step</strong>. Alpine Linux cannot be customised using this tool.</p>
  </li>
</ol>

<p>Insert the prepared microSD card into your Raspberry Pi, connect it to a monitor using an HDMI cable, attach a USB keyboard (a mouse is not necessary), and then connect the power supply. Your Raspberry Pi should automatically boot to the Alpine Linux login screen.</p>

<h2 id="installing-alpine-linux">Installing Alpine Linux</h2>

<p>Log in with <code class="language-plaintext highlighter-rouge">root</code> . You don’t need to type a password. Then, type <code class="language-plaintext highlighter-rouge">setup-alpine</code> and follow the installer questions.</p>

<p>For hostname, you can enter whatever you prefer, it doesn’t have to be equal to the public hostname.</p>

<p>For network configuration (Ethernet recommended), your home router will provide DHCP, but this is a bad idea to use long-term, because if your LAN IP changes (which can happen every few hours or days), the port forwarding you set up in your router will stop working. It is recommended to manually set an IP outside the DHCP pool, to avoid collisions.</p>

<p>Alternatively, some routers offer a MAC to IP pairing that makes the DHCP server remember a host’s IP given its hardware MAC address. In this case, select DHCP here. In any case, your RPi IP is important. Write it down as you will be using it again soon.</p>

<ol>
  <li>To open a new terminal without cancelling the installer process, press <code class="language-plaintext highlighter-rouge">Ctrl + Alt + F2</code>.</li>
  <li>Run <code class="language-plaintext highlighter-rouge">ip a show eth0</code> to find out the MAC address, then you can add this MAC to an IP of your choice in your router settings. This is usually called “DHCP Static IP assignment”.</li>
  <li>You can return to the installer by pressing <code class="language-plaintext highlighter-rouge">Ctrl + Alt + F1</code>.</li>
</ol>

<p>For timezone I chose <code class="language-plaintext highlighter-rouge">Europe/Amsterdam</code>.</p>

<p>For NTP client, the default is sufficient, press enter to accept the default choice.</p>

<p>For mirrors, entering <code class="language-plaintext highlighter-rouge">f</code> will rank and find the fastest.</p>

<p>No need to set up a user, although using <code class="language-plaintext highlighter-rouge">root</code> for everyday activities is discouraged, this will be exclusively a MTProto Proxy box that you will set up once and forget about it.</p>

<p>If you would like to access this Raspberry Pi remotely (without the need for a video or USB cable), then setting up SSH is a good idea. Otherwise, disabling SSH is better from a safety perspective, especially considering this host will be exposed to the internet.</p>

<p>If you want to enable SSH, the easiest is to set up a long and complex password that you will remember. But it is a best practice to use SSH Keys. This is outside the scope of this article, as there are thousands of articles on how to configure an SSH server to use SSH Keys. However, you will likely need to set up password access at least temporarily. To this end, when asked about allowing root access, enter <code class="language-plaintext highlighter-rouge">yes</code>. Otherwise <code class="language-plaintext highlighter-rouge">prohibit-password</code> will only allow access if SSH Keys have been configured.</p>

<p>Because the Raspberry Pi only has one microSD card slot and no onboard storage, you will have to overwrite the microSD card. This is fine. It will suggest you to try using the boot media. Otherwise, if you reboot the Raspberry Pi or it loses power momentarily, all settings will be lost.</p>

<p>It will look something like <code class="language-plaintext highlighter-rouge">/media/mmcblk0</code>. Reply yes to using this boot media, and then type <code class="language-plaintext highlighter-rouge">mmcblk0</code> when the installer asks what disk to use.</p>

<p>For installation mode, <code class="language-plaintext highlighter-rouge">sys</code> is the easiest. For encrypted installs or more advanced configurations, please consult the Alpine Linux installation manual.</p>

<h1 id="finally-setting-up-your-proxy">Finally, setting up your proxy</h1>

<p>Reboot, and enter <code class="language-plaintext highlighter-rouge">root</code> as user, and your chosen password.</p>

<p>Install some basic tools, run:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apk add vim git nano
</code></pre></div></div>

<p>You can choose another text editor, only <code class="language-plaintext highlighter-rouge">vi</code> is available by default, but nano is recommended for beginners.</p>

<p>To install Docker, we need to enable Community repositories. Edit <code class="language-plaintext highlighter-rouge">/etc/apk/repositories</code>. I like using Vim. Simply move the cursor to the <code class="language-plaintext highlighter-rouge">#</code> in front of the community repository URL, and press <code class="language-plaintext highlighter-rouge">x</code> to delete a single character. To save and quit, type <code class="language-plaintext highlighter-rouge">:wq</code>.</p>

<p>My repository list looks like this after the changes:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#/media/mmcblk0/apks
http://alpine.mirror.wearetriple.com/v3.19/main
http://alpine.mirror.wearetriple.com/v3.19/community
</code></pre></div></div>

<p>Install Docker:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apk update &amp;&amp; apk add docker
</code></pre></div></div>

<p>Let’s add Docker to startup services:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rc-update add docker
</code></pre></div></div>

<p>Then, start Docker with:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rc-service docker start
</code></pre></div></div>

<p>Now, generate a secret by running:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run --rm nineseconds/mtg:2 generate-secret tgproxy.0x7.io &gt; config.toml
</code></pre></div></div>

<p>You can choose another domain name that you prefer, there’s more details in the documentation: <a href="https://github.com/9seconds/mtg">https://github.com/9seconds/mtg</a>. You have written a secret to <code class="language-plaintext highlighter-rouge">config.toml</code>. Now you can edit this <code class="language-plaintext highlighter-rouge">config.toml</code> and edit it to look as follows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>secret = "Y0uRS3cr37"
bind-to = "0.0.0.0:7104"
</code></pre></div></div>

<p>The secret will already be in the file, simply surround it with double quotes, and you can choose another port if you prefer. I recommend setting the same port for the configuration, container, host, and forward in the router, for simplicity reasons.</p>

<p>Finally, Start your Docker container:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run -d -v $PWD/config.toml:/config.toml -p 7104:7104 --name mtg-proxy --restart=unless-stopped nineseconds/mtg:2
</code></pre></div></div>

<p>Note the “unless-stopped” part. This means that, as long as your Docker service is set to start with the system, your proxy container will also start automatically.</p>

<p>If everything went well, you should now be able to connect to your MTProto Proxy through any Telegram client. Print the configuration:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker exec mtg-proxy /mtg access /config.toml
</code></pre></div></div>

<p>If you are connected via SSH, you can now copy this configuration and keep it safe to give to friends and family. Finally, forward port <code class="language-plaintext highlighter-rouge">7104</code> in your router settings to port <code class="language-plaintext highlighter-rouge">7104</code> on your Raspberry Pi IP (refer to the top of the article on setting up a static IP or configuring DHCP).</p>

<p>If you would like to verify everything is working appropriately, reboot your Raspberry Pi by typing <code class="language-plaintext highlighter-rouge">reboot</code>, and if you added your proxy to Telegram, it should connect successfully after a few seconds.</p>

<p>If you have set up a dynamic DNS service, you can replace your IP address from the links generated with your dynamic DNS hostname.</p>

<p><strong>Note</strong>: If you face any problems setting up your proxy, please contact me over e-mail and I’d be happy to help. I speak Spanish and English. Find my e-mail on this website’s sidebar!</p>

<p>If you need a Telegram proxy, I set up one <a href="tg://proxy?port=6122&amp;secret=7kc85dSVjrX5aMh2gKI4VKBnb29nbGUuY29t&amp;server=tgproxy.0x7.io">here</a>. It might not last forever, but if it’s available, feel free to use it! Simply click that link, or add it to Telegram with the following details:</p>

<ul>
  <li>Protocol: <code class="language-plaintext highlighter-rouge">MTPROTO</code></li>
  <li>Hostname: <code class="language-plaintext highlighter-rouge">tgproxy.0x7.io</code></li>
  <li>Port: <code class="language-plaintext highlighter-rouge">6122</code></li>
  <li>Secret: <code class="language-plaintext highlighter-rouge">7kc85dSVjrX5aMh2gKI4VKBnb29nbGUuY29t</code></li>
</ul>

<p><img src="https://leonca.st/assets/images/2024-03-24-set-up-your-own-telegram-proxy/tgproxy_screenshot.png" alt="Telegram proxy settings screenshot" /></p>]]></content><author><name>León Castillejos</name></author><category term="Telegram" /><category term="proxy" /><category term="censorship-evasion" /><category term="writeup" /><category term="Docker" /><category term="arm" /><category term="raspberry-pi" /><category term="alpine-linux" /><summary type="html"><![CDATA[Set up a Telegram MTProto proxy on a Raspberry Pi using Alpine Linux and Docker in a few minutes and communicate freely.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2024-03-24-set-up-your-own-telegram-proxy/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2024-03-24-set-up-your-own-telegram-proxy/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">When the “better coding style” is the wrong style</title><link href="https://leonca.st/2023/08/16/when-the-right-choice-is-the.html" rel="alternate" type="text/html" title="When the “better coding style” is the wrong style" /><published>2023-08-16T00:00:00+02:00</published><updated>2023-08-16T00:00:00+02:00</updated><id>https://leonca.st/2023/08/16/when-the-right-choice-is-the</id><content type="html" xml:base="https://leonca.st/2023/08/16/when-the-right-choice-is-the.html"><![CDATA[<p>Code is always read more than it is written or debugged. It is of the utmost importance that code is optimised for readability. And in this regard, it must be written such that the largest amount of people possible can read and understand it as quickly as possible.</p>

<p>The reason the title of this post is so peculiar is that there exists a set of developers who are convinced they possess the “correct way” of writing code, and believe their style to be superior and objectively correct. I would like to illustrate why this is rarely the case.</p>

<p>It takes a lot of humility and introspection to accept community conventions. Of course, there are different coding styles and guides, and I find it is often a matter of taste than a verifiable truth. Having flexibility in terms of where to place the braces, variable and function naming conventions, and other style choices is sometimes beneficial, but almost always harmful. We all have our own preferred way of writing code, and this will sometimes cause conflict in teams, where different people have conflicting opinions and views on what code should look like.</p>

<p>I will argue that keeping in line with coding styles and standards is important even for your personal projects on which you work alone, as this allows you to get used to the conventions of the particular language or framework. This is important, because often, each community will have different opinions and styles of code. You can see this in Rubocop for Ruby, Black for Python, or <code class="language-plaintext highlighter-rouge">go fmt</code>. The best guides will homogenise coding style for an entire language, or even an entire company. And, of course, if there are coding style guides out there, it’s better to follow those instead of creating guides from scratch. It may be difficult to follow these standards at first, as there is a significant learning curve, and you may disagree with the format of the finished code.</p>

<p>The primary objective of coding conventions is to establish a harmonious and legible codebase. These guidelines expedite the onboarding process for new developers and streamline ongoing maintenance efforts. While some of these conventions may appear to be arbitrary at first glance, adhering to them significantly fosters a collaborative environment in software development, ensuring that all team members can effortlessly navigate and contribute to the project.</p>

<p>Many of these coding guides will have straightforward integrations with your favourite code editor.
The best approach is to have it format on save, this avoids having to run it manually, and committing potentially non-compliant code to your team’s repository. In a team, you should also set git hooks that complain if your code is not formatted as required.</p>

<p>Some examples of conventions:</p>

<ul>
  <li>Black (Python):
    <ul>
      <li>Black enforces a consistent line length (default is 88 characters), which helps to keep code readable on any screen.</li>
      <li>It formats code in a way that makes diffs easier to read in version control, which is important for understanding changes over time.</li>
    </ul>
  </li>
  <li>Rubocop (Ruby)
    <ul>
      <li>Rubocop enforces naming conventions, which helps to keep code self-documenting and makes it easier for other developers to understand the purpose of different parts of the code.</li>
      <li>It checks for redundant code and suggests more concise ways of expressing the same logic, promoting cleaner and more efficient code.</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">go fmt</code>
    <ul>
      <li>go fmt uses tabs for indentation and spaces for alignment, ensuring a consistent look of the code across various editors and viewers.</li>
      <li>It standardizes the ordering of imports, which can help developers quickly understand the dependencies of a file.</li>
    </ul>
  </li>
</ul>

<p>While those seem like sensible choices, there are thousands of choices any individual developer can make in a codebase. For example, <a href="https://en.wikipedia.org/wiki/Indentation_style">indentation styles</a>, <a href="https://en.wikipedia.org/wiki/Naming_convention_(programming)">naming conventions</a>, <a href="https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html">Apache Maven directory layout conventions</a>, <a href="https://gist.github.com/tracker1/59f2c13044315f88bee9">Node.js directory layout conventions</a> and much more. Like with most things, everyone has their favourite style.</p>]]></content><author><name>León Castillejos</name></author><category term="rant" /><category term="leadership" /><category term="productivity" /><category term="career" /><summary type="html"><![CDATA[Code is always read more than it is written or debugged. It is of the utmost importance that code is optimised for readability. And in this regard, it must be written such that the largest amount of people possible can read and understand it as quickly as possible.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2023-08-13-when-the-right-choice-is-the/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2023-08-13-when-the-right-choice-is-the/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Lessons from AWS: One-way and Two-way Doors</title><link href="https://leonca.st/2022/07/14/lessons-from-aws-one-way-and-two-way.html" rel="alternate" type="text/html" title="Lessons from AWS: One-way and Two-way Doors" /><published>2022-07-14T00:00:00+02:00</published><updated>2022-07-14T00:00:00+02:00</updated><id>https://leonca.st/2022/07/14/lessons-from-aws-one-way-and-two-way</id><content type="html" xml:base="https://leonca.st/2022/07/14/lessons-from-aws-one-way-and-two-way.html"><![CDATA[<p>Amazon, like possibly all big companies, is full of wisdom, and I was able to experience this firsthand during my time there.</p>

<p>I was not able to appreciate it back then, but every passing month I start to apply the knowledge and the lessons I learned there.</p>

<p>The one-way and two-way door lesson is one of choices and actions. You can read the full letter from Jeff Bezos to Amazon shareholders that started this <a href="https://www.sec.gov/Archives/edgar/data/1018724/000119312516530910/d168744dex991.htm">here</a>.</p>

<p>One-way doors are those actions that are irreversible, or very difficult to reverse. Examples include selling your company, or big rebranding operations where you change the name of the company. One-way doors often either carry a lot of momentum, or may require that, once the decision is taken, the company assumes it and moves forward with the choice.</p>

<p>Two-way doors are actions that are easy to reverse. These actions can sometimes be seen everywhere throughout the standard software development lifecycle. From <a href="https://en.wikipedia.org/wiki/A/B_testing">A/B tests</a>, <a href="https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/bluegreen-deployments.html">blue/green deployments</a>, experiments (like what <a href="https://hbr.org/2020/03/building-a-culture-of-experimentationa">Booking.com</a> does) and so on. These decisions can be quickly reversed, and in the case of experiments, they’re deployed to a small fraction of their customer base to measure their impact. This is a great way to ensure you are building a great product iteratively.</p>

<p>The theory is easy enough, but actually identifying one-way and two-way doors in real-life situations is a much more difficult task. Often times, these decisions will not be as clear-cut as the examples given above. However, this will come to you naturally with practice. Being able to differentiate between one-way and two-way doors will make you a better thinker, philosopher, and leader. And if you are a software engineer, you will be able to take decisions in a much more agile way, as you will be able to quickly measure and understand the impact of your actions.</p>

<p>When it refers to businesses, banks used to be very slow-moving, and hesitant to adopt new technologies and systems, relying mostly on one-way doors, whereas startups used to be hectic and chaotic, treating everything as a two-way door, but it seems that with time, regulations have forced banks to adopt more modern technologies, like what <a href="https://ec.europa.eu/info/law/payment-services-psd-2-directive-eu-2015-2366_en">PSD2</a> outlines, for security reasons, whereas startups are starting to build a resiliency culture possibly borrowed from banks, for their own survival.</p>

<p>Naturally, all of this is highly subjective, and often depends on the risk tolerance of the individual taking the decision. Sometimes, losing a customer target demographic is not a one-way door if it can be regained back, for example, when rolling out controversial marketing campaigns.</p>

<p>With that being said, it is also sometimes possible to make what would be one-way doors suddenly become two-way. Precisely, experiments and other highly specific business intelligence can inform your decisions, and either adapt changes, or inform you on what your customer base is more tolerant of, thus making it become two-way, as certain demographics are more accepting of change than others.</p>

<p>I encourage you, dear reader, to think about whether the decision you are about to take constitutes a one-way or a two-way door. If it turns out to be a two-way door, you will be able to take the decision without much <a href="https://en.wikipedia.org/wiki/Decision_fatigue">decision fatigue</a>. Simply commit to it, and undo it if you don’t get the expected results. There is no need to overanalyse every decision, which frees up valuable mental resources for the one-way doors that you will find in the future.</p>]]></content><author><name>León Castillejos</name></author><category term="aws" /><category term="amazon" /><category term="opinion" /><category term="career" /><category term="leadership" /><summary type="html"><![CDATA[Amazon, like possibly all big companies, is full of wisdom, and I was able to experience this firsthand during my time there.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2022-07-14-lessons-from-aws-one-way-and-two-way/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2022-07-14-lessons-from-aws-one-way-and-two-way/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">scp and rsync reference</title><link href="https://leonca.st/2022/04/10/scp-and-rsync-reference.html" rel="alternate" type="text/html" title="scp and rsync reference" /><published>2022-04-10T00:00:00+02:00</published><updated>2022-04-10T00:00:00+02:00</updated><id>https://leonca.st/2022/04/10/scp-and-rsync-reference</id><content type="html" xml:base="https://leonca.st/2022/04/10/scp-and-rsync-reference.html"><![CDATA[<p>Similar to my previous post on SSH tunnelling, this post is a quick reference for typical rsync and scp usage.</p>

<h2 id="scp">scp</h2>

<p><code class="language-plaintext highlighter-rouge">scp</code>'s syntax is as follows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>scp [options] source target
</code></pre></div></div>

<p>Where options is any scp argument, and source and target can be either network hosts (hostnames or IP addresses), or directories. For specifying the directory of a remote host, you append a colon after the hostname, and type the path. For example: <code class="language-plaintext highlighter-rouge">host:/etc/mypath</code>.</p>

<p>Note that scp obeys any configuration specified on <code class="language-plaintext highlighter-rouge">~/.ssh/config</code> or <code class="language-plaintext highlighter-rouge">/etc/ssh/ssh_config</code>. For example, if you defined a host <code class="language-plaintext highlighter-rouge">test123</code> with a username, and a port, you can use “test123” in place of the host, without needing to use the full syntax like <code class="language-plaintext highlighter-rouge">scp -P 1234 user@test123 {...}</code>.</p>

<h3 id="basic-options">Basic options</h3>

<ul>
  <li>-P is used for specifying the port, in case the remote SSH host is using a port other than 22</li>
  <li>-v turns on verbose mode</li>
  <li>-q turns on quiet mode</li>
  <li>-r enables recursively copying entire directories</li>
  <li>-o specifies SSH options in the usual format</li>
  <li>-i specifies an identity file</li>
  <li>-C enables compression</li>
</ul>

<h3 id="using-scp">Using scp</h3>

<p>Here are three examples. Any of the flags specified above will work in these examples.</p>

<h4 id="copy-a-local-file-to-a-remote-host">Copy a local file to a remote host</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>scp /etc/mypath/file remote_host:/etc/somepath
</code></pre></div></div>

<p>This copies the local file <code class="language-plaintext highlighter-rouge">/etc/mypath/file</code> into <code class="language-plaintext highlighter-rouge">remote_host</code> under <code class="language-plaintext highlighter-rouge">/etc/somepath/file</code>.</p>

<h4 id="copy-a-remote-file-from-a-remote-host">Copy a remote file from a remote host</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>scp remote_host:/etc/mypath/file /etc/somepath
</code></pre></div></div>

<p>This copies the remote file <code class="language-plaintext highlighter-rouge">/etc/mypath/file</code> from <code class="language-plaintext highlighter-rouge">remote_host</code> into the local filesystem <code class="language-plaintext highlighter-rouge">/etc/somepath/file</code>.</p>

<h4 id="copy-an-entire-directory-from-a-remote-host-to-the-local-filesystem">Copy an entire directory from a remote host to the local filesystem</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>scp -r remote_host:/etc/mypath /etc/remote_host_dir/
</code></pre></div></div>

<h2 id="rsync">rsync</h2>

<p><code class="language-plaintext highlighter-rouge">rsync</code>'s syntax is as follows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rsync [options] source target
</code></pre></div></div>

<p>Where options is any rsync argument, and source and target work similarly to scp as explained above.</p>

<p>Again, just like scp, rsync follows SSH custom config files.</p>

<h3 id="basic-options-1">Basic options</h3>

<ul>
  <li>-v enables verbose mode</li>
  <li>-q turns on quiet mode</li>
  <li>-r enables recursively copying entire directories</li>
  <li>-n execute a “dry run”, that is, run once to print changes, then exit without transferring anything</li>
  <li>-P shows progress during transfer</li>
  <li>-a enables attribute preservation</li>
  <li>-z enables compression</li>
  <li>-c enables checksum checking, which tells rsyn what files to skip based on a checksum instead of modification time and size</li>
  <li>-h enables human-readable number format</li>
  <li>–delete files that have been deleted from the source since the last run, useful for backing up, this effectively turns rsync into a sync tool, without which it is just a file transfer tool with checksums and directory diff transfers</li>
</ul>

<h3 id="using-rsync">Using rsync</h3>

<h4 id="sync-from-the-local-filesystem-to-a-remote-host">Sync from the local filesystem to a remote host</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rsync -r /etc/mypath remote_host:/etc/somepath
</code></pre></div></div>

<p>This copies the <code class="language-plaintext highlighter-rouge">/etc/mypath</code> directory and all its files and subdirectories to the remote <code class="language-plaintext highlighter-rouge">/etc/somepath</code> directory.</p>

<h4 id="sync-a-remote-host-to-the-local-filesystem">Sync a remote host to the local filesystem</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rsync -r remote_host:/etc/mypath /etc/somepath
</code></pre></div></div>

<p>This copies the remote <code class="language-plaintext highlighter-rouge">/etc/mypath</code> directory on <code class="language-plaintext highlighter-rouge">remote_host</code> to <code class="language-plaintext highlighter-rouge">/etc/somepath</code> on the local filesystem.</p>

<h4 id="practical-example-downloading-a-remote-directory-with-recursive-verbose-checksum-human-readable-and-progress-arguments-as-well-as-deleting-files-that-no-longer-exist-on-the-source">Practical example: downloading a remote directory with recursive, verbose, checksum, human-readable, and progress arguments, as well as deleting files that no longer exist on the source</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rsync -rvchP --delete nas.example.com:/mnt/backup /mnt/remotebackup/storage
</code></pre></div></div>

<h2 id="wrapping-up">Wrapping up</h2>

<p>scp and rsync are powerful tools that make use of SSH to quickly transfer files and even entire directories.</p>

<p>I like using scp for one-off single file transfer, whereas rsync has many more options you can <a href="https://linux.die.net/man/1/rsync">read in the manual</a>, making it an ideal candidate for backup cronjobs.</p>]]></content><author><name>León Castillejos</name></author><category term="tip" /><summary type="html"><![CDATA[Similar to my previous post on SSH tunnelling, this post is a quick reference for typical rsync and scp usage.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2022-04-10-scp-and-rsync-reference/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2022-04-10-scp-and-rsync-reference/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Breaking bad habits thanks to dark patterns</title><link href="https://leonca.st/2022/02/20/breaking-bad-habits-thanks-to-dark.html" rel="alternate" type="text/html" title="Breaking bad habits thanks to dark patterns" /><published>2022-02-20T00:00:00+01:00</published><updated>2022-02-20T00:00:00+01:00</updated><id>https://leonca.st/2022/02/20/breaking-bad-habits-thanks-to-dark</id><content type="html" xml:base="https://leonca.st/2022/02/20/breaking-bad-habits-thanks-to-dark.html"><![CDATA[<p>Most digital products and services are optimised to generate as much revenue as possible. An app will only generate revenue for the creator for as long as you keep actively engaging with it. Therefore, one of the most important digital metrics is what’s called “user retention”. This is the percentage of users that return to the app in a specific timeframe.</p>

<p>While the calculations are not something I find particularly interesting, it is important to understand that the design for most Internet products and services is driven by this, among other factors. These are UX research topics that are continuously being refined and expanded upon.</p>

<h1 id="increased-friction">Increased friction</h1>

<p>To this end, I’ve been observing an annoying trend of increasing friction in all websites for the last few years. See here:</p>

<p><img src="https://leonca.st/assets/images/2022-02-20-breaking-bad-habits-thanks-to-dark/1.jpg" alt="Dark patterns" /></p>

<p>If you use the Internet frequently, you may be accustomed to these dialogs that infest the web. Every website wants you to sign up for their newsletter, accept their cookies, and create an account with them.</p>

<h1 id="dark-patterns">Dark patterns</h1>

<p>It is easy to conclude why the web is designed like this. It is in these companies’ best interests for you to create an account and always be logged in so they can:</p>

<ul>
  <li>Build an accurate profile of you to target you with tailored ads, making more likely for you to click on them.</li>
  <li>Send you notifications and reminders to get back into the website.</li>
  <li>Gamify your experience, giving you virtual trophies and achievements.</li>
</ul>

<h1 id="improving-your-internet-browsing-experience">Improving your Internet browsing experience</h1>

<p>As an aside: I can’t recommend <a href="https://www.no-thanks-extension.com">“No, Thanks.”</a> and <a href="https://www.i-dont-care-about-cookies.eu">“I don’t care about cookies”</a> enough, they’re both excellent extensions created maintained by Daniel Kladnik, who believes the web should have fewer annoyances, pop-ups, dialogs, and modals.</p>

<h1 id="impulsive-behaviour">Impulsive behaviour</h1>

<p>After having read multiple books on the subjects of attention and effective work, I am fully convinced that being able to <strong>be mindful and pay attention to the things that matter is one of the most important skills in this age of Internet-connected attention-draining devices</strong>. Mindfulness improves many aspects of your life: From work to interpersonal relationships and even hobbies, because you will be more effective, and have more time to be able to enjoy your favourite activities outside work.</p>

<p>But it is quite clear that, while our time on this planet is quite limited on an individual level, companies will continue to aggressively fight each other for your attention.</p>

<h1 id="my-criteria-for-digital-services-or-products">My criteria for digital services or products</h1>

<ul>
  <li>Do not allow the application to send me notifications unless it is justified. For example, my e-mail app, my bank, or other security applications should be able to send me notifications, but under no circumstances can these applications send me promotions or unsolicited messages. If this is the case, I will either revoke their notification permissions, or fully uninstall them. In particular, social apps are never allowed notifications except in the case of direct messages (no likes, no favourites, no reposts, no photo tags, nothing like that) and only if I use the app less than once every week or two weeks. I use Telegram daily, so Telegram has no notification permissions on the OS level, but I only use Signal a handful of times every month, so revoking notification permissions here would mean I would possibly miss messages from my contacts because checking Signal is not part of my routine.</li>
  <li>Do not install the native smartphone app unless it is a benefit for me. In particular, if installing the application allows me to have increased security, such as two-factor authentication codes, or if I need to upload pictures taken with my phone’s camera, and so on.</li>
</ul>

<p>Because the native app is not installed, it is often the case that I will tap a link on, say, my e-mail app, that would open the app, but opens a webview instead. In this webview, cookies are sometimes not preserved, and that’s when the trouble starts, because the website will ask me to install the app and/or sign in, which is particularly annoying when you want to simply read an article. It is even more annoying if you turn on two-factor authentication, as that’s an extra step you have to take. Often, after signing in, it will return you to the homepage instead of the article that you wanted to read, so you have to close the webview, and tap the link again to finally read the article… Do you see where I’m coming from? Friction. There’s a lot of friction on the modern web. However, there are ways you can leverage this to your advantage.</p>

<h1 id="why-is-this-such-a-big-deal">Why is this such a big deal?</h1>

<p>If I had to condense the <a href="https://jamesclear.com/atomic-habits">“Atomic Habits” book by James Clear</a> as much as possible, it would go as follows:</p>

<blockquote>
  <p>“How to Create a Good Habit
The 1st law (Cue): Make it obvious.
The 2nd law (Craving): Make it attractive.
The 3rd law (Response): Make it easy.
The 4th law (Reward): Make it satisfying.”</p>
</blockquote>

<p>With these laws in mind, let’s analyse a typical flow for interacting with one of these websites nowadays:</p>

<ul>
  <li>Law 1: Cue. Checks out, because the website will send you a message, either via smartphone push notifications or e-mail, in regards to someone replying to you, interacting with your content, or simply content posted by other users.</li>
  <li>Law 2: Craving. Well, you know if you tap the link, you will be able to read what was mentioned, and possibly interact with other users, or read other content. All the content at your fingertips!</li>
  <li>Law 4: Reward. This checks out too. Simply interacting with others, even negatively, for defending our ideas, is proven to have positive psychological effects. Occasionally, websites like Reddit or Hacker News use karma point systems that increase the social status on your website as other people like your comments and posts. Some sites go as far as giving you virtual trophies and achievements to gamify your experience further.</li>
</ul>

<p>Did you notice I didn’t mention the third law? That is because all these websites have a serious shortcoming here. And this is by design: As the sites are optimised to gather as much of your data as possible, they’ll try to get you to sign up, give up your email address, your real name, perhaps your phone number, sometimes also ask for permission to read your contacts, as Twitter does. And this is exactly where you can break this perverse psychological manipulation. Habits will not form if they don’t align with the 4 laws, so you can go out of your way to make it as difficult as possible by using the methods I use, like not installing the smartphone apps, turning on two-factor authentication, and adding as much friction to the process as possible. Another good tip is to make use of something like <a href="https://simplelogin.io">SimpleLogin</a> or <a href="https://www.fastmail.help/hc/en-us/articles/4406536368911-Masked-Email">FastMail masked addresses</a>, such that you save these emails on your password manager, instead of remembering the username, and you make it even more difficult to log in by accident or out of habit.</p>

<h1 id="in-summary">In summary</h1>

<p>The more these websites will continue to be designed for information gathering, the more vulnerable they are to added sign-in and sign-up friction, and the more you can leverage this to your advantage to break addictive habits.</p>

<p>Try it today, and let me know how it goes! Remember, the time you spend watching TikTok videos or engaging in pointless Twitter debates is time you never get back while the platforms profit.</p>]]></content><author><name>León Castillejos</name></author><category term="tip" /><category term="opinion" /><category term="productivity" /><summary type="html"><![CDATA[Most digital products and services are optimised to generate as much revenue as possible. An app will only generate revenue for the creator for as long as you keep actively engaging with it. Therefore, one of the most important digital metrics is what’s called “user retention”. This is the percentage of users that return to the app in a specific timeframe.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2022-02-20-breaking-bad-habits-thanks-to-dark/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2022-02-20-breaking-bad-habits-thanks-to-dark/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">AWS CloudFormation: Appending elements to lists</title><link href="https://leonca.st/2021/03/03/cloudformation-appending-elements-to-lists.html" rel="alternate" type="text/html" title="AWS CloudFormation: Appending elements to lists" /><published>2021-03-03T00:00:00+01:00</published><updated>2021-03-03T00:00:00+01:00</updated><id>https://leonca.st/2021/03/03/cloudformation-appending-elements-to-lists</id><content type="html" xml:base="https://leonca.st/2021/03/03/cloudformation-appending-elements-to-lists.html"><![CDATA[<p>Short reference on manipulating CloudFormation lists.</p>

<p>In order to add individual elements to a list, we will need to make use of the functions <code class="language-plaintext highlighter-rouge">!Split</code>, <code class="language-plaintext highlighter-rouge">!Sub</code> and <code class="language-plaintext highlighter-rouge">!Join</code>.</p>

<p>First, <code class="language-plaintext highlighter-rouge">!Split</code>: takes a string and makes a list out of it, by placing each element separated by the specified delimiter. It takes two parameters: A <strong>delimiter</strong> (in our case, a <em>single comma</em>, and a <strong>source string</strong> (for which we make use of the <code class="language-plaintext highlighter-rouge">!Sub</code> function). In the above case, we are using this function to pass a list of SecurityGroups, that we make by creating a comma-separated string.</p>

<p>The <code class="language-plaintext highlighter-rouge">!Sub</code> function will substitute variables in an input string with specified values. We use this to construct a comma-separated string of elements. It takes two parameters: a <strong>string</strong> to output, and the <strong>substitution</strong> to apply. In this case, the output we will get is <code class="language-plaintext highlighter-rouge">a,b</code>, where <code class="language-plaintext highlighter-rouge">a</code> is a string that we will construct by splitting a list using <code class="language-plaintext highlighter-rouge">!Join</code>, using the CloudFormation parameters, and <code class="language-plaintext highlighter-rouge">b</code> is the security group built within the CloudFormation template itself.</p>

<p>Lastly, the <code class="language-plaintext highlighter-rouge">!Join</code> function does the opposite of <code class="language-plaintext highlighter-rouge">!Split</code>: It takes a list of elements, and outputs a string with the specified delimiter.</p>

<p>Example template:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">AWSTemplateFormatVersion</span><span class="pi">:</span> <span class="s2">"</span><span class="s">2010-09-09"</span>
<span class="na">Description</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Appending</span><span class="nv"> </span><span class="s">elements</span><span class="nv"> </span><span class="s">to</span><span class="nv"> </span><span class="s">a</span><span class="nv"> </span><span class="s">list</span><span class="nv"> </span><span class="s">in</span><span class="nv"> </span><span class="s">CloudFormation"</span>

<span class="na">Parameters</span><span class="pi">:</span>
  <span class="na">MyVPC</span><span class="pi">:</span>
    <span class="na">Type</span><span class="pi">:</span> <span class="s2">"</span><span class="s">AWS::EC2::VPC::Id"</span>
  <span class="na">MySubnetList</span><span class="pi">:</span>
    <span class="na">Type</span><span class="pi">:</span> <span class="s2">"</span><span class="s">List&lt;AWS::EC2::Subnet::Id&gt;"</span>
  <span class="na">ExistingSG</span><span class="pi">:</span>
    <span class="na">Type</span><span class="pi">:</span> <span class="s2">"</span><span class="s">List&lt;AWS::EC2::SecurityGroup::Id&gt;"</span>

<span class="na">Resources</span><span class="pi">:</span>
  <span class="na">NewALB</span><span class="pi">:</span>
    <span class="na">Type</span><span class="pi">:</span> <span class="s2">"</span><span class="s">AWS::ElasticLoadBalancingV2::LoadBalancer"</span>
    <span class="na">Properties</span><span class="pi">:</span>
      <span class="na">Name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">My</span><span class="nv"> </span><span class="s">new</span><span class="nv"> </span><span class="s">ALB"</span>
      <span class="na">Scheme</span><span class="pi">:</span> <span class="s2">"</span><span class="s">internal"</span>
      <span class="na">SecurityGroups</span><span class="pi">:</span> <span class="kt">!Split</span>
        <span class="pi">-</span> <span class="s2">"</span><span class="s">,"</span>
        <span class="pi">-</span> <span class="kt">!Sub</span>
          <span class="pi">-</span> <span class="s2">"</span><span class="s">${existingSgToString},${NewSG}"</span>
          <span class="pi">-</span> <span class="na">existingSgToString</span><span class="pi">:</span> <span class="kt">!Join</span> <span class="pi">[</span><span class="s2">"</span><span class="s">,"</span><span class="pi">,</span><span class="kt">!Ref</span> <span class="s2">"</span><span class="s">ExistingSG"</span><span class="pi">]</span>
      <span class="na">Subnets</span><span class="pi">:</span> <span class="kt">!Ref</span> <span class="s2">"</span><span class="s">MySubnetList"</span>
  <span class="na">NewSG</span><span class="pi">:</span>
    <span class="na">Type</span><span class="pi">:</span> <span class="s2">"</span><span class="s">AWS::EC2::SecurityGroup"</span>
    <span class="na">Properties</span><span class="pi">:</span>
      <span class="na">GroupDescription</span><span class="pi">:</span> <span class="s2">"</span><span class="s">My</span><span class="nv"> </span><span class="s">new</span><span class="nv"> </span><span class="s">security</span><span class="nv"> </span><span class="s">group"</span>
      <span class="na">SecurityGroupIngress</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="na">CidrIp</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0.0.0.0/0"</span>
          <span class="na">FromPort</span><span class="pi">:</span> <span class="m">22</span>
          <span class="na">IpProtocol</span><span class="pi">:</span> <span class="s2">"</span><span class="s">tcp"</span>
          <span class="na">ToPort</span><span class="pi">:</span> <span class="m">22</span>
      <span class="na">VpcId</span><span class="pi">:</span> <span class="kt">!Ref</span> <span class="s2">"</span><span class="s">MyVPC"</span>
</code></pre></div></div>

<p>In our case, the list is the existing security groups, which is then turned into a string, appended to the new security group, and then converted back into a list again.</p>]]></content><author><name>León Castillejos</name></author><category term="aws" /><category term="aws-cfn" /><category term="tip" /><summary type="html"><![CDATA[Short reference on manipulating CloudFormation lists.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2021-03-03-cloudformation-appending-elements-to-lists/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2021-03-03-cloudformation-appending-elements-to-lists/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">SSH tunnelling</title><link href="https://leonca.st/2020/12/23/ssh-tunnelling.html" rel="alternate" type="text/html" title="SSH tunnelling" /><published>2020-12-23T00:00:00+01:00</published><updated>2020-12-23T00:00:00+01:00</updated><id>https://leonca.st/2020/12/23/ssh-tunnelling</id><content type="html" xml:base="https://leonca.st/2020/12/23/ssh-tunnelling.html"><![CDATA[<p>Quick reference guide to use when you need to use OpenSSH’s various tunnelling features.</p>

<p>I initially wrote this as a draft for myself because I would often forget what each parameter does, and what the correct syntax is, so I’m releasing this post in the hope that others find it helpful.</p>

<h2 id="basic-options">Basic options</h2>

<p>The following options can be used with any of the three tunnel types below this section.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">-N</code> tells SSH to not execute any command, this option is necessary if the remote host has shell access disabled, as trying to spawn a shell would kick you out immediately</li>
  <li><code class="language-plaintext highlighter-rouge">-q</code> suppresses most warning and diagnostic messages</li>
  <li><code class="language-plaintext highlighter-rouge">-f</code> sets the SSH session up for background execution</li>
  <li><code class="language-plaintext highlighter-rouge">-p</code> sets the SSH port, by default it’s 22, but if it’s a different port number, you must specify it here</li>
</ul>

<h2 id="local-forwarding">Local forwarding</h2>

<p>Exposes a port from the server to the client. For example, if your client is on a VPN and you want to give other machines in your LAN access to a port on the server that’s not accessible via the Internet.</p>

<p><code class="language-plaintext highlighter-rouge">ssh -L ABC:hostname:XYZ user@server</code></p>

<p>This will make the client on port <code class="language-plaintext highlighter-rouge">ABC</code> listen for connections and, once it receives one, forward them to <code class="language-plaintext highlighter-rouge">hostname</code> on port <code class="language-plaintext highlighter-rouge">XYZ</code>.</p>

<p>For the above example, you can run the following command:</p>

<p><code class="language-plaintext highlighter-rouge">ssh -L 8080:10.3.1.200:443 user@server</code></p>

<p>This will make the SSH client listen on port <code class="language-plaintext highlighter-rouge">8080</code> and forward any incoming requests to the machine with the IP <code class="language-plaintext highlighter-rouge">10.3.1.200</code> (from the perspective of the server) over port <code class="language-plaintext highlighter-rouge">443</code>.</p>

<p>Now, you can open a browser in your local machine and type <code class="language-plaintext highlighter-rouge">https://localhost:8080</code> and you will connect to <code class="language-plaintext highlighter-rouge">https://10.3.1.200</code> as seen from the SSH server.</p>

<h2 id="remote-forwarding">Remote forwarding</h2>

<p>Exposes a port from the client to the server. For example, you can run a web server on your client, then, expose it to the remote server so that friends and co-workers can connect to it even if you’re behind a restrictive NAT.</p>

<p><code class="language-plaintext highlighter-rouge">ssh -R ABC:hostname:XYZ user@server</code></p>

<p>The above command will map port <code class="language-plaintext highlighter-rouge">ABC</code> on the specified <code class="language-plaintext highlighter-rouge">hostname</code> to the port <code class="language-plaintext highlighter-rouge">XYZ</code> on the client.</p>

<p>For the example given above, you can expose a web server running on the client on port 80 in the following manner:</p>

<p><code class="language-plaintext highlighter-rouge">ssh -R 8080:localhost:80 user@server</code></p>

<p>After running this command, you can now connect to port 8080 on <code class="language-plaintext highlighter-rouge">server</code> and the SSH server will connect back to the client on port 80 where the web server is running</p>

<h2 id="dynamic-socks-forwarding">Dynamic (SOCKS) forwarding</h2>

<p>This allows you to use SOCKS-aware applications behind your SSH server. This is generally used for masking your browser IP behind the SSH server’s IP, potentially bypassing content filtering firewalls or increasing your anonymity to website owners.</p>

<p><code class="language-plaintext highlighter-rouge">ssh -D XYZ user@server</code></p>

<p>Where <code class="language-plaintext highlighter-rouge">XYZ</code> is the <a href="http://localhost">localhost</a> port you can connect your application (for example, web browser). Once you are connected to the SSH server, you must configure your applications to use the proxy settings for the SOCKS protocol with the IP address <code class="language-plaintext highlighter-rouge">127.0.0.1</code> or <code class="language-plaintext highlighter-rouge">localhost</code> and the port <code class="language-plaintext highlighter-rouge">XYZ</code> you have specified.</p>]]></content><author><name>León Castillejos</name></author><category term="tip" /><summary type="html"><![CDATA[Quick reference guide to use when you need to use OpenSSH’s various tunnelling features.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2020-12-23-ssh-tunnelling/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2020-12-23-ssh-tunnelling/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">My path into AWS: Part 2, leadership principles</title><link href="https://leonca.st/2020/12/17/my-path-into-aws-part-2.html" rel="alternate" type="text/html" title="My path into AWS: Part 2, leadership principles" /><published>2020-12-17T00:00:00+01:00</published><updated>2020-12-17T00:00:00+01:00</updated><id>https://leonca.st/2020/12/17/my-path-into-aws-part-2-</id><content type="html" xml:base="https://leonca.st/2020/12/17/my-path-into-aws-part-2.html"><![CDATA[<p>This is an ongoing effort to openly document my AWS interview experience. I will try to cover everything I find relevant, but I’m open to suggestions on what to include. Let me know via Twitter!</p>

<p><strong>DISCLAIMER</strong>: I am sharing my personal experience, and my views don’t necessarily represent Amazon’s. For more information, please consult Amazon’s official documentation and websites.</p>

<p>If you wish to see a list of all the posts for this series, click <a href="https://leonca.st/tags/#aws-path-series">here</a>.</p>

<p>The most crucial factor in the quality of Amazon hires is their leadership skills. Amazon wants to hire not only people who are already smart, but also people who go above and beyond for their own professional development, strong, charismatic people who can push teams forward, and laser-focused individuals that put the customer first and foremost.</p>

<blockquote>
  <p>When we hire someone, they have to be at least 50% better at their job than the current employees.</p>
</blockquote>

<p>Amazon has <a href="https://www.amazon.jobs/en/principles">14 leadership principles</a> that are evident throughout everything we do. It is no secret, and there are hundreds of thousands of posts breaking down every single leadership principle in great detail, with specific examples and possible questions, but in reality, it all boils down to how you express those leadership principles in your professional life. This is not an exam, and there are no right or wrong answers. What recruiters really want to see is how you’re able to apply these key leadership principles and integrate them into everything you do. As important as it may be to have them memorised, it’s even more important to be able to give very specific examples for each principle with as much detail as possible.</p>

<h2 id="how-to-prepare-the-interview">How to prepare the interview</h2>

<p>A smart way to prepare those leadership principles is to write down at least two or three examples from your professional career for each principle. In my case, because I didn’t have enough professional experience, I also included examples from my academic career, university in particular, but try to keep this at a minimum. There are tons of questions a recruiter can ask for each principle, and many examples readily available online. Just searching the name of the principle on your favourite search engine will probably yield tens or hundreds of sample questions to use, but it can even be more insightful to write your own questions. Even thinking backwards can work: Think about an example that uses the leadership principle, and then ask yourself for what kind of question would your answer would make sense.</p>

<p>Some leadership principle question samples:</p>

<ul>
  <li><strong>Customer obsession</strong> - “Tell me about a time when you had to deal with a customer that was angry because they disliked a previous conversation with one of your coworkers”</li>
  <li><strong>Deliver results</strong> - “Have you ever faced difficulties finishing a project? Where did those difficulties stem from? How did you resolve the situation?”</li>
  <li><strong>Invent and simplify</strong> - “Think about a complex process in your previous roles that had opportunity for improvement. Were you able to make it better? If yes, what did you do? If not, why not, what would have you done?”</li>
</ul>

<p>These are just a few example questions I made up. I invite you to write your own questions and let me know via [link removed].</p>

<p>In general, you will be told in advance the kind of leadership principles you’d be asked during the interview. But it is usually close to the actual interview day, so you won’t have a lot of time to prepare them. In my case, I had a little more than a week, but this is probably not enough time for you to prepare them if you are working full-time, so a good idea is to have at least one scenario for each principle ready one week ahead of your scheduled interviews. You will not usually be asked all of the 14 leadership principles. For example, I was asked <em>only</em> about ten of them, but this can change if you are interviewing for management or senior roles that require more experience.</p>

<p>Interviewers do not expect you to give perfect answers 100% of the time, and even if you aren’t able to give successful examples in all scenarios, it is important you understand the leadership principle in question, and that you are able to explain why your example wasn’t successful and what you could have done in a different situation. For example, in my case, one of the principles I was explaining was not a success story because, even though I had the intention of applying the principle, my manager did not let me go forward, and I had no competence to reverse his decision. This is sometimes common: you want to do something that you think is the correct way forward but, either because of management incompetence or a communication issue, the person you report to won’t let you proceed.</p>

<p>Even if you managed to present all stories for the 14 leadership principles as successful, these principles can be framed in a multitude of ways, which means that not all examples you write may be useful during your interview, so you must be ready to improvise. Hopefully, after spending about two weeks preparing them, you should have a good overview of your professional career and can provide examples on-the-fly without much thought. <strong>Important</strong>: Instead of rambling, if you get stuck at some point during the interview, <strong>be honest with your interviewer and tell them you need a little more time to think about the question</strong>. This will look much better on you than using filler words or “ehhh…”, “uhhh…” and similar. For example, you can say “Please give me a minute to think about this” or you can even ask them to rephrase the question, which will buy you some time while they speak. Lastly, interviewers will want to know about your stories with varying degrees of detail. Some will want less detail, and others more. You can always ask them, after you’ve been talking for a while, if you should continue describing the situation or if they have enough information to start asking you questions.</p>

<h2 id="structuring-your-storytelling">Structuring your storytelling</h2>

<p>In order to answer these questions, you should use the <strong>STAR</strong> technique in order to give well-structured responses. This will also signal the instructor you have invested effort into preparing the interview, which is always welcome. The STAR technique is as follows:</p>

<ul>
  <li><strong>S</strong>ituation: Describe the problematic situation and the context that leads to the trouble. Don’t go into more detail than necessary, as you can give further context on the steps you took and the difficulties you faced in later steps.</li>
  <li><strong>T</strong>ask: Describe your responsibility in the context explained previously. Explain how you prepared a plan and what steps you wanted to take to correct the situation.</li>
  <li><strong>A</strong>ction: Here, you can go into the details and specifics of <em>how</em> you carried out your duties. Did you face challenges or difficulties? Did you make last-minute arrangements?</li>
  <li><strong>R</strong>esult: What was the outcome? Were you able to solve the initial situation? If not, and if you weren’t able to explain it previously, why not? And most importantly, what did you learn from the experience?</li>
</ul>

<h2 id="summary">Summary</h2>

<ul>
  <li>Read up on the leadership principles and write a few short stories for each.</li>
  <li>Be honest. Not all examples have to result in positive outcomes, as the most important takeaway from the questions in the interview is what you learned, and that you tried to apply the leadership principles, even if unsuccessfully in the end due to external circumstances.</li>
  <li>If you reuse scenarios for multiple LPs, let your interviewer know, as the different interviews will talk with each other and it may look dishonest on you if you talked about the same situation twice.</li>
  <li>You are in full control, as you’re the one who knows the most about the situations you describe.</li>
  <li>It’s reasonable to present academic examples if you lack professional experience, but try to keep it at a minimum.</li>
</ul>

<p>In the future, I may release comprehensive blog posts on each specific leadership principle. Let me know if there’s a specific principle you’d like to see first. See you on part 3!</p>]]></content><author><name>León Castillejos</name></author><category term="opinion" /><category term="career" /><category term="aws" /><category term="amazon" /><category term="aws-path-series" /><summary type="html"><![CDATA[This is an ongoing effort to openly document my AWS interview experience. I will try to cover everything I find relevant, but I’m open to suggestions on what to include. Let me know via Twitter!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2020-12-17-my-path-into-aws-part-2-/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2020-12-17-my-path-into-aws-part-2-/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">My path into AWS: Part 1, Introduction</title><link href="https://leonca.st/2020/11/27/aws-part1.html" rel="alternate" type="text/html" title="My path into AWS: Part 1, Introduction" /><published>2020-11-27T00:00:00+01:00</published><updated>2020-11-27T00:00:00+01:00</updated><id>https://leonca.st/2020/11/27/aws-part1</id><content type="html" xml:base="https://leonca.st/2020/11/27/aws-part1.html"><![CDATA[<p>This will be a series of posts on the AWS recruitment process. If you wish to see a list of all the posts for this series, click <a href="https://leonca.st/tags/#aws-path-series">here</a>. I will try to cover everything I find relevant, but I’m open to suggestions on what to include. Let me know via Twitter!</p>

<p><strong>DISCLAIMER</strong>: I am sharing my personal experience, and my views don’t necessarily represent Amazon’s. For more information, please consult Amazon’s official documentation and websites.</p>

<p>If you wish to see a list of all the posts for this series, click <a href="https://leonca.st/tags/#aws-path-series">here</a>.</p>

<p>I’ve been meaning to write this for the past few weeks, but suffice to say I’ve been quite stressed, as I had to move about 1500 km, from the city I was born in, and the city I spent more than 25 years of my life in, to a different city: Dublin.</p>

<p>Fortunately, things have settled down now and I have managed to find some time to write this post.</p>

<p>A bit on my background and why I decided to join AWS first. For the past 4-5 years, I’ve been dreaming about the possibility of joining a high-performance company the likes of AWS, Google, Microsoft, or similar. I’ve gone through multiple psychological steps, including one where I thought I was not a good fit, and that there’s no way I’d ever reach such goal, so I’d better settle for more easily reachable goals (if only one could travel 4 years back in time). I have worked both professionally and informally as a systems administrator, and I have also done a fair bit of programming on my own. If you don’t already know me, I’m passionate about computers, and I strive to become part of a high-performing team of passionate engineers who, like me, want to build the future. Professional development and passion have been a constant that have driven my life for the past few years. Always with the hopes of some day reaching the point I’m at today. In fact, I have probably submitted my resume at least a dozen of times at AWS, Microsoft, Google, Apple, Cloudflare, Akamai, Twilio, and other software and computer network companies to no avail. In particular, regarding AWS, I had already failed one interview, and had an error on a second one that disqualified me for the next recruitment steps. The problem had more to do with the interview environment than my knowledge, but nevertheless I was unfortunately not allowed to restart the process.</p>

<p>Before AWS, I was working for cPanel as a Linux technical analyst. My daily duties consisted of having customers contact me for help with cPanel products, and I was able to connect to customer machines in order to quickly troubleshoot their systems and provide a solution.</p>

<p>cPanel was a very fast-paced environment, and I got the chance to sharpen up my customer-facing interpersonal skills while simultaneously working on something I have decades of experience with: Linux systems.</p>

<p>I suspect this is exactly the reason why an AWS recruiter reached out to me on LinkedIn. My official title, as displayed on LinkedIn was “Linux Technical Analyst at cPanel”. The recruiter mentioned there would be a week-long learning session regarding AWS, labs included, which, at the end of the process, would culminate in an interview for a potential AWS role. Then it was a matter of signing up using the provided link, and showing up at the scheduled time.</p>

<p>The sessions were spread across three different sessions, each taking place in a different day, with approximately 3 hours for each session in which the instructors taught us a few different AWS technologies, in our case these technologies were:</p>

<ul>
  <li>AWS Lambda</li>
  <li>Amazon API Gateway</li>
  <li>Amazon Cognito</li>
</ul>

<p>We were provided with a funded, if temporary AWS account so that, during the duration of the training, we were able to use AWS facilities without needing to spend our money.</p>

<p>Before these sessions, I had only ever heard about AWS. I’ve never used their products in any meaningful way. I thought I’d fail because I had no experience with AWS. After all, there are tons of AWS certified experts out there who are not AWS employees. Why would they choose me?</p>

<p>During the third and last session, the instructors described how the challenge would be carried out. This was the “trial by fire” that would determine if we are eligible for an interview at AWS or not. By now, it would seem quite obvious I passed this challenge, not without the typical hurdles of situations like these. This test was scheduled to be handed in 24 hours, but by the time the instructors logged off because the session ended, I had been working on the challenge for 3 hours, with the last hour in a state of complete lockup, as there was something obvious I was missing, but I was unable to continue working, so I forced myself to go to bed, only to wake up 3 hours later and finish and submit the challenge in about 10 minutes).</p>

<p>The last session concluded on September 5th. As I always do, I assumed the worst, thinking I would be dismissed and forgotten, and that my chances of landing an interview were practically nonexistent.</p>

<p>While this may seem unnecessarily negative, thinking in these terms has some advantages. First of all, once I had finished all my tasks, I submitted them, expecting nothing, which allows me to change my mental context. The alternative would be obsessing over my grade and frantically check my e-mail inbox every day, only to find it empty and become increasingly frustrated as time passes. Secondly, it prepares me for the worst. In this case, the worst is being ghosted or simply being told I’m not a good fit for the team. It wouldn’t be too terrible since I already had a job I enjoyed, but of course it would be a tough blow. Third, if I end up passing, I wouldn’t get too overconfident.</p>

<p>While that’s the technique I use for coping with difficult situations, I also want to emphasise that it’s very important to have confidence in yourself. If there’s a slim chance, as minuscule as it may be, that you are able to land the job of your dreams, then, why not try it? By not trying at all, you already have the “no”. There’s no way to fail if you never try, of course, but there’s also no way to succeed. I have failed a thousand times, and <strong>I can only hope I will fail a thousand more</strong>, because that, and only that, is an indicative of my progress. Perhaps I was contacted on LinkedIn because they already had my resume on their records and they thought I could be a good candidate. This wouldn’t have been the case had I never submitted my CV in the first place.<strong>I know very well receiving rejection after rejection is disheartening</strong>, because every time you try and fail, it’s kind of a signal that perhaps you’re doing things wrong, and this has personally affected me, but it is necessary to reframe this in different terms if you want to get anywhere.</p>

<p>In the end, I ended up being invited for a formal interview on September 16th, about 11 days after submitting the final task. Over the course of a few days I was informed about how it all would take place. The interviews would be carried out on September 22. A total of 4 interviews, with a different interviewer, lasting 1 hour each. Like all <a href="https://en.wikipedia.org/wiki/Big_Tech">GAFAM</a> companies, interviewing for Amazon is quite different. Each company has its own style. In the case of Amazon, they strongly emphasise their <a href="https://www.aboutamazon.com/about-us/leadership-principles">leadership principles</a>. I will talk about these leadership principles more in future posts, but it’s all very much up to you and your personal experience, as well as your personality. There’s no correct answer here, Amazon simply wants to see you demonstrating your leadership skills in real-world examples. They will often ask you very specific details, and, in many cases, a single situation can be framed and adapted to many different leadership principles, by simply focusing on the specifics of any given situation. This is why it’s very important to be consistent and also inform your interviewers if you are reusing scenarios, as they will meet and discuss your performance and leadership examples.</p>

<p>The interview process is quite exhausting, and very fast-paced, but this is to be expected from a high performance company such as Amazon. You do not need to worry, as keeping calm during the process will also add bonus points to your process, because you will have to face difficult, stressing scenarios once you’re in. This is second nature to me, as I’m able to rationalise stressful situations, but this skill can be learned. It’s simply about getting out of your comfort zone. Stress strikes you when things are not going the way you expect them to, which can happen at any time, regardless of what you’re doing: Cooking, relationships, weather, sports, travelling, and more. I’d say believing in yourself is one of the most (if not the single most) valuable skills you can hold. Once you understand nobody knows more about your professional career than your own self, it gets much easier. It doesn’t matter how many background checks, or how many past employers your recruiter speaks to. Only you will have the full picture.</p>

<p>When preparing for my Amazon interview, I wrote a lot about myself and my past roles, even though many of the questions I anticipated didn’t actually appear during the interview, it helped me gain confidence in myself and carve out ways to answer complex questions. As a guide, try writing at least half a DIN-A4 page (or a single DIN-A5 page if you will) for each of these questions:</p>
<ul>
  <li>Why do you want to work at Amazon?</li>
  <li>What makes you the ideal candidate?</li>
  <li>What is your biggest weakness?</li>
  <li>What finished project are you most proud of?</li>
  <li>What are your aspirations?</li>
  <li>What advice would you give to your 5 year younger self?</li>
  <li>Have you ever taken a decision that later on proved to have negative effects? How did you overcome this negative situation?</li>
</ul>

<p>Note that these questions must be answered <strong>honestly and truthfully</strong>, otherwise they won’t be very useful. These will help you get to know yourself, and exist in addition to the mandatory leadership principles questions you’ll get. Also note it’s highly unlikely you’ll be asked all of them, especially the third one, regarding your weaknesses. Many people think it is rude to ask a candidate about their weaknesses, and other people try to frame their weakness in a positive light, such as by saying “I work too hard” or “I become frustrated when things don’t work the way they are supposed to”, but this looks shallow and dishonest to recruiters. Even if that was the truth, it is important to give a sense of why it is negative, and the steps you’re taking to rectify it. I believe being aware of one’s limitations and handicaps is the single most important thing in order to become a better person today than you were yesterday, every day. You also can make up your own questions, but hopefully you get a sense of what an employer is looking for in a candidate. The fact I was able to work as a technical recruiter in one of my roles also helped me see the other part of the recruiting interview, from the eyes of the employer, which was incredibly enriching.</p>

<p>Questions? Let me know: [link removed] on Twitter. For other platforms, check out the side menu.</p>]]></content><author><name>León Castillejos</name></author><category term="opinion" /><category term="career" /><category term="aws" /><category term="amazon" /><category term="aws-path-series" /><summary type="html"><![CDATA[This will be a series of posts on the AWS recruitment process. If you wish to see a list of all the posts for this series, click here. I will try to cover everything I find relevant, but I’m open to suggestions on what to include. Let me know via Twitter!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://leonca.st/assets/images/2020-11-23-aws-part1/header.jpg" /><media:content medium="image" url="https://leonca.st/assets/images/2020-11-23-aws-part1/header.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>