Linux에서 포트가 열려 있는지 효율적으로 테스트합니까?


197

bash 스크립트에서 포트 445가 서버에서 열려 있는지 / 듣지 않는지 어떻게 빨리 알 수 있습니까 ?

몇 가지 옵션을 시도했지만 빠른 것을 원합니다.
1. lsof -i :445 (초가 걸립니다)
2. netstat -an |grep 445 |grep LISTEN(초가 걸립니다)
3. telnet(돌아 오지 않음)
4. nmap, netcat서버에서 사용할 수 없습니다

먼저 열거하지 않고 그 후에 greps하는 방법을 아는 것이 좋습니다.


1
netcat이 있습니까? 빠른 장애 경로 IIRC가 있습니다. netcat.sourceforge.net
JimR

5
netstat -lnt( -t유무에 관계없이 -a)는 수신 TCP 연결로만 출력을 제한합니다. 속도가 약간 빨라질 수 있습니다. -4IPv6이 필요하지 않은 경우에만 IPv4 를 추가 할 수 있습니다 .
Bartosz Moczulski

lsof -i는 개인적인 마음에 드는 것입니다.
매트 조이스

14
netstat -an | grep PORTNUMBER | grep -i listen출력이 비어 있으면 포트가 사용 중이 아닙니다.
automatix

lsof느린 지 모르겠지만 일반적으로 나열된 솔루션 중 가장 좋습니다. 귀하의 netstat솔루션은 매우 신뢰할 수 없습니다 (사용할 때마다 추측 할 수 있습니다 grep; 예를 들어 누군가가 4450을 듣고 있다면 true를 반환합니다). telnet그리고 netcat실제로 항상 당신이 원하는하지 않을 수 있습니다 연결을 만들려고.
petersohn

답변:


155

내가 최근에 알게 된 놀람은 Bash가 파일 설명 자로 tcp 연결을 기본적으로 지원한다는 것이다. 쓰다:

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6

0,1,2는 stdin, stdout 및 stderr이므로 파일 설명 자로 6을 사용하고 있습니다. Bash는 자식 프로세스 에 5를 사용하기도 하므로 3,4,6,7,8 및 9는 안전해야합니다.

아래 주석 에 따라 스크립트에서 로컬 서버 에서 수신 대기하는지 테스트하십시오 .

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection

누군가가 듣고 있는지 확인하려면 루프백으로 연결을 시도하십시오. 실패하면 포트가 닫히거나 액세스가 허용되지 않습니다. 그런 다음 연결을 닫으십시오.

이메일 전송, 실패시 스크립트 종료 또는 필요한 서비스 시작과 같은 사용 사례에 맞게이를 수정하십시오.


2
이것은 단지 나를 위해 매달렸다.
Aman Jain

@AmanJain cat은 EOF 또는 Ctrl-C가 종료 될 때까지 기다립니다. 프로토콜에 맞게 조정해야합니다. BTW 원격 서버에서 이것을 실행하고 있습니까?
스펜서 Rathbun

서버의 스크립트에 /etc/init.d/ 아래에 포트 확인 코드를 포함하고 싶습니다
Aman Jain

@ AmanJain 로컬 시스템을 위해 업데이트했습니다. 듣고 있는지 확인하고 싶습니까? http를 통한 페이지 요청과 같은 프로토콜 검사가 없습니까?
스펜서 Rathbun

1
모든 OS (예 : 오늘 발견 한 우분투 16)가 /dev/tcp/IP/PORT트리 를 구축하기 위해 컴파일 된 bash와 함께 제공되는 것은 아니기 때문에 이것은 신뢰할 수있는 방법이 아닙니다.
dyasny

107

여기에 "빠른 답변"이라는 매우 짧은 내용이 있습니다. 셸 스크립트에서 원격 TCP 포트가 열려 있는지 테스트하는 방법은 무엇입니까?

nc -z <host> <port>; echo $?

"원격"주소로 127.0.0.1과 함께 사용합니다.

포트가 열려 있으면 "0"을, 포트가 닫혀 있으면 "1"을 반환합니다.

예 :

nc -z 127.0.0.1 80; echo $?

-z nc는 데이터를 보내지 않고 수신 데몬 만 스캔하도록 지정합니다. 이 옵션을 -l 옵션과 함께 사용하면 오류가 발생합니다.


2
가장 쉬운 방법 인 것 같습니다. 감사합니다. 샘플 스크립트 링크는 더 이상 작동하지 않지만 어쨌든 자체 설명이 가능합니다.
derFunk

좋은! 이것은 많은 포트가 열려있는 서버의 다른 답변보다 훨씬 빠릅니다. netstat / lsof가 1s +를받는 동안 <0.01 초 안에 반환
Tim

2
Fedora, Centos 등의 최신 배포판이 제공되는 nmap 기반 ncat에서는 -z 플래그를 사용할 수 없습니다 (nmap-ncat-6.01-9.fc18.x86_64)
Zack

9
직관적으로, 포트가 열려 있으면 "0"을, 포트가 닫혀 있으면 "1"을 반환합니다.
Sean

3
@Sean unix 명령은 일반적으로 성공을 나타내고 실패가 0이 아닌 경우 '0'을 리턴합니다. 따라서 '0'은 성공적으로 연결되었음을 나타내고 0이 아닌 경우 어떤 이유로 연결되지 않았 음을 나타냅니다. 그러나 'nc'의 일부 버전은 '-z'인수를 지원하지 않으므로 stackoverflow.com/a/25793128/6773916 이 더 나은 솔루션 일 수 있습니다.
Rich Sedman

89

훨씬 빠른 결과를 위해 netstat를이 방법으로 사용할 수 있습니다.

Linux에서 :

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

Mac에서 :

netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

포트에서 수신 대기중인 프로세스 목록 (이 예에서는 445)을 출력하거나 포트가 비어 있으면 아무 것도 출력하지 않습니다.


1
netstat 구문이 올바르지 않습니다. netstat -ln --tcp는 작동하지만 여전히 느립니다
Aman Jain

6
실제로 올바른 구문이지만 Linux를 사용하고 있으며 Mac에 있습니다. Linux의 경우 다음을 사용하십시오.netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ".445"'
anubhava

21
이것은 아무것도 출력하지 않았습니다.
Jürgen Paul

1
문제는 리눅스에 관한 것이 었으므로 아마도 의견에 답이 있어야합니다.
UpTheCreek

1
포트 80을 확인하려면을 사용해야했습니다 awk '$6 == "LISTEN" && $4 ~ "80$"'. 포트 번호 앞에 점을 확인하는 대신을 \.80사용했습니다 80$. 그렇지 않으면,이 포함 된 IP 주소 .8080같은 포트로 일치합니다 8000.
Patrick Oscity

37

이를 위해 netcat을 사용할 수 있습니다.

nc ip port < /dev/null

서버에 연결하고 직접 연결을 닫습니다. netcat이 연결할 수 없으면 0이 아닌 종료 코드를 리턴합니다. 종료 코드는 변수 $?에 저장됩니다. 예로서,

nc ip port < /dev/null; echo $?

netcat이 포트에 성공적으로 연결할 수있는 경우에만 0을 반환합니다.


1
이 답변에는 더 많은 투표가 필요합니다. nc는이 경우에 완벽하게 작동합니다. / dev / tcp 트릭은 영리하지만 신호 인터럽트가있는 스크립트를 구현하는 것은 어려운 것 같습니다.
Avindra Goolcharan

5
nc-z이 목적을위한 플래그를 가지고 있으며, 에서 입력 할 필요가 없습니다 /dev/null. -z위 의 플래그를 사용하여 이미 답변이 있습니다 .
Abe Voelker

2
@AbeVoelker 모든 버전의 nc가 -z 플래그를 지원하지는 않습니다. 나는 CentOS 7을 사용하고 있으며 Tony의 솔루션이 내가 필요로하는 것을 발견했습니다.
Shadoninja

@Shadoninja 알아 두세요! 2014 년부터 내 의견에서 반전을 편집 할 수 있다면 그렇게 할 것입니다.
Abe Voelker

'nc'는 더 이상 '-z'를 지원하지 않으므로이 답변이 최상의 솔루션 인 것 같습니다.
Rich Sedman

18

bash를 사용하여 Spencer Rathbun의 답변을 기반으로합니다.

true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed

"Connection Refused"메시지가 표시되지 않습니다. 서비스가 영원히 기다리지 않고 연결을 수락하면 자동 종료됩니다.
Seff

새로운 연결 후 데이터를 보내지 않는 서비스를위한 최상의 솔루션입니다. netcat 호출보다 약 20 배 빠릅니다. 단축 될 수 있음: &>/dev/null </dev/tcp/127.0.0.1/$PORT
ens

16

그것들은 / proc / net / tcp에 나열되어 있습니다.

":"다음의 두 번째 열입니다 (16 진수).

> cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 10863 1 ffff88020c785400 99 0 0 10 -1                     
   1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7983 1 ffff88020eb7b3c0 99 0 0 10 -1                      
   2: 0500010A:948F 0900010A:2328 01 00000000:00000000 02:00000576 00000000  1000        0 10562454 2 ffff88010040f7c0 22 3 30 5 3                   
   3: 0500010A:E077 5F2F7D4A:0050 01 00000000:00000000 02:00000176 00000000  1000        0 10701021 2 ffff880100474080 41 3 22 10 -1                 
   4: 0500010A:8773 16EC97D1:0050 01 00000000:00000000 02:00000BDC 00000000  1000        0 10700849 2 ffff880104335440 57 3 18 10 -1                 
   5: 0500010A:8772 16EC97D1:0050 01 00000000:00000000 02:00000BF5 00000000  1000        0 10698952 2 ffff88010040e440 46 3 0 10 -1                  
   6: 0500010A:DD2C 0900010A:0016 01 00000000:00000000 02:0006E764 00000000  1000        0 9562907 2 ffff880104334740 22 3 30 5 4                    
   7: 0500010A:AAA4 6A717D4A:0050 08 00000000:00000001 02:00000929 00000000  1000        0 10696677 2 ffff880106cc77c0 45 3 0 10 -1  

그래서 :50세 번째 열에 있는 것 중 하나는 stackoverflow이어야합니다. :)

man 5 proc자세한 내용을 살펴보십시오 . 그리고 sed 등으로 따끔 따끔 따끔 따끔 따끔 따끔 따르는 독자를위한 운동으로 남겨두고 ...


10
ss -tl4 '( sport = :22 )'

2ms는 충분히 빠르다?

콜론을 추가하면 Linux에서 작동합니다.


2
대단한 ss것보다 훨씬 빠릅니다 nc. l을위한 듣기 , 4IPv4를위한 것입니다; sport(물론) 소스 포트를 나타 냅니다. 위의 명령은 수신 TCP 포트 ( t옵션)를 가정합니다 . uUDP에는 옵션을 사용 하거나 두 프로토콜에는 모두 사용하지 않습니다. ss항상 Nixcraft 에 대한 자세한 정보 . 참고 : ss필터는 여기서 작동하지 않습니다. 왜 bash (4.3.11, ss 유틸리티, iproute2-ss131122)는 grep 과 함께 가야하는지 모르겠습니다 .
Campa

ss명령이 결과를 반영하는 종료 코드를 리턴하지 않는 것이 너무 나쁩니다 . 항상 0 종료 코드를 리턴합니다.
John Greene

| grep LISTEN?
leucos

나는 State Recv-Q Send-Q Local Address:Port Peer Address:Port지금? 이것은 무엇을 의미 하는가?
검은

6

Mac과 Linux 모두에서 작동하는 것은 다음과 같습니다.

netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'

안전하게 제거 할 수 있다고 생각합니다 [\\.\:].
Patrick Oscity

6
nc -l 8000

여기서 8000은 포트 번호입니다. 포트가 비어 있으면 쉽게 닫을 수있는 서버가 시작됩니다. 그렇지 않으면 오류가 발생합니다.

nc: Address already in use

5

Linux 테스트 서버 중 하나에서 포트가 열려 있는지 확인하고 싶었습니다. 내 개발 컴퓨터에서 테스트 서버로 텔넷에 연결하여이를 수행 할 수있었습니다. 개발자 컴퓨터에서 다음을 실행하십시오.

$ telnet test2.host.com 8080
Trying 05.066.137.184...
Connected to test2.host.com

이 예에서는 호스트 test2.host.com 에서 포트 8080 이 열려 있는지 확인하고 싶습니다.


1

tcping 은 오버 헤드가 매우 낮은 훌륭한 도구이며 시간을 단축 시키는 인수도 있습니다.

[root@centos_f831dfb3 ~]# tcping 10.86.151.175 22 -t 1
10.86.151.175 port 22 open.
[root@centos_f831dfb3 ~]# tcping 10.86.150.194 22 -t 1
10.86.150.194 port 22 user timeout.
[root@centos_f831dfb3 ~]# tcping 1.1.1.1 22 -t 1
1.1.1.1 port 22 closed.

1
Spencer 솔루션에 추가 설치가 필요하지 않은 경우 tcping을 설치할 가치가 있는지 확실하지 않지만 가장 깨끗하고 사람이 읽을 수있는 솔루션입니다.
bdombro

1

netcat 명령도 사용할 수 있습니다

[location of netcat]/netcat -zv [ip] [port]

또는

nc -zv [ip] [port]

-z – 실제로 데이터를 보내지 않고 수신 데몬을 검색하도록 nc를 설정합니다.
-v – 상세 모드를 활성화합니다.


-2

nmap올바른 도구입니다. 간단히 사용nmap example.com -p 80

로컬 또는 원격 서버에서 사용할 수 있습니다. 또한 방화벽이 액세스를 차단하고 있는지 식별하는 데 도움이됩니다.


-4

iptables를 사용하는 경우 다음을 시도하십시오.

iptables -nL

또는

iptables -nL | grep 445

그것은 단지 iptables 규칙을 나열합니다 ... 이것은 열린 포트와 상관이 없을 수 있습니다.
David Goodwin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.