diff --git a/man/syslogd.8 b/man/syslogd.8 index 6e5df9f..56f296d 100644 --- a/man/syslogd.8 +++ b/man/syslogd.8 @@ -13,7 +13,7 @@ .Nd System Log Daemon .Sh SYNOPSIS .Nm -.Op Fl ?46Adhnv +.Op Fl ?46Adhnsv .Op Fl b Ar addr[:port] .Op Fl b Ar :port .Op Fl f Ar file @@ -180,6 +180,10 @@ The size argument takes optional modifiers; k, M, G. E.g., 100M is The optional number of files kept include both gzipped files and the first rotated (not zipped) file. The default for this, when omitted, is 5. +.It Fl s +Operate in secure mode. Do not log messages from remote machines. If +specified twice, no network socket will be opened at all, which also +disables logging to remote machines. .It Fl v Print .Nm diff --git a/src/socket.c b/src/socket.c index dd279be..098da93 100644 --- a/src/socket.c +++ b/src/socket.c @@ -97,11 +97,14 @@ eaddr: free(entry); err: return -1; } -static int socket_opts(int sd, int family) +static int socket_opts(int sd, int family, int secure) { socklen_t len, slen; int on = 1; + if (secure) + goto skip; + /* * This first one is best-effort only, try to increase receive * buffer size. Alert user on failure and proceed. @@ -113,7 +116,7 @@ static int socket_opts(int sd, int family) ERR("Failed increasing size of socket receive buffer"); } - switch (family) { +skip: switch (family) { case AF_INET6: if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { ERR("setsockopt (IPV6_ONLY), suspending IPv6"); @@ -138,6 +141,7 @@ int socket_create(struct addrinfo *ai, void (*cb)(int, void *), void *arg) { struct sockaddr_un *sun = (struct sockaddr_un *)ai->ai_addr; mode_t mode = ai->ai_protocol; + int secure = ai->ai_flags & AI_SECURE; int type = ai->ai_socktype | SOCK_CLOEXEC | SOCK_NONBLOCK; int sd; @@ -150,13 +154,16 @@ int socket_create(struct addrinfo *ai, void (*cb)(int, void *), void *arg) if (sd < 0) return -1; - if (socket_opts(sd, ai->ai_family)) + if (socket_opts(sd, ai->ai_family, secure)) goto err; + if (secure) + goto skip; + if (bind(sd, ai->ai_addr, ai->ai_addrlen) < 0) goto err; - if (ai->ai_family == AF_UNIX) { +skip: if (ai->ai_family == AF_UNIX) { if (chmod(sun->sun_path, mode) < 0) goto err; } diff --git a/src/syslogd.c b/src/syslogd.c index 3b2c09a..f8ef157 100644 --- a/src/syslogd.c +++ b/src/syslogd.c @@ -127,6 +127,7 @@ static int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */ static int mask_C1 = 1; /* mask characters from 0x80 - 0x9F */ static int send_to_all; /* send message to all IPv4/IPv6 addresses */ static int MarkSeq = 0; /* mark sequence number */ +static int SecureMode; /* when true, receive only unix domain socks */ static int RemoteAddDate; /* Always set the date on remote messages */ static int RemoteHostname; /* Log remote hostname from the message */ @@ -191,8 +192,8 @@ static int addpeer(struct peer *pe0) int usage(int code) { printf("Usage:\n" - " syslogd [-46Adnrvh?] [-b :PORT] [-b ADDR[:PORT]] [-f FILE] [-m SEC]\n" - " [-P PID_FILE] [-p SOCK_PATH] [-R SIZE[:NUM]]\n" + " syslogd [-46Adnrsvh?] [-b :PORT] [-b ADDR[:PORT]] [-f FILE] [-m SEC]\n" + " [-P PID_FILE] [-p SOCK_PATH] [-R SIZE[:NUM]]\n" "\n" "Options:\n" " -4 Force IPv4 only\n" @@ -212,6 +213,9 @@ int usage(int code) " -R S[:R] Enable log rotation. The size argument (S) takes k/M/G qualifiers,\n" " e.g. 2M for 2 MiB. The optional rotations argument default to 5.\n" " Rotation can also be defined per log file in syslog.conf\n" + " -s Operate in secure mode, do not log messages from remote machines.\n" + " If specified twice, no socket at all will be opened, which also\n" + " disables support for logging to remote machines.\n" "\n" " -? Show this help text\n" " -v Show program version and exit\n" @@ -242,7 +246,7 @@ int main(int argc, char *argv[]) KeepKernFac = 1; #endif - while ((ch = getopt(argc, argv, "46Ab:dhHf:m:nP:p:R:v?")) != EOF) { + while ((ch = getopt(argc, argv, "46Ab:dhHf:m:nP:p:R:sv?")) != EOF) { switch ((char)ch) { case '4': family = PF_INET; @@ -312,6 +316,10 @@ int main(int argc, char *argv[]) parse_rotation(optarg, &RotateSz, &RotateCnt); break; + case 's': + SecureMode++; + break; + case 'v': printf("syslogd v%s\n", VERSION); exit(0); @@ -393,7 +401,7 @@ int main(int argc, char *argv[]) SIMPLEQ_FOREACH(pe, &pqueue, next) { if (pe->pe_name && pe->pe_name[0] == '/') create_unix_socket(pe); - else // XXX if (cffwd() && SecureMode <= 1) + else if (SecureMode < 2) create_inet_socket(pe); } @@ -540,6 +548,11 @@ static void create_inet_socket(struct peer *pe) } for (r = res; r; r = r->ai_next) { + if (SecureMode) + r->ai_flags |= AI_SECURE; + else + r->ai_flags &= ~AI_SECURE; + sd = socket_create(r, inet_cb, NULL); if (sd < 0) continue; @@ -1907,24 +1920,6 @@ void doexit(int signo) exit(0); } -/* - * Check active rules for action FWD - */ -static int cffwd(void) -{ - struct filed *f; - int fwd = 0; - - SIMPLEQ_FOREACH(f, &fhead, f_link) { - if (f->f_type == F_FORW || - f->f_type == F_FORW_SUSP || - f->f_type == F_FORW_UNKN) - fwd++; - } - - return fwd; -} - /* Create fallback .conf with err+panic sent to console */ static FILE *cftemp(void) { diff --git a/src/syslogd.h b/src/syslogd.h index 8c2b231..13b3f62 100644 --- a/src/syslogd.h +++ b/src/syslogd.h @@ -111,6 +111,8 @@ #define LIST_DELIMITER ':' /* delimiter between two hosts */ +#define AI_SECURE 0x8000 /* Tell socket_create() to not bind() */ + /* From The Practice of Programming, by Kernighan and Pike */ #ifndef NELEMS #define NELEMS(array) (sizeof(array) / sizeof(array[0])) diff --git a/syslogd.service.in b/syslogd.service.in index 5cc88cf..a91d1bb 100644 --- a/syslogd.service.in +++ b/syslogd.service.in @@ -6,7 +6,7 @@ Requires=syslog.socket [Service] Type=simple -ExecStart=@SBINDIR@/syslogd -n +ExecStart=@SBINDIR@/syslogd -sn StandardOutput=null Restart=on-failure