224 lines
8.5 KiB
JavaScript
224 lines
8.5 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
/**
|
|||
|
|
* Check Omada firewall rules for Blockscout access
|
|||
|
|
* Queries Omada Controller API to list firewall rules that might block Blockscout
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { OmadaClient } from '../omada-api/src/client/OmadaClient.js';
|
|||
|
|
import { FirewallService } from '../omada-api/src/services/FirewallService.js';
|
|||
|
|
import dotenv from 'dotenv';
|
|||
|
|
import { fileURLToPath } from 'url';
|
|||
|
|
import { dirname, join } from 'path';
|
|||
|
|
|
|||
|
|
const __filename = fileURLToPath(import.meta.url);
|
|||
|
|
const __dirname = dirname(__filename);
|
|||
|
|
|
|||
|
|
// Load environment variables
|
|||
|
|
dotenv.config({ path: join(__dirname, '..', '.env') });
|
|||
|
|
|
|||
|
|
const BLOCKSCOUT_IP = '192.168.11.140';
|
|||
|
|
const BLOCKSCOUT_PORT = '80';
|
|||
|
|
|
|||
|
|
async function main() {
|
|||
|
|
console.log('════════════════════════════════════════');
|
|||
|
|
console.log('Omada Firewall Rules Check for Blockscout');
|
|||
|
|
console.log('════════════════════════════════════════');
|
|||
|
|
console.log('');
|
|||
|
|
console.log(`Blockscout IP: ${BLOCKSCOUT_IP}`);
|
|||
|
|
console.log(`Blockscout Port: ${BLOCKSCOUT_PORT}`);
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
// Get Omada credentials from environment
|
|||
|
|
const controllerUrl = process.env.OMADA_CONTROLLER_URL || process.env.OMADA_CONTROLLER_BASE_URL;
|
|||
|
|
const apiKey = process.env.OMADA_API_KEY || process.env.OMADA_CLIENT_ID;
|
|||
|
|
const apiSecret = process.env.OMADA_API_SECRET || process.env.OMADA_CLIENT_SECRET;
|
|||
|
|
const siteId = process.env.OMADA_SITE_ID;
|
|||
|
|
|
|||
|
|
if (!controllerUrl || !apiKey || !apiSecret) {
|
|||
|
|
console.error('❌ Missing Omada credentials in .env file');
|
|||
|
|
console.error('');
|
|||
|
|
console.error('Required environment variables:');
|
|||
|
|
console.error(' OMADA_CONTROLLER_URL (or OMADA_CONTROLLER_BASE_URL)');
|
|||
|
|
console.error(' OMADA_API_KEY (or OMADA_CLIENT_ID)');
|
|||
|
|
console.error(' OMADA_API_SECRET (or OMADA_CLIENT_SECRET)');
|
|||
|
|
console.error(' OMADA_SITE_ID (optional)');
|
|||
|
|
process.exit(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log(`Controller URL: ${controllerUrl}`);
|
|||
|
|
console.log(`Site ID: ${siteId || 'auto-detect'}`);
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// Initialize Omada client
|
|||
|
|
const client = new OmadaClient({
|
|||
|
|
baseUrl: controllerUrl,
|
|||
|
|
clientId: apiKey,
|
|||
|
|
clientSecret: apiSecret,
|
|||
|
|
siteId: siteId,
|
|||
|
|
verifySsl: process.env.OMADA_VERIFY_SSL !== 'false',
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const firewallService = new FirewallService(client);
|
|||
|
|
|
|||
|
|
console.log('Fetching firewall rules...');
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
// List all firewall rules
|
|||
|
|
const rules = await firewallService.listFirewallRules();
|
|||
|
|
|
|||
|
|
console.log(`Found ${rules.length} firewall rules`);
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
// Filter rules that might affect Blockscout
|
|||
|
|
const relevantRules = rules.filter((rule) => {
|
|||
|
|
// Check if rule affects Blockscout IP or port 80
|
|||
|
|
const affectsBlockscoutIP =
|
|||
|
|
!rule.dstIp ||
|
|||
|
|
rule.dstIp === BLOCKSCOUT_IP ||
|
|||
|
|
rule.dstIp.includes(BLOCKSCOUT_IP.split('.').slice(0, 3).join('.'));
|
|||
|
|
|
|||
|
|
const affectsPort80 =
|
|||
|
|
!rule.dstPort ||
|
|||
|
|
rule.dstPort === BLOCKSCOUT_PORT ||
|
|||
|
|
rule.dstPort.includes(BLOCKSCOUT_PORT) ||
|
|||
|
|
rule.dstPort === 'all';
|
|||
|
|
|
|||
|
|
const isTCP =
|
|||
|
|
!rule.protocol ||
|
|||
|
|
rule.protocol === 'tcp' ||
|
|||
|
|
rule.protocol === 'tcp/udp' ||
|
|||
|
|
rule.protocol === 'all';
|
|||
|
|
|
|||
|
|
return rule.enable && (affectsBlockscoutIP || affectsPort80) && isTCP;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (relevantRules.length === 0) {
|
|||
|
|
console.log('ℹ️ No firewall rules found that specifically target Blockscout');
|
|||
|
|
console.log('');
|
|||
|
|
console.log('Checking for default deny policies...');
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
// Check for default deny rules
|
|||
|
|
const denyRules = rules.filter(
|
|||
|
|
(rule) => rule.enable && (rule.action === 'deny' || rule.action === 'reject')
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (denyRules.length > 0) {
|
|||
|
|
console.log(`⚠️ Found ${denyRules.length} deny/reject rules that might block traffic:`);
|
|||
|
|
console.log('');
|
|||
|
|
denyRules.forEach((rule) => {
|
|||
|
|
console.log(` - ${rule.name} (Action: ${rule.action}, Priority: ${rule.priority})`);
|
|||
|
|
});
|
|||
|
|
console.log('');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Check all rules for reference
|
|||
|
|
console.log('All firewall rules:');
|
|||
|
|
console.log('');
|
|||
|
|
rules.forEach((rule) => {
|
|||
|
|
const status = rule.enable ? '✓' : '✗';
|
|||
|
|
console.log(
|
|||
|
|
` ${status} ${rule.name} (Action: ${rule.action}, Direction: ${rule.direction}, Priority: ${rule.priority})`
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
console.log(`🔍 Found ${relevantRules.length} rule(s) that might affect Blockscout:`);
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
relevantRules.forEach((rule) => {
|
|||
|
|
console.log(`Rule: ${rule.name}`);
|
|||
|
|
console.log(` ID: ${rule.id}`);
|
|||
|
|
console.log(` Enabled: ${rule.enable ? 'Yes' : 'No'}`);
|
|||
|
|
console.log(` Action: ${rule.action}`);
|
|||
|
|
console.log(` Direction: ${rule.direction}`);
|
|||
|
|
console.log(` Protocol: ${rule.protocol || 'all'}`);
|
|||
|
|
console.log(` Source IP: ${rule.srcIp || 'Any'}`);
|
|||
|
|
console.log(` Source Port: ${rule.srcPort || 'Any'}`);
|
|||
|
|
console.log(` Destination IP: ${rule.dstIp || 'Any'}`);
|
|||
|
|
console.log(` Destination Port: ${rule.dstPort || 'Any'}`);
|
|||
|
|
console.log(` Priority: ${rule.priority}`);
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
if (rule.action === 'deny' || rule.action === 'reject') {
|
|||
|
|
console.log(' ⚠️ WARNING: This rule BLOCKS traffic!');
|
|||
|
|
console.log('');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('════════════════════════════════════════');
|
|||
|
|
console.log('Recommendations');
|
|||
|
|
console.log('════════════════════════════════════════');
|
|||
|
|
console.log('');
|
|||
|
|
|
|||
|
|
// Check if there's an allow rule for Blockscout
|
|||
|
|
const allowRules = relevantRules.filter((rule) => rule.action === 'allow');
|
|||
|
|
const denyRules = relevantRules.filter(
|
|||
|
|
(rule) => rule.action === 'deny' || rule.action === 'reject'
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (denyRules.length > 0 && allowRules.length === 0) {
|
|||
|
|
console.log('❌ Issue Found:');
|
|||
|
|
console.log(' Deny rules exist that might block Blockscout, but no allow rules found.');
|
|||
|
|
console.log('');
|
|||
|
|
console.log('✅ Recommended Action:');
|
|||
|
|
console.log(' Create an allow rule with HIGH priority (above deny rules):');
|
|||
|
|
console.log('');
|
|||
|
|
console.log(' Name: Allow Internal to Blockscout HTTP');
|
|||
|
|
console.log(' Enable: Yes');
|
|||
|
|
console.log(' Action: Allow');
|
|||
|
|
console.log(' Direction: Forward');
|
|||
|
|
console.log(' Protocol: TCP');
|
|||
|
|
console.log(' Source IP: 192.168.11.0/24 (or leave blank for Any)');
|
|||
|
|
console.log(' Destination IP: 192.168.11.140');
|
|||
|
|
console.log(' Destination Port: 80');
|
|||
|
|
console.log(' Priority: High (above deny rules)');
|
|||
|
|
console.log('');
|
|||
|
|
} else if (allowRules.length > 0) {
|
|||
|
|
const highestAllowPriority = Math.max(...allowRules.map((r) => r.priority));
|
|||
|
|
const lowestDenyPriority = denyRules.length > 0
|
|||
|
|
? Math.min(...denyRules.map((r) => r.priority))
|
|||
|
|
: Infinity;
|
|||
|
|
|
|||
|
|
if (highestAllowPriority < lowestDenyPriority) {
|
|||
|
|
console.log('✅ Configuration looks correct:');
|
|||
|
|
console.log(' Allow rules have higher priority than deny rules.');
|
|||
|
|
console.log('');
|
|||
|
|
} else {
|
|||
|
|
console.log('⚠️ Potential Issue:');
|
|||
|
|
console.log(' Some deny rules have higher priority than allow rules.');
|
|||
|
|
console.log(' Ensure allow rules are above deny rules in priority.');
|
|||
|
|
console.log('');
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
console.log('ℹ️ No specific rules found for Blockscout.');
|
|||
|
|
console.log(' Traffic should be allowed by default (LAN → LAN on same subnet).');
|
|||
|
|
console.log(' If issues persist, check for default deny policies.');
|
|||
|
|
console.log('');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('════════════════════════════════════════');
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ Error querying Omada Controller:');
|
|||
|
|
console.error('');
|
|||
|
|
if (error.message) {
|
|||
|
|
console.error(` ${error.message}`);
|
|||
|
|
} else {
|
|||
|
|
console.error(' ', error);
|
|||
|
|
}
|
|||
|
|
console.error('');
|
|||
|
|
console.error('Troubleshooting:');
|
|||
|
|
console.error(' 1. Verify Omada Controller is accessible');
|
|||
|
|
console.error(' 2. Check API credentials in .env file');
|
|||
|
|
console.error(' 3. Verify network connectivity to controller');
|
|||
|
|
process.exit(1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
main().catch((error) => {
|
|||
|
|
console.error('Fatal error:', error);
|
|||
|
|
process.exit(1);
|
|||
|
|
});
|
|||
|
|
|