[comp.unix.wizards] syslog + chroot + ftpd

luis@lutetia.rice.edu (Luis Soltero) (07/28/90)

has anyone noticed that syslog stops logging when ftpd logs in an
anonymous ftp user?  i have tracked the problem to the chroot system
call. prior to chroot() syslog works as advertized. once the chroot()
is executed inside tftpd, however, syslog calls no longer get
recorded. 

any ideas?

here are some system specifics.
	sunOS 4.0.3
	bsd ftpd 4.xx or sunof ftpd


--luis@rice.edu

guy@auspex.auspex.com (Guy Harris) (07/29/90)

>has anyone noticed that syslog stops logging when ftpd logs in an
>anonymous ftp user?  i have tracked the problem to the chroot system
>call. prior to chroot() syslog works as advertized. once the chroot()
>is executed inside tftpd, however, syslog calls no longer get
>recorded. 

The 4.3BSD "syslog()" (as appears in SunOS 4.0, among other systems)
connects to "syslogd" using a UNIX-domain socket.  Do a "chroot()", and
that UNIX-domain socket may no longer be accessible....

I seem to remember much discussion of fixes to this problem at one
point; I no longer remember what conclusions were drawn, if any.

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (07/29/90)

In article <LUIS.90Jul27181155@lutetia.rice.edu> luis@lutetia.rice.edu (Luis Soltero) writes:
  [ on a Sun ]
> has anyone noticed that syslog stops logging when ftpd logs in an
> anonymous ftp user?

syslog's poor model has ftp writing to a UNIX-domain socket in the
filesystem. Naturally, ftp can't find the file after it chroots. Try
hardlinking in a new /dev/log (I think) below ftp's home directory.

If error messages were piped out stderr to an error-handling program,
these problems would never happen.

---Dan

jik@athena.mit.edu (Jonathan I. Kamens) (07/30/90)

In article <LUIS.90Jul27181155@lutetia.rice.edu>, luis@lutetia.rice.edu
(Luis Soltero) writes:
|> has anyone noticed that syslog stops logging when ftpd logs in an
|> anonymous ftp user?  i have tracked the problem to the chroot system
|> call. prior to chroot() syslog works as advertized. once the
chroot()
|> is executed inside tftpd, however, syslog calls no longer get
|> recorded. 

In article <3787@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris)
writes:
|> The 4.3BSD "syslog()" (as appears in SunOS 4.0, among other systems)
|> connects to "syslogd" using a UNIX-domain socket.  Do a "chroot()",
and
|> that UNIX-domain socket may no longer be accessible....

And finally, In article <29159:Jul2820:23:5290@kramden.acf.nyu.edu>,
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
|> syslog's poor model has ftp writing to a UNIX-domain socket in the
|> filesystem. Naturally, ftp can't find the file after it chroots. Try
|> hardlinking in a new /dev/log (I think) below ftp's home directory.
|> 
|> If error messages were piped out stderr to an error-handling
program,
|> these problems would never happen.

  Both Guy and Dan are correct in essence about the cause of the
problem, which is (in more detail) that when the 4.3BSD syslog() sends
messages to /dev/log by doing a sendto() on an unconnected socket,
rather than doing connect() when openlog() is called so that the program
has an idea of where messages should be sent, even after a chroot().

  Dan's first suggested solution will work for the special case of
ftpd's chroot() for anonymous ftp, but will not work for the general
case of other programs which do a chroot().

  The BSD networking release sources (and thus, I assume, the 4.4BSD
sources) solve this problem by doing a connect() to /dev/log the first
time logging is done (or when openlog() is called), so that the program
knows where to send messages even after the chroot().  If you can get
your hands on this version of the syslog library code (it may be
available on uunet.uu.net, or, if you have a BSD source license, you
should be able to get it from BSD), you can install it in your C library
and relink ftpd to get rid of the problem.

  Dan's second suggested solution is, as is somewhat usual for Dan :-),
a condemnation of a particular feature of Unix simply because he
believes that it's "the wrong way to do things."  Whether or not said
condemnation is correct, it holds little weight in my mind when
presented as an unsupported assertion.  In any case, I disagree with it,
and think that the syslog system is useful in ways that "an
error-handling program" on stderr would not be.

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (07/31/90)

