本文内容适用于 Debian / Ubuntu 系统;部分本地操作以 macOS 下的 Terminal 为例。

最近在 VPS 上搭好了自己的 Tiny Tiny RSS 服务和这个 Blog(有关这两部分的内容我稍后也会写)。而在此之前,我在 VPS 上重新安装了 Ubuntu 18.04 LTS,本文就记录下重装后的一些简单配置过程。

安全

SSH 安全

为了避免自己的 VPS 被 ssh 弱口令扫描,我们不妨使用 RSA 密钥对进行 ssh 登录,并关闭密码登录。

使用 RSA 密钥登录

1. 在本地生成密钥

在本机 Terminal 中执行:

ssh-keygen -b 2048 -t rsa

提示 Enter file in which to save the key (/Users/~/.ssh/id_rsa):
// 使用默认文件位置,直接回车即可

提示 Enter passphrase (empty for no passphrase):
// 设置密钥的密码(留空即为免密码登录)

提示 Enter same passphrase again:
// 再次输入密钥的密码

此时就已经在 ~/.ssh/ 下生成了 id_rsa (私钥) 和 id_rsa.pub (公钥) 两个文件。

2. 在服务器端添加密钥

使用 scp 命令将公钥上传到服务器:

scp ~/.ssh/id_rsa.pub [email protected]的域名或ip:/root/

// 输入 ssh 密码并回车确认

ssh 到服务器上,随后执行

mkdir ~/.ssh && chmod 700 ~/.ssh

mv id_rsa.pub ~/.ssh && cd .ssh

mv id_rsa.pub authorized_keys && chmod 600 authorized_keys

此时就可以使用 RSA 密钥登录 VPS 了。

关闭 ssh 的密码登录 & 防止 Broken pipe 错误

设置好 RSA 密钥登录后,我们就可以关闭 ssh 的密码登录了。同时,为了避免在使用 ssh 时空闲连接时间过长而导致 Write failed: Broken pipe 错误,我们可以在 ssh 配置文件中设置 ClientAliveInterval 参数,这会允许服务器在一定时间内发送一个特定的包给客户端,一旦超时,则说明断线,就关闭连接,避免了空闲连接时间过长报错。

编辑 ssh 配置文件:vim /etc/ssh/sshd_config

PasswordAuthentication yes 改为 PasswordAuthentication no,并去除行前的注释符号 #
ClientAliveInterval 一行改为 ClientAliveInterval 60,并去除行前的注释符号 #
保存退出,执行 /etc/init.d/ssh restart 重启 ssh 服务即可。

防火墙配置

安装 fail2ban

fail2ban 是 Linux 上一个著名的入侵保护的开源框架,它能通过 iptables 将尝试暴破 ssh 密码的 IP 封停,有效防止暴力破解攻击。

apt-get install fail2ban
安装并配置 ufw 防火墙

ufw,即 uncomplicated firewall(简单防火墙),是 Ubuntu 系统默认的防火墙组件,它可以简化对 iptables 的配置。

// Ubuntu 系统已经自带了 ufw 防火墙

// 此处允许了 80 / 443 / 22 三个端口的访问

// 会提示你可能影响 ssh 连接,务必确认已将你的 ssh 端口加入到 ufw rules 中,然后按 y 确认开启

使用 NTP 同步系统时间

许多服务都要求服务器时间与标准时间误差不能过大,因此我们使用 NTP 进行时间同步。

apt-get install ntp

优化

提高文件并发数

echo '* soft nofile 51200
* hard nofile 51200' >> /etc/security/limits.conf

然后,执行:

ulimit -n 51200

设置虚拟内存

某些 VPS 服务商会预先设置好虚拟内存,所以我们先查看系统当前可用内存:

free -m

输出样例:

$ free -m

              total        used        free      shared  buff/cache   available

Mem:            982         277         112           1         592         533

Swap:          1023           2        1021

如果输出中没有上面的 Swap 一行或 Swap 后为 0,则表示系统没有设置虚拟内存,可以参考下面的方法设置:

1. 创建 swapfile

 dd if=/dev/zero of=/root/swapfile bs=1M count=1024

