Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
Added missing examples of configuration with description
  • Loading branch information
vkatsuba committed Nov 1, 2020
1 parent 61f3cc2 commit 27aa695
Showing 1 changed file with 207 additions and 6 deletions.
213 changes: 207 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,42 @@ Jungerl code. It contains a generic [RADIUS](https://en.wikipedia.org/wiki/RADIU
several authentication mechanisms and dynamic configuration
(it implements the `config_change/3` application callback).

## Erlang Version Support
# Contents

* [Erlang Version Support](#erlang-version-support)
* [Building eradius](#building-eradius)
* [Using eradius](#using-eradius)
* [Run sample server](#run-sample-server)
* [Metrics](#metrics)
* [RADIUS server configuration](#radius-server-configuration)
* [eradius configuration example 1](#eradius-configuration-example-1)
* [eradius configuration example 2](#eradius-configuration-example-2)
* [eradius configuration example 3](#eradius-configuration-example-3)
* [Support of failover for client](#support-of-failover-for-client)
* [Failover configuration](#failover-configuration)
* [Failover Erlang code usage](#failover-erlang-code-usage)
* [Eradius counter aggregator](#eradius-counter-aggregator)

# Erlang Version Support

All minor version of the current major release and the highest minor version of the
previous major release will be supported.
At the moment this means OTP 21.3, OTP 22.x and OTP 23.x are supported. OTP versions before 21.0
do not work due the use of logger. When in doubt check the `otp_release` section in
[.travis.yml](.travis.yml) for tested versions.

## Building eradius
# Building eradius

```sh
$ rebar3 compile
```

## Using eradius
# Using eradius

Eradius requires a certain degree of configuration which is described in the
app.src file. Minimal examples of server callbacks can be found in the tests.

## Run sample server
# Run sample server

```sh
$ cd sample
Expand All @@ -48,10 +64,9 @@ Then run a simple benchmark:
ok
```

## Metrics
# Metrics

Eradius exposes following metrics via exometer:

* counter and handle time for requests
* counter for responses (this includes acks, naks, accepts etc.)

Expand All @@ -67,6 +82,192 @@ all have a time span of 60s. The precise metrics are defined in [include/eradius

See more in [METRICS.md](METRICS.md).

# RADIUS server configuration

> :warning: **Notes** :warning:
> * Square brackets ([]) denote an array that consists of n comma-separated objects.
> * Curly brackets ({}) denote a tuple that consists of a defined number of objects.
Servers in this configuration are endpoints consisting of an IPv4 address and one or more ports.
`servers` is a list `[]` of said endpoints:
```
servers == { servers, [<Server>] }
```
Each server is tuple ({}):
```
Server == { <SymbolicName>, { <IP>, [<Ports>] } } | { <SymbolicName>, { <IP>, [<Ports>] }, <ExtraServerOptions> }
ExtraServerOptions == [<ServerOption>]
ServerOption == {rate_config, <SymbolicNameLimit> | <RateConfigList>}
```

Rate configuration can be configurated per server, in extra configuration, with a symbolic name or directly in server
```
{SymbolicNameLimit, RateConfigList}
RateConfigList == [<RateOption>]
RateOption == { limit | max_size | max_time, integer() | undefined }
```

Each server is assigned a list of handlers. This list defines the NASes that are allowed to send RADIUS requests to a server and
which handler is to process the request.

Handler assignment: `{<SymbolicName>, [<Handlers>]}`
```
SymbolicName == Reference to a previously defined server.
Handler == { <HandlerDefinition>, [<Sources>] }
```
If only one handler module is used, it can be defined globally as `{radius_callback, <HandlerMod>}`.
If more than one handler modules are used, they have to be given in the HandlerDefinition:
```
HandlerDefinition == {<HandlerMod>, <NasId>, <HandlerArgs>} | {<NasId>, <HandlerArgs>}
HandlerMod == Handler module to process the received requests.
NasId == String describing the Source.
HandlerArgs == List of arguments givent the handler module.
Source == {<IP>, <Secret>} | {<IP>, <Secret>, [<SourceOption>]}
SourceOption == {group, <GroupName>} | {nas_id, <NasId> }
IP == IPv4 source address.
Secret == Binary. Passphrase, the NAS authenticates with.
GroupName:
RADIUS requests received by a server are forwarded to lists of nodes.
The lists are assigned to handlers, so the RADIUS requests of every handler can be forwarded to different nodes, if necessary.
The lists are referenced by a GroupName. If only one group is defined, the GroupName can be omitted.
In this case, all handlers forward their requests to the same list of nodes.
Session nodes == {session_nodes, ['node@host', ...]} | {session_nodes, [{<GroupName>, ['node@host', ...]}]}
```

## eradius configuration example 1

All requests are forwarded to the same globally defined list of nodes.
Only one handler module is used.
```erlang
[{eradius, [
{session_nodes, ['node1@host1', 'node2@host2']},
{radius_callback, tposs_pcrf_radius},
{servers, [
{root, {"127.0.0.1", [1812, 1813]}}
]},
{root, [
{
{"NAS1", [handler_arg1, handler_arg2]},
[ {"10.18.14.2", <<"secret1">>} ]
},
{
{"NAS2", [handler_arg1, handler_arg2]},
[ {"10.18.14.3", <<"secret2">>, [{nas_id, <<"name">>}]} ]
}
]}
]}]
```

## eradius configuration example 2

Requests of different sources are forwarded to different nodes.
Different handlers are used for the sources.
```erlang
[{eradius, [
{session_nodes, [
{"NodeGroup1", ['node1@host1', 'node2@host2']},
{"NodeGroup2", ['node3@host3', 'node4@host4']}
]},
{servers, [
{root, {"127.0.0.1", [1812, 1813]}}
]},
{root, [
{
{tposs_pcrf_handler1, "NAS1", [handler_arg1, handler_arg2]},
[ {"10.18.14.2", <<"secret1">>, [{group, "NodeGroup1"}]} ]
},
{
{tposs_pcrf_handler2, "NAS2", [handler_arg3, handler_arg4]},
[ {"10.18.14.3", <<"secret2">>, [{group, "NodeGroup2"}]} ]
}
]}
]}]
```
## eradius configuration example 3

Example of full configuration with keys which can use in `eradius`:
```erlang
[{eradius, [
{client_ip, {127, 0, 0, 1}},
{client_ports, 256},
{resend_timeout, 500},
{tables, [dictionary]},
{session_nodes, local},
{radius_callback, eradius_server_sample},
{root, [
{{"root", []}, [{"127.0.0.1", "secret"}]}
]},
{servers, [
{root, {"127.0.0.1", [1812, 1813]}}
]},
{counter_aggregator, false},
{histogram_buckets, [10, 30, 50, 75, 100, 1000, 2000]},
{logging, true},
{logfile, "./radius.log"},
{default_route, {{127, 0, 0, 1}, 1812, <<"secret">>}, pool_name},
{servers_pool, [
{pool_name, [
{{127, 0, 0, 2}, 1812, <<"secret">>, [{retries, 3}]},
{{127, 0, 0, 3}, 1812, <<"secret">>}
]}
]},
{recbuf, 8192} % Size of RADIUS receive buffer
]}].
```

# Support of failover for client

Added support for fail-over.
Set of secondary RADIUS servers could be passed to the RADIUS client API `eradius_client:send_request/3` via options or to RADIUS proxy via configuration.

If the response wasn't received after a number of requests specified by `retries` RADIUS client options - such RADIUS servers will be marked as non-active and RADIUS requests will not be sent for such non-active RADIUS servers, while configurable timeout (`eradius.unreachable_timeout`) is not expired.

Secondary RADIUS servers could be specified via RADIUS proxy configuration, with the new configuration option - pool name.

## Failover configuration

Configuration example of failover where the `pool_name` is `atom` specifies name of a pool of secondary RADIUS servers.
```erlang
[{eradius, [
%%% ...
{default_route, {{127, 0, 0, 1}, 1812, <<"secret">>}, pool_name}
%%% ...
]}]
```
All pools are configured via:
```erlang
[{eradius, [
%%% ...
{servers_pool, [
{pool_name, [
{{127, 0, 0, 2}, 1812, <<"secret">>, [{retries, 3}]},
{{127, 0, 0, 3}, 1812, <<"secret">>}
]}
]}
%%% ...
]}]
```
## Failover Erlang code usage
In a case when RADIUS proxy (eradius_proxy handler) is not used, a list of RADIUS upstream servers could be passed to the `eradius_client:send_radius_request/3` via options, for example:
```erlang
eradius_client:send_request(Server, Request, [{failover, [{"localhost", 1814, <<"secret">>}]}]).
```
If `failover` option was not passed to the client through the options or RADIUS proxy configuration there should not be any performance impact as RADIUS client will try to a RADIUS request to only one RADIUS server that is defined in `eradius_client:send_request/3` options.

# Eradius counter aggregator
The `eradius_counter_aggregator` would go over all nodes in an Erlang cluster and aggregate the counter values from all nodes.
Configuration value of `counter_aggregator` can be `true` or `false` where `true` - is enable, `false` - is disable counter aggregator.
By default the `counter_aggregator` is disabled and have default value `false`.
Configuration example:
```erlang
[{eradius, [
%%% ...
{counter_aggregator, true}
%%% ...
]}]
```

<!-- Badges -->
[travis]: https://travis-ci.com/travelping/eradius
[travis badge]: https://img.shields.io/travis/com/travelping/eradius/master.svg?style=flat-square
Expand Down

0 comments on commit 27aa695

Please sign in to comment.