{"id":48,"date":"2026-09-06T11:24:13","date_gmt":"2026-09-06T11:24:13","guid":{"rendered":"https:\/\/nodeguard.io\/blog\/?p=48"},"modified":"2026-10-17T21:58:17","modified_gmt":"2026-10-17T19:58:17","slug":"how-to-secure-a-linux-vps","status":"publish","type":"post","link":"https:\/\/nodeguard.io\/blog\/how-to-secure-a-linux-vps\/","title":{"rendered":"How to Secure a Linux VPS: Essential Ubuntu 26.04 Hardening Guide"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Your VPS is not anonymous. The moment an IPv4 address is assigned to your server, it becomes part of a public range that automated scanners sweep continuously. Log in to a brand-new box, run <code>journalctl -u ssh --since \"10 minutes ago\"<\/code>, and you will usually find failed root logins already stacking up \u2014 from hosts you have never heard of, in countries you have never visited.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"540\" src=\"https:\/\/nodeguard.io\/blog\/wp-content\/uploads\/2026\/09\/secure-a-linux-vps-failed-ssh-logins.webp\" alt=\"How to secure a Linux VPS \u2014 failed SSH login attempts on a fresh server\" class=\"wp-image-70\" srcset=\"https:\/\/nodeguard.io\/blog\/wp-content\/uploads\/2026\/09\/secure-a-linux-vps-failed-ssh-logins.webp 1200w, https:\/\/nodeguard.io\/blog\/wp-content\/uploads\/2026\/09\/secure-a-linux-vps-failed-ssh-logins-300x135.webp 300w, https:\/\/nodeguard.io\/blog\/wp-content\/uploads\/2026\/09\/secure-a-linux-vps-failed-ssh-logins-767x345.webp 767w, https:\/\/nodeguard.io\/blog\/wp-content\/uploads\/2026\/09\/secure-a-linux-vps-failed-ssh-logins-1024x461.webp 1024w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><figcaption class=\"wp-element-caption\">Eleven minutes after provisioning: 1,284 failed login attempts, none of them personal.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">None of that is personal. It is background radiation. Bots enumerate address space, knock on port 22, try <code>root:admin<\/code>, <code>root:123456<\/code>, <code>ubuntu:ubuntu<\/code>, and move on. The overwhelming majority of compromised servers are not victims of clever attacks; they are victims of defaults left untouched.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The good news is that the fix is boring and finite. You can secure a Linux VPS to a genuinely respectable baseline in about thirty minutes, and most of that time is spent waiting for <code>apt<\/code> to finish. This guide walks through the sequence we would follow on any new Ubuntu or Debian box, with the reasoning behind each step, because a checklist you understand is one you will actually maintain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Tested on Ubuntu 26.04 LTS. Every command below also works unchanged on Ubuntu 24.04 LTS and Debian 13 except where noted.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Start From a Clean, Current Image<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Security begins before your first SSH session. When you deploy, choose a current LTS release rather than whatever is familiar \u2014 Ubuntu 26.04 LTS or Debian 13 both carry years of security support ahead of them, which means patches keep arriving without a distribution upgrade in the middle of your busiest quarter. An OS approaching end of life is a slow-motion vulnerability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your provider offers SSH key injection at deploy time, use it. Every NodeGuard <a href=\"\/cloud-vps\" data-type=\"link\" data-id=\"\/cloud-vps\">Cloud VPS<\/a> can be provisioned with your public key already in place, which means the server never has a password-authenticated root account exposed to the internet, not even for the ten minutes it takes you to configure one. That closes the single most common window of exposure entirely.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Patch Before You Do Anything Else<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Images are snapshots. Even a freshly published one was built days or weeks ago, and the packages inside it are frozen at that moment. Your first command should always be:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt full-upgrade -y\nsudo reboot\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>full-upgrade<\/code> rather than <code>upgrade<\/code> matters here: it allows packages to be added or removed when dependencies changed, which is exactly what happens with kernel and library updates. Reboot afterward if the kernel was replaced \u2014 a patched kernel sitting on disk while the vulnerable one is still running protects nobody.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create a Non-Root User With sudo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Working as root is a habit worth breaking. Not because root is inherently dangerous, but because it removes the pause between intent and consequence. A mistyped <code>rm -rf<\/code> under a normal account throws a permission error; the same command as root does exactly what you asked.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adduser alex\nusermod -aG sudo alex\nrsync --archive --chown=alex:alex ~\/.ssh \/home\/alex\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That last line copies your existing authorized key to the new user before you lock root out \u2014 skip it and you will lock yourself out instead. Open a <strong>second terminal<\/strong> and confirm you can log in as the new user and run <code>sudo -v<\/code> successfully. Do not close your original session until that works. This is the single most common way people strand themselves on a fresh server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lock Down SSH<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH is the front door, and it deserves the most attention. Edit <code>\/etc\/ssh\/sshd_config<\/code> or, better, drop a file into <code>\/etc\/ssh\/sshd_config.d\/99-hardening.conf<\/code> so your changes survive package upgrades cleanly. Every directive here is documented in the <a href=\"https:\/\/man.openbsd.org\/sshd_config\" data-type=\"link\" data-id=\"https:\/\/man.openbsd.org\/sshd_config\" target=\"_blank\" rel=\"noreferrer noopener\">OpenSSH manual<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PermitRootLogin no\nPasswordAuthentication no\nKbdInteractiveAuthentication no\nPubkeyAuthentication yes\nMaxAuthTries 3\nX11Forwarding no\nAllowUsers alex<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you have a static IP or connect through a <a href=\"\/secure-vpn\" data-type=\"link\" data-id=\"\/secure-vpn\">VPN<\/a>, tighten it further with <code>AllowUsers alex@your.static.ip<\/code> so SSH only answers from an address you control.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why key-only authentication is non-negotiable<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A strong password is guessable given enough attempts; a 4096-bit RSA or Ed25519 key is not, in any timeframe that matters. Turning off password authentication does not merely make brute-force attacks harder \u2014 it makes them structurally impossible. The bots will keep knocking, and every attempt will fail at the protocol level before a password is ever evaluated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generate your key locally, never on the server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-keygen -t ed25519 -C \"workstation-2026\"\nssh-copy-id alex@your-server-ip\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Changing the port, and one modern gotcha<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Moving SSH off port 22 is not real security \u2014 a port scan finds it in seconds \u2014 but it does cut log noise by an enormous margin, which makes genuine anomalies visible. If you change it, be aware of a change in recent releases: <strong>Ubuntu 24.04 and 26.04 use socket activation for SSH.<\/strong> The <code>Port<\/code> directive in <code>sshd_config<\/code> is ignored, because <code>systemd<\/code> owns the listening socket. Setting a new port and reloading will appear to work and then refuse connections.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The most reliable fix is to bypass socket activation entirely:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl disable --now ssh.socket\nsudo systemctl enable --now ssh.service\nsudo ss -tulpn | grep sshd\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That final verification step is the important one. Always confirm the daemon is listening where you think it is, from a second session, before you disconnect.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Put a Default-Deny Firewall in Front<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A firewall&#8217;s job is not to block known-bad traffic. It is to permit only known-good traffic, so that a service you forgot you installed cannot quietly accept connections from the world.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ufw default deny incoming\nsudo ufw default allow outgoing\nsudo ufw allow 2222\/tcp    # your SSH port \u2014 add this FIRST\nsudo ufw allow 80,443\/tcp\nsudo ufw enable\nsudo ufw status verbose\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add the SSH rule before enabling, every single time. UFW will warn you, and the warning is not decorative.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two things worth knowing. First, databases should almost never appear in this list \u2014 MariaDB, PostgreSQL, and Redis belong bound to <code>127.0.0.1<\/code>, reachable by your application and nothing else. Second, if you sit behind a CDN or proxy such as Cloudflare, your firewall sees the proxy&#8217;s IP rather than the visitor&#8217;s. Restore the real client IP at the web-server layer, or your logs and rate limits will be measuring the wrong thing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Slow Down Brute Force With Fail2Ban<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Even with key-only SSH, repeated failed attempts consume resources and bury real events in noise. <a href=\"https:\/\/github.com\/fail2ban\/fail2ban\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/github.com\/fail2ban\/fail2ban\" rel=\"noreferrer noopener\">Fail2Ban<\/a> reads your logs and firewalls off repeat offenders automatically.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install fail2ban -y\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create <code>\/etc\/fail2ban\/jail.local<\/code> \u2014 never edit <code>jail.conf<\/code>, which package updates overwrite:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;DEFAULT]\nbantime  = 1h\nfindtime = 10m\nmaxretry = 5\nbackend  = systemd<\/code><\/pre>\n\n\n<p>[sshd]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">enabled = true port = 2222<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On current Ubuntu and Debian releases the <code>systemd<\/code> backend matters, because journald has largely replaced flat log files. Check your work with <code>sudo fail2ban-client status sshd<\/code>. Also whitelist your own static IP under <code>ignoreip<\/code> if you have one \u2014 Fail2Ban does not distinguish between an attacker and a sysadmin who fat-fingered a passphrase five times.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Turn On Automatic Security Updates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The gap between a vulnerability being <a href=\"https:\/\/ubuntu.com\/security\/notices\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/ubuntu.com\/security\/notices\" rel=\"noreferrer noopener\">disclosed<\/a> and being exploited at scale is now measured in hours. Manual patching cannot win that race, and most breaches exploit something that was fixed upstream weeks earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install unattended-upgrades -y\nsudo dpkg-reconfigure --priority=low unattended-upgrades\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The default configuration applies security updates only, which is the right balance \u2014 you get patched without feature updates surprising you at 3 a.m. If you want unattended reboots for kernel updates, enable <code>Unattended-Upgrade::Automatic-Reboot<\/code> with a scheduled time, and make sure your services start cleanly on boot before you trust it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reduce the Attack Surface<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every listening service is a potential entry point. Audit what your server is actually exposing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ss -tulpn\nsudo systemctl list-units --type=service --state=running\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Look for anything you did not deliberately install. Stock images frequently ship with services you will never use. Remove them rather than merely stopping them \u2014 an uninstalled package cannot be started by a dependency later. Where a service must run but only serves local traffic, bind it to <code>127.0.0.1<\/code> instead of <code>0.0.0.0<\/code>. That one change is worth more than most firewall rules, because it holds even if the firewall is misconfigured.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Harden the Kernel and Shared Memory<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A small set of <code>sysctl<\/code> values closes off common network-level tricks. Add them to <code>\/etc\/sysctl.d\/99-hardening.conf<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>net.ipv4.conf.all.rp_filter = 1\nnet.ipv4.conf.all.accept_redirects = 0\nnet.ipv4.conf.all.send_redirects = 0\nnet.ipv4.conf.all.accept_source_route = 0\nnet.ipv4.icmp_echo_ignore_broadcasts = 1\nnet.ipv4.tcp_syncookies = 1\nkernel.dmesg_restrict = 1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Apply with <code>sudo sysctl --system<\/code>. These are conservative, widely deployed settings; they will not break a normal web or application server, and they remove several classes of spoofing and reconnaissance outright.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Secure the Application Layer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Server hardening is necessary but insufficient. In practice, the majority of real-world compromises on hosting infrastructure arrive through the application, not the operating system.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Serve everything over TLS.<\/strong> Certbot issues free <a href=\"https:\/\/letsencrypt.org\/\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/letsencrypt.org\/\" rel=\"noreferrer noopener\">Let&#8217;s Encrypt<\/a> certificates and renews them automatically. Redirect HTTP to HTTPS at the web server or CDN, and enable HSTS once you are confident the site works without exception.<\/li>\n\n\n\n<li><strong>Use per-application database users.<\/strong> One database, one user, only the privileges that application needs. A SQL injection in a marketing site should never expose your billing data.<\/li>\n\n\n\n<li><strong>Isolate PHP applications.<\/strong> Separate PHP-FPM pools per site, each running as its own system user, mean a compromised plugin in one site cannot read files belonging to another.<\/li>\n\n\n\n<li><strong>Keep <a href=\"\/wordpress-hosting\" data-type=\"link\" data-id=\"\/wordpress-hosting\">WordPress<\/a> lean.<\/strong> Most WordPress breaches trace back to an abandoned plugin or theme. Delete what you do not use, enable automatic updates for the core and for plugins you trust, and enforce strong credentials with two-factor authentication on admin accounts.<\/li>\n\n\n\n<li><strong>Restrict file permissions.<\/strong> Web roots should be <code>755<\/code> for directories and <code>644<\/code> for files, owned by a user the web server can read but generally cannot write.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Back Up as Though You Will Need It<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Assume, calmly, that something will eventually go wrong \u2014 a bad deploy, a failed disk, a successful attack. The question is not whether you have backups, but whether you have <em>restores<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A workable pattern: a nightly <code>mysqldump<\/code> plus a compressed archive of your web roots, retained locally for a week, and copied off-server to separate storage. Backups that live only on the machine they protect are not backups. And schedule a restore drill \u2014 pull last night&#8217;s archive onto a scratch server and bring the site up. The first time you attempt a restore should never be during an incident.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Watch What You Have Built<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hardening is a state, not an event. A light monitoring rhythm keeps that state from decaying:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Review authentication failures and Fail2Ban bans weekly: <code>sudo lastb | head -20<\/code><\/li>\n\n\n\n<li>Confirm unattended upgrades are actually applying: <code>cat \/var\/log\/unattended-upgrades\/unattended-upgrades.log<\/code><\/li>\n\n\n\n<li>Track disk, memory, and load, so that a resource anomaly reaches you before your visitors do<\/li>\n\n\n\n<li>Watch for unexpected outbound connections \u2014 compromised servers usually phone home<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How to Secure a Linux VPS: Your 30-Minute Checklist<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Deploy a current LTS image with your SSH key injected<\/li>\n\n\n\n<li><code>apt update &amp;&amp; apt full-upgrade<\/code>, then reboot<\/li>\n\n\n\n<li>Create a sudo user, copy your key, verify in a second terminal<\/li>\n\n\n\n<li>Disable root login and password authentication in <code>sshd_config.d<\/code><\/li>\n\n\n\n<li>Change the SSH port, working around socket activation, and verify with <code>ss -tulpn<\/code><\/li>\n\n\n\n<li>Enable UFW with default-deny, allowing SSH first<\/li>\n\n\n\n<li>Install Fail2Ban with a <code>jail.local<\/code> using the systemd backend<\/li>\n\n\n\n<li>Enable <code>unattended-upgrades<\/code><\/li>\n\n\n\n<li>Audit listening services; bind local-only services to <code>127.0.0.1<\/code><\/li>\n\n\n\n<li>Apply <code>sysctl<\/code> hardening<\/li>\n\n\n\n<li>Issue TLS certificates and lock down the application layer<\/li>\n\n\n\n<li>Configure off-server backups \u2014 and test a restore<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">None of this is exotic. It is the same sequence experienced administrators run on autopilot, and it eliminates the overwhelming majority of opportunistic attacks, because opportunistic attacks depend entirely on defaults.<\/p>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-question-1788699979152\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">How do I secure a Linux VPS?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Secure a Linux VPS by working through a fixed sequence: patch the system fully, create a non-root sudo user, switch SSH to key-only authentication and disable root login, enable a default-deny firewall, install Fail2Ban, and turn on automatic security updates. Those six steps stop the overwhelming majority of automated attacks, because automated attacks depend entirely on defaults being left in place. Everything after that \u2014 kernel tuning, application hardening, backups \u2014 reduces the damage of the attacks that get past the first layer.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1788700027300\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">How long does it take to harden a new VPS?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>About thirty minutes for the core baseline, and most of that is spent waiting for <code>apt<\/code> to finish rather than typing. The steps that matter most \u2014 key-only SSH, a default-deny firewall, and unattended upgrades \u2014 take roughly ten minutes combined. Backups and application-layer hardening take longer and are worth scheduling separately, but the server is no longer low-hanging fruit once the first ten minutes are done.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1788700040961\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Is changing the SSH port worth it?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Changing the SSH port is not a security measure, because a port scan finds the new port in seconds. It is a noise-reduction measure, and that is still valuable: moving off port 22 cuts automated login attempts by an enormous margin, which makes genuine anomalies visible in your logs instead of buried under thousands of bot entries. Change it if you want readable logs. Do not change it and consider the server secured.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1788700064217\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Do I still need Fail2Ban if I use SSH keys?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Yes, though for a different reason than most people assume. With password authentication disabled, brute-force attempts cannot succeed \u2014 but they still consume CPU, bandwidth and log space, and they bury real events in noise. Fail2Ban also protects services beyond SSH, including web application logins and mail. Treat it as noise control and multi-service coverage rather than as your primary SSH defence.<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">At NodeGuard, our <a href=\"\/cloud-vps\" data-type=\"link\" data-id=\"\/cloud-vps\">Cloud VPS<\/a> instances ship with key-based access from first boot, automated monitoring, and clean current images across Ubuntu, Debian, AlmaLinux, Rocky, and Fedora \u2014 so the baseline above starts closer to done. Plans begin at \u20ac7\/month with full root access, which means the server is genuinely yours to configure.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Harden it once, properly, and then get back to building the thing you actually wanted the server for.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>Your VPS is not anonymous. The moment an IPv4 address is assigned to your server, it becomes part of a public range\u2026<\/p>\n","protected":false},"author":2,"featured_media":62,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,18],"tags":[44,40,36,6,33,35,43,37,5,38,41,39,42,34,45],"class_list":["post-48","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security","category-linux","tag-cloud-vps","tag-debian-13","tag-fail2ban","tag-linux-server","tag-linux-vps","tag-server-hardening","tag-ssh-keys","tag-ssh-security","tag-sysadmin","tag-ubuntu-26-04","tag-ubuntu-server","tag-ufw-firewall","tag-unattended-upgrades","tag-vps-security","tag-web-hosting-security"],"_links":{"self":[{"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/posts\/48","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/comments?post=48"}],"version-history":[{"count":13,"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/posts\/48\/revisions"}],"predecessor-version":[{"id":87,"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/posts\/48\/revisions\/87"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/media\/62"}],"wp:attachment":[{"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/media?parent=48"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/categories?post=48"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nodeguard.io\/blog\/wp-json\/wp\/v2\/tags?post=48"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}