linux内核一些参数研究

linux内核中的参数:

  • tcp_syncookies
    用于防止syn攻击。要慎用此参数,因为这与tcp协议的其他部分冲突。

    SYN攻击:正常情况下,服务器收到客户端的连接SYN包后会将客户端加入半连接队列(SYN队列,这个队列长度有限,由==tcp_max_syn_backlog==参数控制)并回复一个ack包并等待客户端的确认,且超时会进行重试。重试次数由参数tcp_synack_retries==指定,重试间隔时间依次为1,2,4,8,16s,加上最后一次重试后等待32s,因此需要总共等待63s。
    利用这种机制,攻击者向服务器发送大量SYN包,然后立即断开。会导致服务器的SYN队列长时间溢出,无法接受新的正常的连接。

==tcp_syncookies==设置为1后,当syn队列溢出后,服务器端将不再使用syn队列,对于新来的syn包服务器端TCP会利用源端地址、端口号和时间戳生成一个序号(也叫cookie)并返回给客户端(不再将其放入syn队列并分配内存),正常客户端会给出正确的响应,服务器端收到响应后直接建立连接(即使客户端不再SYN队列中),进入established状态。非正常连接不会给出正确响应同时不再被加入SYN队列也不会建立连接。

虽然tcpsyncookies可以一定程度上使得在遭受DDos攻击时依然可以对外响应请求。但是正常情况下并不应该依赖此参数。因为在正常情况下,如果打开此参数会发哦之服务器真正过载时无法看到正确的错误日志。并且此参数使得TCP协议改变(妥协版TCP),TCP滑动窗口机制失效(有待验证)_

正常情况下,对于并发量过高的问题,应该依赖以下三个参数解决:

tcp_max_syn_backlog

tcp_synack_retries

tcp_abort_on_overflow

  • tcp_synack_retries
    指服务器端TCP接受到客户端SYN包并返回ack+SYN后超时重试的次数。
  • tcp_syn_retries
    主动发送TCP连接的一方重试发送SYN的次数
  • __tcp_max_syn_backlog
    半连接队列最大长度,并发量过高时可适当增加此值。

  • somaxconn
    established队列长度(完成三次握手),可以由listen函数中的backlog参数指定,但必须小于配置文件中somaxconn的值。

  • tcp_abort_on_overflow
    设置服务器过载无法接受新的连接时直接返回RST包给客户端。默认不启用,慎用此参数
  • tcp_tw_reuse
    timewait端口重用,慎用_。NAT环境下会导致tcp连接建立错误,仅适用于客户端,对作为服务器端的机器无用
    使用要求客户端和服务器端都必须开启tcp_timestamps选项。内核依靠tcp_timestamps这个参数判断是旧的连接还是新的连接。旧连接直接丢弃,新连接复用端口号。
  • tcp_tw_recycle
    timewait端口快速回收,慎用_。NAT环境下会导致tcp连接建立错误。打开此选项后,time_wait状态的端口会被快速回收,然后接收新的连接。linux内核通过timestamps防止旧的数据发送到新的连接上。这会导致NAT环境下客户端建立连接失败。原因:NAT下的多个客户端请求服务器时,源端地址相同,当第一个客户端建立短连接然后立马释放进入time_wait状态然后被回收后,另一个客户端再次以相同的端口号连接时,服务器端比较时间戳就认为是一个旧的数据,直接丢失,造成新的合法的连接失败。
  • tcp_timestamps
    tcp_tw_reuse和tcp_tw_recycle都需要同时设置此参数
  • tcp_max_tw_buckets
    设置time_wait状态连接的数量。这个参数只是为了防止简单的ddos攻击。默认值为180000,平时不要人为降低。当受到ddos攻击是,降低这个值可以快速清除time_wait状态的连接。
  • msl
    最大报文生存时间

    30s or 1min or 2min,通常为2分钟

  • ip_local_port_range
    客户单允许使用的端口范围

time_wait

time_wait状态的tcp仍然占用端口号,因此如果time_wait状态的socket连接过多过导致系统剩余端口号不足,从而无法接受新的连接。

主动关闭的一方才会进入time_wait状态,在传统c/s架构的系统中,通常是c端主动关闭连接;在http和ftp服务器上,通常是server主动关闭连接。

nf_conntrack_max

nf_conntrack是一个内核模块,用于跟踪一个连接的状态。这个连接状态可供其他模块使用,例如iptables的nat和state模块。(state模块用于定义防火墙规则,使用的连接的状态就是由nf_conntrack模块提供)。nf_conntrack_max记录了可以跟踪的最大连接个数,centos默认值为65536。如果iptable的防火墙规则太多,而服务器的连接数又非常多,容易出现如下错误:
kernel nf_conntrack table full dropping packet
解决办法是增大nf_conntrack_max的值(治标),如果无法解决,需要修改防火墙规则或者关闭iptables(治本)或者直接移除nf_conntrack模块。

查看当前最大值:
cat /proc/sys/net/netfilter/nf_conntrack_max
或者
sysctl -a|grep nf_conntrack_max

查看当前值:
cat /proc/sys/net/netfilter/nf_conntrack_count

暂时修改:
sysctl -w nf_conntrack_max=6553600

若需要永久更改(防止重启网卡或者系统失效):
需要将设置写入/etc/sysctl.conf文件
执行sysctl -p会立即将配置文件/etc/sysctl.conf中的参数生效。

tcp_max_orphans

tcp RST

vm.dirty_ratio/hugepage/

linux默认使用当前可用内存的40%作为文件系统的缓存,当文件缓存超过

SO_REUSEADDR

这个参数作用:
1)如果服务器端使用端口号8888开启一个server socket,然后由于某种原因服务端重启服务。如果不设置此参数,由于旧的socket处于timewait状态(通常持续2分钟)此时端口号8888被占用,服务将重启失败。因此需要设置SO_REUSEADDR参数,保证可以快速重用处于timewait状态的socket端口。

2)若不设置此参数
如果使用如下方式绑定一个端口时:
0.0.0.0:port
将不再可以使用其他的ip绑定相同的port
10.103.16.30:port将会失败

参考网址

enter description here