diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-06-30 12:03:33 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-06-30 12:03:33 +0000 |
commit | 80d252a897910383dbba81611e33c0260703af2d (patch) | |
tree | 40853d2bca575b63a23595dbfcdc9176b76bf616 | |
parent | 92df6b7e73db05570cf439bfee21b88d91dba36c (diff) |
Add a -U command line switch for syslogd to specify an explict bind
address to receive UDP packets. One advantge over -u and the *
sockets is that you can bind to localhost and divert the packets
with pf. It is also possible to use a non standard port.
OK jung@ jmc@
-rw-r--r-- | usr.sbin/syslogd/privsep.c | 4 | ||||
-rw-r--r-- | usr.sbin/syslogd/syslogd.8 | 20 | ||||
-rw-r--r-- | usr.sbin/syslogd/syslogd.c | 98 | ||||
-rw-r--r-- | usr.sbin/syslogd/syslogd.h | 4 |
4 files changed, 109 insertions, 17 deletions
diff --git a/usr.sbin/syslogd/privsep.c b/usr.sbin/syslogd/privsep.c index 49c66b5cbbb..4b637061b30 100644 --- a/usr.sbin/syslogd/privsep.c +++ b/usr.sbin/syslogd/privsep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.c,v 1.51 2015/01/19 16:40:49 bluhm Exp $ */ +/* $OpenBSD: privsep.c,v 1.52 2015/06/30 12:03:32 bluhm Exp $ */ /* * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org> @@ -186,6 +186,8 @@ priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[]) close(fd_udp); if (fd_udp6 != -1) close(fd_udp6); + if (fd_bind != -1) + close(fd_bind); for (i = 0; i < nunix; i++) if (fd_unix[i] != -1) close(fd_unix[i]); diff --git a/usr.sbin/syslogd/syslogd.8 b/usr.sbin/syslogd/syslogd.8 index 16291073b77..3ecc9e32f3a 100644 --- a/usr.sbin/syslogd/syslogd.8 +++ b/usr.sbin/syslogd/syslogd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: syslogd.8,v 1.35 2015/06/15 22:39:14 jmc Exp $ +.\" $OpenBSD: syslogd.8,v 1.36 2015/06/30 12:03:32 bluhm Exp $ .\" .\" Copyright (c) 1983, 1986, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -30,7 +30,7 @@ .\" from: @(#)syslogd.8 8.1 (Berkeley) 6/6/93 .\" $NetBSD: syslogd.8,v 1.3 1996/01/02 17:41:48 perry Exp $ .\" -.Dd $Mdocdate: June 15 2015 $ +.Dd $Mdocdate: June 30 2015 $ .Dt SYSLOGD 8 .Os .Sh NAME @@ -46,6 +46,7 @@ .Op Fl m Ar mark_interval .Op Fl p Ar log_socket .Op Fl s Ar reporting_socket +.Op Fl U Ar bind_address .Ek .Sh DESCRIPTION .Nm @@ -111,6 +112,21 @@ Specify path to an .Dv AF_LOCAL socket for use in reporting logs stored in memory buffers using .Xr syslogc 8 . +.It Fl U Ar bind_address +Create a UDP socket for receiving messages and bind it to the +specified address. +This can be used, for example, with a pf divert-to rule to receive +packets when syslogd is bound to localhost. +A port number may be specified using the +.Ar host:port +syntax. +IPv6 addresses can be used by surrounding the address portion with +square brackets +.Po +.Ql [\& +and +.Ql ]\& +.Pc . .It Fl u Select the historical .Dq insecure diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index 8477ae189f8..bd91a00e884 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syslogd.c,v 1.165 2015/06/29 11:04:28 bluhm Exp $ */ +/* $OpenBSD: syslogd.c,v 1.166 2015/06/30 12:03:32 bluhm Exp $ */ /* * Copyright (c) 1983, 1988, 1993, 1994 @@ -219,6 +219,8 @@ int NoDNS = 0; /* when true, will refrain from doing DNS lookups */ int IPv4Only = 0; /* when true, disable IPv6 */ int IPv6Only = 0; /* when true, disable IPv4 */ int IncludeHostname = 0; /* include RFC 3164 style hostnames when forwarding */ +char *bind_host = NULL; +char *bind_port = NULL; char *path_ctlsock = NULL; /* Path to control socket */ @@ -275,9 +277,9 @@ char *linebuf; int linesize; int fd_ctlsock, fd_ctlconn, fd_klog, fd_sendsys, - fd_udp, fd_udp6, fd_unix[MAXUNIX]; + fd_udp, fd_udp6, fd_bind, fd_unix[MAXUNIX]; struct event ev_ctlaccept, ev_ctlread, ev_ctlwrite, ev_klog, ev_sendsys, - ev_udp, ev_udp6, ev_unix[MAXUNIX], + ev_udp, ev_udp6, ev_bind, ev_unix[MAXUNIX], ev_hup, ev_int, ev_quit, ev_term, ev_mark; void klog_readcb(int, short, void *); @@ -314,7 +316,7 @@ void printsys(char *); char *ttymsg(struct iovec *, int, char *, int); void usage(void); void wallmsg(struct filed *, struct iovec *); -int loghost(char *, char **, char **, char **); +int loghost_parse(char *, char **, char **, char **); int getmsgbufsize(void); int unix_socket(char *, int, mode_t); void double_rbuf(int); @@ -330,7 +332,7 @@ main(int argc, char *argv[]) int ch, i; int lockpipe[2] = { -1, -1}, pair[2], nullfd, fd; - while ((ch = getopt(argc, argv, "46C:dhnuf:Fm:p:a:s:V")) != -1) + while ((ch = getopt(argc, argv, "46C:dhnuf:Fm:p:a:s:U:V")) != -1) switch (ch) { case '4': /* disable IPv6 */ IPv4Only = 1; @@ -367,6 +369,11 @@ main(int argc, char *argv[]) case 'p': /* path */ path_unix[0] = optarg; break; + case 'U': /* allow udp only from address */ + if (loghost_parse(optarg, NULL, &bind_host, &bind_port) + == -1) + errx(1, "bad bind address: %s", optarg); + break; case 'u': /* allow udp input port */ SecureMode = 0; break; @@ -425,8 +432,7 @@ main(int argc, char *argv[]) hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; - i = getaddrinfo(NULL, "syslog", &hints, &res0); - if (i) { + if (getaddrinfo(NULL, "syslog", &hints, &res0)) { errno = 0; logerror("syslog/udp: unknown service"); die(0); @@ -476,6 +482,64 @@ main(int argc, char *argv[]) freeaddrinfo(res0); + fd_bind = -1; + if (bind_host) { + if (bind_port == NULL) + bind_port = "syslog"; + if (getaddrinfo(bind_host, bind_port, &hints, &res0)) { + errno = 0; + logerror("syslog/udp: unknown bind address"); + die(0); + } + + for (res = res0; res; res = res->ai_next) { + switch (res->ai_family) { + case AF_INET: + if (IPv6Only) + continue; + break; + case AF_INET6: + if (IPv4Only) + continue; + break; + default: + continue; + } + + fd_bind = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (fd_bind == -1) + continue; + + i = 1; + if (setsockopt(fd_bind, SOL_SOCKET, SO_REUSEADDR, + &i, sizeof(i)) == -1) { + logerror("setsockopt udp"); + close(fd_bind); + fd_bind = -1; + if (!Debug) + die(0); + continue; + } + if (bind(fd_bind, res->ai_addr, res->ai_addrlen) < 0) { + logerror("bind udp"); + close(fd_bind); + fd_bind = -1; + if (!Debug) + die(0); + continue; + } + double_rbuf(fd_bind); + break; + } + if (fd_bind == -1) { + logerror("socket udp"); + die(0); + } + + freeaddrinfo(res0); + } + #ifndef SUN_LEN #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) #endif @@ -610,6 +674,7 @@ main(int argc, char *argv[]) &ev_sendsys); event_set(&ev_udp, fd_udp, EV_READ|EV_PERSIST, udp_readcb, &ev_udp); event_set(&ev_udp6, fd_udp6, EV_READ|EV_PERSIST, udp_readcb, &ev_udp6); + event_set(&ev_bind, fd_bind, EV_READ|EV_PERSIST, udp_readcb, &ev_bind); for (i = 0; i < nunix; i++) event_set(&ev_unix[i], fd_unix[i], EV_READ|EV_PERSIST, unix_readcb, &ev_unix[i]); @@ -660,6 +725,8 @@ main(int argc, char *argv[]) if (fd_udp6 != -1) event_add(&ev_udp6, NULL); } + if (fd_bind != -1) + event_add(&ev_bind, NULL); for (i = 0; i < nunix; i++) if (fd_unix[i] != -1) event_add(&ev_unix[i], NULL); @@ -975,7 +1042,8 @@ usage(void) (void)fprintf(stderr, "usage: syslogd [-46dFhnuV] [-a path] [-C CAfile] [-f config_file]\n" - " [-m mark_interval] [-p log_socket] [-s reporting_socket]\n"); + " [-m mark_interval] [-p log_socket] [-s reporting_socket]\n" + " [-U bind_address]\n"); exit(1); } @@ -1981,7 +2049,7 @@ cfline(char *line, char *progblock, char *hostblock) logerror(ebuf); break; } - if (loghost(++p, &proto, &host, &port) == -1) { + if (loghost_parse(++p, &proto, &host, &port) == -1) { snprintf(ebuf, sizeof(ebuf), "bad loghost \"%s\"", f->f_un.f_forw.f_loghost); logerror(ebuf); @@ -2195,15 +2263,21 @@ cfline(char *line, char *progblock, char *hostblock) * Parse the host and port parts from a loghost string. */ int -loghost(char *str, char **proto, char **host, char **port) +loghost_parse(char *str, char **proto, char **host, char **port) { - *proto = NULL; + char *prefix = NULL; + if ((*host = strchr(str, ':')) && (*host)[1] == '/' && (*host)[2] == '/') { - *proto = str; + prefix = str; **host = '\0'; str = *host + 3; } + if (proto) + *proto = prefix; + else if (prefix) + return (-1); + *host = str; if (**host == '[') { (*host)++; diff --git a/usr.sbin/syslogd/syslogd.h b/usr.sbin/syslogd/syslogd.h index a64e1fe7fe3..04d64555946 100644 --- a/usr.sbin/syslogd/syslogd.h +++ b/usr.sbin/syslogd/syslogd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syslogd.h,v 1.16 2014/10/05 18:14:01 bluhm Exp $ */ +/* $OpenBSD: syslogd.h,v 1.17 2015/06/30 12:03:32 bluhm Exp $ */ /* * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org> @@ -44,7 +44,7 @@ extern int nunix; extern char *path_unix[MAXUNIX]; extern char *path_ctlsock; extern int fd_ctlsock, fd_ctlconn, fd_klog, fd_sendsys; -extern int fd_udp, fd_udp6, fd_unix[MAXUNIX]; +extern int fd_udp, fd_udp6, fd_bind, fd_unix[MAXUNIX]; #define dprintf(_f...) do { if (Debug) printf(_f); } while (0) extern int Debug; |