下面是我的理解,可能有误,仅供参考。

要调优,三次/四次握手必须烂熟于心。

client                  server
(SYN_SENT)      —>  (SYN_RECV)
(ESTABLISHED)   <—
—>  (ESTABLISHED)

client(主动)            server
(FIN_WAIT_1)    —>    (CLOSE_WAIT)
(FIN_WAIT_2)    <—
(TIME_WAIT)     <—    (LAST_ACK)
—>    (CLOSED)

大家熟知的 SYN flooding/SYN spoofing 就是在 SYN_RECV 的状态下发起的进攻。这种由于 TCP/IP 协议引起的缺陷只能防治而不好根治,除非换了 TCP/IP。通过下面的方式,可以在一定程度上缓解 DDOS 攻击。

  • 增大半连接的队列,即 backlog queue
  • 人工干预以减少 SYS_RECV 的时间,可以降低第一个重传包的时间或者减少重传的次数

检测 SYN 攻击,可以使用 netstat 命令查看当前的连接类型以及连接数目,如果发现有大量的 SYN_RECV,就值得怀疑了:
$ netstat -tuna | grep :80 | awk '{print $6}' | sort | uniq -c

或者可以通过 wget/curl 从远端实际来测试一下访问的速度:
$ time wget -O /dev/null www.example.com
正常情况下,其 real time 在个位数(s)左右,如果出现长达数十秒乃至几百秒的情况,有可能是此类情况。

最简单的方式是通过 syncookie 实现,Linux 还实现了一种称作 SYN cookie 的机制,开启:
# echo 1 > /proc/sys/net/ipv4/tcp_syncookies

该机制会在服务器收到 SYN 请求后,构造一个带有 ISN(initial sequence number)的 SYN/ACK 包,该 ISN 称为 cookie,其实就是一个哈希。通过此就可以验证客户端的真实性了
注意:SYN cookie 机制不会使用到 backlog queue,因此不必担心 queue 被填满然后服务器主动放弃连接。

使用了 SYN cookie 之后,在 /var/log/kern.log 会发现不少如下的 log,起作用了 
possible SYN flooding on port 80. Sending cookies

除了使用 syncookie,还可以修改 backlog queue 来达到目的。backlog queue 是一个用来处理在三次握手过程中带有 SYN 标志的包的数据结构,可以用来控制系统同时处理的最大连接,当达到该阈值后,接下来的请求会被系统丢弃。这需要系统开辟额外的内存来处理进来的包。如果处理的不好会导致系统内存耗尽,导致严重的性能问题。

tcp_max_syn_backlog 定义了 backlog queue 的半连接数量:
# echo 90000 > /proc/sys/net/ipv4/tcp_max_syn_backlog

当客户端发起 SYN 请求后,服务端会立刻发送 SYN+ACK 的回应,该次半连接会到 backlog queue 中,服务器会等待客户返回 ACK,如果在一段时间内没有应答,服务器会重新发送刚刚的 SYN+ACK,经历了几次还是没有回应后,服务器会主动断开此次半连接。
我们就可以修改重发的次数来减少整个半连接的时间:
# echo 3 > /proc/sys/net/ipv4/tcp_synack_retries

——————————————————————————-
|Value|    Time of retransmission      |         Total time         |
——————————————————————————-
|1       | in 3rd second                          |            9 seconds      |
——————————————————————————-
|2       | in 3rd and 9th second            |            21 seconds   |
——————————————————————————-
|3       | in 3rd, 9th and 21st second  |            45 seconds    |
——————————————————————————-
这张表格显示了不同重传次数消耗的总时间

上面属于 passive 连接,也就是客户端连接服务端,还有个相反的 active TCP connection 参数:
# echo 3 > /proc/sys/net/ipv4/tcp_syn_retries

tcp_fin_timeout 参数会通知 kernel 在 FIN_WAIT_2 状态 sockets 的存活时间,根据理解应该是 server 主动终止,像下面这样。

server                        client
(FIN_WAIT_1)    —>    (CLOSE_WAIT)
(FIN_WAIT_2)    <—
(TIME_WAIT)     <—    (LAST_ACK)
—>    (CLOSED)

