Wrapper — первые шаги | Популярный Linux

Опубликовано Kreativka в Пнд, 23/04/2012 — 22:23

Что мы подразумеваем под словом wrapper? Под эти словом подразумевается программа, которая из себя вызывает другую или несколько. Для чего это нужно? Представьте себе ситуацию, с которой мне пришлось сталкнуться в моей организации. Начнем с того, что орга низация занимается разработкой программных продуктов и дизайном веб серверов. В нашей сети есть машины и под Linux и под Windows 95/NT и даже Mac. Многим (в связи со спецификой работы) нужен терминальный доступ к серверу. Было два варианта: поставить SSH или открыть 23 порт с нормальным шелом. Первый вариант не подходит — все сказали зачем нам дополнительный софт ставить, когда есть нормальный телнет. Мне же не подходил второй вариант, но 20 человек против одного, сами понимаете. Всех пользователей надо б ыло ограничить в доступе к определенным директориям, запретить просмотр системных файлв и т.д.
Как выйти из такой ситуации? Поставить последний bash с возможностью работать в restricted режиме? Тоже не подходит. Я давно слышал, что многие запускали NCSA HTTP Daemon из под этого самого wrapper-a. Тем самым, демон работал в своей собственной файловой системе. Это мне как раз и нужно. Работа началсь. Первым делом, надо создать свою собственную файловую систему. Я ее создал в /usr/ и назвал env. Далее, создал в этой директории такие же поддиректории, как и в корневой файловой системе:

$ ls -la /usr/env
total 10
drwxr-xr-x 10 root wheel 512 Apr 18 17:49 .
drwxr-xr-x 19 root wheel 512 Apr 18 16:08 ..
drwxr-xr-x 2 root wheel 512 Apr 18 16:05 bin
drwxr-xr-x 2 root wheel 512 Apr 17 19:47 dev
drwxr-xr-x 2 root wheel 512 Apr 28 12:09 etc
drwxr-xr-x 4 root wheel 512 Apr 18 16:08 home
drwxr-xr-x 2 root wheel 512 Apr 18 16:05 sbin
drwxr-xr-x 2 root wheel 512 Apr 17 19:48 tmp
drwxr-xr-x 6 root wheel 512 Apr 18 16:05 usr
drwxr-xr-x 4 root wheel 512 Apr 19 16:07 var
$

После чего в директорию /usr/env/usr/lib скопировал нужные библиотеки:

$ ls -la /usr/env/usr/lib
total 6640
drwxr-xr-x 2 root wheel 1024 Apr 19 16:10 .
drwxr-xr-x 6 root wheel 512 Apr 18 16:05 ..
-r—r—r— 1 root wheel 1040382 Apr 17 19:50 libc.a
-r—r—r— 1 root wheel 512558 Apr 17 19:50 libc.so
-r—r—r— 1 root wheel 512558 Apr 17 19:50 libc.so.3
-r—r—r— 1 root wheel 1263628 Apr 17 19:50 libc_pic.a
-r—r—r— 1 root wheel 1189452 Apr 17 19:50 libc_r.a
-r—r—r— 1 root wheel 565215 Apr 17 19:50 libc_r.so
-r—r—r— 1 root wheel 565215 Apr 17 19:50 libc_r.so.3
-r—r—r— 1 root wheel 4004 Apr 17 19:50 libcalendar.a
-r—r—r— 1 root wheel 4948 Apr 17 19:50 libcalendar.so
-r—r—r— 1 root wheel 4948 Apr 17 19:50 libcalendar.so.2
-r—r—r— 1 root wheel 51750 Apr 17 19:50 libcam.a
-r—r—r— 1 root wheel 50156 Apr 17 19:50 libcam.so
-r—r—r— 1 root wheel 50156 Apr 17 19:50 libcam.so.2
-r—r—r— 1 root wheel 6358 Apr 17 19:50 libcom_err.a
-r—r—r— 1 root wheel 5828 Apr 17 19:50 libcom_err.so
-r—r—r— 1 root wheel 5828 Apr 17 19:50 libcom_err.so.2
-r—r—r— 1 root wheel 30064 Apr 17 19:50 libcompat.a
-r—r—r— 1 root wheel 6198 Apr 17 19:50 libcrypt.a
-r—r—r— 1 root wheel 7607 Apr 17 19:50 libcrypt.so
-r—r—r— 1 root wheel 7607 Apr 17 19:50 libcrypt.so.2
-r—r—r— 1 root wheel 80084 Apr 17 19:50 libcurses.a
-r—r—r— 1 root wheel 45964 Apr 17 19:50 libcurses.so
-r—r—r— 1 root wheel 45964 Apr 17 19:50 libcurses.so.2
-r—r—r— 1 root wheel 106908 Apr 19 16:10 libmytinfo.a
-r—r—r— 1 root wheel 84057 Apr 19 16:10 libmytinfo.so
-r—r—r— 1 root wheel 84057 Apr 19 16:10 libmytinfo.so.2
-r—r—r— 1 root wheel 108778 Apr 19 16:10 libncurses.a
-r—r—r— 1 root wheel 70059 Apr 19 16:10 libncurses.so
-r—r—r— 1 root wheel 70059 Apr 19 16:10 libncurses.so.3
-r—r—r— 1 root wheel 38852 Apr 17 20:08 libutil.a
-r—r—r— 1 root wheel 30107 Apr 17 20:08 libutil.so
-r—r—r— 1 root wheel 30107 Apr 17 20:08 libutil.so.2
$

