ssh 常见配置

环境信息

  • Centos 7

ssh 免密登陆

在需要免密码登陆的场景下,可以配置 ssh 密钥登陆。配置步骤如下

  1. 在本地服务器上面执行命令生成密钥对
    $ ssh-keygen 
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/testuser/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/testuser/.ssh/id_rsa.
    Your public key has been saved in /home/testuser/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:Lzvl8GbOQETBVcTf8lf0Qk9KUQAESs9h8wARud+iQrk [email protected]
    The key's randomart image is:
    +---[RSA 2048]----+
    | .BBB*=.o+.|
    | oo= =. o o|
    | o.o .+ *.|
    | .. = =|
    | .S. . +.|
    | o...+ . o|
    | . .o*.. .|
    | E o== |
    | ..=o |
    +----[SHA256]-----+
    以上命令生成了公私密钥对,分别存储在了 /home/testuser/.ssh/id_rsa.pub/home/testuser/.ssh/id_rsa 中。
  2. 在本地服务器上面执行命令将其公钥添加到目标主机的 /home/testuser/.ssh/authorized_keys。或者手动拷贝公钥追加到目标主机的 .ssh/authorized_keys
    $ ssh-copy-id -p 30000 [email protected]
    /bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/testuser/.ssh/id_rsa.pub"
    The authenticity of host '[172.31.30.115]:30000 ([172.31.30.115]:30000)' can't be established.
    ECDSA key fingerprint is SHA256:vKD5th2QpWYv/hmt+180BsENDHWNcJdKiEBOH06h/K8.
    ECDSA key fingerprint is MD5:bf:8c:b9:e6:31:92:1f:a9:b6:7b:8f:50:d7:10:9e:fd.
    Are you sure you want to continue connecting (yes/no)? yes
    /bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new [email protected]'s password:

    Number of key(s) added: 1

    Now try logging into the machine, with: "ssh -p '30000' '[email protected]'"
    and check to make sure that only the key(s) you wanted were added.
  3. 在本地服务器上面验证可以免密登陆到目标服务器。

如果要配置双向免密,将以上步骤反过来操作一遍即可

常见配置

登录服务器,经常遇见以下提示信息,说明有主机一直在尝试暴力破解用户名密码

There were 696 failed login attempts since the last successful login.

查看登录失败的用户名和 ip 地址

$ grep "Failed password for invalid user " /var/log/secure | awk '{print $11,$13}' | sort | uniq -c | sort -k1 -n
3 wangli 47.74.0.77
3 work 47.74.0.77
3 yt 47.74.0.77
3 yx 47.74.0.77
3 yyz 47.74.0.77
3 zabbix 47.74.0.77
3 zd 47.74.0.77
3 zhangfan 47.74.0.77
3 zxy 47.74.0.77
4 client003 47.74.0.77
4 client004 47.74.0.77
4 dell 47.74.0.77
4 ftpuser 47.74.0.77
4 inspur 47.74.0.77
4 wang 47.74.0.77
5 git 47.74.0.77
5 nagios 47.74.0.77
5 testuser 47.74.0.77
6 omnisky 47.74.0.77
7 oracle 47.74.0.77
8 jenkins 47.74.0.77
10 hadoop 47.74.0.77
10 postgres 47.74.0.77
11 ubuntu 47.74.0.77
11 user 47.74.0.77
12 admin 47.74.0.77
15 test 47.74.0.77

sshd 加固配置建议

修改 sshd 配置文件 /etc/ssh/sshd_config,更改以下配置

  • sshd 默认端口 22 改为其他端口
  • 禁止 root 用户登录,创建其他普通用户以登录系统,普通用户登录后有需要再切换到 root
/etc/ssh/sshd_config
Port 30000
PermitRootLogin no
...

修改配置后重启 sshd 服务生效

systemctl restart sshd

如果可以安全的保存秘钥,也可以使用秘钥登录,禁止用户名密码登录,具体配置可参考:ssh 秘钥登录

若使用密码登陆,建议 配置 fail2ban 防止暴力破解

SSH 隧道

