<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Servicios Rogeliowar</title><link>https://blog.serviciosrogeliowar.com/en/</link><description>Recent content on Servicios Rogeliowar</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2026 Rogelio Guerra Riverón</copyright><lastBuildDate>Fri, 22 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.serviciosrogeliowar.com/en/index.xml" rel="self" type="application/rss+xml"/><item><title>Wazuh SIEM with Docker: complete deployment with SSL and compliance rules</title><link>https://blog.serviciosrogeliowar.com/en/posts/wazuh-siem-docker-ssl-cumplimiento/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/wazuh-siem-docker-ssl-cumplimiento/</guid><description>&lt;h2 class="relative group"&gt;What is ENS and Why It Matters
 &lt;div id="what-is-ens-and-why-it-matters" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-is-ens-and-why-it-matters" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href="https://ens.ccn.cni.es/" target="_blank" rel="noreferrer"&gt;National Security Framework (ENS)&lt;/a&gt;&lt;/strong&gt; is the mandatory cybersecurity regulatory framework for Spanish Public Administrations and private companies that provide services to them. It is regulated by the &lt;a href="https://www.boe.es/eli/es/rd/2022/05/03/311" target="_blank" rel="noreferrer"&gt;Royal Decree 311/2022&lt;/a&gt; and establishes the principles, requirements, and security measures that must be applied to information systems that handle public data or services.&lt;/p&gt;</description></item><item><title>Connect your mobile to SSH from anywhere with WireGuard and Termius</title><link>https://blog.serviciosrogeliowar.com/en/posts/conectar-el-movil-a-ssh-desde-cualquier-lugar-con-wireguard-y-termius/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/conectar-el-movil-a-ssh-desde-cualquier-lugar-con-wireguard-y-termius/</guid><description>&lt;h2 class="relative group"&gt;The Problem
 &lt;div id="the-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I needed to access my home server via SSH from my mobile phone without exposing it directly to the internet. The obvious options were bad: opening port 22 to the world is suicidal, and trusting third-party apps with root access didn&amp;rsquo;t convince me. The solution that worked: WireGuard + Termius.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Why This Combination
 &lt;div id="why-this-combination" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-this-combination" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;WireGuard is lightweight, fast, and consumes little battery on mobile devices. Termius is a polished SSH client that handles private keys well. Together, you have secure access without complications.&lt;/p&gt;</description></item><item><title>How to Clean Up Exposed Credentials in Git with git-filter-repo and Rotate Tokens</title><link>https://blog.serviciosrogeliowar.com/en/posts/como-limpiar-credenciales-expuestas-en-git-con-git-filter-repo-y-rotar-tokens/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/como-limpiar-credenciales-expuestas-en-git-con-git-filter-repo-y-rotar-tokens/</guid><description>&lt;h2 class="relative group"&gt;The Real Problem
 &lt;div id="the-real-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-real-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I recently realized I had pushed a &lt;code&gt;.env&lt;/code&gt; file with API credentials to a private repository. Even though it was private, that&amp;rsquo;s no excuse. A compromised access, a repository that becomes public, or simply a security audit would have exposed my tokens. I learned that &lt;strong&gt;I can&amp;rsquo;t rely on deleting files in subsequent commits&lt;/strong&gt;—Git keeps all the history.&lt;/p&gt;</description></item><item><title>Migrate Grafana and Listmonk to centralized PostgreSQL in Docker</title><link>https://blog.serviciosrogeliowar.com/en/posts/migrar-grafana-y-listmonk-a-postgresql-centralizado-en-docker/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/migrar-grafana-y-listmonk-a-postgresql-centralizado-en-docker/</guid><description>&lt;h2 class="relative group"&gt;The initial problem
 &lt;div id="the-initial-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-initial-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I had Grafana and Listmonk running in Docker containers, each with its own embedded PostgreSQL instance. This worked, but it was inefficient: two database engines consuming resources and no centralized way to do backups. I decided to consolidate everything into a single shared PostgreSQL instance.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Preparation: setting up central PostgreSQL
 &lt;div id="preparation-setting-up-central-postgresql" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#preparation-setting-up-central-postgresql" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The first step was to create the PostgreSQL server that would be the central point. I did this with a dedicated docker-compose:&lt;/p&gt;</description></item><item><title>Restic: encrypted backups with deduplication for your Linux server</title><link>https://blog.serviciosrogeliowar.com/en/posts/restic-backups-cifrados-deduplicacion/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/restic-backups-cifrados-deduplicacion/</guid><description>&lt;p&gt;I already had &lt;a href="https://blog.serviciosrogeliowar.com/en/posts/backups-automaticos-con-rsync-y-cron-para-docker-domestico/" &gt;backups with rsync and cron&lt;/a&gt;, but rsync copies files, not snapshots. If you accidentally delete a file and the backup syncs before you notice, you lose it. &lt;a href="https://restic.net/" target="_blank" rel="noreferrer"&gt;Restic&lt;/a&gt; solves that and adds something rsync will never provide: &lt;strong&gt;AES-256 encryption, deduplication, and snapshots with navigable history&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 class="relative group"&gt;What makes Restic different
 &lt;div id="what-makes-restic-different" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-makes-restic-different" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Feature&lt;/th&gt;
					&lt;th&gt;rsync&lt;/th&gt;
					&lt;th&gt;Restic&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;AES-256 encryption&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;Yes&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Deduplication&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;Yes (block-level)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Navigable snapshots&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;Yes&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Multiple backends&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;SFTP, S3, Backblaze, rclone…&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Integrity checking&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;restic check&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Retention policy&lt;/td&gt;
					&lt;td&gt;Manual&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;restic forget --prune&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Deduplication is especially useful for database backups and configuration directories that change little: a Restic repository with 6 months of daily backups usually takes up much less space than 180 full copies.&lt;/p&gt;</description></item><item><title>VPN with Wireguard in Docker: Secure access to internal services without exposing ports</title><link>https://blog.serviciosrogeliowar.com/en/posts/vpn-con-wireguard-en-docker-acceso-seguro-a-servicios-internos-sin-exponer-puertos/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/vpn-con-wireguard-en-docker-acceso-seguro-a-servicios-internos-sin-exponer-puertos/</guid><description>&lt;h2 class="relative group"&gt;Why you need this
 &lt;div id="why-you-need-this" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-you-need-this" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;A few months ago I faced a common problem: I wanted to access my internal services (Jellyfin, Home Assistant, etc.) from outside my home, but I didn&amp;rsquo;t want to expose them directly on the internet. Opening ports is an unnecessary risk. The solution was to set up a VPN with Wireguard in Docker. It was the best decision I made for my home infrastructure.&lt;/p&gt;</description></item><item><title>Monitoring Docker containers with Prometheus and Grafana: automatic alerts at home</title><link>https://blog.serviciosrogeliowar.com/en/posts/monitorizacion-de-contenedores-docker-con-prometheus-y-grafana-alertas-automaticas-en-casa/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/monitorizacion-de-contenedores-docker-con-prometheus-y-grafana-alertas-automaticas-en-casa/</guid><description>&lt;h2 class="relative group"&gt;The Problem
 &lt;div id="the-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After spending months running containers on my home server, I got tired of discovering issues when things were already broken. A container consuming all the memory. A volume full with no warning. I needed real visibility into what was happening in my infrastructure.&lt;/p&gt;
