跳转至内容

sysctl

来自 ArchWiki

sysctl 是一个用于在运行时检查和修改内核参数的工具。sysctl 是在 procfs 中实现的,即位于 /proc/ 下的虚拟进程文件系统。

安装

procps-ng 软件包应该已经安装,因为它是 base 元软件包的依赖项。

配置

sysctl 的预加载/配置文件可以在 /etc/sysctl.d/99-sysctl.conf 中创建。对于 systemd/etc/sysctl.d//usr/lib/sysctl.d/ 是内核 sysctl 参数的插入目录。命名和源目录决定了处理顺序,这一点很重要,因为最后处理的参数可能会覆盖之前的参数。例如,/usr/lib/sysctl.d/50-default.conf 中的参数将被 /etc/sysctl.d/50-default.conf 中的相同参数以及从两个目录中稍后处理的任何配置文件所覆盖。

要手动加载所有配置文件,执行

# sysctl --system 

这还将输出所应用的层级结构。也可以使用以下命令显式加载单个参数文件

# sysctl --load=filename.conf

更多信息请参阅 新配置文件,特别是 sysctl.d(5)

可用的参数是列在 /proc/sys/ 下的那些参数。例如,kernel.sysrq 参数指的是文件系统上的 /proc/sys/kernel/sysrq 文件。sysctl --all 命令可用于显示所有当前可用的值。

注意 如果您安装了内核文档 (linux-docs),您可以在 /usr/lib/modules/$(uname -r)/build/Documentation/admin-guide/sysctl/ 中找到有关 sysctl 设置的详细信息。本文档的 #另请参阅 部分提到了在线版本。强烈建议在更改 sysctl 设置之前阅读这些内容。

可以通过文件操作或使用 sysctl(8) 实用程序来更改设置。例如,要临时启用 魔术 SysRq 键

# sysctl kernel.sysrq=1

或者

# echo "1" > /proc/sys/kernel/sysrq 

有关 kernel.sysrq 的详细信息,请参阅 Linux 内核文档

要在重启后保留更改,请添加或修改 /etc/sysctl.d/99-sysctl.conf 中的相应行,或修改 /etc/sysctl.d/ 中其他适用的参数文件。

