MADMIN
MADMIN/Documentation

User Manual

Complete guide to the MADMIN management portal.

Get Started

MADMIN runs on Ubuntu 24.04 LTS. The automated installer handles everything: system packages, PostgreSQL, Python virtualenv, Nginx reverse proxy, iptables/ipset rules, and the systemd service.

Requirements

  • Ubuntu 24.04 LTS (fresh install recommended)
  • Root / sudo access
  • Internet connectivity (for apt and pip packages)

Installation

  1. Clone the repository: git clone https://github.com/EdoardoFiore/madmin.git
  2. Enter the directory: cd madmin
  3. Run the setup script with your chosen admin username and password:
    sudo bash scripts/setup-madmin.sh -u <username> -p '<password>'

Post-install access

ItemValue
URLhttps://<server-ip>:7443
Usernameas specified during install (-u flag)
Passwordas specified during install (-p flag)
TLSSelf-signed cert — accept browser warning on first visit

Security checklist (post-install)

  • Change the default admin password
  • Enable TOTP 2FA for all admin accounts
  • Confirm DEBUG=false in /opt/madmin/backend/.env
  • Review default_rules.json firewall rules
  • Replace the self-signed TLS cert in the Nginx config if needed
  • Set up a remote backup destination in Settings → Backup

Useful commands

systemctl status madmin       # check service status
systemctl restart madmin      # restart after config changes
journalctl -u madmin -f       # follow live logs

1. Access

The portal is reachable via browser at the server address on port 7443 (HTTPS). The certificate is self-signed: the browser will show a security warning that can be dismissed by accepting the risk.

Login

Enter your username and password on the login screen and click Sign in. Credentials are set during installation.

Two-factor authentication (2FA)

If the account has 2FA enabled (or it is enforced globally), a second field appears after credentials where you enter the 6-digit code generated by your authenticator app (Google Authenticator, Authy, or similar).

2. Dashboard

The dashboard is the main screen and shows a real-time overview of system status.

WidgetDescription
CPUProcessor usage percentage
RAMMemory usage with total and free values
DiskUsed and available storage
UptimeHow long the system has been running
Network trafficBytes sent and received per interface
Module widgetsEach active module can publish its own widgets (e.g. connected VPN clients, active DHCP leases)

The traffic chart updates automatically. Historical data is retained for the last 24 hours.

3. User Management

Accessible from the sidebar. Split into two parts: your own profile and management of other users (admin-only).

My Profile

Every user can update their own security settings regardless of permissions.

Change password

  1. Enter current password, new password, and confirm.
  2. Click Save Password.

Configure 2FA

  1. Click Configure 2FA to open the wizard.
  2. Scan the QR code with your authenticator app or enter the secret manually.
  3. Enter the 6-digit code from the app to verify.
  4. Save the provided backup codes in a safe place — they allow access if you lose your device.
  5. To disable 2FA, click Remove 2FA and confirm.

User Management (admins only)

The table shows all users with status, creation date, and assigned permissions.

Create a new user

  1. Click New User.
  2. Fill in: Username (3–50 chars, letters/numbers/hyphens/underscores), Email (optional), Password, Active, Superuser, Force 2FA.
  3. Select the permissions to assign.
  4. Click Save.

Core permissions

PermissionAccess granted
users.viewView user list
users.manageCreate, edit, delete users
firewall.viewView firewall rules
firewall.manageAdd / edit / delete rules
network.viewView network interfaces
network.manageConfigure network interfaces
services.viewView service status
services.manageStart / stop / restart services
settings.view / manageView or modify system settings
backup.view / manageDownload, create, restore or schedule backups
cron.view / manageView or manage scheduled tasks
audit.viewView audit logs
modules.view / manageView or enable / disable modules

Each module adds its own permissions (e.g. wireguard.view, dhcp.manage).

Edit a user: pencil icon in the row. Disable: toggle in the row. Delete: trash icon → confirm. Reset 2FA: dedicated button in the edit panel.

4. Firewall

The firewall manages the machine's iptables rules, organised by table and chain.

Tables and Chains

TableAvailable chainsTypical use
FilterINPUT, OUTPUT, FORWARDBlock or allow traffic
NATPREROUTING, POSTROUTINGDNAT (port forwarding), SNAT, Masquerade
MangleINPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTINGAdvanced packet modification
RawPREROUTING, OUTPUTExclude traffic from connection tracking

Adding a Rule

  1. Select table and chain.
  2. Click Add Rule.
  3. Fill in the relevant fields (irrelevant ones can be left empty).