&lt;p&gt;I decided to implement a monitoring stack with Prometheus and Grafana. Here I document exactly how I did it.&lt;/p&gt;</description></item><item><title>AUTH LOGIN manual in Python with smtplib: special characters and error 535</title><link>https://blog.serviciosrogeliowar.com/en/posts/auth-login-manual-en-python-con-smtplib-caracteres-especiales-y-error-535/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/auth-login-manual-en-python-con-smtplib-caracteres-especiales-y-error-535/</guid><description>&lt;h2 class="relative group"&gt;The Problem
 &lt;div id="the-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;A few days ago I tried to automate sending emails from my home server. Nothing complicated: a Python script with smtplib to send notifications. The problem came when I configured a password with special characters: &lt;code&gt;MiPasw0rd$Ñ&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; smtplib
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server &lt;span style="color:#f92672"&gt;=&lt;/span&gt; smtplib&lt;span style="color:#f92672"&gt;.&lt;/span&gt;SMTP(&lt;span style="color:#e6db74"&gt;&amp;#39;mail.example.com&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;587&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server&lt;span style="color:#f92672"&gt;.&lt;/span&gt;starttls()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server&lt;span style="color:#f92672"&gt;.&lt;/span&gt;login(&lt;span style="color:#e6db74"&gt;&amp;#39;usuario@example.com&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;MiPasw0rd$Ñ&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# Error 535&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Result: &lt;code&gt;SMTPAuthenticationError: (535, b'5.7.8 Authentication credentials invalid')&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The strange thing is that the password was correct. I could access it manually without problems. Error 535 suggested authentication failures, but the real problem was in the encoding.&lt;/p&gt;</description></item><item><title>Automatic backups with rsync and cron for home Docker</title><link>https://blog.serviciosrogeliowar.com/en/posts/backups-automaticos-con-rsync-y-cron-para-docker-domestico/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/backups-automaticos-con-rsync-y-cron-para-docker-domestico/</guid><description>&lt;h2 class="relative group"&gt;The Problem
 &lt;div id="the-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Recently I lost a hard drive without warning. It wasn&amp;rsquo;t catastrophic because I had backups, but it made me aware that many hobbyists with home servers have no data protection strategy at all. If your Docker server crashes tomorrow, how long would it take you to recover it?&lt;/p&gt;
&lt;p&gt;In this article I share how I automated backups of my Docker infrastructure using rsync and cron. It&amp;rsquo;s simple, efficient, and it works.&lt;/p&gt;</description></item><item><title>Environment variables with special characters in Docker Compose: the dollar sign problem and how to recreate containers</title><link>https://blog.serviciosrogeliowar.com/en/posts/variables-de-entorno-con-caracteres-especiales-en-docker-compose-el-problema-del-dollar-y-como-recrear-contenedores/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/variables-de-entorno-con-caracteres-especiales-en-docker-compose-el-problema-del-dollar-y-como-recrear-contenedores/</guid><description>&lt;h2 class="relative group"&gt;The Real Problem
 &lt;div id="the-real-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-real-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been running services on my home server with Docker Compose for months. Recently I tried setting a password with special characters in my &lt;code&gt;.env&lt;/code&gt; file. The password was something like &lt;code&gt;Pass$word123!@&lt;/code&gt;. When starting the containers, the variable arrived empty or malformed. After investigating, I discovered that Docker Compose was interpreting the &lt;code&gt;$&lt;/code&gt; as a reference to another variable.&lt;/p&gt;</description></item><item><title>Incremental synchronization from SMB with smbprotocol on Linux: NTLM authentication and log control</title><link>https://blog.serviciosrogeliowar.com/en/posts/sincronizacion-incremental-desde-smb-con-smbprotocol-en-linux-autenticacion-ntlm-y-control-de-logs/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/sincronizacion-incremental-desde-smb-con-smbprotocol-en-linux-autenticacion-ntlm-y-control-de-logs/</guid><description>&lt;h2 class="relative group"&gt;The Problem
 &lt;div id="the-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Recently I needed to sync an SMB share from a NAS with my Linux server. The obvious solution would be &lt;code&gt;smbclient&lt;/code&gt; or &lt;code&gt;mount -t cifs&lt;/code&gt;, but I wanted:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Incremental&lt;/strong&gt; synchronization (only new or modified files)&lt;/li&gt;
&lt;li&gt;Detect files &lt;strong&gt;deleted&lt;/strong&gt; from the share&lt;/li&gt;
&lt;li&gt;Control &lt;strong&gt;NTLM&lt;/strong&gt; authentication directly from code&lt;/li&gt;
&lt;li&gt;Silence the obscene amount of logs that &lt;code&gt;smbprotocol&lt;/code&gt; spits out&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Python &lt;code&gt;smbprotocol&lt;/code&gt; library solved all of this, but there&amp;rsquo;s no documentation on how to do it properly. Here&amp;rsquo;s my solution.&lt;/p&gt;</description></item><item><title>Smart Excel Import in Python: Flexible Column Detection and Heterogeneous Data Cleaning</title><link>https://blog.serviciosrogeliowar.com/en/posts/importacion-inteligente-de-excel-en-python-deteccion-flexible-de-columnas-y-limpieza-de-datos-heterogeneos/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/importacion-inteligente-de-excel-en-python-deteccion-flexible-de-columnas-y-limpieza-de-datos-heterogeneos/</guid><description>&lt;p&gt;I&amp;rsquo;ve been working with Excel spreadsheets that arrive from different departments. Each one uses different column names, the data is dirty (phone numbers with notes, tax IDs mixed with text), and codes have inconsistent formats. Here I document the solution I built.&lt;/p&gt;

&lt;h2 class="relative group"&gt;The real problem
 &lt;div id="the-real-problem" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-real-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I was receiving Excel files where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Columns called &amp;ldquo;NIF&amp;rdquo; in one, &amp;ldquo;CIF&amp;rdquo; in another, &amp;ldquo;Identification&amp;rdquo; in the third&lt;/li&gt;
&lt;li&gt;Phone numbers like &amp;ldquo;123-456-7890 (ext 5)&amp;rdquo;, &amp;ldquo;9876543210 - unavailable&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Tax IDs with dashes, spaces and varied letters&lt;/li&gt;
&lt;li&gt;Product codes with inconsistent prefixes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I couldn&amp;rsquo;t expect everyone to format the same way. I needed a system that was flexible.&lt;/p&gt;</description></item><item><title>Systemd timers: the modern cron alternative you needed</title><link>https://blog.serviciosrogeliowar.com/en/posts/systemd-timers-la-alternativa-moderna-a-cron-que-necesitabas/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/systemd-timers-la-alternativa-moderna-a-cron-que-necesitabas/</guid><description>&lt;h2 class="relative group"&gt;Why I Left Cron
 &lt;div id="why-i-left-cron" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-i-left-cron" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been using cron on my servers for years. It&amp;rsquo;s simple, reliable, and it works. But recently I discovered systemd timers and I&amp;rsquo;m not going back. The main reason: &lt;strong&gt;integrated logs in journald&lt;/strong&gt;, no &lt;code&gt;.log&lt;/code&gt; files scattered around the system, and better control over what happens when the server starts or reboots.&lt;/p&gt;
&lt;p&gt;In my specific case, I had a backup that wouldn&amp;rsquo;t run if the server was off at the scheduled time. With cron, it simply got lost. With systemd timers and &lt;code&gt;Persistent=true&lt;/code&gt;, the task runs as soon as the server boots up.&lt;/p&gt;</description></item><item><title>The hidden cost of --reload in uvicorn: what actually consumes CPU in production</title><link>https://blog.serviciosrogeliowar.com/en/posts/el-coste-oculto-de---reload-en-uvicorn-que-consume-cpu-realmente-en-produccion/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/el-coste-oculto-de---reload-en-uvicorn-que-consume-cpu-realmente-en-produccion/</guid><description>&lt;h2 class="relative group"&gt;The Problem Nobody Sees
 &lt;div id="the-problem-nobody-sees" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem-nobody-sees" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Two months ago I deployed a FastAPI API to production and the server was behaving strangely. CPU stable at 40-50% for no apparent reason. I thought it was a memory leak, that it was the logs, that it was the database. It was &lt;code&gt;--reload&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It turns out that copy-pasting the development command directly into the Docker container is more common than it should be. And yes, uvicorn with &lt;code&gt;--reload&lt;/code&gt; works. The server responds. Requests go fast. But there&amp;rsquo;s a cost you don&amp;rsquo;t see until you have 10K requests daily.&lt;/p&gt;</description></item><item><title>Hardening Linux servers: practical guide</title><link>https://blog.serviciosrogeliowar.com/en/posts/hardening-servidores-linux/</link><pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/hardening-servidores-linux/</guid><description>&lt;h1 class="relative group"&gt;Server Security Hardening: Essential Steps
 &lt;div id="server-security-hardening-essential-steps" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#server-security-hardening-essential-steps" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h1&gt;
&lt;p&gt;Having a server exposed to the Internet without minimal security configuration is leaving the door wide open. In this article, I&amp;rsquo;ve compiled the steps I apply on my own servers to reduce the attack surface without complicating day-to-day management.&lt;/p&gt;

&lt;h2 class="relative group"&gt;SSH: the first line of defense
 &lt;div id="ssh-the-first-line-of-defense" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ssh-the-first-line-of-defense" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The SSH service is the most attacked entry point on any Linux server. These are the most important settings in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>AI Agent with Claude Haiku to Generate Blog Articles from the Terminal</title><link>https://blog.serviciosrogeliowar.com/en/posts/agente-ia-con-claude-haiku-para-generar-articulos-de-blog-desde-el-terminal/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/agente-ia-con-claude-haiku-para-generar-articulos-de-blog-desde-el-terminal/</guid><description>&lt;h2 class="relative group"&gt;Why Automate Content Generation
 &lt;div id="why-automate-content-generation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-automate-content-generation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Writing technical articles takes time. Between server configuration, troubleshooting, and documentation, I find little time to write. So I decided to create an AI agent to help me structure and generate drafts from the terminal.&lt;/p&gt;
&lt;p&gt;Claude Haiku is perfect for this: it&amp;rsquo;s fast, cheap, and works well for text generation tasks. It doesn&amp;rsquo;t require powerful GPUs. I simply run a script and have an article ready to edit.&lt;/p&gt;</description></item><item><title>CI/CD with local GitLab Runner to automatically deploy a Hugo blog</title><link>https://blog.serviciosrogeliowar.com/en/posts/cicd-con-gitlab-runner-local-para-desplegar-automaticamente-un-blog-hugo/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/cicd-con-gitlab-runner-local-para-desplegar-automaticamente-un-blog-hugo/</guid><description>&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Tired of manually deploying my Hugo blog every time I publish an article. I decided to set up a local CI/CD pipeline with GitLab Runner. The result: automatic, reliable, and without depending on external services.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Prerequisites
 &lt;div id="prerequisites" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;You need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A server with Docker installed&lt;/li&gt;
&lt;li&gt;A repository on GitLab (can be self-hosted or gitlab.com)&lt;/li&gt;
&lt;li&gt;Hugo installed locally for testing&lt;/li&gt;
&lt;li&gt;SSH access configured on your server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;Installing GitLab Runner
 &lt;div id="installing-gitlab-runner" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#installing-gitlab-runner" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;First, install GitLab Runner on your server. I did it on Docker because I already had the daemon running.&lt;/p&gt;</description></item><item><title>Complete monitoring with Prometheus, Grafana and Loki: metrics, logs and Docker containers</title><link>https://blog.serviciosrogeliowar.com/en/posts/monitoring-prometheus-grafana-loki/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/monitoring-prometheus-grafana-loki/</guid><description>&lt;p&gt;A server without monitoring is a blind server. You don&amp;rsquo;t know when the disk fills up, which container is consuming too much RAM, or how many 404 requests your web is generating. This article documents how I configured the complete stack: &lt;a href="https://prometheus.io/" target="_blank" rel="noreferrer"&gt;Prometheus&lt;/a&gt; + &lt;a href="https://github.com/prometheus/node_exporter" target="_blank" rel="noreferrer"&gt;Node Exporter&lt;/a&gt; + &lt;a href="https://grafana.com/" target="_blank" rel="noreferrer"&gt;Grafana&lt;/a&gt; + &lt;a href="https://grafana.com/oss/loki/" target="_blank" rel="noreferrer"&gt;Loki&lt;/a&gt; + &lt;a href="https://grafana.com/docs/loki/latest/send-data/promtail/" target="_blank" rel="noreferrer"&gt;Promtail&lt;/a&gt;.&lt;/p&gt;

&lt;h2 class="relative group"&gt;The architecture
 &lt;div id="the-architecture" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-architecture" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[Servidor doméstico]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── node-exporter → métricas del sistema (CPU, RAM, disco, red)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── docker-stats- → métricas de contenedores (textfile collector)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ collector
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── prometheus → recolecta y almacena métricas
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── loki → agrega y almacena logs
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── promtail → envía logs de Nginx y syslog a Loki
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── grafana → dashboards de todo lo anterior&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;All services run in Docker, coordinated by the same &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Configure Traefik v2.11 as a reverse proxy with Docker and automatic HTTPS with Let's Encrypt</title><link>https://blog.serviciosrogeliowar.com/en/posts/configurar-traefik-v211-como-reverse-proxy-con-docker-y-https-automatico-con-lets-encrypt/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/configurar-traefik-v211-como-reverse-proxy-con-docker-y-https-automatico-con-lets-encrypt/</guid><description>&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After months of using nginx manually, I decided to switch to Traefik. The reason is simple: managing SSL certificates for each new service is tedious. Traefik automates all of that with integrated Let&amp;rsquo;s Encrypt. Here&amp;rsquo;s my actual configuration.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Why Traefik
 &lt;div id="why-traefik" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-traefik" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;With Traefik you don&amp;rsquo;t need to reload nginx every time you add a container. It automatically detects Docker services, generates SSL certificates on demand, and redirects traffic. All declarative.&lt;/p&gt;</description></item><item><title>CSS that doesn't fail: common styling mistakes on web pages and how to avoid them</title><link>https://blog.serviciosrogeliowar.com/en/posts/css-errores-comunes-estilos/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/css-errores-comunes-estilos/</guid><description>&lt;p&gt;CSS seems simple until something doesn&amp;rsquo;t work as you expect. You spend hours staring at the browser inspector, change one property, then another, and the problem persists. This article collects the most frequent errors I&amp;rsquo;ve encountered building this blog, with direct solutions.&lt;/p&gt;

&lt;h2 class="relative group"&gt;The background that disappears when scrolling
 &lt;div id="the-background-that-disappears-when-scrolling" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-background-that-disappears-when-scrolling" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; The page looks good in the visible area, but when you scroll down a white or unexpected background appears.&lt;/p&gt;</description></item><item><title>Emergency replica: how to have your home server backed up on a VPS</title><link>https://blog.serviciosrogeliowar.com/en/posts/replica-emergencia-vps/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/replica-emergencia-vps/</guid><description>&lt;p&gt;Having a server at home has an obvious weak point: if the power goes out, the router fails, or the disk dies, your website disappears. The solution is to have a replica in the cloud ready to activate in minutes.&lt;/p&gt;

&lt;h2 class="relative group"&gt;The architecture
 &lt;div id="the-architecture" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-architecture" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[servidor-casa] → rsync cada 6h → [VPS réplica]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; servicios activos réplica en espera
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TTL DNS: 5 min Uptime Kuma vigilando&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The home server pushes content to the VPS every 6 hours. If the server goes down, I change the DNS and in 5 minutes the VPS serves the site.&lt;/p&gt;</description></item><item><title>Fail2ban to protect SSH and Nginx: practical configuration on Ubuntu</title><link>https://blog.serviciosrogeliowar.com/en/posts/fail2ban-para-proteger-ssh-y-nginx-configuracion-practica-en-ubuntu/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/fail2ban-para-proteger-ssh-y-nginx-configuracion-practica-en-ubuntu/</guid><description>&lt;h2 class="relative group"&gt;The Problem: Brute Force Attacks
 &lt;div id="the-problem-brute-force-attacks" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem-brute-force-attacks" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After exposing my Ubuntu server to the internet, I spent a night reviewing logs. SSH received failed login attempts every second. Nginx also had suspicious requests to common routes. I needed something to block these attempts automatically. Fail2ban was my solution.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Installation
 &lt;div id="installation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#installation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install fail2ban
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl start fail2ban
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl enable fail2ban&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Verify that it&amp;rsquo;s running:&lt;/p&gt;</description></item><item><title>How to index your website in Google Search Console: practical guide with sitemap and domain verification</title><link>https://blog.serviciosrogeliowar.com/en/posts/como-indexar-tu-sitio-web-en-google-search-console-guia-practica-con-sitemap-y-verificacion-de-dominio/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/como-indexar-tu-sitio-web-en-google-search-console-guia-practica-con-sitemap-y-verificacion-de-dominio/</guid><description>&lt;p&gt;When I put my first site in production on a home server, I made the mistake of thinking Google would discover it on its own. It didn&amp;rsquo;t. After a week with no trace in search results, I understood that I needed to be more proactive. Here&amp;rsquo;s what I learned setting up Google Search Console from scratch.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Why you need Google Search Console
 &lt;div id="why-you-need-google-search-console" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-you-need-google-search-console" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Google Search Console is not optional. It&amp;rsquo;s your direct communication with Google about your site. It shows you indexing errors, security issues, and most importantly: it lets you tell Google exactly which pages to index and when.&lt;/p&gt;</description></item><item><title>How to set up your own web infrastructure at home with Docker and Traefik: from zero to automatic HTTPS</title><link>https://blog.serviciosrogeliowar.com/en/posts/como-montar-tu-propia-infraestructura-web-en-casa-con-docker-y-traefik-desde-cero-hasta-https-automatico/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/como-montar-tu-propia-infraestructura-web-en-casa-con-docker-y-traefik-desde-cero-hasta-https-automatico/</guid><description>&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;A few months ago I decided to stop using expensive cloud services and set up my own infrastructure at home. The solution I found was combining Docker with Traefik. It works well and now I have several services running under HTTPS without manually touching a certificate. I&amp;rsquo;ll tell you how I did it.&lt;/p&gt;

&lt;h2 class="relative group"&gt;What you need
 &lt;div id="what-you-need" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-you-need" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;A server with Docker installed (any Linux machine with 2GB of RAM is enough). Your own domain. A bit of patience with DNS. That&amp;rsquo;s it.&lt;/p&gt;</description></item><item><title>Security email notifications from the terminal with msmtp and Gmail</title><link>https://blog.serviciosrogeliowar.com/en/posts/notificaciones-de-seguridad-por-email-desde-el-terminal-con-msmtp-y-gmail/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/notificaciones-de-seguridad-por-email-desde-el-terminal-con-msmtp-y-gmail/</guid><description>&lt;h2 class="relative group"&gt;Why you need this
 &lt;div id="why-you-need-this" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-you-need-this" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;When you run a server at home, you need to know if something strange happens. A script that sends you an email when it detects a failed login attempt, an expiring certificate, or a nearly full disk is invaluable. The problem is that your ISP blocks port 25, so you can&amp;rsquo;t use sendmail directly. That&amp;rsquo;s where msmtp comes in.&lt;/p&gt;</description></item><item><title>SSH authentication by public key: disable passwords on Ubuntu Server</title><link>https://blog.serviciosrogeliowar.com/en/posts/autenticacion-ssh-por-clave-publica-desactivar-contrasenas-en-ubuntu-server/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/autenticacion-ssh-por-clave-publica-desactivar-contrasenas-en-ubuntu-server/</guid><description>&lt;h2 class="relative group"&gt;Why Switch to Key-Based Authentication
 &lt;div id="why-switch-to-key-based-authentication" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-switch-to-key-based-authentication" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After months of maintaining a home server with open SSH access, I got tired of brute force password attacks. Switching to public key authentication was the best security decision I made. Keys are mathematically impossible to crack through brute force, while passwords are always a target.&lt;/p&gt;

&lt;h2 class="relative group"&gt;SSH Key Generation
 &lt;div id="ssh-key-generation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ssh-key-generation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;First, generate a key pair on your local machine (not on the server):&lt;/p&gt;</description></item><item><title>Static blog with Hugo and Blowfish theme on a home server</title><link>https://blog.serviciosrogeliowar.com/en/posts/blog-estatico-con-hugo-y-tema-blowfish-en-un-servidor-domestico/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/blog-estatico-con-hugo-y-tema-blowfish-en-un-servidor-domestico/</guid><description>&lt;p&gt;I&amp;rsquo;ve been wanting to document my infrastructure projects better for a while. After trying several options, I decided to set up a static blog with Hugo. The combination of Hugo + Blowfish turned out to be exactly what I needed: fast, clean, and easy to maintain.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Why Hugo and Blowfish
 &lt;div id="why-hugo-and-blowfish" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-hugo-and-blowfish" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Hugo is a static site generator written in Go. It&amp;rsquo;s incredibly fast and requires no database or complicated dependencies. Blowfish is a modern, minimalist theme that&amp;rsquo;s well documented. Both work great on a home server with limited resources.&lt;/p&gt;</description></item><item><title>WireGuard VPN: Access your home server from anywhere</title><link>https://blog.serviciosrogeliowar.com/en/posts/wireguard-vpn-servidor-dom%C3%A9stico/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/wireguard-vpn-servidor-dom%C3%A9stico/</guid><description>&lt;p&gt;One of the classic problems with having a server at home is secure remote access. Opening SSH ports directly to the world is a bad idea — you see it in the auth logs: hundreds of attempts per day. The elegant solution is a VPN, and &lt;a href="https://www.wireguard.com/" target="_blank" rel="noreferrer"&gt;WireGuard&lt;/a&gt; is today&amp;rsquo;s best available option.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Why WireGuard?
 &lt;div id="why-wireguard" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-wireguard" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Compared to &lt;a href="https://openvpn.net/" target="_blank" rel="noreferrer"&gt;OpenVPN&lt;/a&gt; or IPSec:&lt;/p&gt;</description></item><item><title>How This Blog Was Born</title><link>https://blog.serviciosrogeliowar.com/en/posts/bienvenida/</link><pubDate>Wed, 29 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/posts/bienvenida/</guid><description>&lt;p&gt;This blog was born from a real process.&lt;/p&gt;
&lt;p&gt;I had a domain, a home server, and the desire to build something of my own. Instead of following a generic tutorial, I decided to document exactly what I was doing — errors included.&lt;/p&gt;

&lt;h2 class="relative group"&gt;What you&amp;rsquo;ll find here
 &lt;div id="what-youll-find-here" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-youll-find-here" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Articles about what I&amp;rsquo;m building and learning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux server configuration&lt;/li&gt;
&lt;li&gt;Service deployment with Docker&lt;/li&gt;
&lt;li&gt;Networks, DNS, and security&lt;/li&gt;
&lt;li&gt;Automation and infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No shortcuts, no simplifications. Real process, documented step by step.&lt;/p&gt;</description></item><item><title>About Me</title><link>https://blog.serviciosrogeliowar.com/en/sobre-mi/</link><pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.serviciosrogeliowar.com/en/sobre-mi/</guid><description>&lt;h2 class="relative group"&gt;Hi, I&amp;rsquo;m Rogelio
 &lt;div id="hi-im-rogelio" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#hi-im-rogelio" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m a sysadmin passionate about real infrastructure: the kind that runs on actual hardware, not just in the cloud. I&amp;rsquo;ve spent years building and maintaining my own web infrastructure from home, learning along the way everything that courses don&amp;rsquo;t teach.&lt;/p&gt;

&lt;h2 class="relative group"&gt;What you&amp;rsquo;ll find here
 &lt;div id="what-youll-find-here" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-youll-find-here" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This blog is my public technical notebook. I document what I do, what I break, and how I fix it. No generic examples — everything comes from real cases.&lt;/p&gt;</description></item></channel></rss>