FreeRADIUS Proxy and Realm Routing Configuration - 夜莺博客

FreeRADIUS Proxy and Realm Routing Configuration

RADIUS proxying is what lets one authentication service front several back ends: a local user database for staff, an outsourced provider for guest access, a partner realm for a business-to-business link. The proxy server decides, based on the realm in the User-Name (everything after the @), which home server or pool should handle the request. FreeRADIUS has changed how this is expressed between version 3 and version 4, so configuration copied from an older deployment frequently needs translation. This article covers the concepts, the version 3 model, and the version 4 replacement.

The Three Building Blocks

  1. Home server — a remote RADIUS server the proxy will forward to, defined by address, port and shared secret.
  2. Home server pool — a group of home servers used for redundancy or load sharing.
  3. Realm — a label that maps an incoming realm to a home server or pool.

The realm is extracted from the User-Name by the rlm_realm module, which parses the suffix after the @. That extraction is what allows one server to make a routing decision per request with no client-side configuration.

Version 3: proxy.conf

# Home server
home_server remoteradius1 {
    type    = auth
    ipaddr  = radius1.network.example
    port    = 1812
    secret  = aS3cr3T
}

# Pool with fail-over between members
home_server_pool remote_radius_failover {
    type        = fail-over
    home_server = remoteradius1
    home_server = remoteradius2
}

# Realm definition - this label selects the pool
realm network.example {
    auth_pool = remote_radius_failover
}

Proxying happens after the authorize section of the virtual server. The rlm_realm instance strips the realm from the User-Name and sets the Proxy-to-Realm control attribute, which the proxy core then uses to pick a pool.

A useful detail for debugging: by default the realm is stripped before forwarding, which changes what the home server sees in the User-Name. If the remote server authenticates on the full user@realm string, you must configure the home server not to strip it — a mismatch here produces a clean Access-Reject that looks like a credential problem and is not.

Version 4: rlm_radius Instead of proxy.conf

In version 4 the proxy.conf file is deprecated and proxying moves out of the server core into a RADIUS client module, rlm_radius. The configuration is more verbose but more explicit. Instead of setting Proxy-to-Realm, you define a per-realm authenticate section and set Auth-Type:

# One rlm_radius instance per home server
radius remoteradius1 {
    mode = proxy
    transport = udp
    udp {
        ipaddr = radius1.network.example
        port   = 1812
        secret = aS3cr3T
    }
    type = Access-Request
    type = Accounting-Request
    status_check = none
}
authenticate proxy-network.example {
    redundant-load-balance {
        remoteradius1
        remoteradius2
    }
}

recv Access-Request {
    preprocess
    files
    update control {
        Auth-Type := "proxy-network.example"
    }
    pap
}

The mapping from version 3 to version 4 is therefore: home_server → an rlm_radius instance, home_server_pool → an authenticate section, and Proxy-to-Realm → setting Auth-Type.

Selective Proxying in a Virtual Server

The most common real requirement is proxying only some realms and handling the rest locally. In version 3 that is an unlang conditional in the authorize section:

authorize {
    if (User-Name =~ /@realm1\.com$/) {
        update control {
            Proxy-to-Realm := "realm1"
        }
    }
    else {
        files
    }
}

Requests matching the realm go to the remote server; everything else falls through to the local files module. That pattern is how a single RADIUS server serves both an internal directory and an outsourced guest realm without running two instances.

Testing and Troubleshooting

radiusd -XC                      # config check only
radiusd -X                       # debug mode, watch the whole exchange
radtest bob@realm1.com pass 127.0.0.1 0 testing123
radclient -x 127.0.0.1:1812 auth testing123 < request.txt

In debug output the line that tells you routing worked is the one naming the home server and the pool it came from. If you see the request being handled locally for a realm that should be proxied, the regex in the authorize section is not matching — check anchoring, since an unanchored pattern will match substrings you did not intend.

Also test what happens when the home server is down. A proxy with no fail-over pool and no status_check will sit on the request until the client times out, which from the user's perspective looks like a slow rejection rather than a clean failure.

Related reading on this site: FreeRADIUS EAP-TLS for Wired 802.1X with Cisco Switches deployment notes, Cisco ISE Policy Sets for Wired 802.1X: Setup Guide for the commercial equivalent, and RADIUS CoA and Disconnect-Message Configuration Guide for server-initiated session changes.

原文链接:https://www.freeradius.org/documentation/freeradius-server/4.0.0/howto/protocols/radius/proxy_config.html