feature request & patch submit: chroot(2) in sshd
Birger Toedtmann
birger at takatukaland.de
Mon Oct 30 21:30:28 EST 2000
On Sun, Oct 29, 2000 at 04:07:35PM -0500, Hank Leininger wrote:
> On 2000-10-29, Birger Toedtmann <birger at takatukaland.de> wrote:
>
> > On Sun, Oct 29, 2000 at 01:52:58AM -0500, Hank Leininger wrote:
>
> > > Aren't you missing a 'chdir("/")' in there? Else you leak '.'
> > > outside the chroot jail. (Unless a chdir is guaranteed to be done
> > > between here, and when user processes get control?)
>
> > Well, right beneath this code session.c switches uid/gid and then sets
> > the environment. $HOME is set to pw->pw_dir (already set to "/") and
> > $HOME/.ssh/environment gets its share. After this, the chdir() is
> > made....
>
> Ah. OK, so there is a chdir() guaranteed. Although you raise a good
> point:
>
> > ...hmmm - do you think one might be able to fool .ssh/environment into
> > leaking information about "."?
>
> I'm really not sure. But for warm-and-fuzzy, obviously-correct behavior,
> I'd vote for an explicit chdir(pw->pw_dir) right after pw->pw_dir = "/" as
> you suggest. Consider the alternative -- we might audit the behavior of
> ..ssh/environment usage now and deem it safe, only to have others decide
> later, for whatever seems like good reasons at the time, to break our
> assumptions wrt its safety in the face of things getting reordered, odd
> custom shells, forced commands from authorized_keys, scp's, and whatnot.
> Better IMHO to have the fact that it is Done Right localized and hard to
> break accidentally by other subtle means.
[...]
Alright, this seems reasonable. So I tested around a bit with some weird
outcome. The new patch includes a chdir() right after chroot(). I set the
home of my prisoner to 644 just to have a closer look. Whoops - first chdir()
succeeded, the second did not! I think with uid=0 chdir()ing to a 644 sounds
quite ok, whereas uid!=0 makes some difference. Maschine is a linux box.
BTW: I (stupendously) oversaw the chroot.diff within contrib/ which does
something similar upon a "/./"-criterion regarding the homedir section of
user credentials. Now I'm not quite sure about the usefulness of either
patch but we use the UseChroot/ChrootGroup one quite sucessfully on a web
application server maintained via ssh by its customers.
Regards,
--
Birger Tödtmann, Bielefeld, Germany.
00 83 E2 57 EC 60 0B 1C D3 18 AE 2A 40 55 81 22
-------------- next part --------------
Common subdirectories: openssh-2.2.0p1/contrib and openssh-2.2.0p1chroot/contrib
diff -u openssh-2.2.0p1/servconf.c openssh-2.2.0p1chroot/servconf.c
--- openssh-2.2.0p1/servconf.c Fri Aug 18 05:59:06 2000
+++ openssh-2.2.0p1chroot/servconf.c Mon Oct 30 12:03:49 2000
@@ -68,6 +68,8 @@
#endif
options->permit_empty_passwd = -1;
options->use_login = -1;
+ options->use_chroot = -1;
+ options->chroot_group = -1;
options->num_allow_users = 0;
options->num_deny_users = 0;
options->num_allow_groups = 0;
@@ -158,6 +160,10 @@
options->permit_empty_passwd = 0;
if (options->use_login == -1)
options->use_login = 0;
+ if (options->use_chroot == -1)
+ options->use_chroot = 0;
+ if (options->chroot_group == -1)
+ options->chroot_group = 0;
if (options->protocol == SSH_PROTO_UNKNOWN)
options->protocol = SSH_PROTO_1|SSH_PROTO_2;
if (options->gateway_ports == -1)
@@ -189,6 +195,7 @@
sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
+ sUseChroot, sChrootGroup,
sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups
} ServerOpCodes;
@@ -236,6 +243,8 @@
{ "strictmodes", sStrictModes },
{ "permitemptypasswords", sEmptyPasswd },
{ "uselogin", sUseLogin },
+ { "usechroot", sUseChroot },
+ { "chrootgroup", sChrootGroup },
{ "randomseed", sRandomSeedFile },
{ "keepalive", sKeepAlives },
{ "allowusers", sAllowUsers },
@@ -540,6 +549,14 @@
case sUseLogin:
intptr = &options->use_login;
goto parse_flag;
+
+ case sUseChroot:
+ intptr = &options->use_chroot;
+ goto parse_flag;
+
+ case sChrootGroup:
+ intptr = &options->chroot_group;
+ goto parse_int;
case sGatewayPorts:
intptr = &options->gateway_ports;
diff -u openssh-2.2.0p1/servconf.h openssh-2.2.0p1chroot/servconf.h
--- openssh-2.2.0p1/servconf.h Fri Aug 18 05:59:06 2000
+++ openssh-2.2.0p1chroot/servconf.h Mon Oct 30 12:03:49 2000
@@ -87,6 +87,9 @@
int permit_empty_passwd; /* If false, do not permit empty
* passwords. */
int use_login; /* If true, login(1) is used */
+ int use_chroot; /* If true, do a chroot to homedir */
+ int chroot_group; /* If nonzero, chroot only when equal
+ to gid */
unsigned int num_allow_users;
char *allow_users[MAX_ALLOW_USERS];
unsigned int num_deny_users;
diff -u openssh-2.2.0p1/session.c openssh-2.2.0p1chroot/session.c
--- openssh-2.2.0p1/session.c Wed Aug 30 00:21:22 2000
+++ openssh-2.2.0p1chroot/session.c Mon Oct 30 12:06:58 2000
@@ -948,6 +948,26 @@
}
#endif /* USE_PAM */
+ /* Do a chroot, if configured. */
+ if (options.use_chroot) {
+ if ((!options.chroot_group)
+ || (options.chroot_group == pw->pw_gid)) {
+ debug("Doing chroot to %s.",pw->pw_dir);
+ if (chroot(pw->pw_dir) < 0) {
+ log("Requested chroot failed: [%d] %s\n",
+ errno,strerror(errno));
+ exit(1);
+ }
+ debug("Doing chdir to / within chroot dir %s.",pw->pw_dir);
+ pw->pw_dir = "/";
+ if (chdir(pw->pw_dir) < 0) {
+ log("Unable to chdir to home directory /: [%d] %s\n",
+ errno,strerror(errno));
+ exit(1);
+ };
+ }
+ }
+
/* Set login name, uid, gid, and groups. */
/* Login(1) does this as well, and it needs uid 0 for the "-h"
switch, so we let login(1) to this for us. */
diff -u openssh-2.2.0p1/sshd.8 openssh-2.2.0p1chroot/sshd.8
--- openssh-2.2.0p1/sshd.8 Tue Aug 29 02:33:51 2000
+++ openssh-2.2.0p1chroot/sshd.8 Mon Oct 30 12:03:50 2000
@@ -290,6 +290,15 @@
Only user names are valid; a numerical user ID isn't recognized.
By default login is allowed regardless of the user name.
.Pp
+.It Cm ChrootGroup
+Only useful when
+.Cm UseChroot
+is set to
+.Dq yes .
+Specifies which group of users
+.Nm sshd
+should drop into a chrooted homedir (a.k.a. sandbox) upon login.
+Only numerical gid's are allowed.
.It Cm Ciphers
Specifies the ciphers allowed for protocol version 2.
Multiple ciphers must be comma-separated.
@@ -597,6 +606,12 @@
The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is AUTH.
+.It Cm UseChroot
+Do a chroot(2) into the users homedirectory after successful login.
+If option
+.Cm ChrootGroup
+is not set, this applies for all users. The default is
+.Dq no .
.It Cm UseLogin
Specifies whether
.Xr login 1
More information about the openssh-unix-dev
mailing list