Howto log multiple sftpd instances with their chroot shared via NFS

Peter Stuge peter at stuge.se
Sat Sep 25 07:36:00 AEST 2021


Hi Hildegard,

Hildegard Meier wrote:
> I think, the sftpd process should just not write to the /dev/log
> unix socket (because this leads to the problem here), but to the
> local kernel directly, something like what you describe here.

Exactly, but unfortunately the code that sets the socket path is in
the system C library, without any interface to control the setting.


> But how could I do this concrete with Ubuntu Linux? What you write
> is rather abstract and I am not so expert that I understand what
> you mean with LD_PRELOAD wrapper.

Setting the LD_PRELOAD environment variable to a library filename when
starting a program loads that library into memory before the system C
library and the program itself. Symbols (ie. functions) loaded from
the preloaded library are not replaced by later (system) libraries,
making it possible to override and/or wrap libc functionality in this
fairly brutish way, hence a bit unpleasant.

Attached is source code for a simple such wrapper overriding openlog(),
syslog() and closelog(). It might work only on the older system, or on
both. You only need this hack on one server, the other can use /dev/log.

The wrapper directs logging to /dev/log_<hostname> instead of /dev/log.
Since libc has no interface to manipulate the socket path these functions
override the normal functions with a very limited implementation.
Adjust the template on line 49 if you want to change the destinateion.

Although functionality is limited it could work well for sftp-server.

One simplification is that this openlog() ignores all option flags
except LOG_NDELAY and that syslog() always behaves as if openlog() was
called with the LOG_PID option. Since this is exactly what OpenSSH log.c
does all log messages should look the same as with the libc implementation.

Note that log messages are silently lost on any error, e.g. syslog-ng
not running. Also note that if log messages, the openlog() ident
parameter or the username (when ident == NULL) are very long then
messages are silently truncated to 2048 chars. OpenSSH sends max 500
chars.


You didn't mention if your two sshd are configured to use the in-process
sftp-server (Subsystem sftp internal-sftp in sshd_config) - if so then
this is probably not really the best solution, since LD_PRELOAD would
have to be set for the entire sshd process, which I don't recommend
because this code is so simplistic compared to libc.

Anyway, try it if you like.


The comment near the top of the file shows how to compile. sshd can't
be configured to set LD_PRELOAD so to use the compiled .so with
sftp-server you have to create a simple script:

--8<-- /usr/local/libexec/sftp-server-hostlog
#!/bin/sh
export LD_PRELOAD=/usr/local/libexec/hostlog.so
exec /usr/lib/sftp-server "$*"
-->8--

and then configure sshd to call that instead of sftp-server:

--8<-- /etc/ssh/sshd_config
Subsystem sftp /usr/local/libexec/sftp-server-hostlog
-->8--

Adjust paths as needed, also in the compile command.


For anyone else interested please go ahead but note that I haven't
put huge effort into portability; it might work outside Linux but
I haven't tested anywhere else so YMMV.


Kind regards

//Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hostlog.c
Type: text/x-c
Size: 2359 bytes
Desc: not available
URL: <http://lists.mindrot.org/pipermail/openssh-unix-dev/attachments/20210924/2ded19a4/attachment-0001.c>


More information about the openssh-unix-dev mailing list