操作系统篇
选择操作系统
服务器端 主流操作系统有三个系列,分别是
- Windows Server
- Unix
- Linux
而大多数服务器的操作都是Linux,而主流的 Linux 发行版可以根据其源头或基础分为几个主要系列。每个系列都有其独特的特点和适用场景。以下是一些主要的 Linux 发行版系列:
Debian 系列
- Debian: 一个稳定、社区驱动的发行版,以其稳定性和丰富的软件包著称。
- Ubuntu: 基于 Debian,具有更频繁的更新和更友好的用户界面,适合桌面和服务器使用。
- Linux Mint: 基于 Ubuntu,提供更简化和用户友好的桌面体验。
Red Hat 系列
- Red Hat Enterprise Linux (RHEL): 商业发行版,提供企业级支持和稳定性。
- CentOS: RHEL 的社区版本,提供与 RHEL 类似的功能和稳定性。 在2020年12月,CentOS项目宣布了一个重大变更,CentOS逐渐停止维护和更新。未来,CentOS项目的投入重点将由CentOS Linux转向CentOS Stream,CentOS Stream成为RHEL的上游版本。
- Fedora: 由 Red Hat 支持的社区发行版,专注于最新技术和创新。
- Rocky Linux是由CentOS项目的联合创始人Gregory Kurtzer发起的,作为CentOS传统版本的替代方案。Rocky Linux的目标是提供一个与RHEL完全兼容的社区驱动发行版,继续CentOS之前的使命,即作为RHEL的下游版本。
- AlmaLinux是由CloudLinux公司发起的另一个CentOS替代方案,旨在填补CentOS转向CentOS Stream后留下的空白。AlmaLinux提供与RHEL完全兼容的环境,并承诺提供稳定的长期支持。
SUSE 系列
- SUSE Linux Enterprise: 商业发行版,提供企业级支持和稳定性。
- openSUSE: 社区驱动的发行版,提供稳定和滚动更新版本(openSUSE Leap 和 openSUSE Tumbleweed)。
Arch Linux 系列
- Arch Linux: 以其简单和高度可定制性著称,采用滚动更新模式。
- Manjaro: 基于 Arch Linux,提供更友好的安装和使用体验。
其他系列
- Gentoo: 源代码发行版,允许用户根据需求编译优化软件。
- Slackware: 一个历史悠久的发行版,以其简单和稳定性著称。
- Alpine Linux: 轻量级发行版,专注于安全性和资源效率。
这些系列中的发行版各有其优点和适用场景,用户可以根据个人需求和偏好选择合适的发行版。
最终选择
对于服务器,首先需要考虑的是安全和稳定,所以更建议使用更新频率低,社区支持久的,稳定的发行版本。
Debian
系列推荐Debian
作为服务器系统。
Red Hat
系列,由于CentOS
不再位于RHEL
下游,所以不再推荐。作为CentOS
的替代品,更推荐 Rocky Linux
或者 AlmaLinux
。
本文使用Debian 12
作为服务器首选系统,后续所有软件如无特殊说明,皆默认安装在Debian系统中。
准备工作
一台安装了Debian 12
的服务器,首先使用root用户登录
修改root用户密码
使用一下命令修改root密码
passwd
会提示输入两次新密码,建议设置为16 位的随机大小写字母 + 数字的密码
安装常用工具
apt update && apt upgrade -y
apt install vim curl sudo -y
创建非 root 账户
使用以下命令创建一个具有提权能力的账户:
比如用户名为username
useradd -m -G sudo -s /bin/bash username
然后我们给这个用户设置一个至少为 16 位的随机大小写字母 + 数字的密码(个人建议的最低安全性需求):
passwd username
SSH安全措施
配置免密登录
在本地(自己电脑上)运行如下,生成一对公钥/密钥(yuè)
ssh-keygen -t rsa -b 4096
保存密钥: 当系统提示你输入文件名时,按回车键使用默认路径(通常是 ~/.ssh/id_rsa
)。如果你希望使用其他名称或路径,可以自行指定。
-t rsa
指定使用RSA算法。
-b 4096
指定密钥长度为4096位。
设置密码(可选): 系统会询问是否为密钥设置密码。你可以选择设置一个密码,也可以直接按回车键跳过。
将公钥复制到远程主机:
使用ssh-copy-id
命令: 这个命令可以自动将公钥复制到远程主机的~/.ssh/authorized_keys
文件中:
ssh-copy-id username@remote_host
username
是你在远程主机上的用户名。
remote_host
是远程主机的IP地址或域名。
你需要输入远程主机用户的密码来完成公钥的复制。
配置完成后,可以尝试新开一个terminal窗口进行ssh登录,检查是否需要输入密码,如果不再需要密码,可继续进行下一步操作。
同样的,可以分别对root用户和非root用户进行配置免密登录。
禁用root账户密码登录:
root
账户的用户名固定为root
,如果允许其通过密码登录,攻击者只需进行密码穷举即可尝试攻破系统。之前我们已经创建了非 root
账户,在这里我们只需要禁用非 root
账户的 SSH 登录即可。
修改 ssh端口号
ssh端口号默认为22,固定端口号并不安全,建议改为高位端口号,建议修改为10000-65535
之间的任意一个端口。
禁用密码登录
已经配置好了免密码登录,就可以禁用密码登录了。
上述三个修改,配置文件的都位于 /etc/ssh/sshd_config
但我不建议直接修改此文件,而是创建一个新的自定义文件custom.conf
,防止 OpenSSH 更新后配置冲突。自定义文件中的配置项会覆盖默认配置
编辑自定义文件
sudo vim /etc/ssh/sshd_config.d/custom.conf
把以下内容写入custom.conf
Port 54928
Port 22
PermitRootLogin prohibit-password
passwordauthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
之后重启 SSH 服务生效:
sudo systemctl restart ssh
然后尝试通过54928端口进行ssh登录,如果可以正常登录,可以把Port22这行配置删除,然后再次重启 SSH 服务。
sshd 配置修改完,先用 sudo sshd -T 看一下有效配置:
Root 用户登录方式
sudo sshd -T | grep -i "PermitRootLogin"
密码认证
sudo sshd -T | grep -i "PasswordAuthentication"
ssh 端口
sudo sshd -T | grep -i "Port"
配置UFW防火墙
在正式启用 UFW 之前,我们需要先设置规则。我们首先来设置 UFW 的默认行为:
sudo ufw default allow outgoing # 默认允许所有数据出站
sudo ufw default deny incoming # 默认禁止所有数据入站
我们可以通过以下命令查看 UFW 当前生效的规则:
sudo ufw status
sudo ufw status numbered # 加上数字编号
可以通过以下命令允许或拒绝某端口的传入 / 传出流量(部分以 22、80、443 端口为例): 其中 proto可为 tcp或者udp
# 允许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
启动防火墙前务必保证SSH端口被放行
sudo ufw enable|disable|reload
配置CF网段到防火墙白名单
RULES=$(sudo ufw status numbered | grep 'Cloudflare IP' | awk -F"[][]" '{print $2}' | sort -nr)
for RULE in $RULES; do
echo "Deleting rule $RULE"
echo "y" | sudo ufw delete $RULE
done
for cfip in `curl -sw '\n' https://www.cloudflare.com/ips-v{4,6}`; do ufw allow proto tcp from $cfip to any port 443 comment 'Cloudflare IP'; done
ufw reload > /dev/null
添加完了之后使用以下命令查看防火墙现有规则列表:
sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 54928/tcp ALLOW IN Anywhere # SSH Port
[ 2] 443/tcp ALLOW IN 173.245.48.0/20 # Cloudflare IP
[ 3] 443/tcp ALLOW IN 103.21.244.0/22 # Cloudflare IP
[ 4] 443/tcp ALLOW IN 103.22.200.0/22 # Cloudflare IP
[ 5] 443/tcp ALLOW IN 103.31.4.0/22 # Cloudflare IP
[ 6] 443/tcp ALLOW IN 141.101.64.0/18 # Cloudflare IP
[ 7] 443/tcp ALLOW IN 108.162.192.0/18 # Cloudflare IP
[ 8] 443/tcp ALLOW IN 190.93.240.0/20 # Cloudflare IP
[ 9] 443/tcp ALLOW IN 188.114.96.0/20 # Cloudflare IP
[10] 443/tcp ALLOW IN 197.234.240.0/22 # Cloudflare IP
[11] 443/tcp ALLOW IN 198.41.128.0/17 # Cloudflare IP
[12] 443/tcp ALLOW IN 162.158.0.0/15 # Cloudflare IP
[13] 443/tcp ALLOW IN 104.16.0.0/13 # Cloudflare IP
[14] 443/tcp ALLOW IN 104.24.0.0/14 # Cloudflare IP
[15] 443/tcp ALLOW IN 172.64.0.0/13 # Cloudflare IP
[16] 443/tcp ALLOW IN 131.0.72.0/22 # Cloudflare IP
[17] Anywhere ALLOW IN 172.20.0.0/24 # Docker内网
[18] 443/udp ALLOW IN Anywhere
[19] 54928/tcp (v6) ALLOW IN Anywhere (v6) # SSH Port
[20] 443/tcp ALLOW IN 2400:cb00::/32 # Cloudflare IP
[21] 443/tcp ALLOW IN 2606:4700::/32 # Cloudflare IP
[22] 443/tcp ALLOW IN 2803:f800::/32 # Cloudflare IP
[23] 443/tcp ALLOW IN 2405:b500::/32 # Cloudflare IP
[24] 443/tcp ALLOW IN 2405:8100::/32 # Cloudflare IP
[25] 443/tcp ALLOW IN 2a06:98c0::/29 # Cloudflare IP
[26] 443/tcp ALLOW IN 2c0f:f248::/32 # Cloudflare IP
[27] 443/udp (v6) ALLOW IN Anywhere (v6)