MTCL Log Server
CGNAT Command Center
Live ingest · indexing progress · storage telemetry
Updating... RX: - · TX: - Raw: - Index: -
Loading system status...

Server Health

CPU
0%50%100%
--%
Processor Usage

System load

RAM
0%50%100%
--%
Physical Memory

Kitni RAM use ho rahi hai

VMEM
0%50%100%
--%
Virtual Memory (Commit)

RAM + Swap combined limit

DISK
0%50%100%
--%
Data Disk Used

/data mount space

Log Pipeline (Live)

INGEST
--
Logs Per Minute

Routers se aa rahi lines

INDEX
--
Searchable Sessions

Search mein dikhne wale records

QUEUE
--
Pending Index

Abhi process hona baqi hai

Log Ingest Trend

Raw vs Indexed

Router Ingest (LPM)

Storage Layers

Index Backlog by Router

Storage Nodes

User Management

Create portal users, assign roles, and control which screens each user can access.

Loading users...

Router Management

Add, edit, and disable MikroTik source mappings for ingest tracking.

Configured Router Sources

Ingest shows if logs are arriving. Click Qty for counts. Live Logs opens on-demand view (no background load).

Name Expected IP NAT Pool Ingest Qty Config Actions

Router Live Logs

Click Live Logs to load...
Opens on demand only.

MikroTik CGNAT Session Logging

Complete documentation for MTCL BRAS routers. Apply these RouterOS settings so every NAT session produces accurate Start Date/Time, End Date/Time, and Duration in Search Logs. Each router uses its own NAT address-list (pool) name — configure pool names in Routers tab first.

Overview — How Start/End Time Works

LayerSourceStart TimeEnd Time
1MikroTik SESSION_STARTExact (connection new)
2MikroTik SESSION_RST (strict)From matched STARTExact (TCP reset)
3Log server SESSION_TIMEOUTFrom STARTSTART + timeout (UDP / silent close)
RouterOS has no connection-state=closing. Silent UDP timeout does not emit firewall logs. Keep router udp-timeout and server SESSION_TIMEOUT aligned (recommended: 5m).

Prerequisites

  1. Router registered in dashboard → Routers with correct Expected IP.
  2. NAT Address-List Name set per router (same name used in NAT src-address-list=).
  3. Find your NAT pool name on MikroTik: /ip firewall nat print → note src-address-list.
  4. Firewall filter rules must be placed before fasttrack / accept established.
  5. Do not use empty interface-list=SUBSCRIBER on BRAS with dynamic PPPoE — use address-list + in-interface~"<pppoe-" for RST.

Log Server Settings

SettingValue
Log server IP175.29.56.6
Ingest port15514 (UDP/TCP)
Syslog facilitydaemon
Server timeoutSESSION_TIMEOUT=5m in /opt/cgnat-log-system/.env
Router UDP timeoutudp-timeout=5m (match server)

Common RouterOS Steps (All Routers)

These steps are identical on every BRAS. Per-router values (IP, pool name) are in the next section.

1. Connection Tracking

RouterOS
/ip firewall connection tracking set enabled=yes tcp-established-timeout=1d udp-timeout=5m

2. SESSION_START Rule

Use the NAT rule's src-address-list name (pool). Replace POOL_NAME with your router's pool from the table below.

RouterOS
/ip firewall filter
add chain=forward action=log connection-state=new \
    src-address-list=POOL_NAME log-prefix="SESSION_START" \
    comment="CGNAT START" \
    place-before=[find where action=fasttrack-connection]

3. SESSION_RST Rule (Strict)

Only log invalid/RST from subscriber PPPoE interfaces — avoids uplink noise.

RouterOS
/ip firewall filter
add chain=forward action=log connection-state=invalid \
    in-interface~"<pppoe-" log-prefix="SESSION_RST" \
    comment="CGNAT RST strict" \
    place-before=[find where action=fasttrack-connection]
Disable any old broad SESSION_RST rule that used only pool + invalid without in-interface~"<pppoe-".

4. Remote Syslog Action

Set src-address to this router's Expected IP (see per-router section).

RouterOS
/system logging action
add name=cgnat-remote target=remote remote=175.29.56.6 remote-port=15514 \
    src-address=ROUTER_IP syslog-facility=daemon

