FreeRADIUS and an operator panel for ISPs and WISPs that use MikroTik as their NAS.
PPPoE, Hotspot and IPoE customers, plans, recharges and live sessions, set up on a fresh server with one command.
Install · MikroTik setup · Upgrade · Backups · Contributing · Security
Warning
Preview: not ready for production yet. Until v1.0.0, a release can bring breaking changes. Try it on a test server or with a few customers, and read the release notes before you upgrade (the installer takes a backup before it changes anything).
ISPGrid installs FreeRADIUS, MariaDB and a web panel on one Ubuntu server. Your MikroTik NAS send their logins to it, and your staff manage customers in the panel. Every change in the panel is written to FreeRADIUS at once; when a customer who is online is changed, their session is disconnected so the change applies now.
- Customers: PPPoE, Hotspot and IPoE accounts, with profile, address, device limit, NAS binding, static IP, pool, address lists, an override speed (with an optional end date) and extra RADIUS attributes.
- Plans and recharges: speed (with burst), validity in days or hours, data and time limits with an optional fair usage speed, time slots; recharge to give a customer a plan and an expiry. Expired and disabled customers get a disabled pool and a notice page.
- Invoices and payments: off until you turn it on in System, then Billing. An invoice with every paid recharge and for manual charges (a CPE), payments by cash, UPI, bank or your own methods, discounts and Free customers, GST (CGST/SGST or IGST by place of supply) or one tax of your country, invoice and receipt PDFs, dues and a CSV export for filing.
- Quick pay: off until you turn it on in System, then Quick pay. A public page (
/pay) where customers pay their dues, and renew a plan that has ended or ends soon, by username or mobile number without logging in, through Paytm (more gateways can be added). Payments land on their invoices, renewals are booked with their invoice, and the customer gets a confirmation message. - Hotspot: off until you turn it on in App settings (while it is off, FreeRADIUS refuses Hotspot page logins). A Hotspot plan can start its validity at the customer's first login instead of at the recharge.
- Online and Login log: who is connected, from which NAS, IP and device, with traffic; every accepted and refused login with the reason. Disconnect a session from the panel.
- Network: NAS, pools, IP ranges with an IP inventory, address lists.
- Staff, roles and Activity log: staff accounts with two-factor login and passkeys; an Admin role and a Technician role (or your own) that set what each person may see and do; who changed what, newest first.
- Notifications: expiry reminders, recharge and welcome messages by SMS (MSG91, DLT templates) and WhatsApp
(wacrm), as rules you set up in the panel. Other providers can be added (see
CONTRIBUTING.md). - Import: customers from CSV, checked by the same rules as the form.
- Languages: English and Hindi; each staff member picks their own. More can be added (see
CONTRIBUTING.md). - Installer: firewall, nightly backups, HTTPS with Let's Encrypt, WireGuard or L2TP/IPsec tunnels for NAS that are not on your network, and a FreeRADIUS self-test (164 checks) at the end of every install and upgrade.
- A fresh Ubuntu 24.04 or 26.04 server, amd64, with at least 3 GB of free disk. No FreeRADIUS, MariaDB or MySQL on it yet. These are the only two systems ISPGrid has been tested on, so the installer stops on anything else (Debian and other distributions included).
- Root access (
sudo). - MikroTik NAS: RouterOS 7 (any connection type) or RouterOS 6 (LAN or L2TP/IPsec).
- Sizing: on a 2 vCPU, 2 GB test server, about 1,100 PPPoE logins per second were answered with none lost
(2,000 customers logging in at once). Run
deploy/tests/radius_load_test.shas root on your own server to measure it; it creates its own test customers (lt_00001and up) and removes them when it ends.
On a cloud server, open the ports first in your provider's firewall (security group); the installer sets up the
firewall on the server itself but cannot reach the provider's. SSH (TCP 22), and as needed: TCP 80 and 443 for the
panel (80 also for the Let's Encrypt check), UDP 51820 for WireGuard, UDP 500 and 4500 for L2TP/IPsec, UDP 1812 and
1813 for --routers=public. For --access=domain, point the domain's DNS at the server before you start.
curl -fsSL https://raw.githubusercontent.com/ispgrid/ispgrid/master/deploy/install.sh -o install.sh
sudo bash install.sh --admin-email=you@example.comThe installer asks what it needs to know (where your NAS are, how you open the panel, the admin password) and
prints a summary at the end: the panel address, the admin login, and what to set on your NAS. Every run is
logged to /var/log/ispgrid-install.log; sudo ispgrid-info shows the summary again later.
Common options (all of them: sudo bash install.sh --help):
| Option | What it does |
|---|---|
--routers=MODE |
Where your NAS are: lan, wireguard, l2tp or public (see below). Default: lan. |
--access=MODE |
How you open the panel: local on your network (the firewall lets only private networks reach it), public on a public IP, or domain with HTTPS. Default: local. |
--domain=panel.example.com |
With --access=domain: the name pointing at this server, for a Let's Encrypt certificate. |
--le-email=EMAIL |
With --access=domain: where Let's Encrypt sends certificate expiry notices. Default: the admin's email. |
--admin-email=EMAIL |
The first admin's login. The password is asked (hidden); with --yes it is generated and shown once. |
--timezone=Asia/Kolkata |
The timezone for FreeRADIUS, MariaDB and the panel. |
--version=vX.Y.Z |
The version to install. Default: the newest release. |
--yes |
Ask nothing and use the defaults. |
Passkeys need the panel on HTTPS with a domain name (--access=domain); browsers do not offer them over plain HTTP.
SETUP.md walks through the whole MikroTik setup: RADIUS, PPPoE (pools, profile, server), NAT, the notice page for expired customers, IPoE, Hotspot and protecting the router. In short:
| Mode | Use it when | What the installer sets up |
|---|---|---|
lan |
The NAS reach the server on a private network. | RADIUS (UDP 1812, 1813) allowed from that network. |
wireguard |
The NAS are elsewhere and run RouterOS 7. | A WireGuard server (UDP 51820); NAS connect through the tunnel. |
l2tp |
The NAS are elsewhere and run RouterOS 6. | An L2TP/IPsec server (UDP 500, 4500); NAS connect through the tunnel. |
public |
Only if a tunnel is impossible. | RADIUS open to the internet. Not recommended: RADIUS traffic is not encrypted. |
For each NAS:
-
Tunnel modes only: on the server, create the NAS's tunnel login. It prints the RouterOS commands to paste, including the tunnel address to use in step 2.
sudo /opt/ispgrid/deploy/wireguard/wg-add-peer.sh office-nas # wireguard sudo /opt/ispgrid/deploy/l2tp/l2tp-add-peer.sh office-nas # l2tp
-
In the panel: Network, NAS, add the NAS with its address (its tunnel address in a tunnel mode) and a RADIUS secret.
-
On the NAS: point
/radiusat the server with the same secret, forpppand/orhotspot, and allow Disconnect-Requests from the panel:/radius add address=SERVER-ADDRESS secret="THE-SECRET" service=ppp,hotspot /radius incoming set accept=yes /ppp aaa set use-radius=yes accounting=yes interim-update=5mIn a tunnel mode, use the
/radiusline the add-peer script printed instead (it also sets the source address). For Hotspot, also turn onuse-radiusin the Hotspot server profile.If the NAS firewall drops input it does not know, accept UDP 3799 from the server (or from the tunnel interface), or Disconnect from the panel will not reach it.
The full order, with the MikroTik side, is in SETUP.md.
- System, App settings: currency, phone format, language, the Hotspot switch, and how long the login log and session history are kept.
- Network, Pools: add the IP pools your NAS hand out, with the same names as on the NAS.
- Plans: create a plan with its speed, validity and pool.
- Customers: add a customer, then Recharge on their page to give them the plan. They can log in now; you see them in Online, and a refused login in Login log with the reason.
Run the installer again. It takes a backup first, keeps your data and settings, and runs the self-test at the end:
sudo /opt/ispgrid/deploy/install.sh --version=vX.Y.ZFrom v0.1.3, sudo ispgrid upgrade --version=vX.Y.Z does the same.
Add-ons add features without changing ISPGrid itself, such as Session records (IPDR) for Indian ISPs or Customer documents. They are installed on the server, never from the panel (ISPGrid v0.1.3 or newer):
sudo ispgrid addon list # installed add-ons, updates, and what else is listed
sudo ispgrid addon add ispgrid/ipdr # the newest version for your ISPGrid
sudo ispgrid addon add ispgrid/ipdr@v0.1.2 # hold one version
sudo ispgrid addon update # move every add-on to its newest listed version
sudo ispgrid addon remove ispgrid/ipdr # its data, such as its database, is kept
sudo ispgrid addon remove ispgrid/ipdr --delete-data # also delete its data (the run's backup keeps a copy)Each change takes a backup first and puts the panel in maintenance for a minute or two; customers stay online. Upgrades of ISPGrid move add-ons to their newest listed version too, unless you held one.
A server installs only add-ons from the ISPGrid add-on list, at the exact commit
that was reviewed before it was listed. --allow-unlisted installs one that is not listed (your own, or a branch):
its code was not reviewed, and every run says so.
A backup runs every night at 02:30 and is kept for 14 days in /var/backups/ispgrid: the database
(radius-*.sql.gz, and ispgrid_*-*.sql.gz: usage per day, ispgrid_usage, and add-ons such as Session records), the invoice logos
(files-core-billing-*.tgz) and the configuration that belongs to it (config-*.tgz: FreeRADIUS, the panel's .env, the add-on list, the tunnel keys). Run one now with sudo ispgrid-backup. Copy /var/backups/ispgrid to another machine: a backup on
the same disk does not survive the disk.
To restore, on a server installed with the same ISPGrid version:
sudo systemctl stop freeradius ispgrid-queue
sudo runuser -u ispgrid -- php /opt/ispgrid/artisan down
gunzip < /var/backups/ispgrid/radius-YYYYMMDD-HHMM.sql.gz | sudo mysql radius
# usage per day:
sudo mysql -e 'CREATE DATABASE IF NOT EXISTS ispgrid_usage'
gunzip < /var/backups/ispgrid/ispgrid_usage-YYYYMMDD-HHMM.sql.gz | sudo mysql ispgrid_usage
# each add-on database, e.g. Session records:
sudo mysql -e 'CREATE DATABASE IF NOT EXISTS ispgrid_ipdr'
gunzip < /var/backups/ispgrid/ispgrid_ipdr-YYYYMMDD-HHMM.sql.gz | sudo mysql ispgrid_ipdr
sudo tar -xzf /var/backups/ispgrid/config-YYYYMMDD-HHMM.tgz -C /
# the invoice logos, when there is a files-core-billing backup:
sudo tar -xzf /var/backups/ispgrid/files-core-billing-YYYYMMDD-HHMM.tgz -C /
sudo /opt/ispgrid/deploy/install.sh --yesThe last step sets the database passwords to the restored ones, installs the add-ons again, restarts the services and the tunnels, and brings the panel back up.
There is no uninstaller. ISPGrid sets up the whole server (MariaDB, FreeRADIUS, nginx, PHP, the firewall and the
tunnels), which is why it needs a fresh one. To stop using it, copy /var/backups/ispgrid to another machine and
rebuild the server.
| Path | What |
|---|---|
/opt/ispgrid |
The panel (Laravel). |
/etc/freeradius |
FreeRADIUS, with the isp virtual server. |
/var/backups/ispgrid |
Nightly backups. |
/var/log/ispgrid-install.log |
Install and upgrade log. |
radius (MariaDB) |
One database for the panel and FreeRADIUS: the panel writes, FreeRADIUS reads. |
The panel is Laravel 13 with Livewire 4 and Tailwind 4, tested with Pest.
composer install
npm install
cp .env.example .env
php artisan key:generate
composer run devTests run against a local MariaDB or MySQL database named radius_test (user root, host 127.0.0.1, pinned in
phpunit.xml):
php artisan test --compact
bash deploy/tests/installer/test_install_sh.sh # installer helpersBranches follow GitHub flow: one branch per feature from master, merged back when it is done and tested.
Releases are tags (v0.1.0), and the installer installs tags.
Please report security problems privately, not in a public issue: see SECURITY.md.
How the installer locks the server down:
- The panel runs as its own user,
ispgrid, not root. PHP-FPM, the queue worker and the scheduler all run as that user. It has no login shell. - That user cannot change the panel's code.
/opt/ispgridbelongs to root;ispgridcan write onlystorage/andbootstrap/cache. If someone broke into the panel, they could not rewrite its code or plant anything invendor/. .envis readable by the panel, not writable (root:ispgrid, mode 640), and other users cannot read it.- One root command. The panel's only sudo rule is
systemctl restart freeradius, for RADIUS settings changes. - Root never runs the panel's code. The installer runs Composer as root without its scripts and every
artisancommand asispgrid. - The database login is limited to the
radiusdatabase and add-on databases namedispgrid_...; FreeRADIUS only readsradius. - Secrets stay off command lines, which every user can read with
ps: the admin password is handed over in the environment. - ufw opens only what is needed: SSH, the panel (with
--access=local, only to private networks), and RADIUS, the notice page and the WireGuard or L2TP tunnel for your NAS.
So installing an add-on or upgrading needs root: use sudo ispgrid addon or the installer, not composer as the
ispgrid user. Don't give ispgrid ownership of /opt/ispgrid to get around that: it removes the
protection, and a package added with Composer by hand is removed at the next upgrade anyway.
Pull requests are welcome. CONTRIBUTING.md explains how to add a language, a notification
provider (SMS, WhatsApp, email) or a trigger.
ISPGrid stands on the work of these projects. Thank you to everyone who builds and maintains them.
On the server
- FreeRADIUS (packages from InkBridge Networks): authentication, authorization and accounting
- MariaDB: the database shared by FreeRADIUS and the panel
- PHP and nginx: run and serve the panel
- Certbot and Let's Encrypt: HTTPS certificates
- WireGuard, strongSwan and xl2tpd: tunnels for NAS that are not on your network
- Ubuntu: the supported server
The panel
- Laravel, with Fortify (login, two-factor) and Passkeys
- Livewire and Blaze, with Alpine.js
- Tailwind CSS and Vite
- Heroicons: icons
- spatie/laravel-activitylog: the activity log
- Dompdf and DejaVu fonts: invoice and receipt PDFs
- Geist, JetBrains Mono and Noto Sans Devanagari: fonts
Testing and tooling
Each keeps its own licence. ISPGrid is not affiliated with or endorsed by any of these projects.
ISPGrid is open source under the MIT License.
The fonts in resources/fonts (Geist, JetBrains Mono, Noto Sans Devanagari) are under the SIL Open Font License. The icons are from
Heroicons (MIT License, Copyright (c) Tailwind Labs, Inc.).