Skip to content

About

πŸš€ Secure your Linux VPS or Pi effortlessly! Easy Server Security is a zero-dependency Python hardening tool. πŸ§… Features a friendly interactive menu, safe dry-runs, and auto-configures SSH, firewalls & sysctl. 🍟 Guaranteed not to lock you out! πŸ₯” Get a plain-English security score in seconds. πŸ”’

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

3 Commits

Folders and files

Repository files navigation

Easy Server Security

Every Linux admin has a mental checklist they re-do by hand on every new box. This is that checklist, with a menu on the front.

You spin up a fresh VPS. Or you flash Raspberry Pi OS onto a card and stick the Pi in a drawer. Then you do the dance: harden SSH, set up the firewall, install fail2ban, turn on unattended upgrades, poke at sysctl, remember that thing about NTP you always forget until TLS starts failing three weeks later.

It takes half an hour if you're quick. It takes half an hour every time. And if you're honest, somewhere around the fourth server you started skipping steps.

sudo python3 main.py

That opens a menu. Everything is in there. No flags to memorise, no --help to go read first.

 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
 β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β•   β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•
 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•    β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘
 β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β•šβ•β•β•β•β–ˆβ–ˆβ•‘  β•šβ–ˆβ–ˆβ•”β•     β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•‘
 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
 β•šβ•β•β•β•β•β•β•β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•   β•šβ•β•      β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β• β•šβ•β•β•β•β•β•

   [1]  Quick harden          recommended defaults, no questions
   [2]  Guided harden         confirm each step as you go
   [3]  Dry run               preview everything, change nothing
   [4]  Check status          what's secured, what's drifted
   [5]  Full report           plain-English summary you can save
   [6]  Optional hardening    the extras, separately
   [7]  Settings              ports, SSH key, forwarding
   [8]  About
   [q]  Quit

Why this one and not the other twelve hardening scripts

Because most of them will lock you out of your own server and shrug about it.

That's the failure mode that actually matters. Thorough is easy β€” anyone can sed a config file into oblivion. The real question is whether the thing hardening your SSH access is careful enough not to strand you outside your own machine at 2am with nothing but a provider's terrible web console.

Easy Server Security is built around that:

  • Password auth is never disabled on a hope. It only goes off if a real, non-empty authorized_keys exists. If there isn't one, it says so plainly and leaves password login alone rather than silently welding the door shut.
  • In guided mode you have to confirm you tested key login in a separate session before it touches password auth.
  • The new sshd config is validated before it's ever loaded. sshd -t fails, it rolls back, nothing changes.
  • It reloads sshd, never restarts it. Your current session survives. Always.
  • The sudo policy is checked with visudo before install β€” and if visudo isn't available, it refuses to write the file at all rather than risk breaking sudo.
  • Dry run shows every change before you commit to any of them, and doesn't even need root.

Safety isn't a bullet at the bottom of this README. It's the reason the tool is shaped the way it is.


What it actually does

18 core steps, applied by default. All idempotent, all re-checkable any time.

SSH hardening Root login off, key-only auth, MaxAuthTries 3, 30s grace, idle timeout, no X11/agent forwarding. Optional port change
Firewall Default-deny in, allow out. Auto-detects ufw or nftables. SSH rate-limited as your first brute-force speed bump
fail2ban Sane sshd jail. Detects nginx / apache / postfix if running and wires up jails for them too
Unattended upgrades Security patches land on their own. apt or dnf, whichever you have
sysctl hardening SYN cookies, no source routing, no ICMP redirects, ignore broadcast pings, reverse path filtering, martian logging, restricted kernel pointers
Password policy Ageing, 12-char minimum with complexity, umask 027, account lockout after 5 failures
File permissions Locks down passwd, shadow, group, sshd_config, grub.cfg. Reports world-writable files
Account audit Locks empty-password accounts. Flags duplicate UIDs and sudo access that's grown generous
Sudo policy Command logging, credential cache limits, flags every passwordless rule
Service cleanup Finds telnet, rsh, rlogin, tftp, rpcbind and friends still breathing, puts them down
Kernel modules Blocks 11 filesystems and protocols a normal server never uses β€” cramfs, jffs2, dccp, sctp, rds, tipc and the rest
Filesystem mounts /dev/shm gets noexec, nosuid, nodev
Core dumps Disabled system-wide, so a crash can't spill passwords and keys onto disk
Cron restriction Scheduling limited to root, cron directories tightened
Idle logout Shell sessions time out after 15 minutes
Login banner Authorised-access-only warning, which a lot of compliance regimes require
Time sync Verifies NTP is actually synchronized, not just installed. The step everyone skips and everyone regrets
Disk alerts Hourly timer, warns at 85% via syslog and wall

