Replicate FreeRADIUS responses to a another host
Hi! I need to replicate Access-Accept, Access-Reject and Accounting-Request and Accounting-Response tickets to another system for lawful interception. Actually I need to add some other attributes, but this can all be done in unlang and is already working. I wanted to use rlm_replicate for this, but it did not replicate the response. I created a patch for rlm_replicate: - using the module in Post-Auth will replicate the response. - use the original request->packet->id that the response matches the request - when replicating an accounting-request, send a response right away (is there a better way without changing the current behaviour?) Is it possible to have this functionality included? --- rlm_replicate.c 2019-02-25 22:41:30.000000000 +0100 +++ rlm_replicate.c 2019-03-05 11:46:41.000000000 +0100 @@ -87,12 +87,21 @@ static int replicate_packet(UNUSED void case PW_CODE_ACCESS_REQUEST: pool = realm->auth_pool; break; + case PW_CODE_ACCESS_ACCEPT: + pool = realm->auth_pool; + break; + case PW_CODE_ACCESS_REJECT: + pool = realm->auth_pool; + break; #ifdef WITH_ACCOUNTING case PW_CODE_ACCOUNTING_REQUEST: pool = realm->acct_pool; break; + case PW_CODE_ACCOUNTING_RESPONSE: + pool = realm->acct_pool; + break; #endif #ifdef WITH_COA @@ -125,7 +134,7 @@ static int replicate_packet(UNUSED void } packet->code = code; - packet->id = fr_rand() & 0xff; + packet->id = request->packet->id; packet->sockfd = fr_socket(&home->src_ipaddr, 0); if (packet->sockfd < 0) { REDEBUG("Failed opening socket: %s", fr_strerror()); @@ -191,11 +200,18 @@ static int replicate_packet(UNUSED void */ RDEBUG("Replicating list '%s' to Realm '%s'", fr_int2str(pair_lists, list, "<INVALID>"), realm->name); - if (rad_send(packet, NULL, home->secret) < 0) { + if (rad_send(packet, request->packet, home->secret) < 0) { REDEBUG("Failed replicating packet: %s", fr_strerror()); rcode = RLM_MODULE_FAIL; goto done; } + if (code == PW_CODE_ACCOUNTING_REQUEST) { + rcode = replicate_packet(instance, request, PAIR_LIST_REPLY, PW_CODE_ACCOUNTING_RESPONSE); + if (rcode != RLM_MODULE_OK) { + goto done; + } + + } /* * We've sent it to at least one destination. @@ -224,6 +240,11 @@ static rlm_rcode_t CC_HINT(nonnull) mod_ return replicate_packet(instance, request, PAIR_LIST_REQUEST, request->packet->code); } +static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *request) +{ + return replicate_packet(instance, request, PAIR_LIST_REPLY, request->reply->code); +} + static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, REQUEST *request) { return replicate_packet(instance, request, PAIR_LIST_REQUEST, request->packet->code); @@ -264,6 +285,7 @@ module_t rlm_replicate = { .type = RLM_TYPE_THREAD_SAFE, .methods = { [MOD_AUTHORIZE] = mod_authorize, + [MOD_POST_AUTH] = mod_post_auth, [MOD_ACCOUNTING] = mod_accounting, [MOD_PREACCT] = mod_preaccounting, #ifdef WITH_PROXY -- Greetings Daniel Finger EWE TEL GmbH Cloppenburger Straße 310 26133 Oldenburg E-Mail: info@ewe.de Internet: www.ewe.de Handelsregister Amtsgericht Oldenburg HRB 3723 Aufsichtsratsvorsitzender: Michael Heidkamp Geschäftsführer: Norbert Westfal (Sprecher), Sebastian Jurczyk, Ludwig Kohnen, Maximilian Oertle
On Mar 5, 2019, at 8:04 AM, Daniel Finger <df@ewetel.de> wrote:
I need to replicate Access-Accept, Access-Reject and Accounting-Request and Accounting-Response tickets to another system for lawful interception.
That's... not really good. Sending *response* packets to another system is a pretty terrible idea. e.g. Accounting-Response packets are empty, and therefore don't contain any useful information.
Actually I need to add some other attributes, but this can all be done in unlang and is already working.
I wanted to use rlm_replicate for this, but it did not replicate the response.
I created a patch for rlm_replicate: - using the module in Post-Auth will replicate the response. - use the original request->packet->id that the response matches the request - when replicating an accounting-request, send a response right away (is there a better way without changing the current behaviour?)
Is it possible to have this functionality included?
I don't think so. For one, sending *response* packets somewhere else is very bad. For another, there are issues with the patch.
@@ -125,7 +134,7 @@ static int replicate_packet(UNUSED void }
packet->code = code; - packet->id = fr_rand() & 0xff; + packet->id = request->packet->id;
That changes the behaviour for *all* packets. This is wrong. The patch should use the same ID only when needed. e.g. only for response packets.
@@ -191,11 +200,18 @@ static int replicate_packet(UNUSED void */ RDEBUG("Replicating list '%s' to Realm '%s'", fr_int2str(pair_lists, list, "<INVALID>"), realm->name); - if (rad_send(packet, NULL, home->secret) < 0) { + if (rad_send(packet, request->packet, home->secret) < 0) {
This is similarly wrong. You've made this change for *all* packets. Not just for the response packets. The second argument is the original request packet, and is used only for response packets. Adding the second argument for request packets is not correct.
REDEBUG("Failed replicating packet: %s", fr_strerror()); rcode = RLM_MODULE_FAIL; goto done; } + if (code == PW_CODE_ACCOUNTING_REQUEST) { + rcode = replicate_packet(instance, request, PAIR_LIST_REPLY, PW_CODE_ACCOUNTING_RESPONSE); + if (rcode != RLM_MODULE_OK) { + goto done; + } + + }
The same goes here. You're *always* replicating an Accounting-Response packet. Any patch needs to be much more conservative. It's OK to add functionality. It's not OK to change existing functionality. Alan DeKok.
participants (2)
-
Alan DeKok -
Daniel Finger