/system logging
add topics=firewall,info action=cgnat-remote
add topics=firewall,warning action=cgnat-remote

Per-Router Configuration

Ready-to-paste commands for each registered router. Pool names come from dashboard Routers → NAT Address-List Name.

Loading router list...

Verification

RouterOS
# START must show pppoe user + NAT block
/log print where message~"SESSION_START" and message~"<pppoe"

# Strict RST should be pppoe-side only
/log print where message~"SESSION_RST" and message~"<pppoe"

# Find old rules to disable
/ip firewall filter print where log-prefix~"SESSION"

Expected log line example:

firewall,info SESSION_START forward: in:<pppoe-user> out:Uplink, connection-state:new,snat proto TCP,
  10.100.1.5:1234->8.8.8.8:443, NAT (10.100.1.5:1234->103.52.34.26:1234)->8.8.8.8:443

Troubleshooting

IssueFix
syntax error on connection-state=closingNot supported on RouterOS — use START + RST + server timeout
Start time always -Enable SESSION_START with correct pool name
End time always -Enable strict RST; for UDP rely on SESSION_TIMEOUT
Duration 0s / duplicate rowsRemove old broad RST rules; re-index after MikroTik changes
User emptyLog line must contain in:<pppoe-username>
Logs not arrivingCheck UDP/TCP 15514; verify src-address on syslog action
interface-list=SUBSCRIBER errorList is empty — use pool + in-interface~"<pppoe-" instead
High router CPUDo not enable TRAFFIC on all established flows

Search Field Mapping

MikroTik EventSearch ColumnMeaning
SESSION_STARTStart Date/TimeConnection opened
SESSION_RSTEnd Date/TimeTCP reset / invalid close
Server timeoutEnd Date/TimeUDP / silent session close
in:<pppoe-user>User IDPPPoE subscriber username
NAT (...)NAT IP / PortCGNAT public mapping

Storage Node Setup & Replication

Complete guide to add a remote archive storage node for MTCL CGNAT logs. Archive hours are compressed on the application server, then replicated via rsync over SSH to a dedicated storage server.

Overview

RoleServerPath
Application / Log Server10.30.90.249 · 175.29.56.6/data/archive/
Storage Node10.30.90.250 · storagenode1/srv/cgnat/archive/
Replication serviceApp servercgnat-replicator (systemd)
SSH key (replicator)App server/root/.ssh/cgnat_storage_replica
Important: Setup scripts run on different machines. Storage node script runs on 10.30.90.250. App replication script and verify_storage_node.sh run on the application server (249) — not on the storage node.

Architecture

Router syslog → Ingest (:15514) → Raw (/data/raw/)
    → Indexer (/data/indexed/) → Compressor → Archive (/data/archive/YYYY/MM/DD/HH/)
        → Replicator (rsync) → Storage Node (/srv/cgnat/archive/YYYY/MM/DD/HH/)

Each completed hour folder contains compressed archive files plus manifest.json. The replicator copies the entire hour directory and records success in archive_metadata (SQLite at /data/metadata/cgnat.db).

Prerequisites

  1. Storage server with Ubuntu 22.04+ (or similar Linux), root SSH access.
  2. Enough disk for long-term archive retention (recommend dedicated volume for /srv/cgnat/archive).
  3. Network: app server 10.30.90.249 must reach storage node 10.30.90.250 on TCP 22.
  4. On app server: cgnat-compressor and cgnat-replicator services running.
  5. Dashboard login with admin or noc role to register the node.

Step 1 — Prepare Storage Node (run on 10.30.90.250)

On the storage server as root, create archive directory and authorize the app server's replicator SSH key.

Option A — Automated script

First run Step 2 on the app server to generate the public key, copy the key file to storage node, then:

Bash (storage node)
# On STORAGE NODE (10.30.90.250) as root
export ARCHIVE_ROOT=/srv/cgnat/archive
export APP_SERVER_IP=10.30.90.249

mkdir -p "$ARCHIVE_ROOT"
chmod 755 "$ARCHIVE_ROOT"
mkdir -p /root/.ssh && chmod 700 /root/.ssh

# Paste app-server public key (from setup_app_storage_replication.sh output):
echo 'PASTE_PUBLIC_KEY_ONE_LINE' >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