SSH 隧道(SSH Tunneling),也叫 SSH 端口转发 ,是一种通过加密的 SSH 连接来传输其他协议数据(如 HTTP、MySQL、VNC 等)的技术。SSH 隧道(SSH Tunneling),也叫 SSH 端口转发,是一种通过加密的 SSH 连接来传输其他协议数据(如 HTTP、MySQL、VNC 等)的技术。

SSH 隧道主要解决以下三大核心痛点:

  • 数据加密(安全性) : 许多老旧协议(如 Telnet 或某些数据库连接)是明文传输的。通过隧道传输,可以为这些协议提供端到端的加密。

  • 突破防火墙限制(内网穿透) : 比如你在家里想访问公司内网的某个服务,或者公司防火墙封锁了 8080 端口,但允许 22 (SSH) 端口,你就可以通过隧道绕过去。

  • 隐藏真实服务 : 很多服务器为了安全,只开放 SSH 端口。你可以关闭数据库(如 MySQL 3306)的公网访问,只允许通过 SSH 隧道进行本地连接。

SSH 隧道的三种模式

  • 本地端口转发 (Local Forwarding)

    • 原理 : 把发往你本地机器 A 端口的数据,通过 SSH 隧道转发到远程机器 B 的端口。 是你通过 SSH Server 去访问别人(目标服务器)
    • 命令ssh -L [本地端口]:[目标服务器IP]:[目标端口] [SSH用户名]@[REMOTE_IP]
  • 远程端口转发 (Remote Forwarding)

    • 原理 :把发往远程服务器 A 端口(可以被外部访问)的数据,通过 SSH 隧道转发到你本地机器 B 的端口(无法被外部访问)。 是别人通过在 SSH Server 上启动的(远程)端口(转发流量)访问你的 本地 IP:端口 ,主要用于本地是内网,外网无法直接访问的场景中。
    • 命令ssh -R [远程端口]:[本地IP]:[本地端口] [SSH用户名]@[远程服务器IP]

      这条命令在远程服务器上(拥有公网 IP,别人可以访问)开启了 远程端口 ,这个远程端口可以被外部访问,当外部流量访问此端口时,流量会通过 SSH 连接转发到(不能被外部直接访问)本地端口,从而实现内网访问能被外网访问的效果。

  • 动态端口转发 (Dynamic Forwarding)

    • 原理 :不绑定固定端口,而是开启一个 SOCKS 代理,根据应用协议动态转发。
    • 命令ssh -D [本地代理端口] [SSH用户名]@[远程服务器IP]

SSH 隧道模式经常配合使用的其他选项:

  • -N : 告诉 SSH 不要执行远程命令(只用于转发端口)。
  • -f : 让 SSH 在后台运行。
  • -C : 压缩数据,适合带宽较慢的情况。

SSH 隧道相关配置( /etc/ssh/sshd_config

  • GatewayPorts yes

常见错误

Could not load host key

docker 容器中安装 openssh-server 后,使用命令 /usr/sbin/sshd -D 启动 sshd 服务,通常会报以下错误

$ /usr/sbin/sshd
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key

执行以下命令解决:

ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N '' 
ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''
ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key -N ''

配置 ssh 公私钥免密登录后提示输入密码登陆

在使用了 ssh-copy-id [email protected] 配置免密钥登录之后,发现 ssh 到机器上还是需要密码。在目标服务器上面查看 ssh 日志

# cat /var/log/secure
sshd[14034]: pam_unix(sshd:session): session closed for user testuser
sshd[14133]: Authentication refused: bad ownership or modes for file /home/testuser/.ssh/authorized_keys
sshd[14133]: Connection closed by 172.31.30.123 port 44164 [preauth]
sshd[14313]: Authentication refused: bad ownership or modes for file /home/testuser/.ssh/authorized_keys
sshd[14313]: Connection closed by 172.31.30.123 port 15928 [preauth]
sshd[16213]: Authentication refused: bad ownership or modes for file /home/testuser/.ssh/authorized_keys

看到登陆报错: Authentication refused: bad ownership or modes for file /home/testuser/.ssh/authorized_keys,检查文件 /home/testuser/.ssh/authorized_keys 权限,看到文件权限为 -rw-rw-r--

# ll /home/testuser/.ssh/
total 4
-rw-rw-r-- 1 testuser testuser 2815 Aug 31 14:15 authorized_keys

修改文件权限为 600,重新登陆,可以免密码登陆。