Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 35 additions & 26 deletions doc/man/man5/keepalived.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ if they exit with a non-zero status.

By default the scripts will be executed by user keepalived_script if that user
exists, or if not by root, but for each script the user/group under which it is
to be executed can be specified.
to be executed can be specified. If the groupname is preceeded by a ':' character,
then the supplementary groups of the user executing the script will be set
for the process; if ':' is specified with no groupname, then the supplementary
groups will be specified as above, and the primary group will be the primary
group of the user executing the script.

There are significant security implications if scripts are executed with root
privileges, especially if the scripts themselves are modifiable or replaceable
Expand Down Expand Up @@ -266,6 +270,11 @@ possibly following any cleanup actions needed.
# To keep symlinks in pathnames, specify use_syslink_paths.
\fBuse_symlink_paths \fR[<BOOL>]

# By default, keepalived does not set the supplementary groups of a
# process running a script. This option changes the default to setting
# the supplementary groups for a script.
\fBset_supplementary_groups

# The startup and shutdown scripts are run once, when keepalived starts
# before any child processes are run, and when keepalived stops after
# all child processes have terminated, respectively.
Expand All @@ -280,9 +289,9 @@ possibly following any cleanup actions needed.
# The timeouts (in seconds default 10 seconds) are the time allowed for
# scripts to run; if the timeout expires the scripts will be killed (this
# is to stop keepalived hanging waiting for the scripts to terminate).
\fBstartup_script\fR SCRIPT_NAME [username [groupname]]
\fBstartup_script\fR SCRIPT_NAME [username [:][groupname]]
\fBstartup_script_timeout\fR SECONDS # range [1,1000]
\fBshutdown_script\fR SCRIPT_NAME [username [groupname]]
\fBshutdown_script\fR SCRIPT_NAME [username [:][groupname]]
\fBshutdown_script_timeout\fR SECONDS # range [1,1000]

# Set of email To: notify. To include a display name, the whole email address
Expand Down Expand Up @@ -727,7 +736,7 @@ possibly following any cleanup actions needed.
# If this option is not specified, the user defaults to keepalived_script
# if that user exists, otherwise the uid/gid under which keepalived is running.
# If groupname is not specified, it defaults to the user's group.
\fBscript_user \fRusername [groupname]
\fBscript_user \fRusername [:][groupname]

# Don't run scripts configured to be run as root if any part of the path
# is writable by a non-root user. Also, enforce the default script_user is
Expand All @@ -748,7 +757,7 @@ possibly following any cleanup actions needed.

# script to be run by keepalived to process notify events
# The FIFO name will be passed to the script as the last parameter
\fBnotify_fifo_script \fRSTRING|QUOTED-STRING [username [groupname]]
\fBnotify_fifo_script \fRSTRING|QUOTED-STRING [username [:][groupname]]

# FIFO to write vrrp notify events to.
# The string written will be a line of the form: INSTANCE "VI_1" MASTER 100
Expand All @@ -759,7 +768,7 @@ possibly following any cleanup actions needed.

# script to be run by keepalived to process vrrp notify events
# The FIFO name will be passed to the script as the last parameter
\fBvrrp_notify_fifo_script \fRSTRING|QUOTED-STRING [username [groupname]]
\fBvrrp_notify_fifo_script \fRSTRING|QUOTED-STRING [username [:][groupname]]

# FIFO to write notify healthchecker events to
# The string written will be a line of the form:
Expand All @@ -770,7 +779,7 @@ possibly following any cleanup actions needed.

# script to be run by keepalived to process healthchecher notify events
# The FIFO name will be passed to the script as the last parameter
\fBlvs_notify_fifo_script \fRSTRING|QUOTED-STRING [username [groupname]]
\fBlvs_notify_fifo_script \fRSTRING|QUOTED-STRING [username [:][groupname]]

# By default, when keepalived reloads the vrrp instance and sync group states
# are not written to the relevant FIFOs. Setting this option will cause the
Expand Down Expand Up @@ -1451,7 +1460,7 @@ The syntax for the vrrp script is:

# user/group names to run script under.
# group default to group of user
\fBuser \fRUSERNAME [GROUPNAME]
\fBuser \fRusername [:][groupname]

# assume script initially is in failed state
\fBinit_fail\fR
Expand Down Expand Up @@ -1549,22 +1558,22 @@ The syntax for vrrp_sync_group is :
# global script_user and script_group

# to MASTER transition
\fBnotify_master \fR/path/to_master.sh [username [groupname]]
\fBnotify_master \fR/path/to_master.sh [username [:][groupname]]