提示
  • 某些可以应用的参数可能依赖于尚未加载的内核模块。例如,/proc/sys/net/bridge/* 中的参数依赖于 br_netfilter 模块。如果在运行时(或重启后)未加载它,这些参数将静默地无法应用。请参阅 内核模块
  • sysctl 参数也可以通过在参数名称前加上 sysctl. 来使用内核命令行参数进行应用(例如 sysctl.vm.swappiness=40)。这对于在不修改全系统配置的情况下进行永久更改非常有用。

安全

另请参阅 安全#内核加固,以及本文的其余部分。

网络

提升性能

增大接收队列长度。

在从网卡的环形缓冲区获取接收到的帧后,它们将被存储在该队列中。

对于高速网卡,增大此值可能有助于防止丢包。

net.core.netdev_max_backlog = 16384
注意 在 SIP 路由器等实时应用程序中,此选项需要高速 CPU,否则队列中的数据将会过时。

增加最大连接数

内核将接受的连接上限(默认为 4096)

net.core.somaxconn = 8192
警告 增大此值可能仅在高负载服务器上提高性能,并可能导致处理速率变慢(例如单线程阻塞服务器)或工作线程/进程数量不足 [1]

增加分配给网络接口的内存

本文章或章节需要扩充。

原因: 解释每个选项的单位是什么(字节、千字节还是内存页?) (在 Talk:Sysctl 中讨论)

本文或本章节的准确性存在争议。

原因: 此部分似乎是由 Cloudflare 的博客文章激发的,但 Red Hat 的 tuned 配置建议使用更小的值,并声称“这似乎仅在 40Gb 速度下才有必要”。因此,这些设置对商品硬件似乎没有用处。(在 Talk:Sysctl 中讨论)

默认情况下,Linux 网络堆栈未针对 WAN 链路上的高速大文件传输(即处理更多网络数据包)进行配置,设置正确的值可能会节省内存资源。

net.core.rmem_default = 1048576
net.core.rmem_max = 16777216
net.core.wmem_default = 1048576
net.core.wmem_max = 16777216
net.core.optmem_max = 65536
net.ipv4.tcp_rmem = 4096 1048576 2097152
net.ipv4.tcp_wmem = 4096 65536 16777216

也可以增加默认的 4096 UDP 限制。

net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

有关更多信息和推荐值,请参阅以下来源:

启用 TCP Fast Open

本文章或章节需要扩充。

原因: 提及“默认使所有监听器支持 Fast Open,无需显式 TCP_FASTOPEN 套接字选项”的选项,即值 1027 (0x1+0x2+0x400)。(在 Talk:Sysctl#TCP Fast Open 中讨论)

TCP Fast Open 是传输控制协议 (TCP) 的一个扩展,它通过允许在发送方的初始 TCP SYN 期间交换数据来帮助减少网络延迟 [2]。使用值 3 代替默认的 1 允许 TCP Fast Open 用于传入和传出连接。

net.ipv4.tcp_fastopen = 3

调整待处理连接的处理方式

tcp_max_syn_backlog 是处于“等待确认”状态的待处理连接的最大队列长度。

如果发生 SYN 泛洪 DOS 攻击,此队列可能会迅速填满,此时 TCP SYN cookies 将介入,使您的系统能够继续响应合法流量,并允许您获得访问权限以阻止恶意 IP。

如果服务器在高峰时段遭遇过载,您可能需要稍微增加此值。

net.ipv4.tcp_max_syn_backlog = 8192

tcp_max_tw_buckets 是处于 TIME_WAIT 状态的套接字的最大数量。

达到此数量后,系统将开始销毁处于此状态的套接字。

增加此值以防止简单的 DOS 攻击。

net.ipv4.tcp_max_tw_buckets = 2000000

tcp_tw_reuse 设置 TCP 是否应在 TIME-WAIT 状态下为新的传出连接重用现有连接,前提是新时间戳严格大于前一个连接记录的最新时间戳。

默认值为 2,表示仅对环回连接启用。您可以将其设置为 1 以对所有连接启用,这有助于避免耗尽可用网络套接字。

net.ipv4.tcp_tw_reuse = 1

指定在套接字被强制关闭之前等待最终 FIN 数据包的秒数。这严格违反了 TCP 规范,但对于防止拒绝服务攻击是必需的。

net.ipv4.tcp_fin_timeout = 10

tcp_slow_start_after_idle 设置 TCP 是仅针对新连接以默认窗口大小开始,还是也针对空闲时间过长的现有连接以默认窗口大小开始。

此设置会损害持久单连接性能,可以将其关闭。

net.ipv4.tcp_slow_start_after_idle = 0

更改 TCP keepalive 参数

本文或本章节已过时。

原因: filesystem 2025.05.03-1 在 /usr/lib/sysctl.d/10-arch.conf 中将 net.ipv4.tcp_keepalive_time 设置为 120。请参阅 [3]。(在 Talk:Sysctl 中讨论)

TCP keepalive 是一种 TCP 连接机制,有助于确定另一端是否已停止响应。TCP 将在一段时间的空闲后多次向网络对等方发送包含空数据的 keepalive 探测。如果对等方没有响应,套接字将自动关闭。默认情况下,TCP keepalive 进程在发送第一个 keepalive 探测之前会等待两小时(7200 秒)的套接字活动,然后每 75 秒重新发送一次。只要有 TCP/IP 套接字通信正在进行且处于活动状态,就不需要 keepalive 数据包。

注意 使用以下设置,您的应用程序将在 120 秒 (60s + 10s + 10s + 10s + 10s + 10s + 10s) 后检测到死掉的 TCP 连接。
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6

启用 MTU 探测

最大传输单元 (MTU) 越长,性能越好,但可靠性越差。

这是因为丢失的数据包意味着需要重传更多数据,而且互联网上的许多路由器无法交付非常长的数据包。

net.ipv4.tcp_mtu_probing = 1

有关更多信息,请参阅 https://blog.cloudflare.com/path-mtu-discovery-in-practice/

TCP 时间戳

警告 TCP 时间戳可防止回绕序列号(在千兆速度下)并实现 TCP 中的往返时间计算。不建议关闭 TCP 时间戳,因为它可能会导致安全风险 [4]

禁用时间戳生成将减少峰值,并可能在千兆网络上提供性能提升。

net.ipv4.tcp_timestamps = 0

TCP 选择性确认

由布尔值 tcp_sack 控制的 TCP 选择性确认 (TCP SACK) 允许接收端向发送方提供有关丢失段的更多详细信息,从而减少重传量。这在高延迟网络上很有用,但在高速局域网 (LAN) 上禁用此项以提高吞吐量。此外,如果您不发送 SACK,肯定不想发送重复项,因此请禁用 tcp_dsack!转发确认在 SACK 之上工作,如果 SACK 被禁用,它也将被禁用。[5]

net.ipv4.tcp_sack = 1

启用 BBR

BBR 拥塞控制算法可以帮助实现更高的带宽和更低的互联网流量延迟。首先,加载 tcp_bbr 模块。

注意 BBR GitHub 表示,“这不是 Google 的官方产品。”
net.core.default_qdisc = cake
net.ipv4.tcp_congestion_control = bbr

增加临时端口范围

本文或本章节的准确性存在争议。

原因: 此更改如何提升性能? (在 Talk:Sysctl#net.ipv4.ip_local_port_range 中讨论)

Wikipedia:临时端口通常由传输控制协议 (TCP)、用户数据报协议 (UDP) 或流控制传输协议 (SCTP) 用作客户端-服务器通信的客户端端的端口分配。

net.ipv4.ip_local_port_range = 30000 65535

TCP/IP 堆栈加固

以下指定了一组参数,以加强 IPv4 协议及具有等效项的相关 IPv6 参数的内核网络安全选项。

对于某些用例,例如将系统用作路由器,其他参数可能也很有用或必需。

有助于防止 SYN 泛洪攻击。仅在达到 net.ipv4.tcp_max_syn_backlog 时介入。更多详细信息,例如在 [6]。自 linux 5.10 起,它默认已设置。

net.ipv4.tcp_syncookies = 1

TCP rfc1337

本文或本章节的准确性存在争议。

原因: 这似乎不是 TCP 标准的一部分?描述可能不准确。[7] (在 Talk:Sysctl#net.ipv4.tcp_rfc1337 中讨论)

防止 TCP time-wait 刺杀风险,丢弃处于 time-wait 状态的套接字的 RST 数据包。在 Linux 之外不受广泛支持,但符合 RFC 标准。

net.ipv4.tcp_rfc1337 = 1

反向路径过滤

通过启用反向路径过滤,内核将对从机器上所有接口接收到的数据包进行源验证。这可以防止攻击者使用 IP 欺骗方法进行破坏。

内核的默认值为 0(无源验证),但 systemd 附带了 /usr/lib/sysctl.d/50-default.conf,将 net.ipv4.conf.all.rp_filter 设置为 2(宽松模式)[8]

以下内容将把反向路径过滤机制设置为值 1(严格模式)。

net.ipv4.conf.*.rp_filter = 1
-net.ipv4.conf.all.rp_filter

net.ipv4.conf.default.*net.ipv4.conf.interface.*net.ipv4.conf.all.* 之间的关系和行为在 ip-sysctl.html 中有说明。

记录 Martian 数据包

Martian 数据包是一个 IP 数据包,它指定了一个为互联网编号分配机构 (IANA) 特殊用途保留的源地址或目标地址。有关详细信息,请参阅 保留 IP 地址

通常 Martian 和不可路由数据包可能被用于危险目的。记录这些数据包以供进一步检查可能很有用 [9]

net.ipv4.conf.*.log_martians = 1
-net.ipv4.conf.all.log_martians
注意 这可能会使您的日志中充斥大量信息,建议仅在测试时启用此功能。

禁用 ICMP 重定向

背景信息在 什么是 ICMP 重定向?它们应该被阻止吗?

禁用 ICMP 重定向接受

net.ipv4.conf.*.accept_redirects = 0
-net.ipv4.conf.all.accept_redirects
net.ipv6.conf.*.accept_redirects = 0
-net.ipv6.conf.all.accept_redirects

在非路由器上禁用 ICMP 重定向发送

net.ipv4.conf.*.send_redirects = 0
-net.ipv4.conf.all.send_redirects

忽略 ICMP 回显请求

禁用 ICMP 回显(又称 ping)请求

net.ipv4.icmp_echo_ignore_all = 1
net.ipv6.icmp.echo_ignore_all = 1
注意 请注意,这可能会导致依赖 ICMP 回显响应的监控工具和/或应用程序出现问题。

其他

允许非特权用户创建 IPPROTO_ICMP 套接字

本文或本章节已过时。

原因: /usr/lib/sysctl.d/50-default.confnet.ipv4.ping_group_range 设置为 0 2147483647。(在 Talk:Sysctl 中讨论)

IPPROTO_ICMP (icmp(7)) 套接字类型增加了发送 ICMP_ECHO 消息和接收相应 ICMP_ECHOREPLY 消息的可能性,而无需打开 raw(7) 套接字(这是一项需要 CAP_NET_RAW 能力或带有适当特权所有者的 SUID 位的操作)。这些 ICMP_ECHO 消息由 ping 应用程序发送,因此除了 ICMP Echo 套接字外,IPPROTO_ICMP 套接字也被称为 ping 套接字。

ping_group_range 决定了允许其用户创建 IPPROTO_ICMP 套接字的组的 GID 范围。此外,拥有 CAP_NET_RAW 能力的所有者也被允许创建 IPPROTO_ICMP 套接字。默认情况下,此范围是 1 0,这意味着除了 root 之外,没有人被允许创建 IPPROTO_ICMP 套接字。为了利用此设置,当前使用原始套接字的程序需要移植以改用 IPPROTO_ICMP 套接字。例如,QEMU 使用 IPPROTO_ICMP 进行 SLIRP(即用户模式网络),因此允许运行 QEMU 的用户创建 IPPROTO_ICMP 套接字意味着可以从客户机执行 ping 操作。

仅允许 GID 为 100 的组成员的用户创建 IPPROTO_ICMP 套接字

net.ipv4.ping_group_range = 100 100

允许系统中的所有用户创建 IPPROTO_ICMP 套接字

net.ipv4.ping_group_range = 0 65535

虚拟内存

有几个关键参数可以调整 Linux 内核的虚拟内存子系统以及脏数据写入磁盘的操作。更多信息,请参阅官方 Linux 内核文档。例如

  • vm.dirty_ratio = 10
包含(作为包含空闲页和可回收页的总可用内存的百分比)生成磁盘写入的进程自身开始写出脏数据时的页数。
  • vm.dirty_background_ratio = 5
包含(作为包含空闲页和可回收页的总可用内存的百分比)后台内核刷新线程开始写出脏数据时的页数。

正如参数注释中所述,在设置这些值时需要考虑 RAM 的总量。例如,通过使用已安装的系统 RAM 而不是可用内存来进行简化

警告
  • 较高的比例值可能会提高性能,但也会增加数据丢失的风险。
  • 将此值设置为 0 可能会导致磁盘上的延迟增加和峰值。

有关更多信息,请参阅 https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/

  • 共识是,如果 RAM 为 1 GB(即 10% 为 100 MB),将 vm.dirty_ratio 设置为 RAM 的 10% 是一个合理的数值。但如果机器有更多的 RAM,例如 16 GB(10% 为 1.6 GB),则该百分比可能不成比例,因为它会变成在旋转磁盘上长达几秒的写回操作。在这种情况下,一个更合理的值可能是 3(16 GB 的 3% 约为 491 MB)。
  • 类似地,将 vm.dirty_background_ratio 设置为 5 对于小内存值可能完全没问题,但同样,请根据特定系统上的 RAM 量进行考虑和相应调整。

VFS 缓存

减小虚拟文件系统 (VFS) 缓存参数值可能会提高系统响应速度。

  • vm.vfs_cache_pressure = 50
该值控制内核回收用于缓存目录和索引节点对象(VFS 缓存)的内存的倾向。将其从默认值 100 降低会使内核不太倾向于回收 VFS 缓存(不要将其设置为 0,这可能会产生内存不足的情况)。

MDADM

请参阅 RAID#更改同步速度限制

故障排除

轻微的周期性系统冻结

将脏字节设置为足够小的值(例如 4 MiB)

vm.dirty_background_bytes = 4194304
vm.dirty_bytes = 4194304
注意 dirty_background_bytesdirty_bytes 参数是 dirty_background_ratiodirty_ratio(如在 #虚拟内存 中所见)的对应项。一次只能指定其中一个参数。

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.