Использую пропатченную библиотеку libcap и пропатченное ядро 2.6.16. В результате не работает ntpdate, ntpd - они запускаются в chroot да еще и от имени другого пользователя, насколько я понимаю.
Выглядит это так:
# ntpdate -q -v ntp.psn.ru
29 Oct 14:45:39 ntpdate[27589]: ntpdate 4.1.2@1.892 Tue Apr 20 03:31:20 MSD 2004 (1)
29 Oct 14:45:39 ntpdate[27589]: setreuid failed
Если вызвать:
# strace ntpdate -q -v ntp.psn.ru
то конец вывода будет таким:
open("/etc/passwd", O_RDONLY) = 4
fcntl64(4, F_GETFD) = 0
fcntl64(4, F_SETFD, FD_CLOEXEC) = 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=5260, ...}) = 0
mmap2(NULL, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7def000
read(4, "root0:0:System Administrator:"..., 131072) = 5260
close(4) = 0
munmap(0xb7def000, 131072) = 0
chroot("/var/empty") = 0
chdir("/") = 0
setgid32(109) = 0
prctl(0x8, 0x1, 0x805062c, 0x8048983, 0xb7e61588) = 0
setresuid32(-1, 104, -1) = 0
capset(0x19980330, 0, {CAP_SYS_TIME, CAP_SYS_TIME, 0}) = 0
setreuid32(104, 104) = -1 EPERM (Operation not permitted)
time(NULL) = 1162122423
write(2, "29 Oct 14:47:03 ", 1629 Oct 14:47:03 ) = 16
getpid() = 27612
write(2, "ntpdate[27612]: setreuid failed\n", 32ntpdate[27612]: setreuid failed
) = 32
exit_group(1) = ?
Process 27612 detached
Если загрузить обычное (непатченное ядро), то все работает нормально. 104 - это uid для пользователя ntp.
Что с этим можно сделать, крайне желательно наличие ntp на ejudge-сервере.
Проблемы с запуском программ на пропатченном ядре
Last edited by dk on 24 November 2006, 20:09, edited 2 times in total.
То есть реализовывать контроль процессов полностью в user-space?
Насколько я знаю, некоторые так и делают. Можно сделать программку на базе strace, которая будет трассировать программу и перехватывать "нехорошие" системные вызовы. Кроме того, можно периодически просматривать /proc/PID на предмет контроля превышения максимального разрешенного размера адресного пространства.
Мое отношение к подобным вещам скорее отрицательное. Вот выдержка из одного моего письма:
Насколько я знаю, некоторые так и делают. Можно сделать программку на базе strace, которая будет трассировать программу и перехватывать "нехорошие" системные вызовы. Кроме того, можно периодически просматривать /proc/PID на предмет контроля превышения максимального разрешенного размера адресного пространства.
Мое отношение к подобным вещам скорее отрицательное. Вот выдержка из одного моего письма:
> Вопрос такой.
> Чем обусловлено твое решение следить (время исполнения,
> использование памяти и проч.)за откомпилированными решениями
> участников ядром операционной системы? Не лучше ли делать это на
> виртуальной машине, чтобы иметь полный контроль надо всем, эмулируя
> работу всех инструкций процессора и отслеживая таким образом все
> возможные ситуации?
На это есть несколько причин.
Во-первых, ядро ОС само по себе является виртуальной машиной. Поскольку в
задачи ядра и так входит управление доступом процессов к ресурсам, то
поместить дополнительную (очень простую на самом деле) проверку ограничений
в ядро представляется логичным. В результате получается безопасная система с
ничтожными накладными расходами.
В современных версиях Linux есть подобные системы (типа SELinux), которые
очень гибки и позволяют практически произвольным образом настраивать
ограничения на процессы. Честно говоря, в SELinux я не разбирался, возможно,
что можно настроить и его.
Любая виртуальная машина требует значительных накладных расходов. Это
проценты и десятки процентов, если перехватываются только системные вызовы,
а сам код выполняется процессором, и тысячи процентов, если речь идёт о
полной интерпретации. Кроме того, отслеживать поведение процессов под
виртуальными машинами - это отдельная задача, поскольку межпроцессные
коммуникации существенно затруднены.
Ну я в подробностях всех этих юзерспэйсов не очень разбираюсь... Я смотрю на ситуацию исключительно со стороны простоты развертывания системы, а в этом случае модификация ядра крайне нежелательна.
Коли уж на то пошло, то лучше действительно пускать на виртуальной машине под linux-vserver, я полагаю. Но я в этом тоже мало понимаю.
Коли уж на то пошло, то лучше действительно пускать на виртуальной машине под linux-vserver, я полагаю. Но я в этом тоже мало понимаю.
Следующая софтина, не работающая на патченном ядре: nmap
# nmap localhost
Starting nmap 3.55 ( http://www.insecure.org/nmap/ ) at 2006-11-24 20:05 MSK
nmap: setreuid failed: Operation not permitted
# strace nmap localhost
<SKIPPED>
chroot("/var/resolv") = 0
chdir("/") = 0
setgid32(430) = 0
setresuid32(-1, 145, -1) = 0
capset(0x19980330, 0, {CAP_NET_RAW, CAP_NET_RAW, 0}) = 0
setreuid32(145, 145) = -1 EPERM (Operation not permitted)
write(2, "nmap: ", 6nmap: ) = 6
write(2, "setreuid failed", 15setreuid failed) = 15
write(2, ": Operation not permitted", 25: Operation not permitted) = 25
write(2, "\n", 1
) = 1
munmap(0xb7fc3000, 4096) = 0
exit_group(1) = ?
Process 19356 detached
# nmap localhost
Starting nmap 3.55 ( http://www.insecure.org/nmap/ ) at 2006-11-24 20:05 MSK
nmap: setreuid failed: Operation not permitted
# strace nmap localhost
<SKIPPED>
chroot("/var/resolv") = 0
chdir("/") = 0
setgid32(430) = 0
setresuid32(-1, 145, -1) = 0
capset(0x19980330, 0, {CAP_NET_RAW, CAP_NET_RAW, 0}) = 0
setreuid32(145, 145) = -1 EPERM (Operation not permitted)
write(2, "nmap: ", 6nmap: ) = 6
write(2, "setreuid failed", 15setreuid failed) = 15
write(2, ": Operation not permitted", 25: Operation not permitted) = 25
write(2, "\n", 1
) = 1
munmap(0xb7fc3000, 4096) = 0
exit_group(1) = ?
Process 19356 detached