新服务器必做的基本设置——服务器迁移之记录

Category 碎碎念

最近各大服务器厂商都开始做年末的促销了,不满于先前服务器时断时续的网络质量,我也趁着优惠换了一家供应商租赁了服务器,着手将所有服务迁移到新服务器上来。新购置的服务器空空如也,各种设置不免繁琐,于是我把过程记录下来,在又遇上新服务器时就能方便查阅。

基本设置

网络连通性

我租赁的都是海外服务器,可以免去很多麻烦,也会带来很多麻烦。海外服务器最首要的麻烦就是网络问题,厂商提供的 IP 可能会被防火墙污染,一买来就无法连接。比较方便的方法是在网站 https://ping.pe/ 上输入服务器 IP 检查服务器在全球范围内的连通状态,如果在大陆地区一片飘红,那么就必须联系客服申请更换 IP 了。

我在 RackNerd 上更换过 IP,客服的回应很快,更换也是免费的。但至于其他 IP 余量比较紧张的厂商,可能就会收取少许的额外费用。

服务器参数

GitHub 上可以找到很多用于测试服务器参数的 bash 脚本,我比较常用的是 Bench.sh。使用 SSH 连接并登录 root 用户后,输入 wget -qO- bench.sh | bash,自动下载脚本并开始测试。给出的测试结果包括系统信息、I/O 读写速度、网络速度:

-------------------- A Bench.sh Script By Teddysun -------------------
 Version            : v2023-10-15
 Usage              : wget -qO- bench.sh | bash
----------------------------------------------------------------------
 CPU Model          : Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz
 CPU Cores          : 2 @ 2699.998 MHz
 CPU Cache          : 30720 KB
 AES-NI             : ✓ Enabled
 VM-x/AMD-V         : ✗ Disabled
 Total Disk         : 49.2 GB (1.9 GB Used)
 Total Mem          : 976.2 MB (96.0 MB Used)
 Total Swap         : 1023.0 MB (340.0 KB Used)
 System uptime      : 23 days, 4 hour 40 min
 Load average       : 0.03, 0.01, 0.00
 OS                 : Debian GNU/Linux 11
 Arch               : x86_64 (64 Bit)
 Kernel             : 5.10.0-8-amd64
 TCP CC             : 
 Virtualization     : Dedicated
 IPv4/IPv6          : ✓ Online / ✗ Offline
 Organization       : AS35916 MULTACOM CORPORATION
 Location           : Los Angeles / US
 Region             : California
----------------------------------------------------------------------
 I/O Speed(1st run) : 133 MB/s
 I/O Speed(2nd run) : 264 MB/s
 I/O Speed(3rd run) : 296 MB/s
 I/O Speed(average) : 231.0 MB/s
----------------------------------------------------------------------
 Node Name        Upload Speed      Download Speed      Latency
 Speedtest.net    917.95 Mbps       911.80 Mbps         0.48 ms
 Los Angeles, US  917.27 Mbps       906.25 Mbps         1.04 ms
 Dallas, US       919.58 Mbps       129.57 Mbps         31.06 ms
 Montreal, CA     792.01 Mbps       674.81 Mbps         72.70 ms
 Paris, FR        567.70 Mbps       655.98 Mbps         144.64 ms
 Amsterdam, NL    584.61 Mbps       271.38 Mbps         139.27 ms
 Shanghai, CN     387.34 Mbps       25.47 Mbps          187.49 ms
 Chongqing, CN    27.54 Mbps        0.65 Mbps           224.27 ms
 Hongkong, CN     528.81 Mbps       23.52 Mbps          145.39 ms
 Mumbai, IN       358.96 Mbps       430.29 Mbps         235.43 ms
 Singapore, SG    366.75 Mbps       638.25 Mbps         184.59 ms
 Tokyo, JP        375.91 Mbps       198.06 Mbps         118.29 ms
----------------------------------------------------------------------
 Finished in        : 6 min 31 sec
 Timestamp          : 2023-11-10 03:01:34 EST
----------------------------------------------------------------------

在测试结果中主要比对提供的服务器参数是否与购买时的配置清单匹配、网络状况是否满足要求,同时也可对服务器的具体工作状况加深印象。我的测试结果没有什么问题,相比旧服务器硬件有所升级,网络的连接比顺畅很多。新服务器来自于 CloudCone,这款 2 核 1 GB 的服务器售价是每年 $16.5,还是比较划算的。

由于我对 Debian 系统有着特殊的感情,不管 PC 设备还是服务器的首选 Linux OS 都是 Debian。后续涉及的安装软件等操作在不同 OS 上可能有所不同,读者自行留意,不再反复重提。

路由测试

