feat: plug-and-play refactor — docker-npm action, CF support, whitelist live-update
- Replace iptables-allports with docker-npm action (DOCKER-USER + xt_string X-Forwarded-For matching + INPUT chain) matching user's working setup - Add telegram_notif.sh (deployed to /data/action.d/ at first run, user-editable) - Add cloudflare.conf action; jail.cloudflare.local enabled via CF compose file - Two compose files: docker-compose.yml (standard) and docker-compose.cloudflare.yml - entrypoint: modprobe xt_string, DOCKER-USER chain check, CF jail auto-selection, telegram_notif.sh deployment to persistent volume on first run - Fix whitelist live-update: addignoreip/delignoreip called alongside jail.local write - Hardcode AUTOBAN_THR=75 and DEFAULT_DAYS=3 (remove env vars) - Include Nginx Proxy Manager in both compose files with shared log bind mount - Rewrite filters for actual NPM log format ([Client <HOST>] real IP extraction) - Add DATA_DIR, Telegram, CF API key fields to .env.example Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,9 +19,9 @@ const CF_SYNC = process.env.CF_SYNC || '/usr/local/bin/cloudflare-wh
|
||||
const MANUAL_JAIL = process.env.MANUAL_JAIL || 'manual-bans';
|
||||
const BAN_HIST_FILE = process.env.BAN_HIST_FILE || '/data/ban-history.json';
|
||||
const SUBNETS = (process.env.SUBNETS_TO_IGNORE || '10.0.0.0/8,172.16.0.0/12').split(',').map(s => s.trim());
|
||||
const DEFAULT_DAYS = parseInt(process.env.DEFAULT_LOOKBACK_DAYS || '3');
|
||||
const DEFAULT_DAYS = 3;
|
||||
const ABUSE_KEY = process.env.ABUSEIPDB_API_KEY;
|
||||
const AUTOBAN_THR = parseInt(process.env.AUTOBAN_THRESHOLD || '75');
|
||||
const AUTOBAN_THR = 75;
|
||||
// Optional: POST to this URL on every manual ban (Discord, Slack, n8n, etc.)
|
||||
const WEBHOOK_URL = process.env.WEBHOOK_URL || '';
|
||||
|
||||
@@ -73,11 +73,12 @@ async function addWhitelist(ip, note) {
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(JAIL_LOCAL, lines.join('\n'));
|
||||
// unban from all jails
|
||||
// Live-update running fail2ban (no reload needed)
|
||||
const jails = await getJails();
|
||||
await Promise.all(jails.map(j =>
|
||||
run(`fail2ban-client set ${j} unbanip ${ip}`).catch(() => {})
|
||||
));
|
||||
await Promise.all(jails.map(j => Promise.all([
|
||||
run(`fail2ban-client set ${j} addignoreip ${ip}`).catch(() => {}),
|
||||
run(`fail2ban-client set ${j} unbanip ${ip}`).catch(() => {}),
|
||||
])));
|
||||
if (fs.existsSync(CF_SYNC)) exec(`${CF_SYNC} &`);
|
||||
}
|
||||
|
||||
@@ -87,6 +88,11 @@ async function removeWhitelist(ip) {
|
||||
new RegExp(`\\s*${ip.replace(/\./g, '\\.')}(?:\\s*#[^\\n]*)?`, 'g'), ''
|
||||
);
|
||||
fs.writeFileSync(JAIL_LOCAL, updated);
|
||||
// Live-update running fail2ban (no reload needed)
|
||||
const jails = await getJails();
|
||||
await Promise.all(jails.map(j =>
|
||||
run(`fail2ban-client set ${j} delignoreip ${ip}`).catch(() => {})
|
||||
));
|
||||
if (fs.existsSync(CF_SYNC)) exec(`${CF_SYNC} &`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user