<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>VPS &amp; Security on Aquasp's blog</title><link>https://aquasp.blog/tag/vps-security/</link><description>Recent content in VPS &amp; Security on Aquasp's blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 15 May 2026 15:53:11 +0000</lastBuildDate><atom:link href="https://aquasp.blog/tag/vps-security/index.xml" rel="self" type="application/rss+xml"/><item><title>How to avoid timeouts while you are logged on SSH</title><link>https://aquasp.blog/how-to-avoid-timeouts-while-you-are-logged-on-ssh/</link><pubDate>Tue, 09 Dec 2025 01:41:02 +0000</pubDate><guid>https://aquasp.blog/how-to-avoid-timeouts-while-you-are-logged-on-ssh/</guid><description>&lt;h2 id="introduction"&gt;Introduction&#10;&lt;/h2&gt;&lt;p&gt;One of the most frustrating things when working on a server?&lt;/p&gt;&#10;&lt;p&gt;Your SSH session dies because of a brief Wi-Fi hiccup, idle timeout, or flaky connection.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Fix it forever in 30 seconds.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h2 id="the-universal-fix-edit-your-ssh-config"&gt;The Universal Fix: Edit Your SSH Config&#10;&lt;/h2&gt;&lt;p&gt;This works on &lt;strong&gt;Linux, macOS, and Windows&lt;/strong&gt; — and survives network glitches up to ~4–5 minutes.&lt;/p&gt;&#10;&lt;h3 id="step-1-create-or-edit-the-ssh-config-file"&gt;Step 1: Create or Edit the SSH Config File&#10;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;On Linux / macOS:&lt;/strong&gt;&lt;/p&gt;&#10;&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;mkdir -p ~/.ssh&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nano ~/.ssh/config&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;On Windows (PowerShell):&lt;/strong&gt;&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;# Replace YourUsername with your actual Windows username&#10;mkdir &amp;#34;$HOME\.ssh&amp;#34; -Force&#10;notepad &amp;#34;$HOME\.ssh\config&amp;#34;&#10;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="step-2-add-these-lines"&gt;Step 2: Add These Lines&#10;&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;sshHost *&#10; ServerAliveInterval 120&#10; ServerAliveCountMax 3&#10; TCPKeepAlive yes&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Save and exit.&lt;/p&gt;&#10;&lt;p&gt;Done. That’s it.&lt;/p&gt;&#10;&lt;h2 id="what-this-actually-does"&gt;What This Actually Does&#10;&lt;/h2&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Setting&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Meaning&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Host *&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Apply these rules to &lt;strong&gt;every&lt;/strong&gt; SSH connection&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ServerAliveInterval 120&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Every 2 minutes, your computer sends a tiny “I’m still here” packet&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ServerAliveCountMax 3&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;If 3 packets in a row fail → only then close the connection (~6 min)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;TCPKeepAlive yes&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Extra OS-level keepalive (helps with some routers/firewalls)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Result: Your SSH session now survives:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Wi-Fi switching&lt;/li&gt;&#10;&lt;li&gt;Laptop sleep/wake&lt;/li&gt;&#10;&lt;li&gt;Brief internet drops&lt;/li&gt;&#10;&lt;li&gt;VPN reconnects&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;…without freezing or dying.&lt;/p&gt;&#10;&lt;h2 id="youre-now-unbreakable"&gt;You&amp;rsquo;re Now Unbreakable&#10;&lt;/h2&gt;&lt;p&gt;From now on, when your internet blinks, your SSH session just… waits patiently.&lt;/p&gt;&#10;&lt;p&gt;No more “Connection reset by peer”&#10;No more lost tmux sessions&#10;No more rage&lt;/p&gt;&#10;&lt;p&gt;You’ve officially leveled up.&lt;/p&gt;&#10;&lt;p&gt;Thank you for reading — stay connected!&lt;/p&gt;&#10;</description></item><item><title>How to easily self-host at home and put your projects online under CGNAT</title><link>https://aquasp.blog/how-to-easily-self-host-at-home-and-put-your-projects-online-under-cgnat/</link><pubDate>Tue, 09 Dec 2025 01:13:41 +0000</pubDate><guid>https://aquasp.blog/how-to-easily-self-host-at-home-and-put-your-projects-online-under-cgnat/</guid><description>&lt;h2 id="introduction"&gt;Introduction&#10;&lt;/h2&gt;&lt;p&gt;Want to run heavy services on a powerful server at home, even though your ISP puts you behind CGNAT? This guide shows you exactly how to put them online — the &lt;strong&gt;old-school, bulletproof way&lt;/strong&gt; using SSH reverse tunnels.&lt;/p&gt;&#10;&lt;p&gt;No Cloudflare Tunnel. No Ngrok. Just SSH + systemd.&lt;/p&gt;&#10;&lt;h2 id="the-downsides-and-why-theyre-manageable"&gt;The Downsides (and Why They’re Manageable)&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;Home internet isn’t datacenter-grade (outages happen)&lt;/li&gt;&#10;&lt;li&gt;Most ISPs use CGNAT → you can’t open ports normally&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use a cheap VPS as a public “jump box”. Your heavy server stays home. The VPS only forwards ports.&lt;/p&gt;&#10;&lt;h2 id="how-it-works--the-magic-of-reverse-ssh-tunnels--r"&gt;How It Works – The Magic of Reverse SSH Tunnels (-R)&#10;&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Internet → Cheap VPS (public IP) → SSH reverse tunnel → Your home server (behind CGNAT)&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Your home server initiates an outbound SSH connection to the VPS and says:&#10;“Anything that hits port 8096 on you → send it to my local Jellyfin on 8096”&lt;/p&gt;&#10;&lt;p&gt;Zero ports opened on your home router. Zero exposure.&lt;/p&gt;&#10;&lt;h2 id="step-by-step-setup"&gt;Step-by-Step Setup&#10;&lt;/h2&gt;&lt;h3 id="1-on-your-home-server-the-powerful-one"&gt;1. On Your Home Server (the powerful one)&#10;&lt;/h3&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;&lt;span style="color:#75715e"&gt;# Create folder for tunnel configs&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mkdir -p /etc/sshtunnels&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Example: expose Jellyfin (port 8096)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo nano /etc/sshtunnels/jellyfin.conf&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Content of the file:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;8096:8096 # remote_port:local_port&#10;443:8443 # optional: HTTPS reverse proxy on VPS → your local 8443&#10;80:8080&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One line per service. First number = port on the &lt;strong&gt;VPS&lt;/strong&gt;, second = port on &lt;strong&gt;your home server&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;h3 id="2-generate-an-ssh-key-if-you-dont-have-one"&gt;2. Generate an SSH Key (if you don’t have one)&#10;&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-keygen -t ed25519 -C &amp;#34;home-server-tunnel&amp;#34;&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copy the public key to your VPS:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-copy-id user@your-vps-ip&#10;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="3-create-the-tunnel-manager-script"&gt;3. Create the Tunnel Manager Script&#10;&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo nano /usr/local/bin/sshtunnel.sh&#10;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;#!/bin/bash&#10;&#10;# === EDIT THESE ===&#10;REMOTE_USER=&amp;#34;root&amp;#34; # or your VPS user&#10;REMOTE_HOST=&amp;#34;123.45.67.89&amp;#34; # your VPS public IP&#10;SSH_KEY=&amp;#34;/home/youruser/.ssh/id_ed25519&amp;#34;&#10;SSH_PORT=&amp;#34;22&amp;#34; # change if you use a non-standard port&#10;# ==================&#10;&#10;INSTANCE=&amp;#34;$1&amp;#34;&#10;CONFIG_FILE=&amp;#34;/etc/sshtunnels/${INSTANCE}.conf&amp;#34;&#10;&#10;if [[ ! -f &amp;#34;$CONFIG_FILE&amp;#34; ]]; then&#10; echo &amp;#34;Error: Config file $CONFIG_FILE not found!&amp;#34;&#10; exit 1&#10;fi&#10;&#10;# Build -R arguments&#10;FORWARD_OPTS=&amp;#34;&amp;#34;&#10;while IFS=: read -r remote_port local_port; do&#10; [[ -z &amp;#34;$remote_port&amp;#34; || &amp;#34;$remote_port&amp;#34; =~ ^# ]] &amp;amp;&amp;amp; continue&#10; # Clean any old process using the remote port&#10; ssh -p &amp;#34;$SSH_PORT&amp;#34; &amp;#34;$REMOTE_USER@$REMOTE_HOST&amp;#34; \&#10; &amp;#34;lsof -i :$remote_port -t | xargs -r kill -9&amp;#34; 2&amp;gt;/dev/null&#10; FORWARD_OPTS=&amp;#34;$FORWARD_OPTS -R $remote_port:localhost:$local_port&amp;#34;&#10;done &amp;lt; &amp;#34;$CONFIG_FILE&amp;#34;&#10;&#10;echo &amp;#34;Starting tunnel $INSTANCE → $REMOTE_HOST ($FORWARD_OPTS)&amp;#34;&#10;&#10;exec ssh -o StrictHostKeyChecking=no \&#10; -o ServerAliveInterval=30 \&#10; -o ServerAliveCountThreshold=3 \&#10; -o ExitOnForwardFailure=yes \&#10; -o GatewayPorts=yes \&#10; -N -T \&#10; -i &amp;#34;$SSH_KEY&amp;#34; \&#10; -p &amp;#34;$SSH_PORT&amp;#34; \&#10; $FORWARD_OPTS \&#10; &amp;#34;$REMOTE_USER@$REMOTE_HOST&amp;#34;&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Make it executable:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo chmod +x /usr/local/bin/sshtunnel.sh&#10;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="4-create-a-systemd-service-auto-start--auto-reconnect"&gt;4. Create a Systemd Service (Auto-Start &amp;amp; Auto-Reconnect)&#10;&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo nano /etc/systemd/system/sshtunnel@.service&#10;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[Unit]&#10;Description=SSH Reverse Tunnel for %i&#10;After=network-online.target&#10;Wants=network-online.target&#10;&#10;[Service]&#10;User=youruser # ← change to your home user (not root!)&#10;Group=youruser&#10;ExecStart=/usr/local/bin/sshtunnel.sh %i&#10;Restart=always&#10;RestartSec=10&#10;&#10;[Install]&#10;WantedBy=multi-user.target&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Reload and enable:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo systemctl daemon-reload&#10;&#10;# Start a tunnel (example: jellyfin)&#10;sudo systemctl enable --now sshtunnel@jellyfin.service&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Check status:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo systemctl status sshtunnel@jellyfin.service&#10;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="5-on-the-vps-side-optional-but-recommended"&gt;5. On the VPS Side (Optional but Recommended)&#10;&lt;/h3&gt;&lt;p&gt;Install a tiny web server or Caddy/nginx to terminate TLS and proxy to the forwarded ports.&lt;/p&gt;&#10;&lt;p&gt;Example with Caddy (automatic HTTPS):&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;# On the VPS&#10;apt install caddy&#10;&#10;# /etc/caddy/Caddyfile&#10;jellyfin.yourdomain.com {&#10; reverse_proxy localhost:8096&#10;}&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now jellyfin.yourdomain.com → your home Jellyfin, fully encrypted.&lt;/p&gt;&#10;&lt;p&gt;All running on my beast home server behind CGNAT.&lt;/p&gt;&#10;&lt;h2 id="pros-of-this-setup"&gt;Pros of This Setup&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;Works behind any CGNAT / ISP block&lt;/li&gt;&#10;&lt;li&gt;No third-party dependency (no Cloudflare, no Ngrok)&lt;/li&gt;&#10;&lt;li&gt;Full encryption possible&lt;/li&gt;&#10;&lt;li&gt;Survives reboots (systemd + Restart=always)&lt;/li&gt;&#10;&lt;li&gt;Costs almost nothing&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="final-words"&gt;Final Words&#10;&lt;/h2&gt;&lt;p&gt;This is the one really cool way I’ve found to self-host heavy services at home in 2025.&lt;/p&gt;&#10;&lt;p&gt;Your powerful hardware stays home. Your $1/month VPS is just a traffic cop.&lt;/p&gt;&#10;&lt;p&gt;Thank you for reading — now go build your unstoppable home lab!&lt;/p&gt;&#10;</description></item><item><title>How to Make Your VPS Safer Against Accidental Deletions</title><link>https://aquasp.blog/how-to-make-your-vps-safer-against-accidental-deletions/</link><pubDate>Tue, 09 Dec 2025 00:31:57 +0000</pubDate><guid>https://aquasp.blog/how-to-make-your-vps-safer-against-accidental-deletions/</guid><description>&lt;h2 id="introduction"&gt;Introduction&#10;&lt;/h2&gt;&lt;p&gt;Have you ever deleted a file or a folder by mistake in a VPS? That feeling sucks. Sometimes you are working fast and you delete a really important file/folder. This happened to me previously. Today I want to share an amazing tool with you guys: &lt;code&gt;trash-cli&lt;/code&gt; . It adds a trash in the CLI to prevent these human mistakes.&lt;/p&gt;&#10;&lt;h2 id="installing-trash-cli"&gt;Installing trash-cli&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;trash-cli&lt;/code&gt; is a lightweight, command-line tool available in Debian repositories, making it ideal for VPS environments with limited resources.&lt;/p&gt;&#10;&lt;h3 id="installation-steps"&gt;Installation Steps&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;Update your package list:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;&#10;&lt;li&gt;Install &lt;code&gt;trash-cli&lt;/code&gt;:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt install trash-cli&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;&#10;&lt;li&gt;Verify the installation:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;trash --version&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should see version information if installed correctly.&lt;/p&gt;&#10;&lt;p&gt;This process is quick and adds minimal overhead to your VPS.&lt;/p&gt;&#10;&lt;h2 id="using-trash-cli-for-safer-deletions"&gt;Using trash-cli for Safer Deletions&#10;&lt;/h2&gt;&lt;p&gt;Once installed, &lt;code&gt;trash-cli&lt;/code&gt; provides commands to manage files safely. It moves items to &lt;code&gt;~/.local/share/Trash/&lt;/code&gt; instead of deleting them.&lt;/p&gt;&#10;&lt;h3 id="basic-commands"&gt;Basic Commands&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Trash a file or directory&lt;/strong&gt;: &lt;code&gt;trash file.txt&lt;/code&gt; or &lt;code&gt;trash directory&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;List trashed items&lt;/strong&gt;: &lt;code&gt;trash-list&lt;/code&gt; (shows files with deletion dates).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Restore items&lt;/strong&gt;: &lt;code&gt;trash-restore&lt;/code&gt; (interactive menu to select and recover files).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Empty the trash&lt;/strong&gt;: &lt;code&gt;trash-empty&lt;/code&gt; (permanently deletes all trashed items).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Empty old items&lt;/strong&gt;: &lt;code&gt;trash-empty 30&lt;/code&gt; (deletes items older than 30 days).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Example workflow:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;trash important_file.txt # Move to trash&#10;trash-list # Check what&amp;#39;s there&#10;trash-restore # Recover if needed&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This replaces risky &lt;code&gt;rm&lt;/code&gt; usage in daily operations.&lt;/p&gt;&#10;&lt;h2 id="aliasing-rm-to-use-trash-cli"&gt;Aliasing rm to Use trash-cli&#10;&lt;/h2&gt;&lt;p&gt;To make &lt;code&gt;rm&lt;/code&gt; safer by default, alias it to &lt;code&gt;trash&lt;/code&gt; in your shell configuration. This ensures most deletions go to the trash bin.&lt;/p&gt;&#10;&lt;h3 id="setting-up-the-alias"&gt;Setting Up the Alias&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;Edit your &lt;code&gt;~/.bashrc&lt;/code&gt; file:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;nano ~/.bashrc&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;&#10;&lt;li&gt;Add this line at the end:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;alias rm=&amp;#39;trash&amp;#39;&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Save and exit (Ctrl+X, Y, Enter).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Reload the configuration:&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;source ~/.bashrc&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, &lt;code&gt;rm file.txt&lt;/code&gt; will use &lt;code&gt;trash&lt;/code&gt; instead of permanent deletion.&lt;/p&gt;&#10;&lt;h2 id="automating-trash-emptying-with-cron"&gt;Automating Trash Emptying with Cron&#10;&lt;/h2&gt;&lt;p&gt;To prevent the trash from accumulating indefinitely, automate emptying with a cron job.&lt;/p&gt;&#10;&lt;h3 id="setting-up-weekly-emptying"&gt;Setting Up Weekly Emptying&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;Edit your crontab:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;crontab -e&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;&#10;&lt;li&gt;Add this line for weekly deletion (e.g., every Sunday at 2 AM):&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;0 2 * * 0 /usr/bin/trash-empty&#10;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;0 2 * * 0&lt;/code&gt;: Sunday at 2:00 AM.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;/usr/bin/trash-empty&lt;/code&gt;: Clears all trash.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ol start="3"&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Save and exit.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Verify:&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;crontab -l&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Adjust the schedule as needed (e.g., change &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;1-6&lt;/code&gt; for weekdays). For partial emptying, use &lt;code&gt;trash-empty 30&lt;/code&gt; to delete items older than 30 days.&lt;/p&gt;&#10;&lt;h2 id="conclusion"&gt;Conclusion&#10;&lt;/h2&gt;&lt;p&gt;By installing &lt;code&gt;trash-cli&lt;/code&gt;, aliasing &lt;code&gt;rm&lt;/code&gt; to &lt;code&gt;trash&lt;/code&gt;, and setting up automated emptying, you can make your VPS much safer against accidental deletions. This approach adds a recoverable layer without sacrificing performance. Remember to combine it with regular backups and cautious command usage. If you&amp;rsquo;re new to VPS management, start small and test thoroughly. For more advanced setups, explore integrating with monitoring tools. Stay safe out there!&lt;/p&gt;&#10;</description></item><item><title>How to make your VPS secure</title><link>https://aquasp.blog/how-to-make-your-vps-secure/</link><pubDate>Tue, 09 Dec 2025 00:30:29 +0000</pubDate><guid>https://aquasp.blog/how-to-make-your-vps-secure/</guid><description>&lt;h2 id="introduction"&gt;Introduction&#10;&lt;/h2&gt;&lt;p&gt;If you just bought a VPS and are starting to self-host, this is one of the &lt;strong&gt;most important security improvements&lt;/strong&gt; you can make.&lt;/p&gt;&#10;&lt;p&gt;By switching to SSH key authentication and disabling password login, your server becomes nearly immune to brute-force attacks — even if someone discovers your password or you&amp;rsquo;re still using the default port 22.&lt;/p&gt;&#10;&lt;h2 id="step-1-generate-an-ssh-key-pair-on-your-local-machine"&gt;Step 1: Generate an SSH Key Pair on Your Local Machine&#10;&lt;/h2&gt;&lt;h3 id="linux--macos"&gt;Linux &amp;amp; macOS&#10;&lt;/h3&gt;&lt;p&gt;Open a terminal and run:&lt;/p&gt;&#10;&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;ssh-keygen -t rsa -b &lt;span style="color:#ae81ff"&gt;4096&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or (newer recommended format):&lt;/p&gt;&#10;&lt;p&gt;Bash&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-keygen -t ed25519&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Press Enter to accept the default file location and &lt;strong&gt;leave the passphrase empty&lt;/strong&gt; (just hit Enter twice).&lt;/p&gt;&#10;&lt;p&gt;Your keys will be saved as:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Private key: ~/.ssh/id_rsa or ~/.ssh/id_ed25519&lt;/li&gt;&#10;&lt;li&gt;Public key: ~/.ssh/id_rsa.pub or ~/.ssh/id_ed25519.pub&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;Never share the private key!&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h3 id="windows-powershell"&gt;Windows (PowerShell)&#10;&lt;/h3&gt;&lt;p&gt;Open PowerShell and run:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-keygen.exe -t ed25519&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(or -t rsa -b 4096 if ed25519 is not supported)&lt;/p&gt;&#10;&lt;p&gt;Press Enter through the prompts (no passphrase). Keys will be created in C:\Users\YourUser.ssh\&lt;/p&gt;&#10;&lt;h2 id="step-2-copy-your-public-key-to-the-vps"&gt;Step 2: Copy Your Public Key to the VPS&#10;&lt;/h2&gt;&lt;h3 id="linux--macos-easiest-method"&gt;Linux &amp;amp; macOS (Easiest Method)&#10;&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-copy-id user@your-vps-ip&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Replace user and your-vps-ip with your actual username and server IP.&lt;/p&gt;&#10;&lt;h3 id="windows"&gt;Windows&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;Paste your public key (it’s one long line starting with ssh-ed25519 or ssh-rsa) → Save with &lt;strong&gt;Ctrl+O → Enter → Ctrl+X&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;Test it: Open a &lt;strong&gt;new&lt;/strong&gt; terminal/PowerShell and try logging in. It should work &lt;strong&gt;without asking for a password&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Edit the file:Bash&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;nano ~/.ssh/authorized_keys&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Create the .ssh folder and authorized_keys file (if they don&amp;rsquo;t exist):Bash&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir -p ~/.ssh&#10;chmod 700 ~/.ssh&#10;touch ~/.ssh/authorized_keys&#10;chmod 600 ~/.ssh/authorized_keys&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Log into your VPS normally (with password):PowerShell&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;ssh user@your-vps-ip&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copy your public key to clipboard:PowerShell&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;Get-Content $HOME\.ssh\id_ed25519.pub | Set-Clipboard&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(or id_rsa.pub if you used RSA)&lt;/p&gt;&#10;&lt;h2 id="step-3-disable-password-authentication"&gt;Step 3: Disable Password Authentication&#10;&lt;/h2&gt;&lt;p&gt;Now that key login works, disable password login entirely.&lt;/p&gt;&#10;&lt;p&gt;Log into your VPS (using your key) and edit the SSH config:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo nano /etc/ssh/sshd_config&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Find and change (or add) these lines:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;PasswordAuthentication no&#10;ChallengeResponseAuthentication no&#10;UsePAM no&#10;PubkeyAuthentication yes&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Save and exit.&lt;/p&gt;&#10;&lt;p&gt;Restart the SSH service:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo systemctl restart sshd&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(or sudo service ssh restart on older systems)&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Final test&lt;/strong&gt;: Try logging in from a new terminal. It should only work with your private key — password attempts will be rejected instantly.&lt;/p&gt;&#10;&lt;h2 id="done"&gt;Done!&#10;&lt;/h2&gt;&lt;p&gt;Your VPS is now protected against:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Brute-force attacks&lt;/li&gt;&#10;&lt;li&gt;Credential stuffing&lt;/li&gt;&#10;&lt;li&gt;Weak or leaked passwords&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Even if an attacker knows your username and password, they &lt;strong&gt;cannot log in&lt;/strong&gt; without your private key file.&lt;/p&gt;&#10;&lt;p&gt;Pro tip: Back up your private key securely and consider adding a passphrase later using ssh-keygen -p.&lt;/p&gt;&#10;&lt;p&gt;Thank you for reading! 😊&lt;/p&gt;&#10;</description></item><item><title>Page Cache, Object Cache and CDN cache - Understanding all types of caching</title><link>https://aquasp.blog/page-cache-object-cache-and-cdn-cache-understanding-all-types-of-caching/</link><pubDate>Mon, 08 Dec 2025 23:13:04 +0000</pubDate><guid>https://aquasp.blog/page-cache-object-cache-and-cdn-cache-understanding-all-types-of-caching/</guid><description>&lt;hr&gt;&#10;&lt;h2 id="understanding-the-different-types-of-caching-especially-for-scaling-cms-sites"&gt;Understanding the Different Types of Caching (Especially for Scaling CMS Sites)&#10;&lt;/h2&gt;&lt;p&gt;If you’ve ever wondered what people mean when they talk about “page cache,” “object cache,” or “CDN cache,” this post is for you. These are the three main caching layers that make a massive difference when scaling WordPress, WooCommerce, or any other CMS.&lt;/p&gt;&#10;&lt;h2 id="what-is-page-caching"&gt;What is Page Caching?&#10;&lt;/h2&gt;&lt;p&gt;Page caching (also called &lt;strong&gt;full-page caching&lt;/strong&gt; or &lt;strong&gt;HTML caching&lt;/strong&gt;) is exactly what it sounds like: the entire rendered HTML page is saved as a static file.&lt;/p&gt;&#10;&lt;p&gt;With a truly static site (plain HTML + CSS + JS), there’s no need for page caching because every file is already static.&#10;But with a CMS like WordPress, every request normally triggers PHP → theme → plugins → database queries → HTML output. That process eats CPU and takes time.&lt;/p&gt;&#10;&lt;p&gt;Full-page caching shortcuts all of that. The first visitor triggers the full PHP+MySQL process, the resulting HTML is saved, and every visitor after that gets served the pre-generated static HTML instantly — no PHP, no database queries, almost zero CPU.&lt;/p&gt;&#10;&lt;p&gt;Result: 10–100× lower server load and dramatically faster page loads.&lt;/p&gt;&#10;&lt;h2 id="what-is-object-caching"&gt;What is Object Caching?&#10;&lt;/h2&gt;&lt;p&gt;Object caching stores the results of expensive database queries (or any slow computation) in fast memory (usually Redis or Memcached).&lt;/p&gt;&#10;&lt;p&gt;Think of it as a super-fast middleman between your PHP code and the database.&lt;/p&gt;&#10;&lt;p&gt;Example with WordPress:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;WordPress needs the list of published posts → it asks MySQL.&lt;/li&gt;&#10;&lt;li&gt;First request: MySQL does the work, returns the data, object cache saves it in RAM.&lt;/li&gt;&#10;&lt;li&gt;Next 10 000 requests: object cache instantly returns the same data from memory → MySQL sleeps peacefully.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Object cache is smart — it automatically invalidates itself when data changes (e.g., you publish a new post).&lt;/p&gt;&#10;&lt;p&gt;Why you still need it even with full-page caching:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Logged-in users (including the WordPress dashboard, WooCommerce account pages, etc.) can’t be fully cached for everyone.&lt;/li&gt;&#10;&lt;li&gt;Those pages still hit PHP and MySQL → object cache makes them tolerable instead of painfully slow.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Object cache + full-page cache together is the classic high-traffic combo.&lt;/p&gt;&#10;&lt;h2 id="what-is-cdn-caching"&gt;What is CDN Caching?&#10;&lt;/h2&gt;&lt;p&gt;A CDN (Content Delivery Network) copies your static assets (CSS, JS, images, fonts) — and optionally your full HTML pages — to “PoP” servers all over the world.&lt;/p&gt;&#10;&lt;p&gt;Without a CDN: a visitor in Japan downloads everything from your origin server in, say, Brazil → high latency.&lt;/p&gt;&#10;&lt;p&gt;With a CDN:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Static files are served from the closest PoP (often &amp;lt; 30 ms away).&lt;/li&gt;&#10;&lt;li&gt;If you also enable full-page caching on the CDN, the entire HTML page is served from that nearby PoP too → the origin server is never touched for cached pages.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;This is why some sites load instantly from anywhere on the planet.&lt;/p&gt;&#10;&lt;h2 id="real-world-example-wordpress-traffic-flow"&gt;Real-World Example: WordPress Traffic Flow&#10;&lt;/h2&gt;&lt;h3 id="no-caching-at-all"&gt;No caching at all&#10;&lt;/h3&gt;&lt;p&gt;Visitor → Web server → PHP → dozens of plugin files → MySQL queries → HTML → visitor&#10;→ High CPU, slow TTFB, easily hits resource limits.&lt;/p&gt;&#10;&lt;h3 id="with-full-page-caching-only"&gt;With full-page caching only&#10;&lt;/h3&gt;&lt;p&gt;First visitor: same slow path as above (but the HTML is saved).&#10;Next 10 000 visitors: Web server instantly serves the pre-built HTML → almost zero CPU.&lt;/p&gt;&#10;&lt;h3 id="with-object-caching-only"&gt;With object caching only&#10;&lt;/h3&gt;&lt;p&gt;Every request still runs PHP + plugins, but database queries are answered from RAM instead of disk → faster than no cache, but still heavy.&lt;/p&gt;&#10;&lt;h3 id="with-full-page-cache--object-cache"&gt;With full-page cache + object cache&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;Anonymous visitors → static HTML (super fast, almost no load)&lt;/li&gt;&#10;&lt;li&gt;Logged-in users → PHP runs, but object cache makes DB queries instant → manageable load&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="add-cdn-with-full-page-caching-on-top"&gt;Add CDN with full-page caching on top&#10;&lt;/h3&gt;&lt;p&gt;Even the static HTML is now served from edge locations worldwide. Your origin server can basically take a nap until something actually needs PHP (e.g., form submissions, cache invalidation).&lt;/p&gt;&#10;&lt;h2 id="conclusion"&gt;Conclusion&#10;&lt;/h2&gt;&lt;p&gt;Here’s the hierarchy from most impactful to least (for most CMS sites):&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Full-page caching on the CDN&lt;/strong&gt; → fastest for visitors, scales to millions of hits with almost zero origin load.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Full-page caching on the origin&lt;/strong&gt; → still massive win if you can’t cache on the CDN.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Object caching (Redis/Memcached)&lt;/strong&gt; → mandatory for logged-in users, WooCommerce, dashboards, etc.&lt;/li&gt;&#10;&lt;li&gt;Everything else (OPcache, browser cache, etc.) → nice to have, usually enabled by default.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;If you only do one thing: enable proper full-page caching (and push it to your CDN if possible).&#10;If you have logged-in traffic or a shop: add Redis/Memcached object caching.&lt;/p&gt;&#10;&lt;p&gt;That’s it — the three caching layers that power basically every high-traffic WordPress site on the planet.&lt;/p&gt;&#10;&lt;p&gt;Hope this cleared things up!&lt;/p&gt;&#10;&lt;p&gt;Thanks for reading! 😊&lt;/p&gt;&#10;</description></item></channel></rss>