Linux 서버에서 최대 연결 수를 제한하는 것은 무엇입니까?


89

Linux 서버에서 열 수있는 최대 TCP 소켓 수를 제어하는 ​​커널 매개 변수 또는 기타 설정은 무엇입니까? 더 많은 연결을 허용 할 때의 단점은 무엇입니까?

ab 를 사용 하여 Apache 서버를로드 테스트하는 동안 서버 에서 열린 연결을 최대한 쉽게 확장 할 수 있음을 알았습니다 . 연결 재사용을 허용하는 ab의 -k 옵션을 생략하고 약 10,000 개 이상의 요청을 보내도록하면 Apache가 첫 번째 11,000 정도의 요청을 처리 한 다음 60 초 동안 정지합니다. netstat 출력을 보면 TIME_WAIT 상태에서 11,000 개의 연결이 표시됩니다. 분명히 이것은 정상입니다. TCP 안정성 때문에 클라이언트와의 연결이 완료된 후에도 연결은 기본적으로 60 초 동안 열려 있습니다.

이것이 서버를 DoS하는 쉬운 방법 인 것처럼 보이며 일반적인 튜닝 및 예방 조치가 무엇인지 궁금합니다.

내 테스트 출력은 다음과 같습니다.

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

테스트 중에 실행하는 netstat 명령은 다음과 같습니다.

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab

답변:


64

마침내 연결 수를 제한하는 설정을 찾았습니다 net.ipv4.netfilter.ip_conntrack_max. 이것은 11,776로 설정되었으며 내가 설정 한 것은 tcp_fin_timeout더 많은 연결을 사용할 수있게되기 위해 몇 초 를 기다리기 전에 테스트에서 처리 할 수있는 요청 수입니다. conntrack표는 커널이 가득하면, 커널이 패킷을 삭제하고 로그에서 이것을 인쇄 시작 있도록 연결의 상태를 추적하기 위해 사용하는 것입니다 :

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

다음 단계는 커널이 TIME_WAIT패킷을 삭제하지 않고 상태 에서 모든 연결을 재활용하도록 하는 것입니다. 에 의해 연결에 사용 가능한 로컬 포트 ​​수보다 더 크게 설정 tcp_tw_recycle하거나 늘리면 이 문제가 발생할 ip_conntrack_max수 있습니다 ip_local_port_range. 커널이 로컬 포트를 벗어나면 연결을 재활용하기 시작합니다. 이것은 더 많은 메모리 추적 연결을 사용하지만 tcp_tw_recycle문서가 위험하다는 것을 암시하기 때문에 켜는 것보다 더 나은 솔루션처럼 보입니다 .

이 구성을 사용하면 하루 종일 ab를 실행할 수 있으며 연결이 부족하지 않습니다.

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

tcp_max_orphans설정은 테스트에 영향을 미치지 않았으며 이유를 모르겠습니다. TIME_WAIT8192가 있으면 상태 에서 연결을 닫을 것이라고 생각 하지만 그렇게하지는 않습니다.


3
이 매개 변수는 어디에서 구성합니까?
Codevalley

2
즉, 시스템에 의존하지만, 우분투 서버에있을 수 있습니다 @Codevalley 그들은 /etc/sysctl.conf에 갈
벤 윌리엄스

24

이 점에서 / proc 파일 시스템이 무엇을 제공해야하는지 정말로보고 싶을 것입니다.

마지막 페이지에서 다음 사항에 관심이있을 수 있습니다.

  • / proc / sys / net / ipv4 / tcp_max_orphans- 시스템에 연결 되지 않은 최대 소켓 수를 제어합니다 . 이를 늘리면 고아 소켓 당 최대 64kbyte의 스왑 불가능 메모리를 소비 할 수 있습니다 .
  • / proc / sys / net / ipv4 / tcp_orphan_retries 는 소켓이 분리되어 닫히기 전에 재시도 횟수를 제어합니다. 해당 페이지에서 귀하에게 직접 관심이있는 웹 서버에 대한 특정 참고 사항이 있습니다 ...

