System load
Server Health
Kitni RAM use ho rahi hai
RAM + Swap combined limit
/data mount space
Log Pipeline (Live)
Routers se aa rahi lines
Search mein dikhne wale records
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.
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...
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
| Layer | Source | Start Time | End Time |
|---|---|---|---|
| 1 | MikroTik SESSION_START | Exact (connection new) | — |
| 2 | MikroTik SESSION_RST (strict) | From matched START | Exact (TCP reset) |
| 3 | Log server SESSION_TIMEOUT | From START | START + timeout (UDP / silent close) |
connection-state=closing. Silent UDP timeout does not emit firewall logs. Keep router udp-timeout and server SESSION_TIMEOUT aligned (recommended: 5m).
Prerequisites
- Router registered in dashboard → Routers with correct Expected IP.
- NAT Address-List Name set per router (same name used in NAT
src-address-list=). - Find your NAT pool name on MikroTik:
/ip firewall nat print→ notesrc-address-list. - Firewall filter rules must be placed before fasttrack / accept established.
- Do not use empty
interface-list=SUBSCRIBERon BRAS with dynamic PPPoE — use address-list +in-interface~"<pppoe-"for RST.
Log Server Settings
| Setting | Value |
|---|---|
| Log server IP | 175.29.56.6 |
| Ingest port | 15514 (UDP/TCP) |
| Syslog facility | daemon |
| Server timeout | SESSION_TIMEOUT=5m in /opt/cgnat-log-system/.env |
| Router UDP timeout | udp-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
/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.
/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.
/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]
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).
/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
# 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
| Issue | Fix |
|---|---|
syntax error on connection-state=closing | Not 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 rows | Remove old broad RST rules; re-index after MikroTik changes |
| User empty | Log line must contain in:<pppoe-username> |
| Logs not arriving | Check UDP/TCP 15514; verify src-address on syslog action |
interface-list=SUBSCRIBER error | List is empty — use pool + in-interface~"<pppoe-" instead |
| High router CPU | Do not enable TRAFFIC on all established flows |
Search Field Mapping
| MikroTik Event | Search Column | Meaning |
|---|---|---|
SESSION_START | Start Date/Time | Connection opened |
SESSION_RST | End Date/Time | TCP reset / invalid close |
| Server timeout | End Date/Time | UDP / silent session close |
in:<pppoe-user> | User ID | PPPoE subscriber username |
NAT (...) | NAT IP / Port | CGNAT 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
| Role | Server | Path |
|---|---|---|
| Application / Log Server | 10.30.90.249 · 175.29.56.6 | /data/archive/ |
| Storage Node | 10.30.90.250 · storagenode1 | /srv/cgnat/archive/ |
| Replication service | App server | cgnat-replicator (systemd) |
| SSH key (replicator) | App server | /root/.ssh/cgnat_storage_replica |
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
- Storage server with Ubuntu 22.04+ (or similar Linux), root SSH access.
- Enough disk for long-term archive retention (recommend dedicated volume for
/srv/cgnat/archive). - Network: app server
10.30.90.249must reach storage node10.30.90.250on TCP 22. - On app server:
cgnat-compressorandcgnat-replicatorservices running. - 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:
# 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
# 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
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.
# 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)
| Variable | Example |
|---|---|
REPLICATION_MODE | rsync |
REPLICA_TARGETS | root@10.30.90.250:/srv/cgnat/archive |
REPLICA_MIN_SUCCESS | 1 |
DELETE_LOCAL_AFTER_REPLICA | false (keep local copy) |
Step 3 — Register in Dashboard
Open Storage Nodes tab and add or verify the node:
| Field | Example value |
|---|---|
| Node Name | MTCL Storage Node |
| Node Key | storage-primary (unique ID) |
| Endpoint | root@10.30.90.250:/srv/cgnat/archive |
| Region | Private LAN 10.30.90.x |
| Health Status | healthy |
| Status | Enabled |
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)
# 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.
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 badge | Meaning |
|---|---|
| Ready (test only) | SSH/rsync OK; only .connectivity-test/ exists — waiting for first archive hour |
| Waiting | Node reachable; no real archive yet |
| Storing | Archive hours replicated; data on storage node |
| Unreachable | SSH 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.
# 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
| Issue | Fix |
|---|---|
| SSH permission denied | Verify pubkey in storage authorized_keys; use -i /root/.ssh/cgnat_storage_replica |
| Rsync fails | Check RSYNC_RSH in cgnat-replicator systemd unit; restart replicator |
| Only test file, no archive | Normal until first hour completes; check /data/archive on app server |
| verify script fails on storage node | Run verify on app server (249), not storage node |
| Dashboard shows Unreachable | Confirm endpoint format: user@IP:/path; node enabled; SSH from app server works |
| Replicator not syncing | journalctl -u cgnat-replicator -f; ensure manifest.json exists per hour |
| Adding second storage node | Add 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.
System Log Viewer
Software errors and service logs from indexer, admin-api, parser, and replicator.
Storage Nodes Management
Register replication/storage nodes and maintain health + availability state.
/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.
Search Results
| 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. | |||||||||||||
Live Syslog Monitor
Checking live status...
Total Logs Saved
Matched Logs
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: -
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
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)
license.json bhejein.
Clients
| Name | Routers | Status |
|---|---|---|
| Loading... | ||
Client Detail
System Status
Admin API
UPSearch API
UPMetadata DB
OKReplication
RUNService 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.