VPS基础安全配置实践指南

记录了新购VPS后必须进行的一系列基础安全设置,旨在提升服务器的防御能力,防止常见攻击。

Author Avatar

ghung

  ·  4 min read

本文基于 @Raven95676 的原帖,并结合我的个人使用习惯进行了定制化整理,作为自己的操作备忘录。

原帖地址:VPS基本安全措施

前言 #

随着逐渐看到一些「Self Host」的服务,拥有一台属于自己的服务器的想法越来越强烈。终于,在24年的一次促销中,买到了第一台具有公网IP的小机器,1c1g。

拿到了机器,开机之后意味着暴露在了互联网中。在互联网中,每时每刻都有无数的恶意流量发出。我们需要做什么呢?

如果选择将网站 / 服务放在知名厂商虚拟主机上,虚拟主机的厂商会负责基本的服务器安全措施。但如果放在 VPS 上,那么你就是服务器的安全负责人了。更多的权限代表着更多的义务,VPS 在具有更高的自由度的情况下自然有更高的风险。而我们要做到的不是绝对安全,而是比大多数人安全。 只要做到没那么容易被攻破那就是胜利。

安全管理系统 #

有些 VPS 厂商默认提供的是 root 账户。众所周知,root 账户拥有整个系统最高的权限,这么高的权限自然是不安全的。正确的做法是创建一个非 root 账户,在必须使用 root 权限时使用 sudo 提权。

创建非 root 账户 #

使用以下命令创建一个具有提权能力的账户:

useradd -m -G sudo -s /bin/bash 用户名
  • useradd: 这是一个用于创建新用户的命令。
  • -m: 此选项会在 /home 目录下为新用户创建主目录。
  • -G sudo: 此选项将新用户添加到 sudo 组,允许其使用 sudo 命令执行管理员操作。
  • -s /bin/bash: 此选项指定新用户的默认 shell 为 /bin/bash(常用 shell)。
  • 用户名: 这是你要创建的新用户的用户名。

然后我们给这个用户设置一个至少为 16 位的随机大小写字母 + 数字的密码:

passwd 用户名

建议把 root 用户的密码也改掉,云服务器的默认密码强度还是差点,而且有些服务商会通过邮件来发送默认密码,不太安全。

禁用 root SSH 密码登陆 #

先不提 root 登录本身就是危险的行为,root 账户的用户名固定为”root”,如果允许其通过密码登录,攻击者只需进行密码穷举即可尝试攻破系统。之前我们已经创建了非 root 账户,在这里我们只需要禁用非 root 账户的 SSH 登录即可。

执行以下命令编辑 SSH 配置文件:

sudo vim /etc/ssh/sshd_config

进行如下设置:

# 禁止 Root 用户通过密码远程登录 
PermitRootLogin prohibit-password

查看/etc/ssh/sshd_config.d/目录下有无其他配置文件,防止不生效。有些厂商的初始镜像内已经有了一些配置会覆盖掉我们编写的。

ls /etc/ssh/sshd_config.d/

之后重启 SSH 服务生效:

sudo systemctl restart ssh

为什么不设置成 no:

庄 sir:

另,直接禁掉 root 登录 PermitRootLogin no 我也不常用,更习惯和其他 sudoer 一样配密钥然后禁止密码登录仅允许密钥登录。我是一般能操做线下集群的机子才会这么配,不然出个故障没 root 用不了了,比如存储满了远程 ssh session 都建立不了。

Oganneson:

理论上 PermitRootLogin 是好的,但在服务器寄掉需要救援时就会变麻烦,我其实更推荐只关闭远程密码登录,保留本地密码登录,出问题时可以通过 vnc 或者 ipmi 本地登录 root 进行救援。

修改 SSH 端口号 #

登上去第一件事就是改 SSHD 的 端口并修改防火墙,22 全是猜密码的请求。
有个小技巧,就是改端口并重启 sshd 后当前的连接并没有断,新建一个终端使用新端口发请求,能连上就是修改正确,要是不能建立新连接,还可以改回来,或查下防火墙的配置。

