Skip to content
MSFE-NG edited this page Oct 16, 2026 · 21 revisions

CLI reference

msfe-ng is installed in /opt/msfe-ng/bin and on root's PATH. Everything the UI does is also a command, which is what the cron jobs and the doctor's "fix" hints use.

msfe-ng health                      check the running daemon via its Unix socket
msfe-ng panel                       report the detected control panel
msfe-ng config                      print the effective config as JSON (password redacted)
msfe-ng doctor [--fix] [--all]      check every link of the scanning chain; names each fix (--fix applies the mechanical ones; --all prints acknowledged notices too)
msfe-ng doctor ack <check name> [--days <n> | --forever] [--note <text>]   acknowledge a notice: hidden while it stays at that level (30 days by default)
msfe-ng doctor unack <check name>   take an acknowledgement back
msfe-ng doctor acks                 list acknowledgements: active (hiding), expired (showing again), resolved
msfe-ng resolver <status|install>   private DNS resolver (unbound on loopback) so the blocklists answer this host
msfe-ng upgrade [--check]           upgrade MSFE-NG to the latest release (or just compare versions)
msfe-ng version | help

msfe-ng sync [--dry-run]            policy → MailScanner rule files (cron: every 10 min)
msfe-ng rules lint                  check managed ruleset files for unparsable lines
msfe-ng rules adopt [--from <dir>]  borrow existing on-disk rules into the custom store
msfe-ng import <dir> [--save]       import a legacy ConfigServer MSFE dir (e.g. /usr/msfe)

msfe-ng engine <status|install|configure|enable|disable|lint>
msfe-ng engine perl [--apply] [--json]       which perl the RPM engine runs under (engine_perl); --apply rewrites the shebangs
msfe-ng engine migrate-legacy [--run]        ConfigServer MailScanner → the RPM (preflight without --run)
msfe-ng legacy decommission [--run]          remove ConfigServer's front-end only, backed up first (preflight without --run)
msfe-ng engine <wire|unwire> [--dry-run]     route mail through MailScanner via Exim (or undo)
msfe-ng service <status|start|stop|reload|restart|queue-fix|spool-repair>
msfe-ng exim <status|enable-scanning|disable-scanning>   the mailflow kill switch (named-queue wiring only)
msfe-ng exim <enable|disable>-cpanel-spamassassin        cPanel's own SpamAssassin (double scan; Forced Global OFF)
msfe-ng mailscanner <status|enable-logging|disable-logging>

