LDIRECTORD(8)
๐ NAME ๐
Okay bestie, this is LDIRECTORD(8) from the User Contributed Perl Documentation crew โจ It's ldirectord โ the Linux Director Daemon โ and it's literally a daemon to monitor remote services and control Linux Virtual Server. ๐ฆ
๐ก SYNOPSIS ๐ก
ldirectord [-d|--debug] [--] [configfile] start | stop | restart |
try-restart | reload | force-reload | status
ldirectord [-h|-?|--help|-v|--version]
๐ซ DESCRIPTION ๐ซ
So ldirectord is a daemon that monitors and administers real servers in a cluster of load balanced virtual servers. It's typically started from heartbeat, but you can also run it from the command line, no cap.
On startup, ldirectord reads the file /etc/ha.d/conf/configuration. After parsing that file, entries for virtual servers are created on the LVS. Then, at regular intervals, the specified real servers are monitored, and if they're considered alive, they get added to a list for each virtual server. If a real server fails, it's removed from that list. ๐
Only one instance of ldirectord can be started for each configuration, but more instances of ldirectord may be started for different configurations. This helps to group clusters of services. Normally one would put an entry inside /etc/ha.d/haresources:
nodename virtual-ip-address ldirectord::configuration
to start ldirectord from heartbeat. ๐ซถ
โจ OPTIONS โจ
configurationโ This is the name for the configuration as specified in the file/etc/ha.d/conf/configuration.-d,--debugโ Don't start as daemon and log verbosely. ๐-h,--helpโ Print user manual and exit.-v,--versionโ Print version and exit.startโ Start the daemon for the specified configuration. ๐stopโ Stop the daemon for the specified configuration. This is the same as sending aTERMsignal to the running daemon.restartโ Restart the daemon for the specified configuration. The same as stopping and starting. ๐reloadโ Reload the configuration file. This is only useful for modifications inside a virtual server entry. It will have no effect on adding or removing a virtual server block. This is the same as sending aHUPsignal to the running daemon.statusโ Status of the running daemon for the specified configuration. ๐
Side note, bestie: the synopsis also liststry-restartandforce-reloadas actions, but this page's OPTIONS prose doesn't explain them, so I'm not inventing extra lore. ๐
๐ SYNTAX ๐
๐ง Description of how to write configuration files ๐ง
virtual = (ip_address|hostname:portnumber|servicename)|firewall-mark โ Defines a virtual service by IP-address (or hostname) and port (or servicename) or firewall-mark. A firewall-mark is an integer greater than zero. The configuration of marking packets is controlled using the -m option to ipchains(8). All real services and flags for a virtual service must follow this line immediately and be indented. ๐ฅ
checktimeout = n โ Timeout in seconds for connect, external, external-perl and ping checks. If the timeout is exceeded then the real server is declared dead. If defined in a virtual server section then the global value is overridden. If undefined then the value of negotiatetimeout is used. negotiatetimeout is also a global value that may be overridden by a per-virtual setting. If both checktimeout and negotiatetimeout are unset, the default is used.
Default: 5 seconds โณ
negotiatetimeout = n โ Timeout in seconds for negotiate checks. If defined in a virtual server section then the global value is overridden. If undefined then the value of checktimeout is used. checktimeout is also a global value that may be overridden by a per-virtual setting. If both negotiatetimeout and checktimeout are unset, the default is used.
Default: 30 seconds โณ
checkinterval = n โ Defines the number of seconds between server checks. When fork=no this option defines the amount of time ldirectord sleeps between running all of the realserver checks in all virtual service pools. When fork=yes this option defines the amount of time each forked child sleeps per virtual service pool after running all realserver checks for that pool. If set in the virtual server section then the global value is overridden, but ONLY if using forking mode (fork = yes).
Default: 10 seconds โฑ๏ธ
checkcount = n โ This option is deprecated and slated for removal in a future version. Please see the 'failurecount' option. The number of times a check will be attempted before it is considered to have failed. Only works with ping checks. Note that the checktimeout/negotiatetimeout is additive, so if a connect check is used, checkcount is 3 and checktimeout is 2 seconds, then a total of 6 seconds worth of timeout will occur before the check fails. If defined in a virtual server section then the global value is overridden.
Default: 1 โ ๏ธ
failurecount = n โ The number of consecutive times a failure will have to be reported by a check before the realserver is considered to have failed. A value of 1 will have the realserver considered failed on the first failure. A successful check will reset the failure counter to 0. If defined in a virtual server section then the global value is overridden.
Default: 1 ๐
autoreload = yes | no โ Defines if <ldirectord> should continuously check the configuration file for modification. If this is set to 'yes' and the configuration file changed on disk and its modification time (mtime) is newer than the previous version, the configuration is automatically reloaded.
Default: no ๐
callback = "/path/to/callback" โ If this directive is defined, ldirectord automatically calls the executable /path/to/callback after the configuration file has changed on disk. This is useful to update the configuration file through scp on the other heartbeated host. The first argument to the callback is the name of the configuration. This directive might also be used to restart ldirectord automatically after the configuration file changed on disk. However, if autoreload is set to yes, the configuration is reloaded anyway. ๐
fallback = ip_address|hostname[:portnumber|sercvicename] [gate | masq | ipip] โ the server onto which a webservice is redirected if all real servers are down. Typically this would be 127.0.0.1 with an emergency page. If defined in a virtual server section then the global value is overridden. ๐จ
fallbackcommand = "path to script" โ If this directive is defined, the supplied script is executed whenever all real servers for a virtual service are down or when the first real server comes up again. In the first case, it is called with "start" as its first argument, in the latter with "stop". Additional parameters are vserver with vport (vserver:vport) as second param and protocol (tcp/udp) as third param to identify the virtual service within the fallback script. If defined in a virtual server section then the global value is overridden. ๐
logfile = "/path/to/logfile"|syslog_facility โ An alternative logfile might be specified with this directive. If the logfile does not have a leading '/', it is assumed to be a syslog(3) facility name.
Default: log directly to the file /var/log/ldirectord.log. ๐
emailalert = "emailaddress[, emailaddress]..." โ A valid email address for sending alerts about the changed connection status to any real server defined in the virtual service. This option requires perl module MailTools to be installed. Automatically tries to send email using any of the built-in methods. See perldoc Mail::Mailer for more info on methods. Multiple addresses may be supplied, comma delimited. If defined in a virtual server section then the global value is overridden. ๐ง
emailalertfrom = emailaddress โ A valid email address to use as the from address of the email alerts. You can use a plain email address or any RFC-compliant string for the From header in the body of an email message (such as: "ldirectord Alerts" <alerts@example.com>) Do not quote this string unless you want the quotes passed in as part of the From header.
Default: unset, take system generated default (probably root@hostname) โ๏ธ
emailalertfreq = n โ Delay in seconds between repeating email alerts while any given real server in the virtual service remains inaccessible. A setting of zero seconds will inhibit the repeating alerts. The email timing accuracy of this setting is dependent on the number of seconds defined in the checkinterval configuration option. If defined in a virtual server section then the global value is overridden.
Default: 0 ๐
emailalertstatus = all | none | starting | running | stopping | reloading,... โ Comma delimited list of server states in which email alerts should be sent. all is a short-hand for "starting,running,stopping,reloading". If none is specified, no other option may be specified, otherwise options are ored with each other. If defined in a virtual server section then the global value is overridden.
Default: all ๐
smtp = ip_address|hostname" โ A valid SMTP server address to use for sending email via SMTP. If defined in a virtual server section then the global value is overridden. ๐ฎ
execute = "configuration" โ Use this directive to start an instance of ldirectord for the named configuration. โก
supervised = yes | no โ If yes, then ldirectord does not go into background mode. All log-messages are redirected to stdout instead of a logfile. This is useful to run ldirectord supervised from daemontools. See http://untroubled.org/rpms/daemontools/ or http://cr.yp.to/daemontools.html for details.
Default: no ๐งธ
fork = yes | no โ If yes, then ldirectord will spawn a child process for every virtual server, and run checks against the real servers from them. This will increase response times to changes in real server status in configurations with many virtual servers. This may also use less memory then running many separate instances of ldirectord. Child processes will be automatically restarted if they die.
Default: no ๐ฑ
quiescent = yes | no โ If yes, then when real or failback servers are determined to be down, they are not actually removed from the kernel's LVS table. Rather, their weight is set to zero which means that no new connections will be accepted. This has the side effect, that if the real server has persistent connections, new connections from any existing clients will continue to be routed to the real server, until the persistent timeout can expire. See ipvsadm for more information on persistent connections. This side-effect can be avoided by running the following:
echo 1 > /proc/sys/net/ipv4/vs/expire_quiescent_template
If the proc file isn't present this probably means that the kernel doesn't have LVS support, LVS support isn't loaded, or the kernel is too old to have the proc file. Running ipvsadm as root should load LVS into the kernel if it is possible. If no, then the real or failback servers will be removed from the kernel's LVS table. The default is yes. If defined in a virtual server section then the global value is overridden.
Default: yes ๐
readdquiescent = yes | noโ okay so picture this: a real or failback server gets flagged as down. If this isyes, ldirectord readds it to the kernel's LVS table with weight0โ but only if it isn't already chilling in that table. Set it tonoand you get to manually remove the realserver yourself, which is how you manually disable all persistent connections. ๐cleanstop = yes | noโyesmeans when ldirectord exits, it takes every virtual server pool it's managing and removes them all from the kernel's LVS table. Clean exit, no crumbs. โจ
no means the virtual server pools it's managing, plus any real or failback servers listed in them at the moment ldirectord exits, get left exactly as-is. So if you want to be able to stop ldirectord without having traffic to your realservers interrupted, this is the one you want set to no. ๐ซถ
If it's defined inside a virtual server section, the global value gets overridden.
Default: yes
maintenancedir =directoryname โ set this and ldirectord will go looking for a special file in that directory, and if it finds one, it forces the status of the real server that file identifies to down โ straight up skipping the normal health check. Which is lowkey iconic if you want to force servers down for maintenance without touching the actual ldirectord config file. ๐ ๏ธ
For example: given a realserver with IP 172.16.1.2, service on port 4444, and a resolvable reverse DNS entry pointing to "realserver2.example.com", ldirectord will check whether any of these files exist:
172.16.1.2:4444
172.16.1.2
realserver2.example.com:4444
realserver2.example.com
realserver2:4444
realserver2
If any one of those files is found, ldirectord immediately forces the status of that server to down, exactly as if the check had failed. ๐ญ
Note bestie: since it checks for the IP/hostname without the port, you can decide to place an entire realserver into maintenance across a huge pile of virtual service pools with a single file (say, because you're about to reboot the server ๐) โ or include the port number and put just one particular service into maintenance.
This option is not valid in a virtual server section.
Default: disabled
๐ธ Section virtual ๐ธ
The following commands must follow a virtual entry and must be indented with a minimum of 4 spaces or one tab. The parser is literally counting, bestie, so don't get cute with the whitespace. ๐
real = ip_address|hostname[->ip_address|hostname][:portnumber|servicename] gate | masq | ipip [weight] ["request", "receive"] [ "<l:l-threshold>" ] [ "<u:u-threshold>" ]
realโ defines a real service by IP-address (or hostname) and port (or servicename). If the port is omitted then a0will be used โ this is intended primarily forfwmarkservices where the port for real servers is ignored. Optionally a range of IPv4 addresses (or two hostnames) may be given, and in that case each IPv4 address in the range is treated as a real server using the given port. ๐ฆ
The second argument defines the forwarding method and must be gate, ipip or masq. The third argument is optional and defines the weight for that real server โ omit it and a weight of 1 is used. The next two arguments are also optional: they define a request-receive pair used to check if a server is alive, and they override the request-receive pair in the virtual server section. Those two strings must be quoted. If the request string starts with http://... then the IP-address and port of the real server are overridden; otherwise the IP-address and port of the real server are used. The last two optional arguments set the lower and upper connection thresholds for real servers, using the -y and -x ipvsadm arguments. โญ
๐จ For TCP and UDP (non fwmark) virtual services, unless the forwarding method ismasqand the IP address of a real server is non-local (not present on an interface on the host running ldirectord), then the port of the real server will be set to that of its virtual service. That is, port-mapping is only available if the real server is another machine and the forwarding method ismasq. This is due to the way that the underlying LVS code in the kernel functions. No cap, that's just how it works. ๐
More than one of these entries may be inside a virtual section. The checktimeout, negotiatetimeout, checkcount, fallback, emailalert, emailalertfreq and quiescent options listed above may also appear inside a virtual section, and when they do, the global setting is overridden. ๐
checktype = connect | external | external-perl | negotiate | off | on | ping | checktimeoutNโ the type of check to perform, obviously.negotiatesends a request and matches a receive string.connectonly attempts to make a TCP/IP connection, so the request and receive strings may be omitted. Ifchecktypeis a number thennegotiateandconnectare combined, so after each N connect attempts one negotiate attempt is performed โ which is genuinely so useful for checking often whether a service answers, while doing a negotiating check in much longer intervals. ๐ต๏ธโโ๏ธ
ping means ICMP ping will be used to test the availability of real servers โ and ping is also used as the connect check for UDP services. off means no checking takes place and no real or fallback servers get activated. on means no checking takes place and real servers are always activated. Default is negotiate.
service = dns | ftp | http | https | http_proxy | imap | imaps | ldap | ldaps | mysql | nntp | none | oracle | pgsql | pop | pops | radius | simpletcp | sip | smtp | submissionโ the type of service to monitor when usingchecktype=negotiate.nonedenotes a service that will not be monitored.simpletcpsends the request string to the server and tests it against the receive regexp. The other types of checks connect to the server using the specified protocol โ please see therequestandreceivesections for protocol-specific info. ๐ก
Default:
- Virtual server port is
21:ftp - Virtual server port is
25:smtp - Virtual server port is
53:dns - Virtual server port is
80:http - Virtual server port is
110:pop - Virtual server port is
119:nntp - Virtual server port is
143:imap - Virtual server port is
389:ldap - Virtual server port is
443:https - Virtual server port is
587:submission - Virtual server port is
636ldaps - Virtual server port is
993:imaps - Virtual server port is
995:pops - Virtual server port is
1521:oracle - Virtual server port is
1812:radius - Virtual server port is
3128:http_proxy - Virtual server port is
3306:mysql - Virtual server port is
5432:pgsql - Virtual server port is
5060:sip - Otherwise:
none
checkcommand = "path to script"โ this setting is used whenchecktypeisexternalorexternal-perl, and it's the command that gets run to check the status of a real server. It should exit with status0if everything is ok, or non-zero otherwise. ๐
Four parameters are passed to the script:
- virtual server ip/firewall mark
- virtual server port
- real server ip
- real server port
If the checktype is external-perl then the command is assumed to be a Perl script, and it's evaluated into an anonymous subroutine which gets called at check time, avoiding a fork-exec. Bestie, that's a whole glow-up. โจ The argument signature and exit code conventions are identical to checktype external โ that is, an external-perl checktype should also work as an external checktype.
Default: /bin/true
checkport =n โ the number of the port to monitor. Sometimes the check port differs from the service port. ๐คทโโ๏ธ
Default: port specified for each real server
request = "uri to requested object"โ this object gets requested everycheckintervalseconds on each real server. The string must be inside quotes. Note that this string may be overridden by an optional per-real-server-based request-string. ๐จ
For an HTTP/HTTPS check, this should be a relative URI, while it has to be absolute for the http_proxy check type. In the latter case, this URI will be requested through the proxy backend that's being checked.
For a DNS check, this should be the name of an A record, or the address of a PTR record to look up.
For a MySQL, Oracle or PostgeSQL check, this should be an SQL SELECT query. The data returned is not checked โ only that the answer is one or more rows. This is a required setting. ๐ค
For a simpletcp check, this string is sent verbatim except any occurrences of \n are replaced with a new line character.
receive = "regexp to compare"โ if the requested result contains this regexp to compare, the real server is declared alive. The regexp must be inside quotes. Keep in mind that regexps are not plain strings and that you need to escape the special characters if they should be literals โ yes, this is where people get humbled. ๐ Note that this regexp may be overridden by an optional per-real-server-based receive regexp.
For a DNS check, this should be any one of the A record's addresses or any one of the PTR record's names. In the case of dynamic DNS answers (different answers on the same question), a regex to match multiple addresses or PTR record names could also be defined. ๐
For a MySQL check, the receive setting is not used.
httpmethod = GET | HEADโ sets the HTTP method used to fetch the URI specified in the request-string.GETis the method used by default if the parameter isn't set. IfHEADis used, the receive-string should be unset. ๐ฏ
Default: GET
virtualhost = "hostname"โ used when using a negotiate check with HTTP or HTTPS. Sets the host header used in the HTTP request. In the case of HTTPS this generally needs to match the common name of the SSL certificate ๐ โ if it's not set, then the host header is derived from the request url for the real server if present. As a last resort, the IP address of the real server is used.login = "username"โ for FTP, IMAP, LDAP, MySQL, Oracle, POP and PostgreSQL, this is the username used to log in.
For RADIUS, the username is used for the attribute User-Name.
For SIP, the username is used as both the to and from address for an OPTIONS query.
Default:
- FTP:
Anonymous - MySQL Oracle, and PostgreSQL: must be specified in the configuration
- SIP:
ldirectord\@<hostname>, hostname is derived as per thepasswdoption below. - Otherwise: empty string, which denotes that case authentication will not be attempted.
passwd = "password"โ the password to use to log in to FTP, IMAP, LDAP, MySQL, Oracle, POP, PostgreSQL and SIP servers. ๐
For RADIUS, the passwd is used for the attribute User-Password.
Default:
- FTP:
ldirectord\@<hostname>, where hostname is the environment variableHOSTNAMEevaluated at run time, or sourced fromunameif unset. - Otherwise: empty string. In the case of LDAP, MySQL, Oracle, and PostgreSQL this means that authentication will not be performed.
database = "databasename"โ and this is exactly where our page cuts off, so hold that thought for the next bit bestie ๐ซถ๐
databaseโ the database to use for MySQL, Oracle and PostgreSQL servers; this is the database that the query (set byreceiveup above โฌ๏ธ) gets performed against. It's a required setting, bestie โ no skipping ๐secret = "radiussecret"โ the secret for RADIUS servers โจ this is the secret used to perform an Access-Request with the username (set byloginabove) andpasswd(set bypasswdabove). Default: empty string ๐ซscheduler = scheduler_nameโ the scheduler LVS uses for loadbalancing โ๏ธ for the info on the available schedulers, pls go see theipvsadm(8)man page, it's right there, iykyk. Default:"wrr"persistent = nโ number of seconds for persistent client connections โฑ๏ธnetmask = w.x.y.z | prefixlenโ netmask used for the granularity of persistent client connections ๐ IPv4 netmask should be specified in dotted quad notation. IPv6 netmask should be specified as a prefix length between 1 and 128. yes, between 1 and 128, don't get cute with it ๐protocol = tcp | udp | fwmโ the protocol to be used. If the virtual is specified as an IP address and port then it must be one oftcporudp๐ซถ if it's a firewall mark then the protocol must befwm. no mixing and matching bestie.
Default:
- Virtual is an IP address and port, and the port is not 53:
tcp - Virtual is an IP address and port, and the port is 53:
udp - Virtual is a firewall mark:
fwm
monitorfile = "/path/to/monitorfile"โ file to continuously log the real service checks to, for this virtual service ๐ this is so useful for monitoring when and why real services were down, or for statistics. obsessed honestly.
The log format is: [timestamp|pid|real_service_id|status|message]
Default: no separate logging of service checks. ๐
ops = yes | noโ specify that a virtual service uses one-packet scheduling ๐ฏ this option can be used only for UDP services (read that again, only UDP). If this option is specified, all connections are created only to schedule one packet. The option is useful to schedule UDP packets from the same client port to different real servers โจ kinda iconic ngl.servicename = short nameโ a name for this service ๐ธ this is for the sole purpose of making it easier to know which service is affected when e-mail notifications are sent out. It will be included in the e-mail subject and body ๐งcomment = commentโ notes about this service, included in e-mail notifications (for example, purpose of the service or the relevant administrator to contact) ๐ฌ
๐ IPv6 ๐
Directives for IPv6 are virtual6, real6, fallback6 ๐ IPv6 addresses specified for virtual6, real6, fallback6 and a file of maintenance directory should be enclosed by brackets ([2001:db8::abcd]:80) โ brackets are not optional, they're the whole vibe ๐
Following checktype and service are supported ๐
checktype:connect | external | external-perl | negotiate | off | on | checktimeoutNservice:dns | http | https | nntp | none | simpletcp | sip
๐ Note: when using a service type with http or https, you need to install the perl module perl-Net-INET6Glue. no module, no service, that's the rule fr fr ๐ญ
๐ FILES ๐
/etc/ha.d/ldirectord.cf/var/log/ldirectord.log/var/run/ldirectord.configuration.pid/etc/services
๐ SEE ALSO ๐
ipvsadm, heartbeat ๐ฆ
Ldirectord Web Page: http://www.vergenet.net/linux/ldirectord/ ๐
๐ AUTHORS ๐
- Horms
<horms@verge.net.au> - Jacob Rief
<jacob.rief@tiscover.com>
okay that's literally the whole page bestie, you ate that ๐
โจ this one's brought to you by perl v5.42.0, dated 2026-10-01, and it's LDIRECTORD(8) โ go forth and loadbalance, periodt ๐ซถ๐
๐ฆ where this page comes from
- opensuse-leap 16.0: ldirectord 4.18.0+git105.9ea1183-160000.1.1 ยท GPL-2.0-only AND LGPL-2.1-or-later
- opensuse-leap 16.0: ldirectord 4.18.0+git105.9ea1183-160000.1.1 ยท GPL-2.0-only AND LGPL-2.1-or-later
- opensuse-leap 16.0: ldirectord 4.18.0+git105.9ea1183-160000.1.1 ยท GPL-2.0-only AND LGPL-2.1-or-later
- opensuse-leap 16.0: ldirectord 4.18.0+git105.9ea1183-160000.1.1 ยท GPL-2.0-only AND LGPL-2.1-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms