--- ijb20/jcc.c.chroot Thu Apr 8 18:59:39 1999 +++ ijb20/jcc.c Fri Apr 9 03:12:15 1999 @@ -26,6 +26,8 @@ #include #include #include +#include +#include #ifdef __BEOS__ #include /* BeOS has select() for sockets only. */ @@ -133,6 +136,10 @@ char *forwardfile = NULL; char *aclfile = NULL; +int user = 0; +int group = 0; +char *rootdir = NULL; + char *jarfile = NULL; FILE *jar; @@ -836,6 +843,48 @@ continue; } + if(strcmp(cmd, "user") == 0) { + struct passwd *p; + p = getpwnam(arg); + if(p == NULL) { + fprintf(logfp, + "%s: user unknown: %s", + prog, arg); + err = 1; + } else { + user = p->pw_uid; + continue; + } + } + + if(strcmp(cmd, "group") == 0) { + struct group *p; + p = getgrnam(arg); + if(p == NULL) { + fprintf(logfp, + "%s: group unknown: %s", + prog, arg); + err = 1; + } else { + group = p->gr_gid; + continue; + } + } + + if(strcmp(cmd, "rootdir") == 0) { + struct stat st; + if (stat(arg, &st) == -1 + || !S_ISDIR(st.st_mode)) { + fprintf(logfp, + "%s: not a directory: %s", + prog, arg); + err = 1; + } else { + rootdir = strdup(arg); + continue; + } + } + fprintf(logfp, "%s: unrecognized directive " "in configuration file " @@ -852,6 +902,18 @@ InitWin32(); #endif + if (rootdir != NULL && chdir(rootdir) == -1) { + fprintf(logfp, "%s: can't chdir to %s\n", prog, rootdir); + err = 1; + } + + if (rootdir != NULL && chroot(rootdir) == -1) { + fprintf(logfp, "%s: can't chroot to %s\n", prog, rootdir); + err = 1; + } + + if (err) exit(1); + if(logfile) { FILE *tlog = fopen(logfile, "a"); if(tlog == NULL) { @@ -932,6 +997,16 @@ fprintf(logfp, "There may be another junkbuster or some other " "proxy running on port %d\n", hport); + err = 1; + } + + if (group != 0 && setgid(group) == -1) { + fprintf(logfp, "%s, can't setgid to GID #%d\n", prog, group); + err = 1; + } + + if (user != 0 && setuid(user) == -1) { + fprintf(logfp, "%s, can't setuid to UID #%d\n", prog, user); err = 1; } --- ijb20/ijbman.html.chroot Fri Apr 9 04:27:43 1999 +++ ijb20/ijbman.html Fri Apr 9 04:32:42 1999 @@ -751,6 +751,26 @@ you should probably have firewall; they are not intended to replace one. +


user  username
+This tells junkbuster to change the user ID (UID) to the one represented +by the given username. It works only on UNIX. It can be used together +with the group and rootdir options. The \fPlogfile\fI and probably +its parent directory should be writable by UID or GID junkbuster is running +as. +


group  groupname
+This tells junkbuster to change the group ID (GID) to the one represented +by the given groupname. It works only on UNIX. It can be used together +with the user and rootdir options. The \fPlogfile\fI and probably +its parent directory should be writable by UID or GID junkbuster is running +as. +


rootdir  directory
+Junkbuster will try to chroot(2) to the given directory at startup. +All the config file paths (except the main config file) are interpreted +relative to this directory. This (together with the user and +group options) allows to enhance the security of the system +where junkbuster is running. Note that the directory subtree should +contain all the files chrooted program may need. See the README.chroot +file in the distribution for details on setting up the chroot directory tree.