Common fields

FieldDescriptionExample
Protocoltcp, udp, icmp, alltcp
SourceIP or network (CIDR)192.168.1.0/24
DestinationIP or network (CIDR)10.0.0.1
PortSingle or range80 or 8000:9000
CommentInternal noteAllow HTTP from LAN

Additional fields — Filter

FieldDescription
StateNEW, ESTABLISHED, RELATED, INVALID
In / Out InterfaceIngress or egress interface (e.g. eth1)
ActionACCEPT, DROP, REJECT, LOG

Additional fields — NAT

FieldDescriptionUse
To DestinationIP:Port of destination (DNAT)Inbound port forwarding
To SourceSource IP to use (SNAT)Force egress with specific IP
To PortsDestination port to remapChange port during NAT
ActionDNAT, SNAT, MASQUERADE, REDIRECT

Rule ordering

Rules are evaluated top to bottom: the first match determines the outcome. Drag rows to reorder — order is saved automatically.

iptables preview

The Preview panel shows the exact iptables command that will be executed for the selected rule.

Import / Export

Chain rules can be exported to JSON and re-imported on another system using the dedicated buttons.

5. Network Interfaces

Shows all physical interfaces with real-time statistics: status, speed, configuration type (DHCP or Static), primary / secondary IPs, IPv6, MAC, MTU, traffic counters and error counts.

WAN interface (eth0)

The WAN interface is read-only — it cannot be configured from the portal.

Configure an interface (non-WAN)

  1. Click the gear icon on the interface card.
  2. Choose DHCP (automatic) or Static (enter IP CIDR, gateway, DNS).
  3. Optionally set a custom MTU.
  4. Click Save, then Apply Netplan.
Changes are saved to /etc/netplan/ but not activated until you click "Apply Netplan". This operation may briefly interrupt connectivity.

6. Modules

Modules are optional components that extend MADMIN. They must first be activated from the Modules section, after which they appear in the sidebar menu.

Activate / Deactivate a Module

  1. Go to Modules in the sidebar.
  2. Click Activate — the system installs dependencies and initialises the database.
  3. Click Deactivate to disable it and remove its data.
Deactivation is irreversible for data: all module configuration is deleted.

6.1 WireGuard VPN

Modern, high-performance VPN based on public-key cryptography.

Core concepts

  • Instance: a WireGuard server (interface wg0, wg1, …)
  • Client: a device that connects to the server
  • Full Tunnel: all traffic routes through the VPN
  • Split Tunnel: only traffic to specific networks routes through the VPN

Create an Instance

  1. Click New Instance.
  2. Fill in: Name, UDP Port (default 51820), Subnet (e.g. 10.10.0.0/24), Tunnel mode (Full / Split).
  3. Click Create.

Manage Clients

ActionDescription
Add ClientGenerates key pair and assigns IP in the VPN subnet
QR CodeScan with the WireGuard mobile app
Download Config.conf file to import in the desktop client
Send configSends a download link by email
Enable / DisableDisabled clients cannot connect
DeleteRemoves the client and its configuration

Firewall (Firewall tab in the instance)

Based on groups: clients are assigned to groups, and specific rules are applied per group.

  • Default policy: ACCEPT (all allowed, rules used to block exceptions) or DROP (all blocked, rules used to open exceptions).
  • Groups: listed in the left panel, draggable to change priority.
  • Group rules: Action (ACCEPT/DROP), Protocol, Destination CIDR, Port, Description. Evaluated top to bottom.

6.2 OpenVPN

Traditional certificate-based VPN compatible with a wide range of devices.

  • Supports both UDP and TCP (useful when UDP is blocked)
  • Uses an internal PKI (certificate authority)
  • Slightly slower but more compatible with restrictive environments

Create an Instance

  1. Click New Instance.
  2. Fill in: Name, Port (default 1194), Protocol (UDP/TCP), Subnet, Public endpoint, Tunnel mode, advanced options (cipher, cert lifetime).

Client management and the firewall are structurally identical to WireGuard: same group logic, same per-instance default policy. Revoked clients cannot be added to groups.

6.3 DHCP Server

Manages automatic IP address assignment to devices on the local network.

Create a Subnet

  1. Click New Subnet.
  2. Fill in: Name, Interface, Network CIDR (e.g. 192.168.1.0/24), IP Range (start → end), Gateway, DNS, Domain (optional), Lease time (default 86400s = 24h).

Static Reservations (fixed IPs per MAC)

  1. Open the Reservations tab inside the subnet.
  2. Click Add Reservation, enter MAC address and IP to always assign.

Active Leases

The Leases tab shows connected devices with IP, MAC, hostname and expiry.

Apply Configuration

After any change click Apply Configuration — the DHCP service is restarted with the new settings.

6.4 DNS Server

Internal DNS server powered by BIND9, useful for resolving internal names or acting as a resolver for the local network.

ModeDescription
RecursiveResolves any domain by querying root servers
Forwarder onlyForwards queries to configured upstream DNS (e.g. 8.8.8.8)
Non-recursiveOnly answers configured local zones

Create a Zone

  1. Zones → New Zone.
  2. Choose: Master (authoritative zone, for internal domains) or Forward (delegate queries to specific DNS).
  3. Enter zone name (e.g. company.local) and description.

DNS Record Types

TypeUse
AName → IPv4
AAAAName → IPv6
CNAMEAlias (e.g. www → server.company.local)
MXMail server for the domain
TXTText record (SPF, DKIM, …)
PTRReverse lookup (IP → Name)
NSAuthoritative name server
SRVService location

DNS Test

The Test tab lets you query the local DNS server by entering a name and selecting the record type.

6.5 IPsec VPN (StrongSwan)

VPN designed for stable site-to-site connections between two sites/routers. High interoperability standard (compatible with Cisco, Fortinet, MikroTik, etc.).

Create a Tunnel

  1. Click New Tunnel.
  2. Fill in: Name, Local network (e.g. 192.168.1.0/24), Remote network, Remote gateway, IKE version (IKEv2 recommended), Authentication (PSK or Certificate), Cipher suite.

Status and Management

The tunnel can be started/stopped manually. The SA section shows active security associations and traffic statistics.

Firewall (Firewall section in tunnel detail)

IPsec firewall operates per Child SA (phase 2, local/remote subnet pair). Each Child SA has two independent sections:

  • Outbound rules (local → remote)
  • Inbound rules (remote → local)

Each has its own default policy (ACCEPT or DROP) independent of the other.

FieldOptionsNotes
DirectionOutbound / Inbound / BothWhich direction to apply the rule
ActionACCEPT / DROPAllow or block
ProtocolAll / TCP / UDP / ICMP
Porte.g. 80 or 8000-8100TCP/UDP only; range with hyphen
Source / DestinationCIDREmpty = use the tunnel subnet
DescriptionFree textInternal note

6.6 Reverse Proxy

Manages nginx as a reverse proxy to expose internal services with automatic SSL/TLS (Let's Encrypt), HTTP authentication, and IP-based access control.

Prerequisite: the module occupies ports 80 and 443. If another service or DNAT rule already uses them, activation is blocked with a warning describing the conflict.
TermDescription
Proxy HostProxy rule: one or more source domains → one backend
BackendInternal service the traffic is forwarded to (IP:port)
Access ListReusable policy combining authentication and/or IP rules
CertificateLet's Encrypt TLS certificate associated with a Proxy Host

Proxy Hosts — Create a Host

  1. Click New Host.
  2. Details tab: source domains, scheme (http/https towards backend), backend host/IP, backend port, access list, options (HTTP/2, Block exploits, WebSocket, Cache).
  3. SSL tab: click Request Let's Encrypt certificate to get TLS automatically. After issuance you can enable Force HTTPS.
  4. Advanced tab: custom nginx snippet appended at the end of the location / block.
  5. Click Save.

Host actions

ActionDescription
EditOpens the edit form
Enable / DisableActivates or removes the vhost from nginx without deleting it
Request / Renew certIssues or renews the Let's Encrypt certificate
Revoke certRevokes the certificate and removes it from the host
DeleteRemoves the host and nginx vhost (cert is revoked if present)

Access Lists

Reusable policies combining HTTP Basic authentication and IP allow/deny rules. Assignable to multiple Proxy Hosts.

  1. Click New List.
  2. Details tab: Name, Satisfy Any (authentication or IP rule is sufficient — nginx satisfy any), Pass auth to backend.
  3. Authorisations tab: username/password pairs for HTTP Basic Auth.
  4. Rules tab: IP rules (allow/deny + CIDR + order). If IP rules exist, nginx automatically appends deny all.

SSL/TLS Certificates

The Certificates tab lists all issued certs with domains, provider, issue/expiry dates and status (Valid / Expiring / Expired). Available actions: Renew and Revoke.

Automatic renewal is handled by certbot via a hook in /etc/letsencrypt/renewal-hooks/deploy/. Manual renewal is not necessary as long as the domain is reachable from the internet on port 80.

How it works internally

  • nginx is configured with files in /etc/nginx/madmin-revproxy/.
  • Each Proxy Host generates madmin-proxy-{id}.conf in sites-available/ with a symlink in sites-enabled/.
  • A catch-all vhost (madmin-acme.conf) serves ACME HTTP-01 challenges on port 80.
  • After each change nginx is reloaded automatically (systemctl reload nginx).

7. Crontab (Scheduled Tasks)

Schedule automatic execution of commands at regular intervals.

Add a Task

  1. Click New Task.
  2. Define the schedule via Preset (predefined list) or Manual (5 cron fields: Minute Hour Day Month Weekday).
  3. Enter the Command to run (absolute path recommended).
  4. Enable or disable the task with the toggle.
  5. Click Save.

Cron expression examples

0 2 * * *      → every day at 02:00
*/15 * * * *   → every 15 minutes
0 0 1 * *      → first day of every month at midnight

8. Logs & Audit

Audit Log

Records every operation performed through the portal (who did what and when).

ColumnDescription
TimestampDate and time of the operation
UserAccount that performed the action
OperationHTTP method + API path
Response codeGreen = success, red = error
DurationIn milliseconds
Client IPSource address

Available filters: Category (Writes / All / Reads), User, keyword search, Date range. Click a row to view the request payload. Export CSV downloads filtered logs as a spreadsheet.

System Log

Shows MADMIN service logs in real time (equivalent to journalctl). Options: line count, text filter, Hide AUDIT.

  • Red: critical errors
  • Orange: warnings
  • Cyan: audit log entries
  • Dark grey: HTTP access log entries

9. Settings

Customisation

  • Company name: text in the menu and header (default: MADMIN)
  • Primary colour: colour picker, propagated via CSS variable
  • Theme: light or dark

Backup

  • Export backup: archive with system configuration
  • Import backup: restore from a previous backup file
  • Scheduled backups: daily, weekly, or monthly to a local or remote destination (S3, FTP)

Security

  • Enforce 2FA globally: all users must configure 2FA
  • Token lifetime: session validity in minutes (default 720 = 12h)

Audit

  • Log retention: days to keep audit logs (older entries are automatically pruned)

10. Common Configurations

Practical examples using the portal firewall.

10.1 DNAT — Port Forwarding (inbound traffic)

Scenario: connections to the public IP on port 8080 → internal server 192.168.1.10 port 80.

Where: Table NAT → Chain PREROUTING

FieldValue
Protocoltcp
Port8080
ActionDNAT
To Destination192.168.1.10:80
To make DNAT work, you also usually need a Filter → FORWARD rule allowing traffic to 192.168.1.10:80.

10.2 SNAT — Change the outbound source IP

Scenario A — specific IP for an internal machine: traffic from 192.168.1.50 exits with secondary IP 1.2.3.4.

Where: Table NAT → Chain POSTROUTING

FieldValue
Source192.168.1.50
Out Interfaceeth0
ActionSNAT
To Source1.2.3.4

Scenario B — specific IP for a VPN: traffic from interface wg0 exits with secondary IP 1.2.3.4.

FieldValue
In Interfacewg0
Out Interfaceeth0
ActionSNAT
To Source1.2.3.4

10.3 Masquerade — Dynamic NAT for LAN

Scenario: devices on 192.168.1.0/24 exit to the internet using the server's public IP (dynamic IP).

Where: Table NAT → Chain POSTROUTING

FieldValue
Source192.168.1.0/24
Out Interfaceeth0
ActionMASQUERADE
MASQUERADE uses the current IP of the egress interface (useful with dynamic IP). SNAT requires an explicit IP and is slightly more performant with a static IP.

10.4 Block an IP or Network

Where: Table Filter → Chain INPUT

FieldValue
Source1.2.3.4
ActionDROP
Place this rule before any more general permissive rules, otherwise it won't be reached.

10.5 Allow only specific inbound ports

Scenario: allow only SSH (22) and HTTPS (443), drop everything else.

Where: Table Filter → Chain INPUT

RuleState / Protocol / PortAction
1State: ESTABLISHED,RELATEDACCEPT
2TCP port 22ACCEPT
3TCP port 443ACCEPT
4(no filter)DROP
Order is critical: the DROP rule must be last.