Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.git
.github
.idea
.vscode
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,7 @@ go.work.sum
.env

# Editor/IDE
# .idea/
# .vscode/
.idea/
tests/
.vscode/
build/
12 changes: 12 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,24 @@ radtest testuser password 127.0.0.1 0 test
- **TLS verification**: Set `insecure_skip_tls_verify: true` for self-signed Keycloak certs.
- **Asynchronous/multi-request support**: Multiple RADIUS requests are handled concurrently for high performance.

## Docker and Compose (UDP)

- Set **`listen_addr: "0.0.0.0:1812"`** in `keyrad.yaml`. Binding to **`127.0.0.1`** only listens inside the container, so traffic published with **`ports: - "1812:1812/udp"`** never reaches the process.
- Publish UDP explicitly, e.g. **`ports: ["1812:1812/udp"]`**.
- **`clients.conf` matches the UDP source address keyrad sees.** With bridge networking that is often the **Docker gateway** (e.g. `172.17.0.1`) or another **RFC1918** address, **not** your NAS IP and **not** `127.0.0.1`. If nothing matches, keyrad logs at **Info**: `RADIUS: datagram received but no clients.conf match` with `remote_ip` — use that value to add a `client { }` block or a CIDR (see example `clients.conf` with `172.16.0.0/12` for lab; tighten in production).
- On **Linux**, **`network_mode: host`** makes the original NAS source visible and avoids Docker UDP port mapping quirks; then do not rely on `ports:` for 1812. On **Docker Desktop (Mac/Windows)** host mode behaves differently; test from another container on the same user-defined network, or from the LAN to the host’s IP with a matching `clients.conf` entry for the observed `remote_ip`.
- See **`docker-compose.example.yml`** for a minimal compose file.

## Troubleshooting
- **403 errors**: Ensure your Keycloak client has the correct service account roles.
- **Invalid Message-Authenticator**: Check shared secrets in `clients.conf` and your RADIUS client.
- **OTP not working**: Ensure user has the credential enrolled in Keycloak.
- **Legacy OTP**: If your client cannot handle RADIUS challenge-response, use `--disable-challenge-response`.

## Known issues
- The password is more than 16 characters.
Some devices use RADIUS 1.0 (RFC 2138), which limits passwords to 16 characters. For example: Checkpoint version < R81.10.00 - https://support.checkpoint.com/results/sk/sk13740

## Support
If you need professional support, please write to

Expand Down
124 changes: 0 additions & 124 deletions auth/otp.go

This file was deleted.

16 changes: 16 additions & 0 deletions docker-compose.example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Example only — copy/adjust paths and image.
services:
keyrad:
image: keyrad:latest
container_name: keyrad_svc
volumes:
- ./keyrad.yaml:/app/keyrad.yaml:ro
- ./clients.conf:/app/clients.conf:ro
restart: always
#ports:
# - "1812:1812/udp"
# Optional: more verbose logs (RADIUS + Keycloak details).
command: ["/app/keyrad", "-debug", "-c", "/app/keyrad.yaml", "-r", "/app/clients.conf"]
# Linux: to see real NAS source IPs (and avoid NAT changing the client IP), you can instead use:
network_mode: "host"
# and remove `ports:` (keyrad binds 0.0.0.0:1812 on the host network stack).
19 changes: 19 additions & 0 deletions dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM alpine:3.21

RUN apk add --no-cache ca-certificates \
&& addgroup -g 65532 -S keyrad \
&& adduser -u 65532 -S -D -G keyrad -H -s /sbin/nologin keyrad \
&& mkdir -p /app \
&& chown keyrad:keyrad /app

WORKDIR /app

COPY build/amd64/keyrad /app/keyrad
RUN chown root:root /app/keyrad \
&& chmod 0555 /app/keyrad

USER 65532:65532

EXPOSE 1812/udp

CMD ["/app/keyrad"]
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ go 1.25.5
require layeh.com/radius v0.0.0-20231213012653-1006025d24f8

require gopkg.in/yaml.v3 v3.0.1

require (
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.27.1 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
Expand Down
Loading
Loading