# to BACKUP transition
\fBnotify_backup \fR/path/to_backup.sh [username [groupname]]
\fBnotify_backup \fR/path/to_backup.sh [username [:][groupname]]

# FAULT transition
\fBnotify_fault \fR"/path/fault.sh VG_1" [username [groupname]]
\fBnotify_fault \fR"/path/fault.sh VG_1" [username [:][groupname]]

# executed when stopping vrrp
\fBnotify_stop \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_stop \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]

# notify_deleted causes DELETED to be sent to notifies rather
# than the default FAULT after a vrrp instance is deleted during a
# reload. If a script is specified, that script will be executed
# as well.
\fBnotify_deleted [\fR<STRING>|<QUOTED-STRING> [username [groupname]]]
\fBnotify_deleted [\fR<STRING>|<QUOTED-STRING> [username [:][groupname]]]

# for ANY state transition.
# "notify" script is called AFTER the notify_* script(s) and
Expand All @@ -1579,7 +1588,7 @@ The syntax for vrrp_sync_group is :
# strings sent are the same ones listed above
# ("GROUP"/"INSTANCE", "MASTER"/"BACKUP"/"FAULT"/"STOP"/"DELETED")
# (note: DELETED is only applicable to instances)
\fBnotify \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]

# The notify fifo output is the same as the last 4 parameters for the "notify"
# script, with the addition of "MASTER_RX_LOWER_PRI" instead of state for an
Expand Down Expand Up @@ -2199,16 +2208,16 @@ The syntax for vrrp_instance is :
\fBdebug \fR<LEVEL>

# notify scripts, alert as above
\fBnotify_master \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_backup \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_fault \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_master \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]
\fBnotify_backup \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]
\fBnotify_fault \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]
# executed when stopping vrrp
\fBnotify_stop \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_stop \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]
\fBnotify \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]

# The notify_master_rx_lower_pri script is executed if a master
# receives an advert with priority lower than the master's priority.
\fBnotify_master_rx_lower_pri \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_master_rx_lower_pri \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]

# Send vrrp instance priority notifications on notify FIFOs.
\fBnotify_priority_changes\fR <BOOL>
Expand Down Expand Up @@ -2440,10 +2449,10 @@ The syntax for virtual_server is :
\fBhysteresis \fR<INTEGER>

# Script to execute when quorum is gained.
\fBquorum_up \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBquorum_up \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]

# Script to execute when quorum is lost.
\fBquorum_down \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBquorum_down \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]

# IP family for a fwmark service (only needed if all real servers are tunnelled
# and persistence_granularity is not specified). Defaults to inet if not specified.
Expand Down Expand Up @@ -2506,10 +2515,10 @@ The syntax for virtual_server is :

# Script to execute when healthchecker
# considers service as up.
\fBnotify_up \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_up \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]
# Script to execute when healthchecker
# considers service as down.
\fBnotify_down \fR<STRING>|<QUOTED-STRING> [username [groupname]]
\fBnotify_down \fR<STRING>|<QUOTED-STRING> [username [:][groupname]]

# maximum number of connections to server
\fButhreshold \fR<INTEGER>
Expand Down Expand Up @@ -2714,9 +2723,9 @@ The syntax for virtual_server is :

# Specify the username/groupname that the script should
# be run under.
# If GROUPNAME is not specified, the group of the user
# If groupname is not specified, the group of the user
# is used
\fBuser \fRUSERNAME [GROUPNAME]
\fBuser \fRusername [:][groupname]
}

# BFD instance name to check
Expand Down
1 change: 1 addition & 0 deletions keepalived/bfd/bfd_daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ start_bfd(__attribute__((unused)) data_t *prev_global_data)
alloc_bfd_buffer();

init_data(conf_file, bfd_init_keywords, false);
notify_resource_release();

if (reload)
init_global_data(global_data, prev_global_data, true);
Expand Down
1 change: 1 addition & 0 deletions keepalived/check/check_daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ start_check(data_t *prev_global_data)
}

init_data(conf_file, check_init_keywords, false);
notify_resource_release();