tcp_max_orphans는 흥미롭지 만 작동하지 않는 것 같습니다. 테스트 중에 고아 소켓을 측정하려고하면 tcp_max_orphans가 8,092 인 동안 11,651이 나타납니다. # netstat --inet -p | grep "localhost : www"| sed -e 's / \ + / / g'| 컷 -d ''-f 1-4,6-7 | 정렬 | UNIQ -c 11651 TCP 0 0 로컬 호스트 : www가 TIME_WAIT -
벤 윌리엄스

tcp_orphan_retries 설정을 살펴보십시오. 아이디어는 소켓이 "더 빨리"컬링됩니다 ...
Avery Payne

@Jauder Ho의 제안 + tcp_orphan_retries는 상황에 대한 잠재적 인 승리처럼 들립니다.
에이버리 페인

3

직접 설정할 수있는 튜너 블이 없다고 생각합니다. 이것은 TCP / IP 조정 범주에 속합니다. 조정할 수있는 것을 찾으려면 'man 7 tcp'를 시도하십시오. sysctl ( 'man 8 sysctl')을 사용하여이를 설정합니다. 'sysctl -a | grep tcp '는 조정할 수있는 대부분을 보여 주지만, 모두 보여줄지 잘 모르겠습니다. 또한 이것이 변경되지 않으면 TCP / IP 소켓은 파일 디스크립터처럼 보입니다. 그래서 그 링크에서 다음 섹션은 당신이 찾고있는 것을 수 있습니다.


2

tcp_fin_timeout을 설정하고 다음을 설정하십시오. TIME_WAIT가 더 빨리 종료됩니다.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

조심해! 어려운 길을 경험했다. "이로 인해로드 균형 조정 및 NAT가있는 프레임이 손실 될 수 있습니다. 로컬 네트워크를 통해서만 통신하는 서버에만 사용하십시오." - wiki.archlinux.org/index.php/Sysctl
헹크

@ Henk 나는 그것이 tcp_tw_recycle잠재적으로 위험한 것이라고 생각합니다 . tcp_tw_reuse더 안전하고 동시에 사용할 이유가 없습니다.
Vladislav Rastrusny

2

스톡 아파치 (1)는 250 개의 동시 연결 만 지원하도록 사전 정의 된 상태로 제공되었습니다. 더 많은 것을 원한다면 더 많은 동시 세션을 허용하도록 수정해야 할 헤더 파일이 하나 있습니다. 이것이 Apache 2에서도 여전히 사실인지는 모르겠습니다.

또한 Apache를 실행하는 계정에 대해 더 많은 열린 파일 설명자를로드 할 수있는 옵션을 추가해야합니다. 이전 설명에서 지적하지 못한 부분입니다.

작업자 설정과 Apache 자체에 어떤 종류의 keepalive 시간 초과, 한 번에 실행중인 예비 서버 서버 수 및 이러한 추가 프로세스가 얼마나 빨리 종료되는지에주의하십시오.


1

TIME_WAIT 상태에서 소요되는 시간을 줄일 수 있습니다 (net.ipv4.tcp_fin_timeout 설정). Apache를 YAWS 또는 nginx 또는 이와 유사한 것으로 바꿀 수 있습니다.

더 많은 연결에 대한 절충은 일반적으로 메모리 사용과 관련이 있으며 분기 프로세스가있는 경우 CPU를 손상시키는 많은 하위 프로세스가 있습니다.


1
tcp_fin_timeout은 TIME-WAIT 만료를 설정하기위한 것이 아니라, 커널을 다시 빌드하는 것 외에는 변경할 수 없지만 이름에서 알 수 있듯이 FIN을위한 것입니다.
Alexandr Kurilin

0

단일 IP 주소에서 열 수있는 소켓의 절대 수는 2 ^ 16이며 커널이 아닌 TCP / UDP에 의해 정의됩니다.


6
아닙니다. 원격 주소가 다른 한 로컬 포트가 고유하지 않아도되므로 더 열 수 있습니다. 또한 서버 당 OP가 말했으며 서버 당> 1 주소를 가질 수 있습니다.
MarkR

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.