前言
SSH 是我们连接服务器最常用的方式,就像远程控制电脑的一把钥匙。只要拿到这把钥匙,别人就可以随意进出服务器,查看、修改甚至删除里面的内容。所以,SSH 的安全就是服务器的安全第一道防线。
如果配置不当,比如使用简单密码、允许任何人连接、没有限制登录方式,就很容易被黑客扫描到并尝试暴力破解。一旦成功,后果可能是服务器被入侵、网站被篡改、数据被删除,甚至被用来攻击其他人。
本文采用Debian12系统作为演示
DD脚本(非必选)
如选择商家提供的系统,忽略这一步。
有时候商家提供的系统太臃肿,想要轻便一点的;又或者像一些大厂,他们的系统内置了一些检测的软件,就想要一个“纯净”的系统。现在已经习惯了拿到机器,第一时间DD系统。
- Leitbogioro 来源
国外服务器
wget --no-check-certificate -qO InstallNET.sh 'https://raw.githubusercontent.com/leitbogioro/Tools/master/Linux_reinstall/InstallNET.sh' && chmod a+x InstallNET.sh
国内服务器
wget --no-check-certificate -qO InstallNET.sh 'https://gitee.com/mb9e8j2/Tools/raw/master/Linux_reinstall/InstallNET.sh' && chmod a+x InstallNET.sh
安装
debian12为例,默认密码LeitboGi0ro
,建议修改密码和端口,防止被人扫描爆破。
bash InstallNET.sh -debian 12 -pwd '密码' -port "端口"
- Bin456789 来源
国外服务器
curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh $_
国内服务器
curl -O https://gitlab.com/bin456789/reinstall/-/raw/main/reinstall.sh || wget -O reinstall.sh $_
安装
debian12为例,默认密码123@@@
,建议修改密码和端口,防止被人扫描爆破。
bash reinstall.sh debian 12 --password 密码 --ssh-port 端口
以上两个DD脚本均以debian系统举例,其他Linux系统同理,Windows自行查看GitHub。
SSH登录防护
修改密码
登录SSH后,给现在的账户修改密码,此时一般是root用户,我习惯先修改了密码,再进行其他操作。
推荐两个密码生成的网站:
建议密码长度大于20个字符,且字母大小写、数字、符号全选上,这样几乎很难被破解密码。
接下来修改密码:
passwd
把新密码复制粘贴进去。注意,这里的密码是看不见的,正常输入就好。然后回车,回车后还要再确认一次新密码,再次粘贴新密码进去。
就会看到成功的提示passwd: password updated successfully
。
更新系统软件包
apt update -y
apt upgrade -y
apt update
是查更新,apt upgrade
是装更新。更新意味着修复安全漏洞(很多更新是为了防黑客)、提高软件稳定性、获得新功能、避免旧版软件带来的兼容性问题。
DD系统一般比较纯净,可能会缺少一些我们常用的软件,我们安装新机常用软件包安装组合
apt install sudo wget curl -y
修改默认 SSH 端口
一般系统默认都是22端口,不修改端口意味别人更加容易扫到并破解你。可用的端口范围:0-65535,建议修改成高位的端口。
nano /etc/ssh/sshd_config
找到
Port
可以使用快捷搜索
ctrl+w
,搜索Port
,如果你知道默认的端口,例如22端口,可以直接搜索Port 22
,回车把Port后面的数字改成你想要的端口,可用的端口范围:0-65535,建议修改成高位的端口,例如53142。注意:
port
和端口
中间有个空格如果在Port的前面有个
#
号,这说明这行被注释了,无法生效,要把前面的#
号给删除Ctrl+x
确认保存且退出。
安装sudo
如果没有执行上面的常用软件包安装组合,那么你可能需要安装sudo,已执行的忽略
apt install sudo -y
重启SSH
sudo service sshd restart
注意:请不要关闭当前的ssh窗口!如果你密码或者端口号搞错了,那就会无法登录SSH。这时,我们需要另外单独开一个SSH窗口测试是否修改成功。
注意:请不要关闭当前的ssh窗口!如果你密码或者端口号搞错了,那就会无法登录SSH。这时,我们需要另外单独开一个SSH窗口测试是否修改成功。
注意:请不要关闭当前的ssh窗口!如果你密码或者端口号搞错了,那就会无法登录SSH。这时,我们需要另外单独开一个SSH窗口测试是否修改成功。
使用普通账户代替 root 提高安全性
使用 root 登录系统,一旦密码泄露或账号被入侵,攻击者就能立即拥有最高权限,非常危险。而使用普通用户登录,只有在需要时才通过 sudo
临时提权,能有效限制潜在破坏范围。
创建一个新的普通用户
sudo adduser jack
名字你可以随便起,这里以jack
为例。
接下会让你输入两次jack账户的密码,密码也是看不到的,正常输入即可,其他一路回车。
将新用户加入 sudo 组(授予管理员权限)
sudo usermod -aG sudo jack #jack换成你的用户名
测试 sudo 权限
切换到新用户:
su - jack #jack换成你的用户名
然后测试一下:
sudo ls /root
系统会提示你输入一次jack
的密码确认:
[sudo] password for jack:
输入密码确认后,如果你能看到 /root 目录说明配置成功。
取消普通账户切换root权限时密码(非必要,慎重选择)
经过上面输入sudo ls /root
时,你会发现jack账户临时使用root权限,会让你输入jack账户的密码。如果不想每次都输入密码,那么我们再做些调整:
注意:这样会和我们所说的安全建议,是完全相反的。这样操作会让普通账户轻而易举的切换成root权限。虽然操作简单方便,但是安全性降低了。
非必要,不要如此操作!!!
非必要,不要如此操作!!!
非必要,不要如此操作!!!
visudo
在 User Privilege Specification
下加入一行 jack ALL=(ALL) NOPASSWD: ALL
,jack
改成你的用户名
禁止root登陆
配置ssh文件
nano /etc/ssh/sshd_config
Ctrl+w
搜索PermitRootLogin
,把后面的值改为no
,Ctrl+x
确认保存并退出。
重启SSH
sudo service sshd restart
注意:请不要关闭当前的ssh窗口!我们需要另外单独开一个SSH窗口测试是否修改成功。
修改SSH登录账户密码
到你的SSH客户端,修改服务器的登录账户和密码,例如把root改成jack,密码换成jack的密码。
密钥登录(备选)
虽然我更喜欢密码登录,但是密码登录的安全性是远远不如密钥登录的。
本地SSH登录
第一步:生成 SSH 密钥
ssh-keygen -t rsa -b 4096 -C "[email protected]"
一路按回车,会在 ~/.ssh/
下生成:
id_rsa
:私钥(保存在本地,不能泄露)id_rsa.pub
:公钥(上传到服务器)
第二步:上传公钥到服务器
方法一:ssh-copy-id(推荐)
ssh-copy-id 用户名@服务器IP
方法二:手动上传
cat ~/.ssh/id_rsa.pub # 本地复制公钥内容
登录服务器后操作
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys # 粘贴进去并保存
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
第三步:测试密钥登录
ssh 用户名@服务器IP
如果能直接登录而不需要密码,说明配置成功!
使用第三方 SSH 工具登录
一、Xshell 登录(支持 Windows)
生成密钥对
打开 Xshell → 工具 → "用户密钥生成向导"
类型选择:RSA,位数选择:2048 或 4096
点击“生成密钥” → 保存
.ppk
和.pub
文件(公钥和私钥)可设置密钥口令(建议设置)
上传公钥到服务器
打开
.pub
文件,复制内容登录服务器,把内容粘贴到:
~/.ssh/authorized_keys
中设置权限:
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
配置会话使用密钥登录
在 Xshell 中新建连接
认证方式选择“公钥”
加载你刚才生成的
.ppk
私钥文件保存并连接
二、PuTTY 登录(轻量好用)
使用 PuTTYgen 生成密钥对
打开
PuTTYgen
工具选择 RSA(2048 或 4096 位),点击“生成”
保存私钥(
.ppk
),复制上方的公钥内容
上传公钥到服务器(同上)
使用 PuTTY 登录
打开 PuTTY → 填写 IP 地址
在左侧导航栏中:
Connection
→SSH
→Auth
→ 浏览选择你的.ppk
私钥文件回到 Session 页面,保存配置 → 点击连接
三、Termius 登录(跨平台)
进入 Termius 应用,点击左边的 Keychain,点击 New Key
选择 Generate Key 或导入已有
.pem/.ppk
文件配置连接时,选择使用该私钥
同样需要将公钥复制到服务器的
~/.ssh/authorized_keys
文件中
四、MobaXterm 登录(全能型)
打开 MobaXterm → Tools → "MobaKeyGen"
生成密钥对后,保存
.ppk
或.pem
文件在 MobaXterm 的 SSH 会话中 → 设置使用私钥文件进行认证
上传公钥到服务器(可通过 MobaXterm 自带的 SFTP)
禁止密码登录
编辑 SSH 配置文件
sudo nano /etc/ssh/sshd_config
通过ctrl+w
分别搜索PermitRootLogin
、PubkeyAuthentication
、PasswordAuthentication
,修改后面的值,Ctrl+x
确认保存且退出。(注意:如果在PasswordAuthentication
的前面有个#
号,这说明这行被注释了,无法生效,要把前面的#
号给删除)
PermitRootLogin prohibit-password # 禁止root用户密码登录(允许密钥登录)
PubkeyAuthentication yes # 启用密钥认证
PasswordAuthentication no # 禁用密码认证
重启 ssh
sudo service sshd restart
注意:先确保密钥登录没问题再关闭密码登录,否则可能无法再远程连接。
普通账户使用SFTP
在提高 SSH 安全性时,我们通常会用普通用户登录系统,并禁用 root 登录。但是这样做之后,新用户使用SSH客户端,通过 SFTP(如 Termius、FileZilla、WinSCP)登录时,会发现无法访问系统的 /root
目录或其他关键文件夹,默认只允许访问自己的家目录(如 /home/yourname
)。
这是系统为了安全起见,限制普通用户访问高权限目录。那我们该怎么办呢?以下是推荐的安全做法:
普通用户的默认目录是
/home/用户名/
,SFTP 登录后也会默认进入这里上传或下载多个文件时,建议使用
.zip
或.tar.gz
打包处理可以为常用操作写一两个脚本,节省手动输入命令(不懂就让AI写)
场景举例:
创建了一个普通用户 jack
,并设置好了 SSH 登录 + sudo 权限。现在你想通过 SFTP 管理 /root/config.txt
这个文件。
复制到自己的目录再操作
把 root 目录下的文件复制到你自己目录下
sudo cp /root/config.txt /home/jack/
修改文件权限
把文件权限改成你自己的
sudo chown jack:jack /home/jack/config.txt
现在你就可以用 Termius 或其他 SFTP 工具连接后,直接直接访问、编辑、下载 /home/jack/config.txt
这个文件啦!
把编辑后的文件复制回 /root 覆盖旧文件
sudo mv /home/jack/config.txt /root/
如果你只是修改了某一部分,也可以使用更稳妥的:
sudo cp /home/jack/config.txt /root/config.txt
如果 /root/
下已经有一个 config.txt
文件:
系统不会提示你确认,会直接覆盖原来的文件
原文件内容会被完全替换
文件的修改时间会变成现在这个时间
如何避免意外覆盖
可以在移动前先备份一份原文件:
sudo cp /root/config.txt /root/config.txt.bak
或者在复制时让系统提示你:
sudo cp -i /home/jack/config.txt /root/
其中 -i
代表 interactive(交互)模式,会提示你是否覆盖。
用 root 登录 SFTP(仅了解,不建议)
修改SSH配置文件:
sudo nano /etc/ssh/sshd_config
找到PermitRootLogin
,并把后面的值改为yes
,Ctrl+w确认保存并退出。
这样做便可以使用root登录,但这会让你的服务器暴露巨大安全风险,黑客只要知道你的 IP,就能疯狂撞 root 密码,极易被入侵。所以除非是临时使用、且不连接公网,否则强烈不建议启用 root 登录。
防火墙UFW
安装ufw
sudo apt install ufw -y
设置ufw使用默认值
sudo ufw default deny incoming
sudo ufw default allow outgoing
允许SSH连接
如果没有改端口:
sudo ufw allow ssh
修改了SSH端口的:
sudo ufw allow 新端口/tcp comment 'SSH'
允许http连接
sudo ufw allow http
允许https连接
sudo ufw allow https
允许其他端口连接
sudo ufw allow 端口
启动ufw
sudo ufw enable
查看ufw状态
sudo ufw status
删除规则
查询规则数列
sudo ufw status numbered
删除规则
sudo ufw delete 需要删除规则前面的数字
重启ufw
sudo ufw reload
禁ping
sudo nano /etc/ufw/before.rules
Ctrl+w
搜索# ok icmp codes for INPUT
,一般是这段的最后一行-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT
,把ACCEPT
改成DROP
,然后Ctrl+x
确认保存并退出。
重启ufw
sudo ufw reload
安装Fail2ban
有时候我们遇到一些不法分子对我们的VPS进行ssh扫描爆破,为了防止暴力破解ssh,我们可以用到一款很好的防止暴力破解工具——Fail2Ban。安装 Fail2Ban 主要是为了增强系统的安全性,防止暴力破解攻击和其他恶意行为。
之前也有写过一篇关于Fail2Ban的文章《SSH安全工具—— Fail2Ban》
上面已经做了一些前期工作,我们先安装rsyslog。Debian12默认没有安装rsyslog,没有它可能会无法启动Fail2Ban。rsyslog 是一种日志管理工具,主要用于在 Unix 和 Linux 系统中收集、存储和转发日志信息。它是一个强大的日志系统,常用于系统监控、安全审计、故障排查等。
sudo apt install rsyslog -y
安装Fail2ban
sudo apt install fail2ban -y
配置Fail2ban
在Debian12中,Fail2ban使用的是jail.local
,可以在/etc/fail2ban/
中创建jail.local
文件,然后使用vi或nano等工具,把下方配置信息填入其中。或者直接输入nano /etc/fail2ban/jail.local
,把下方配置信息复制进去并保存退出。配置信息根据自身需求调整。
[DEFAULT]
backend = systemd
banaction = ufw
bantime = 15m
findtime = 15m
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
以下是配置信息的解释:
[DEFAULT]
部分这个部分包含 Fail2Ban 的全局默认设置,适用于所有监控的服务,除非在单个服务配置中被覆盖。
backend = systemd
这个参数指定了日志后端的类型。在这里,
systemd
表示 Fail2Ban 会使用systemd
的日志系统来跟踪系统日志。如果使用的是其他日志系统(如
syslog
),可以将其更改为相应的后端。
banaction = ufw
这个配置指定了当 Fail2Ban 检测到攻击时,采取的封禁措施。
ufw
表示使用 Uncomplicated Firewall (UFW) 工具来阻止恶意 IP 地址。其他可选的封禁方法包括
iptables
(如果未使用 UFW)等。
bantime = 15m
封禁时间,即 Fail2Ban 在发现恶意 IP 地址后,会将其封禁多长时间。这里设置为
15m
,表示封禁 15 分钟。你可以根据需要将其更改为
m
(分钟)、h
(小时)或d
(天),如果是无限禁封,设置为-1
。
findtime = 15m
这是 查找时间窗口,它定义了 Fail2Ban 在多长时间内监测指定数量的失败登录尝试(由
maxretry
定义)。在这里,15m
表示在 15 分钟内,如果检测到超过maxretry
次的失败尝试,将触发封禁。如果在此时间窗口内失败的尝试次数超过
maxretry
,Fail2Ban 就会采取行动。
[sshd]
部分这是针对 SSH 服务(
sshd
)的配置,定义了 SSH 登录尝试的限制和封禁规则。
enabled = true
这个参数启用了 SSH 服务的 Fail2Ban 监控。如果设置为
false
,则 Fail2Ban 不会监控 SSH 服务的日志。这里设置为
true
,表示启用对 SSH 服务的监控。
port = ssh
这个参数指定了监控的服务端口。
ssh
是一个预定义的端口名,指的是默认的 SSH 端口(22)。如果你使用的是非默认端口(比如
2222
),可以改为port = 2222
。
filter = sshd
这个配置指定了 Fail2Ban 用于过滤 SSH 服务的日志文件的过滤器。
sshd
是预定义的过滤器,用于匹配与 SSH 登录相关的日志条目。过滤器会基于日志中出现的特定关键字(如
Failed password
)来识别失败的登录尝试。
logpath = /var/log/auth.log
日志路径,指定了 Fail2Ban 需要监控的日志文件。在这里,它指定了
/var/log/auth.log
,这是大多数基于 Debian 系统(如 Ubuntu)中保存认证相关日志的文件。如果你使用的是其他日志文件,可以修改为相应的路径。
maxretry = 3
最大重试次数,这个参数定义了在
findtime
时间窗口内允许的最大失败登录尝试次数。这里设置为3
,意味着如果在 15 分钟内尝试 SSH 登录失败 3 次以上,Fail2Ban 会认为这是恶意攻击并封禁该 IP 地址。
设置开机启动
sudo systemctl enable fail2ban
启动Fail2ban
sudo systemctl start fail2ban
重启Fail2ban(一定要执行,否则可能无法禁封IP)
sudo service fail2ban restart #重启
查看Fail2ban状态
sudo systemctl status fail2ban
查看日志和活动
tail -f /var/log/fail2ban.log
一些Fail2ban的命令
sudo fail2ban-client status #查看状态
sudo fail2ban-client status sshd #查看sshd的详细状态
auth.log处理(非必选)
认证日志/var/log/auth.log
反复出现CRON信息大量出现pam_unix(cron:session): session opened for user root by (uid=0),平时看日志的时候,一大片,看起来很碍事,很影响查看日志。
Apr 6 00:17:01 joe CRON [166555]: pam_unix(cron:session): session opened for user root(uid=0) by (uid=0)
Apr 6 00:17:01 joe CRON [166555]: pam_unix(cron:session): session closed for user root
Apr 6 01:17:01 joe CRON [166642]: pam_unix(cron:session): session opened for user root(uid=0) by (uid=0)
Apr 6 01:17:01 joe CRON [166642]: pam_unix(cron:session): session closed for user root
Apr 6 02:17:01 joe CRON [166735]: pam_unix(cron:session): session opened for user root(uid=0) by (uid=0)
Apr 6 02:17:01 joe CRON [166735]: pam_unix(cron:session): session closed for user root
Apr 6 03:10:01 joe CRON [166814]: pam_unix(cron:session): session opened for user root(uid=0) by (uid=0)
Apr 6 03:10:01 joe CRON [166814]: pam_unix(cron:session): session closed for user root
处理方法
nano /etc/pam.d/common-session-noninteractive
找到这一行session required pam_unix.so
在这行的上一行添加
session [success=1 default=ignore] pam_succeed_if.so service in cron quiet use_uid
Ctrl+x
确认保存并退出。
重启 crond 服务
sudo service cron restart
修改主机名
主机系统一般是商家自动生成,有时候要改成我们想要的名字
如果你想将主机名修改为 myservers,可以使用以下命令:
sudo hostnamectl set-hostname myservers
这将会把系统的主机名设置为 myservers
,并且这个修改是永久的。
修改后,你可以检查主机名是否已更改,使用以下命令:
hostnamectl
该命令将显示当前的主机名和其他系统信息。如果 myservers
已成功设置,它会显示在 Static hostname
旁边。
确保 /etc/hosts
文件中的主机名部分也做了相应的更改:
nano /etc/hosts
找到类似的行:
127.0.1.1 旧的主机名
将旧的主机名
替换为myservers
。
如果没有,则新起一行
127.0.1.1 myservers
Ctrl+x确认保存并退出。
完成这些步骤后,myservers
就会成为系统的主机名,重新打开SSH就会显示新的主机名。
总结
通过本教程,我们完成了 SSH 的核心安全配置,这些设置能有效提升服务器安全性,降低被攻击风险。并非每一项都要配置,选择合适自己且安全的。建议每台服务器上线后第一时间进行配置,保障系统稳定运行。
新系统适用的:
评论区