if (reload)
init_global_data(global_data, prev_global_data, true);
Expand Down
11 changes: 9 additions & 2 deletions keepalived/check/check_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,19 @@ dump_tracking_rs(FILE *fp, const void *data)
static void
dump_notify_vs_rs_script(FILE *fp, const notify_script_t *script, const char *type, const char *state)
{
int i;

if (script->path)
conf_write(fp, " %s %s notify script = %s, params = %s, uid:gid %u:%u", type, state,
script->path, cmd_str(script), script->uid, script->gid);
script->path, cmd_str(script), script->user_id.uid, script->user_id.gid);
else
conf_write(fp, " %s %s notify script = %s, uid:gid %u:%u", type, state,
cmd_str(script), script->uid, script->gid);
cmd_str(script), script->user_id.uid, script->user_id.gid);
if (script->user_id.num_sup_grp) {
conf_write(fp, " Supplementary groups:");
for (i = 0; i < script->user_id.num_sup_grp; i++)
conf_write(fp, " %u", script->user_id.sup_grp[i]);
}
}

static void
Expand Down
12 changes: 9 additions & 3 deletions keepalived/check/check_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,20 @@ dump_misc_check(FILE *fp, const checker_t *checker)
{
const misc_checker_t *misck_checker = checker->data;
char time_str[26];
int i;

conf_write(fp, " Keepalive method = MISC_CHECK");
if (misck_checker->script.path)
conf_write(fp, " path = %s", misck_checker->script.path);
conf_write(fp, " script = %s", cmd_str(&misck_checker->script));
conf_write(fp, " timeout = %lu", misck_checker->timeout/TIMER_HZ);
conf_write(fp, " dynamic = %s", misck_checker->dynamic ? "YES" : "NO");
conf_write(fp, " uid:gid = %u:%u", misck_checker->script.uid, misck_checker->script.gid);
conf_write(fp, " uid:gid = %u:%u", misck_checker->script.user_id.uid, misck_checker->script.user_id.gid);
if (misck_checker->script.user_id.num_sup_grp) {
conf_write(fp, " Supplementary groups:");
for (i = 0; i < misck_checker->script.user_id.num_sup_grp; i++)
conf_write(fp, " %u", misck_checker->script.user_id.sup_grp[i]);
}
ctime_r(&misck_checker->last_ran.tv_sec, time_str);
conf_write(fp, " Last ran = %" PRI_tv_sec ".%6.6" PRI_tv_usec " (%.24s.%6.6" PRI_tv_usec ")", misck_checker->last_ran.tv_sec, misck_checker->last_ran.tv_usec, time_str, misck_checker->last_ran.tv_usec);
conf_write(fp, " Last status = %u", misck_checker->last_exit_code);
Expand Down Expand Up @@ -172,7 +178,7 @@ misc_user_handler(const vector_t *strvec)
return;
}