msfe-ng monitor [--dry-run]         auto-clean rules, spool repair, Telegram alerts (cron: every 5 min)
msfe-ng autoban <status|run [--dry-run]|rules>   temporary csf bans for spam sources and match rules (cron: every minute)
msfe-ng autoban rejects [--limit n] [--json]     messages Exim refused at DATA for a match rule set to reject at SMTP time (from exim_rejectlog)
msfe-ng autoban smtp-off [--dry-run]             remove the Exim fragment behind those rejects and restart Exim (the kill switch; a save or sync puts it back)
msfe-ng report <ip> [--category <id|name>]... [--comment <text>] [--dry-run] [--json]   report one address to AbuseIPDB by hand (categories 10 Web Spam + 19 Bad Web Bot by default; the comment is public; --dry-run validates and prints without sending; exit 1 when refused or failed)
msfe-ng report list [--ip <ip>] [--limit n] [--json]   the reports sent so far, newest first (backup_dir/reports.jsonl)
msfe-ng digest [--dry-run]          quarantine digests to digest-enabled domains (cron: daily)
msfe-ng housekeeping                prune old log rows and bodies per retention (cron: nightly)
msfe-ng selftest [--to <address>]   send GTUBE / EICAR / clean test mail through the MTA (default recipient: the first cPanel account's own mailbox, else root@localhost)
msfe-ng spambox <enable|disable|status>

msfe-ng db-migrate [--status]       apply / list SQL migrations
msfe-ng db <backup|fix|bayes-repair|bayes-recreate>
msfe-ng db import-legacy [--database <name>] [--dry-run]   dump ConfigServer's MailControl database (default `mailscanner`) into backup_dir and copy the rows MSFE-NG does not have into its own maillog
msfe-ng conf test [--no-lint] [--json] [--with <id>=<file>]   lint + cross-file checks as findings (exit 1 on a failure)
msfe-ng conf grep <text>            find a text in every configuration file (case-insensitive; id:line: text)
msfe-ng conf test-message <clean|gtube|eicar|file.eml> [--offline] [--json]   what the chain would do with a message
msfe-ng snapshot export [file] [--only mailscanner|msfe]   MailScanner etc tree + /etc/msfe-ng as one tar.gz
msfe-ng snapshot import <file> [--dry-run] [--only …] [--yes]   compare with this host, import chosen files
msfe-ng snapshot list
msfe-ng backup <file.tgz> | restore <file.tgz>      aliases: snapshot export/import --only msfe
msfe-ng delivery test <address> [--ip <ip>] [--selector <s>] [--audit] [--days <n>] [--json | --html] [--force]   deliverability diagnostic (+ cPanel audit; exit 1 on a failure, 3 on a bad address)
msfe-ng delivery eml <file.eml> [--bounce] [--address <a>] [--ip <ip>] [--selector <s>] [--audit] [--json | --html]   the same for a saved message, or a bounce taken apart
msfe-ng delivery inbox <install [--dry-run] | uninstall [--dry-run] | status | new | poll <token> [--json] | remove <token> | sweep>   the diagnostic inbox (dt-<token>@<host> addresses via exim.conf.local)
msfe-ng delivery testmail --from <hosted address> --to <address> [--tag <t>] [--follow <secs>] [--json]   send a real test message and follow it through the Exim log
msfe-ng delivery osint <address> [--providers a,b] [--json | --html] [--force]   public-information lookup for an address (needs osint_enabled; exit 0 complete, 2 usage, 3 invalid/failed, 4 partial)
msfe-ng delivery osint <providers [--json] | sweep>   print id, name, `configured`/`not configured` (key set; keyless sources are always configured) and disclosure for each source; delete reports past retention
msfe-ng delivery osint monitor <list [--json] | add <address> [--sources a,b] [--interval-mins n] | remove <id|address> | enable <id> | disable <id> | run [--dry-run] [--id n] | history <id> [--json]>   scheduled OSINT checks (daily to weekly, a monthly usage budget, Telegram alerts on changes; exit 0 ok, 1 database or limit, 2 usage, 3 invalid input)
msfe-ng delivery monitor <list [--json] | add <address> [--interval-mins n] [--audit] [--ip ..] [--selector ..] | remove <id|address> | run [--dry-run] [--id n]>   scheduled re-tests (history in MySQL, regressions to Telegram)
msfe-ng acctdns scan [--user <u>] [--domain <d>] [--all] [--json]   SPF, DKIM and DMARC for every domain hosted here (subdomains with --all; exit 1 on a failure, 3 on a non-cPanel host)
msfe-ng acctdns fix <domain> <spf|dkim|dmarc> [--record <r>] [--json]   install the record through cPanel's own installer (exit 1 when it refused)
msfe-ng service units [--json]   the daemons mail depends on: running now, and enabled at boot? (exit 1 when one needs attention; other stopped or failed services on the host are listed as down and do not affect the exit code)
msfe-ng service unit <name> <enable|start|restart|enable-now>   act on one of them
msfe-ng footers <status [--json] | set "<directive>" on|off ... [--dry-run] | off [--dry-run] | restore [<backup>] [--dry-run] | backups>   what MailScanner changes in delivered mail, one switch per setting, with backups (see Settings → What MailScanner changes in mail)
msfe-ng localsub <status [--json] | on [--dry-run] | off [--dry-run] | restore [<backup>] [--dry-run] | backups>   hide the loopback hop in the Received: line of authenticated webmail submissions, via /etc/exim.conf.local with backup, validation and rollback (see Settings → Local submission privacy)
msfe-ng dmarc fetch [--dry-run] [--keep] [--json]   read the DMARC report mailbox, store the reports, delete the imported mails (cron: hourly)
msfe-ng dmarc import <file>... [--json]   store DMARC report files (.xml, .xml.gz, .zip) or saved report mails (.eml)
msfe-ng dmarc <status [--json] | test | prune>   last fetch and stored totals | IMAP login check | drop rows past retention

Example, watching one address (needs osint_enabled and the database; the first run at the next 5-minute msfe-ng monitor pass is a baseline and never alerts; the exit codes are 0 done, 1 database/limit/no such monitor, 2 usage, 3 invalid input):

msfe-ng delivery osint monitor add alice@example.org --sources gravatar,hibp --interval-mins 2880
msfe-ng delivery osint monitor list
msfe-ng delivery osint monitor run --id 3
msfe-ng delivery osint monitor history 3

Environment: MSFE_NG_SOCKET (daemon socket), MSFE_NG_CONFIG (config file), MSFE_NG_MIGRATIONS (migrations dir), MSFE_NG_DMARC_LOCK (the DMARC fetch lock file, default /run/msfe-ng-dmarc.lock), MSFE_NG_SMTP_DENY_BLOCK (the cPanel ACL block directory the SMTP-time reject hook goes into, default ACL_CHECK_MESSAGE_PRE_BLOCK; set it for the daemon and the cron alike, see Rules → Reject at SMTP time).

/etc/msfe-ng/config.toml

Seeded by the installer with comments; editable from the Config tab.

Group Keys
Database db_host, db_port, db_name, db_user, db_pass
Paths mailscanner_conf, mailscanner_custom_dir, mailscanner_rules_dir, mailscannerq_conf, spambox_conf, quarantine_dir, archive_dir, maillog_path, exim_mainlog_path, backup_dir, socket, webroot
Interface & release refresh_secs, rows_per_page, view_new_window, learn_updates_db, forward_subject, forward_body, release_from, spamcop_address, dovecot_lda, csf_comment_default, geoip_url
Queue auto-clean queue_clean_frozen_hours, queue_clean_bounce_hours, queue_clean_spam_score
Doctor accept_exiscan (keep cPanel's ClamAV pass in Exim on purpose; the double-scan notice becomes OK)
Auto-ban autoban_high_enabled, autoban_high_count, autoban_high_window_secs, autoban_high_ban_secs, the same autoban_spam_*, autoban_telegram
Telegram telegram_bot_token, telegram_chat_id, alert_queue_size, alert_scan_stuck_mins, alert_burst_per_hour, alert_cooldown_mins
AbuseIPDB abuseipdb_key (manual reports from the client-IP view and msfe-ng report; secret)
DMARC reports dmarc_imap_host, dmarc_imap_port, dmarc_imap_tls, dmarc_imap_verify, dmarc_imap_user, dmarc_imap_pass (secret), dmarc_imap_folder, dmarc_delete_imported, dmarc_retention_days, dmarc_alerts, dmarc_alert_min_messages — see DMARC reports
Delivery test delivery_runs_per_min, delivery_cache_secs, delivery_log_days, delivery_max_monitors, delivery_helo
OSINT osint_enabled (false), osint_hibp_key (secret), osint_hibp_mode (direct/range), osint_search_key (secret), osint_validation_key (secret), osint_runs_per_min, osint_max_concurrent, osint_deadline_secs, osint_max_external_queries, osint_cache_secs, osint_retention_hours, osint_max_monitors, osint_history_days, osint_monitor_budget — see OSINT

mailscanner_conf is seeded with the engine's conf found at install time (/etc/MailScanner/MailScanner.conf, or ConfigServer's /usr/mailscanner/etc/MailScanner.conf); when the file it names is missing, MSFE-NG falls back to whichever of those exists. mailscanner_rules_dir is normally left out: sync then writes into that conf's %rules-dir%. Set it only to write somewhere else on purpose. msfe-ng config prints the values in effect.

Policy (scores, actions, retention, lists, per-domain overrides) lives under /etc/msfe-ng/policy/ and is what sync turns into rule files.

Clone this wiki locally