banhack233
HOST PROTECTION, MADE PRACTICAL
Notificationsv0.2.3

fail2ban / sshguard style · Host audits · Keepalive · Notifications · Autostart

Notification channels and reliable delivery

Telegram, Discord, Slack, Feishu/Lark, generic webhooks and email are supported. Merge the following fragments into notifications. Values are placeholders; keep real credentials local. See configuration.

Language, time zones and credentials

From v0.2.3, set notifications.language="en" and notifications.timezone="UTC" for English alerts. Supported languages are en and zh-CN; omitted values retain Chinese and host-local time. Each channel can override language. This covers console, email, cards, generic payloads and retries. Custom text and GeoIP names remain unchanged; location_language only controls an additional Chinese location row. See international setup.

Keep configuration and environment files private and outside Git. bot_token_env and email password_env name variables in the sending process; they take precedence over inline credentials and do not fall back when missing. JSON does not expand arbitrary ${VARIABLE} strings. After edits run config-check and restart.

Telegram

Create a bot with Telegram's official @BotFather. Send /start in a private chat, or add the bot to a group with send permission; channels require permission to publish. Check chat.id in your own Bot API getUpdates response. Forum topics additionally need message_thread_id.

{"telegram": {"enabled": true, "bot_token_env": "BANHACK233_TELEGRAM_BOT_TOKEN", "chat_id": "-1000000000000", "message_thread_id": 42, "disable_notification": false}}

Remove message_thread_id for ordinary chats. A local bot_token is also supported. If bot_token_env is configured it takes precedence, without falling back when the variable is missing. The variable must exist in the daemon environment, not just an interactive terminal.

For systemd, add this using systemctl edit banhack233:

[Service]
EnvironmentFile=/etc/banhack233/notifications.env

Create a root-only environment file containing your token assignment, then run systemctl daemon-reload and restart the daemon. Manual notify-test needs the same variable. Do not paste environment dumps into issues. Windows SYSTEM tasks do not automatically inherit a user's temporary environment.

Messages are plain text without Telegram Markdown/HTML parsing, bounded for provider limits. Topic IDs, silent notifications, HTTP errors and Bot API ok are supported. Telegram Bot API

Discord

Create an incoming webhook in the destination channel:

{"discord": {"enabled": true, "url": "https://discord.com/api/webhooks/WEBHOOK_ID/WEBHOOK_TOKEN"}}

Delivery uses bounded embeds, wait=true, and disabled allowed_mentions, so an @everyone string cannot ping the server. Rate-limit responses supply retry timing. Confirm channel permissions. Discord webhook reference

Slack, Feishu and Lark

{
  "slack": {"enabled": true, "url": "https://hooks.slack.com/services/WORKSPACE/CHANNEL/TOKEN"},
  "feishu": {"enabled": true, "url": "https://open.feishu.cn/open-apis/bot/v2/hook/PLACEHOLDER", "secret": "", "location_language": "zh-CN"}
}

Slack uses incoming webhooks and Block Kit. Feishu/Lark uses bot cards; configure the local signing secret if required and keep the clock correct. Lark URLs work through feishu.url or webhooks[].format="lark". Feishu/Lark business errors are checked even on HTTP 200.

Generic webhooks and email

{
  "webhooks": [{"name": "operations", "enabled": true, "url": "https://alerts.example.com/hooks/banhack233", "format": "json", "headers": {}}],
  "email": {"enabled": true, "from": "sender@example.com", "to": "operator@example.com", "password": "LOCAL_SMTP_CREDENTIAL", "smtp_host": "smtp.example.com", "smtp_port": 465}
}

Formats: text, json, discord, slack, feishu, lark. Keep Authorization headers local. Redirects are rejected to avoid forwarding credentials; configure the final endpoint. SMTP presets cover QQ, 163, 126, Gmail, Outlook, Hotmail and Live. Only missing host/port values are inferred. Port 465 uses implicit TLS; other ports require STARTTLS. Use the provider's supported SMTP/app credential.

SMTP authentication and overseas providers

Set email.username if the SMTP login differs from from; omitted means from. Use an environment credential instead of an inline password:

{
  "email": {
    "enabled": true,
    "from": "alerts@example.com",
    "to": "operator@example.com",
    "username": "SMTP_USERNAME",
    "password_env": "BANHACK233_SMTP_PASSWORD",
    "smtp_host": "smtp.example.com",
    "smtp_port": 587,
    "language": "en"
  }
}

The client implements SMTP PLAIN over TLS, not OAuth2. Host/port inference is not an authentication compatibility guarantee. Gmail requires an eligible account with 2-Step Verification and an app password; administrator policy may prevent app passwords. Google guidance

Outlook.com requires OAuth2/Modern Auth, which this client does not implement. Its retained host/port preset alone is insufficient; use a compatible SMTP relay or another channel. Microsoft requirements

For international Lark, copy the actual custom-bot URL from your Lark tenant; do not reuse a Feishu tenant URL or change its hostname by hand. Set the target's language="en" and location_language="en" for English labels without the extra Chinese location row. Lark custom-bot guide

SMTP uses direct TCP, not HTTP proxy variables. HTTP bot/webhook requests support proxies configured in the daemon's environment; see network setup.

Queue and frequency

Setting Behavior
Batching 60 seconds from the first event, or 20 events by default
Scan isolation Daemon enqueues; a separate worker performs delivery
Channel isolation Independent concurrent channels, each with a 10-second deadline
Persistence state_path + ".notifications.json", private file, atomic replacement
Retry Failed channels only; 1, 2, 4… minutes up to one hour, honoring longer Retry-After
Retention Up to 1000 alerts and 24 hours per alert; expiry is logged
Full queue New enqueue fails and is logged; protection scans continue
Disabled channels Their queued deliveries are dropped

The queue stores events, not endpoint URLs or credentials. Events may contain sensitive addresses/process details. Reordering generic webhook entries changes their queue identity; drain pending deliveries first. A crash after receiver acceptance but before local acknowledgement can duplicate a message. This is bounded retry, not exactly-once messaging. Overseas APIs require working host connectivity; standard HTTP proxy environment variables are supported.

Acceptance and troubleshooting

sudo banhack233 config-check
sudo banhack233 notify-test -channel telegram
sudo banhack233 notify-test -channel discord
sudo banhack233 notify-test -channel feishu,slack,email
sudo banhack233 notify-test -channel webhook:operations

Manual tests send immediately without using the retry queue and fail with nonzero exit status. Verify actual receipt, destination, permissions and backlog. Telegram 400 often means chat/topic ID, 401 token, 403 permission or a user who has not started the bot, and 429 rate limiting. Logs omit token URLs and provider error bodies. Automated tests use mock servers; live acceptance needs your local credentials.