Docs menu
docs

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

sshsentry.yamlsha256:2bcd93fdc81a
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.

sshsentry.yamlsha256:e705b562f2b4
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:

shellsha256:9c11c9e671e7
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-alerts after setup. Add the sender address to your contacts so alerts don't land in spam.

Digest, learn mode, GeoIP, sharing

sshsentry.yamlsha256:d3156d723cb6
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.