正常情况下,直接通过 sudo vim /etc/ssh/sshd_config 修改 SSH 端口,然后再使用 sudo systemctl restart ssh.service 重启 SSH 服务应用更改是可行的:

# 设置 SSH端口 Port 自拟
Port 20251

但是在 Ubuntu 22.10 或更高版本中各位可能发现这是无效的,各位会发现 SSH 服务在重启后依然监听原端口。

因为在 Ubuntu 22.10 或更高版本中,ssh 默认通过套接字激活。

在 Ubuntu 22.10、Ubuntu 23.04 和 Ubuntu 23.10 中进行修改的方法是:

sudo mkdir -p /etc/systemd/system/ssh.socket.d
sudo vim /etc/systemd/system/ssh.socket.d/listen.conf
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo systemctl restart ssh.service

listen.conf 的参考配置为:

[Socket]
ListenStream=
ListenStream=2233

在 Ubuntu 24.04 中进行修改的方法是:

sudo vim /etc/ssh/sshd_config
sudo systemctl daemon-reload
sudo systemctl restart ssh.service

如果不在乎通过套接字激活节省的内存,可以通过以下命令恢复到非套接字激活:

警告: 务必确认配置文件正常。

sudo systemctl disable --now ssh.socket
sudo systemctl enable --now ssh.service

如有配置迁移(Ubuntu 22.10 及以上,Ubuntu 24.04 以下):

sudo systemctl disable --now ssh.socket
rm -f /etc/systemd/system/ssh.service.d/00-socket.conf
rm -f /etc/systemd/system/ssh.socket.d/addresses.conf
sudo systemctl daemon-reload
sudo systemctl enable --now ssh.service

Fail2ban 防暴力破解 SSH 配置SSH ip白名单 #

执行以下命令安装 Fail2ban:

sudo apt install fail2ban

安装完成后 Fail2ban会自动运行,可以检查一下服务状态

sudo systemctl status fail2ban

如果为dead,注意开启fail2ban服务

sudo systemctl start fail2ban

官方推荐的做法是利用 jail.local 来进行自定义设置: 这样做的好处是,在升级 Fail2ban 时,你的自定义配置不会丢失。

sudo vim /etc/fail2ban/jail.local

可以参照以下配置文件来进行自己的配置(记得删注释):

[sshd]
ignoreip = 127.0.0.1/8 # 白名单,知道自己的固定公网ip网段可以配置
enabled = true
filter = sshd
port = 22 # 端口,改了的话这里也要改
maxretry = 5 # 最大尝试次数
findtime = 300 # 多少秒以内最大尝试次数规则生效
bantime = 600 # 封禁多少秒,-1是永久封禁(不建议永久封禁)
action = %(action_)s[port="%(port)s", protocol="%(protocol)s", logpath="%(logpath)s", chain="%(chain)s"] # 不需要发邮件通知就这样设置
banaction = iptables-multiport # 禁用方式
logpath = /var/log/auth.log # SSH 登陆日志位置

直接复制版本:

[sshd]
ignoreip = 127.0.0.1/8
enabled = true
filter = sshd
port = 20253
maxretry = 5 
findtime = 300 
bantime = 600
action = %(action_)s[port="%(port)s", protocol="%(protocol)s", logpath="%(logpath)s", chain="%(chain)s"]
banaction = iptables-multiport
logpath = /var/log/auth.log

设置fail2ban开机自动启动:

sudo systemctl enable fail2ban

使用密钥登录 #

如果 VPS 厂商提供了 SSH 密钥绑定功能,可以忽略本节内容并按照 VPS 厂商提供的方法绑定。

在本地 powershell 中运行:

ssh-keygen -t ed25519

或者

ssh-keygen -t rsa -b 4096

二者加密算法不同:

  • -b 4096 指定生成的 RSA 密钥的长度为 4096 位

  • Ed25519 的密钥长度固定,约为 256 位,无需指定密钥长度。

直接使用默认的密钥路径即可。密码可以留空,也可以设置。

Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\<user>/.ssh/id_ed25519): # 直接回车
Enter passphrase (empty for no passphrase): # 可以留空,也可以设置
Enter same passphrase again: # 和上一个一样

然后我们在 VPS 上编辑 SSH 授权密钥文件,注意需要在root用户和非root用户下都需要添加:

vim ~/.ssh/authorized_keys

如果目标用户的家目录下还没有 .ssh 目录, 确保目录的权限是 700

mkdir -p ~/.ssh
chmod 700 ~/.ssh

创建authorized_keys文件并赋予相应权限

touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

之后打开 C:\\\Users<user\>/.ssh/id\_ed25519.pub,复制其内容并粘贴过去。


执行以下命令编辑 SSH 配置文件:

sudo vim /etc/ssh/sshd_config

进行如下设置:

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no

如果发现没有生效: 检查 /etc/ssh/sshd_config.d下的文件

之后重启 SSH 服务生效:

sudo systemctl restart ssh

启用 UFW 防火墙 #

如果 VPS 厂商提供了防火墙功能,且没有复杂的需求,可以忽略本节内容并使用 VPS 厂商提供的防火墙。

在正式启用 UFW 之前,我们需要先设置规则。我们首先来设置 UFW 的默认行为:

sudo ufw default allow outgoing # 默认允许所有数据出站
sudo ufw default deny incoming # 默认禁止所有数据入站

我们可以通过以下命令查看 UFW 当前生效的规则:

sudo ufw status
sudo ufw status numbered  # 加上数字编号

我们可以通过以下命令允许或拒绝某端口的传入 / 传出流量(部分以 22、80、443 端口为例):

# 允许22端口的proto协议的流量入站
sudo ufw allow in 22/proto

#允许22端口的proto协议的流量出站
sudo ufw allow out 22/proto

# 在未指定in/out的情况下,默认为in
sudo ufw allow 22/proto

# 在未指定proto的情况下,默认为tcp和udp
sudo ufw allow 22

# 拒绝的话就把allow改成deny
sudo ufw deny 22

# 允许从start_port到end_port的端口
sudo ufw allow start_port:end_port

# 允许复数个端口,以英文逗号分隔
sudo ufw allow port1,port2

# 允许来自于特定ip或cidr段的流量
sudo ufw allow from ip/cidr

# 允许来自于特定ip或cidr段端口22的流量
sudo ufw allow from ip/cidr to any port 22

# 允许来自于特定ip或cidr段端口22的tcp协议的流量
sudo ufw allow from ip/cidr to any proto tcp port 22

# 如果指定复数个端口,则必须指定协议
sudo ufw allow from ip to any proto tcp port 80,443

# comment用于注释
sudo ufw allow from ip to any proto tcp port 80,443 comment "hello"

我们可以通过以下命令删除生效的规则:

sudo ufw delete allow 22 # 在规则前面加个delete
sudo ufw delete 1 # 按照numbered的编号删除也行

在确定所有规则均成功设置后,通过以下命令启动 \ 关闭 \ 重启 UFW

启动防火墙前务必保证 22 端口(或者其他 SSH 端口)被放行。

sudo ufw enable|disable|reload

如果需要重置规则,请使用:

重置规则前务必保证 UFW 处于关闭状态。

sudo ufw reset

本人建议仅放行正在使用的端口,比如 22、80、443。

默认情况下,UFW 仅记录不符合规则的被拒绝的数据包。如果需要记录与该服务相关的每个详细信息,可以在 allow 后加上 log 以进行记录。

# 成功连接 ssh 的也记一下日志备查比较好 ufw allow log 22/tcp

更改时区 #

sudo timedatectl set-timezone Asia/Shanghai

保证软件更新 #

日常更新系统 #

个人建议定期登录 VPS 运行 sudo apt update && sudo apt upgrade 来保证 VPS 内所有软件包均为最新。

不过 Ubuntu 默认会每天自动安装系统的安全更新,所以说这个频率没必要太勤。