In article <1990Jul29.202447.11548@athena.mit.edu>
jik@athena.mit.edu (Jonathan I. Kamens) writes [ trimmed & reordered ]:
> In article <29159:Jul2820:23:5290@kramden.acf.nyu.edu>,
> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> |> syslog's poor model has ftp writing to a UNIX-domain socket in the
> |> filesystem. Naturally, ftp can't find the file after it chroots. Try
> |> hardlinking in a new /dev/log (I think) below ftp's home directory.
>   Dan's first suggested solution will work for the special case of
> ftpd's chroot() for anonymous ftp, but will not work for the general
> case of other programs which do a chroot().

But it is the only solution for someone who doesn't want to muck with
his libraries, or for someone without source code, or for someone who
doesn't want to spend half an hour working bugs out of new BSD stuff.
In other words, theory is nice, but I think Luis wanted practice.

> |> If error messages were piped out stderr to an error-handling program,
> |> these problems would never happen.
>   Dan's second suggested solution is, as is somewhat usual for Dan :-),
> a condemnation of a particular feature of Unix simply because he
> believes that it's "the wrong way to do things."  Whether or not said
> condemnation is correct, it holds little weight in my mind when
> presented as an unsupported assertion.

Say what? I believe that good old stderr is a much better model than
syslog(), and I supported my assertion by pointing out that it would
solve problems like this.

> In any case, I disagree with it,
> and think that the syslog system is useful in ways that "an
> error-handling program" on stderr would not be.

Now you're making unsupported assertions. In what conceivable way can
syslog() do better than stderr? We could settle on some conventions for
standard error message formats, then make programs to interpret them in
different ways. This is obviously much more general and flexible than
syslog: you can change what's done with a program's errors simply by
editing a command line. You don't have to futz with syslogd, edit any
configuration files, stick new 'n' important special files into your
system, or conform to the facility-level-file model of error handling.
In the future we'll get backward compatibility trivially, rather than by
leaving obsolete daemons, /dev/log, and similar clutter around.

---Dan

jik@athena.mit.edu (Jonathan I. Kamens) (07/31/90)

In article <11477:Jul3018:50:4290@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
|> Now you're making unsupported assertions. In what conceivable way can
|> syslog() do better than stderr?

  You seem to be suggesting that all programs output errors to stderr, and
daemons that need to do some sort of logging have their stderr piped through a
program that knows how to process those error messages.

  There are a few things right off the top of my head that I see wrong with
this scheme:

1. It requires an extra process running for every daemon that's going to spit
   out errors.  Maybe that's no big deal for you, but my workstation has
   enough daemons running in the background right now, without an extra one
   tacked on for every daemon I'm running now.

2. It eliminates one channel of communication between the program and the
   outside world.  Currently, daemons have stdout, stderr, and syslog().  You
   propose to reduce them to stdout and stderr.

3. Under your scheme, every time I start up a process that I want to log
   messages, I have to pipe its stderr though this logging process of yours. 
   I often start up processes of this sort from the shell, e.g. if I'm
   restarting named after changing one of its config files.  To be honest, I
   don't want to be bothered remembering to do "(named > /dev/null) |&
   /usr/bin/logerrors" (yes, I use csh :-) every time I start it, rather than
   just doing "named" and knowing that it's smart enough to know how to get
   its logging messages to where they belong.

4. There are some programs that run interactively that need to be able to
   both output errors to stderr to the users and to log messages in the system
   logs.  For example, su.  How would su print error messages if it couldn't
   use stderr because it was piped through an error logging program.
   Furthermore, are you going to require users to type "su | logerrors" just
   to make sure that their su attempts get logged?  And, of course, if they
   *don't* type that, does that mean they can su without it getting logged
   anywhere?

5. To generalize (3) and (4) above, the syslog() mechanism is controlled by
   the system.  Stdin, stdout and stderr are controlled by the user.  There
   has to be a way for programs to log things in a way that is guaranteed to
   get them logged (as long as the syslogd is running, of course, and it
   should be running all the time), no matter where stderr points.

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

tchrist@convex.COM (Tom Christiansen) (07/31/90)

In article <11477:Jul3018:50:4290@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>In what conceivable way can syslog() do better than stderr? 

