Tag Archives: 서버관리

OpenSSH + chroot 환경에서의 필수 파일들

http://sourceforge.net/projects/chrootssh/ 에서 진행하는 SSH의 chroot 패치가 있다.

—————————–openssh-chrootssh.patch———————–
— session.c.org 2005-07-25 01:28:59.000000000 +0900
+++ session.c 2005-07-25 01:28:35.000000000 +0900
@@ -58,6 +58,8 @@
 #include “session.h”
 #include “monitor_wrap.h”
 
+#define CHROOT
+
 #if defined(KRB5) && defined(USE_AFS)
 #include <kafs.h>
 #endif
@@ -1258,6 +1260,12 @@
 void
 do_setusercontext(struct passwd *pw)
 {
+
+#ifdef CHROOT
+     char *user_dir;
+        char *new_root;
+#endif /* CHROOT */
+
 #ifndef HAVE_CYGWIN
  if (getuid() == 0 || geteuid() == 0)
 #endif /* HAVE_CYGWIN */
@@ -1315,6 +1323,27 @@
    restore_uid();
   }
 #endif
+
+#ifdef CHROOT
+  user_dir = xstrdup(pw->pw_dir);
+  new_root = user_dir + 1;
+
+     while((new_root = strchr(new_root, ‘.’)) != NULL) {
+    new_root–;
+    if(strncmp(new_root, “/./”, 3) == 0) {
+      *new_root = ‘\0’;
+      new_root += 2;
+  
+      if(chroot(user_dir) != 0)
+   fatal(“Couldn’t chroot to user’s directory %s”, user_dir);
+      pw->pw_dir = new_root;
+      break;
+    }
+  
+    new_root += 2;
+  }
+#endif /* CHROOT */
+    
 # ifdef USE_PAM
   /*
    * PAM credentials may take the form of supplementary groups.
———————————————————————————–


——————————openssh.spec.diff————————————
—- openssh.spec.org    2005-05-31 18:43:30.000000000 +0900
+++ openssh.spec    2005-07-25 22:34:42.000000000 +0900
@@ -13,7 +13,8 @@
 Patch1: openssh-rpm.patch
 Patch2: openssh-loginallow.patch
 Patch3: openssh-mCOOKIE.patch
 Patch4: openssh-multibyte.patch
+Patch5: openssh-chrootssh.patch
 Copyright: BSD
 Group: Applications/Internet
 BuildRoot: %{_tmppath}/openssh-%{version}-buildroot
@@ -90,6 +91,7 @@
 %patch2 -p1 -b .loginallow
 %patch3 -p1 -b .mCOOKIE
 %patch4 -p1 -b .multibyte
+%patch5 -p0 -b .chrootssh
 #autoconf


 %build
———————————————————————————–

매번 설치할때마다 중요한 파일 목록들을 까먹어 기록해 둔다.

bin:
bash cat chmod cp cut egrep gunzip gzip hostname
ls mkdir mv rm rmdir sh tar


dev:
null (mknod null c 1 3)
zero (mknod zero c 1 5)


etc:
DIR_COLORS DIR_COLORS.xterm bashrc group inputrc
passwd profile termcap vimrc


etc/profile.d:
colorls.sh lang.sh vim.sh


etc/sysconfig:
i18n


lib:
ld-2.2.4.so ld-linux.so.2 libc-2.2.4.so libc.so.6
libcrypt.so.1 libdl-2.2.4.so libdl.so.2 libm.so.6
libnsl.so.1 libnss_files.so.2 libpthread.so.0
libresolv.so.2 libtermcap.so.2 libtermcap.so.2.0.8
libutil.so.1


usr/bin:
dircolors du id mesg vim whoami


usr/lib:
libgpm.so.1 libncurses.so.5 libperl.so
libpython2.5.so.1.0


usr/share/terminfo:
*


usr/share/vim:
*

PHP 보안의 약방의 감초 open_basedir

오늘은 PHP보안에 있어 중요하지만 또한 많은 사람이 모르고 있는 open_basedir이라는 옵션에 대해 이야기 해보도록 하자.

우선 내가 운영하는 서버의 경우 php.ini에 다음과 같은 무식한 옵션이 있었다.

[code]disable_functions = php_uname, putenv, getmyuid, getmypid, passthru, leak, listen, diskfreespace,
tmpfile, link, ignore_user_abord, shell_exec, popen, dl, set_time_limit, exec, system,
highlight_file, source, show_source, fpaththru, virtual, posix_ctermid, posix_getcwd,
posix_getegid, posix_geteuid, posix_getgid, posix_getgrgid, posix_getgrnam, posix_getgroups,
posix_getlogin, posix_getpgid, posix_getpgrp, posix_getpid, posix_getppid, posix_getpwnam,
posix_getpwuid, posix_getrlimit, posix_getsid, posix_getuid, posix_isatty, posix_kill, posix_mkfifo,
posix_setegid, posix_seteuid, posix_setgid, posix_setpgid, posix_setsid, posix_setuid, posix_times,
posix_ttyname, posix_uname[/code]

이 얼마나 무식한가? 하지만 저것도 다 막은것이 아니다.

심지어 fopen같은 경우에는 사용하는 웹어플리케이션이 너무 많아 막을수가 없었다.

뭐랄까, 도둑이 들까봐, 창문 잠그고 굴둑도 막아버렸는데, 대문을 활짝 열어놓은 기분이랄까?

PHP에는 safe_mode라는 훌륭한 보안 모드가 있다. 하지만 이것을 사용하면 대부분의 웹어플리케이션이 비정상 작동을 하게 된다.

제로보드가 잠식하고 있는 우리나라의 웹호스팅 업계에서는 엄두도 낼수 없는 옵션이다.

다음과 같은 코드를 작성하여 실행해 보자.

[code]<?
    $fp=fopen(“/etc/passwd”, “r”);
    while(!feof($fp)) {
        print(fread($fp, 4096));
        flush();
    }
?>[/code]

어떤 결과가 나오는가? 아주 멋지게 우리가 필요로 하는 정보를 내뿜어 준다.

disable_function에 fopen을 추가해 보자. 수많은 난관을 만나게 된다. 당장에 테터툴즈가 설치가 안되더라;

php.ini에 있는 open_basedir에 현재 서비스 하고 있는 페이지의 Document Root를 넣어보자. (예 : /var/www)

그리고 다시 시도해보자. 되는가? 잔인한 Fatal Error를 만나게 될것이다.

하지만 마찬가지로, PHP에서 세션을 저장하거나 업로드 파일을 올릴때 사용하는 /tmp등도 접근할수 없게 된다.

어떻게 해야 할까? 옵션을 지정할때 :를 구분자로 주어 여러개 지정할수 있다.

[code]open_basedir /var/www:/tmp[/code]

와 같이 설정해보자. 어떤가? 잘 되는것을 확인할수 있다.

안된다면 upload_tmp_dir 와 session.save_path 가 /tmp로 지정되어있는지부터 확인하여야 할것이다.

만약에 웹호스팅을 하고 있다면? open_basedir옵션이 없으면 더더욱 골치가 아파지게 된다.

누구든지 다른 사람의 계정의 파일을 열어볼수 있다면? “항상 적은 내부에 있다”

apache의 설정파일에서 VirtualHost부분을 찾아서 다음과 같이 php_admin_value로 값을 설정하자.

[code]<VirtualHost *>
    DocumentRoot /home/USER
    ServerName USER.domain
    <IfModule mod_php5.c>
        php_admin_value open_basedir /home/USER:/tmp
    </IfModule>
</VirtualHost>[/code]

이런식으로 모든 가상호스트에 대해 설정을 하면 동일한 결과를 볼수 있다.

하지만 이것은 PHP의 함수들에 대한 제제일뿐이다. system(“cat /etc/passwd”)같은 명령은 어찌할수가 없다.

system명령을 disable_function에 추가해 버릴까? 이부분에 대해서는 다음에 좀더 이야기 해보도록 하자.

PS : upload_tmp_dir, session.save_path 을 /tmp가 아닌, 다른곳으로 변경한다면, 웹인젝션을 시도하는 나쁜놈들이 좀더 헷갈리게 할수 있겠죠?