Install¶
This is the 15-minute path on a fresh Ubuntu 24.04. Adapt for Debian, RHEL, etc.
What you need before starting
- One Linux server with sudo
- Python 3.12+
- Outbound HTTPS to
api.openrouter.ai,api.telegram.org, optionallycloudflare.comfor the tunnel - A Telegram bot token (create one with @BotFather)
- Optional: an OpenRouter API key for cloud LLM fallback
1. System packages¶
sudo apt update
sudo apt install -y python3 python3-venv python3-pip git fail2ban ufw \
nginx postgresql nginx-extras apache2-utils
apache2-utils is for htpasswd (used by the optional dashboard reverse-proxy basic auth, see deploy/fenrirsoc/).
2. Clone and set up the venv¶
sudo useradd -r -s /usr/sbin/nologin -m -d /home/p3guardian p3guardian || true
sudo usermod -a -G adm p3guardian # so it can read /var/log/*
cd /opt
sudo git clone https://github.com/P3consultingtech/p3guardian.git
sudo chown -R p3guardian:p3guardian /opt/p3guardian
cd /opt/p3guardian
sudo -u p3guardian python3 -m venv .venv
sudo -u p3guardian .venv/bin/pip install -e .
3. Configure .env¶
Create /opt/p3guardian/.env with at minimum:
# Database โ leave empty for SQLite, fill for PostgreSQL
DATABASE_URL=postgresql://p3guardian:<password>@localhost/p3guardian
# Telegram
TELEGRAM_BOT_TOKEN=<your-telegram-bot-token>
TELEGRAM_CHAT_ID=<your-chat-id>
# AI backend โ at least one of:
OPENROUTER_API_KEY=<your-openrouter-key> # cloud, faster
OPENROUTER_MODEL=qwen/qwen3.5-flash-02-23
# or:
OLLAMA_URL=http://127.0.0.1:11434
OLLAMA_MODEL=qwen3:0.6b
# Public URL (used in Telegram links, can be LAN IP for dev)
WEB_PUBLIC_URL=https://app.<your-domain>
# GDPR breach notifications (recommended)
BREACH_NOTIFICATION_ENABLED=true
BREACH_NOTIFICATION_EMAIL=<your-dpo-email>
Full reference: Environment variables.
4. Create the database (PostgreSQL path)¶
sudo -u postgres psql <<EOF
CREATE USER p3guardian WITH PASSWORD '<password>';
CREATE DATABASE p3guardian OWNER p3guardian;
GRANT ALL PRIVILEGES ON DATABASE p3guardian TO p3guardian;
EOF
Tables are created automatically on first start by Base.metadata.create_all. No migrations to run.
5. systemd unit¶
[Unit]
Description=P3 Guardian โ AI Security Monitor (Fenrir SOC)
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
User=p3guardian
Group=p3guardian
WorkingDirectory=/opt/p3guardian
EnvironmentFile=/opt/p3guardian/.env
ExecStart=/opt/p3guardian/.venv/bin/python -m p3guardian
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
# Hardening
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now p3guardian.service
sudo systemctl status p3guardian.service
6. Verify¶
# Service is active
systemctl is-active p3guardian.service
# Logs are flowing
sudo journalctl -u p3guardian -n 30 --no-pager
# Dashboard responds
curl -s http://127.0.0.1:8443/api/stats | python3 -m json.tool
You should see all 9 monitors logged as Monitor started: in the journal:
auth -> /var/log/auth.log
honeypot -> /var/log/nginx/honeypot.log
fail2ban -> /var/log/fail2ban.log
nginx -> /var/log/nginx/access.log
ufw -> /var/log/ufw.log
kernel -> /var/log/kern.log
package -> /var/log/dpkg.log
baseline -> [periodic:600s]
cve -> [periodic:21600s]
And on Telegram, your bot should send a startup message:
7. Smoke test detection¶
Trigger a fake honeypot hit from outside your LAN (LAN IPs are whitelisted by default โ see IP_WHITELIST in env vars):
Within ~1 second you should see:
- A new row in
eventswithsource='honeypot',category='honeypot_hit',severity=HIGH - An
investigation_jobsrow enteringstatus='investigating' - 30-90 seconds later, a Telegram alert with the analyst's verdict
- A new entry on the dashboard's AI Investigations panel
8. Optional: expose the dashboard publicly¶
The dashboard listens on 127.0.0.1:8443. To expose it via Cloudflare Tunnel + nginx with basic auth, see the bundled deploy/fenrirsoc/ recipe.
Then change the placeholder password:
9. Optional: enable Autonomous Response (after week 1)¶
Out of the box, Fenrir's responder pipeline is limited to fail2ban IP banning. Sprint 2 adds five revertible host-level actions โ kill_process, file_quarantine, service_stop, isolate_network, package_rollback โ gated by analyst confidence and revertible from Telegram or /autonomous.
These are disabled by default. The recommended rollout:
# Week 1 โ passive observation only. The dispatcher persists everything
# it WOULD have done, but executes nothing.
AUTO_ACTION_ENABLED=true
AUTO_ACTION_DRY_RUN=true
AUTO_ACTION_MIN_CONFIDENCE=85
AUTO_ACTION_TYPES=kill_process,file_quarantine,service_stop
After 7 days, review every row on the dashboard's /autonomous page. Confirm no false positives would have hit critical processes. Add anything missing to AUTO_ACTION_PROCESS_WHITELIST. Then:
Full operational checklist: Autonomous response.
Before you go internet-facing¶
The defaults shipped above are picked for a 15-minute first install. Several of them are intentionally permissive for development convenience and must be changed before production exposure: the IP whitelist, the dashboard authentication, the LLM model size, the auto-action confidence threshold.
Read the Hardening checklist before exposing this server to the internet. Five-minute review, prevents the obvious own-goals.
What's next¶
- Read the Architecture overview if you skipped it
- Open Monitors to understand each detector
- Configure Compliance so daily audits start
- Set up Telegram chat ID so alerts reach you