Configuration
Everything lives in /etc/sshsentry/sshsentry.yaml (override with -c). Any key you leave out uses the default shown here, taken from the code in 0.2.0.
Core and rules
log_file: auto # auto = /var/log/auth.log or /var/log/securestate_db: /var/lib/sshsentry/state.dbpoll_seconds: 1file_check_seconds: 60 # how often to re-check passwd and authorized_keyscooldown_minutes: 60 # don't repeat the same alert within this timealert_log: "" # optional JSON-lines alert file rules: brute_force: {enabled: true, failures: 5, window_minutes: 10} login_after_failures: {enabled: true, failures: 5, lookback_minutes: 60} new_ip: {enabled: true} new_country: {enabled: true} # needs geoip2 + GeoLite2-Country new_user: {enabled: true, passwd_file: /etc/passwd} new_ssh_key: enabled: true paths: [/root/.ssh/authorized_keys, "/home/*/.ssh/authorized_keys"]learn_existing_log: true # first run: learn normal IPs silently
The brute-force threshold is one number for stdout and every destination. Learn mode can suggest a value; it never changes it unless you run --accept-threshold.
Alert destinations
Stdout is always on. Everything else is off until alerting.enabled: true plus the destination's own enabled. Severity order: LOW < MEDIUM < HIGH < CRITICAL.
alerting: enabled: true timeout: 5 email: {enabled: true, min_severity: HIGH} # SMTP settings: the top-level email: block slack: {enabled: true, min_severity: MEDIUM, webhook_url_env: SSHSENTRY_SLACK_WEBHOOK} webhook: {enabled: false, min_severity: LOW, url_env: SSHSENTRY_WEBHOOK_URL} email: smtp_host: smtp.example.com smtp_port: 587 starttls: true username: alerts@example.com password_env: SSHSENTRY_SMTP_PASSWORD # keep the password out of the YAML from: alerts@example.com to: [you@example.com] subject_prefix: "[sshsentry]"
Put secrets in /etc/sshsentry/env (loaded by the systemd unit) rather than the YAML:
sudo install -m 600 /dev/null /etc/sshsentry/envecho 'SSHSENTRY_SMTP_PASSWORD=your-app-password' | sudo tee /etc/sshsentry/env >/dev/nullecho 'SSHSENTRY_SLACK_WEBHOOK=https://hooks.slack.com/services/...' | sudo tee -a /etc/sshsentry/env
- URLs must be
https://(http://only for localhost). A bad destination is disabled with a warning; monitoring continues. - Slack markup characters in usernames are escaped, so an attacker-chosen
<!channel>can't ping your channel. - Run
--test-alertsafter setup. Add the sender address to your contacts so alerts don't land in spam.
Digest, learn mode, GeoIP, sharing
digest: enabled: false time: "08:00" # server local time send: true destination: email # email | slack | webhook send_when_quiet: true save_text: true text_dir: "" # "" = digests/ next to state_db host_label: "" include_chain_hash: true learn_mode: {enabled: false, days: 3, percentile: 99, margin: 2, min_threshold: 3, max_threshold: 50}geoip: {database: /usr/share/GeoIP/GeoLite2-Country.mmdb}sharing: {enabled: false, endpoint: "", timeout: 5} # opt-in, https only
All off by default. Learn mode records failures per IP per window for days and suggests a threshold; during it, alerts print with [learning: not sent] and nothing is sent. Sharing reports only attacker IPs for brute-force and login-after-failures alerts; see the privacy policy.
The fully commented config is sshsentry.yaml in the repo.