features

What sshsentry detects

Each rule below is in the 0.2.0 release. Alerts are short, specific, and suggest the next thing to check.

SeverityMeaningRules
LOWWorth knowing, usually youNew IP
MEDIUMSomeone is tryingBrute force
HIGHCheck this nowLogin after failures, new country, new user, new SSH key
CRITICALAn attacker may be inEscalation (alerting on)

Each destination can filter with min_severity.

rule brute_force

Brute force MEDIUM

5+ failed logins from one IP within a sliding 10 minutes. Invalid usernames count too, so key-only servers are covered.

brute_force.alertsha256:8fc8b93d983a
[2026-10-17 02:10:31] MEDIUM: Brute force. 5 failed SSH logins from 203.0.113.45 in 30 sec, trying user(s): admin, oracle, root, test. Consider fail2ban, a firewall block, or disabling password logins.

config: rules.brute_force: failures 5, window_minutes 10

rule login_after_failures

Login after failures HIGH

A successful login from an IP that failed 5+ times in the last 60 minutes. This is the one you really want to hear about.

login_after_failures.alertsha256:f42ce6e0230d
[2026-10-17 02:16:08] HIGH: Login after failures. User 'deploy' logged in via password from 192.0.2.77 after 6 failed attempts from that IP. If this wasn't you, change the password, check ~/.ssh/authorized_keys and review running processes.

config: rules.login_after_failures: failures 5, lookback_minutes 60

rule escalation

Escalation CRITICAL

With alerting turned on, an IP already alerted for brute force that later logs in gets one CRITICAL alert to every destination. It replaces the login-after-failures alert for that login.

escalation.alertsha256:c900a94dea1e
ESCALATION: successful login from 192.0.2.77 after brute force. User 'deploy' logged in via password after 6 failed attempts from that IP ...

config: needs alerting.enabled: true; once per brute-force alert

rule new_country

New country HIGH

A successful login from a country never seen for that user. Needs the optional geoip2 library and a free MaxMind GeoLite2-Country database; skipped with a one-line note if missing.

config: rules.new_country + geoip.database

rule new_ip

New IP LOW

A successful login from an IP never seen for that user. Approve your own addresses with --approve IP.

new_ip.alertsha256:5654939dba39
[2026-10-17 02:47:33] LOW: New IP login. User 'chris' logged in via publickey from 100.64.12.9, an address never seen for this user. If expected, approve it with: sshsentry.py --approve 100.64.12.9

config: rules.new_ip

rule new_user

New user HIGH

A new account appears in /etc/passwd. Existing accounts are recorded silently on the first run.

config: rules.new_user.passwd_file

rule new_ssh_key

New SSH key HIGH

A new line in any watched authorized_keys file (root and /home/* by default, globs allowed). Existing keys are the silent baseline.

config: rules.new_ssh_key.paths

daily digest

One short screen a day

Optional (digest.enabled). Summarizes the last 24 hours, stores it locally, and can send it to one destination. Each day carries a hash chain line so a rewritten history can be spotted later: tamper-evident, not tamper-proof.

digest-2026-10-17.txtsha256:fc796dcb2b49
sshsentry daily digest, 2026-10-17Period: Fri Oct 16 08:00 to Sat Oct 17 08:00 (server time) Failed logins: 12 from 2 IP address(es).Most active: 203.0.113.45, 6 attempts (usernames tried: admin, oracle, root, test).Successful logins: 4  - chris from 198.51.100.23 (2x) [new IP]  - deploy from 192.0.2.77 [new IP]  << after 6 failed attempts from that IP. Check this.  - chris from 100.64.12.9 [new IP]New IPs seen: 3 (198.51.100.23, 192.0.2.77, 100.64.12.9). Integrity chain: 9c41e07ab2d3 (sha256 9c41e07ab2d3...)
privacy

Local by default

State lives in a local SQLite file. Alerts go to stdout unless you enable email, Slack or a webhook (each off by default). Community sharing of attacker IPs is opt-in, sends no usernames or log lines, and can be reviewed with --show-shared and erased with --forget-me. See the privacy policy.

detection only

It watches. It does not block.

sshsentry never changes firewall rules, accounts or keys. Use fail2ban, a firewall and key-only SSH for prevention. A responder that helps you act on an incident is planned and shown only as a simulation in the live demo; it is not in this release.

limits

Honest limits

SSH-focused. It won't see web-app attacks or anything that leaves no login or account trace (silent zero-days, rootkits that tamper with logs). Someone with root can edit local logs; ship logs off-box if that worries you.