# Optional: restrict SSH to app server
ufw allow from 10.30.90.249 to any port 22 proto tcp comment 'CGNAT replicator' || true

Option B — Use bundled setup script

Bash (storage node)
# Copy pubkey to /tmp/cgnat_replica.pub on storage node first, then:
bash /opt/cgnat-log-system/scripts/setup_storage_node.sh /tmp/cgnat_replica.pub
Public key must be a single line in authorized_keys. Line breaks or spaces in the key will break SSH.

Step 2 — Configure App Server Replication (run on 10.30.90.249)

On the application server as root, generate SSH key, update .env, register node in database, and configure replicator.

Bash (app server)
# On APPLICATION SERVER (10.30.90.249) as root
cd /opt/cgnat-log-system

# Automated setup (generates key, updates .env + admin DB):
STORAGE_IP=10.30.90.250 bash scripts/setup_app_storage_replication.sh

# Copy printed public key to storage node authorized_keys (Step 1)
# Then test SSH:
ssh -i /root/.ssh/cgnat_storage_replica root@10.30.90.250 'mkdir -p /srv/cgnat/archive && echo OK'

# Test rsync:
rsync -av -e "ssh -i /root/.ssh/cgnat_storage_replica -o BatchMode=yes" \
  /etc/hostname root@10.30.90.250:/srv/cgnat/archive/.connectivity-test/

# Restart replicator:
systemctl restart cgnat-replicator
systemctl status cgnat-replicator

.env values (reference)

VariableExample
REPLICATION_MODErsync
REPLICA_TARGETSroot@10.30.90.250:/srv/cgnat/archive
REPLICA_MIN_SUCCESS1
DELETE_LOCAL_AFTER_REPLICAfalse (keep local copy)

Step 3 — Register in Dashboard

Open Storage Nodes tab and add or verify the node:

FieldExample value
Node NameMTCL Storage Node
Node Keystorage-primary (unique ID)
Endpointroot@10.30.90.250:/srv/cgnat/archive
RegionPrivate LAN 10.30.90.x
Health Statushealthy
StatusEnabled

Click Refresh List. Expand Details on each node to see live OS, disk capacity, archive usage, and replication status.

Loading configured nodes...

Step 4 — Verify (run on app server only)

Bash (app server)
# Must run on APPLICATION SERVER (10.30.90.249), NOT on storage node
cd /opt/cgnat-log-system
STORAGE_IP=10.30.90.250 bash scripts/verify_storage_node.sh

Expected output: SSH_OK, rsync success, cgnat-replicator active.

Running verify_storage_node.sh on the storage node itself will fail — it needs app-server SSH key and local metadata DB.

When Does Archive Data Appear?

Dashboard badgeMeaning
Ready (test only)SSH/rsync OK; only .connectivity-test/ exists — waiting for first archive hour
WaitingNode reachable; no real archive yet
StoringArchive hours replicated; data on storage node
UnreachableSSH probe failed — check key, firewall, endpoint

Real data starts after compressor finishes an hour under /data/archive/YYYY/MM/DD/HH/ and replicator syncs it. Check Details for Archive used, hour folders, and Replicated (DB) counts.

Bash (manual check)
# From app server — storage node archive size + hour count
ssh -i /root/.ssh/cgnat_storage_replica root@10.30.90.250 \
  'du -sh /srv/cgnat/archive; find /srv/cgnat/archive -mindepth 4 -maxdepth 4 -type d | wc -l'

# Replicated files in metadata DB
sqlite3 /data/metadata/cgnat.db \
  "SELECT COUNT(*), SUM(size) FROM archive_metadata WHERE storage_node LIKE '%10.30.90.250%'"

Troubleshooting

IssueFix
SSH permission deniedVerify pubkey in storage authorized_keys; use -i /root/.ssh/cgnat_storage_replica
Rsync failsCheck RSYNC_RSH in cgnat-replicator systemd unit; restart replicator
Only test file, no archiveNormal until first hour completes; check /data/archive on app server
verify script fails on storage nodeRun verify on app server (249), not storage node
Dashboard shows UnreachableConfirm endpoint format: user@IP:/path; node enabled; SSH from app server works
Replicator not syncingjournalctl -u cgnat-replicator -f; ensure manifest.json exists per hour
Adding second storage nodeAdd comma-separated target in REPLICA_TARGETS or register multiple enabled nodes in dashboard

