AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1162826
Accepted
Contango
Contango
Asked: 2024-07-21 18:50:23 +0800 CST2024-07-21 18:50:23 +0800 CST 2024-07-21 18:50:23 +0800 CST

如何确保 SSH 在 8 小时不活动后断开连接?

  • 772

在我们的 Debian 服务器上,我希望确保任何 SSH 连接都会在 8 小时后超时并断开连接。这是我们的安全顾问推荐的。

我执行了以下步骤:

# Log in as root then:
sudo vi /etc/ssh/sshd_config
# Use / to search for and change:
ClientAliveInterval=3600
ClientAliveCountMax=8
# Second parameter is number of hours before connection times out and drops.

# Then test config:
sudo sshd -t
# Restart
sudo systemctl restart sshd

然而,测试失败了。当我临时设置ClientAliveInterval=120并ClientAliveCountMax=2重新启动 sshd 守护进程时,我预计连接会在 4 分钟不活动后断开。然而,事实并非如此。

有任何想法吗?

ssh
  • 1 1 个回答
  • 195 Views

1 个回答

  • Voted
  1. Best Answer
    Esa Jokinen
    2024-07-22T03:26:23+08:002024-07-22T03:26:23+08:00

    OpenSSHsshd_config

    自 OpenSSH 9.2(Debian 12)以来正确的配置关键字

    OpenSSH 9.2(2023 年 2 月 2 日)引入了针对非活动会话的新功能。

    • sshd(8):通过新的 sshd_config(5)ChannelTimeout指令添加对通道不活动超时的支持。这允许在可配置间隔内未看到流量的通道自动关闭。不同的超时可应用于会话、X11、代理和 TCP 转发通道。

    • sshd(8):添加 sshd_configUnusedConnectionTimeout选项,用于终止一段时间内没有打开通道的客户端连接。这补充了上面的 ChannelTimeout 选项。

    对于本题中的八个小时,例如,

    ChannelTimeout *=8h
    UnusedConnectionTimeout 1m
    

    在哪里:

    • 分别监控*=8h所有通道。如果您希望任何通道上的活动重置超时,请使用特殊关键字global=8h。
    • 设置UnusedConnectionTimeout为一分钟,以便在最后一个通道关闭后立即终止连接。

    对于 OpenSSH < 9.2,必须通过其他方式来完成。

    使用的配置关键字用于无响应的会话

    并不ClientAliveInterval监视不活动的情况而是监视客户端是否仍然有响应。

    设置超时间隔(以秒为单位),如果在此间隔内未收到来自客户端的任何数据,sshd(8)将通过加密通道发送一条消息,以请求客户端做出响应。默认值为 0,表示不会将这些消息发送给客户端。

    以下文档ClientAliveCountMax可能有助于理解这一点:

    如果ClientAliveInterval设置为 15,并ClientAliveCountMax保留默认值,则无响应的SSH 客户端将在大约 45 秒后断开连接。设置为零ClientAliveCountMax将禁用连接终止。

    📜历史记录:在OpenSSH 8.2(2020 年 2 月 14 日)之前ClientAliveCountMax, 与 的工作方式不同0,其副作用是它可能被用于终止空闲连接。来自变更日志:

    Bug修复

    • sshd(8):使其ClientAliveCountMax=0具有合理的语义:它现在将完全禁用连接终止,而不是在第一次活动测试后无论成功与否都立即终止连接的当前行为。bz2627

    ⚠️然而,这种误导性的指令已在整个互联网上重复:

    • 极客问答:在 Linux 中断开非活动 SSH 连接
    • Vivek Gite 在nixCraft上:Linux / UNIX 在一段时间不活动后自动注销 BASH / TCSH / SSH 用户
    • Hayden James 在Linuxblog.io上发表文章:如何终止不活动的 SSH 会话
    • KGIII 在Linux 上的使用技巧:禁用非活动 SSH 会话
    • Aaron Kili 在Techmint上:如何在 Linux 中断开不活动或空闲的 SSH 连接
    • Satish Kumar 在教程要点中提到:如何在 Linux 中断开不活动或空闲的 SSH 连接?

    其中,只有 GiteClientAliveCountMax=0可以在 2020 年之前工作,但这算吗?毕竟,这篇文章很可能是在 2021 年写的……这让我想知道是否有人阅读过文档,或者他们正忙着复制粘贴其他人的博客文章。🤦‍♂️

    深入讨论替代方案

    脚本——小心谨慎,正确检测不活动

    Hayden James 给出了一个使用脚本自动化进程的示例。但是,使用该脚本很危险,因为它可能会终止正在使用的 SSH 会话。该脚本获取“空闲时间”,其中ps -eo pid,etimes,comm不etimes显示进程的空闲时间,而是显示进程运行的总时间。来自ps(1):

    标准格式说明符

    代码 标题 描述
    电子时代 过去 自进程启动以来经过的时间(以秒为单位)。

    Satish Kumar建议使用who来列出活跃用户,并使用 的第五列w -h来检测不活跃用户。但是,这个脚本也有一些缺陷:

    • 第五列不包含整数形式的秒数,而是字符串值,例如2.00s、7:51m或5days。[[ "$idle" -gt "1800" ]];无法正确解析。
    • 如果可以比较的话,该脚本将会终止用户的所有进程......
      • ...如果用户在任何会话中都没有输入任何内容。
      • ...包括终端多路复用器(screen、tmux)和其他旨在存在于活动 SSH 会话之外的进程。

    对不活动状态的检测应该更加精确,对要终止的进程的选择也应该更加精确。

    这种方法可能有效:

    1. 直接从 第二列中获取会话who。
    2. 用于stat获取 TTY 设备的最后访问时间(参见Celada 的解答)。
      who -s | awk '{ print $2 }' | (cd /dev && xargs stat -c '%n %U %X')
      
      可以直接转换为以秒为单位的年龄:
      who -s | awk '{ print $2 }' | (cd /dev && xargs stat -c '%n %U %X') \
        | awk '{ print $1"\t"$2"\t"'"$(date +%s)"'-$3 }'
      
    3. 用于pgrep查找sshdTTY 的进程,或者pkill终止它们。
      user=$(echo "$line" | awk '{print $1}')
      tty=$(echo "$line" | awk '{print $2}')
      age=$(echo "$line" | awk '{print $3}')
      pgrep -f "sshd: ${user}@${tty}"
      

    全部放在一起(更完整的内容find-inactive-ssh-sessions.sh请参见 oh2fih/ Misc-Scripts):

    #!/bin/bash
    MAX_IDLE=28800  # default 8 hours
    KILL=0          # set 1 to kill instead of list
    
    # Get TTYs with the seconds since the last access time
    TTYS=$(
      who -s \
        | awk '{ print $2 }' \
        | grep -ve "^:"
      )
    if [ "$TTYS" = "" ]; then
      exit 0
    fi
    
    TTY_AGES=$(
      echo "$TTYS" \
        | (cd /dev && xargs stat -c '%U %n %X') \
        | awk '{ print $1"\t"$2"\t"'"$(date +%s)"'-$3 }'
      )
    
    # Get sshd processes of the TTYs; list or kill
    while IFS= read -r line ; do 
      user=$(echo $line | awk '{print $1'})
      tty=$(echo $line | awk '{print $2'})
      age=$(echo $line | awk '{print $3'})
      if (( $age > $MAX_IDLE )); then
        if (( KILL == 1 )); then
          pkill -f "sshd: ${user}@${tty}"
        else
          pgrep -f -a "sshd: ${user}@${tty}"
        fi
      fi
    done <<< "$TTY_AGES"
    

    Shell 中的内置功能

    正如Vivek Gite所提到的,shell 具有在一段时间不活动后自动注销用户的功能。如果不需要强制注销,这些功能可能会有用,因为用户可以更改这些设置。

    • TMOUTbash、zsh&的环境变量ksh。
      export TMOUT=28800
      
    • autologout设置tcsh& csh。
      set -r autologout 28800
      

    如果您通过例如配置这些/etc/profile.d/,它们将影响所有会话。但是,您也可以使用中的功能sshd_config来配置它们:SetEnv& ForceCommand。例如,

    SetEnv TMOUT=28800
    
    Match Group cshusers
        ForceCommand set -r autologout 28800
    

    这个推荐从何而来?

    该建议可能基于NIST 800-171 修订版 2:

    3.1.11 在定义的条件后终止(自动)用户会话。

    讨论

    此要求涉及用户发起的逻辑会话的终止,而不是与通信会话相关的网络连接的终止(即断开与网络的连接)。每当用户(或代表用户行事的进程)访问组织系统时,就会启动逻辑会话(用于本地、网络和远程访问)。此类用户会话可以终止(从而终止用户访问),而无需终止网络会话。会话终止会终止与用户逻辑会话相关的所有进程,但用户(即会话所有者)专门创建的进程除外,以便在会话终止后继续运行。需要自动终止会话的条件或触发事件可以包括组织定义的用户不活动期、对某些类型事件的针对性响应以及对系统使用的时间限制。

    您应该决定哪一个对您更重要:防止某人未经许可使用连接还是管理连接的可靠性。是否可以通过其他方式防止未经授权的使用?例如,是否可以将 SSH 连接仅限于公司计算机,是否可以强制锁定不活动的公司计算机?

    • 8

相关问题

  • 如何最好地设置 ssh 隧道以访问远程网络 (Linux)

  • SSH 和重定向

  • 通过 SSH 会话使用 NET USER 命令拒绝访问

  • SSH 服务器零日漏洞利用 - 保护自己的建议

  • ubuntu apt-get upgrade - 如何在 shell 中单击确定?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve