sysctl是一種用於在運行時檢查和更改內核參數的工具。sysctl在procfs中實現,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
命令可用於顯示所有當前可用的值。
/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/
中的配置文件中Help:Reading#添加、創建、編輯文件或修改對應的行。
/proc/sys/net/bridge/*
中的參數依賴於 br_netfilter
模塊。如果br_netfilter
沒有在運行時(或重啟後)加載,那麼這些參數將安靜的不生效。參見內核模塊。安全
參閱安全#內核加固,以及本文的其餘部分。
網絡
性能優化
增加接收隊列的大小
進入系統的網絡數據幀在從網卡上的環形緩衝區中取出後,會存放在這個隊列中。
在使用高速網卡時增加系統的這個設定值可能有助於防止數據包丟失:
net.core.netdev_max_backlog = 16384
增加最大連接數
可以更改設置內核接受的連接數上限(默認 4096):
net.core.somaxconn = 8192
增加專用於網絡接口的內存
默認情況下,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
有關詳細信息和推薦值,請參閱以下來源:
- http://www.nateware.com/linux-network-tuning-for-2013.html
- https://blog.cloudflare.com/the-story-of-one-latency-spike/
啟用 TCP Fast Open
TCP Fast Open 是傳輸控制協議 (TCP) 的擴展,它通過在發送方的初始 TCP SYN [2] 時使用值 3
而不是默認值 1
允許傳入和傳出連接的 TCP 快速打開:
net.ipv4.tcp_fastopen = 3
調整掛起的連接處理
tcp_max_syn_backlog
是掛起連接等待確認的最大隊列長度。
在碰到 synflood DOS 攻擊的情況下,這個隊列會很快填滿,此時 TCP SYN cookies 將開始允許您的系統繼續響應合法流量,並允許您獲得阻止惡意 IP 的權限。
如果伺服器在尖峰時間系統網絡過載,您可能需要稍微增加此值:
net.ipv4.tcp_max_syn_backlog = 8192
tcp_max_tw_buckets
表示系統內允許處於 TIME_WAIT 狀態的最大sockect連接數。
達到此數字後,系統將開始銷毀處於此狀態的 socket 連接。
增加該值可以防止簡單的 DOS 攻擊:
net.ipv4.tcp_max_tw_buckets = 2000000
tcp_tw_reuse
設置當新時間戳嚴格大於上一個連接記錄的最新時間戳時,TCP 是否應該為新的傳出連接重用 TIME-WAIT 狀態下的現有連接。
默認值為 2
,表示僅對迴環連接啟用。您可以將其設置為 1
以對所有連接啟用,這有助於避免用完可用的網絡 sockets:
net.ipv4.tcp_tw_reuse = 1
指定在強制關閉 socket 之前需要等待的最終 FIN 數據包時間(秒數)。這完全違反了 TCP 規範,但防止拒絕服務攻擊需要這個。在 Linux 2.2 中,默認值為 180 [3]:
net.ipv4.tcp_fin_timeout = 10
tcp_slow_start_after_idle
設置 TCP 是否應僅對新連接或空閒時間過長的現有連接開啟'以默認窗口大小啟動連接'。
此設置會破壞持久的單連接性能,可以將其關閉:
net.ipv4.tcp_slow_start_after_idle = 0
更改 TCP 保活參數
TCP 保活是一種 TCP 連接機制,有助於確定另一端是否已停止響應。TCP會在一段時間的空閒時間後,多次向網絡對端發送包含空數據的保活探測。如果對端沒有響應,socket 將自動關閉。默認情況下,TCP 保活進程在發送第一個保活探測之前等待 socket 活動兩個小時(7200 秒),然後每75秒重新發送一次。只要有 TCP/IP socket 通信在進行並處於活動狀態,就不需要保活數據包。
net.ipv4.tcp_keepalive_time = 60 net.ipv4.tcp_keepalive_intvl = 10 net.ipv4.tcp_keepalive_probes = 6
啟用 MTU 探測
最大傳輸單元 (MTU) 越長,性能越好,但可靠性越差。
這是因為MTU設置大了一旦發生數據包丟失就意味著需要重新傳輸的數據更多,而且網際網路上的許多路由器並不能傳送非常長的數據包:
net.ipv4.tcp_mtu_probing = 1
更多信息,可以參閱這篇文章。
TCP 時間戳
禁用時間戳生成可以減少低性能尖峰的發生並可能提高千兆網絡的性能:
net.ipv4.tcp_timestamps = 0
也可以參考這篇文章了解關於 TCP 時間戳的信息。
TCP 選擇性確認
TCP 選擇性確認 (TCP SACK),由布爾值 tcp_sack
控制,允許接收方向發送方提供有關丟失段的更多詳細信息,從而減少重傳量。這在延遲較高的網絡上非常有用,但在高速區域網上禁用此功能可以提高吞吐量。如果您不發送 SACK,也請禁用 tcp_dsack
,因為您肯定不希望發送重複數據!前向確認在 SACK 之上工作,如果 SACK 被禁用,它也將被禁用。[5]
net.ipv4.tcp_sack = 1
啟用 BBR
BBR 擁塞控制算法可以幫助實現更高的帶寬和更低的網際網路流量延遲。
啟用 BBR 需要先加載 tcp_bbr
模塊。
net.core.default_qdisc = cake net.ipv4.tcp_congestion_control = bbr
增加臨時埠範圍
通常傳輸控制協議 (TCP)、用戶數據報協議 (UDP) 或流控制傳輸協議 (SCTP) 會使用Wikipedia:Ephemeral port 作為客戶端與伺服器端之間的埠分配協商。
net.ipv4.ip_local_port_range = 30000 65535
TCP/IP 協議棧加固
下面指定了一個參數集,用於加強 IPv4 協議內核的網絡安全選項,並且也存在等效項的相關 IPv6 參數。
對於某些用例,例如將系統用作路由器,其他參數也可能有用或需要。
TCP SYN cookie 保護
此項設置有助於抵禦 SYN 洪水攻擊。只有訪問請求達到 net.ipv4.tcp_max_syn_backlog
時才會啟動。更多詳細信息,例如 [6]。 從 linux包 5.10 開始,它是默認設置的。
net.ipv4.tcp_syncookies = 1
TCP rfc1337
可以防止 tcp time-wait assassination 缺陷,丟棄處於 time-wait 狀態的 socket 的 RST 數據包。 除 Linux 之外並不廣泛支持,但符合 RFC:
net.ipv4.tcp_rfc1337 = 1
反向路徑過濾
通過啟用反向路徑過濾,內核將對從機器上所有網絡接口接收到的數據包進行來源驗證。這可以防止使用 IP 欺騙方法的攻擊者破壞系統。
內核的 net.ipv4 .conf.all.rp_filter
默認值為 0
(關閉來源驗證),但 systemd 提供默認 /usr/lib/sysctl.d/50-default.conf
將其設置到 2
(寬鬆模式)[8]。
以下配置將反向路徑過濾機制設置為值 1
(嚴格模式):
net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.rp_filter = 1
ip-sysctl.html 這裡解釋了 net.ipv4.conf.default.*
、net.ipv4.conf.interface.*
和 net.ipv4.conf.all.*
之間的關係和行為。
記錄 martian 數據包
martian 數據包是指那些包內的源地址或目標地址被設置成 IP 保留地址的特殊數據包。IP 保留地址由 IANA 為了特殊用途而保留。這些包要麼在廣域網上要麼根本無法傳輸數據,要麼包內的源地址與實際的發包源地址不符(例如特地偽造虛假源地址的數據包)。
net.ipv4.conf.default.log_martians = 1 net.ipv4.conf.all.log_martians = 1
禁用 ICMP 重定向
相關背景知識可以參考什麼是 ICMP 重定向? 他們應該被阻止嗎?
下面的配置用來禁用 ICMP 重定向的接收功能:
net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0
下面的配置用來在非路由器上禁用 ICMP 重定向的發送功能:
net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0
忽略 ICMP 回應請求
要禁用 ICMP 回應(又叫 ping)請求:
net.ipv4.icmp_echo_ignore_all = 1 net.ipv6.icmp.echo_ignore_all = 1
其它
允許非特權用戶創建 IPPROTO_ICMP socket
IPPROTO_ICMP (icmp(7)) socket 類型增加了在不打開 raw(7) socket 的情況下發送 ICMP_ECHO 消息和接收相應 ICMP_ECHOREPLY 消息的功能,該操作需要設置 CAP_NET_RAW 功能權限或具有指定特權用戶的 SUID 位。這些 ICMP_ECHO 消息由 ping 應用程式發送,因此除了 ICMP Echo socket 之外,IPPROTO_ICMP socket 也稱為 ping socket。
ping_group_range
確定允許其用戶創建 IPPROTO_ICMP socket 的組的 GID 範圍。此外,還允許有 CAP_NET_RAW 功能權限的用戶創建 IPPROTO_ICMP socket。默認情況下這個範圍是 1 0
,意味著除了 root 之外沒有人被允許創建 IPPROTO_ICMP socket。要利用這項設置,當前使用原始 socket 的程序需要移植到使用 IPPROTO_ICMP socket。例如,QEMU 將 IPPROTO_ICMP 用於 SLIRP,即用戶模式網絡,因此允許運行 QEMU 的用戶創建 IPPROTO_ICMP socket,這樣就可以在客戶機內進行 ping 操作了。
下面的配置只允許 GID 為 100 的組成員的用戶創建 IPPROTO_ICMP 套接字:
net.ipv4.ping_group_range = 100 100
下面的配置允許系統中的所有用戶創建 IPPROTO_ICMP 套接字:
net.ipv4.ping_group_range = 0 65535
虛擬內存
有幾個關鍵參數可以調整 Linux 內核的虛擬內存子系統的操作以及將髒數據(dirty data)寫出到磁碟。有關詳細信息,請參閱官方 Linux 內核文檔。 例如:
vm.dirty_ratio = 10
- 包括占可用內存總量(可用頁面和可回收頁面)的百分比,和正在發生磁碟寫入的進程本身將開始寫出髒數據的頁數。
vm.dirty_background_ratio = 5
- 包括可用頁面和可回收頁面的總可用內存的百分比以及後台內核刷新線程將要開始寫出髒數據的頁數。
如參數注釋中所述,在設置這些值時需要考慮 RAM 總量。例如,可以通過用已安裝的系統內存而不是可用內存來簡化計算:
- 較高的比率值可能會提高性能,但也會增加數據丟失的風險。
- 將此值設置為
0
可能會導致更高的磁碟延遲和低性能尖峰。
更多信息請參考 [9]。
- 共識是,如果 RAM 為 1 GB,則將
vm.dirty_ratio
設置為 RAM 的 10% 是一個合理的值(10% 也就是 100 MB)。 但是如果機器有更多的 RAM,比如 16 GB(10% 就是 1.6 GB),這個百分比可能因為機械磁碟上旋轉回寫的幾秒鐘時間差異而不是線性的。 在這種情況下更合理的值可能是3
(16 GB 的 3% 大約是 491 MB)。 - 同樣,將
vm.dirty_background_ratio
設置為5
可能只適用於小內存值,所以要考慮並根據特定系統上的內存容量進行相應調整。
VFS 緩存
降低虛擬文件系統 (VFS) 緩存參數值可能會提高系統響應能力:
vm.vfs_cache_pressure = 50
- 這個值控制內核回收用於緩存目錄和 inode 對象(即 VFS 緩存)內存的積極性。 將它從默認值 100 降低會使內核不太願意回收 VFS 緩存(不要將其設置為 0,這可能會產生內存不足的情況)。
MDADM
參考 RAID#修改同步速度限制。
故障排除
小周期系統凍結
如果遇到這個問題,可以將髒字節(dirty bytes)設置為足夠小的值(例如 4M):
vm.dirty_background_bytes = 4194304 vm.dirty_bytes = 4194304
dirty_background_bytes
和 dirty_bytes
參數是 dirty_background_ratio
和 dirty_ratio
的對應項(如 #虛擬內存 中所示)。一次只能指定一個參數。