购买海外服务器的用户一般会比较看重线路,即去回程的数据需要经过哪些路由的转发,例如拥有 CN2 GIA 线路的海外服务器在大陆访问也十分通畅,很受追捧。我购买的廉价服务器自然没有这样的线路,不过研究研究数据如何穿越海底光缆到达大洋彼岸也是很有意思的事。

网站 https://tools.ipip.net/traceroute.php 提供了各地区节点,可以查询各地去往服务器的数据线路。另一种方法是使用系统自带的测试工具,可以追踪由本机发出的数据。

后文的例子中,将 8.8.8.8 当作为服务器的 IP 地址,将 1.1.1.1 当作为本地 IP 地址,读者需要根据自己的实际情况修改。

在本地电脑上打开终端,使用 tracert 命令追踪住服务器需要经过的路由:

> tracert 8.8.8.8

通过最多 30 个跃点跟踪到 [8.8.8.8] 的路由

  1     3 ms     2 ms     1 ms  10.131.192.1
  2     3 ms     2 ms     3 ms  202.113.18.233
  3     1 ms     1 ms     1 ms  202.113.18.102
  4     3 ms     4 ms     2 ms  117.131.219.1
  5     6 ms     3 ms     3 ms  117.131.131.13
  6     *        *        *     请求超时。
  7     *        *        *     请求超时。
  8     7 ms     8 ms     7 ms  221.183.89.121
  9     *        *        *     请求超时。
 10     *        *        *     请求超时。
 11     *        *        *     请求超时。
 12     *        *        *     请求超时。
 13   193 ms   192 ms   192 ms  eth-0-19.10g.cr1.ny1.ip.coresite.com [206.223.143.40]
 14     *        *        *     请求超时。
 15   195 ms   195 ms   195 ms  8.8.8.8

跟踪完成。

查询一下 IP 的归属就能知道,去程数据先往北京,走寻常不过的 221.183.*.* 的 AS9808 路由再跨过大洋。

在服务器端可以查看回程线路,使用 mtr 命令向本地 IP 传递数据:

 Note 有的服务器厂商可能没有在 OS 里预装 mtr 工具,可以通过 apt-get install mtr-tiny 安装。

# mtr 1.1.1.1 -r
HOST: cc.server                   Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- undefined.hostname.localh  0.0%    10    9.1   5.3   0.7  15.1   6.1
  2.|-- multacom.com               0.0%    10    0.8   0.8   0.7   1.1   0.1
  3.|-- 182.54.129.88              0.0%    10    0.5   6.7   0.5  61.5  19.2
  4.|-- 218.30.54.189              0.0%    10    5.9   5.3   2.5   7.9   1.8
  5.|-- ???                       100.0    10    0.0   0.0   0.0   0.0   0.0
  6.|-- 202.97.58.121              0.0%    10  154.4 155.1 152.7 156.3   1.2
  7.|-- 202.97.48.209             90.0%    10  175.8 175.8 175.8 175.8   0.0
  8.|-- 202.97.108.126             0.0%    10  178.8 175.0 166.5 178.8   5.4
  9.|-- 219.150.49.154            20.0%    10  179.2 177.2 172.5 182.1   3.5
 10.|-- 221.238.222.118           10.0%    10  169.8 167.8 159.2 175.3   5.1
 11.|-- 218.69.12.90              10.0%    10  188.9 184.8 176.4 189.0   5.1
 12.|-- ???                       100.0    10    0.0   0.0   0.0   0.0   0.0

线路中的路由主要是 202.97.*.*,也就是传统的 163 骨干网。据说在网络较空闲时,该款服务器线路会动态切换为 CN2,我对此也不是很在意就是了。

 Warning 测试结果中的路由 IP 地址会暴露设备所处的地理位置,在社交平台上公开前务必三思。

创建新用户

在购买服务器后,除了服务器 IP 地址外,供应商还会提供 root 用户的密码,用户可以通过 SSH 连接服务器。但 root 用户的权限太高,误操作容易造成不可逆的结果。在 Linux 的使用中,不论是服务器还是本地 PC,通常都是新建普通用户供日常使用,在权限不足时通过 sudo 命令提权,完成操作后自动「尽早」地退出 root 模式。

首先是使用 adduser 用户名 新建用户,创建用户的过程中会提示设定并确认密码,按提示输入即可:

