In the world of server security, File Integrity Monitoring (FIM) is a critical layer of defense. It's the "silent alarm" that tells you when a configuration file, a system binary, or a sensitive database has been tampered with.
While there are enterprise grade tools like Tripwire or OSSEC, sometimes you need something lightweight, transparent, and easy to deploy.
In this post, Iβll walk you through a project I built: a Bash based File Integrity Checker that uses SQLite for baseline storage and Docker for a fully isolated testing environment.
π The Core Concept: Baseline vs. Reality
The tool works on a simple but powerful principle:
-
Initialize (
--init): Scan your critical files, calculate their SHA-256 hashes, and store them in a persistent SQLite database. This is your "known-good" state. -
Check (
--check): Periodically re-scan those same files. If a single bit has changed, the hashes won't match, and an alert is triggered.
π οΈ The Tech Stack
- Bash: The engine. It handles the file traversal, hashing logic, and alerting.
- SQLite3: Instead of messy text files, I used SQLite to store the baseline. Itβs fast, structured, and handles hundreds of files with ease.
- Docker & Docker Compose: To make testing easy, I containerized the entire app.
- MailHog: A "superpower" for development. It's a mock SMTP server that catches all outgoing alert emails so you can verify them in a web UI without spamming your real inbox.
π A Deep Dive into the Code
1. The Hashing Logic
We use sha256sum to ensure high cryptographic security. Even a tiny change to a file (like adding a space) results in a completely different hash.
# Calculate hash and store in database
current_hash=$(sha256sum "$file_path" | awk '{print $1}')
sqlite3 "$DB_PATH" "INSERT INTO file_hashes (file_path, hash) VALUES ('$file_path', '$current_hash');"
2. Multi Layered Alerting
One of the biggest challenges in shell scripting is ensuring email delivery. My script uses a "fallback" strategy:
-
Primary:
ssmtp(sendmail) via the local system. -
Secondary:
curlto talk directly to the MailHog API. -
Last Resort: Standard
mailcommand.
π³ The Docker Testing Workflow
Testing a security tool can be nerve wracking you don't want to accidentally modify your host's /etc/ files! Thatβs where Docker shines.
I created a docker-compose.yml that spins up:
- An Ubuntu-based checker container with mock system files.
- A MailHog container for email visualization.
How to test a "Malicious" change:
- Start the environment:
docker-compose up -d
- Create the baseline:
docker exec -it file_integrity_checker bash /app/file_integrity_checker.sh --init
- Simulate a hack:
docker exec -it file_integrity_checker bash -c "echo 'MALICIOUS_CODE' >> /etc/myapp/config/app.yaml"
- Run the check:
docker exec -it file_integrity_checker bash /app/file_integrity_checker.sh --check
-
See the alert: Open
http://localhost:8025and watch the security alert arrive in your MailHog inbox!
π‘ Key Lessons Learned
-
Volume Mounts & Permissions: When mounting files from macOS to a Linux container, file permissions (like the execute bit) can be tricky. I learned that executing via
bash <script>is often more robust than relying on the+xbit in a shared volume. -
Architecture Matters: Adding
platform: linux/amd64to thedocker-compose.ymlwas essential for ensuring the MailHog image (which is AMD64 only) runs smoothly on modern ARM64 chips like the Apple M1/M2.
π Conclusion
Building your own security tools is one of the best ways to understand how systems work. This project taught me about hashing, database persistence in shell, and the power of Docker for creating reproducible security labs.
What's next for this project? I'm looking into adding Slack/Discord webhook support and real time monitoring via inotify.
Thanks for reading! If you have questions about Bash security or Docker setups, let's chat in the comments! π‘οΈ
Top comments (0)