tra-loi-cau-hoi-phat-trien-web.com

"Lũ lụt có thể xảy ra" trong nhật ký mặc dù số lượng kết nối SYN_RECV thấp

Gần đây, chúng tôi có một máy chủ Apache đã phản hồi rất chậm do lũ lụt. Cách giải quyết cho vấn đề này là kích hoạt tcp_syncookies (net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf).

Tôi đã đăng một câu hỏi về điều này tại đây nếu bạn muốn có thêm nền tảng.

Sau khi kích hoạt đồng bộ hóa, chúng tôi bắt đầu thấy thông báo sau trong/var/log/message sau mỗi 60 giây:

[84440.731929] possible SYN flooding on port 80. Sending cookies.

Vinko Vrsalovic thông báo với tôi rằng điều này có nghĩa là backlog đồng bộ đã đầy, vì vậy tôi đã nâng tcp_max_syn_backlog lên 4096. Tại một số điểm, tôi cũng hạ tcp_synack_retries xuống 3 (giảm từ mặc định là 5) bằng cách phát hành sysctl -w net.ipv4.tcp_synack_retries=3. Sau khi làm điều này, tần số dường như giảm xuống, với khoảng thời gian của các tin nhắn thay đổi trong khoảng 60 đến 180 giây.

Tiếp theo tôi đã phát hành sysctl -w net.ipv4.tcp_max_syn_backlog=65536, Nhưng tôi vẫn nhận được thông báo trong nhật ký.

