다른 앱에서 생성된 기존 소켓의 소켓 옵션이 표시됩니까?
-
06-07-2019 - |
문제
기존 소켓에 특정 소켓 옵션이 설정되어 있는지 테스트하고 싶습니다.즉, 다음에서 볼 수 있는 거의 모든 것입니다.
#!/usr/bin/env python
'''See possible TCP socket options'''
import socket
sockettypelist = [x for x in dir(socket) if x.startswith('SO_')]
sockettypelist.sort()
for sockettype in sockettypelist:
print sockettype
옵션을 어떻게 보는지 아시는 분 계시나요? 기존의 소켓, 즉 다른 프로세스에 의해 생성된 소켓입니까?아아, 내가 Python 소켓 프로그래밍에 관해 읽은 거의 모든 문서는 새로운 소켓을 만드는 것에 관한 것입니다.
해결책
불행히도, Nailer의 답변은 SOL_TCP 레벨 소켓 옵션 만 포착하며 SO_Socket 레벨 옵션 (SO_KEEPALIVE와 같은)은 아닙니다.
일부 배포판은 SystemTap과 함께 몇 가지 예를 제공합니다. 그중 하나는 pfiles.stp입니다. 실행중인 프로세스의 소켓에서 소켓 옵션을 얻는 데 사용할 수 있습니다. 파일의 예 :
$ ./pfiles.stp `pgrep udevd`
787: udevd
Current rlimit: 32 file descriptors
0: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
O_RDWR|O_LARGEFILE
/dev/null
1: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
O_RDWR|O_LARGEFILE
/dev/null
2: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
O_RDWR|O_LARGEFILE
/dev/null
3: S_IFDIR mode:0600 dev:0,9 ino:1 uid:0 gid:0 rdev:0,0
O_RDONLY
inotify
4: S_IFSOCK mode:0777 dev:0,4 ino:2353 uid:0 gid:0 rdev:0,0
O_RDWR
socket:[2353]
SO_PASSCRED,SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(111616)
sockname: AF_UNIX
5: S_IFSOCK mode:0777 dev:0,4 ino:2354 uid:0 gid:0 rdev:0,0
O_RDWR
socket:[2354]
SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(33554432)
ulocks: rcv
6: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
O_RDONLY|O_NONBLOCK
pipe:[2355]
7: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
O_WRONLY|O_NONBLOCK
pipe:[2355]
다른 팁
파이썬에서는 불가능합니다.
Linux 커널은 BSD 및 기타 UNIX와 같은 OSS와 달리 TCP 소켓 상태에 대해보고 할 메커니즘을 제공하지 않습니다. 커널 이이 정보를 노출시키지 않으므로 Python-Linux-Procfs 모듈 또는 이와 유사한 정보를 통해 볼 수 없습니다.
Q. 'LSOF가 소켓 옵션, 소켓 상태 및 방언의 TCP 플래그 및 값을보고하지 않는 이유는 무엇입니까?'
A. '소켓 옵션, 소켓 상태 및 TCP 플래그 및 값은 /Proc 파일 시스템을 통해 사용할 수 없습니다.'
그러나 SystemTap의 네트워크 탭 세트는 프로세스에 의해 설정된 소켓 옵션을 가로 채는 데 사용할 수있는 tcp.setsockopt 브레이크 포인트를 제공하지만 파이썬이 아닌 Stap으로 처리됩니다.
필요한 탭 세트를 다음과 같이 만들었습니다.
# Show sockets setting options
# Return enabled or disabled based on value of optval
function getstatus(optlen)
{
if ( optlen == 1 )
return "enabling"
else
return "disabling"
}
probe begin
{
print ("\nChecking for apps making socket calls\n")
}
# See apps setting a socket option
probe tcp.setsockopt
{
status = getstatus(user_int($optval))
printf (" App '%s' (PID %d) is %s socket option %s... ", execname(), pid(), status, optstr)
}
# Check setting the socket option worked
probe tcp.setsockopt.return
{
if ( ret == 0 )
printf ("success")
else
printf ("failed")
printf ("\n")
}
probe end
{
print ("\nClosing down\n")
}
소켓 라이브러리는 실제로 새로운 소켓을 생성하고 조작하는 것입니다.다른 프로세스에서 생성된 소켓은 보안상의 이유로 표시되지 않습니다.임의의 응용 프로그램이 자신의 소켓을 관리하는 방식을 변경하거나 소켓에서 데이터를 더 나쁘게 읽는 방식을 변경하는 것을 원하지 않을 것입니다.따라서 소켓은 핸들에 의해 참조되는 시스템 개체이며 (괜찮은 OS에서는) 액세스 권한이 적용됩니다.그렇기 때문에 다른 프로세스에서 생성된 기존 소켓을 나열할 수 없습니다.
결국 소켓 핸들을 검색하는 방법을 찾을 수 있습니다(어딘가에 방법이 있을 것입니다. Windows에서 시스템 핸들을 나열하는 방법을 본 기억이 납니다). 그러나 이는 여전히 OS에 매우 특정한 것이므로 Python에서는 사용할 수 없을 가능성이 높습니다. 그리고 여전히 해당 소켓에서 어떤 작업도 수행할 수 있는 권한이 없을 수 있습니다.
이제 특정 애플리케이션이 특정 기능을 어떻게 달성했는지 알고 싶다면 다른 방법이 있습니다.가장 확실한 방법은 프록시나 방화벽을 설치하거나(Kerio WinRoute 방화벽에 소켓 옵션이 나열되어 있다는 것을 기억합니다), 아니면 스택오버플로우에 이 기능을 달성하는 방법을 묻는 것입니다.