Bir Linux sunucusundaki maksimum bağlantı sayısını sınırlayan nedir?


89

Hangi çekirdek parametresi veya diğer ayarlar, bir Linux sunucusunda açılabilecek maksimum TCP soket sayısını kontrol eder? Daha fazla bağlantıya izin vermenin değişmezliği nedir?

Bir Apache sunucusunu ab ile test ederken , sunucudaki açık bağlantıları arttırmanın oldukça kolay olduğunu fark ettim . Ab's -k seçeneğini bırakıp, bağlantının yeniden kullanılmasına izin verir ve yaklaşık 10.000'den fazla istek göndermesini sağlarsanız, Apache ilk 11.000'in üzerinde olan istekleri yerine getirir ve sonra 60 saniye durur. Netstat çıktısına bakıldığında TIME_WAIT durumunda 11.000 bağlantı gösteriliyor. Görünüşe göre bu normal. Bağlantılar, TCP güvenilirlik nedenleriyle istemci onlarla yapıldıktan sonra bile varsayılan olarak 60 saniye açık tutulur .

Bu bir sunucuyu DoS yapmanın kolay bir yolu olacak gibi görünüyor ve bunun için ne gibi olağan ayarların ve önlemlerin olduğunu merak ediyorum.

İşte benim test çıktım:

# 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

Test sırasında çalıştırdığım netstat komutu:

 # 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

Yanıtlar:


64

Sonunda gerçekten bağlantı sayısını sınırlama edildi ayar bulundu: net.ipv4.netfilter.ip_conntrack_max. Bu, 11,776 olarak ayarlandı ve ne olursa olsun tcp_fin_timeout, daha fazla bağlantının kullanılabilir olması için saniyeler beklemeden önce testimde sunabileceğim istek sayısı . conntrackMasa çekirdeği tam girince, çekirdek paketlerini bırakarak ve günlüğünde bu yazdırmaya başlar, böylece bağlantı durumunu izlemek için kullandığı şudur:

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

Bir sonraki adım, çekirdeği TIME_WAITpaketleri bırakmak yerine durumdaki tüm bu bağlantıları geri dönüştürmeye almaktı. Bunu, bağlantılar için sağlanan yerel bağlantı noktalarının sayısından daha büyük olacak şekilde açarak tcp_tw_recycleya da artırarak gerçekleştirebilirdim . Sanırım çekirdek yerel bağlantı noktalarının dışına çıktığında geri dönüşüm bağlantılarına başlıyor. Bu, daha fazla bellek izleme bağlantısı kullanıyor, ancak dokümanlar bunun tehlikeli olduğunu ima ettiğinden, açılmasından daha iyi bir çözüm gibi görünüyor .ip_conntrack_maxip_local_port_rangetcp_tw_recycle

Bu yapılandırma ile tüm gün ab çalıştırabilirim ve hiçbir zaman bağlantı kesilemez:

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_orphansAyar benim testlerde üzerinde herhangi bir etkisi yoktu ve ben nedenini bilmiyorum. TIME_WAIT8192 kişiden bir tanesinin devletle olan bağlantılarını kapattığını düşünürdüm ama bu benim için yapmaz.


3
Bu paragrafları nerede yapılandırabiliriz?
Codevalley

2
@Codevalley Bu sisteme bağlı olabilir, ancak Ubuntu Sunucusunda /etc/sysctl.conf
Ben Williams

24

/ Proc dosya sisteminin size bu konuda neler sunabileceğini görmek istiyorsunuz.

Bu son sayfada ilginizi çeken aşağıdakileri bulabilirsiniz:

  • / proc / sys / net / ipv4 / tcp_max_orphans , sistem tarafından tutulan bir şeylere bağlı olmayan maksimum soket sayısını kontrol eder . Bunu yükseltmek, yetim soket başına 64kbyte kadar değiştirilemez bellek tüketebilir .
  • / proc / sys / net / ipv4 / tcp_orphan_retries , bir soket kullanılmadan ve kapanmadan önce yeniden deneme miktarını kontrol eder. Bu sayfada sizi ilgilendiren web sunucuları hakkında özel bir not var ...