当处于 CLOST_WAIT 的 client 有意(攻击)/无意(client 突然崩溃等)不发 fin 来继续时,server 会一直停留在 FIN_WAIT_2 状态,造成资源的浪费。
可以适当的减小该时间:
# echo 15 > /proc/sys/net/ipv4/tcp_fin_timeout

跟 tcp_fin_timeout 相关的有 tcp_max_orphans 参数,表示没有跟任何用户文件相关联的 socket 最大个数,超出的将被内核丢弃。
建议该参数只增加不减小,但增加也意味着内存的消耗增加:
# echo 327680 > /proc/sys/net/ipv4/tcp_max_orphans

相关的 tcp_orphans_retries 关闭本端 TCP 连接前的重试次数,默认 7,高负载的 webserver 建议可以减小。这里解释了设置为 0 的情况。

下面这三个参数一起解释:
tcp_tw_recycle
tcp_tw_reuse
tcp_timestamps

其中 tcp_tw_recycle/tcp_tw_reuse 这两个官方的建议保持默认为 0,而 tcp_timestamps 这个参数在特定的情况开启会引起很严重的问题(via 12)。

基本的情况就是,你的客户或者你的服务器在一个 NAT 后面,如果开启这个参数,会导致服务器能收到三次握手的 SYN 但是不会返回任何的 SYN+ACK,其结果是客户无法访问你的网站。可以通过 tcpdump 或者下面的这个查看:
# netstat -s | grep timestamp

tcp_timestamps 是 tcp 协议中的一个扩展项,通过时间戳的方式来检测过来的包以防止 PAWS(Protect Against Wrapped  Sequence numbers),可以提高 tcp 的性能,2.6 的内核默认是打开的。只要 client/server/nat/loadbalancer 不同时打开该选项就不会出现上面的问题。与之相关的包括 tcp_tw_recycle,如果 tcp_timestamps 和 tcp_tw_recycle 同时开启,就会开启时间戳选项,导致上面的问题。如果有上述的网络结构,比较合理的方式是禁用 tcp_tw_recyle 而开启 tcp_timestamps。禁用了 tcp_tw_recycle 其 TIME_OUT sockets 回收功能就没了,可以配合 tcp_tw_reuse 让 TIME_WAIT 降下来。

netdev_max_backlog 这个参数跟 TCP 的传输队列有关,发送队列长度是 txqueuelen ,netdev_backlog 则决定接收队列的长度。
前者通过 ifconfig 命令改变:
# ifconfig eth0 txqueuelen 10000
对于高吞吐的网络而言,默认的 100 肯定是不够的,一个 rrt 为 120ms 的千兆以太网络,可以设置成 10000 以上的值。

对于接受端而言,需要修改的话就涉及到了 /proc/sys/net/core/netdev_max_backlog 了,如果接收包的速度大于内核能处理的速度,则需要队列来维持,此数值表示最大队列值。默认为 1000,如果超过该数值,会引起丢包,根据实际情况增大。

对于网络不是很好的情况,可以开启 tcp_sack 参数。该实现是 TCP 的一个选项,称为 Selective Acknowlegement(SACK),默认开启,对于千兆网络可以关闭,能提高一定的性能。

keepalive 的情况,Linux 内置支持,只需要开启相应的内核参数就可以了,主要是下面三个:
tcp_keepalive_time 表示 TCP 发出第一个 keepalive 信息之前等待的时间,默认为 7200
tcp_keepalive_intvl keepalive 的时间间隔,默认是 75
tcp_keepalive_probes 触发的次数,默认是 9

ip_local_port_range 128M 内存以上的机器默认是 32768 61000,可以进一步扩大 10240 65535,尽量不要使用 1024 周围的,避免冲突。

以上只是网络内核参数的一小小部分,有待继续补充。

ref:

http://www.frozentux.net/ipsysctl-tutorial/chunkyhtml/tcpvariables.html

http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

http://www.symantec.com/connect/articles/hardening-tcpip-stack-syn-attacks

http://www.saview.net/archives/201

