Skip to content

Commit

Permalink
scraps: +rsyslogs
Browse files Browse the repository at this point in the history
  • Loading branch information
mk-fg committed Oct 1, 2019
1 parent 2dc2d32 commit e75850e
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 0 deletions.
27 changes: 27 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3274,6 +3274,33 @@ useful for GUIs, alas.

.. _GPM: https://github.com/telmich/gpm

rsyslogs
^^^^^^^^

Wrappers to test tools that tend to spam /dev/log regardless of their settings.

rsyslogs.c is a SUID wrapper binary that uses mount --bind + unshare to replace
/dev/log with /dev/null within namespace where it'd run rsyslog, and is made to
silence rsyslogd in particular.

Example use (see also top of rsyslogs.c itself)::

% gcc -O2 -o rsyslogs scraps/rsyslogs.c && strip rsyslogs
% sudo chown root:user rsyslogs && sudo chmod 4110 rsyslogs
% cp scraps/rsyslogs.conf rsyslog.conf
% ./rsyslogs

rsyslogs.ldpreload.c is an LD_PRELOAD wrapper suitable for simplier
single-process tools (e.g. "logger") where it's enough to override
connect/sendto/sendmsg and such::

% gcc -nostartfiles -fpic -shared -ldl -D_GNU_SOURCE rsyslogs.ldpreload.c -o sd.so
% LD_PRELOAD=./sd.so logger test

Use something like these occasionally when setting up logging on a dev machine,
where such uncommon spam to syslog gets delivered via desktop notifications
(see desktop/notifications/logtail tool in this repo) and annoys me.


License (WTFPL)
---------------
Expand Down
38 changes: 38 additions & 0 deletions scraps/rsyslogs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// SUID wrapper to prevent rsyslog from using /dev/log via unshare.
// Simple suid unshare leaves real-uid as-is and mount checks that and fails.
//
// build: gcc -O2 -o rsyslogs rsyslogs.c && strip rsyslogs
// perms: chown root:user rsyslogs && chmod 4110 rsyslogs
// run: ./rsyslogs

int main(int argc, char **argv) {
clearenv();
int uid;

if (argc == 1) {
// unshare part
uid = getuid();
if (setreuid(0, 0)) exit(135);
int n, bin_len = 250; char bin[bin_len]; char cmd[bin_len];
if ((n = readlink("/proc/self/exe", bin, bin_len)) > 0) {
bin[n] = 0;
n = sprintf( cmd,
"mount -o bind /dev/null /dev/log"
" && exec %s rsyslog %d", bin, uid ); }
if (n < 0) exit(135);
execl("/usr/bin/unshare", "unshare", "-m", "sh", "-c", cmd, NULL);
exit(135); }

// rsyslog part
if (argc < 3 || strcmp(argv[1], "rsyslog")) exit(136);
if (!(uid = atoi(argv[2]))) exit(136);
if (setreuid(uid, uid)) exit(137);
execl( "/usr/bin/rsyslogd",
"rsyslogd", "-n", "-iNONE", "-f", "rsyslog.conf", NULL );
exit(138);
}
74 changes: 74 additions & 0 deletions scraps/rsyslogs.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
### Init

$AbortOnUncleanConfig on
$ErrorMessagesToStderr on
$RepeatedMsgReduction off
$PreserveFQDN off
$ActionResumeInterval 30
$ActionResumeRetryCount -1

global(shutdown.enable.ctlc="on")

template(name="stdlog" type="list") {
property(name="timereported" dateFormat="rfc3339")
constant(value=" ")

property(name="pri-text")
constant(value=" ")
property(name="programname")
constant(value="[")
property(name="procid")
constant(value="]:")

# See sp-if-no-1st-sp in http://www.rsyslog.com/doc/v8-stable/configuration/property_replacer.html
property(name="msg" spifno1stsp="on")
property(name="msg" droplastlf="on")
constant(value="\n")
}

$ActionFileDefaultTemplate stdlog

# module(
# load="builtin:omfile"
# fileOwner="root" fileGroup="wheel" fileCreateMode="0640"
# dirOwner="root" dirGroup="wheel" dirCreateMode="0750")
module(load="imfile")
module(load="omprog")


### Inputs

# module(load="imklog")

# module(
# load="imuxsock"
# SysSock.RateLimit.Interval="0"
# SysSock.UsePIDFromSystem="on")
# input(
# type="imuxsock"
# Socket="/dev/log")

input(
type="imfile"
File="/tmp/syslog.in"
Tag="myapp:"
Severity="notice"
Facility="local4")


### Outputs
# http://www.rsyslog.com/regex/

# if ($programname == "event-gen" and $msg startswith ' INFO :: --event-csv: ') then {
# action(type="omfile" file="/some/path/events.csv" template="csv")
# stop
# }

## Non-piped/rotated logs tend to be filled with debug info way too quickly, causing problems
action(type="omfile" file="/tmp/syslog.out")

# Note: busybox also has svlogd for this
# # 4M x 10 = 0-50M in current + 0-10 files
# action(type="omprog" signalOnClose="on" binary="/usr/bin/tinylog -s4194304 -k10 /boot/fat/syslog")
# # 10M x 10 = 0-100M in current + 0-10 files (gzipped)
# action(type="omprog" signalOnClose="on" binary="/usr/bin/tinylog -s10485760 -k10 -z /var/log/syslog")
55 changes: 55 additions & 0 deletions scraps/rsyslogs.ldpreload.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
LD_PRELOAD library to disable syslog() call, overriding it with no-op.
Use-case is testing apps without them spamming local syslog.
Compile with:
gcc -nostartfiles -fpic -shared \
-ldl -D_GNU_SOURCE rsyslogs.ldpreload.c -o sd.so
Usage: LD_PRELOAD=./sd.so logger test
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <errno.h>

#include <sys/socket.h>


int (*real_connect)(int, const struct sockaddr *, socklen_t);
int (*real_sendto)( int fd, const void *message,
size_t length, int flags, const struct sockaddr *sk, socklen_t dest_len );
int (*real_sendmsg)(int fd, const struct msghdr *msg, int flags);

void _init(void) {
const char *err;
real_connect = dlsym(RTLD_NEXT, "connect");
if ((err = dlerror()) != NULL) fprintf(stderr, "dlsym (connect): %s\n", err);
real_sendto = dlsym(RTLD_NEXT, "sendto");
if ((err = dlerror()) != NULL) fprintf(stderr, "dlsym (sendto): %s\n", err);
real_sendmsg = dlsym(RTLD_NEXT, "sendmsg");
if ((err = dlerror()) != NULL) fprintf(stderr, "dlsym (sendmsg): %s\n", err);
}


int dev_log_fd = 0;

int connect(int fd, const struct sockaddr *addr, socklen_t addr_len) {
if (addr->sa_family == AF_UNIX && !strcmp(addr->sa_data, "/dev/log"))
{ dev_log_fd = fd; return 0; }
return real_connect(fd, addr, addr_len);
}

ssize_t sendto(
int fd, const void *message, size_t length,
int flags, const struct sockaddr *sk, socklen_t dest_len ) {
if (dev_log_fd && fd == dev_log_fd) return length;
return real_sendto(fd, message, length, flags, sk, dest_len);
}

ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
if (dev_log_fd && fd == dev_log_fd) return msg->msg_iovlen;
return real_sendmsg(fd, msg, flags);
}

0 comments on commit e75850e

Please sign in to comment.