为什么要做安全防护
Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的网站、APP、服务、甚至线下基础设施都建立在 Linux 的基石之上,这背后牵涉到巨大的经济利益和商业价值,当然也就意味着黑灰产有巨大的攻击动力。但是这些服务是如此重要、根本不允许出现重大的安全漏洞。于是无数的运维专业人员都在安全攻防的战场上拼搏努力,这才让大家能享受到基本稳定的现代化数字生活。
- 对于前者,我的建议是:安全无小事,尽量多查一些安全方面的信息,免得自己真的受了损失才后悔莫及;
- 对于后者,我的建议是:不用紧张,我们的服务器仍不具有太高的价值、一般不会吸引到高水平的攻击,需要面对的基本都是一些自动化脚本的恶意扫描和登录尝试,跟着本文做一些基础的防护即可。
具体的风险到底是什么
正如我们所知,任何人只需要知道【IP 地址】+【端口】+【用户名】+【密码】这四个要素,就能登录你的 VPS 服务器。那很显然,这四要素的安全就是我们要防护的底线。我们来逐一分析:
- 【IP 地址】:恶意脚本会随机尝试和扫描 IP 段,可以简单认为是公开信息、无法隐藏
- 【端口】:如果使用默认端口,那么【端口 = 22】
- 【用户名】:如果使用默认用户,那么【用户名 = root】
【密码】:密码不存在默认值,一定是由 VPS 后台随机生成或由你自行设置的。也就是说,如果你的服务器都是默认设置,则四要素中的三个已经是已知的,那么你整个服务器的安全,就全部寄托在一串小小的密码上了。这时有几种情况:
- 如果你用了 VPS 管理后台随机生成密码,它一般包含随机的十几个大小写混杂的字母和符号,相对比较安全
- 如果你为了好记、把密码改成了类似123456这种超弱的密码,破解你的 VPS 服务器可谓不费吹灰之力
- 如果你为了好记、把密码改成了比较复杂、但在别的地方用过的密码,其实也并不安全。你要明白黑客手里有作弊器,比如说密码表,包含数万、数十万、数百万甚至更多曾经泄漏的真实密码)
- 但你要明白,没有哪个黑客真的要坐在电脑前一次一次的尝试你的密码,全部的攻击尝试都是恶意脚本自动进行的,它会 24 小时不眠不休的工作。也许每天你酣睡之时,你的服务器都在经受着一轮又一轮的冲击。
一旦密码被成功撞破,意味着你的四要素全部被攻击者掌握,恶意脚本就会快速登录服务器、获取服务器的最高 root 控制权、安装部署它的恶意服务,然后就可以用你的服务器来 24 小时做各种坏事(比如挖矿、传播病毒、发送垃圾邮件、欺诈邮件、做 BT 中继、甚至暗网公众节点等等等等)。如果恶意脚本比较克制,其实可以做到相当的隐蔽性。而新人一般也不会去观察留意 VPS 的登录记录、进程变化、CPU 占用变化、流量变化等指标,你其实就很难发现自己被黑了。直到你的 VPS 服务商封禁你的账号、或者收到律师函为止。
- 别忘了,你获得 VPS 时大概率需要使用真实的支付信息,你登录各种网站、社交平台时也会留下你的 IP 地址,这些都与你的身份有直接或者间接的关系。于是,一旦这些坏事发生,它们就会不可避免地与你产生关联。
所以,一起来跟着下面的教程,来给我们的小鸡做一些基础的安全防护吧。
开始安全防护工作
本文以Ubuntu20.04为例子,Debian的操作也是类似的,CentOS系统会不太一样,请自行搜索相关内容。(强烈安利大家使用Ubuntu或者Debian系统)
任何涉及到安装的操作之前,先更新一下我们安装包的索引,可以的话,顺便更新一下软件。这本身也是安全的一部分,新的软件意味着更少的漏洞。
sudo apt update && apt upgrade
保持即可,直接回车。
更新完毕,我们进入正题。
本次教程讲分为SSH篇、宝塔篇和全局篇来讲解,后续如果有补充也会更新至相应位置。
SSH篇
1、更改SSH端口
第一步,我们先来解决【端口 = 22
】的问题。(注意:有些 VPS 服务商,默认的端口已经是非 22 端口,那么你可以忽略这一步,当然也可以跟着本文改成别的端口)
- 我们要做的第一件事,当然就是【用
nano
这个文本编辑器打开SSH远程登录程序设置
】,在 windows 下,你会【找到文件并双击】,在 Linux 下该怎么办呢?仔细看看上面的命令说明,是不是就很简单了?没错,就是:
nano /etc/ssh/sshd_config
- 文件打开后,你就进入了
nano
的界面,稍微观察一下,你会发现,它把重要的快捷键都显示在屏幕下方了(下图红框内),直接开卷考试、不用死记硬背,是不是很贴心呢?
- 我们要做的第二件事,是【在打开的文件中找到
Port
这一项,并修改它的端口】。Port 后面的数字就是 SSH 的端口,一般建议把它改成一个大于1024
小于65535
的整数(本文以7777
为例)。结合nano
的快捷键,想一下该怎么操作呢?- 使用
ctrl+w
进入搜索模式,然后输入Port 22
并回车 删除22
并改成
说明:如果这一行开头有个7777 #
,证明这一行【不生效】(被注释掉了),你可像我一样在文件最后写一个不带#
的,或者把#
删掉就好。
- 本文以
7777
为例,就意味着随着本文的发布,这个端口会变成一个不大不小的特征,也许会被攻击者优先尝试,所以强烈建议你用一个自己想到的其他端口,毕竟,你有 6 万多个端口可以自由选择。 - 使用
我们要做的第三件事,是【保存文件并退出】
- 如果第 3 步你有仔细观察,就会发现保存并不是常见的
ctrl+s
。 - 正确的快捷键:保存是
ctrl+o
+回车
,退出是ctrl+x
- 如果第 3 步你有仔细观察,就会发现保存并不是常见的
- 我们最后要做的事,是【重启 ssh 服务,使变更生效】
sudo service sshd restart
注意:为了保证你不会失联,请不要关闭当前的 ssh 登录窗口!而是另外开一个窗口来测试!
注意:为了保证你不会失联,请不要关闭当前的 ssh 登录窗口!而是另外开一个窗口来测试!
注意:为了保证你不会失联,请不要关闭当前的 ssh 登录窗口!而是另外开一个窗口来测试!
修改登陆配置
现在新的端口已经生效,下次登录时就要用7777
了。
登陆变成了:
ssh root@你的服务器IP -p 7777
如果是用其他客户端,记得修改端口。
2、使用复杂的密码
如果你想给当前的用户设置重新设置一个密码,那么可以到这个网站,生成一个复杂的密码,当作你服务器的密码。
https://1password.com/zh-cn/password-generator/
passwd
出现提示让你修改密码。然后粘贴进去就行了。(注意为了安全的考量,Linux下输入密码是没有显示的)
3、新建普通用户
接下来,我们来解决【用户名 = root
】的问题。
首先你要理解, Linux 系统中的root
,不仅仅是一个管理员账号那么简单。它是整个系统的【根基】、是系统的主宰、至高无上的神。一旦root
账号出现安全问题,整个系统都只能任人鱼肉、无处可逃。那么就跟随我进行操作吧:
- 我们要做的第一件事,是【新增一个用户并设定登录密码】,名字你可以随便起,我这里以
seven
为例:
adduser seven
执行命令后,根据提示操作即可。请务必设置一个用户密码(别忘记设置密码时看不到******的)。之后系统会询问你一些用户的附加信息,这些就可以无视,一路回车即可。
我们要做的第二件事,是【安装
sudo
功能】(sudo
就是在关键时刻,让普通账户临时获得root
的神力,战力全开拯救世界)
apt update && apt install sudo #Debain默认没有,Ubuntu自身应该是已经有安装的
- 我们要做的第三件事,是【把
seven
用户加入sudo
名单里,让他有资格借用root
的神力】
visudo
在 User Privilege Specification
下加入一行 seven ALL=(ALL) NOPASSWD: ALL
即可。
我要特别说明的是NOPASSWD
这个设置,它的意思是seven
用户临时使用root
权限时,不用额外输入密码。这与一般的安全建议相反。我之所以如此推荐,是因为很多新人不顾危险坚持使用root
账号就是因为用root
时不用重复输入密码、觉得轻松。“两害相权取其轻”,我认为【直接用root
用户的风险】大于【使用sudo
时不用输密码的风险】,所以做了以上的建议。
如果你希望遵守传统习惯、每次使用sudo
时需要输入密码,那么这一行改成seven ALL=(ALL:ALL) ALL
即可。
4、禁止root登陆
- 现在你已经逐渐熟悉 Linux 了,所以这次换你思考,我们要做的第一件事是什么呢?没错,还是【用
nano
编辑器打开SSH远程登录程序设置
】,什么,你想不起来怎么操作了?那去复习一下上面的内容再回来吧!………… 正确答案:
nano /etc/ssh/sshd_config
- 找到
PermitRootLogin Yes
这一项,然后把它后面的设定值改为no
即可。还记得怎么操作吗?………… 正确答案:- 使用
ctrl+w
进入搜索模式,然后输入PermitRootLogin
并回车
- 删除
yes
并改成no
- 使用
保存文件并退出。还记得怎么操作吗?………… 正确答案:
- 保存是
ctrl+o
,然后回车
确认 - 退出是
ctrl+x
- 保存是
- 重启 ssh 服务,让变更生效。还记得………… 算了直接公布正确答案:
sudo service sshd restart
注意:为了保证你不会失联,请不要关闭当前的 ssh 登录窗口!而是另外开一个窗口来测试!
注意:为了保证你不会失联,请不要关闭当前的 ssh 登录窗口!而是另外开一个窗口来测试!
注意:为了保证你不会失联,请不要关闭当前的 ssh 登录窗口!而是另外开一个窗口来测试!
- 下次通过远程登录,
root
用户已无法连接,
用户名就要换成 seven
了!如果你用的是类似 PuTTY、FinalShell 的软件,为方便起见,我们可以把 seven
设置成默认登录用户名。(别忘了保存 Session)
ssh seven@你的服务器IP -p 7777
图
接下来先跳到全局篇,一会儿再回来。
5、启用 RSA 密钥验证登录并禁止密码登陆(大招)
接下来,我们来解决【密码】可能被撞破的问题。
前面我说过,黑客并不是很蠢的用穷举法破解你的密码,而是会用一些比如“密码表”的作弊手段。除非你用的是随机生成的超长密码(比如借助 1Password,或者 macOS 的 keychain 等密码管理工具),否则很容易中招。
超长随机密码虽然安全性有所提高,但是基本上无法记忆,手动输入也十分麻烦易错。为了解决这个困境,我们可以直接弃用【密码验证】方式,改用更安全的【密钥验证】。
所谓的【密钥验证】,就是生成【一对】相关联的密钥文件(公钥和私钥),然后把【公钥】上传到 VPS 备用。每次登录时,SSH 会将【公钥】和【私钥】进行匹配,若验证是正确的【密钥对】,则验证通过。(换言之,你无需记忆和输入复杂的密码,只要保护好【私钥】这个文件不外泄即可)
本文以
RSA
密钥举例,是因为RSA
密钥在各种设备、各种SSH
客户端中有广泛悠久的支持历史,且目前依然能提供够用的安全性。但它绝非唯一选择。其他的常见密钥还有:
DSA
– 已经从数学层面被证明不安全,所以永远不要用它ECDSA
– 密钥小安全性高,但其算法被指留有 NSA 的后门,如果你的 VPS 上有值得 NSA 关注的东西就不要用它Ed25519
– 这是一个与ECDSA
十分类似的算法,故具有相似的性能优势。同时其文档全部公开,所以普遍认为无后门所以,如果你的设备和软件都支持的话,我建议优先选择
Ed25519
密钥。
那我们现在就来配置【密钥验证】吧!
我们服务器上先创建目录下,创建一个.ssh
的文件夹
检查一下服务器上的.ssh
目录,已经有了。
我找一台没有服务器配置密钥对的VPS,发现没办法连接了
全世界只有这把钥匙能打开我服务器的锁
如果想要在其他电脑上连接你的vps,就必须要带好你的密钥文件(妥善保管好,丢失了就进不去系统了)
到这里为止,配合上全局篇的内容你的 VPS 已经完成了基本安全保障,虽然称不上固若金汤,但一般的恶意脚本应该已经无法对你造成伤害了!
宝塔篇
1、更改宝塔8888端口
默认宝塔采用8888
端口(新版本宝塔已经随机端口了),强烈建议修改!
bt
2、尽量用反向代理
一般反向代理配置:
location / {
proxy_pass http://127.0.0.1:8080/; #改成你服务的端口号
rewrite ^/(.*)$ /$1 break;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade-Insecure-Requests 1;
proxy_set_header X-Forwarded-Proto https;
}
这样的话,就不需要开发相应的端口给外部访问了,一定程度可以保证安全性。
全局篇
1、安装UFW防火墙
Ubuntu默认自己已经是自带ufw防火墙了,只是没有启动而已(如果是Debian的话,需要安装)
- 设置ufw使用默认值
sudo ufw default deny incoming
sudo ufw default allow outgoing
- 允许SSH连接
如果没有改端口:
sudo ufw allow ssh
现在我们改了端口:
sudo ufw allow 7777/tcp comment 'SSH'
- 允许http连接
sudo ufw allow http
- 允许https连接
sudo ufw allow https
- 启动ufw防火墙
sudo ufw enable
- 查看ufw防火墙状态
sudo ufw status
sudo ufw status numbered
- 删除一条规则
sudo ufw delete 5
- 重载配置
sudo ufw reload
2、禁止Ping
- 宝塔用户
如果是宝塔用户,可以在这边禁止Ping
- 未安装宝塔的用户
sudo nano /etc/ufw/before.rules
搜索:echo-request
,把ACCEPT
改成DROP
3、禁止暴力破解
安装Fail2ban
sudo apt update && sudo apt install fail2ban
cd /etc/fail2ban # 进入fail2ban目录
sudo cp fail2ban.conf fail2ban.local # 复制一份配置文件
默认的是没有配置的,我们加入一个配置
[sshd]
enable = ture
port = 9753 # 注意改成自己对应的端口
filter =sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = -1
sudo service fail2ban restart #重启
sudo fail2ban-client status #查看状态
sudo fail2ban-client status sshd #查看sshd的详细状态
sudo fail2ban-client set sshd unbanip 192.0.0.1 #解禁指定IP
好了,我们回到SSH篇的第5点。
最后
其实,只要是在互联网上,只要是有价值的内容,但凡涉及到需要输入密码的,都强烈推荐使用强密码,而不要使用非常简单的密码,有些同学可能觉得麻烦,但等到数据丢了或者账户被盗了之后,你再后悔可能都来不及了。
参考资料
感谢互联网,感谢以下分享的作者们。
https://blog.laoda.de/archives/how-to-secure-a-linux-server/?highlight=%E4%BF%9D%E6%8A%A4
https://www.youtube.com/watch?v=sO-afVsDJOA
https://techguides.yt/guides/secure-linux-server/
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-20-04
附录
安装PuTTY
虽然 Windows 10 之后的 PowerShell 和 WSL 也可以达到很好的 SSH 操作体验。但是因为并非所有版本的 Windows 都有最新的组件,故本文还是以老牌的 PuTTY 为例,进行 SSH 远程登录的操作详解。(使用其他工具的话、在 SSH 登陆之后的操作都是一样的)
下面就跟我一步步操作吧。
- 进入 PuTTY 的官网,选择适合你操作系统的版本下载。(本文以 64 位版本为例)
- 安装运行后,将会看到 PuTTY 的主界面。现在请拿出你记东西的小本本,在下图的对应位置填入你 VPS 的IP 地址(VPS IP)和端口(VPS PORT)。为了方便以后使用时不用重复输入,我们可以保存会话 (Saved Sessions),未来使用时只要按 Load 即可一键载入设置。
- 我建议将
Connection
中的keepalive
设置为 60 秒,防止你一段时间没有操作之后 SSH 自动断线。另外务必再次保存设置。
注意
对 PuTTY 的任何设置更新都要再次手动保存 Session,不然关闭后就会丢失
- 点击 Open 就会进入 SSH 连接窗口,对应下图输入用户名与密码,与你的 VPS 远程主机建立连接。(本文假设默认用户名是
root
,另外,在 Linux 系统输入密码的时候,是不会出现******
这种提示符的,这样可以避免密码长度泄漏,不是你的键盘坏掉了哦!)
PuTTYgen生成密钥对(适合Windows用户使用)
1、运行PuTTYgen
(PuTTY 密钥生成器)
位置是 开始菜单
—> 所有程序
—> PuTTY (64-bit)
—> PuTTYgen
- 点击
Generate
开始生成(在界面空白处乱晃鼠标增加随机数)
注意:
本图中是以
2048
位的RSA
密钥为例的。但实际上,如果要获得与EDCSA/Ed25519
的256
位密钥相同的安全性,你需要使用3072
位的RSA
密钥。(即右下角的数字改成3072
)
- 你可以给私钥设置密码,增加一层安全性
- 点击
Save public key
保存公钥,文件名为id_rsa.pub
- 点击
Save private key
保存私钥,文件名为id_rsa
(PuTTY 私钥自带.ppk
后缀) - 最重要的,将上方红框内的内容,向下滚动全部复制出来并保存,文件名为
authorized_keys
。(用 vscode 保存,默认会变成带txt
后缀的文本文件,这没关系,之后上传 VPS 时我们会把后缀名去掉)
2、将公钥上传至 VPS 的seven
用户下
- 这一步如果是机子上装过
FinalShell
的同学,可以直接用自带的上传文件功能来上传,如果没有FinalShell
,可以去官网下载,或者就需要用到WinSCP
了。
- 去官网下载并安装,会提示你导入 PuTTY 的设置,当然一键导入啦!
- 如果没有提示导入或者你已经提前安装好了,那按照下图进行配置即可
- WinSCP 左边的目录就是本地电脑上的文件夹和文件,请定位到密钥所在的文件夹
- WinSCP 右边的目录则是 VPS 服务器上的文件夹和文件,默认就在
/home/seven/
文件夹,此时在请点击右下角X hidden
来显示隐藏文件
- 在右边(VPS 中)点击右键并新建文件夹,起名
.ssh
(注意有一个.
)
- 将【公钥】
authorized_keys
上传到.ssh
文件夹内
- 在上传时,将【公钥】从
authorized_keys.txt
改名为authorized_keys
(去掉.txt
这个后缀名)
完整流程演示如下:
3、在 VPS 端设置 SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录
- SSH 远程连接到 VPS 上(PuTTY)
- 修改
authorized_keys
文件权限为600
(仅所有者可读可写)
chmod 600 ~/.ssh/authorized_keys
修改 SSH 配置。这个我们已经用了很多次,但现在我们已经从无所不能的
root
变成了普通用户seven
,此时的我们是没有权限直接编辑 SSH 配置的。这时候就需要使用sudo
命令了:
sudo nano /etc/ssh/sshd_config
- 找到(
ctrl+w
)PasswordAuthentication
改成no
- 找到(
ctrl+w
)PubkeyAuthentication
改成yes
,然后保存(ctrl+o
)退出(ctrl+x
) - 重启 SSH 服务。(啰嗦君:别忘了现在需要使用
sudo
来获得权限)
sudo systemctl restart ssh
- 完整流程如下:
- VPS 端已经设置好了公钥,现在要给 PuTTY 指定私钥位置供登录时使用(啰嗦君:别忘了保存 Session)
- 至此,【密钥登录】已成功开启、【密码验证】已成功关闭、并且还给 PuTTY 保存了默认的登录用户名和私钥。未来使用 PuTTY 登录时,载入
VPS-SERVER
配置后,点击Open
就可以一键登录了。如果你给私钥设置了密码保护,登录时当然还需要输入这个密码才能使用密钥,如下图:
- 别忘了给
WinSCP
也做对应的密钥设置,否则之后想要传输文件时就无法登录了:
注意
任何需要借助 SSH 进行登录的软件都需要密钥验证了,软件过多,无法逐一展示,请根据你的需要自行设置好哦
暂无评论内容