Clearing a Switchvox blocked IP list from Chrome's console
A step-by-step way to export and clear thousands of Switchvox blocked IPs through the built-in API, without clicking through the list one row at a time.
Switchvox automatically blocks addresses that fail too many logins or registrations. On a system that’s been exposed to the internet for a while, that Blocked IPs list can grow into the thousands. Removing entries one at a time in the web interface takes several seconds per row, and on a busy appliance that constant clicking can bog it down.
This guide uses two short scripts you run from Google Chrome’s developer console while logged in to Switchvox. The first saves a copy of the list and summarizes it without changing anything. The second removes the entries one at a time through Switchvox’s own API, at a steady, gentle pace.
Before you clear anything
A huge blocked list is a symptom, not the problem. Clearing it doesn’t stop whatever is filling it, so check these first:
- Is anything open to the whole internet? In the Switchvox admin portal, go to Server > Access Control and find the row for All Networks (0.0.0.0/0). If SIP or Web Admin Portal is on for that row, the whole internet can reach those services, and the list will refill as fast as you clear it. See locking down an exposed on-prem phone system and fix exposure first.
- Is anything actually being blocked that shouldn’t be? Go to Server > Connection Status. If your SIP trunk and every phone show as registered, nothing legitimate is trapped. The list is just history, and clearing it is housekeeping, not an emergency.
- Is the system patched? An internet-exposed Switchvox on an old version has bigger problems than a long block list. See patch Sangoma Switchvox now.
Clearing the list unblocks every address on it, including ones that were attacking you. Only do this after exposure is fixed, and only on a Switchvox you administer.
What you need
- Google Chrome (Microsoft Edge works the same way)
- A Switchvox administrator login
- Admin API access allowed for the network you’re connecting from. If the scripts return an access error, check the Admin API setting for your network under Server > Access Control.
Step 1: Open the console
- Log in to the Switchvox admin portal in Chrome, and stay on any admin page.
- Press F12 to open Chrome’s developer tools. (On Windows, Ctrl+Shift+J opens the console directly.)
- Click the Console tab at the top of the developer tools panel.
- The first time you paste into the console, Chrome shows a warning and blocks the paste. That’s a safety feature against scams that trick people into pasting malicious code. Read the script first, then type
allow pastingand press Enter. Chrome remembers that choice, so you only do it once.
Keep this tab open and in front the whole time. Refreshing or navigating away stops a running script.
Step 2: Export and review the list (read-only)
Paste this into the console and press Enter. It changes nothing on the phone system. It prints how many entries there are, a breakdown by type, the oldest and newest block dates, and downloads a CSV copy for your records:
(async () => {
const res = await fetch('/json', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ request: { method: 'switchvox.blockedIps.getList', parameters: {} } }),
});
const data = await res.json();
const blocked = data?.response?.result?.blocked_ips;
if (!blocked) {
console.error('Unexpected response. Are you logged in as an admin?', data);
return;
}
const raw = blocked.blocked_ip;
const list = Array.isArray(raw) ? raw : raw ? [raw] : [];
console.log(`Blocked IPs on this Switchvox: ${blocked.total_items}`);
if (list.length === 0) return;
const byType = {};
for (const e of list) byType[e.limit_type] = (byType[e.limit_type] || 0) + 1;
console.table(byType);
const dates = list.map((e) => e.date_applied).filter(Boolean).sort();
console.log(`Oldest block: ${dates[0]} Newest block: ${dates[dates.length - 1]}`);
const cols = ['id', 'ip', 'limit_type', 'date_applied', 'credentials'];
const csv = [cols.join(','), ...list.map((e) => cols.map((c) => JSON.stringify(e[c] ?? '')).join(','))].join('\n');
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([csv], { type: 'text/csv' }));
a.download = `switchvox-blocked-ips-${new Date().toISOString().slice(0, 10)}.csv`;
a.click();
console.log(`Saved ${list.length} entries to ${a.download}`);
})();
How to read the results:
- Block types:
sipmeans failed phone registrations (scanners hunting for extensions).https_adminmeans failed logins to the admin portal.https_mainmeans the user portal, andapimeans API logins. - Newest block date: if it’s today, attacks are still happening, and exposure is still a problem. If it’s months old, the list is stale history.
- The CSV: keep it with your ticket notes. Once you clear the list, that evidence is gone.
Step 3: Clear the list
Paste this into the same console and press Enter:
(async () => {
window.stopClearing = false;
const DELAY_MS = 600;
const call = (method, parameters = {}) =>
fetch('/json', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ request: { method, parameters } }),
}).then((r) => r.text());
const getIds = async () => {
const data = JSON.parse(await call('switchvox.blockedIps.getList'));
const raw = data?.response?.result?.blocked_ips?.blocked_ip;
const list = Array.isArray(raw) ? raw : raw ? [raw] : [];
return list.map((e) => e.id);
};
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
let removed = 0;
let errors = 0;
for (let pass = 1; pass <= 20; pass++) {
const ids = await getIds();
console.log(`Pass ${pass}: ${ids.length} blocked IPs remaining`);
if (ids.length === 0) break;
for (const id of ids) {
if (window.stopClearing) {
console.warn(`Stopped by you. Removed ${removed} so far.`);
return;
}
const reply = await call('switchvox.blockedIps.remove', { blocked_ip_id: String(id) });
if (reply.includes('"success"') || reply.includes('23880')) {
removed++;
if (removed % 25 === 0) console.log(`Removed ${removed}...`);
} else {
errors++;
console.warn(`Could not remove entry ${id}:`, reply.slice(0, 200));
if (errors >= 12) {
console.error('Too many errors. Stopping so you can investigate.');
return;
}
}
await sleep(DELAY_MS);
}
}
console.log(`Finished. Removed ${removed} entries with ${errors} errors.`);
})();
What it does:
- Asks Switchvox for the current list, then removes each entry by its ID, one at a time, with a short pause between each.
- Prints progress every 25 removals.
- When it finishes a pass, it asks for the list again and repeats, so anything blocked while it was running gets caught too.
- Treats Switchvox error
23880(entry not found) as success, since it means that entry is already gone. - Stops on its own if it hits repeated errors, so you can look at what’s wrong.
To stop it at any time, type this in the console and press Enter:
window.stopClearing = true
A few practical notes:
- Don’t speed it up. Sending removals in parallel, or without a pause, can overload the appliance. Slow and steady finishes the job.
- Big lists take a while. Expect roughly 25 to 50 removals a minute on a healthy system, and slower on a busy one. Several thousand entries can take a couple of hours.
- Keep the tab in front. Chrome slows down scripts in background tabs, so the run goes faster when you leave that tab visible.
- One tab per phone system. Don’t run it from two tabs against the same Switchvox.
Step 4: Confirm it worked
When the console says Finished, run the Step 2 script again. It should report zero blocked IPs, or only a few new ones if something is still being blocked. Then check Server > Connection Status to confirm your trunk and phones are still registered.
If new blocks show up right away, go back to Before you clear anything. Something is still exposed.
Sources
- PySwitchvox (Digium): the official Python client for the Switchvox Extend API, whose method names the scripts use
- Switchvox clear all blocked IPs example (GitHub): a published example using the
blockedIps.getListandblockedIps.removemethods with theblocked_ip_idparameter - Switchvox Developer Central (Digium): Extend API documentation and request format
- How Chrome DevTools helps to defend against self-XSS attacks (Chrome for Developers): the paste warning and the one-time
allow pastingoverride
From Small Town Sysadmin
Get new guides by email
Plain-English tech tips, scam and security alerts, and fixes for small offices, whether you're the office manager or the IT pro. No spam, and you can unsubscribe anytime.