Понятно, что можно скомпелировать нужные программы без того, чтобы они нуждались в этих библиотеках, но времени было мало и пришлось их просто скопировать.
Далее, стоит подумать о том, какие программы стоит отдать пользователям. Стандартный набор выглядит у меня примерно так:

$ ls -la /usr/env/bin
total 1140
drwxr-xr-x 2 root wheel 512 Apr 18 16:05 .
drwxr-xr-x 10 root wheel 512 Apr 18 17:49 ..
-r-xr-xr-x 1 root wheel 55296 Apr 18 15:00 cat
-r-xr-xr-x 1 root wheel 58184 Apr 18 15:00 chmod
-r-xr-xr-x 1 root wheel 60904 Apr 18 15:01 cp
-r-xr-xr-x 1 root wheel 258328 Apr 18 14:55 csh
-r-xr-xr-x 1 root wheel 43792 Apr 18 15:02 ln
-r-xr-xr-x 1 root wheel 173432 Apr 18 14:57 ls
-r-xr-xr-x 1 root wheel 46156 Apr 18 15:02 mkdir
-r-xr-xr-x 1 root wheel 155768 Apr 18 15:03 mv
-r-xr-xr-x 1 root wheel 51820 Apr 18 15:06 pwd
-r-xr-xr-x 1 root wheel 158552 Apr 18 15:03 rm
-r-xr-xr-x 1 root wheel 43208 Apr 18 15:04 rmdir
$

Можно еще что то положить и в sbin, но это уже не столь важно. Далее поговорим о содержимом etc. Что стоит туда класть? Если у Вас Linux, то достаточно положить Файл паролей, где все пароли заменены звездочкой, делается для того, чтобы ls показывал имя пользователя. И файл групп group и файл termcap. Далее по вашему усмотрению.
Отлично, файловая система создана, приступаем к написанию wrapper-a.
Вот код моего:

  1. #include
  2. #include
  3. #include
  4. #include
  5.  
  6. void main( int argc, char *argv[] )
  7. {
  8.  uid_t uid;
  9.  gid_t gid;
  10.  char *p, *home;
  11.  struct passwd *wpass;
  12.  
  13.  p = «/usr/env»;
  14.  uid = getuid();
  15.  gid = getgid();
  16.  wpass = getpwuid(uid);
  17.  home = wpass->pw_dir;
  18.  
  19.  if( chdir(p) )
  20.  {
  21.  fprintf(stderr, «chdir to %s failed\n«, p );
  22.  }
  23.  else if( chroot(p) )
  24.  {
  25.  fprintf(stderr, «chroot to %s failed\n«, p );
  26.  }
  27.  else if( setuid(uid) != 0 )
  28.  {
  29.  fprintf(stderr, «setuid failed\n« );
  30.  }
  31.  else if( setgid(gid) != 0 )
  32.  {
  33.  fprintf(stderr, «setuid failed\n« );
  34.  }
  35.  else if ( chdir(home) )
  36.  {
  37.  fprintf(stderr, «chdir to %s failed\n«, home);
  38.  }
  39.  else
  40.  {
  41.  execl( «/bin/csh»,«csh»,(char *)0 );
  42.  fprintf(stderr, «execl failed for shell.\n«);
  43.  }
  44.  exit(0);
  45. }