tcp_max_orphans ilginç ama çalışmıyor gibi görünüyor. Test sırasında yetim soketleri ölçmeye çalıştığımda bunların 11,651'ini görüyorum, tcp_max_orphans 8,092. # netstat --inet -p | grep "localhost: www" | sed -e 's / \ + / / g' | kesilmiş -d '' -f 1-4,6-7 | sıralama | uniq -c 11651 tcp 0 0 yerel ev sahibi: www TIME_WAIT -
Ben Williams

Tcp_orphan_retries ayarına bakın - fikir şu ki, soketler daha çabuk toplandı ...
Avery Payne

@Jauder Ho'nun önerisi + tcp_orphan_retries durumunuz için potansiyel kazanma gibi geliyor.
Avery Payne

3

Bunu doğrudan ayarlayabilecek bir ayar olduğunu sanmıyorum. Bu, TCP / IP ayar kategorisine girer. Neyi ayarlayabileceğinizi bulmak için 'man 7 tcp''yi deneyin. Sysctl ('man 8 sysctl') bunları ayarlamak için kullanılır. 'sysctl -a | grep tcp 'size ayarlayabileceğiniz şeylerin çoğunu gösterecek, ancak hepsini gösterip göstermeyeceğinden emin değilim. Ayrıca, bu değişmediği sürece, TCP / IP yuvaları açılır, dosya tanımlayıcılarına benzer. Yani bu ve bu bağlantıdaki bir sonraki bölüm aradığınız şey olabilir.


2

Aşağıdakileri ayarlamayı ve tcp_fin_timeout ayarını deneyin. Bu TIME_WAIT'i daha hızlı kapatmalı.

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

Burada dikkatli ol! Zor yoldan deneyimli. "Bu, yük dengeleme ve NAT'lara sahip çerçevelerin düşmesine neden olabilir, bunu yalnızca yerel ağınız üzerinden iletişim kuran bir sunucu için kullanın." - wiki.archlinux.org/index.php/Sysctl
Henk

@Henk Bence bu tcp_tw_recyclepotansiyel olarak tehlikeli. tcp_tw_reusedaha güvenli ve bunları aynı anda kullanmak için herhangi bir neden görmüyorum.
Vladislav Rastrusny 17:12

2

Stok apache (1) yalnızca 250 eşzamanlı bağlantıyı desteklemek için önceden tanımlanmış olarak gelirdi - eğer daha fazlasını istiyorsanız, daha fazla eşzamanlı oturuma izin verecek şekilde değiştirilecek tek bir başlık dosyası vardı. Bunun Apache 2 ile hala doğru olup olmadığını bilmiyorum.

Ayrıca, Apache'yi çalıştıran hesap için daha fazla sayıda açık dosya tanımlayıcısına izin vermek için bir seçenek eklemeniz gerekir - önceki yorumların göstermediği bir şey.

İşçi ayarlarınıza ve Apache'nin içinde ne kadar kalıcı zaman aşımına sahip olduğunuza, bir kerede kaç yedek sunucunuz çalıştığına ve bu ekstra işlemlerin ne kadar hızlı bir şekilde öldürüldüğüne dikkat edin.


1

TIME_WAIT durumunda harcanan zamanı azaltabilirsiniz (Set net.ipv4.tcp_fin_timeout). Apache'yi YAWS veya nginx veya benzeri bir şeyle değiştirebilirsiniz.

Daha fazla bağlantının takas edilmesi genellikle bellek kullanımını içerir ve bir çatallama işleminiz varsa, CPU'nuzu tarayan birçok alt işlem vardır.


1
tcp_fin_timeout, çekirdeğin yeniden yapılandırılması dışında değişken olmayan TIME-WAIT son kullanma tarihini ayarlamak için değil, adından da anlaşılacağı gibi FIN için kullanılır.
Alexandr Kurilin

0

Tek bir IP adresinde açılabilen mutlak yuva sayısı 2 ^ 16'dır ve çekirdek tarafından değil, TCP / UDP tarafından tanımlanır.


6
Hayır değil. Uzak adresler farklı olduğu sürece yerel portun benzersiz olması gerekmediğinden daha fazla açabilirsiniz. Dahası, OP sunucu başına dedi ve sunucu başına> 1 adresiniz olabilir.
MarkR

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.