Documentation
Installation and usage guide for the DenyGrid agent and its plugins.
Installing the agent
Prerequisites
- OS : Debian 8+ to 13+, Ubuntu, RHEL, CentOS
- Arch : x86_64, ARM
- Python : 3.5+
- Privileges : root (to read logs)
Automatic installation
With enrollment key (recommended)
Get your enrollment key from My profile → Machine enrollment key in the dashboard, then:
# Install the agent with automatic enrollment (no admin approval needed)
curl -sSL https://denygrid.com/client/install.sh | sudo bash -s -- --key VOTRE_CLE
# Install all plugins
curl -sSL https://denygrid.com/client/update_plugins.sh | sudo bash
Without enrollment key (admin approval)
# Install the agent + systemd service
curl -sSL https://denygrid.com/client/install.sh | sudo bash
# Install all plugins
curl -sSL https://denygrid.com/client/update_plugins.sh | sudo bash
The agent is installed in /opt/security-monitor/ and creates a systemd service security-monitor.
Manual installation
mkdir -p /opt/security-monitor
cd /opt/security-monitor
curl -sSL https://denygrid.com/client/agent.py -o agent.py
curl -sSL https://denygrid.com/client/config.json.example -o config.json
chmod 600 config.json
# Edit config.json with your API key
nano config.json
Configuration
The file /opt/security-monitor/config.json holds the entire configuration:
{
"api_url": "https://denygrid.com/api",
"api_key": "",
"enrollment_key": "",
"machine_alias": "Production Server",
"scan_interval": 60,
"auto_register": true,
"auto_update": true,
"verify_ssl": true,
"plugins": {
"http": { "enabled": true },
"firewall": { "enabled": true },
"ftp": { "enabled": false },
"smtp": { "enabled": false },
"mysql": { "enabled": false },
"pam": { "enabled": false }
}
}
| Option | Description | Default |
|---|---|---|
api_url | URL of the DenyGrid server API | — |
api_key | API key (generated automatically after enrollment) | empty |
enrollment_key | Enrollment key for auto-approval (from My profile) | empty |
machine_alias | Name shown in the dashboard | hostname |
scan_interval | Collection frequency in seconds | 60 |
auto_register | Automatic machine registration | true |
auto_update | Automatic agent update | true |
verify_ssl | Verify the server's SSL certificate | true |
--key option at install time, the API key is generated and configured automatically. Without an enrollment key, the machine requires manual approval by an administrator. You can regenerate your key at any time from your profile (the old one will be invalidated).Updating
| What | Command |
|---|---|
| Agent only | curl -sSL https://denygrid.com/client/update_agent.sh | sudo bash |
| All plugins | curl -sSL https://denygrid.com/client/update_plugins.sh | sudo bash |
| Specific plugin | curl -sSL .../client/install_plugin_http.sh | sudo bash |
The update script creates an automatic backup and preserves the configuration.
SSH plugin built-in
SSH collection is built into the agent — no plugin to enable.
| Event type | Description |
|---|---|
ssh_failed | Failed login attempt |
ssh_invalid_user | Non-existent user |
ssh_success | Successful login |
ssh_closed | Connection closed |
Log sources: /var/log/auth.log, /var/log/secure, journalctl -u sshd
HTTP / WordPress plugin enabled by default
Analyzes Apache and Nginx logs to detect web attacks, scans, CVEs and WordPress attempts.
Configuration
"http": {
"enabled": true,
"auto_discover": true, // auto-scan of log directories
"log_paths": [], // manual paths (optional)
"max_log_files": 100,
"scan_threshold": 10, // 404 threshold for scan detection
"scan_window": 60 // window in seconds
}
Event types
| Event | Description |
|---|---|
http_sql_injection | SQL injection attempt |
http_xss_attempt | XSS attempt |
http_suspicious_path | Suspicious path (traversal, config...) |
http_scan_detected | Directory scan (404 burst) |
http_ddos_detected | DDoS (100+ req/5min per IP) |
http_slowloris_detected | Slowloris attack |
http_backdoor_detected | Backdoor access attempt |
http_cve_* | CVE exploitation (Log4j, Spring4Shell...) |
wp_login_failed | Failed WordPress login |
wp_xmlrpc_attack | XML-RPC attack |
wp_brute_force | wp-login brute force |
wp_plugin_scan | WordPress plugin scan |
wp_shell_upload | Shell upload attempt |
Scanned directories: /var/log/apache2, /var/log/nginx, /var/log/httpd
CrowdSec lists: 1080+ patterns included (587 user-agents, 209 backdoors, 93 sensitive data, CVEs).
FTP plugin opt-in
Monitors vsftpd, proftpd and pure-ftpd.
Enabling
# Via the installation script (recommended)
curl -sSL https://denygrid.com/client/install_plugin_ftp.sh | sudo bash
# Or manually in config.json
"ftp": { "enabled": true }
| Event | Description |
|---|---|
ftp_failed | Failed login |
ftp_invalid_user | Non-existent user |
ftp_success | Successful login |
ftp_connect | Incoming connection |
SMTP plugin opt-in
Monitors Postfix, Exim4, Sendmail and Dovecot. 18 detection patterns covering authentication, relay, spam and scans.
Enabling
"smtp": { "enabled": true }
Event types
| Event | Description |
|---|---|
smtp_auth_failed | SASL authentication failure |
smtp_auth_abort | Authentication aborted |
smtp_brute_force | Brute force detected (5+ failures/IP) |
smtp_relay_denied | Relay attempt denied |
smtp_relay_scan | Open relay scan (3+ attempts) |
smtp_scan_detected | SMTP scan |
smtp_spam_attempt | Spam attempt (10+ sends) |
smtp_rate_abuse | Rate limit exceeded |
smtp_tls_error | TLS error |
smtp_helo_rejected | HELO/EHLO rejected |
Sources: /var/log/mail.log, /var/log/maillog, journalctl -u postfix -u exim4
MySQL plugin opt-in
Monitors MySQL and MariaDB: authentication failures, SQL injections, privilege abuse.
Enabling
"mysql": {
"enabled": true,
"monitor_queries": false // true = also monitors dangerous queries
}
Event types
| Event | Description |
|---|---|
mysql_auth_failed | Access denied |
mysql_brute_force | Brute force detected |
mysql_root_attempt | root login from the network |
mysql_sql_injection | Dangerous query (DROP, LOAD DATA...) |
mysql_privilege_abuse | Privilege escalation |
mysql_connect_scan | MySQL port scan |
Sources: /var/log/mysql/error.log, /var/log/mariadb/mariadb.log, journalctl -u mysql -u mariadb
PAM / System plugin opt-in
Monitors system authentications: sudo, su, cron, PAM sessions.
Enabling
"pam": {
"enabled": true,
"monitor_cron_exec": false // true = monitors cron executions
}
Event types
| Event | Description |
|---|---|
pam_auth_failed | PAM authentication failure |
pam_brute_force | PAM brute force detected |
pam_sudo_failed | sudo command denied |
pam_su_failed | User switch denied |
pam_account_locked | Account locked |
pam_account_expired | Account expired |
system_login_failed | System login failure |
Sources: /var/log/auth.log, /var/log/secure, journalctl -t sudo -t su -t login
Firewall plugin enabled by default
Automatically applies dashboard bans via iptables. Fetches the blacklist every 5 minutes.
Configuration
"firewall": {
"enabled": true,
"check_interval": 300, // seconds between each sync
"backend": "iptables",
"auto_unban": true, // auto-unban when removed from the dashboard
"chain_name": "SECURITY_MONITOR"
}
Verification
# View the active rules
iptables -L SECURITY_MONITOR -n -v
# Count the banned IPs
iptables -L SECURITY_MONITOR -n | grep DROP | wc -l
iptables installed.Auto-ban
The system automatically detects malicious IPs and bans them according to rules configurable from the dashboard (Menu → Auto-ban).
Default rules
| Rule | Threshold | Window | Ban duration |
|---|---|---|---|
| SSH Brute Force | 3 events | 15 min | 5 days |
| HTTP CVE | 3 events | 15 min | 30 days |
| HTTP attacks | 5 events | 15 min | 7 days |
| FTP Brute Force | 5 events | 30 min | 1 day |
| SMTP Brute Force | 5 events | 15 min | 1 day |
| SMTP Scan | 3 events | 15 min | 7 days |
| SMTP Relay Abuse | 5 events | 30 min | 2 days |
| SMTP Spam / Rate | 10 events | 1h | 7 days |
Advanced options
- Repeat offender: an already-banned IP is re-banned on the very first attempt
- Permanent ban: after N bans (default 3), the next one is permanent
- Graduation: duration × multiplier on each repeat offense
- Tor/VPN: reduced thresholds for IPs identified as Tor or VPN
Troubleshooting
The agent does not start
# Check the status
systemctl status security-monitor
# View the logs
journalctl -u security-monitor -f
# Test manually
python3 /opt/security-monitor/agent.py
Plugins do not load
# Check the logs
journalctl -u security-monitor | grep -i plugin
# Check permissions
ls -la /opt/security-monitor/plugins/
# Update the plugin system
curl -sSL https://denygrid.com/client/update_agent.sh | sudo bash
IPs are not banned automatically
- Check the rules in the dashboard (Menu → Auto-ban)
- Check that the IP is not whitelisted
The dashboard is slow
- Use Cache mode on the Events page
- Increase
innodb_buffer_pool_sizein the MySQL config
Buffer stuck
# Check the buffer size
ls -lh /opt/security-monitor/log_buffer.json
# If too large, reset it
sudo systemctl stop security-monitor
sudo rm /opt/security-monitor/log_buffer.json
sudo systemctl start security-monitor