DEV Community

Alan Varghese
Alan Varghese

Posted on

Build a Lightweight File Integrity Monitor with Bash, SQLite, and Docker

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:

  1. 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.
  2. 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');"
Enter fullscreen mode Exit fullscreen mode

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: curl to talk directly to the MailHog API.
  • Last Resort: Standard mail command.

🐳 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:

  1. An Ubuntu-based checker container with mock system files.
  2. A MailHog container for email visualization.

How to test a "Malicious" change:

  1. Start the environment:
   docker-compose up -d
Enter fullscreen mode Exit fullscreen mode
  1. Create the baseline:
   docker exec -it file_integrity_checker bash /app/file_integrity_checker.sh --init
Enter fullscreen mode Exit fullscreen mode
  1. Simulate a hack:
   docker exec -it file_integrity_checker bash -c "echo 'MALICIOUS_CODE' >> /etc/myapp/config/app.yaml"
Enter fullscreen mode Exit fullscreen mode
  1. Run the check:
   docker exec -it file_integrity_checker bash /app/file_integrity_checker.sh --check
Enter fullscreen mode Exit fullscreen mode
  1. See the alert: Open http://localhost:8025 and 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 +x bit in a shared volume.
  • Architecture Matters: Adding platform: linux/amd64 to the docker-compose.yml was 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)