conf: add directives to specify interfaces for binding sockets
Add binddevice, bindacqdevice, and bindcmddevice directive to specify the interface for binding the NTP server, NTP client, and command socket respectively.
This commit is contained in:
parent
4ef944b734
commit
c4a2550518
6 changed files with 96 additions and 12 deletions
6
cmdmon.c
6
cmdmon.c
|
@ -157,8 +157,8 @@ static void read_from_cmd_socket(int sock_fd, int event, void *anything);
|
|||
static int
|
||||
open_socket(int family)
|
||||
{
|
||||
const char *local_path, *iface;
|
||||
IPSockAddr local_addr;
|
||||
const char *local_path;
|
||||
int sock_fd, port;
|
||||
|
||||
switch (family) {
|
||||
|
@ -173,7 +173,9 @@ open_socket(int family)
|
|||
SCK_GetLoopbackIPAddress(family, &local_addr.ip_addr);
|
||||
local_addr.port = port;
|
||||
|
||||
sock_fd = SCK_OpenUdpSocket(NULL, &local_addr, NULL, SCK_FLAG_RX_DEST_ADDR);
|
||||
iface = CNF_GetBindCommandInterface();
|
||||
|
||||
sock_fd = SCK_OpenUdpSocket(NULL, &local_addr, iface, SCK_FLAG_RX_DEST_ADDR);
|
||||
if (sock_fd < 0) {
|
||||
LOG(LOGS_ERR, "Could not open command socket on %s",
|
||||
UTI_IPSockAddrToString(&local_addr));
|
||||
|
|
38
conf.c
38
conf.c
|
@ -192,6 +192,11 @@ static IPAddr bind_acq_address4, bind_acq_address6;
|
|||
the loopback address will be used */
|
||||
static IPAddr bind_cmd_address4, bind_cmd_address6;
|
||||
|
||||
/* Interface names to bind the NTP server, NTP client, and command socket */
|
||||
static char *bind_ntp_iface = NULL;
|
||||
static char *bind_acq_iface = NULL;
|
||||
static char *bind_cmd_iface = NULL;
|
||||
|
||||
/* Path to the Unix domain command socket. */
|
||||
static char *bind_cmd_path = NULL;
|
||||
|
||||
|
@ -422,6 +427,9 @@ CNF_Finalise(void)
|
|||
Free(keys_file);
|
||||
Free(leapsec_tz);
|
||||
Free(logdir);
|
||||
Free(bind_ntp_iface);
|
||||
Free(bind_acq_iface);
|
||||
Free(bind_cmd_iface);
|
||||
Free(bind_cmd_path);
|
||||
Free(ntp_signd_socket);
|
||||
Free(pidfile);
|
||||
|
@ -511,10 +519,16 @@ CNF_ParseLine(const char *filename, int number, char *line)
|
|||
parse_authselectmode(p);
|
||||
} else if (!strcasecmp(command, "bindacqaddress")) {
|
||||
parse_bindacqaddress(p);
|
||||
} else if (!strcasecmp(command, "bindacqdevice")) {
|
||||
parse_string(p, &bind_acq_iface);
|
||||
} else if (!strcasecmp(command, "bindaddress")) {
|
||||
parse_bindaddress(p);
|
||||
} else if (!strcasecmp(command, "bindcmdaddress")) {
|
||||
parse_bindcmdaddress(p);
|
||||
} else if (!strcasecmp(command, "bindcmddevice")) {
|
||||
parse_string(p, &bind_cmd_iface);
|
||||
} else if (!strcasecmp(command, "binddevice")) {
|
||||
parse_string(p, &bind_ntp_iface);
|
||||
} else if (!strcasecmp(command, "broadcast")) {
|
||||
parse_broadcast(p);
|
||||
} else if (!strcasecmp(command, "clientloglimit")) {
|
||||
|
@ -2228,6 +2242,30 @@ CNF_GetBindAcquisitionAddress(int family, IPAddr *addr)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
CNF_GetBindNtpInterface(void)
|
||||
{
|
||||
return bind_ntp_iface;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
CNF_GetBindAcquisitionInterface(void)
|
||||
{
|
||||
return bind_acq_iface;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
CNF_GetBindCommandInterface(void)
|
||||
{
|
||||
return bind_cmd_iface;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
CNF_GetBindCommandPath(void)
|
||||
{
|
||||
|
|
3
conf.h
3
conf.h
|
@ -79,6 +79,9 @@ extern void CNF_GetFallbackDrifts(int *min, int *max);
|
|||
extern void CNF_GetBindAddress(int family, IPAddr *addr);
|
||||
extern void CNF_GetBindAcquisitionAddress(int family, IPAddr *addr);
|
||||
extern void CNF_GetBindCommandAddress(int family, IPAddr *addr);
|
||||
extern char *CNF_GetBindNtpInterface(void);
|
||||
extern char *CNF_GetBindAcquisitionInterface(void);
|
||||
extern char *CNF_GetBindCommandInterface(void);
|
||||
extern char *CNF_GetBindCommandPath(void);
|
||||
extern char *CNF_GetNtpSigndSocket(void);
|
||||
extern char *CNF_GetPidFile(void);
|
||||
|
|
|
@ -630,7 +630,7 @@ This would change the source port used for client requests to UDP port 1123.
|
|||
You could then persuade the firewall administrator to open that port.
|
||||
|
||||
[[bindacqaddress]]*bindacqaddress* _address_::
|
||||
The *bindacqaddress* directive sets the network interface to which
|
||||
The *bindacqaddress* directive specifies a local IP address to which
|
||||
*chronyd* will bind its NTP client sockets. The syntax is similar to the
|
||||
<<bindaddress,*bindaddress*>> and <<bindcmdaddress,*bindcmdaddress*>>
|
||||
directives.
|
||||
|
@ -638,6 +638,19 @@ directives.
|
|||
For each of the IPv4 and IPv6 protocols, only one *bindacqaddress* directive
|
||||
can be specified.
|
||||
|
||||
[[bindacqdevice]]*bindacqdevice* _interface_::
|
||||
The *bindacqdevice* directive binds the client sockets to a network device
|
||||
specified by the interface name. This can be useful when the local address is
|
||||
dynamic, or to enable an NTP source specified with a link-local IPv6 address.
|
||||
This directive can specify only one interface and it is supported on Linux
|
||||
only.
|
||||
+
|
||||
An example of the directive is:
|
||||
+
|
||||
----
|
||||
bindacqdevice eth0
|
||||
----
|
||||
|
||||
[[dumpdir]]*dumpdir* _directory_::
|
||||
To compute the rate of gain or loss of time, *chronyd* has to store a
|
||||
measurement history for each of the time sources it uses.
|
||||
|
@ -1336,6 +1349,17 @@ Currently, for each of the IPv4 and IPv6 protocols, only one *bindaddress*
|
|||
directive can be specified. Therefore, it is not useful on computers which
|
||||
should serve NTP on multiple network interfaces.
|
||||
|
||||
[[binddevice]]*binddevice* _interface_::
|
||||
The *binddevice* directive binds the NTP server sockets to a network device
|
||||
specified by the interface name. This directive can specify only one interface
|
||||
and it is supported on Linux only.
|
||||
+
|
||||
An example of the directive is:
|
||||
+
|
||||
----
|
||||
binddevice eth0
|
||||
----
|
||||
|
||||
[[broadcast]]*broadcast* _interval_ _address_ [_port_]::
|
||||
The *broadcast* directive is used to declare a broadcast address to which
|
||||
chronyd should send packets in the NTP broadcast mode (i.e. make *chronyd* act
|
||||
|
@ -1664,8 +1688,8 @@ smoothtime 50000 0.01
|
|||
=== Command and monitoring access
|
||||
|
||||
[[bindcmdaddress]]*bindcmdaddress* _address_::
|
||||
The *bindcmdaddress* directive allows you to specify an IP address of an
|
||||
interface on which *chronyd* will listen for monitoring command packets (issued
|
||||
The *bindcmdaddress* directive specifies a local IP address to which *chronyd*
|
||||
will bind the UDP socket listening for monitoring command packets (issued
|
||||
by *chronyc*). On systems other than Linux, the address of the interface needs
|
||||
to be already configured when *chronyd* is started.
|
||||
+
|
||||
|
@ -1676,9 +1700,10 @@ directory will be created on start if it does not exist. The compiled-in default
|
|||
path of the socket is _@CHRONYRUNDIR@/chronyd.sock_. The socket can be
|
||||
disabled by setting the path to _/_.
|
||||
+
|
||||
By default, *chronyd* binds to the loopback interface (with addresses
|
||||
_127.0.0.1_ and _::1_). This blocks all access except from localhost. To listen
|
||||
for command packets on all interfaces, you can add the lines:
|
||||
By default, *chronyd* binds the UDP sockets to the addresses _127.0.0.1_ and
|
||||
_::1_ (i.e. the loopback interface). This blocks all access except from
|
||||
localhost. To listen for command packets on all interfaces, you can add the
|
||||
lines:
|
||||
+
|
||||
----
|
||||
bindcmdaddress 0.0.0.0
|
||||
|
@ -1696,6 +1721,17 @@ An example that sets the path of the Unix domain command socket is:
|
|||
bindcmdaddress /var/run/chrony/chronyd.sock
|
||||
----
|
||||
|
||||
[[bindcmddevice]]*bindcmddevice* _interface_::
|
||||
The *bindcmddevice* directive binds the UDP command sockets to a network device
|
||||
specified by the interface name. This directive can specify only one interface
|
||||
and it is supported on Linux only.
|
||||
+
|
||||
An example of the directive is:
|
||||
+
|
||||
----
|
||||
bindcmddevice eth0
|
||||
----
|
||||
|
||||
[[cmdallow]]*cmdallow* [*all*] [_subnet_]::
|
||||
This is similar to the <<allow,*allow*>> directive, except that it allows
|
||||
monitoring access (rather than NTP client access) to a particular subnet or
|
||||
|
|
10
ntp_io.c
10
ntp_io.c
|
@ -85,14 +85,18 @@ open_socket(int family, int local_port, int client_only, IPSockAddr *remote_addr
|
|||
{
|
||||
int sock_fd, sock_flags, events = SCH_FILE_INPUT;
|
||||
IPSockAddr local_addr;
|
||||
char *iface;
|
||||
|
||||
if (!SCK_IsIpFamilyEnabled(family))
|
||||
return INVALID_SOCK_FD;
|
||||
|
||||
if (!client_only)
|
||||
if (!client_only) {
|
||||
CNF_GetBindAddress(family, &local_addr.ip_addr);
|
||||
else
|
||||
iface = CNF_GetBindNtpInterface();
|
||||
} else {
|
||||
CNF_GetBindAcquisitionAddress(family, &local_addr.ip_addr);
|
||||
iface = CNF_GetBindAcquisitionInterface();
|
||||
}
|
||||
|
||||
if (local_addr.ip_addr.family != family)
|
||||
SCK_GetAnyLocalIPAddress(family, &local_addr.ip_addr);
|
||||
|
@ -103,7 +107,7 @@ open_socket(int family, int local_port, int client_only, IPSockAddr *remote_addr
|
|||
if (!client_only)
|
||||
sock_flags |= SCK_FLAG_BROADCAST;
|
||||
|
||||
sock_fd = SCK_OpenUdpSocket(remote_addr, &local_addr, NULL, sock_flags);
|
||||
sock_fd = SCK_OpenUdpSocket(remote_addr, &local_addr, iface, sock_flags);
|
||||
if (sock_fd < 0) {
|
||||
if (!client_only)
|
||||
LOG(LOGS_ERR, "Could not open NTP socket on %s", UTI_IPSockAddrToString(&local_addr));
|
||||
|
|
|
@ -442,7 +442,8 @@ SYS_Linux_DropRoot(uid_t uid, gid_t gid, int clock_control)
|
|||
Keep CAP_SYS_TIME if the clock control is enabled. */
|
||||
if (snprintf(cap_text, sizeof (cap_text), "%s %s %s",
|
||||
CNF_GetNTPPort() ? "cap_net_bind_service=ep" : "",
|
||||
0 ? "cap_net_raw=ep" : "",
|
||||
CNF_GetBindNtpInterface() || CNF_GetBindAcquisitionInterface() ?
|
||||
"cap_net_raw=ep" : "",
|
||||
clock_control ? "cap_sys_time=ep" : "") >= sizeof (cap_text))
|
||||
assert(0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue