NebularStack
Website

Lunar - Tools

Lunar ships two command-line tools that make it easy to test and integrate a RADIUS deployment without a full backend or a live NAS:

  • radtest is a RADIUS test client for sending real Access-Requests at a server and inspecting the reply.

  • lunar_backend_sim is a stand-in backend API that serves a fixed test virtual and answers every decision, so you can run lunar end-to-end with nothing else in place.

Both are installed under /opt/lunar/bin/ and both are built on lunar's own code, so what they accept and produce matches the server exactly.

Radtest

radtest (/opt/lunar/bin/radtest) is a minimal RADIUS test client. It builds an Access-Request with lunar's own RADIUS codec (the exact code the server runs), sends it over UDP, validates the reply's Response Authenticator, and prints both the request and the reply attribute-by-attribute. Because it uses the server's codec, a request radtest accepts is a request the server accepts.

It supports PAP (default), CHAP, MS-CHAP and MS-CHAPv2.

Usage

radtest [OPTIONS] radius-server[:port] secret

The two positional arguments are the target server (with an optional :port, default 1812) and the shared secret configured for this client on the virtual. Everything else is an option:

Option

Description

--username <name>

User-Name attribute value. Omitted = not sent.

--password <pass>

The password for the -t authentication type. Omitted = no password credential is sent and -t is ignored. This is the basis for methods that need no password, such as MAC authentication by Calling-Station-Id.

-t <type>

Authentication type: pap, chap, mschap or mschapv2 (default pap). Requires --password. Ignored when none is given.

-d <dictionary>

RADIUS dictionary.yaml file. Default: dictionary.yaml under /opt/lunar/share/lunar/radius/.

--nas-port <number>

NAS-Port attribute value. Omitted = not sent.

--nas-ip-address <ip>

NAS-IP-Address attribute value. Default: the source address.

--source-ip <ip>

Source IPv4 to send from (must be a local address). Default: chosen by the kernel route.

--framed-protocol <val>

Framed-Protocol attribute, by name (e.g. PPP, SLIP) or number. Omitted = not sent.

--calling-station-id <id>

Calling-Station-Id attribute value. Omitted = not sent.

--no-message-auth

Do not send a Message-Authenticator in the request. By default one is always added and signed. BlastRADIUS-hardened servers may drop a request without it.

--timeout <seconds>

Seconds to wait for a reply per attempt. Default: 5.

--retry <count>

Number of send attempts before giving up. Default: 3.

Run radtest with no arguments to print this option list.

radtest exits 0 on an Access-Accept and 1 on anything else (reject, timeout or error), so it drops straight into a script or a health check.

Example

$ /opt/lunar/bin/radtest --username test@example.com --password testing123 172.16.0.1 testing123

 Sent Access-Request Id 23 from 172.16.0.1:40297 to 172.16.0.1:1812 length 90
     User-Name = "test@example.com"
     User-Password = "testing123"
     NAS-IP-Address = 172.16.0.1
     Message-Authenticator = 0x00000000000000000000000000000000
 Received Access-Accept Id 23 from 172.16.0.1:1812 to 172.16.0.1:40297 length 93
     Message-Authenticator = 0x93d72b55740823997bbd197e740bc898
     Class = 0x6e733a3a3861...

radtest: Success

A successful run ends in radtest: Success after an Access-Accept. The printed attribute names use their conventional dictionary spelling for readability. This is the console view, not the JSON the API emits.

Passwordless requests

Because --username and --password are both optional, the smallest possible test is just a server and a secret:

$ /opt/lunar/bin/radtest 172.16.0.1 testing123

This sends a valid Access-Request carrying only a NAS-IP-Address and a signed Message-Authenticator, with no User-Name and no password credential. It is a quick way to confirm connectivity, the shared secret and that the server answers, and it is the shape future passwordless methods (such as MAC authentication) will build on.

lunar_backend_sim

lunar_backend_sim (/opt/lunar/bin/lunar_backend_sim) is a self-contained stand-in for your backend API. It serves one fixed test virtual and answers every decision automatically, so you can bring lunar up and watch a full request flow without writing any backend code or configuring a real NAS.

What it serves

The simulator exposes the same backend routes lunar calls, and always returns the same built-in test virtual:

  • virtual id TEST listening on 127.0.0.1, auth port 1812, acct port 1813, CoA port 3799.

  • one client 127.0.0.1 / client-test with shared secret testing123.

Its decision logic is deliberately trivial so the result is never in doubt:

  • auth always returns access-accept.

  • acct always returns accounting-response.

  • coa returns disconnect-ack for a disconnect-request, otherwise coa-ack.

Because auth is answered access-accept unconditionally, the simulator does not validate credentials. Only PAP gives a meaningful radtest result against it; CHAP, MS-CHAP, MS-CHAPv2 and EAP need a real backend that runs the challenge/response, so they will not authenticate here.

For every reply it mirrors the request attributes straight back onto the response. That makes it easy to see, with radtest or the .../test route, exactly what lunar decoded and sent. It speaks both JSON and MessagePack, choosing the reply encoding from the request's Accept / Content-Type headers.

Routes it answers

  • GET /v1/lunar/<server>/virtuals returns the test virtual as a one-element list.

  • GET /v1/lunar/<server>/virtual/<id> returns the test virtual.

  • POST /v1/lunar/<server>/<type>/<id> accepts an inbound auth / acct / coa packet and returns the reply packet.

  • POST /v1/lunar/<server>/log accepts and discards remote log lines (201).

  • GET /v1/lunar/ping is a health probe (200), what lunar's /v1/status hits to decide the backend is reachable.

Usage

lunar_backend_sim [-h listen_ip] [-p listen_port] [-s auth_sleep_ms]
                  [-w worker_threads] [-V] [--enable-client-blast-ma]

Option

Description

-h <ip>

Listen address. Default 127.0.0.1.

-p <port>

Listen port. Default 5555.

-s <ms>

Artificial auth latency in milliseconds. Only the auth path sleeps. Use it to simulate a slow backend. Default 0.

-w <count>

Worker threads. Default 512.

-V

Verbose: pretty-print (syntax-colored) every HTTP request and response. This is the mode to run while learning or debugging. You see each decoded packet lunar posts and each reply the simulator returns.

--enable-client-blast-ma

Mark the test client as requiring Message-Authenticator on inbound requests (BlastRADIUS mitigation), so lunar validates it for this client. By default the test client does not require it, which keeps simple manual tests easy.

Running it in -V verbose mode alongside lunar is the fastest way to understand the request/response flow. See the Quickstart for a full walk-through.