A few ideas on securing a (Cardano node) Linux server

This overview doesn’t aim to be comprehensive, but it gives a few ideas on the minimum required to secure any server accessible from the Internet. Many thanks to Tony from @EliteStakePool as he graciously reviewed and added more input. A physical firewall might be best, however it’s obviously not the same cost. I’ll focus on using mostly FOSS and a very basic network topology.

  • Use a stable production release of your favorite GNU/Linux distribution. With the latest or testing releases of packages come the latest bugs, regressions, and incompatibilities.

  • Always install security updates, use the latest microcode for your CPU, upgrade your BIOS.

  • Always use strong passphrases and encryption whenever possible.

  • Follow good practices and advices on hardening GNU/Linux OS, e.g.

  • Use a Host-based or Network-based Intrusion Prevention Systems or an Intrusion Detection System, depending on your needs, to be installed using the package manager of your distribution whenever possible (when not the case it’s sometimes possible to package an installation from sources, e.g. with checkinstall).

  • Use rkhunter or chkrootkit to check for potential rootkits.

  • Harden Linux kernel in order to make it tougher to use 0-day exploits and/or rootkits, e.g. apply grsecurity patch set https://www.grsecurity.net/ on Linux kernel before compiling it.

  • Use and configure properly your firewall, it doesn’t matter that you use nft, iptables or ufw as long Netfilter is up and running.

  • Avoid letting exploits be executed on world accessible partitions like /tmp or /dev/shm by using flags noexec,nosuid,nodev in /etc/fstab.

  • Avoid running services as root.

  • Limit the programs with suid or sgid bit set, you may list them all with

    • $ sudo find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -l {} \;
  • Disable any unneeded open port/service or at least filter them using an adequate firewall rule. You have several options to list open ports with their associated service (some of these commands will also list services listening on 127.0.0.1 which is on the lo interface i.e. loopback):

    • $ sudo netstat -latupen
    • $ sudo lsof -i
    • $ sudo ss -antlp
  • Use firewall rules to mitigate DoS attacks, port flooding by using connlimit rules, see iptables-extensions(8) for examples.

  • It might also be useful to add a rule with target LOG before dropping packets.

  • Monitor logged on users and activities with w or who, e.g. sudo watch -d -n5 w.

  • Use quotas to mitigate a few resources exhaustion attacks, e.g. fork bombs, see all with ulimit -a (bash builtin).

  • A simple vulnerability scan can be conducted using nmap, it won’t be as precise or comprehensive as a commercial vulnerability scanner, though. For instance :

    • $ sudo nmap --script vuln <target>
      In this case, be aware that when using localhost as target, you’ll also scan for services listening on loopback interface but not if you use an external IP address.
  • For those using systemd services, their security may be checked with systemd-analyze security. It’s possible to harden every UNSAFE or EXPOSED service without messing with the distribution service file by adding an override.conf file in /etc/systemd/system/unit.service.d/ directory (unit being the name of any systemd service). Directives (like ProtectHome, ProtectSystem, ProtectHostname, etc.) are described in systemd.exec(5). The command line to do it is systemctl edit unit.service.

  • a simple overview of system health, load and security events might be easily be set up, using a terminal multiplexer like tmux (and eventually tmuxp session manager to reproduce a tmux session from a YAML/JSON file). Quick, light on resources and secure for remote access via SSH, a text-mode alternative or complement to Grafana. For example: dmesg, journalctl, iptables, tload, htop, systemctl, alone or with any combination of watch, tail, grep…

  • If a remote access using SSH is needed then you might want to :

    • use a different port than the well-known 22/tcp
    • use port knocking
    • disable banners
    • define a number of max concurrent sessions
    • add fail2ban in order to delay any attempt at brute-forcing or password guessing
    • disable root access (you will still be able to sudo su or su when connected)
    • preferably use authentication by certificate, instead of a passphrase
    • when possible, restrict access to the only IP address you’ll be using to connect.
  • Last but not least, instead of providing open services, it’s always possible to use SSH tunneling in order to encrypt traffic and control access to any local service, a few examples here.

4 Likes

Hi @raph_cardano

Very interesting list, you did point the important things.
Recently we have posted a blog post touching basic node security, with how to:
basic-node-security

We also wrote a small bash script that does basic checks of your node [Linux distro].
automation_script

We encourage new stake pool operators who are not sure how to harden their nodes to go visit our blog and read up your post.

I’ve enjoyed the read, thank you.

1 Like

Hi @olimp_pool, great initiative :+1: thank you for your feedback and effort :pray:

1 Like