A host-based intrusion detection system for FTP servers, combines an Isolation Forest ML model with rule based signature engine and a human in the loop (HITL) feedback loop.
the dataset data/samples/dataset.csv contains 109 sessions with both metadata (for inspection) and ML-ready numeric features.
98 normal sessions from production GitHub Actions deployment traffic, 11 anomalous sessions (failed logins, anonymous access).
Supported rules:
- VSFTPD_234_BACKDOOR: detects CVE-2011-2523 exploit attempts (USER with
:)suffix). - FTP_BOUNCE_MGLNDD: detects MGLNDD scanner probes.
- PORT_SCAN: detects connections with no FTP commands (banner grab).
- BRUTE_FORCE: detects sessions with 5 or more failed login attempts.
- ANONYMOUS_ABUSE: detects anonymous login attempts with write commands.
src/ftp_ids/
cli.py # CLI entry point (ftp-ids command)
config.py # paths, contamination, defaults
core/
detector.py # Isolation Forest training and scoring
feature_extractor.py # 17 features from session dicts
rule_engine.py # 5-rule signature engine
session_builder.py # groups events into sessions by IP
storage.py # alerts.csv and clean_pool.csv I/O
parsers/
base.py # abstract parser
vsftpd_parser.py # vsftpd log line parser
dashboard/
app.py # Flask app
stats.py # dashboard statistics
alerts_service.py # alert listing, detail, labeling
retrain_service.py # retrain via subprocess
templates/ # Jinja2 templates (6 pages)
data/
samples/ # sample log files and datasets
models/ # trained model (.pkl)
reports/ # alerts.csv, clean_pool.csv, sessions.csv
notebooks/
eda.ipynb # exploratory data analysis
evaluation.ipynb # model evaluation
scripts/
anonymize.py # log anonymization
tests/
test_vsftpd_parser.py # parser unit tests
- Python 3.10+
- vsftpd with
log_ftp_protocol=YESin/etc/vsftpd.conf
Tested on Ubuntu 24.04 with vsftpd 3.0.3.
# clone the repo
git clone https://github.com/AmraniCh/ftp-ids-ml.git
cd ftp-ids-ml
# create virtual environment
python3 -m venv venv
source venv/bin/activate
# install dependencies
pip install -r requirements.txt
# install the package (editable mode)
pip install -e .Add these lines to /etc/vsftpd.conf to enable detailed logging:
log_ftp_protocol=YES
xferlog_enable=YES
Then restart vsftpd:
sudo systemctl restart vsftpd# parse a log file and print events
ftp-ids parse --log /var/log/vsftpd.log
# show sessions
ftp-ids sessions --log /var/log/vsftpd.log
# extract features
ftp-ids extract --log /var/log/vsftpd.log
# train the model
ftp-ids train --log /var/log/vsftpd.log
# watch for new sessions in real time
ftp-ids watch --log /var/log/vsftpd.log
# mark a session as normal (HITL feedback)
ftp-ids correct --ip 192.168.1.10 --start "2026-06-21 03:41:05"
# retrain the model with feedback
ftp-ids retrain --log /var/log/vsftpd.logcd src/ftp_ids/dashboard
flask runOpen http://localhost:5000 in the browser.
Pages: overview with stats, alerts list with pagination, alert detail with 17 features, live monitoring with real-time notifications.
Before sharing log files, run the anonymization script:
# copy the example config
cp scripts/anonymize.example.conf scripts/anonymize.conf
# edit anonymize.conf with your real values
# (this file is gitignored)
# run
python scripts/anonymize.py data/raw/vsftpd.log data/raw/vsftpd_anon.log scripts/anonymize.confMIT
