![사용하지 않는 로컬 포트를 찾는 가장 쉬운 방법은 무엇입니까?](https://linux55.com/image/27695/%EC%82%AC%EC%9A%A9%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EB%A1%9C%EC%BB%AC%20%ED%8F%AC%ED%8A%B8%EB%A5%BC%20%EC%B0%BE%EB%8A%94%20%EA%B0%80%EC%9E%A5%20%EC%89%AC%EC%9A%B4%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
사용하지 않는 로컬 포트를 찾는 가장 쉬운 방법은 무엇입니까?
현재 나는 다음과 같은 것을 사용하고 있습니다 :
port=$RANDOM
quit=0
while [ "$quit" -ne 1 ]; do
netstat -a | grep $port >> /dev/null
if [ $? -gt 0 ]; then
quit=1
else
port=`expr $port + 1`
fi
done
매우 우회적인 느낌이 들기 때문에 내가 놓친 내장 경로와 같은 더 쉬운 경로가 있는지 궁금합니다.
답변1
내 솔루션은 커널이 ip_local_port_range에서 포트를 할당해야 하는 포트 0에 바인딩하는 것이었습니다. 그런 다음 소켓을 닫고 구성에서 해당 포트 번호를 사용하십시오.
이는 꼭 필요한 경우가 아니면 커널이 포트 번호를 재사용하지 않는 것 같기 때문에 작동합니다. 포트 0에 대한 후속 바인딩에는 다른 포트 번호가 할당됩니다. 파이썬 코드:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 0))
addr = s.getsockname()
print(addr[1])
s.close()
이것은 단지 포트 번호를 제공합니다. 60123
.
이 프로그램을 10,000번 실행하면(이 프로그램을 동시에 실행해야 함) 10,000개의 다른 포트 번호를 얻게 됩니다. 그래서 저는 이 포트를 사용하는 것이 꽤 안전하다고 생각합니다.
답변2
애플리케이션이 이를 지원하는 경우 포트 0을 애플리케이션에 전달해 볼 수 있습니다. 애플리케이션이 이를 커널에 전달하면 요청 시 포트가 동적으로 할당되고 사용되지 않는 것이 보장됩니다(모든 포트가 이미 사용 중이면 할당이 실패합니다).
그렇지 않으면 이 작업을 수동으로 수행할 수 있습니다. 답변의 스크립트에는 경쟁 조건이 있으며 이를 피하는 유일한 방법은 열려고 시도하여 열려 있는지 자동으로 확인하는 것입니다. 포트가 사용 중인 경우 포트를 열지 못한 채 프로그램이 종료되어야 합니다.
예를 들어, GNU netcat을 사용하여 수신하려고 한다고 가정합니다.
#!/bin/bash
read lower_port upper_port < /proc/sys/net/ipv4/ip_local_port_range
while :; do
for (( port = lower_port ; port <= upper_port ; port++ )); do
nc -l -p "$port" 2>/dev/null && break 2
done
done
답변3
하나의 선
나는 모든 범위에서 원하는 수의 포트를 스크랩할 수 있도록 신속하게 트릭을 수행하는 멋진 한 줄짜리 코드를 구성했습니다(가독성을 위해 여기서는 4줄로 분할).
comm -23 \
<(seq "$FROM" "$TO" | sort) \
<(ss -Htan | awk '{print $4}' | cut -d':' -f2 | sort -u) \
| shuf | head -n "$HOWMANY"
한 줄씩
comm
알파벳 순서로 정렬되어야 하는 두 파일의 줄을 비교하는 유틸리티입니다. 세 개의 열(첫 번째 파일에만 나타나는 줄, 두 번째 파일에만 나타나는 줄, 공통 줄)을 출력합니다. 지정하면 -23
다음 열을 억제하고 첫 번째 열만 유지합니다. 이를 사용하여 일련의 텍스트 줄로 표현된 두 세트의 차이를 얻을 수 있습니다. 나는 배웠다comm
여기.
첫 번째 파일은 선택할 수 있는 포트 범위입니다. 에서 까지 seq
정렬된 숫자 시퀀스를 생성합니다. 결과는 숫자순이 아닌 알파벳순으로 정렬되고 첫 번째 파일로 파이프됩니다.$FROM
$TO
comm
comm
프로세스 교체.
두 번째 파일은 명령을 호출하여 얻은 정렬된 포트 목록입니다 ss
( -t
TCP 포트를 의미하며 -a
모든 포트는 설정되고 수신되며 -n
숫자는 구문 분석을 시도하지 않음을 의미함 22
) ssh
. 그런 다음 awk
로컬 주소와 포트가 포함된 네 번째 열만 선택합니다 . 구분 기호를 사용하여 cut
주소와 포트를 구분하고 :
후자( -f2
)만 남깁니다. 그런 다음 요구 사항을 복제하지 않음으로써 요구 사항을 준수합니다 comm
.sort
-u
shuf
이제 첫 번째 "$HOWMANY"
포트를 얻는 데 사용할 수 있는 열려 있는 포트의 정렬된 목록이 있습니다 head -n
.
예
개인 범위(49152-65535)에서 임의의 열린 포트 3개를 확보합니다.
comm -23 <(seq 49152 65535 | sort) <(ss -Htan | awk '{print $4}' | cut -d':' -f2 | sort -u) | shuf | head -n 3
예를 들어 다음과 같이 반환할 수 있습니다.
54930
57937
51399
노트
- 무료 UDP 포트를 얻으려면 대신 in을
-t
사용하세요 .-u
ss
- 사용 가능한 포트를 무작위가 아닌 숫자로 정렬하려면 다음
shuf
으로 바꾸십시오.sort -n
답변4
#!/bin/bash
read LOWERPORT UPPERPORT < /proc/sys/net/ipv4/ip_local_port_range
while :
do
PORT="`shuf -i $LOWERPORT-$UPPERPORT -n 1`"
ss -lpna | grep -q ":$PORT " || break
done
echo $PORT
"ss -lpn" - 연결이 설정된 포트만 표시합니다.
"ss -lpna"를 사용하여 수신 포트도 고려해야 합니다 .
Chris Dunn의 크레딧