과 함께 일하고 있습니다 rsh
. 처음부터 끝까지 전체 과정을 확인하고 싶습니다. 이를 위해 나는 strace
.
운영 체제 이름은 CentOS입니다. 저는 단일 컴퓨터에서 작업하고 있으며 서버와 클라이언트는 동일한 컴퓨터에 있습니다.
내 명령은,rsh localhost ulimit -n
추적을 위해 strace rsh localhost ulimit -n
.
위 명령을 실행하는 동안 열린 모든 파일을 읽었습니다. 그러나 ulimit -n
rsh의 모든 명령은 rsh 데몬에 의해 실행되므로 rsh 서버가 제한을 설정하는 방법을 추적하고 싶습니다 .
제가 찾고 있는 시스템 콜은 인데, 를 setrlimit
사용해도 이 시스템 콜을 보여주지 않습니다 strace rsh localhost ulimit -n
.
이를 위해서는 rsh 서버인 rsh 데몬을 추적해야 합니다. 하지만 이 작업을 어떻게 수행할 수 있는지 모르겠습니다.
명령어와 설명을 알려주세요.
현재 시나리오에서는 rsh가 사용되지 않는다는 것을 알고 있지만 내 프로젝트에서는 rsh를 사용하고 있으므로 rsh가 나쁘다고 말하지 마세요. 나는 이 모든 것을 알고 있습니다.
편집자 No.1
$ sudo lsof -i :514
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
syslogd 2210 root 9u IPv4 6259 UDP *:syslog
xinetd 2658 root 8u IPv4 8745 TCP *:shell (LISTEN)
그리고 /etc/xinetd.d
rshd는 포함되지 않으며 rsh, rexec, rlogin, rsync 등이 포함됩니다.
편집자 2호[Chris Down의 댓글 관련]
rsh localhost strace -o log_new bash -c 'ulimit -n'
달릴 때와는 다른 대답이 나오네요strace rsh localhost ulimit -n
execve("/bin/bash", ["bash", "-c", "ulimit", "-n"], [/* 15 vars */]) = 0
brk(0) = 0x13e86000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbab2000
uname({sys="Linux", node="jhamb.XXX.XXX", ...}) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=57641, ...}) = 0
mmap(NULL, 57641, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2af7bbab3000
close(3) = 0
open("/lib64/libtermcap.so.2", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\17\300T4\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=15584, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbac2000
mmap(0x3454c00000, 2108688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3454c00000
mprotect(0x3454c03000, 2093056, PROT_NONE) = 0
mmap(0x3454e02000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x3454e02000
close(3) = 0
open("/lib64/libdl.so.2", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\16@T4\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=23360, ...}) = 0
mmap(0x3454400000, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3454400000
mprotect(0x3454402000, 2097152, PROT_NONE) = 0
mmap(0x3454602000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x3454602000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\332\1T4\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1726320, ...}) = 0
mmap(0x3454000000, 3506520, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3454000000
mprotect(0x345414f000, 2097152, PROT_NONE) = 0
mmap(0x345434f000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14f000) = 0x345434f000
mmap(0x3454354000, 16728, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3454354000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbac3000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbac4000
arch_prctl(ARCH_SET_FS, 0x2af7bbac3dd0) = 0
mprotect(0x3454602000, 4096, PROT_READ) = 0
mprotect(0x345434f000, 16384, PROT_READ) = 0
mprotect(0x3453e1c000, 4096, PROT_READ) = 0
munmap(0x2af7bbab3000, 57641) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
open("/dev/tty", O_RDWR|O_NONBLOCK) = -1 ENXIO (No such device or address)
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffb504cb00) = -1 EINVAL (Invalid argument)
brk(0) = 0x13e86000
brk(0x13ea7000) = 0x13ea7000
getuid() = 500
getgid() = 500
geteuid() = 500
getegid() = 500
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
open("/proc/meminfo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbab3000
read(3, "MemTotal: 3920228 kB\nMemFre"..., 4096) = 777
close(3) = 0
munmap(0x2af7bbab3000, 4096) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
rt_sigaction(SIGQUIT, {0x1, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
uname({sys="Linux", node="jhamb.XXX.XXX", ...}) = 0
stat("/home/service", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat(".", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
getpid() = 30873
getppid() = 30829
stat(".", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat("/home/service/bin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/local/sbin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/sbin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/sbin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/kerberos/bin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/bin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=801512, ...}) = 0
access("/bin/bash", X_OK) = 0
access("/bin/bash", R_OK) = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=801512, ...}) = 0
access("/bin/bash", X_OK) = 0
access("/bin/bash", R_OK) = 0
getpgrp() = 30829
rt_sigaction(SIGCHLD, {0x436080, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
getpeername(0, {sa_family=AF_INET, sin_port=htons(61000), sin_addr=inet_addr("127.0.0.1")}, [5255137823777882128]) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
getrlimit(RLIMIT_FSIZE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
fstat(1, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbab3000
write(1, "unlimited\n", 10) = 10
exit_group(0) = ?
편집자 3호
# grep -e ulimit -e setrlimit rsh.strace.
rsh.strace.31472:14:22:42.966361 setrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0
rsh.strace.31474:14:22:43.085822 execve("/bin/bash", ["bash", "-c", "ulimit -n"], [/* 4 vars */]) = 0
rsh.strace.31474:14:22:43.546754 setrlimit(RLIMIT_CORE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
편집 4: /etc/security/limits.conf
댓글 삭제됨
* soft core unlimited
* hard core unlimited
@service hard nofile 13000
@service soft nofile 13000
* soft nofile 12000
* hard nofile 12000
답변1
서버에서 어떤 서버 프로세스 rsh
(즉, shell
서비스)가 실행되고 있는지 확인해야 합니다. 전통적으로 이는 TCP 포트(514) 에서 수신 대기 하고 들어오는 연결에 대해 명령을 실행하는 inetd
메타 데몬에 의해 시작됩니다 .xinetd
shell
rshd
lsof -i tcp:shell
(루트로서) 해당 포트에서 어떤 프로세스가 수신 대기 중인지 알려줍니다.
다음 명령을 사용하여 추적할 수 있습니다.
strace -tt -ff -o rsh.strace -p "the-PID"
이 -ff
옵션은 포크를 따라가며 각 프로세스에 대한 로그 파일을 생성하므로 읽기가 더 쉽습니다.
로그 파일의 이름은 해당 프로세스의 프로세스 ID로 rsh.strace.<pid>
지정 됩니다. 서버를 실행하기 위해 새로운 프로세스가 생성됩니다 . 이 프로세스 자체는 사용자의 로그인 셸을 실행하기 위해 다른 프로세스를 생성할 수 있으며, 해석 시 자체적으로 여러 프로세스를 생성할 수 있습니다 ( 사용자의 로그인 셸인 경우 예). 또는 런타임 시에도 해석될 수 있습니다 . 로그인 쉘이 아닙니다).<pid>
xinetd
rshd
~/.bashrc
bash
~/.bashrc
rsh
그러면 누가 이 작업을 수행했는지 확인할 수 있습니다 setrlimit
.
grep setrlimit rsh.strace.*
일단 프로세스를 알아냈습니다. 너 하나 만들 수 있어
grep execve rsh.strace.<that-pid>
이 작업을 수행하기 전에 프로세스가 setrlimit
명령을 실행했는지 확인하면 ulimit
프로세스가 그렇지 않은 경우 execve
해당 부모 또는 조부모가 실행한 것입니다. /를 실행하는 프로세스를 확인하여 fork
상위 프로세스를 찾을 수 있습니다 . clone
예를 들면 다음과 같습니다.<pid>
grep -E '(clone|fork).*= <that-pid>' rsh.strace.*
프로세스가 inetd
/ xinetd
이고 inetd
그 외에도 많은 다른 서비스를 제공하는 경우 대신 해당 서비스에 대해 실행 shell
되도록 구성을 변경 하거나 실제 서비스를 호출하는 래퍼 스크립트를 만들 수 있습니다 .strace -tt -ff -o /var/log/rsh.strace in.rshd
in.rshd
shell
in.rshd
in.rshd
strace
이제 설정할 수 있는 두 가지 항목 ulimit
은 원격 사용자의 로그인 셸 PAM
( pam_limits
모듈 및 을 통해) 시작 스크립트입니다./etc/security/limits.conf
후자의 경우 stracing
rshd
대신 로그인 쉘에서 쉘 추적을 활성화할 수 있습니다. 예를 들어 원격 사용자의 로그인 셸이 bash
또는 인 sh
경우 sh
심볼릭 링크로 다음을 수행하는 래퍼 스크립트로 변경할 bash
수 있습니다 /usr/sbin/in.rshd
(또는 데몬 명령이 있는 경우 ).rsh
#! /bin/sh -
exec /usr/bin/env SHELLOPTS=xtrace "$0.bin" "$@"
로 이름을 바꿉니다 in.rshd.bin
.
답변2
나는 그것에 대한 경험이 많지 않지만 rsh
이것이 내가 그것을 해결하는 데 사용했던 것입니다 strace
.
이 플래그를 사용하여 실행 중인 프로세스를 추적할 수 있습니다 -p
. 그래서 이런 것
linux$ strace -p $(pidof rshd) -o logfile.txt
rsh
또는 strace를 사용하도록 데몬을 시작하는 스크립트를 수정할 수 있습니다 . 이를 위해 strace -o logfile을 사용하는 것이 가장 좋습니다. 그렇지 않으면 rsh 데몬을 시작하는 스크립트에 의해 출력이 숨겨질 수 있습니다.
답변3
매우 간단합니다. 이 작업을 수행하면 rsh machine command
명령 이 실행되는 일이 발생합니다(즉, 동일한 시스템에서 command
) . 이것은 그것을 부르는 것과 관련된 것과 전혀 관련이 없습니다. 거기에서 무슨 일이 일어나고 있는지 알고 싶다면 무슨 일이 일어나고 있는지 살펴보십시오.machine
rsh localhost ulimit -u
ulimit -u
localhost
rsh
ulimit -u
얼굴이 파랗게 질 때까지 분석할 수 있습니다 rshd
. (1) 연결을 가져와 허용되는지 확인하고, (2) 실행할 명령을 수집하고, (3) 명령을 실행하기 위해 분기/실행을 수행하는 것 외에는 아무 작업도 수행하지 않습니다. , 반환 출력을 보내려면 연결하십시오. 특히 어떤 ulimit에서도 이런 일이 발생하는 것을 볼 수 없습니다.