三個小時未使用網路時,如何使 Ubuntu 伺服器休眠?
我每週只有幾天每天真正使用伺服器幾個小時。
它是一個備份伺服器,它向客戶端請求備份數據。
該部分已得到處理,它通過預定的魔術包喚醒並執行其操作。這都很好。我可以喚醒它以在計劃外使用它,這也很好。
我怎麼讓它知道網路有一段時間沒有被使用並讓自己進入睡眠狀態?我想要記錄的網路流量是 SSH、SFTP、rsync 和來自 Canonical 的更新。所有其他流量只是我不在乎的喋喋不休。
我想將以下虛擬碼作為 cron 腳本放入……每 15 分鐘左右檢查一次。我不擔心添加 cron 功能,我對此充滿信心。
if [ lastSignificantNetworkActivity > 3h ] { hibernate }
我可能有 X->Y 問題。我只想讓我的伺服器在通常的 18 小時內處於低功耗保存到磁碟狀態,否則它什麼也不做。我認為網路活動是一個很好的測試指標。我願意接受更發達和更強大的解決方案或固有的伺服器屬性來檢查是否存在。
(我不確定每天的電源循環是否會比 ZFS 整天執行數據完整性檢查的持續磨損更糟……只是不確定。)
找出 SSH 會話產生的網路流量跡象的一種可能實現是通過防火牆規則:
- 最初,匹配進出埠 22/tcp 的流量的規則在啟動時載入;
- 然後,腳本會定期從防火牆檢索統計資訊,並將這些規則的命中計數儲存到臨時文件中;
- 該腳本將能夠通過檢測任何命中計數的變化來檢測網路流量。
該方法還可以檢測 SFTP 和 RSYNC 生成的流量,因為這兩個應用程序都通過 SSH 協議執行。
更新活動的檢測很難通過防火牆執行,因為軟體包下載使用 FTP、HTTP 和 HTTPS 協議,並且需要調整防火牆規則以區分軟體更新和記錄的 HTTP 流量。因此,我的建議是通過檢查和的修改時間
/var/lib/apt/lists
來檢測軟體更新。/var/cache/apt/archives``/var/lib/dpkg/lock
我的實施方案如下:
這些命令行設置
iptables
和ip6tables
規則。# apt-get install iptables-persistent # iptables -w -N fwstats # iptables -w -A fwstats # iptables -w -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED -j fwstats # iptables -w -A OUTPUT -p tcp --dport 22 -m state --state ESTABLISHED -j fwstats # iptables-save > /etc/iptables/rules.v4 # ip6tables -w -N fwstats # ip6tables -w -A fwstats # ip6tables -w -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED -j fwstats # ip6tables -w -A OUTPUT -p tcp --dport 22 -m state --state ESTABLISHED -j fwstats # ip6tables-save > /etc/iptables/rules.v6
這是等效的設置
nftables
:# apt-get install nftables # nft add chain inet filter fwstats # nft add rule inet filter fwstats counter # nft add rule inet filter input tcp dport ssh ct state established jump fwstats # nft add rule inet filter output tcp dport ssh ct state established jump fwstats # echo -e \#\!`which nft` -f\\nflush ruleset > /etc/nftables.conf # nft list ruleset >> /etc/nftables.conf
這是一個監控腳本的模板。該
getStats
功能應根據使用的防火牆進行調整。#!/bin/bash getStats () { if using_nftables; then nft list chain inet filter fwstats | grep counter elif using_xtables; then for xtable in iptables ip6tables; do "${xtable}" -w -xnvL fwstats | egrep '^([[:space:]]+[0-9]+){2,2}' done fi } stateFile="/run/hibernation_state" currentStats="`getStats`" if [ "x${currentStats}" != "x" ]; then previousStats="`cat \"${stateFile}\"`" if [ "x${currentStats}" == "x${previousStats}" ]; then # No network traffic has been detected. Check files related do DPKG and APT clearToHibernate='true' now="`date '+%s'`" for path in "${stateFile}" \ '/var/lib/apt/lists' \ '/var/cache/apt/archives' \ '/var/lib/dpkg/lock' ; do pathModTime="`stat -c '%Y' "${path}"`" # 10800 seconds = 3 hours if [ "$((now-10800))" -lt "${pathModTime}" ]; then clearToHibernate='false' fi done if "${clearToHibernate}"; then # OK to hibernate. systemctl hibernate fi else # Network traffic has been detected. Refresh stats. echo "${currentStats}" > "${stateFile}" fi fi