Syslogd(8) from BSD4.3 is a highly useful general purpose error
handling facility.  It solves numerous problems that crop up from 
ad hoc error logging.  See Eric Allmen's article in the C Advisor
column of UNIX REVIEW for the author's perspective.   Here are
the things that come immediately to my mind:

    * It allows the sysmgr to centrally control what kinds of error
      messages he's interested in, which can be configured to go to 
	  the console
	  files
	  biff sysadmins
	  be forwarded to master log hosts, 
	    which can in turn send to console, files, people, hosts

      These can be used separately or in conjunction (multiple
      destinations), and can be tuned/tweaked according to priority and
      facility class.

    * You don't have to constantly re-invent logging code.  You don't
      have to be careful about opens on the console blocking due to
      control-s or whatnot and hanging YOUR program.  You don't have to be
      careful about remembering to use O_APPEND.  Programmers tend to
      forget things like these.

    * The kernel, C programs, and scripts can all use the same logging facility.  
      This is really neat, although I wish the kernel wouldn't use the same priority 
      in all cases.  You can get at it through both the library interface syslog(3)
      and the script interface of logger(1).

    * You don't have to remember to properly redirect standard error when 
      you start or restart a daemon.  Too often /etc/rc lines just read
	    daemon > /dev/console & echo -n " daemon" > /dev/console
      which means you forgot stderr, plus you can't check it out from 
      your terminal, plus the output is lost except perhaps to hard copy.
      Starting them from your own terminal would have the same problems.


In summary, just writing to stderr is a practice fraught with the danger
of doing it wrong, does not permit easy and fine-grained configurability.
Syslog can be used by all forms of programs, encourages code sharing and a
common interface, and allows you to easily write summarization scripts.

Stderr writing is a bad practice that should shrivel up and die.

I guess this is why we need a comp.unix.admin newsgroup.

--tom
--

    Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
    Convex Computer Corporation                            tchrist@convex.COM
		 "EMACS belongs in <sys/errno.h>: Editor too big!"

jeff@onion.pdx.com (Jeff Beadles) (08/01/90)

luis@lutetia.rice.edu (Luis Soltero) writes:

>has anyone noticed that syslog stops logging when ftpd logs in an
>anonymous ftp user?  i have tracked the problem to the chroot system
>call. prior to chroot() syslog works as advertized. once the chroot()
>is executed inside tftpd, however, syslog calls no longer get
>recorded. 

>any ideas?

Yes, I've seen this many a time.  The problem is that /dev/log can not be
accessed after the chroot.

Here's what I've done to work around it here...

Reboot, and stop the boot process in single user mode.

( replace /usr2/ftp with the home directory of your ftp account)

Then,
% rm -f /dev/log
% mkdir /usr2/ftp/dev
% chmod 711 /usr2/ftp/dev
% chown root /usr2/ftp/dev
% ln -s /usr2/ftp/dev/log /dev/log

Look to see where your "syslogd" process is started.  Mine is in "/etc/rc.net".
Change it so the syslogd is started as:

/etc/syslogd -p /usr2/ftp/dev/log

Now, continue the boot process and check the results.

This way the logfile is within the chroot'ed environment, and can still be
accessed.  IMHO, it's a hack, but I didn't see a easier solution...


Of course, if you do this you're on your own.  I take no responsibility what so
ever. :-)

	-Jeff
-- 
Jeff Beadles	jeff@onion.pdx.com  jeff@quark.wv.tek.com

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (08/01/90)

In article <1990Jul31.141746.27004@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:
> In article <11477:Jul3018:50:4290@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> |> Now you're making unsupported assertions. In what conceivable way can
> |> syslog() do better than stderr?
>   You seem to be suggesting that all programs output errors to stderr, and
> daemons that need to do some sort of logging have their stderr piped through a
> program that knows how to process those error messages.

Yup. (Wow, what a revolutionary idea.)

Let me make three general points first, then address your objections in
their light.

A. A program may invoke a pipe or otherwise avoid stderr if it wants.
B. Multiple processes may send output into one pipe.
C. Pipes are as little work for the system as named UNIX-domain sockets.

> 1. It requires an extra process running for every daemon that's going to spit
>    out errors.

No. See B and C. If you want, you can set up named pipes or sockets
/dev/log*, each feeding into a different type of error processor; as
this special case of my ``proposal'' is a generalization of what syslog
does, your efficiency argument is silly.