# adduser leo
Adding user `leo' ...
Adding new group `leo' (1000) ...
Adding new user `leo' (1000) with group `leo' ...
Creating home directory `/home/leo' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for leo
Enter the new value, or press ENTER for the default
        Full Name []: Leo
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] y

接着安装 sudo 命令,以后就用 sudo 命令管理 root 权限。安装完成后用 visudo 进入配置文件:

# apt-get install sudo
# visudo

在配置文件中找到以下片段:

# User privilege specification
root    ALL=(ALL:ALL) ALL
leo     ALL=(ALL:ALL) ALL

在 root 用户的下一行填上新建用户的用户名,同样填上 ALL=(ALL:ALL) ALL。根据窗口下方的快捷键提示,依次摁 CTRL + O 保存,摁 ENTER 确认,摁 CTRL + X 退出。

SSH 设置

几乎所有远端服务器都是通过 SSH 与用户相连接,当服务器暴露在公网上时,就有无数人尝试爆破 SSH 口令盗取控制权,所以 SSH 的安全是保护服务器的第一道关口。为了避免服务器变成肉鸡,最为基础且最为有效的方法就是修改 SSH 的默认配置。

更改 SSH 端口

SSH 的默认端口是 22,将其改为非常见端口就可以躲过大量定向的爆破。上文中新建的用户名为 leo,通过 ssh leo@8.8.8.8 换用新用户登录 SSH。

打开 SSH 的配置文件:

$ sudo vim /etc/ssh/sshd_config

将文件中 Port 一项改为自定义端口,并将 PermitRootLogin 一项改为 no,禁止直接使用 root 用户登录,修改后例如:

Port 2222
PermitRootLogin no

最后重启 SSH 服务加载配置:

$ sudo service sshd restart

此时可以测试是否可以通过 ssh -p 2222 leo@8.8.8.8 登录,若配置无误,以下两种方式都会失效:

ssh leo@8.8.8.8
ssh root@8.8.8.8

禁止密码登录

凡使用密码作为登录口令,终究有被爆破的可能,况且长密码也很难记忆。更为安全有效的方法是禁止使用密码登录 SSH,使用公私钥完成用户的验证。

在服务器上生成公私钥:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/leo/.ssh/id_rsa):    # 此处摁回车,存储在默认位置
Created directory '/home/leo/.ssh'.
Enter passphrase (empty for no passphrase):                     # 输入 passphrase,若不设置则直接摁回车
Enter same passphrase again:                                    # 重复 passphrase
Your identification has been saved in /home/leo/.ssh/id_rsa     # 私钥保存路径
Your public key has been saved in /home/leo/.ssh/id_rsa.pub     # 公钥保存路径

在生成过程中会提示用户输入 passphrase,若设置了该口令,在私钥验证通过后还需要通过该口令的验证。在私钥被他人盗取的情况下,对方不知道该口令也无法登录,安全性更高。

公钥相当于一把锁,存放在服务器上,私钥相当于一把钥匙,存放在本地。服务器上的授权文件则决定了使不使用该公钥完成验证,所以还要按下列步骤为新生成的公钥添加授权:

$ cd .ssh
$ cat id_rsa.pub >> authorized_keys
$ chmod 600 authorized_keys
$ chmod 700 ~/.ssh

打开 SSH 的配置文件:

$ sudo vim /etc/ssh/sshd_config

找到以下项目,编辑设置开启公钥验证:

PubkeyAuthentication yes

使用 cat /home/leo/.ssh/id_rsa 在终端中输出私钥内容,将其复制后写入到本地的记事本中,将文件保存为 id_rsa,存放在自定义的目录下。接着在本地打开终端,尝试使用私钥连接服务器:

ssh -p 端口号 -i "私钥路径" 用户名@主机名

 Note 相信许多读者使用的是 PuTTY 等更为便捷的 SSH 客户端,在设置项中一定也可以使用私钥的方式完成登录,各种客户端的设置方式不尽相同,就不在此罗列了。

成功登录后,SSH 的公私钥设置就没有问题了。再次打开 SSH 配置文件:

$ sudo vim /etc/ssh/sshd_config

将密码登录关闭,以后全部使用私钥登录:

PasswordAuthentication no

最后重启 SSH 服务,SSH 的设置内容就全部完成了:

$ sudo service sshd restart

安装 Fail2Ban

更改 SSH 的默认设置提升了防御等级,但只顾着防守而没有反制措施,暴露在外的防护手段在积年累月的攻击下,始终有被攻破的风险。Fail2Ban 是用于反制非法访问的有力工具,Fail2Ban 能够根据服务器的访问日志找出密码失败次数过多等具有风险的 IP 并自动封禁,是避免暴力攻击的有效手段。

Fail2Ban 亦可设置邮件通知等功能,读者如有兴趣可以自行搜索,在这里仅介绍基础的 SSH 安全设置。首先在服务器上安装 Fail2Ban:

$ sudo apt-get install fail2ban

Fail2Ban 的默认设置文件为 /etc/fail2ban/jail.conf,一般不改写该文件,而是在同目录下新建 jail.local,其中的设置项会添加入 jail.conf 并覆盖同名设置项。使用 Vim 新建 jail.local 文件:

$ sudo vim /etc/fail2ban/jail.local

在文件中写入针对 SSH 服务的封禁规则:

[sshd]
enable = ture
filter = sshd
port = 2222                     # SSH 服务对应的端口
logpath = /var/log/auth.log     # 日志路径
maxretry = 3                    # 最大允许试错次数
bantime = -1                    # IP 封禁时间(无限)

保存设置后通过 sudo systemctl start fail2ban 启动,Fail2Ban 就开始保护服务器了。以下罗列了在维护时经常需要用到的命令:

$ w                                             # 查看当前服务器登录的用户
$ last                                          # 查看过去一段时间的登录用户
$ sudo systemctl enable fail2ban.service        # 开机启动
$ sudo systemctl status fail2ban.service        # 查看服务运行状态
$ sudo cat /var/log/fail2ban.log                # 查看日志文件
$ sudo fail2ban-client status                   # 查看 fail2ban 的运行状态
$ sudo fail2ban-client status sshd              # 查看 sshd 的详细信息,包括封禁 IP 等
$ sudo fail2ban-client set sshd unbanip 1.1.1.1 # 解封指定 IP 1.1.1.1

或许有读者认为,有必要这么麻烦地折腾 SSH 安全吗?也没见有什么人来连接我的服务器。事实并非如此,当服务器以公网 IP 直接接入互联网后,每天都要面临大量连接请求,多亏了厂商默认设置的强密码,将很多隐患挡在了外头。

诸君如若不信,可以通过以下命令查询指定日期的失败访问:

$ lastb -s 2023-11-6 -t 2023-11-7​
administ ssh:notty    185.224.128.160  Mon Nov  6 04:53 - 04:53  (00:00)
esroot   ssh:notty    170.64.161.15    Mon Nov  6 04:53 - 04:53  (00:00)
administ ssh:notty    185.224.128.160  Mon Nov  6 04:53 - 04:53  (00:00)
admin    ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
esroot   ssh:notty    170.64.161.15    Mon Nov  6 04:52 - 04:52  (00:00)
admin    ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
root     ssh:notty    180.101.88.222   Mon Nov  6 04:52 - 04:52  (00:00)
root     ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
root     ssh:notty    180.101.88.222   Mon Nov  6 04:52 - 04:52  (00:00)
root     ssh:notty    180.101.88.222   Mon Nov  6 04:52 - 04:52  (00:00)
root     ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
odoo     ssh:notty    170.64.161.15    Mon Nov  6 04:52 - 04:52  (00:00)
odoo     ssh:notty    170.64.161.15    Mon Nov  6 04:52 - 04:52  (00:00)
Admin    ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
Admin    ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
root     ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
opc      ssh:notty    170.64.161.15    Mon Nov  6 04:52 - 04:52  (00:00)
Admin    ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
opc      ssh:notty    170.64.161.15    Mon Nov  6 04:52 - 04:52  (00:00)
Admin    ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
root     ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
user     ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)
user     ssh:notty    185.224.128.160  Mon Nov  6 04:52 - 04:52  (00:00)

我查询了还未修改 SSH 默认设置时的失败访问,这里仅截取了很小一部分结果。可以看见,全世界各地都有人在很频繁地尝试连接,爆破 rootAdmin 等常见用户的密码,由此也可见以上安全措施的重要性。

UFW 防火墙设置

UFW 可以用于很方便地管理服务器上的端口,关闭无用的端口也是保证服务器安全的基本措施。安装 UFW 后仅打开需要的服务端口:

$ sudo apt-get install ufw
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow https

千万别忘了我们已经修改了 SSH 的默认端口,再将自定义端口打开并尝看规则是否有误:

$ sudo ufw allow 2222
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
2222                       ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)
2222 (v6)                  ALLOW       Anywhere (v6)

用 systemd 打开 UFW 服务并设定自动启动,服务器上的端口就受 UFW 规则控制了:

$ sudo systemctl start ufw
$ sudo systemctl enable ufw

开启 BBR

BBR(Bottleneck Bandwidth and Round-trip propagation time)是 Google 提出的一种拥塞控制算法,能够保证在有丢包率的不良网络环境下的连接,这对于海外服务器是一项比较重要的功能。

有些服务器默认开启了 BBR,可以通过以下命令检查:

$ sudo sysctl net.ipv4.tcp_available_congestion_control | grep bbr
$ sudo sysctl net.ipv4.tcp_congestion_control | grep bbr

若没有输出,就需要通过以下方式手动开启:

$ sudo sh -c 'echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf'
$ sudo sh -c 'echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf'
$ sudo sysctl -p
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

至此,新购买服务器的配置就差不多完成了,大部分都是和网络安全相关的设置,虽显得繁琐却又不得不做。若服务器厂商另外提供备份和 DDoS 防御等功能也应选择开启,因为廉价服务器不会提供此类服务且各厂商的设置方法都不相同,这类功能就超出本文的范围了。不过将文中的基础功能配置下来,后续就已经可以在服务器上放心地部署服务了。


References