Audit Logs & Portal Login History

Who logged in, when, from which IP — plus all API activity.

Loading audit trail...

System Log Viewer

Software errors and service logs from indexer, admin-api, parser, and replicator.

Loading logs...

Storage Nodes Management

Register replication/storage nodes and maintain health + availability state.

Data kahan store ho raha hai? App server par /data SSHFS mount hai → storage node 10.30.90.250:/srv/cgnat. Raw, index, sessions, archive sab wahan likhte hain. App par sirf /opt/cgnat-log-system chalti hai. Details expand karke totals dekhein · LAN Speed se 10G link test karein.

Configured Storage Nodes

Name Node Key Endpoint Region Health Status Archive Data Notes Actions

Session Logs Search

Search CGNAT sessions with public IP enrichment, NAT mapping, and session timing.

Set filters and click Search.

Search Results

Viewing 0 Matched 0
ID USER ID START DATE/TIME END DATE/TIME DURATION USER DETAILS SRC IP SRC PORT NAT IP NAT PORT DST IP DST PORT APP/ORG NAME BRAS/NAS ID
No search performed yet.
Page 0 / 0

Live Syslog Monitor

Checking live status...

No active no-log alert.

Total Logs Saved

-

Matched Logs

0

Raw Lines (Ingest)

-

Indexed / Searchable

-

Pending Index

-

Indexer Workers

-

Raw Log Disk

-

Index DB Disk

-

Index DB Files

-

Data Disk Used

-

Pipeline stats loading...

Latest Raw File: -

Last Update: -

Seconds Since Update: -

Auto refresh every 10 seconds

Indexer Worker Progress

Router Raw File Progress Indexed Offset Pending

Data Storage & Database Sizes

Loading storage details...

Metadata DB

-

Indexer State

-

JSONL (optional)

-

Raw Backup

-
Storage Layer Path Size What is stored
Loading...

Largest Index DB Hours

Hour Path SQLite Size (db+wal)
Loading...

Router-wise Ingest Graph (logs/min)

Router Ingest Table

Router Source Status Last Log Logs/sec Logs/min Logs/hour

Recent Raw Lines

Waiting for logs...

License Status

Loading license...

Status

-

Customer

-

Edition

-

Days Left

-

Expires: -

Max Routers: - | Tenant: -

Server Fingerprint: -

System Health Alerts

Loading health report...

Overall

-

Indexed Rows

-

Pending Index

-

Disk Used

-

    Client Licenses

    Jin ISP / customer ko aap yeh software dete hain — un ka record, payment aur license file yahan se banayein. (Sirf Super Admin)

    1. Fingerprint lo Customer apne server par License Status tab se machine fingerprint copy kare aur aap ko bheje.
    2. Client add karein Naya client add karein, fingerprint paste karein, max routers aur days set karein.
    3. License generate Payment record karein (optional), phir Generate License — customer ko license.json bhejein.

    Clients

    Name Routers Status
    Loading...

    Client Detail

    Left list se client select karein — payment aur license yahan dikhega.

    System Status

    Admin API

    UP

    Search API

    UP

    Metadata DB

    OK

    Replication

    RUN

    Service Endpoints

    Admin API: http://175.29.56.6:18081

    Search API: http://175.29.56.6:18080

    Server: 175.29.56.6 (Ubuntu)

    Current Time:

    How Data Is Stored (Architecture)

    1. Raw logs (text files) — MikroTik syslog lines are saved as plain .log files under /data/raw/YYYY/MM/DD/HH/{BRAS_IP}.log. These are the original lines; nothing is deleted during indexing.

    2. Search index (SQLite per hour) — Indexer parses each raw line and saves searchable fields into /data/indexed/YYYY/MM/DD/HH/index.db. Each row stores IP, ports, user, timestamps, plus raw_file + raw_offset pointer back to the original line. Raw file content is not duplicated inside SQLite.

    3. Metadata DB — Dashboard users, router registry, audit logs live in /data/metadata/cgnat.db (separate from CGNAT search index).

    4. State files — Indexer progress offsets and active session tracking under /data/state/ (small JSON/marker files).

    Search flow: Dashboard search reads hourly index.db files → returns matched sessions → can trace back to raw log via stored file path + byte offset.