A lightweight, efficient file integrity monitoring tool written in Go. This tool helps system administrators and website owners monitor web files for unauthorized changes, which could indicate a security breach or malware infection.
Repository: magneticat/catscanner
- π File Integrity Monitoring: Generates and verifies SHA-256 hashes of files
- π Change Detection: Identifies new, modified, and deleted files
- π§ Notifications: Email alerts when changes are detected
- π Detailed Logging: All activities are logged with timestamps
- βοΈ Flexible Configuration: JSON-based configuration file
- π Multiple File Types: Support for monitoring various file extensions
- π¨ Email Options: Supports both SMTP and local mail command
- Go 1.16 or higher
- For mail command notifications:
mailutils(Debian/Ubuntu) ormailx(CentOS/RHEL)
-
Clone the repository:
git clone https://github.com/magneticat/catscanner.git cd catscanner -
Build the binary:
go build -o catscanner
-
Create your configuration:
cp config.example.json config.json
-
Edit
config.jsonto match your environment (see Configuration below).
Before scanning for changes, generate an initial integrity file. The integrity file is written atomically (via a temporary file then rename), so a crash during generation will not corrupt the existing baseline.
./catscanner -r -ext ".php,.html,.js" -config config.jsonOn success you'll see: Integrity file regenerated (N files).
To check for file modifications:
./catscanner -s -ext ".php,.html,.js" -config config.jsonWhen changes are detected, the program prints a summary such as: Changes detected: 2 modified, 1 new, 1 whitelisted. Details are always written to the log file.
| Flag | Description |
|---|---|
-r |
Regenerate the integrity file |
-s |
Scan for changes |
-ext |
Comma-separated list of file extensions to scan (default: .php). Extensions may omit the leading dot (e.g. php becomes .php). Empty or invalid (e.g. only commas/spaces) causes exit 2. |
-config |
Path to configuration file (default: config.json) |
-version |
Print program version and exit |
Note:
-rand-sare mutually exclusive. Use one at a time.
| Code | Meaning |
|---|---|
0 |
Success: no changes detected (scan) or integrity file regenerated (regen). |
1 |
Changes detected (scan mode only). |
2 |
Error: invalid usage (-s and -r both/neither), config/load failure, invalid or empty -ext, regeneration failure, missing integrity file, or scan failure. |
This makes catscanner easy to compose in shell scripts and CI pipelines.
./catscanner -versionEdit config.json to match your environment:
{
"target_dir": "/path/to/your/web/files",
"integrity_file": "/path/to/logs/integrity.txt",
"log_file": "/path/to/logs/integrity.log",
"email": "your_email@example.com",
"from_email": "alerts@example.com",
"email_method": "mailcmd",
"smtp_server": "smtp.example.com",
"smtp_port": "587",
"smtp_user": "smtp_username",
"smtp_pass": "smtp_password",
"whitelist": [
"*.tmp",
"cache/*",
"/path/to/your/web/files/temp/*",
"test.php"
]
}| Option | Description |
|---|---|
target_dir |
Directory to monitor for changes |
integrity_file |
File to store file hashes |
log_file |
File to store scan logs |
email |
Email address for notifications (To) |
from_email |
Optional explicit From address for notifications |
email_method |
Email method ("smtp" or "mailcmd") |
smtp_* |
SMTP server configuration |
whitelist |
Array of patterns to exclude from notifications |
The whitelist lets you exclude known-changing files (caches, temp files) from triggering alerts. Changes to whitelisted files are still logged but won't generate email notifications. Patterns use Go's filepath.Match syntax and are matched against the filename, full path, and every trailing sub-path:
*β any sequence of characters except path separators?β any single character except path separator[abc]β one character in the bracket set
Note:
**(globstar) is not supported.
Examples:
"whitelist": [
"*.tmp", // Ignore all .tmp files
"cache/*", // Ignore everything inside a cache/ directory
"test.php", // Ignore a specific file by name
"/full/path/to/specific/file" // Ignore one file by absolute path
]The simplest option for Linux/Unix systems. Requires a local mail transport agent.
{
"email_method": "mailcmd",
"email": "your_email@example.com"
}Install required packages:
# Debian/Ubuntu
sudo apt-get install mailutils
# CentOS/RHEL
sudo yum install mailxFor using an external SMTP server:
{
"email_method": "smtp",
"email": "your_email@example.com",
"smtp_server": "smtp.example.com",
"smtp_port": "587",
"smtp_user": "username",
"smtp_pass": "password"
}For regular monitoring, add to crontab:
# Check every hour
0 * * * * /path/to/catscanner -s -ext ".php,.html,.js" -config /path/to/config.json- Ensure your SMTP port matches the server capability:
- 587: STARTTLS (recommended, used by
smtp.SendMail) - 465: Implicit TLS (not supported; use 587 instead)
- 587: STARTTLS (recommended, used by
- Many providers require a valid From header that matches the authenticated user. Set
from_emailto your mailbox, or leave it empty to default tosmtp_user. - Some providers (e.g., Gmail) require an App Password or OAuth; a normal password may fail.
- Make sure the From domain has proper SPF/DMARC records to avoid spam filtering.
- If using
mailcmd, verify the local MTA is configured to relay mail externally. - Check the application log file for detailed SMTP or mail command error messages.
The test script (test_integrity.sh) demonstrates the full workflow and is fully self-contained β it creates a temporary directory, runs all scenarios, and cleans up after itself. No configuration needed.
chmod +x test_integrity.sh
./test_integrity.shThe script: regenerates the integrity file, scans (no changes), creates a test file, scans again (detects new file), removes the test file, scans again (detects removal), then prints the log and cleans up.
| Scenario | Action |
|---|---|
| First deployment | Run ./catscanner -r -ext ".php,.html,.js" -config config.json to create the initial integrity baseline. |
| Legitimate file changes | After deploying updates, run -r again to refresh the baseline. |
| Scan fails with "Failed to read integrity file" (or missing file) | Run -r to regenerate; the integrity file may be missing or corrupted. |
| Error: "no valid file extensions provided via -ext" | Provide at least one non-empty extension in -ext (e.g. -ext ".php,.html"). |
| No email received | Check email_method, SMTP/mailcmd config, and the log file for errors. |
| False positives from cache/temp | Add patterns to whitelist in config.json. |
- Store the integrity and log files outside the web root
- Disable write permissions on the integrity file after generation
- Use a dedicated email account for notifications
- Keep the config file secure (contains SMTP credentials)
- Regenerate the integrity file after every legitimate deployment
- Email headers (From, To, Subject) are sanitized to prevent header injection when using SMTP or the mail command
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by the need for a simple, efficient file integrity monitoring solution
- Built with Go's standard library for minimal dependencies