if (set_script_uid_gid(strvec, 1, &new_misck_checker->script.uid, &new_misck_checker->script.gid)) {
if (set_script_uid_gid(strvec, 1, &new_misck_checker->script.user_id)) {
report_config_error(CONFIG_GENERAL_ERROR, "Failed to set uid/gid for misc checker script %s - removing", cmd_str(&new_misck_checker->script));
dequeue_new_checker();
}
Expand All @@ -193,7 +199,7 @@ misc_end_handler(void)

if (!script_user_set)
{
if (get_default_script_user(&new_misck_checker->script.uid, &new_misck_checker->script.gid)) {
if (get_default_script_user(&new_misck_checker->script.user_id)) {
report_config_error(CONFIG_GENERAL_ERROR, "Unable to set default user for misc script %s - removing", cmd_str(&new_misck_checker->script));
dequeue_new_checker();
return;
Expand Down
2 changes: 1 addition & 1 deletion keepalived/core/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ noinst_LIBRARIES = libcore.a

libcore_a_SOURCES = main.c daemon.c pidfile.c layer4.c smtp.c \
global_data.c global_parser.c keepalived_netlink.c \
namespaces.c
namespaces.c notify.c

libcore_a_LIBADD =
EXTRA_libcore_a_SOURCES =
Expand Down
42 changes: 28 additions & 14 deletions keepalived/core/global_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ free_global_data(data_t **datap)
FREE_CONST_PTR(data->network_namespace_ipvs);
FREE_CONST_PTR(data->instance_name);
FREE_CONST_PTR(data->process_name);
FREE_CONST_PTR(data->default_script_user_id.sup_grp);
#ifdef _WITH_VRRP_
FREE_CONST_PTR(data->vrrp_process_name);
#endif
Expand Down Expand Up @@ -600,7 +601,9 @@ open_dump_file(const char *default_file_name)
static void
write_fifo_details(FILE *fp, const notify_fifo_t *fifo, const char *type)
{
conf_write(fp, " %s notify fifo = %s, uid:gid %u:%u", type, fifo->name, fifo->uid, fifo->gid);
int i;

conf_write(fp, " %s notify fifo = %s, uid:gid %u:%u", type, fifo->name, fifo->user_id.uid, fifo->user_id.gid);

if (!fifo->script)
return;
Expand All @@ -610,14 +613,20 @@ write_fifo_details(FILE *fp, const notify_fifo_t *fifo, const char *type)
type,
fifo->script->path,
cmd_str(fifo->script),
fifo->script->uid,
fifo->script->gid);
fifo->script->user_id.uid,
fifo->script->user_id.gid);
else
conf_write(fp, " %s notify fifo script = %s, uid:gid %u:%u",
type,
cmd_str(fifo->script),
fifo->script->uid,
fifo->script->gid);
fifo->script->user_id.uid,
fifo->script->user_id.gid);

if (fifo->script->user_id.num_sup_grp) {
conf_write(fp, " Supplementary groups:");
for (i = 0; i < fifo->script->user_id.num_sup_grp; i++)
conf_write(fp, " %u", fifo->script->user_id.sup_grp[i]);
}
}

void
Expand All @@ -632,8 +641,7 @@ dump_global_data(FILE *fp, data_t * data)
struct tm tm;
#endif
unsigned val;
uid_t uid;
gid_t gid;
int i;

if (!data)
return;
Expand Down Expand Up @@ -664,6 +672,7 @@ dump_global_data(FILE *fp, data_t * data)
conf_write(fp, " BFD process name = %s", data->bfd_process_name);
#endif
conf_write(fp, " %s symlinks in script paths", data->use_symlinks ? "Keep" : "Replace");
conf_write(fp, " %set supplementary groups for all scripts", data->set_supplementary_groups ? "S" : "Don't s");
if (data->router_id)
conf_write(fp, " Router ID = %s", data->router_id);
if (data->smtp_server.ss_family) {
Expand Down Expand Up @@ -709,22 +718,21 @@ dump_global_data(FILE *fp, data_t * data)
if (data->reload_file)
conf_write(fp, " Reload_file = %s", data->reload_file);
#endif
conf_write(fp, " keep script symlinks = %s", data->use_symlinks ? "true" : "false");
if (data->config_directory)
conf_write(fp, " config save directory = %s", data->config_directory);
if (data->data_use_instance)
conf_write(fp, " Use instance name in data dumps");
if (data->startup_script)
conf_write(fp, " Startup script = %s, uid:gid %u:%u, timeout %u",
cmd_str(data->startup_script),
data->startup_script->uid,
data->startup_script->gid,
data->startup_script->user_id.uid,
data->startup_script->user_id.gid,
data->startup_script_timeout);
if (data->shutdown_script)
conf_write(fp, " Shutdown script = %s, uid:gid %u:%u timeout %u",
cmd_str(data->shutdown_script),
data->shutdown_script->uid,
data->shutdown_script->gid,
data->shutdown_script->user_id.uid,
data->shutdown_script->user_id.gid,
data->shutdown_script_timeout);
#ifdef _WITH_VRRP_
conf_write(fp, " Dynamic interfaces = %s", data->dynamic_interfaces ? "true" : "false");
Expand Down Expand Up @@ -922,8 +930,14 @@ dump_global_data(FILE *fp, data_t * data)
conf_write(fp, " DBus no interface name = %s", data->dbus_no_interface_name ? data->dbus_no_interface_name : dbus_no_interface_name);
#endif
conf_write(fp, " Script security %s", script_security ? "enabled" : "disabled");
if (!get_default_script_user(&uid, &gid))
conf_write(fp, " Default script uid:gid %u:%u", uid, gid);
if (global_data->default_script_uid_set) {
conf_write(fp, " Default script uid:gid %u:%u", global_data->default_script_user_id.uid, global_data->default_script_user_id.gid);
if (global_data->default_script_user_id.sup_grp) {
conf_write(fp, " Supplementary groups:");
for (i = 0; i < global_data->default_script_user_id.num_sup_grp; i++)
conf_write(fp, " %u", global_data->default_script_user_id.sup_grp[i]);
}
}
#ifdef _WITH_VRRP_
conf_write(fp, " vrrp_netlink_cmd_rcv_bufs = %u", global_data->vrrp_netlink_cmd_rcv_bufs);
conf_write(fp, " vrrp_netlink_cmd_rcv_bufs_force = %d", global_data->vrrp_netlink_cmd_rcv_bufs_force);
Expand Down
Loading
Loading