Trong tất cả điều này, tôi đã xem số lượng kết nối ở trạng thái SYN_RECV (bằng cách chạy watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l') Và nó không bao giờ cao hơn khoảng 240, thấp hơn nhiều so với kích thước của hồ sơ tồn đọng. Tuy nhiên, tôi có một máy chủ Red Hat dao động trong khoảng 512 (giới hạn trên máy chủ này là mặc định là 1024).

Có bất kỳ cài đặt tcp nào khác sẽ giới hạn kích thước của hồ sơ tồn đọng hoặc tôi đang sủa sai cây? Số lượng kết nối SYN_RECV trong netstat -tuna Có tương quan với kích thước của hồ sơ tồn đọng không?


Cập nhật

Theo cách tốt nhất tôi có thể nói rằng tôi đang xử lý các kết nối hợp pháp ở đây, netstat -tuna|wc -l Di chuyển khoảng 5000. Tôi đã nghiên cứu vấn đề này ngày hôm nay và tìm thấy bài đăng này từ một nhân viên của Last.fm, trong đó đã được khá hữu ích.

Tôi cũng đã phát hiện ra rằng tcp_max_syn_backlog không có hiệu lực khi đồng bộ hóa được bật (theo liên kết này )

Vì vậy, như một bước tiếp theo, tôi đặt như sau trong sysctl.conf:

net.ipv4.tcp_syn_retries = 3
        # default=5
net.ipv4.tcp_synack_retries = 3
        # default=5
net.ipv4.tcp_max_syn_backlog = 65536
        # default=1024
net.core.wmem_max = 8388608
        # default=124928
net.core.rmem_max = 8388608
        # default=131071
net.core.somaxconn = 512
        # default = 128
net.core.optmem_max = 81920
        # default = 20480

Sau đó, tôi thiết lập thử nghiệm thời gian phản hồi của mình, chạy sysctl -p Và đồng bộ hóa bị vô hiệu hóa bởi sysctl -w net.ipv4.tcp_syncookies=0.

Sau khi thực hiện điều này, số lượng kết nối ở trạng thái SYN_RECV vẫn còn khoảng 220-250, nhưng các kết nối đã bắt đầu trì hoãn trở lại. Khi tôi nhận thấy những sự chậm trễ này, tôi kích hoạt lại đồng bộ hóa và sự chậm trễ đã dừng lại.

Tôi tin rằng những gì tôi đã thấy vẫn là một sự cải thiện từ trạng thái ban đầu, tuy nhiên một số yêu cầu vẫn bị trì hoãn, điều này còn tệ hơn nhiều so với việc kích hoạt tính năng đồng bộ hóa. Vì vậy, có vẻ như tôi bị mắc kẹt với chúng được kích hoạt cho đến khi chúng tôi có thể có thêm một số máy chủ trực tuyến để đối phó với tải. Ngay cả sau đó, tôi không chắc chắn tôi thấy một lý do hợp lệ để vô hiệu hóa chúng một lần nữa vì chúng chỉ được gửi (dường như) khi bộ đệm của máy chủ đã đầy.

Nhưng tồn đọng đồng bộ hóa dường như không đầy đủ chỉ với ~ 250 kết nối ở trạng thái SYN_RECV! Có thể thông báo tràn ngập SYN là cá trích đỏ và đó là thứ gì đó không phải là syn_backlog đang lấp đầy?

Nếu bất cứ ai có bất kỳ tùy chọn điều chỉnh nào khác mà tôi chưa thử, tôi sẽ rất vui khi dùng thử, nhưng tôi bắt đầu tự hỏi liệu cài đặt syn_backlog không được áp dụng đúng cách vì một số lý do.

30
Alex Forbes

Vì vậy, đây là một câu hỏi gọn gàng.

Ban đầu, tôi rất ngạc nhiên khi bạn thấy bất kỳ các kết nối ở trạng thái SYN_RECV với cookie SYN được bật. Cái hay của cookie SYN là bạn hoàn toàn có thể tham gia vào TCP bắt tay 3 chiều như một máy chủ sử dụng mật mã, vì vậy tôi mong muốn máy chủ không thể hiện các kết nối nửa mở đó sẽ là cùng một trạng thái không được lưu giữ.

Trong thực tế, một cái nhìn nhanh về nguồn (tcp_ipv4.c) cho thấy thông tin thú vị về cách nhân thực hiện các cookie SYN. Về cơ bản, mặc dù bật chúng lên, kernel vẫn hoạt động như bình thường cho đến khi hàng đợi các kết nối đang chờ xử lý của nó đầy. Điều này giải thích danh sách các kết nối hiện có của bạn ở trạng thái SYN_RECV.

Chỉ khi hàng đợi của các kết nối đang chờ đầy, VÀ một gói SYN khác (nỗ lực kết nối) được nhận, VÀ đã hơn một phút kể từ tin nhắn cảnh báo cuối cùng, hạt nhân mới gửi tin nhắn cảnh báo mà bạn đã thấy ("gửi cookie" ). Cookie SYN được gửi ngay cả khi thông báo cảnh báo không; thông điệp cảnh báo chỉ là để cho bạn biết rằng vấn đề chưa biến mất.

Nói cách khác, nếu bạn tắt cookie SYN, tin nhắn sẽ biến mất. Điều đó sẽ chỉ phù hợp với bạn nếu bạn không còn bị lũ lụt.

Để giải quyết một số điều khác bạn đã làm:

  • net.ipv4.tcp_synack_retries: [.__.]
    • Việc tăng này sẽ không có bất kỳ ảnh hưởng tích cực nào đối với những kết nối đến bị giả mạo, cũng như đối với bất kỳ ai nhận được cookie SYN thay vì trạng thái phía máy chủ (cũng không thử lại cho chúng).
    • Đối với các kết nối giả mạo đến, việc tăng này sẽ tăng số lượng gói bạn gửi đến địa chỉ giả và có thể là thời gian mà địa chỉ giả mạo đó vẫn ở trong bảng kết nối của bạn (điều này có thể là một tác động tiêu cực đáng kể).
    • Trong tải thông thường/số lượng kết nối đến, điều này càng cao, bạn càng có khả năng nhanh chóng/hoàn thành thành công các kết nối qua các liên kết thả gói. Có lợi nhuận giảm dần để tăng điều này.
  • net.ipv4.tcp_syn_retries: Thay đổi điều này không thể có bất kỳ ảnh hưởng nào đến các kết nối gửi đến (nó chỉ ảnh hưởng đến các kết nối ngoài)

Các biến khác mà bạn đề cập tôi chưa nghiên cứu, nhưng tôi nghi ngờ câu trả lời cho câu hỏi của bạn có khá nhiều ở đây.

Nếu bạn không bị ngập lụt và máy phản ứng nhanh với các kết nối không phải HTTP (ví dụ: SSH) Tôi nghĩ có thể có vấn đề về mạng và bạn nên nhờ một kỹ sư mạng giúp bạn xem xét. Nếu máy thường không phản hồi ngay cả khi bạn không bị ngập nước, thì có vẻ như đó là sự cố tải nghiêm trọng nếu nó ảnh hưởng đến việc tạo các kết nối TCP (mức độ khá thấp và không tốn tài nguyên)

27
Slartibartfast

Tôi đã gặp phải vấn đề tương tự chính xác trên bản cài đặt Ubuntu Oneiric 11.10 mới chạy máy chủ web (Apache2) với một trang web tải nặng. Trên đồng bộ Ubuntu Oneiric 11.10 được bật theo mặc định.

Tôi đã có cùng một thông điệp kernel nói về một cuộc tấn công lũ lụt có thể xảy ra trên cổng máy chủ web:

kernel: [739408.882650] TCP: Có thể lũ lụt SYN trên cổng 80. Gửi cookie.

Đồng thời, tôi khá chắc chắn rằng không có cuộc tấn công nào xảy ra. Tôi đã có tin nhắn này trở lại trong khoảng thời gian 5 phút. Điều này có vẻ giống như một cái nhìn trộm, bởi vì kẻ tấn công sẽ giữ tải cao mọi lúc, trong khi cố gắng để máy chủ ngừng đáp ứng yêu cầu.

Điều chỉnh net.ipv4.tcp_max_syn_backlog tham số không dẫn đến bất kỳ cải thiện - các tin nhắn tiếp tục ở cùng một tốc độ. thực tế là số lượng kết nối SYN_RECV luôn rất thấp (trong trường hợp của tôi dưới 250) là một chỉ số, rằng phải có một số tham số khác, chịu trách nhiệm cho thông báo này.

Tôi đã tìm thấy thông báo lỗi này https://ormszilla.redhat.com/show_orms.cgi?id=734991 trên trang web của Red Hat nói rằng thông báo kernel có thể là kết quả của một lỗi ( hoặc cấu hình sai) ở phía ứng dụng. Tất nhiên thông điệp tường trình rất sai lệch! Vì đây không phải là tham số kernel chịu trách nhiệm trong trường hợp đó, mà là tham số của ứng dụng của bạn, được truyền vào kernel.

Vì vậy, chúng ta cũng nên xem các thông số cấu hình của ứng dụng máy chủ web của chúng tôi. Lấy tài liệu Apache và truy cập http://httpd.Apache.org/docs/2.0/mod/mpm_common.html#listenbacklog

Giá trị mặc định của tham số ListenBacklog là 511. (Điều này tương ứng với số lượng kết nối mà bạn đã quan sát thấy trên máy chủ Red Hat của mình. Máy chủ khác của bạn có thể có số cấu hình thấp hơn.)

Apache có một tham số cấu hình riêng cho hàng đợi tồn đọng cho các kết nối đến. nếu bạn có nhiều kết nối đến và bất cứ lúc nào (chỉ là một điều ngẫu nhiên) chúng sẽ kết hợp với nhau gần như cùng một lúc, do đó máy chủ web không thể phục vụ chúng đủ nhanh theo cách thích hợp, hồ sơ tồn đọng của bạn sẽ đầy đủ với 511 kết nối và kernel sẽ kích hoạt thông báo trên nêu rõ một cuộc tấn công lũ lụt có thể xảy ra.

Để giải quyết điều này, tôi thêm dòng sau vào /etc/Apache2/ports.conf hoặc một trong các tệp .conf khác, sẽ được tải bởi Apache (/etc/Apache2/Apache2.conf cũng nên ok):

NgheBackLog 5000

bạn cũng nên đặt net.ipv4.tcp_max_syn_backlog đến một giá trị hợp lý. theo hiểu biết của tôi, tối đa kernel sẽ giới hạn giá trị, mà bạn sẽ có thể định cấu hình trong cấu hình Apache. nên chạy

Sudo sysctl -w net.ipv4.tcp_max_syn_backlog=5000

Sau khi điều chỉnh cấu hình, đừng quên khởi động lại Apache của bạn:

Sudo service Apache2 restart ( or Sudo /etc/init.d/Apache2 restart )

Trong trường hợp của tôi, thay đổi cấu hình này ngay lập tức dừng các cảnh báo kernel. Tôi có thể sao chép các thông báo bằng cách đặt giá trị ListenBackLog thấp trong cấu hình Apache.

13
Jeff

Sau một số thử nghiệm với kernel 3.4.9, số lượng kết nối SYN_RECV trong netstat phụ thuộc vào

  • /proc/sys/net/core/somaxconn làm tròn lên tới sức mạnh tiếp theo là 2 (ví dụ: 128 -> 256)
  • 75% của /proc/sys/net/ipv4/tcp_max_syn_backlog nếu /proc/sys/net/ipv4/tcp_syncookies được đặt thành 0 hoặc 100% nếu /proc/sys/net/ipv4/tcp_syncookies được đặt thành 1
  • ListenBackLog trong cấu hình Apache được làm tròn lên tới sức mạnh tiếp theo là 2 (ví dụ: 128 -> 256)

tối thiểu của mỗi tham số này được sử dụng. Sau khi thay đổi somaxconn hoặc ListenBackLog Apache phải được khởi động lại.

Và sau khi tăng tcp_max_syn_backlog Apache cũng phải được khởi động lại.

Không có tcp_syncookies Apache đang chặn, tại sao trong trường hợp này chỉ có 75% tcp_max_syn_backlog là giới hạn là lạ. và việc tăng tham số này sẽ tăng các kết nối SYN_RECV lên 100% giá trị cũ mà không cần khởi động lại Apache.

5
usoft