From: Nick Porter Date: Fri, 8 Mar 2024 11:06:44 +0000 (+0000) Subject: Replace builtin auth logging with calls to linelog X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6640286bea7fe953b72cb0720f10706a36e383e2;p=thirdparty%2Ffreeradius-server.git Replace builtin auth logging with calls to linelog Removes use of xlat_eval and adds flexibility. --- diff --git a/doc/antora/modules/raddb/pages/sites-available/default.adoc b/doc/antora/modules/raddb/pages/sites-available/default.adoc index 6d0d9981c7a..26b73c94b1f 100644 --- a/doc/antora/modules/raddb/pages/sites-available/default.adoc +++ b/doc/antora/modules/raddb/pages/sites-available/default.adoc @@ -84,65 +84,6 @@ packets. At this time, there is no configuration needed for other packet types. -log:: Logging configuration for `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packets - -In v3, the `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` logging was -configured in the main `radiusd.conf` file, -in the main `log` subsection. That -limitation meant that the configuration was -global to FreeRADIUS. i.e. you could not -have different `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` logging for -different virtual server. - -The extra configuration in v4 allows for -increased flexibility. - - -stripped_names:: Log the full -`link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]` attribute, as it was -found in the request. - -allowed values: {no, yes} - - - -auth:: Log authentication requests -to the log file. - -allowed values: {no, yes} - - - -auth_goodpass:: Log "good" -passwords with the authentication -requests. - -allowed values: {no, yes} - - - -auth_badpass:: Log "bad" -passwords with the authentication -requests. - -allowed values: {no, yes} - - - -msg_goodpass:: -msg_badpass:: - -Log additional text at the end of the "Login OK" messages. -for these to work, the "auth" and "auth_goodpass" or "auth_badpass" -configurations above have to be set to "yes". - -The strings below are dynamically expanded, which means that -you can put anything you want in them. However, note that -this expansion can be slow, and can negatively impact server -performance. - - - session:: Controls how ongoing (multi-round) sessions are handled @@ -1277,14 +1218,6 @@ server default { namespace = radius radius { Access-Request { - log { - stripped_names = no - auth = no - auth_goodpass = no - auth_badpass = no -# msg_goodpass = "" -# msg_badpass = "" - } session { # max = 4096 # timeout = 15 diff --git a/raddb/mods-available/linelog b/raddb/mods-available/linelog index cbf7ad33976..453427db1f0 100644 --- a/raddb/mods-available/linelog +++ b/raddb/mods-available/linelog @@ -418,3 +418,37 @@ linelog log_accounting { unknown = "NAS %{Net.Src.IP} (%{&NAS-IP-Address || &NAS-IPv6-Address}) sent unknown Acct-Status-Type %{Acct-Status-Type}" } } + +# +# ## Authentication success / failure logging +# +# A set of sample module instances which can replace the previous builtin auth log messages +# +# The destination settings here pick up from the main radiusd.conf values, but can be +# amended if these logs need to be sent to a different destination. +# +linelog log_auth_access_accept { + destination = ${log.destination} + file { + filename = ${log.file} + } + syslog { + facility = ${log.syslog_facility} + severity = notice + } + + format = "Login OK: [%{User-Name}] (from %client(shortname) port %{NAS-Port} cli %{Calling-Station-Id})" +} + +linelog log_auth_access_reject { + destination = ${log.destination} + file { + filename = ${log.file} + } + syslog { + facility = ${log.syslog_facility} + severity = notice + } + + format = "Login incorrect (%{Module-Failure-Message}): [%{User-Name}] (from %client(shortname) port %{NAS-Port} cli %{Calling-Station-Id})" +} diff --git a/raddb/sites-available/default b/raddb/sites-available/default index 78a3f067e87..b9916b4eaa5 100644 --- a/raddb/sites-available/default +++ b/raddb/sites-available/default @@ -90,73 +90,6 @@ server default { # needed for other packet types. # Access-Request { - # - # log:: Logging configuration for `Access-Request` packets - # - # In v3, the `Access-Request` logging was - # configured in the main `radiusd.conf` file, - # in the main `log` subsection. That - # limitation meant that the configuration was - # global to FreeRADIUS. i.e. you could not - # have different `Access-Request` logging for - # different virtual server. - # - # The extra configuration in v4 allows for - # increased flexibility. - # - log { - # - # stripped_names:: Log the full - # `User-Name` attribute, as it was - # found in the request. - # - # allowed values: {no, yes} - # - stripped_names = no - - # - # auth:: Log authentication requests - # to the log file. - # - # allowed values: {no, yes} - # - auth = no - - # - # auth_goodpass:: Log "good" - # passwords with the authentication - # requests. - # - # allowed values: {no, yes} - # - auth_goodpass = no - - # - # auth_badpass:: Log "bad" - # passwords with the authentication - # requests. - # - # allowed values: {no, yes} - # - auth_badpass = no - - # - # msg_goodpass:: - # msg_badpass:: - # - # Log additional text at the end of the "Login OK" messages. - # for these to work, the "auth" and "auth_goodpass" or "auth_badpass" - # configurations above have to be set to "yes". - # - # The strings below are dynamically expanded, which means that - # you can put anything you want in them. However, note that - # this expansion can be slow, and can negatively impact server - # performance. - # -# msg_goodpass = "" -# msg_badpass = "" - } - # # session:: Controls how ongoing # (multi-round) sessions are handled @@ -1255,6 +1188,13 @@ send Access-Accept { # &reply.EAP-Key-Name := &reply.EAP-Session-Id # } + # + # Call an instance of `linelog` to log the authentication success + # - equivalent to the previous log `auth = yes` option in v3. + # See `mods-enabled/linelog` for message formats and destinations. + # +# log_auth_access_accept + # # Remove `Reply-Message` if the response contains an # `EAP-Message` attribute. Some NAS equipment will @@ -1293,6 +1233,13 @@ send Access-Reject { # eap + # + # Call an instance of `linelog` to log the authentication failure + # - equivalent to the previous log `auth = yes` option in v3. + # See `mods-enabled/linelog` for message formats and destinations. + # +# log_auth_access_reject + # # Remove `Reply-Message` if the response contains an # `EAP-Message` attribute. Some NAS equipment will diff --git a/src/process/radius/base.c b/src/process/radius/base.c index cb7bcd7ec94..2dbae6f936d 100644 --- a/src/process/radius/base.c +++ b/src/process/radius/base.c @@ -137,13 +137,6 @@ typedef struct { } process_radius_sections_t; typedef struct { - bool log_stripped_names; - bool log_auth; //!< Log authentication attempts. - bool log_auth_badpass; //!< Log failed authentications. - bool log_auth_goodpass; //!< Log successful authentications. - char const *auth_badpass_msg; //!< Additional text to append to failed auth messages. - char const *auth_goodpass_msg; //!< Additional text to append to successful auth messages. - fr_time_delta_t session_timeout; //!< Maximum time between the last response and next request. uint32_t max_session; //!< Maximum ongoing session allowed. @@ -186,20 +179,7 @@ static const conf_parser_t session_config[] = { CONF_PARSER_TERMINATOR }; -static const conf_parser_t log_config[] = { - { FR_CONF_OFFSET("stripped_names", process_radius_auth_t, log_stripped_names), .dflt = "no" }, - { FR_CONF_OFFSET("auth", process_radius_auth_t, log_auth), .dflt = "no" }, - { FR_CONF_OFFSET("auth_badpass", process_radius_auth_t, log_auth_badpass), .dflt = "no" }, - { FR_CONF_OFFSET("auth_goodpass", process_radius_auth_t, log_auth_goodpass), .dflt = "no" }, - { FR_CONF_OFFSET("msg_badpass", process_radius_auth_t, auth_badpass_msg) }, - { FR_CONF_OFFSET("msg_goodpass", process_radius_auth_t, auth_goodpass_msg) }, - - CONF_PARSER_TERMINATOR -}; - static const conf_parser_t auth_config[] = { - { FR_CONF_POINTER("log", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) log_config }, - { FR_CONF_POINTER("session", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) session_config }, CONF_PARSER_TERMINATOR @@ -254,127 +234,6 @@ static void radius_packet_debug(request_t *request, fr_packet_t *packet, fr_pair } } -#define RAUTH(fmt, ...) log_request(L_AUTH, L_DBG_LVL_OFF, request, __FILE__, __LINE__, fmt, ## __VA_ARGS__) - -/* - * Return a short string showing the terminal server, port - * and calling station ID. - */ -static char *auth_name(char *buf, size_t buflen, request_t *request) -{ - fr_pair_t *cli; - fr_pair_t *pair; - uint32_t port = 0; /* RFC 2865 NAS-Port is 4 bytes */ - char const *tls = ""; - fr_client_t *client = client_from_request(request); - - cli = fr_pair_find_by_da(&request->request_pairs, NULL, attr_calling_station_id); - - pair = fr_pair_find_by_da(&request->request_pairs, NULL, attr_nas_port); - if (pair != NULL) port = pair->vp_uint32; - - if (request->packet->socket.inet.dst_port == 0) tls = " via proxy to virtual server"; - - snprintf(buf, buflen, "from client %.128s port %u%s%.128s%s", - client ? client->shortname : "", port, - (cli ? " cli " : ""), (cli ? cli->vp_strvalue : ""), - tls); - - return buf; -} - -/* - * Make sure user/pass are clean and then create an attribute - * which contains the log message. - */ -static void CC_HINT(format (printf, 4, 5)) auth_message(process_radius_auth_t const *inst, - request_t *request, bool goodpass, char const *fmt, ...) -{ - va_list ap; - - bool logit; - char const *extra_msg = NULL; - - char password_buff[128]; - char const *password_str = NULL; - - char buf[1024]; - char extra[1024]; - char *p; - char *msg; - fr_pair_t *username = NULL; - fr_pair_t *password = NULL; - - /* - * No logs? Then no logs. - */ - if (!inst->log_auth) return; - - /* - * Get the correct username based on the configured value - */ - if (!inst->log_stripped_names) { - username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name); - } else { - username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_stripped_user_name); - if (!username) username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name); - } - - /* - * Clean up the password - */ - if (inst->log_auth_badpass || inst->log_auth_goodpass) { - password = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password); - if (!password) { - fr_pair_t *auth_type; - - auth_type = fr_pair_find_by_da(&request->control_pairs, NULL, attr_auth_type); - if (auth_type) { - snprintf(password_buff, sizeof(password_buff), "", - fr_dict_enum_name_by_value(auth_type->da, &auth_type->data)); - password_str = password_buff; - } else { - password_str = ""; - } - } else if (fr_pair_find_by_da(&request->request_pairs, NULL, attr_chap_password)) { - password_str = ""; - } - } - - if (goodpass) { - logit = inst->log_auth_goodpass; - extra_msg = inst->auth_goodpass_msg; - } else { - logit = inst->log_auth_badpass; - extra_msg = inst->auth_badpass_msg; - } - - if (extra_msg) { - extra[0] = ' '; - p = extra + 1; - if (xlat_eval(p, sizeof(extra) - 1, request, extra_msg, NULL, NULL) < 0) return; - } else { - *extra = '\0'; - } - - /* - * Expand the input message - */ - va_start(ap, fmt); - msg = fr_vasprintf(request, fmt, ap); - va_end(ap); - - RAUTH("%s: [%pV%s%pV] (%s)%s", - msg, - username ? &username->data : fr_box_strvalue(""), - logit ? "/" : "", - logit ? (password_str ? fr_box_strvalue(password_str) : &password->data) : fr_box_strvalue(""), - auth_name(buf, sizeof(buf), request), - extra); - - talloc_free(msg); -} - /** Keep a copy of some attributes to keep them from being tamptered with * */ @@ -700,13 +559,6 @@ RESUME(access_accept) PROCESS_TRACE; - vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_module_success_message); - if (vp) { - auth_message(&inst->auth, request, true, "Login OK (%pV)", &vp->data); - } else { - auth_message(&inst->auth, request, true, "Login OK"); - } - /* * Check that there is a name which can be used to * identify the user. The configuration depends on @@ -729,18 +581,10 @@ RESUME(access_accept) RESUME(access_reject) { - fr_pair_t *vp; process_radius_t const *inst = talloc_get_type_abort_const(mctx->inst->data, process_radius_t); PROCESS_TRACE; - vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_module_failure_message); - if (vp) { - auth_message(&inst->auth, request, false, "Login incorrect (%pV)", &vp->data); - } else { - auth_message(&inst->auth, request, false, "Login incorrect"); - } - fr_state_discard(inst->auth.state_tree, request); radius_request_pairs_to_reply(request, mctx->rctx); RETURN_MODULE_OK;