1231 words
6 minutes
私人服务器简易防护指南

申请下公网 ip 后,通过路由器的 DMS 将局域网内的服务器暴露到外网,再通过 DDNS 来解决动态公网 ip 的问题,自己的服务器就可以被访问了,但是被暴露出去的服务器无时不刻都会被攻击,必须采取必要的安全措施才可以。以下就是搭建好服务器后个人觉得应该做的安全措施。


SSH 登陆#

自从 ssh 暴露到外网后,通过观察日志发现无时不刻在被爆破,所以密码强度高点还是很有必要的,但是这还远远不够,还应该做以下配置。

  1. 配置 sshd_config 文件

    找见 sshd 的配置文件,并添加以下内容。

    /etc/ssh/sshd_config
    PermitRootLogin no # 禁止root用户远程登录
    PasswordAuthentication no # 禁止使用密码登录
    PermitEmptyPasswords no # 不允许使用空密码登录
    IgnoreUserKnownHosts yes # 不信任'~/.ssh/known_hosts'中的主机
    IgnoreRhosts yes # 不信任'~/.rhosts'中的主机

    使用sudo systemctl restart sshd重启 sshd 即可。

    需要注意的是,必须要把你电脑的公钥保存到服务器的~/.ssh/authorized_keys文件中,不然远程无法登陆了。

    还可以针对不同的用户配置不同的内容:

    /etc/ssh/ssh_config.d/username.conf
    Match User username
    PasswordAuthentication no
    AllowTcpForwarding no
    # 可以在这里添加其他配置
  2. 设置最大尝试限制

    使用fail2ban来达到设置最大尝试限制。fail2ban的工作原理是通过检索日志文件,将多次尝试登陆失败的 ip 地址设置为黑名单,使用的是iptabls,用ufw这种命令是看不到fail2ban的设置的,如果想查看fail2ban的行为,可以使用iptables或者fail2ban-client命令。

    Terminal window
    # 下载fail2ban
    sudo apt install fail2ban

    编写配置文件 jail.conf,但是在阅读 jail.conf 手册时,里面包括了这么一句话:

    .conf files are distributed by Fail2Ban. It is recommended that .conf files should remain unchanged to ease upgrades. If needed, customizations should be provided in *.local files.

    所以按照规范,如果我们想要更改fail2ban的配置应该自己书写一个 jail.local 的文件。在这里我们使用默认的配置,在默认配置基础上增加一点其他配置。

    /etc/fail2ban/jail.d/sshd.conf
    [sshd]
    enabled = true
    ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16
    bantime = 1d
    findtime = 10m
    maxretry = 5

    启动服务并设置为开机自启动。

    如果使用的Debian系统,需要先下载rsyslog,不然会找不到/var/log/auth.log这个文件

    Terminal window
    sudo systemctl enable --now fail2ban

用户权限设置#

在部署服务时,可以使用 docker 来部署,如果向我一样就是喜欢本地部署,不用 docker,那么就应该尽量的使用权限低的用户来启动服务,如果系统被攻破,那么攻击者也拿不到高权限来破坏系统。

目前为止,操作系统和网络安全的学习还不够深入,并不知道黑客攻击进来是什么样的形式,是通过什么方式攻击进来的(我觉得应该有比密码爆破和注入漏洞更高明的方式),也不知道操作系统中的一些底层逻辑(什么情况下该使用什么用户干什么样的事情),所以目前为止我觉得跑服务应该尽可能的跑在权限低的用户上,并且使用用户级别的服务控制命令来跑(systemctl --user),至于有没有必要或者权限问题,等深入学习完以后再回过头来重新思考。

在使用systemctl --user的时候,我遇到了一个问题,如下:

Terminal window
coder@workstation:~$ systemctl --user
Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)

问题发生的起因:

我在部署code-server服务时,使用的管理员用户,在阅读code-server文档时,文档中说:

Never expose code-server directly to the internet without some form of authentication and encryption, otherwise someone can take over your machine via the terminal.

看到才回想起来 vscode 可以Create New Terminal,这问题看来值得考虑。官网文档提供了多种方式来解决这个问题:

There are several approaches to operating and exposing code-server securely: Port forwarding via SSH Using Let’s Encrypt with Caddy Using Let’s Encrypt with NGINX Using a self-signed certificate

所以决定还是使用方便点,安全性没那么安全的 tls 吧。配置好后发现还是怕被密码爆破获取我的管理员权限,后来就决定换个普通用户去运行code-server,于是就发现了 coder 用户。coder 用户应该是code-server创建的,但是个好名字,反正我拿来用了,所以.profile和.bashrc都是 cp 其他用户的配置文件再修修改改使用的。于是就少了一些环境变量,无法运行systemctl --user。

解决:

解决的办法就是添加一个环境变量XDG_RUNTIME_DIR=/run/user/$(id -u)。/run/user/下的文件夹拥有每个用户各自的运行时数据,至于为啥我的 coder 用户没有,至今还不知。

私人服务器简易防护指南
https://blog.emilejones.top/posts/infrastructure/私人服务器简易防护/
Author
EmileJones
Published at
2025-08-02
License
CC BY-NC-SA 4.0
评论