9 optional steps, in their own menu, off by default β€” because each has a real trade-off and you should be the one deciding:

File integrity baseline SHA-256 fingerprints of /etc, /usr/bin, /usr/sbin, /usr/local/*. Drift shows up in status
auditd Detailed security event logging. Costs disk space
AppArmor Confines programs to the files they're allowed to touch
Persistent journald Logs survive reboots, capped at 500 MB so they can't fill the disk
Process accounting Records every command every user runs. Invaluable after an incident
rkhunter Rootkit scanner with a daily automatic scan
Lynis Independent audit tool β€” a second opinion from a different codebase
Block USB storage Stops data walking off on a stick. Skip if you boot from USB
Disable IPv6 Only if you're certain you don't use it

At the end you get a plain-English report β€” not a wall of green checkmarks, but what's solid, what's still recommended, what got skipped, and a security score out of 100.


Zero dependencies. Genuinely zero.

The command-line tool is pure Python standard library. Nothing to pip install. Nothing to break. No dependency tree that rots in eight months.

This matters more than it sounds. You run this on a fresh headless server, over SSH, before that box has anything on it. It cannot need a package index, a virtualenv, or a desktop environment. It needs Python and root. That's the list.


⚠️ It needs sudo

Hardening changes SSH config, firewall rules, kernel parameters and system packages. None of that is possible without root.

sudo python3 main.py

Start it without sudo and it won't pretend otherwise β€” it shows a red warning, greys out everything that would need root, and leaves dry run, status and about available so you can still look around safely.


Getting started

Full step-by-step for absolute beginners: THE_POTATO_PROTOCOL.md. No shame in it, that's what it's there for.

The short version:

git clone https://github.com/Norac-projects/easy-server-security.git
cd easy-server-security
sudo python3 main.py

Then pick [3] Dry run first to see everything it would do, and [1] or [2] when you're happy.

Prefer flags? They still work

The menu is the front door, not a cage. Everything is scriptable:

python3 main.py harden --dry-run              # no sudo needed to preview
sudo python3 main.py harden -y                # everything, sane defaults
sudo python3 main.py harden --non-interactive # zero prompts, for cloud-init / Ansible
sudo python3 main.py harden --open-port 80 --open-port 443
sudo python3 main.py harden --extra auditd --extra journald
sudo python3 main.py harden --all-extras      # core plus every optional step
sudo python3 main.py status                   # exit code 0 = compliant, 2 = drifted
sudo python3 main.py report -o report.txt

Re-running is safe. State lives in /etc/easysec/state.json, so a second run only applies the deltas.


Managing more than one server

pip install -r requirements-gui.txt
python3 fleet_manager.py

This is the answer to "I have twelve servers and I'm not SSHing into each one."

fleet_manager.py is a PySide6 desktop dashboard. You add every server you run β€” hostname, port, user, key path β€” and it connects to each one over SSH using Paramiko and runs this same hardening tool on it remotely. Security scores and drift for your entire fleet in one window.

Select any host and you can dry-run it, harden it, or pull its full report without opening a single terminal. Dark mode by default, light mode toggle, About tab.

It's a nice chair. It is not load-bearing. The command-line tool doesn't know or care that the dashboard exists, and the core hardening logic imports nothing from it. Headless servers never need the GUI dependencies installed.


Requirements

  • Python 3.13 (3.11+ works; the tool checks and tells you)
  • Linux with systemd
  • root / sudo, checked at launch
  • Debian / Ubuntu / Raspberry Pi OS get first-class support, which covers most of the Pi and VPS world. Distro and package manager are detected at runtime rather than assumed, so RHEL-family works for the bulk of it too

Building a single binary

PyInstaller, one file, no Python needed on the target:

pip install pyinstaller
pyinstaller --onefile --name easysec main.py

Drops dist/easysec β€” copy it to /usr/local/bin/ and you've got sudo easysec anywhere. Build on the same architecture you're deploying to (yes, build on the Pi for the Pi).


Project layout

main.py                   CLI + menu entry point. Just run it
fleet_manager.py          optional desktop dashboard for many servers
requirements.txt          empty on purpose. That's the point
requirements-gui.txt      PySide6 + paramiko, dashboard only
src/easysec/
    ui.py                 colours, ASCII art, menu widgets
    menu.py               the interactive menu
    cli.py                argument parsing for scripted use
    context.py            distro detection, state, backups, command runner
    report.py             plain-English reports and scoring
    steps/                one file per hardening area
    gui/                  everything Qt lives here and nowhere else

Third-party tools and licences

The core tool ships no bundled third-party code. It configures software already packaged by your distro, installed through your own package manager:

Tool Licence Used for
OpenSSH BSD-style SSH hardening
ufw GPL-3.0 Firewall (Debian family)
nftables GPL-2.0 Firewall (fallback)
fail2ban GPL-2.0 Brute-force banning
unattended-upgrades GPL-2.0 Automatic patching
chrony GPL-2.0 Time sync
auditd GPL-2.0 Audit logging (optional)
AppArmor GPL-2.0 Access control (optional)
rkhunter GPL-2.0 Rootkit scanning (optional)
Lynis GPL-3.0 Security auditing (optional)
acct GPL-2.0 Process accounting (optional)

Configuring GPL software doesn't make this project GPL β€” no GPL code is copied or linked, so MIT is fine here.

The optional dashboard's dependencies are linked, and matter more:

Package Licence Note
PySide6 LGPL-3.0 Dynamically linked, which LGPL permits for an MIT project. If you redistribute a bundled binary of the GUI, LGPL obliges you to let users replace the Qt libraries
Paramiko LGPL-2.1 Same reasoning

Since these are optional and not bundled with the core tool, a headless install carries no LGPL obligations at all.


Languages

GitHub's language bar will read Python 100% β€” roughly 2,900 lines. No shell glue, no YAML config layer, no JavaScript hiding anywhere. The only non-Python content in the repo is documentation.

If Linguist gets it wrong, .gitattributes is already in place:

*.py linguist-detectable=true
*.md linguist-documentation=true

πŸ“¬ Reach Me

Platform Handle
βœ‰οΈ Email Norac-Projects@Proton.me
✈️ Telegram @NoracProjects
πŸ“· Instagram @NoracProjects
🟠 Reddit u/Norac-Projects

🀝 Let's Collaborate

I'm always up for teaming up on desktop tooling, industrial/OT software, embedded systems, Raspberry Pi projects, or anything privacy-first. If you've got an idea, a gap you've noticed in the tooling world, or just want to build something that doesn't need a cloud subscription to function β€” open an issue, send a message, or just say hi.


🀝 Contributing

Found a bug? Got an idea? Open an issue or send a PR β€” include your logs (Logs tab β†’ Copy all logs) and it's usually diagnosable straight away.


β˜• Support the Work

If one of these tools saved you an afternoon (or a server), you're welcome to buy me a coffee β€” entirely optional, always appreciated, never expected.

β‚Ώ Bitcoin (BTC): 1Ka1cNmfhbNej9iiLzvfVzYqEZh2e1vbNk


πŸ“œ License

MIT β€” do whatever you want, just keep the notice. Bundled third-party components are listed in THIRD_PARTY_NOTICES.md.

License

MIT. See LICENSE. Take it, fork it, ship it, put it in your own tooling.


A Norac Project.

About

πŸš€ Secure your Linux VPS or Pi effortlessly! Easy Server Security is a zero-dependency Python hardening tool. πŸ§… Features a friendly interactive menu, safe dry-runs, and auto-configures SSH, firewalls & sysctl. 🍟 Guaranteed not to lock you out! πŸ₯” Get a plain-English security score in seconds. πŸ”’

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages