For the complete documentation index, see llms.txt. This page is also available as Markdown.

Operations Guide

中文版本:运维指南

Everything you need to run ToughRADIUS in production: configuration reference, environment variables, TLS/EAP certificates, storage, monitoring, backup, and the bundled command-line tools.

Process model

One static binary runs several services concurrently (web/admin API, RADIUS auth, RADIUS accounting, RadSec). If any service fails, the whole process exits so a supervisor can restart it — run it under systemd, Docker, or an equivalent.

# /etc/systemd/system/toughradius.service (reference)
[Unit]
Description=ToughRADIUS server
After=network-online.target

[Service]
ExecStart=/usr/local/bin/toughradius -c /etc/toughradius.yml
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Ports

Port
Protocol
Service
Config key

1816

TCP HTTP

Admin UI + REST API

web.port

1817

TCP HTTPS

Admin UI over TLS (optional; start failure is non-fatal)

web.tls_enabled / web.tls_port

1812

UDP

RADIUS authentication

radiusd.auth_port

1813

UDP

RADIUS accounting

radiusd.acct_port

2083

TCP TLS

RadSec (RFC 6614)

radiusd.radsec_port

3799

UDP (outbound)

CoA/Disconnect to the NAS

per-NAS CoA port field

Configuration

Lookup order: -c <file>./toughradius.yml/etc/toughradius.yml → embedded defaults. Inspect the merged result with toughradius -printcfg.

Working directory layout

On startup ToughRADIUS creates under system.workdir:

Environment variables

Environment variables override the YAML file:

Variable
Overrides

TOUGHRADIUS_SYSTEM_WORKER_DIR

system.workdir

TOUGHRADIUS_SYSTEM_DEBUG

system.debug

TOUGHRADIUS_WEB_HOST / _WEB_PORT / _WEB_TLS_ENABLED / _WEB_TLS_PORT / _WEB_SECRET

web.*

TOUGHRADIUS_DB_TYPE / _DB_HOST / _DB_PORT / _DB_NAME / _DB_USER / _DB_PWD / _DB_DEBUG

database.*

TOUGHRADIUS_RADIUS_ENABLED / _RADIUS_HOST / _RADIUS_AUTHPORT / _RADIUS_ACCTPORT / _RADIUS_DEBUG

radiusd.*

TOUGHRADIUS_RADIUS_RADSEC_PORT / _RADIUS_RADSEC_WORKER / _RADIUS_RADSEC_CA_CERT / _RADIUS_RADSEC_CERT / _RADIUS_RADSEC_KEY

RadSec settings

TOUGHRADIUS_LOGGER_MODE / _LOGGER_FILE_ENABLE

logger.*

TOUGHRADIUS_RADIUS_POOL

RADIUS worker pool size (default 1024)

CLI flags

Flag
Effect

-c <file>

Configuration file path

-initdb

Drop and recreate all tables, then exit

-printcfg

Print merged configuration as JSON, exit

-v

Print version / build time / commit, exit

-h

Usage

Runtime RADIUS settings (EAP method, certificates, intervals, reject-delay…) live in the database and are edited in System Config — no restart needed. See the Admin UI Manual.

Database

  • SQLite (default) — pure-Go driver, zero CGO, file at {workdir}/data/<name>. Fine for small/medium deployments; back up the file.

  • PostgreSQL — set database.type: postgres plus host/user/password. Recommended for production scale and concurrent accounting load.

Schema migration (GORM AutoMigrate) runs automatically at every startup, so upgrades are: stop, replace the binary, start. -initdb is for first installation only — it destroys all data.

Upgrade note — EAP certificate file paths removed. The legacy file-path settings EapTlsCertFile / EapTlsKeyFile / EapTlsCaFile have been removed: the managed certificate store (sys_cert) is now the only source of EAP-TLS/PEAP/TTLS certificate material. If your deployment configured certificate-based EAP via disk file paths, after upgrading you must import the PEM files on the Certificates page (the server certificate must include its private key) and select them by name in System Config → EapTlsServerCert / EapTlsClientCa. Until a managed server certificate is selected, certificate-based EAP methods safely reject all requests (ErrTLSNotConfigured) — plan the re-import before upgrading to avoid an EAP outage. PAP/CHAP/MSCHAPv2 (non-EAP) deployments are unaffected.

