Security Setup (twelve tabs)

Overview. How exposed the box is, read in one pass as cards: exposure, access, permissions and secrets, firewall, Fail2Ban, SSH, WAF, kernel, passwords, AppArmor/SELinux, integrity — each carrying the live state of its area and opening its own tab, with the two or three worst findings named in one verdict line. Under the cards, "Also read on this box": the scheduled tasks, the clock, automatic updates, auditd and the certificates, judged here and managed under System Setup, a click landing on the right tab. Root reads happen only while the screen is on screen; coming back reads again, and while the Overview stays up it reads again quietly.

Exposure. What the internet can reach right now: every port something listens on, with its process, judged against the firewall and against Docker — reachable from anywhere, from some addresses, closed, local only, published past the firewall. The fixes are on the row: Close, Only to me, Private network only, or Open to the world, knowingly.

Access. Who can get in: every authorized key on every account (whose key, how old the file is, which account it opens), who may become root and whether a password is asked, and the accounts themselves — locked, no password, never logged in. Judged (weak keys, keys on service accounts, a world-writable authorized_keys, root by password), with the fix on the row: Remove this key, Take sudo away, Make it ask a password, Lock, Take the shell away. A key is added on the SSH tab; this is the audit of what is already there.

Permissions & secrets. What on the disk is open to everyone: world-writable paths, setuid programs no package shipped, files nobody owns, secrets anyone can read, /tmp and /dev/shm without noexec, the system files that must be root's alone, the umask. Each finding carries its fix in words; the ones that cannot stop anything working go together (Fix every safe one), and the two that can — a setuid bit off, noexec on a mount — one at a time, each saying what stops working.

Firewall. ufw or firewalld (iptables/nftables read and judged): on/off with the defaults explained, the rules folded (a v4 rule and its v6 twin are one line), "Open to the world" (the named services), who may reach SSH, "Who is knocking" (refused connections folded by address) and the log; what is reachable is the Exposure tab's. One dialog for a preset ("Open MongoDB"), a new rule, or "Who may reach SSH" — "to whom" as allow/deny rows, denies before allows, a preview, and the invariant that the operator's own address stays allowed. The SSH port is allowed before the firewall is turned on, cannot be removed while it is the only cover, and a rule that would deny it is refused in Go.

Fail2Ban. Which doors are watched (SSH, web logins, mail, FTP, databases) as jails switched on click, the rule (findtime/bantime/maxretry in words, per jail or global), who is banned right now and why, who is never banned, who is refused for good, the activity folded over a window, the log, and alerts by mail through the box's own Postfix. Vigia owns only /etc/fail2ban/jail.d/zz-lens.local.

SSH. Hardening as a draft proven as one batch: Vigia writes its drop-in, sshd validates it, sshd reloads, then Vigia opens a FRESH login from this computer on the port now in force; if that fails the previous file comes back and the screen says reverted. Root off is refused unless somebody else can get in and become root; password logins go off only once the key alone has proven a fresh login. "Who can log in" lists every account's door (keys, password, AllowUsers/AllowGroups); "Your login" switches Vigia's own login to one of your keys already on the door; "Who logged in" reads the sshd log folded by address with key names by fingerprint. Vigia makes no key and holds none.

Passwords. Password policy: what a password must be, how long it lives, what happens after too many wrong ones — and which accounts break the rules right now. Installing the policy packages asks first and says what they do.

WAF. Two layers: INSIDE THE WEB SERVER, ModSecurity with the OWASP Core Rule Set in nginx or Apache (one form per engine, paranoia level, anomaly thresholds); AT THE DOOR, CrowdSec, which reads the logs, bans at the firewall for every port and shares reputations. CrowdSec's three levers a person actually pulls: what it reads (acquisition sources — a log file, a container's output, a unit's journal, each a Vigia-owned file in acquis.d), alerts by mail through the box's Postfix, and scenarios switched between watch-only and banning. Your own address is allowed in one and whitelisted in the other, and neither can be told to block it. "What it saw" is the activity.

Integrity & rootkits. Three checks, each a job you watch with its report saved on the server: packages against what the distro shipped (debsums/rpm -V), files against a baseline (AIDE), rootkits (rkhunter and chkrootkit). A schedule of timers Vigia owns and a mail when something changed; the two "accept the current state" actions carry a sentence before, because they are the only ones that can hide an intruder. Findings are explained in words.

AppArmor / SELinux. The kernel's second opinion: the denials first (a refusal is far more often a wrong label than an attack, and the screen says which, with the fix when Vigia knows it from the meaning), SELinux booleans and labelling, AppArmor profiles, and what is listening with nothing confining it.

Kernel. The standard sysctl switches against spoofing, probing and escalation, grouped Network / Kernel / Filesystem, read as they are and set through one Vigia file live and at boot, every changed value remembered so Remove puts the box back exactly as it was.