Hi,
I have added a -U feature 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 different port.
My plan is to extend the interface with -T listen_address:port to
receive syslog via TCP.
ok?
bluhm
Index: usr.sbin/syslogd/privsep.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.51
diff -u -p -r1.51 privsep.c
--- usr.sbin/syslogd/privsep.c 19 Jan 2015 16:40:49 -0000 1.51
+++ usr.sbin/syslogd/privsep.c 25 Jun 2015 20:03:17 -0000
@@ -186,6 +186,8 @@ priv_init(char *conf, int numeric, int l
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]);
Index: usr.sbin/syslogd/syslogd.8
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.8,v
retrieving revision 1.35
diff -u -p -r1.35 syslogd.8
--- usr.sbin/syslogd/syslogd.8 15 Jun 2015 22:39:14 -0000 1.35
+++ usr.sbin/syslogd/syslogd.8 25 Jun 2015 19:48:21 -0000
@@ -111,6 +111,19 @@ 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 an UDP socket for receiving messages and bind it to the
+specified address.
+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
Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.164
diff -u -p -r1.164 syslogd.c
--- usr.sbin/syslogd/syslogd.c 15 Jun 2015 21:42:15 -0000 1.164
+++ usr.sbin/syslogd/syslogd.c 25 Jun 2015 19:49:00 -0000
@@ -218,6 +218,8 @@ int NoDNS = 0; /* when true, will refra
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 */
@@ -274,9 +276,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 *);
@@ -313,7 +315,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);
@@ -329,7 +331,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;
@@ -366,6 +368,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;
@@ -424,8 +431,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);
@@ -475,6 +481,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
@@ -609,6 +673,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]);
@@ -659,6 +724,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);
@@ -974,7 +1041,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);
}
@@ -1943,7 +2011,7 @@ cfline(char *line, char *prog)
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);
@@ -2157,15 +2225,21 @@ cfline(char *line, char *prog)
* 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)++;
Index: usr.sbin/syslogd/syslogd.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.h,v
retrieving revision 1.16
diff -u -p -r1.16 syslogd.h
--- usr.sbin/syslogd/syslogd.h 5 Oct 2014 18:14:01 -0000 1.16
+++ usr.sbin/syslogd/syslogd.h 25 Jun 2015 21:54:42 -0000
@@ -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;