Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

PortProtocolServiceConfig key
1816TCP HTTPAdmin UI + REST APIweb.port
1817TCP HTTPSAdmin UI over TLS (optional; start failure is non-fatal)web.tls_enabled / web.tls_port
1812UDPRADIUS authenticationradiusd.auth_port
1813UDPRADIUS accountingradiusd.acct_port
2083TCP TLSRadSec (RFC 6614)radiusd.radsec_port
3799UDP (outbound)CoA/Disconnect to the NASper-NAS CoA port field

Configuration

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

system:
  appid: ToughRADIUS
  location: Asia/Shanghai        # cron/timestamp timezone
  workdir: /var/toughradius      # default in production builds
  debug: false
web:
  host: 0.0.0.0
  port: 1816
  tls_enabled: true              # Enabled by default for compatibility; set false to disable the built-in HTTPS listener
  tls_port: 1817
  secret: <random-string>        # JWT signing secret — change it
database:
  type: sqlite                   # sqlite | postgres
  host: 127.0.0.1                # postgres only
  port: 5432
  name: toughradius.db           # sqlite filename (under {workdir}/data/) or pg database
  user: postgres
  passwd: <password>
  max_conn: 100
  idle_conn: 10
  debug: false
radiusd:
  enabled: true
  host: 0.0.0.0
  auth_port: 1812
  acct_port: 1813
  radsec_port: 2083
  radsec_worker: 100
  radsec_ca_cert: private/ca.crt        # relative paths resolve against workdir
  radsec_cert: private/radsec.tls.crt
  radsec_key: private/radsec.tls.key
  debug: false                   # true = full packet dumps
logger:
  mode: production               # development | production
  file_enable: true
  filename: /var/toughradius/toughradius.log

Working directory layout

On startup ToughRADIUS creates under system.workdir:

/var/toughradius/
├── data/        # SQLite database, metrics data
├── logs/
├── private/     # TLS material (mode 0700)
├── public/
└── backup/      # server-side copies of configuration backups

Environment variables

Environment variables override the YAML file:

VariableOverrides
TOUGHRADIUS_SYSTEM_WORKER_DIRsystem.workdir
TOUGHRADIUS_SYSTEM_DEBUGsystem.debug
TOUGHRADIUS_WEB_HOST / _WEB_PORT / _WEB_TLS_ENABLED / _WEB_TLS_PORT / _WEB_SECRETweb.*
TOUGHRADIUS_DB_TYPE / _DB_HOST / _DB_PORT / _DB_NAME / _DB_USER / _DB_PWD / _DB_DEBUGdatabase.*
TOUGHRADIUS_RADIUS_ENABLED / _RADIUS_HOST / _RADIUS_AUTHPORT / _RADIUS_ACCTPORT / _RADIUS_DEBUGradiusd.*
TOUGHRADIUS_RADIUS_RADSEC_PORT / _RADIUS_RADSEC_WORKER / _RADIUS_RADSEC_CA_CERT / _RADIUS_RADSEC_CERT / _RADIUS_RADSEC_KEYRadSec settings
TOUGHRADIUS_LOGGER_MODE / _LOGGER_FILE_ENABLElogger.*
TOUGHRADIUS_RADIUS_POOLRADIUS worker pool size (default 1024)

CLI flags

FlagEffect
-c <file>Configuration file path
-initdbDrop and recreate all tables, then exit
-printcfgPrint merged configuration as JSON, exit
-vPrint version / build time / commit, exit
-hUsage

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:

ConsumerFilesNotes
RadSecradiusd.radsec_ca_cert / radsec_cert / radsec_keyTLS 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:

go run ./cmd/certgen -type all -output /var/toughradius/private \
  -server-cn radius.example.com -server-dns radius.example.com \
  -days 3650
# then point radsec_cert/radsec_key (or the EAP settings) at the files

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>:

ToolPurpose
radtestMini RADIUS client: auth, acct, flow (auth + start + stop). Flags: -server, -secret, -username, -password, -calling-station, -framed-ip, -session-id
certgenGenerate CA / server / client certificates (see above)
benchmarkLoad tester: total requests -n, concurrency -c, auth/acct modes, CSV stats output
reset-passwordReset a console operator password: go run ./cmd/reset-password -c <cfg> -u admin -p <new>
demo-seedPopulate demo nodes/NAS/profiles/users/sessions for evaluation
config-toolValidate / summarize the settings schema JSON

Production hardening checklist

  • Change web.secret and the default admin password.
  • radiusd.debug: false, logger.mode: production.
  • Restrict UDP 1812/1813 and TCP 1816 to trusted networks (firewall).
  • Use RadSec (2083) or a trusted L2/VPN path for RADIUS across untrusted networks.
  • Unique, strong shared secret per NAS.
  • EAP: prefer eap-tls/eap-peap/eap-ttls with real certificates; mind the MS-CHAPv2 caveats in the Security Policy.
  • Database backups scheduled (config snapshot + DB dump).
  • Supervisor with restart policy; alert on process exit.