Далее делаем: # gcc -o wrapper wrapper.c
А потом копируем его в /bin и делаем его chmod u+s /bin/wrapper После чего, чтобы никто другой не ругался делаем: echo /bin/wrapper >> /etc/shells
Создадим пробного пользователя с шелом /bin/wrapper. И попробуем войти телнетом на машину:

FreeBSD/i386 (joshua) (ttyp1)

login: user120
Password: *****

Last login: Thu Apr 29 13:25:36 from invalid hostname
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
 The Regents of the University of California. All rights reserved.

FreeBSD 3.0-RELEASE (GENERIC)

% ls -la

-rw——- 1 user120 users 518 Apr 16 14:22 mbox
lrwxr-xr-x 1 root wheel 21 Apr 16 16:01 pub —> /var/ftp/users/user120
drwxr-xr-x 2 user120 users 512 Apr 16 16:00 www

% cd /
% ls -la

drwxr-xr-x 10 root wheel 512 Apr 18 13:49 .
drwxr-xr-x 10 root wheel 512 Apr 18 13:49 ..
drwxr-xr-x 2 root wheel 512 Apr 18 12:05 bin
drwxr-xr-x 2 root wheel 512 Apr 17 15:47 dev
drwxr-xr-x 2 root wheel 512 Apr 28 08:09 etc
drwxr-xr-x 4 root wheel 512 Apr 18 12:08 home
drwxr-xr-x 2 root wheel 512 Apr 18 12:05 sbin
drwxr-xr-x 2 root wheel 512 Apr 17 15:48 tmp
drwxr-xr-x 6 root wheel 512 Apr 18 12:05 usr
drwxr-xr-x 4 root wheel 512 Apr 19 12:07 var

%

Вот, теперь пользователь ничего не видит кроме того, что Вы ему разрешили видеть и использовать.
А если хотите запустить демон в своей файловой системе? Вот небольшая программа, которая сделает это:

  1. #include
  2. #include
  3.  
  4. main(argc, argv)
  5. int argc;
  6. char **argv;
  7. {
  8.  char *path, *user, *cmd;
  9.  struct passwd *pwd;
  10.  
  11. #ifdef LOG_DAEMON
  12.  (void) openlog(argv[0], LOG_PID, LOG_DAEMON);
  13. #else
  14.  (void) openlog(argv[0], LOG_PID);
  15. #endif
  16.  
  17.  path = «/usr/env»;
  18.  user = «root»;
  19.  cmd = «/usr/local/sbin/proftpd»;
  20.  
  21.  if (chdir(path)) {
  22.  syslog(LOG_ERR, «chdir(%s): %m», path);
  23.  return (0);
  24.  }
  25.  if ((pwd = getpwnam(user)) == 0) {
  26.  syslog(LOG_ERR, «%s: user unknown», user);
  27.  return (0);
  28.  }
  29.  /* Do the chroot() before giving away root privileges. */
  30.  
  31.  if (chroot(path)) {
  32.  syslog(LOG_ERR, «chroot(%s): %m», argv[1]);
  33.  return (0);
  34.  }
  35.  /* Switch group id then user id. */
  36.  
  37.  if (setgid(pwd->pw_gid)) {
  38.  syslog(LOG_ERR, «setgid(%d): %m», pwd->pw_gid);
  39.  return (0);
  40.  }
  41.  if (setuid(pwd->pw_uid)) {
  42.  syslog(LOG_ERR, «setuid(%d): %m», pwd->pw_uid);
  43.  return (0);
  44.  }
  45.  endpwent();
  46.  (void) execvp(cmd, argv);
  47.  syslog(LOG_ERR, «%s: %m», argv[1]);
  48.  return (0);
  49. }





No votes yet




Запись опубликована в рубрике Без рубрики. Добавьте в закладки постоянную ссылку.