summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2015-06-30 12:03:33 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2015-06-30 12:03:33 +0000
commit80d252a897910383dbba81611e33c0260703af2d (patch)
tree40853d2bca575b63a23595dbfcdc9176b76bf616
parent92df6b7e73db05570cf439bfee21b88d91dba36c (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.c4
-rw-r--r--usr.sbin/syslogd/syslogd.820
-rw-r--r--usr.sbin/syslogd/syslogd.c98
-rw-r--r--usr.sbin/syslogd/syslogd.h4
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;