Avoid restart freeradius on config update to modules
Hi Alan, I am working with the freeradius branch 3.0.27 and freeradius service constantly restarts when a module is updated with new config as per design. I went through previous questionnaires on the same and understood it works as expected. I made a few changes in the code and tested, I am able to successfully reload the configuration instead of restarting the freeradius server. Added the diff for your reference. If this is good, can I create a PR diff --git a/src/include/modules.h b/src/include/modules.h
index 9ba81b3bc1..bd9c9a0e0b 100644 --- a/src/include/modules.h +++ b/src/include/modules.h @@ -144,6 +144,7 @@ typedef struct module_t { int modules_init(CONF_SECTION *); int modules_free(void); int modules_hup(CONF_SECTION *modules); +int my_server_define_types(CONF_SECTION *config); rlm_rcode_t process_authorize(int type, REQUEST *request); rlm_rcode_t process_authenticate(int type, REQUEST *request); rlm_rcode_t module_preacct(REQUEST *request); diff --git a/src/main/mainconfig.c b/src/main/mainconfig.c index 09799da0e2..a61762f4be 100644 --- a/src/main/mainconfig.c +++ b/src/main/mainconfig.c @@ -1317,10 +1317,10 @@ void main_config_hup(void) @@ -50,4 +49,137 @@ index 09799da0e2..38628c7eea 100644
cs = cf_section_alloc(NULL, "main", NULL); if (!cs) return; @@ -1381,6 +1381,7 @@ void main_config_hup(void)
INFO("HUP - loading modules");
+ my_server_define_types(cs); /* * Prefer the new module configuration. */ diff --git a/src/main/modules.c b/src/main/modules.c index 9919482c86..ac0d3b019d 100644 --- a/src/main/modules.c +++ b/src/main/modules.c @@ -29,7 +29,7 @@ RCSID("$Id$") #include <freeradius-devel/modcall.h> #include <freeradius-devel/parser.h> #include <freeradius-devel/rad_assert.h> - +#include <string.h> /** Path to search for modules in * */ @@ -1621,6 +1621,18 @@ int virtual_servers_load(CONF_SECTION *config) return 0; }
+int my_module_hup_module(CONF_SECTION *modules, CONF_SECTION *cs, module_instance_t *node, time_t when, char *name) { + + if (!node && + strstr(name, "eap") != NULL) { + node = module_bootstrap(cs); + module_instantiate(modules, node->name); + + } + return module_hup_module(cs, node, when); + + +} int module_hup_module(CONF_SECTION *cs, module_instance_t *node, time_t when) { void *insthandle; @@ -1716,11 +1728,10 @@ int modules_hup(CONF_SECTION *modules) cs = cf_item_to_section(ci); instname = cf_section_name2(cs); if (!instname) instname = cf_section_name1(cs); - strlcpy(myNode.name, instname, sizeof(myNode.name)); node = rbtree_finddata(instance_tree, &myNode);
- module_hup_module(cs, node, when); + my_module_hup_module(modules, cs, node, when, instname); }
return 1; @@ -1880,6 +1891,20 @@ static bool server_define_types(CONF_SECTION *cs) return true; }
+int my_server_define_types(CONF_SECTION *config) { + /* + * Load dictionaries. + * + */ + CONF_SECTION *cs; + for (cs = cf_subsection_find_next(config, NULL, "server"); + cs != NULL; + cs = cf_subsection_find_next(config, cs, "server")) { + if (!server_define_types(cs)) return -1; + } + return 1; +} + extern char const *unlang_keyword[];
static bool is_reserved_word(const char *name) @@ -1904,7 +1929,6 @@ int modules_init(CONF_SECTION *config) { CONF_ITEM *ci, *next; CONF_SECTION *cs, *modules; - /* * Set up the internal module struct. */ diff --git a/src/main/process.c b/src/main/process.c index 98e3633906..31bf5a7655 100644 --- a/src/main/process.c +++ b/src/main/process.c @@ -6020,7 +6020,6 @@ int radius_event_start(CONF_SECTION *cs, bool have_children) if (fr_start_time != (time_t)-1) return 0;
time(&fr_start_time); - if (!check_config) { /* * radius_event_init() must be called first diff --git a/src/main/radiusd.c b/src/main/radiusd.c index 06b566d073..6d0aaa85d1 100644 --- a/src/main/radiusd.c +++ b/src/main/radiusd.c @@ -111,7 +111,6 @@ int main(int argc, char *argv[]) * free that before any leak reports. */ TALLOC_CTX *autofree = talloc_init("main"); - #ifdef OSFC2 set_auth_parameters(argc, argv); #endif @@ -642,6 +641,7 @@ int main(int argc, char *argv[]) #ifdef WITH_STATS radius_stats_init(1); #endif + if (main_config_init() < 0) exit(EXIT_FAILURE); main_config_hup(); } if (status < 0) { diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c index 24b8c5ee2d..73f0851414 100644 --- a/src/modules/rlm_eap/rlm_eap.c +++ b/src/modules/rlm_eap/rlm_eap.c @@ -27,7 +27,6 @@ RCSID("$Id$")
#include <freeradius-devel/radiusd.h> #include <freeradius-devel/modules.h> - #include "rlm_eap.h"
#include <sys/stat.h> @@ -799,6 +798,7 @@ extern module_t rlm_eap; module_t rlm_eap = { .magic = RLM_MODULE_INIT, .name = "eap", + .type = RLM_TYPE_HUP_SAFE, .inst_size = sizeof(rlm_eap_t), .config = module_config, .instantiate = mod_instantiate,
Thanks, Suriya
On Jan 8, 2025, at 5:53 AM, Suriya Shankar <suriya.dshankar@gmail.com> wrote:
I am working with the freeradius branch 3.0.27 and freeradius service constantly restarts when a module is updated with new config as per design. I went through previous questionnaires on the same and understood it works as expected.
I made a few changes in the code and tested, I am able to successfully reload the configuration instead of restarting the freeradius server. Added the diff for your reference. If this is good, can I create a PR
I don't think this will work. Or at least, it won't do what you want. The EAP module tracks ongoing EAP sessions in internal data structures. If the module is HUP'd, it will reload its configuration, and then start a brand new tracking structure. The result is that all ongoing EAP sessions will fail. This isn't really any different than restarting the server. Rather than sending a patch, perhaps you could describe the problem you're trying to solve. It isn't just "HUP a module", it's something more specific than that. Alan DeKok.
Thanks Alan. It's a RadSec connection, On each restart the connection between the NAS and the Radius Server drops and reestablishes on the next authentication. By making the EAP module HUP'd I noticed the established connection was unaffected but yes the clients had to re authenticate again. Is my understanding correct? Regards, Suriya On Fri, Jan 10, 2025 at 8:30 PM Alan DeKok <aland@deployingradius.com> wrote:
On Jan 8, 2025, at 5:53 AM, Suriya Shankar <suriya.dshankar@gmail.com> wrote:
I am working with the freeradius branch 3.0.27 and freeradius service constantly restarts when a module is updated with new config as per design. I went through previous questionnaires on the same and understood it works as expected.
I made a few changes in the code and tested, I am able to successfully reload the configuration instead of restarting the freeradius server. Added the diff for your reference. If this is good, can I create a PR
I don't think this will work. Or at least, it won't do what you want.
The EAP module tracks ongoing EAP sessions in internal data structures. If the module is HUP'd, it will reload its configuration, and then start a brand new tracking structure.
The result is that all ongoing EAP sessions will fail. This isn't really any different than restarting the server.
Rather than sending a patch, perhaps you could describe the problem you're trying to solve. It isn't just "HUP a module", it's something more specific than that.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
On Jan 10, 2025, at 9:01 PM, Suriya Shankar <suriya.dshankar@gmail.com> wrote:
It's a RadSec connection, On each restart the connection between the NAS and the Radius Server drops and reestablishes on the next authentication. By making the EAP module HUP'd I noticed the established connection was unaffected but yes the clients had to re authenticate again. Is my understanding correct?
Yes. But that doesn't answer my question. Think about the "fix" for a bit. The radsec connections stay up, but all authentications fail. How is that any different from just restarting the server? You're just moving the problem from one location to another. This patch doesn't actually fix anything. Alan DeKok.
Hi Alan, We have multiple virtual servers with multiple ca certs. Hoping by reloading instead, only the authentications with the servers that have changes gets dropped. Thanks, Suriya On Sun, Jan 12, 2025 at 1:47 AM Alan DeKok <aland@deployingradius.com> wrote:
On Jan 10, 2025, at 9:01 PM, Suriya Shankar <suriya.dshankar@gmail.com> wrote:
It's a RadSec connection, On each restart the connection between the NAS and the Radius Server drops and reestablishes on the next authentication. By making the EAP module HUP'd I noticed the established connection was unaffected but yes the clients had to re authenticate again. Is my understanding correct?
Yes. But that doesn't answer my question.
Think about the "fix" for a bit. The radsec connections stay up, but all authentications fail. How is that any different from just restarting the server?
You're just moving the problem from one location to another. This patch doesn't actually fix anything.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
On Jan 13, 2025, at 2:59 AM, Suriya Shankar <suriya.dshankar@gmail.com> wrote:
We have multiple virtual servers with multiple ca certs. Hoping by reloading instead, only the authentications with the servers that have changes gets dropped.
I guess that's true. It's still imperfect, and I'm not sure it's always a good idea. Let me see if I can do something to help here. I don't think I can pull in the patch as-is, but something similar might be OK. Alan DeKok.
participants (2)
-
Alan DeKok -
Suriya Shankar