lsstarboy 发表于 2015-03-05 17:29

FreeBSD下对ssh用户实行chroot

本帖最后由 lsstarboy 于 2015-03-05 17:31 编辑

正常的ssh用户可以直接登录到服务器上,可以浏览服务器的大多数文件,特别是像PHP脚本,一般都不加密,数据库的用户名和密码都是明文的,这会给系统安全造成威胁。
但是网上的资料相对有些乱,大多数文章都直接给出命令,没有给出解释,初学的时候,还要看手册,读源码。本文主要对几个重要的参数做一下解释。

实现目的:1)test组里面的用户,通过ssh登录到系统后,只能看到自己home里面的内容;
 2)可以通过sftp下载和上传文件,包括winsftp。
 3可以通过命令行进行文件的复制、删除,移动
 4)以下内容,以用户test为例,home目录对应的是/home/test/
重点环节说明:

 1)ssh的chroot,最主要的一个配置语句是:ChrootDirectory,后面有两个常用的参数,%h代表是用户的home,一般是/home/用户名。
 2)最容易出错的地方就是权限,ssh的chroot要求的文件夹属主必须是root,权限要求是g-w,o-w,也就是组和其他用户都没有写权限,在源代码中,这个判断是用的&&022来判断,所以一般情况下,可以用755或555来设置权限。
 3)网上的资料,很多都加入了:ForceCommand internal-sftp,这个参数将导致只能使用sftp,不能用putty或其他系统的ssh命令来登录系统了,这是一定要注意的问题。
4)在chroot后,系统会自动进入home,如果chroot放到用户的home中,最好再建一级home/test,也就是宿主系统中,要有两级home:/home/test/home/test,否则登录或使用scp的时候会出问题,winsftp也不会自动进入到相应的目录。
5)在chroot后,以后所有的文件要以这个目录为根目录了,其中包括最重要的shell以及相应的so文件,所以还要建议一个微型的系统,其中包括三个目录:bin、lib、libexec。其中lib目录下的so文件,主要是ls,cp,mv使用。


sshd主要配置:# vi /etc/ssh/sshd_config
……
Subsystem       sftp    internal-sftp
Match Group test
      ChrootDirectory %h
#       ForceCommand internal-sftp
……你会发现配置非常简单,一共四行还注释掉一行。
先看第一行:Subsystem,这个指定了运行sftp的程序,默认的是/usr/libexec/sftp-server,这个相对于内置的sftp来说,功能比较多,也可以使用scp,但是需要的链接库也多,可以见本文后面的资料,如果你想希望功能多并且有耐心复制对应链接库的话,也可以把这一句注释掉。
第二句定义了一个范围,可以是用户,也可以是IP,这里使用了一个test组,表示仅对test组的用户实行chroot。如果没有这句的话,就连root也限制到/root了,遇到问题你主好亲自跑机房接上键盘显示器操作了。
第三句是个重点,这句就是负责chroot的,没有这句就不chroot了……废话!
第四句是让ssh自动执行一个命令,而忽略掉其他配置文件中指定的程序,也就是说,如果你在这地方指定了一个程序,那么就不再执行其他的命令了,包括ssh本身!这地方指定了运行sftp,那么除了sftp外,你不会得到任何东西,包括sh也没有——最后的结果就是:你只能使用sftp上传下载文件,其他的就别想了(当然sftp中也可以有简单的命令)。



文件路径设置:
在/home/test里,要有以下文件和文件夹:bin
      -sh
        -cp
        -ls
        -mv
lib
        -libc.so.7
       -libedit.so.7
      -libncurses.so.8
       -libutil.so.9
libexec
        -ld-elf.so.1
       -ld-elf32.so.1
home/test然后设置属主和权限:# chown -R root /home/test
# chown -R test:test /home/test/home/test
# chmod -R 755 /home/test其中第二句设置test用户的home,以便test可以对该文件夹下的文件进行操作。



测试:
可以分别使用ssh和sftp进行测试,注意如果使用了internal-sftp,scp命令不能用,会提示找不到scp命令,只能使用sftp来进行文件传输。



附一:sftp-server需要的链接库:# ldd /usr/libexec/sftp-server
/usr/libexec/sftp-server:
      libssh.so.5 => /usr/lib/private/libssh.so.5 (0x800825000)
      libcrypt.so.5 => /lib/libcrypt.so.5 (0x800ab2000)
      libcrypto.so.7 => /lib/libcrypto.so.7 (0x800cd2000)
      libz.so.6 => /lib/libz.so.6 (0x8010c5000)
      libc.so.7 => /lib/libc.so.7 (0x8012db000)
      libldns.so.5 => /usr/lib/private/libldns.so.5 (0x801684000)
      libgssapi.so.10 => /usr/lib/libgssapi.so.10 (0x8018e0000)
      libkrb5.so.11 => /usr/lib/libkrb5.so.11 (0x801ae9000)
      libhx509.so.11 => /usr/lib/libhx509.so.11 (0x801d61000)
      libasn1.so.11 => /usr/lib/libasn1.so.11 (0x801fab000)
      libcom_err.so.5 => /usr/lib/libcom_err.so.5 (0x802248000)
      libmd.so.6 => /lib/libmd.so.6 (0x80244a000)
      libroken.so.11 => /usr/lib/libroken.so.11 (0x80265a000)
      libwind.so.11 => /usr/lib/libwind.so.11 (0x80286c000)
      libheimbase.so.11 => /usr/lib/libheimbase.so.11 (0x802a94000)
      libheimipcc.so.11 => /usr/lib/private/libheimipcc.so.11 (0x802c98000)
      libthr.so.3 => /lib/libthr.so.3 (0x802e9a000)附二:ssh的chroot代码,关键是权限和属主的配置:/usr/src/crypto/openssh/session.c,1451行:
       /*
         * Descend the path, checking that each component is a
         * root-owned directory with strict permissions.
         */
      for (cp = path; cp != NULL;) {
                if ((cp = strchr(cp, '/')) == NULL)
                        strlcpy(component, path, sizeof(component));
                else {
                        cp++;
                        memcpy(component, path, cp - path);
                        component = '\0';
                }

                debug3("%s: checking '%s'", __func__, component);

                if (stat(component, &st) != 0)
                        fatal("%s: stat(\"%s\"): %s", __func__,
                            component, strerror(errno));
                if (st.st_uid != 0 || (st.st_mode & 022) != 0)
                        fatal("bad ownership or modes for chroot "
                            "directory %s\"%s\"",
                            cp == NULL ? "" : "component ", component);
                if (!S_ISDIR(st.st_mode))
                        fatal("chroot path %s\"%s\" is not a directory",
                            cp == NULL ? "" : "component ", component);

      }
--
另发于:联动论坛

action08 发表于 2015-03-06 07:28

有些概念说得太复杂了,感觉还是不懂
页: [1]
查看完整版本: FreeBSD下对ssh用户实行chroot