From 86fd430d46ec10aa6157e349bf6d286002e11cfa Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Wed, 18 Feb 2026 12:58:40 -0700 Subject: [PATCH 1/6] Add IP logging for genCall --- index.js | 7 +- migrations/011_update_callLogs_add_srcIp.sql | 1 + .../AstroCom_Rotate.service | 5 ++ .../AstroCom_Rotate.timer | 7 ++ .../astrocom_rotate.sh | 69 +++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 migrations/011_update_callLogs_add_srcIp.sql create mode 100644 tools/Rotating AstroCom Secret/AstroCom_Rotate.service create mode 100644 tools/Rotating AstroCom Secret/AstroCom_Rotate.timer create mode 100644 tools/Rotating AstroCom Secret/astrocom_rotate.sh diff --git a/index.js b/index.js index 4ca64c1..c8058b4 100644 --- a/index.js +++ b/index.js @@ -1031,10 +1031,10 @@ app.get("/api/healthcheck", (req, res) => { }); // logCall function (caller, callee) -const logCall = (caller, callee) => { +const logCall = (caller, callee, srcIp) => { pool.getConnection().then(conn => { - conn.query('INSERT INTO callLogs (caller, callee, timestamp) VALUES (?, ?, ?)', - [caller, callee, Math.floor(Date.now())]).catch(err => { + conn.query('INSERT INTO callLogs (caller, callee, timestamp, srcIp) VALUES (?, ?, ?, ?)', + [caller, callee, Math.floor(Date.now()), srcIp]).catch(err => { console.error('Error logging call:', err); }).finally(() => { conn.release(); @@ -1043,6 +1043,7 @@ const logCall = (caller, callee) => { } const genCall = (req, res, apiKey, ani, number) => { + const srcIp = process.env.PROXY_HEADER ? req.headers[process.env.PROXY_HEADER] : req.remoteAddress; pool.getConnection().then(conn => { //conn.query("SELECT * FROM routes WHERE apiKey = ? AND block_start <= ? AND block_start + block_length >= ?", [apiKey, ani, ani]).then((rows) => { conn.query("SELECT * FROM routes WHERE apiKey = ?", [apiKey]).then((rows) => { // We'll try this Nick, if it doesn't work we'll go back to the original diff --git a/migrations/011_update_callLogs_add_srcIp.sql b/migrations/011_update_callLogs_add_srcIp.sql new file mode 100644 index 0000000..273365a --- /dev/null +++ b/migrations/011_update_callLogs_add_srcIp.sql @@ -0,0 +1 @@ +ALTER TABLE callLogs ADD COLUMN srcIp VARCHAR(255) NOT NULL DEFAULT 'unknown'; \ No newline at end of file diff --git a/tools/Rotating AstroCom Secret/AstroCom_Rotate.service b/tools/Rotating AstroCom Secret/AstroCom_Rotate.service new file mode 100644 index 0000000..7d1d0d8 --- /dev/null +++ b/tools/Rotating AstroCom Secret/AstroCom_Rotate.service @@ -0,0 +1,5 @@ +[Unit] +Description=Rotate AstroCom Secret +[Service] +ExecStart=/usr/bin/astrocom_rotate.sh +Type=oneshot \ No newline at end of file diff --git a/tools/Rotating AstroCom Secret/AstroCom_Rotate.timer b/tools/Rotating AstroCom Secret/AstroCom_Rotate.timer new file mode 100644 index 0000000..ab2e257 --- /dev/null +++ b/tools/Rotating AstroCom Secret/AstroCom_Rotate.timer @@ -0,0 +1,7 @@ +[Unit] +Description=Rotate AstroCom Secret +[Timer] +# This will run daily at 0200 local time +OnCalendar=*-*-* 02:00:00 +[Install] +WantedBy=timers.target \ No newline at end of file diff --git a/tools/Rotating AstroCom Secret/astrocom_rotate.sh b/tools/Rotating AstroCom Secret/astrocom_rotate.sh new file mode 100644 index 0000000..24367f6 --- /dev/null +++ b/tools/Rotating AstroCom Secret/astrocom_rotate.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# --- USER CONFIG --- +IAXBLOCK="from-astrocom" +CONF="/etc/asterisk/iax_custom.conf" + +# Astrocom API endpoint info +ASTROCOM_URL="https://astrocom.tel/api/v1/user/update" # Shouldn't need to change this! +ASTROCOM_TOKEN="" +# ------------------- + +# Parse flags +DRYRUN=0 +if [[ "$1" == "--dry-run" || "$1" == "-n" ]]; then + DRYRUN=1 +fi + +# Generate a 32-char alphanumeric secret +NEWSECRET=$(tr -dc 'A-Za-z0-9' Date: Wed, 18 Feb 2026 13:28:36 -0700 Subject: [PATCH 2/6] Use req.ip properly --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index c8058b4..fa45e2b 100644 --- a/index.js +++ b/index.js @@ -1043,7 +1043,7 @@ const logCall = (caller, callee, srcIp) => { } const genCall = (req, res, apiKey, ani, number) => { - const srcIp = process.env.PROXY_HEADER ? req.headers[process.env.PROXY_HEADER] : req.remoteAddress; + const srcIp = process.env.PROXY_HEADER ? req.headers[process.env.PROXY_HEADER] : req.ip; pool.getConnection().then(conn => { //conn.query("SELECT * FROM routes WHERE apiKey = ? AND block_start <= ? AND block_start + block_length >= ?", [apiKey, ani, ani]).then((rows) => { conn.query("SELECT * FROM routes WHERE apiKey = ?", [apiKey]).then((rows) => { // We'll try this Nick, if it doesn't work we'll go back to the original -- 2.43.5 From 0689dd23e53c1d9413eaf8e7abf920c086a84b61 Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Wed, 18 Feb 2026 13:35:18 -0700 Subject: [PATCH 3/6] Add more log data --- index.js | 18 ++++++++++++++---- migrations/011_update_callLogs_add_srcIp.sql | 4 +++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index fa45e2b..761a33a 100644 --- a/index.js +++ b/index.js @@ -1031,10 +1031,10 @@ app.get("/api/healthcheck", (req, res) => { }); // logCall function (caller, callee) -const logCall = (caller, callee, srcIp) => { +const logCall = (caller, callee, srcIp, success, reason) => { pool.getConnection().then(conn => { - conn.query('INSERT INTO callLogs (caller, callee, timestamp, srcIp) VALUES (?, ?, ?, ?)', - [caller, callee, Math.floor(Date.now()), srcIp]).catch(err => { + conn.query('INSERT INTO callLogs (caller, callee, timestamp, srcIp, success, reason) VALUES (?, ?, ?, ?, ?, ?)', + [caller, callee, Math.floor(Date.now()), srcIp, success, reason]).catch(err => { console.error('Error logging call:', err); }).finally(() => { conn.release(); @@ -1056,17 +1056,20 @@ const genCall = (req, res, apiKey, ani, number) => { // If no row or error, return 401 if (!row) { res.status(401).send(`${process.env.MSG_ROUTE_ADDRESS}/401`) + logCall(ani, number, srcIp, false, "invalid_api_key"); return; } // Validate the ani and number are 7 digit numbers if (!ani || ani < 1000000 || ani > 9999999 || !number || number < 1000000 || number > 9999999) { res.status(400).send(`${process.env.MSG_ROUTE_ADDRESS}/400`); + logCall(ani, number, srcIp, false, "invalid_number"); return; } // Validate the ani is owned by the apiKey if (ani < row.block_start || ani > row.block_start + row.block_length) { res.status(403).send(`${process.env.MSG_ROUTE_ADDRESS}/403`); + logCall(ani, number, srcIp, false, "ani_not_in_block"); return; } @@ -1078,6 +1081,7 @@ const genCall = (req, res, apiKey, ani, number) => { const routeId = row ? row.id : null; if (!routeId) { res.status(404).send(`${process.env.MSG_ROUTE_ADDRESS}/404`); + logCall(ani, number, srcIp, false, "no_route"); return; } @@ -1085,6 +1089,7 @@ const genCall = (req, res, apiKey, ani, number) => { if (blockRows.length > 0) { // ANI is blocked from calling this route console.log(`Blocked Call Attempt: ${ani} -> ${number}`); + logCall(ani, number, srcIp, false, "blocklist"); res.status(403).send(`${process.env.MSG_ROUTE_ADDRESS}/403`); return; } @@ -1093,7 +1098,7 @@ const genCall = (req, res, apiKey, ani, number) => { // Check if the ANI is within the block range // If it is, return `local` console.log(`New Call: ${ani} -> ${number}`); - logCall(ani, number); + logCall(ani, number, srcIp, true); // incriment estCallsMade analytics addAnalytic("estCallsMade"); dailyAnalytic("dailyCallsMade"); @@ -1104,19 +1109,24 @@ const genCall = (req, res, apiKey, ani, number) => { } } else { res.status(404).send(`${process.env.MSG_ROUTE_ADDRESS}/404`); + logCall(ani, number, srcIp, false, "no_route"); + return; } }).catch(err => { console.error('Error checking blocklist:', err); res.status(500).send(`${process.env.MSG_ROUTE_ADDRESS}/500`); + logCall(ani, number, srcIp, false, "blocklist_error"); return; }); }).catch(err => { console.error('Error getting route:', err); res.status(500).send(`${process.env.MSG_ROUTE_ADDRESS}/500`) + }); }).catch(err => { console.error(err); res.status(401).send(`${process.env.MSG_ROUTE_ADDRESS}/401`) + logCall(ani, number, srcIp, false, "invalid_api_key"); }).finally(() => { conn.release(); }); diff --git a/migrations/011_update_callLogs_add_srcIp.sql b/migrations/011_update_callLogs_add_srcIp.sql index 273365a..e94e9af 100644 --- a/migrations/011_update_callLogs_add_srcIp.sql +++ b/migrations/011_update_callLogs_add_srcIp.sql @@ -1 +1,3 @@ -ALTER TABLE callLogs ADD COLUMN srcIp VARCHAR(255) NOT NULL DEFAULT 'unknown'; \ No newline at end of file +ALTER TABLE callLogs ADD COLUMN srcIp VARCHAR(255) NOT NULL DEFAULT 'unknown'; +ALTER TABLE callLogs ADD COLUMN success INTEGER NOT NULL DEFAULT 0; +ALTER TABLE callLogs ADD COLUMN reason VARCHAR(255) NOT NULL DEFAULT 'none'; \ No newline at end of file -- 2.43.5 From 279f18f8d6152abccf85f3ff9f546bd72dcf9e89 Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Wed, 18 Feb 2026 13:36:27 -0700 Subject: [PATCH 4/6] SQL fixes --- migrations/011_update_callLogs_add_details.sql | 4 ++++ migrations/011_update_callLogs_add_srcIp.sql | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 migrations/011_update_callLogs_add_details.sql delete mode 100644 migrations/011_update_callLogs_add_srcIp.sql diff --git a/migrations/011_update_callLogs_add_details.sql b/migrations/011_update_callLogs_add_details.sql new file mode 100644 index 0000000..3018347 --- /dev/null +++ b/migrations/011_update_callLogs_add_details.sql @@ -0,0 +1,4 @@ +ALTER TABLE callLogs + ADD COLUMN srcIp VARCHAR(255) NOT NULL DEFAULT 'unknown', + ADD COLUMN success INTEGER NOT NULL DEFAULT 0, + ADD COLUMN reason VARCHAR(255) NOT NULL DEFAULT 'none'; \ No newline at end of file diff --git a/migrations/011_update_callLogs_add_srcIp.sql b/migrations/011_update_callLogs_add_srcIp.sql deleted file mode 100644 index e94e9af..0000000 --- a/migrations/011_update_callLogs_add_srcIp.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE callLogs ADD COLUMN srcIp VARCHAR(255) NOT NULL DEFAULT 'unknown'; -ALTER TABLE callLogs ADD COLUMN success INTEGER NOT NULL DEFAULT 0; -ALTER TABLE callLogs ADD COLUMN reason VARCHAR(255) NOT NULL DEFAULT 'none'; \ No newline at end of file -- 2.43.5 From e5880a9e49f1a7eb4ca6e56cc2302dd94ae665ed Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Wed, 18 Feb 2026 13:37:30 -0700 Subject: [PATCH 5/6] Allow setting admin pass to specific string --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 761a33a..7f8c35a 100644 --- a/index.js +++ b/index.js @@ -55,7 +55,7 @@ pool.getConnection().then((conn) => { // delete all users (The big scary one lol) conn.query("DELETE FROM users").then(() => { // Generate 32 char random string - const passwd = crypto.randomBytes(32).toString('hex'); + const passwd = process.env.SET_ADMIN_PASS || crypto.randomBytes(32).toString('hex'); bcrypt.hash(passwd, 10).then((hash) => { conn.query("INSERT INTO users (id, username, passwordHash) VALUES (1, 'admin', ?)", [hash]).then(() => { -- 2.43.5 From 4a0fa8864781728a76c8499a656917c302a8799f Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Wed, 18 Feb 2026 13:39:22 -0700 Subject: [PATCH 6/6] Fix logging --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 7f8c35a..82e4c29 100644 --- a/index.js +++ b/index.js @@ -1031,7 +1031,7 @@ app.get("/api/healthcheck", (req, res) => { }); // logCall function (caller, callee) -const logCall = (caller, callee, srcIp, success, reason) => { +const logCall = (caller, callee, srcIp="none_given", success, reason="none_given") => { pool.getConnection().then(conn => { conn.query('INSERT INTO callLogs (caller, callee, timestamp, srcIp, success, reason) VALUES (?, ?, ?, ?, ?, ?)', [caller, callee, Math.floor(Date.now()), srcIp, success, reason]).catch(err => { -- 2.43.5