> 2. It eliminates one channel of communication between the program and the
>    outside world.  Currently, daemons have stdout, stderr, and syslog().  You
>    propose to reduce them to stdout and stderr.

Yes. Daemons don't use stderr anyway. (See below for further discussion.)

> 3. Under your scheme, every time I start up a process that I want to log
>    messages, I have to pipe its stderr though this logging process of yours. 

Ever heard of shell scripts? And see A.

> 4. There are some programs that run interactively that need to be able to
>    both output errors to stderr to the users and to log messages in the system
>    logs.  For example, su.  How would su print error messages if it couldn't
>    use stderr because it was piped through an error logging program.

The reason that such programs *need* two error streams is security. su
should be logging directly to a file, not to a separate daemon that's
easy to clog with spurious messages. See A.

> 5. To generalize (3) and (4) above, the syslog() mechanism is controlled by
>    the system.  Stdin, stdout and stderr are controlled by the user.  There
>    has to be a way for programs to log things in a way that is guaranteed to
>    get them logged (as long as the syslogd is running, of course, and it
>    should be running all the time), no matter where stderr points.

That's really dumb. ``stdin and stdout are controlled by the user. Hence
programs must not read input or produce output.'' Obviously when there's
a security issue the program should be writing directly to files. In
other cases, the user is supposed to be in control. Also see A.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (08/02/90)

In article <104489@convex.convex.com> tchrist@convex.COM (Tom Christiansen) writes:
> In article <11477:Jul3018:50:4290@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> >In what conceivable way can syslog() do better than stderr? 
> Syslogd(8) from BSD4.3 is a highly useful general purpose error
> handling facility.

Yeah, and what do you plan to do with syslog-based systems when people
find a need for more general error logging? How 'bout flags like ``this
is a disk space error, save me!'' or ``I/O? Something wrong with the
disk?''? Or extra parameters like ``I was invoked with the following
arguments''? Or the uid or the gid or part of the environment?

Have you really been deluded into thinking that syslog is sufficiently
flexible to handle everything that good error logging needs?

>     * It allows the sysmgr to centrally control what kinds of error
>       messages he's interested in,

The same is true if you pipe errors to a program that reads from a
central configuration file. In fact, syslog is just such a program. How
could you lose flexibility by *allowing* noncentral control?

>     * You don't have to constantly re-invent logging code.

Oh, yeah, right. Like it's so much effort to fprintf to stderr. This
reflects another problem with syslog: it doesn't let the user take
advantage (?) of some of its features (?) without swallowing the entire
mechanism.

> You don't
>       have to be careful about opens on the console blocking due to
>       control-s or whatnot and hanging YOUR program.

Which reminds me of yet another problem with syslog. What happens when
you flood syslogd with errors? In a correct implementation, either
syslog() blocks, or syslogd loses messages. In the first case, people
like you have been lying to the programmer, who believes that syslog()
will never block (except with exiting children around); the deluded
masses then never even realize there could be security and efficiency
problems. In the second case, you've opened up a huge security hole.
Even denial of service is bad enough: I don't want to risk losing errors
just because twenty programs decide to use syslog() at once.

Which case is it?

At least when I'm writing criticial errors to a file I'll check for the
write() failing. Name one program that checks syslog()'s return code.
(Does it even have a return code?)

>     * You don't have to remember to properly redirect standard error when 
>       you start or restart a daemon.

This seems to be a major issue with you and Jon. Fine: foo by default
reopens stderr as /dev/log. If you say foo -2, it'll send errors to
stderr instead. All daemons adopt this convention. Happy?

> In summary, just writing to stderr is a practice fraught with the danger
> of doing it wrong, does not permit easy and fine-grained configurability.

Ahahahahaha. Good joke.

> Syslog can be used by all forms of programs, encourages code sharing and a
> common interface, and allows you to easily write summarization scripts.

The same is true of stderr, except that syslog is less flexible and
won't expand so easily when people want to add information to their
error messages.

> Stderr writing is a bad practice that should shrivel up and die.

syslog is an insecure, poorly implemented model that will not handle
future needs.

> I guess this is why we need a comp.unix.admin newsgroup.

It is an appropriate topic for comp.unix.admin.

---Dan