sysctl.conf网络内核参数说明(转)的更多相关文章

  1. /etc/sysctl.conf 控制内核相关配置文件

    /etc/sysctl.conf 用于控制内核相关的配置参数,而且它的内容全部是对应于 /proc/sys/ 这个目录的子目录及文件 [root@MongoDB ~]# ll /proc/sys to ...

  2. /etc/sysctl.conf 调优 & 优化Linux内核参数

    from: http://apps.hi.baidu.com/share/detail/15652067 http://keyknight.blog.163.com/blog/static/36637 ...

  3. (转)/etc/sysctl.conf 调优 & 优化Linux内核参数

    /etc/sysctl.conf 调优 & 优化Linux内核参数 from: http://apps.hi.baidu.com/share/detail/15652067 http://ke ...

  4. [Kernel参数]----/etc/sysctl.conf

    修改sysctl方法 方法一:修改/proc下内核参数文件内容 直接修改内核参数ip_forward对应在/proc下的文件/proc/sys/net/ipv4/ip_forward.用下面命令查看i ...

  5. linux内核参数sysctl.conf,TCP握手ack,洪水攻击syn,超时关闭wait

    题记:优化Linux内核sysctl.conf参数来提高服务器并发处理能力 PS:在服务器硬件资源额定有限的情况下,最大的压榨服务器的性能,提高服务器的并发处理能力,是很多运维技术人员思考的问题.要提 ...

  6. linux内核参数sysctl.conf,TCP握手ack,洪水攻击syn,超时关闭wait(转)

    http://www.xshell.net/linux/Linux_sysctl_conf.html 优化Linux内核sysctl.conf参数来提高服务器并发处理能力 Posted by 破冰 o ...

  7. 内核参数优化/etc/sysctl.conf

    net.nf_conntrack_max = 65536000net.netfilter.nf_conntrack_tcp_timeout_established = 1200net.ipv4.tcp ...

  8. linux 作为web应用服务器内核参数/etc/sysctl.conf

    # Kernel sysctl configuration file for Red Hat Linux## For binary values, 0 is disabled, 1 is enable ...

  9. linux 部署nginx作为反向代理入口的内核参数/etc/sysctl.conf

    # Kernel sysctl configuration file for Red Hat Linux## For binary values, 0 is disabled, 1 is enable ...

随机推荐

  1. (原创)Xilinx的ISE生成模块ngc网表文件

    ISE中,右击“Synthesize”,选中“Process Properties”,将“Xilinx Specific Options:-iobuf”的对勾取消. 将取消模块的ioBuff,因为模块 ...

  2. 第一次写Web API接口

    API是什么?只知道是网络接口,具体怎么写?不会!如何调用?不会!那怎么办? 第一次的经历~~ 需求:为其他项目提供一个接口 功能:为项目提供询盘信息和商家信息,格式为Json字符串 拿过来,就开始做 ...

  3. winpcap抓包原理

    winpcap抓包原理 WinPcap 是由伯克利分组捕获库派生而来的分组捕获库,它是在Windows 操作平台上来实现对底层包的截取过滤.WinPcap 是 BPF 模型和 Libpcap 函数库在 ...

  4. iOS开发 iOS9横屏后状态栏隐藏处理

    - (BOOL)prefersStatusBarHidden { return NO; }

  5. ThinkPHP的URL重写+路由+伪静态,实现SEO效果。

    1.URL重写,隐藏网址中的Index.php. ThinkPHP 作为 PHP 框架,是单一入口的,那么其原始的 URL 便不是那么友好.但 ThinkPHP提供了各种机制来定制需要的 URL 格式 ...

  6. Linux快捷键

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  7. laravel 安装完成后安装 vendor 目录

    composer  install 就是将composer.js 中的配置下载安装 生成vendor目录

  8. SPSS数据分析—二分类Logistic回归模型

    对于分类变量,我们知道通常使用卡方检验,但卡方检验仅能分析因素的作用,无法继续分析其作用大小和方向,并且当因素水平过多时,单元格被划分的越来越细,频数有可能为0,导致结果不准确,最重要的是卡方检验不能 ...

  9. 使用 Box2D 做一个 JansenWalker 机器人

    在 Box2DFlash 的官网的首页有一个小 Demo,这个 Demo 中有11个例子,可以通过左右方向键查看不同的例子,里面的每个例子都非常有趣,但最让我感兴趣的,是其中一个叫 JansenWal ...

  10. Python 爬取所有51VOA网站的Learn a words文本及mp3音频

    Python 爬取所有51VOA网站的Learn a words文本及mp3音频 #!/usr/bin/env python # -*- coding: utf-8 -*- #Python 爬取所有5 ...