프로덕션 코드에는 "netstat"를 사용하는 sh 스크립트가 있습니다. 특정 포트에서 수신 대기 중인 모든 PID를 검색하려면 "netstat -lntup" 명령을 사용합니다. 명령을 ss -lntup으로 바꿨습니다. 이제 대부분의 경우 두 명령의 출력은 동일하지만 경우에 따라 "ss"는 동일한 포트에 대해 여러 pid를 반환합니다.
# ss -lntup | grep http
tcp LISTEN 0 128 *:80 *:* users:(("httpd",pid=2355,fd=4),("httpd",pid=1962,fd=4),("httpd",pid=1961,fd=4),("httpd",pid=1960,fd=4),("httpd",pid=1955,fd=4))
tcp LISTEN 0 128 *:443 *:* users:(("httpd",pid=2355,fd=6),("httpd",pid=1962,fd=6),("httpd",pid=1961,fd=6),("httpd",pid=1960,fd=6),("httpd",pid=1955,fd=6))
이 목록을 어떻게 해석해야 합니까? PID가 어떤 식으로든 관련되어 있나요? 여러 프로세스가 동시에 동일한 PID를 수신할 수 있습니까?
감사해요
답변1
PID가 어떤 식으로든 관련되어 있나요?
이 경우에는 분명히 그렇습니다. 공통 상위 프로세스가 있거나 프로세스 중 하나가 다른 프로세스의 상위입니다.
공용 파일 핸들(포트 80의 경우 4, 포트 443의 경우 6)은 하위 프로세스를 시작하기 전에 상위 프로세스가 "소켓"을 생성했음을 나타냅니다.
여러 프로세스가 동시에 동일한 포트를 수신할 수 있습니까?
포트를 수신하는 프로세스(pid)가 아니라 포트에서 수신하는 "소켓"입니다.
소켓은 컴퓨터 메모리에 있는 네트워크 관련 개체입니다.
Eduardo Trápani가 이미 작성한 것처럼 SO_REUSEPORT를 사용하면 여러 소켓이 포트에서 수신 대기할 수 있습니다. 그러나 여기서는 (아마도) 그렇지 않습니다. 두 개의 소켓만 관련되어 있다고 가정합니다(포트 80에 하나, 포트 443에 하나).
프로세스(pid)가 소켓을 생성한 다음 하위 프로세스를 생성하는 경우 해당 프로세스와 해당 하위 프로세스는 일반적으로 하위 프로세스가 생성된 후 소켓을 공유합니다.
운영 체제는 어떤 소켓이 어떤 포트에서 수신 대기 중인지 알고 있지만 소켓은 (적어도 공식적으로) 여러 PID 간에 공유되므로 실제로 수신 대기 중인 PID를 알아낼 방법이 없습니다.
나는 부모 프로세스만이 실제로 소켓을 사용한다고 가정하고 있지만 운영 체제는 이를 알 수 없습니다.
답변2
PID가 어떤 식으로든 관련되어 있나요?
불필요한. 그러나 포트 하이재킹을 방지하려면 동일한 유효 사용자 ID에 속해야 합니다.
여러 프로세스가 동시에 동일한 PID/포트를 수신할 수 있습니까 ?
예, 소켓 옵션 SO_REUSEPORT를 사용하세요.이 페이지(파이썬 예제 포함) 작동 방식과 SO_REUSEADDR(서버에서도 사용됨)과의 관계를 설명합니다.
다음은 페이지에서 발췌한 내용입니다.
SO_REUSEPORT
이 옵션의 동작은 SO_REUSEADDR 개념과 유사하지만 이 옵션을 사용하면 여러 TCP/UDP 서버 소켓을 정확히 동일한 IP 및 동일한 포트에 바인딩할 수 있습니다.
그러나 소켓에는 한 가지 제한 사항이 있습니다. SO_REUSEADDR에 없는 동일한 IP와 동일한 포트를 공유할 수 있습니다. IP/포트를 공유하는 모든 소켓은 동일한 유효 사용자가 있는 프로세스에 의해 생성되어야 합니다. 이는 UDP/TCP 프로토콜에 적용될 수 있습니다. 유효한 사용자를 돌보지 않고 SO_REUSEADDR만 사용하여 여러 UDP 서버 소켓을 바인딩할 수 있습니다(root open *:80으로 실행된 processA 및 userA가 실행한 processB는 SO_REUSEADDR open *:80을 사용할 수 있음). ). 그러나 SO_REUSEPORT는 허용되지 않습니다. 이 시점부터 SO_REUSEPORT가 더 제한적이라고 생각할 수 있습니다.