Large tables to watch: radius_accounting (grows with every session) and radius_online. The radius.AccountingHistoryDays setting (default 90, set to 0 to disable) defines the accounting retention window: a @daily job deletes terminated radius_accounting rows older than that many days (active sessions are untouched) and clears dangling radius_online rows that have missed several interim updates. The operator action log (sys_opr_log) is purged automatically after one year. For very high volumes, still consider database-level archiving as part of your own ops.

TLS and certificates

Three independent certificate consumers:

Consumer
Files
Notes

RadSec

radiusd.radsec_ca_cert / radsec_cert / radsec_key

TLS 1.2+; client certificates are verified if presented (VerifyClientCertIfGiven)

Web HTTPS

{workdir}/private/toughradius.tls.crt + .key (fixed paths)

Listens on web.tls_port when web.tls_enabled is true; failure to load is logged, HTTP keeps running

EAP (TLS/PEAP/TTLS)

System Config → EapTlsServerCert, EapTlsClientCa, EapTlsMinVersion (import certificates on the Certificates page and select them by name)

No server certificate selected disables certificate-based EAP methods

Generate a complete CA/server/client set with the bundled tool:

Logging

zap structured logging. logger.mode: development = human-readable console; production = JSON. File output controlled by logger.file_enable + logger.filename. RADIUS verbosity is additionally tunable at runtime via System Config → LogLevel; radiusd.debug: true dumps full packets (keep off in production).

Metrics

Counters are kept in memory and surfaced through the admin dashboard (there is no Prometheus /metrics HTTP endpoint). RADIUS counters include: radus_accept, radus_online/radus_offline, radus_accounting, radus_auth_drop / radus_acct_drop, radus_radsec_saturated, and per-cause reject counters — radus_reject_passwd_error, radus_reject_not_exists, radus_reject_expire, radus_reject_disabled, radus_reject_limit, radus_reject_bind_error, radus_reject_ldap_error, radus_reject_unauthorized, radus_reject_other. radus_reject_ldap_error means the LDAP/AD backend could not give an authentication answer — for example the directory is unreachable, TLS/StartTLS failed, the service account bind failed, or the LDAP configuration is wrong; wrong passwords are still counted under radus_reject_passwd_error. Accounting-Requests dropped at ingress are classified by reason — radus_acct_drop_nas (unknown or unauthorized NAS), radus_acct_drop_username (missing username), and radus_acct_drop_secret (bad Request Authenticator) — while radus_acct_drop remains the catch-all for back-pressure and response-write drops. System gauges (CPU/memory, process CPU/memory) are sampled every 30 s.

For external monitoring, probe the service ports and watch the log file; treat process exit as the failure signal (the process model is fail-fast).

Backup and restore

System Config → Backup downloads a JSON snapshot (schema version 9.0) of: nodes, NAS devices, profiles, users, system settings, operators, and managed certificates (including their private keys, so certificate-based EAP keeps working after a restore). A copy is also written to {workdir}/backup/. Restore re-imports such a file.

The snapshot does not include accounting history or online sessions. For a full disaster-recovery story, also back up the database itself (copy the SQLite file or use pg_dump).

Security: the snapshot contains secrets — RADIUS user passwords, operator password hashes, and the PEM private keys of managed EAP certificates. Store and transfer backup files as you would any credential.

Command-line tools

All live under cmd/ and run with go run ./cmd/<tool>:

Tool
Purpose

radtest

Mini RADIUS client: auth, acct, flow (auth + start + stop). Flags: -server, -secret, -username, -password, -calling-station, -framed-ip, -session-id

certgen

Generate CA / server / client certificates (see above)

benchmark

Load tester: total requests -n, concurrency -c, auth/acct modes, CSV stats output

reset-password

Reset a console operator password: go run ./cmd/reset-password -c <cfg> -u admin -p <new>

demo-seed

Populate demo nodes/NAS/profiles/users/sessions for evaluation

config-tool

Validate / summarize the settings schema JSON

Production hardening checklist

Last updated