클라이언트와 서버 응용 프로그램 사이에서 청취 모드에있는 열린 포트를 닫고 싶습니다.
Linux에서 포트를 닫는 수동 명령 행 옵션이 있습니까?
참고 : "연결된 소켓을 소유 한 응용 프로그램 만 소켓을 닫아야합니다. 응용 프로그램이 종료 될 때 발생합니다."
나는 그것이 그것을 여는 응용 프로그램에서만 가능한 이유를 이해하지 못합니다 ...하지만 여전히 다른 방법이 있는지 알고 싶습니다.
클라이언트와 서버 응용 프로그램 사이에서 청취 모드에있는 열린 포트를 닫고 싶습니다.
Linux에서 포트를 닫는 수동 명령 행 옵션이 있습니까?
참고 : "연결된 소켓을 소유 한 응용 프로그램 만 소켓을 닫아야합니다. 응용 프로그램이 종료 될 때 발생합니다."
나는 그것이 그것을 여는 응용 프로그램에서만 가능한 이유를 이해하지 못합니다 ...하지만 여전히 다른 방법이 있는지 알고 싶습니다.
답변:
나는 같은 문제가 있었다. 프로세스는 살아 있어야하지만 소켓은 닫아야합니다. 실행중인 프로세스에서 소켓을 닫는 것은 불가능하지 않지만 어렵습니다.
프로세스를 찾으십시오.
netstat -np
당신은 source/destination ip:port portstate pid/processname
지도를 얻을
프로세스에서 소켓의 파일 디스크립터를 찾으십시오.
lsof -np $pid
프로세스 이름, pid, 사용자, fileDescriptor, ... 연결 문자열 목록이 표시됩니다.
연결과 일치하는 fileDescriptor 번호를 찾으십시오. "97"을 의미하는 "97u"와 같은 것입니다.
이제 프로세스를 연결하십시오.
gdb -p $pid
이제 소켓을 닫습니다 :
call close($fileDescriptor) //does not need ; at end.
예:
call close(97)
그런 다음 gdb를 분리하십시오.
quit
그리고 소켓이 닫힙니다.
sudo lsof -np $pid
약 200 라인을 제공하고 원하는 FD를 찾는 방법에 대해 혼란 스럽습니다. 필자의 경우 프로세스는 Chrome 탭이며 열린 웹 소켓을 닫으려고합니다 ...
shutdown
다음 을 사용하는 것이 좋습니다 call shutdown($fileDescriptor, 0)
..
당신은 여기서 잘못된 질문을하고 있습니다. 소켓을 청취 한 응용 프로그램 외부에서 단순히 포트를 "닫는"것은 실제로 불가능합니다. 이를 수행하는 유일한 방법은 포트를 소유 한 프로세스를 완전히 종료하는 것입니다. 그런 다음 약 1-2 분 후에 포트를 다시 사용할 수있게됩니다. 여기에 무슨 일이 일어나고 있습니까?
포트는 OS가 다른 프로세스에 할당 한 리소스입니다. 이것은 OS에 파일 포인터를 요청하는 것과 유사합니다. 그러나 파일 포인터와 달리 한 번에 하나의 프로세스 만 포트를 소유 할 수 있습니다. BSD 소켓 인터페이스를 통해 프로세스는 포트에서 수신 대기하도록 요청하여 OS가 승인합니다. 또한 OS는 다른 프로세스가 동일한 포트를 얻지 않도록합니다. 언제든지 프로세스는 소켓을 닫아 포트를 해제 할 수 있습니다. 그런 다음 OS는 포트를 회수합니다. 또는 포트를 해제하지 않고 프로세스가 종료되면 OS는 결국 포트를 회수합니다 (즉시 발생하지는 않지만 몇 분 정도 소요됨).
이제 두 가지 이유로 할 수있는 작업 (명령 줄에서 포트를 간단히 닫기)이 불가능합니다. 첫째, 가능하다면 한 프로세스가 단순히 다른 프로세스의 리소스 (포트)를 훔칠 수 있음을 의미합니다. 권한있는 프로세스로 제한되지 않는 한 잘못된 정책입니다. 두 번째 이유는 포트를 계속 실행 시키면 포트를 소유 한 프로세스에 어떤 일이 발생하는지 명확하지 않기 때문입니다. 프로세스의 코드는이 리소스를 소유하고 있다고 가정합니다. 우리가 단순히 그것을 제거했다면, 그것은 자체적으로 충돌하게 될 것입니다. 따라서 OS는 특권 프로세스 인 경우에도 이것을 허용하지 않습니다. 대신, 당신은 단순히 그들을 죽여야합니다.
어쨌든 다음은 특정 포트를 소유 한 프로세스를 종료하는 방법입니다.
sudo netstat -ap | grep :<port_number>
예를 들어 프로세스 유지 포트에 해당하는 라인을 출력합니다.
tcp 0 0 *:8000 *:* LISTEN 4683/procHoldingPort
이 경우, procHoldingPort 는 포트를 연 프로세스의 이름이고 4683 은 pid이며 8000 (TCP 임)은 보유한 포트 번호입니다.
그런 다음 마지막 열을 보면 /가 표시됩니다. 그런 다음 이것을 실행하십시오.
kill <pid>
그래도 문제가 해결되지 않으면 netstat 명령을 다시 실행하여 확인할 수 있습니다. 이 작업을 수행:
kill -9 <pid>
일반적으로 가능하면 SIGKILL을 보내지 않는 것이 좋습니다. 이것이 바로 kill
전에 시도해 보라고하는 이유 kill -9
입니다. 사용 kill
하면 더 부드러운 SIGTERM이 전송됩니다.
내가 말했듯이, 이렇게하면 포트가 다시 열리려면 몇 분이 걸립니다. 나는 이것을 가속화하는 방법을 모른다. 다른 사람이 있다면 듣고 싶습니다.
unix.tools.port.close(<my port number>)
내가 사용하는 것처럼 합리적인 것을 게시 할 때까지 init 6
.
퓨저도 사용 가능
fuser -k -n *protocol portno*
여기서 프로토콜은 tcp / udp이고 portno는 닫으려는 숫자입니다. 예 :
fuser -k -n tcp 37
퓨저 매뉴얼 페이지 에서 추가 정보
fuser
실행 후 종료 된 프로세스 순간을 다시 시작하는 "guardian"프로세스 가 있습니까?
fuser
포트를 사용하여 프로세스를 찾아서 종료하지만 소켓이 닫히지 않았다는 사실을 해결하지는 않습니다. 60 초와 커널이 나를 위해 그것을합니다.
포트와 관련된 소켓을 연 프로세스가 무엇인지 알아 내고 해당 프로세스를 종료시킬 수 있습니다.
그러나 해당 프로세스에 사용중인 모든 항목 (열린 파일, 소켓, 포크, 종료시 올바르게 닫히지 않으면 남아있을 수있는 항목)을 초기화 해제하는 핸들러가 없으면 다음과 같이 만들었을 것입니다. 시스템 성능을 끌어냅니다. 또한 소켓은 커널이 프로세스가 종료되었음을 인식 할 때까지 열린 상태로 유지됩니다. 보통 1 분 정도 걸립니다.
더 좋은 질문은 다음과 같습니다. 어떤 포트 (어떤 프로세스와 함께)를 중지하고 싶습니까?
발견 한 백도어 나 바이러스를 종식시키려는 경우 적어도 종료하기 전에 어떤 데이터가 송수신되는지 알아야합니다. (wireshark는 이것에 좋습니다) (그리고 프로세스의 실행 파일 이름은 삭제하고 재부팅 할 때 다시 나타나지 않도록 할 수 있습니다) 또는 설치 한 것 (예 : HTTPD 또는 FTPD 또는 기타) 인 경우 이미 액세스 할 수 있어야합니다 프로세스 자체.
일반적으로 제어 프로그램이 있습니다 (HTTPD 중지 | 시작 등). 또는 그것이 시스템 일이라면, 엉망이되어서는 안됩니다. 어쨌든, 나는 다른 사람들이 당신에게 "방법"각도를주기 때문에, 나는 당신에게 경고를 줄 것이라고 생각했습니다.
iptables를 수정하고 다시 시작하는 스크립트를 작성할 수 있습니다. 포트에있는 모든 패킷을 삭제하는 규칙을 추가하기위한 스크립트와 해당 규칙을 제거하기위한 스크립트.
다른 답변은 포트에 바인딩 된 프로세스를 종료하는 방법을 보여주었습니다. 원하는 것이 아닐 수도 있습니다. 서버가 계속 실행되도록하지만 클라이언트와의 연결을 방지하려면 프로세스를 중지하지 말고 포트를 차단하십시오.
killcx라는 명령을 사용하여 종료 할 프로세스없이 연결을 닫을 수 있습니다.
killcx [dest_ip:dest_port] {interface} dest_ip : remote IP dest_port : remote port interface (optional) : network interface (eth0, lo etc).
killcx 120.121.122.123:1234 killcx 120.121.122.123:1234 eth0
나는이 답변이 질문 자체에 엄격하게 말하지는 않지만 대답을 읽는 것은 관련 정보 일 수 있음을 알고 있습니다.
소켓을 포트 (및 주소)에 바인딩하는 기본 동작은 프로세스가 갑자기 종료되어 소켓이 닫히면 소켓이 잠시 TIME_WAIT에 유지된다는 것입니다. 즉,이 주소 / 포트에 즉시 리 바인드 할 수 없습니다. 표준 BSD 소켓 인터페이스를 통해 시스템 자체를 개발하는 경우 SO_REUSEADDR 소켓 옵션을 사용하여이 동작을 (적어도 어느 정도) 제어 할 수 있습니다. 소켓이 TIME_WAIT 상태 인 경우 기본적으로 동일한 주소 / 포트에 다시 바인딩 할 수 있습니다. 그래도 포트 당 하나의 소켓!
그러나 TIME_WAIT가 다른 곳에 이미 설명되어 있기 때문에이 정보는 개발 지원으로 만 사용해야합니다.
ss를 사용하여 청취 소켓을 닫을 수 있습니다 .
sudo ss --kill state listening src :1234
여기서 1234는 포트 번호입니다.
ss는 iproute2 패키지의 일부이므로 최신 Linux에 이미 설치되어있는 강력한 변경 사항이 있습니다.
관련 질문에 대한 답변 에서 이에 대해 배웠습니다 .