trustfile  trustfile
This feature is experimental, has not been fully documented and is very subject to change. --- ijb20/junkbuster.1.chroot Fri Apr 9 04:02:26 1999 +++ ijb20/junkbuster.1 Fri Apr 9 04:27:16 1999 @@ -749,6 +749,29 @@ firewall;\" ijbfaq.html#firewall they are not intended to replace one. .TP +user \fIusername\fP (New) +This tells junkbuster to change the user ID (UID) to the one represented +by the given \fIusername\fP. It works only on UNIX. It can be used together +with the \fIgroup\fP and \fIrootdir\fP options. The \fPlogfile\fI and probably +its parent directory should be writable by UID or GID junkbuster is running +as. +.TP +group \fIgroupname\fP (New) +This tells junkbuster to change the group ID (GID) to the one represented +by the given \fIgroupname\fP. It works only on UNIX. It can be used together +with the \fIuser\fP and \fIrootdir\fP options. The \fPlogfile\fI and probably +its parent directory should be writable by UID or GID junkbuster is running +as. +.TP +rootdir \fIdirectory\fP (New) +Junkbuster will try to \fIchroot(2)\fP to the given directory at startup. +All the config file paths (except the main config file) are interpreted +relative to this \fIdirectory\fP. This (together with the \fIuser\fP and +\fIgroup\fP options) allows to enhance the security of the system +where junkbuster is running. Note that the \fIdirectory\fP subtree should +contain all the files chrooted program may need. See the README.chroot +file in the distribution for details on setting up the chroot directory tree. +.TP .\" anchor: o_tf trustfile trustfile \fItrustfile\fP (New) This feature is experimental, has not been fully documented and is --- ijb20/junkbuster.init.chroot Fri Apr 9 04:34:12 1999 +++ ijb20/junkbuster.init Fri Apr 9 04:40:11 1999 @@ -1,53 +1,50 @@ #!/bin/sh # -# This is file /etc/rc.d/init.d/junkbuster and was put here -# by the junkbuster rpm +# junkbuster Start/Stop Internet Junkbuster daemon # # chkconfig: 235 84 09 -# -# junkbuster This shell script takes care of starting and stopping -# junkbuster. -# +# description: The junkbuster is a simple HTTP proxy server, which can \ +# filter cookies and other privacy-sensitive HTTP headers \ +# (User-Agent, From, etc), and can block banner ads as well. +# processname: junkbuster # Source function library. . /etc/rc.d/init.d/functions [ -f /usr/sbin/junkbuster ] || exit 0 +[ -f /etc/junkbuster/config ] || exit 0 # See how we were called. case "$1" in start) - # abort if already started - [ -f /var/lock/subsys/junkbuster ] && exit 0 - - # Start daemon. - # - # This works only correctly if the user `nobody' is allowed - # to be in the directory where this file is called - # (for example: /root is NOT ok) - # echo -n "Starting junkbuster: " - su nobody -c "/usr/sbin/junkbuster /etc/junkbuster/config &" + # No "su nobody" here. Use "user", "group", and "rootdir" + # in the config file + /usr/sbin/junkbuster /etc/junkbuster/config & + rm -f /var/run/junkbuster.pid + echo $! >/var/run/junkbuster.pid touch /var/lock/subsys/junkbuster echo junkbuster ;; stop) - # Stop daemon. echo -n "Shutting down junkbuster: " killproc junkbuster rm -f /var/lock/subsys/junkbuster + rm -f /var/run/junkbuster.pid echo junkbuster ;; - restart) + restart|reload) $0 stop $0 start ;; - + status) + status junkbuster + ;; *) - echo "Usage: junkbuster {start|stop|restart}" + echo "Usage: junkbuster {start|stop|restart|reload|status}" exit 1 esac --- /dev/null Tue May 5 22:32:27 1998 +++ ijb20/README.chroot Fri Apr 9 05:08:36 1999 @@ -0,0 +1,65 @@ +Fri Apr 9 04:42:27 CEST 1999 Jan "Yenya" Kasprzak + +I have implemented three new directives - user, group, and rootdir +to enhance the security of the systems junkbuster is running on, +and to reduce the severity of the potential security holes which +may be discovered in this software in the future. + +On UNIX, every root process (= running with effective UID=0) can change +its root directory using the chroot(2) system call. This means all the +absolute paths used by this process (accessing the files etc.) is interpreted +relatively to this directory. This effectively means the chrooted process +cannot access any file above the directory it is chrooted to. So if this +directory contains config files, libraries and maybe the log files, +nobody can use a security hole in this process to obtain access to the +entire system. Even if a remote user would be allowed (by a security hole) +to do anything this process can do, it can access files under its own +root directory and under the UID/GID process is currently running under. + +In JunkBUster you can specify the "rootdir " (for example +"rootdir /var/junkbuster") to tell junkbuster to change its root. +To allow this, the junkbuster should be started as root. + +When the process is started by root, you should use the "user ", +for example "user nobody" to tell junkbuster to revoke its root permissions. +This user ID should have read access to all the config files, and write +access to the log file and log directory. + +**************************************************************** +I *STRONGLY* recommend not to run junkubster as "nobody" user, +because "nobody" user should not own any file, and you need +to give the junkbuster process a write permission at least to the +log file. I recommend to create and use the special user ID "ijb" +(note that the "junkbuster" name is longer than 8 characters and +therefore may not work on all systems). Having a separate UID +allows you to set up the disk quota to this UID and prevent your +disk to be filled with the log file. +**************************************************************** + +You can also use the "group " (for example "group nobody") +to change the process' group ID. + +When you will be setting up the chroot directory, you should put there +all the files necessary for running process. It can mean copies of the +system files, shared libraries, etc. This can vary from system to system. +I have tested it on RedHat Linux 5.2 (glibc 2.0.7-29) system, and +I have used the following layout (root directory in /home/junkbuster): + +/etc/junkbuster (symlink to /home/junkbuster/etc/junkbuster) +/var/log/junkbuster (symlink to /home/junkbuster/var/log/junkbuster) +/home/junkbuster/etc/junkbuster/aclfile +/home/junkbuster/etc/junkbuster/blocklist +/home/junkbuster/etc/junkbuster/config +/home/junkbuster/etc/junkbuster/cookiefile +/home/junkbuster/etc/junkbuster/forward +/home/junkbuster/etc/junkbuster/imagelist +/home/junkbuster/etc/junkbuster/trust +/home/junkbuster/etc/resolv.conf +/home/junkbuster/lib/libnss_dns.so.1 +/home/junkbuster/lib/libresolv.so.2 +/home/junkbuster/var/log/junkbuster/ + +Feel free to contact me with problems with junkbuster's chroot feature. + +-Yenya + --- ijb20/config.chroot Fri Apr 9 05:12:41 1999 +++ ijb20/config Fri Apr 9 05:12:43 1999 @@ -136,3 +136,15 @@ # debugging output "in order" for easy reading. # #single-threaded + +# user name junkbuster is run as (if you start it as root, it will change +# to this UID. Do not use nobody here (see the README.chroot for rationale). +user ijb + +# group name junkbuster is run as +group nobody + +# root directory. junkbuster will chroot(2) to this directory. See the +# README.chroot for details on setting up the chroot tree +rootdir /home/junkbuster +