每隔一段时间,VPS 的日志里就会有几千次登录尝试,他们一般都是扫描默认的 22 端口,然后用密码字典破解登录,如果不幸中招,就会被用来挖矿或者其它非法操作,速度变慢不说,还可能会被你的 VPS 服务商因为滥用资源被禁掉机器。🐒

因此,拿到服务器的第一件事自然是看 ip 是否正常,然后修改 SSH 端口并制作密钥登录,然后修改防火墙规则,珍爱小鸡,防止暴力破解。

基于安全原因,其实不建议开放 root 用户的远程登录权限,但这里为了演示方便默认都为使用 root 用户操作。

修改默认的 SSH 端口

1. 编辑 ssh 配置文件

vim /etc/ssh/sshd_config

将 #Port 22 修改为想要的端口号:0~65535,选择数值较大的比较好。

然后保存,重启 ssh 服务:

systemctl restart sshd.service

2. 增加 SElinux 端口

如果你使用的 CentOS 系统需要设置,其它系统则不用。

查看 SElinux 状态:

/usr/sbin/sestatus -v
semanage port -a -t ssh_port_t -p tcp [端口号]

查看当前 SElinux 允许的 ssh 端口:

semanage port -l | grep ssh

制作密钥登录

然后,要是你被盯上了( ̄▽ ̄"),该端口+设置复杂密码也不安心,这是就要设置用密钥登录,公钥加上唯一对应的私钥就稳当不少。

使用 XShell 制作密钥

打开 XShell

看情况下一步即可,将公钥保存为文件,改名为 authorized_keys 记得最好备份密钥,用户密钥管理者-导出即可。将公钥上传到 /root/.ssh 文件夹并赋予权限

chmod 600 /root/.ssh/authorized_keys

使用 ssh-keygen 工具

目前有四种常见的 SSH Key 类型:

  • DSA 已被认为是一个不安全的算法,不建议使用,由于存在安全性缺陷,OpenSSH 7.0 已停止支援 DSA 演算法。
  • ECDSA 在 OpenSSH 5.7 开始支持 ECDSA,有 256/384/521 位三种长度可选,如果指定不是这三种长度,会发生错误。但 ECDSA 所使用的椭圆曲线是由 NIST 所选择的,有被 NSA 植入后门的可能,另外由于规格复杂,技术上不容易被完全正确操作,因此不推荐使用。
  • RSA 兼容性最好的算法,也是目前 ssh-keygen 默认使用的算法。安全性强度取决于密钥的长度,可以用 -b 参数指定,预设,可设定长度范围从 1024 ~ 16384 位。其中 1024 位已被证明安全性强度不足,而使用默认的 2048 位已足够安全,但还是建议使用更长的 3072 或者 4096 位。
  • ED25519 使用 SHA-512/256 的 EdDSA 签名方案,并选用 Curve25519 这组椭圆曲线的算法。长度固定为 256 位,不需要调整长度,在 OpenSSH 6.5 后才支持。是目前综合安全性和性能最好的算法,推荐使用。

而生成密钥,这里有两种思路:

1. 直接在服务器上生成,然后将私钥下载到本地:

# 生成 RSA 密钥:
ssh-keygen -t rsa -b 4096
# 生成 ECDSA 密钥(推荐):
ssh-keygen -t ed25519

命令执行完成后,会生成密钥对 id_rsa(id_ed25519) 和 id_rsa.pub(id_ed25519.pub),其中 id_rsa 为私钥,做好保存,id_rsa.pub 为公钥,将公钥复制到 /root/.ssh/ 目录重命名为 authorized_keys 并修改权限。

chmod 600 /root/.ssh/authorized_keys

2. 在本地使用 ssh-keygen 生成,手动拷贝或者使用 ssh-copy-id 命令,该命令可以把本地的 ssh 公钥文件复制到远程主机对应的账户下的 authorized_keys 文件中:

ssh-copy-id -i /root/.ssh/id_rsa.pub root@x.x.x.x -p [端口号]
  • -i 参数后面是指定本地公钥文件的路径

之后根据提示输入密码即可,成功会有如下提示:

Now try logging into the machine, with:   "ssh 'root@x.x.x.x'"
and check to make sure that only the key(s) you wanted were added.

如果是手动拷贝的记得设置以下权限:

chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys

最后两种方式都最好编辑登录方式,禁止密码登录:

vim /etc/ssh/sshd_config  

#PubkeyAuthentication no 改为 PubkeyAuthentication yes
#PasswordAuthentication yes 改为 PasswordAuthentication no

重启ssh服务:

systemctl restart sshd.service

记得将私钥文件保管好!

配置防火墙

CentOS (firewalld)

首先查看防火墙状态:

firewall-cmd --state

若没有启用,需要启用:

systemctl start firewalld
systemctl enable firewalld

开放 ssh 端口,使用:

firewall-cmd --permanent --zone=public --add-port=[端口号]/tcp

或者修改 /etc/firewalld/zones/public.xml 添加:

<port protocol="tcp" port="3306"/><!--MySQL数据库-->

防火墙重载:

firewall-cmd --reload

查看已暴露端口:

firewall-cmd --permanent --list-port

或者查看添加端口是否成功:

firewall-cmd --zone=public --query-port=[端口号]/tcp

先不要关闭窗口,测试能连接后再下一步,防止与小鸡失联😐

Debian (ufw)

安装 ufw 后首先设置默认策略:

ufw default deny incoming
ufw default allow outgoing

允许指定端口连接:

ufw allow [端口号]

允许指定端口范围连接:

ufw allow 6660:6670/tcp

启用 ufw:

ufw enable

允许指定的 ip 访问:

ufw allow from 192.168.1.0
# 允许指定子网访问
ufw allow from 192.168.1.0/24
# 允许指定ip访问指定端口
ufw allow from 192.168.1.0 to any port 22
# 允许指定ip访问指定端口的指定协议
ufw allow from 192.168.1.0 to any port 22 proto tcp

禁止指定 ip 访问:

sudo ufw deny from 207.46.232.182
# 禁止指定ip访问指定端口
ufw deny from 192.168.0.1 to any port 22

这里需要注意的是,ufw 的默认匹配顺序是:按照从上到下的顺序一旦规则匹配,其他规则将不会被匹配。因此需要将特定规则放在第一位,将通用规则放在第二位。如果需要插入规则,可以使用插入命令:

ufw status numbered
ufw insert 1 allow from 192.168.1.0

禁止 ping,只需要将 /etc/ufw/before.rules 文件中下列行的 ACCEPT 改为 DROP

# ok icmp codes for input
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j DROP
-A ufw-before-input -p icmp --icmp-type time-exceeded -j DROP
-A ufw-before-input -p icmp --icmp-type parameter-problem -j DROP
-A ufw-before-input -p icmp --icmp-type echo-request -j DROP

然后重载 ufw:

ufw reload

删除指定规则:

ufw delete allow [端口号]

或者通过编号,然后删除指定序号:

ufw status numbered
ufw delete [序号]

查看 ufw 状态:

ufw status

关闭 ufw:

ufw disable

重置 ufw:

ufw reset

配置好以上操作后可以避免绝大多数的恶意破解,当然还有其它进阶操作,但已经足够,毕竟要是真有大佬搞你,只有关机报平安咯🍺

如果你认为这篇文章还不错,可以考虑支持作者