// if 表示 input_file (输入文件),of 表示 output_file (输出文件),bs 表示 block_size (块大小),count 表示计数。

示例中采用的数据块大小为 1M,数据块计数为 1024,所以分配的空间就是 1G 大小。

2. 格式化 swapfile

mkswap /root/swapfile

3. 启用 swapfile

swapon /root/swapfile

4. 设置开机自动加载虚拟内存

echo "/root/swapfile swap swap defaults 0 0" >> /etc/fstab

此时再执行 free -m 即可看到虚拟内存已经启用了。

升级内核 & 开启 BBR 拥塞控制算法

BBR 是 Google 出品的 TCP 拥塞控制算法,其目的是尽量跑满带宽,且尽量不要有排队的情况,可以起到单边加速 TCP 连接的效果。BBR 是内嵌在 Linux 内核中的,而 Linux Kernel 4.9 已加入了该算法,所以我们需要先升级 Linux 内核。

1. 开始前先进行更新

apt-get update && apt-get upgrade -y

2. 建立一个存放内核文件的临时文件夹

mkdir image-temp && cd image-temp

3. 下载最新内核,地址
// 此处以 Ubuntu 系统和 v5.0.10 的内核版本为例

wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.0.10/linux-headers-5.0.10-050010_5.0.10-050010.201904270832_all.deb

wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.0.10/linux-headers-5.0.10-050010-generic_5.0.10-050010.201904270832_amd64.deb

wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.0.10/linux-image-unsigned-5.0.10-050010-generic_5.0.10-050010.201904270832_amd64.deb

wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.0.10/linux-modules-5.0.10-050010-generic_5.0.10-050010.201904270832_amd64.deb

4. 安装内核

dpkg -i *.deb

5. 删除下载的内核文件

cd .. && rm -rf image-temp

6. 删除旧内核(可选)

卸载旧版 linux-image:
获取 linux-image 列表:

dpkg -l | grep linux-image

卸载旧版 linux image:

apt-get purge 旧linux-image名

// 卸载过程中会询问是否中止卸载,选择 No

卸载旧版 linux-headers:
获取 linux-headers 列表:

dpkg -l | grep linux-headers

卸载旧版 linux image:

apt-get purge 旧linux-headers名

卸载旧版 linux-modules:
获取 linux-image 列表:

dpkg -l | grep linux-modules

卸载旧版 linux image:

apt-get purge 旧linux-modules名

7. 更新系统引导并重启

update-grub && reboot

8. 开启 BBR

为了避免升级内核重复添加 bbr 开启代码,使用如下命令先删除之:

sed -i '/net\.core\.default_qdisc=fq/d' /etc/sysctl.conf

sed -i '/net\.ipv4\.tcp_congestion_control=bbr/d' /etc/sysctl.conf

随后开启 bbr:

echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf

echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf

然后,执行 sysctl -p 保存生效。

9. 查看 BBR 是否成功开启

执行 sysctl net.ipv4.tcp_available_congestion_control, 结果中应有 bbr。
执行 lsmod | grep bbr,结果中应有 tcp_bbr。

输出样例:

安装 Docker-CE(可选)

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。iOS 上的 HyperApp 也正是借助 Docker 实现了自动部署应用。

安装 Docker 最方便的方式是使用官方脚本:

curl -fsSL https://get.docker.com -o get-docker.sh

sudo sh get-docker.sh

限制 Docker 容器日志大小

Docker 容器运行过程中会产生大量日志文件,如果不加限制可能会导致 VPS 磁盘空间不足。以下是限制容器日志大小的方法:

编辑 /etc/docker/daemon.json 文件:vim /etc/docker/daemon.json

添加 log-dirverlog-opts 参数:

{
	"log-driver":"json-file",
	"log-opts":{ "max-size" :"50m","max-file":"3"}
}

// 样例中一个容器的日志大小上限是 50 M,最多创建 3 个日志文件

保存退出,随后加载配置文件并重启 Docker:

systemctl daemon-reload

systemctl restart docker

// 设置的日志大小,只对新建的容器有效

手动清理 Docker 容器日志

docker ps | awk '{if (NR>1){print $1}}' | xargs docker inspect --format='{{.LogPath}}' | xargs truncate -s 0