TIPHello,欢迎大家点开这篇文章。从网站的搭建,到实例的购买,再到域名的购买,ICP,还有DNS,Nginx配置,公安网备,SSL等等流程还是蛮繁琐的。这篇我将分享我在云实例的选择,搭建,安全加固。后续的笔记文章,还将会更新到关于网站的设计和安全加固。
关于服务器的选择与基础配置
厂商与实例的选择
云服务器的厂商有非常的多。提供的服务器种类,类型,方式,也各有不同。大体上分为两大实例类型:
- 轻量应用服务器
- 标准的云服务器实例
在选择的时候我们可以针对自己喜欢的云厂商或者根据现实优惠来决断哦。
并根据需求,选择恰当的CPU核心,内存,硬盘(系统盘,也可以按需加数据盘),固定带宽/流量
做好地域规划,实例所在的机房地域影响到访问的速度(国内,海外都可以)
通常购买实例和域名并完成相应的备案,证书获取等手续后。我们可以利用服务器的公网IPv4地址进行开发和设计。
环境选择
按照需求,我们可以灵活的选择服务器搭载的操作系统。这里以我的实例为例子:我选择的是Ubuntu 22.04 ,server的linux发行版更加轻便,可以节省本就补充裕的硬盘空间。
基础配置
创建好实例以后有些基础的配置需要进行
- 首先就是安全组:
如果需要SSH远程控制操作的可以开启22端口(默认是22端口)这里强烈建议进行IP限制
如果后续部署网站则需要开放80/443的TCP端口
当然还有一个是全部 (-1/-1)的ICMP-IPv4。他的作用是ping访问测试连接的可靠性
- 进入服务器命令行终端进行环境配置和基础的安全加固:
当然还是登陆linux老传统,先配置好用户名,主机名,时区,交换分区,日志管理等等,当然还有必少不了的更新老传统:
#bash:sudo apt updatesudo apt upgrade根据个人喜好,可以安装一些基础工具:
#bash:sudo apt install -y curl wget vim htop net-tools git nginx fail2ban| 工具 | 作用 |
|---|---|
curl | 发送网络请求,访问网页,下载文件,测试接口等功能,HTTP/HTTPS/FTP等都支持, |
wget | 可以在shell下载网络文件,断点续传和批量下载 |
vim | 自从用了VIM,我很少用nano了,太强大的文本编辑器了哈哈。本篇文章中关于配置文件修改等的我都将用VIM代替 |
htop | 交互式系统进程监控工具,他可以替代top,查看cpu,内存,进程等等 |
net-tools | 里面有许多的工具:ifconfig, netstat, route… |
git | 分布式版本控制系统,开发时候必备的工具哈哈。太好用了,多人协调同,版本控制。只能说Linus牛! |
nginx | 配置web服务必备的哦。 |
Fail2Ban | 这个和安全加固有关后面会讲到,他能够监控服务日志,自动封禁多次密码错误,恶意访问的IP,抵御暴力破解攻击 |
服务器核心安全加固SSH端
IMPORTANT本篇笔记文章的重点来啦
TIP这里记录我在加固服务器安全时候的做法和想法,嘻嘻。只针对于SSH端的核心加固
我在思考,大厂们是怎么加固自己的服务器的?我作为学生能做到的深度有多少?
想法不如实际行动起来,为了降低服务器被攻击的可能性,以及我做的加固总结。有以下的思路可以考虑采纳:
将SSH端口改为高位非标准端口 安全组限制SSH来源IP UFW开启并仅开放必要端口 定期进行系统更新 SSH快捷连接配置,方便后续主机登录 生成带私钥加密的密钥,用SSH进行密钥连接 密钥自动管理(keychain + ssh-agent) 禁止root登录 禁止密码登录 限制SSH来源IP白名单 自动化检测暴力破解IP,并对其封禁。fail2ban Nginx配置Web安全 配置文件进行.bak备份下面介绍如何逐步实现这些的配置
1. 将SSH端口改为高位非标准端口
这一步需要在云厂商控制台内更改默认开放的端口22为高位端口。更改后由于服务器端口监听的还是22端口,所以我们有两种思路:
- 先在安全组更改高位端口,再用云官方的VNC连接服务器,然后再改端口监听。
- 这一步也可以先在SSH连接服务器,更改配置文件。然后再在安全组更改端口。(推荐)
当然两种方法都可以,安全组释放高位端口(6666为例子): 考虑到每个云厂商设计不一样。大体规则一致,需要注意的点在:优先级为1,如果是100会与之后的80/443端口抢连接权。
我将介绍配置文件的更改:他在etc/ssh/sshd_config: 记得在修改配置前需要备份原始配置文件。这一步将会把服务器的端口监听改到6666:
#bash:sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.baksudo vim /etc/ssh/sshd_config进入vim文本编辑器后,将原有的#Port 22 / Port 22改成:
#vim:Port 6666#bash:sudo sshd -t #检查配置sudo systemctl restart ssh #重启SSH2. 安全组限制SSH来源IP
在云厂商控制台中将6666端口更改来源IP,推荐只允许主机的当前公网IP,每次连接时候更改即可。
3. UFW开启并仅开放必要端口
大体的防火墙分为两个。一个是云厂商的安全组。安全组已经限制了端口的暴露和来源的IP,恶意的访问会在云厂方面就被拦截,难以到达服务器。即使到达服务器。我们依然可以通过服务器的防火墙本身进行二次加固。这里不推荐把服务器的UFW也做SSH的来源IP访问限制。如果经常换地方连接,每次换地方都得VNC连接,修改,再SSH连接。
我将介绍UFW的启用与6666/80/443端口的开放:(注意,如果未备案域名,不能DNS解析到服务器。所以按需开放80/443即可)
#bash:sudo ufw status verbose #查看UFW 状态sudo ufw allow 6666/tcp #开放6666端口的TCP连接许可sudo ufw allow 80/tcp #开放80端口sudo ufw allow 443/tcp #开放443端口sudo ufw delete allow 22/tcp (如果之前有22,删除即可)sudo ufw status numbered #查看UFW防火墙当前规则sudo ufw enable #启用防火墙sudo ufw reload #重载UFW4. 定期进行系统更新
当然我们可以定期进行:
#bash:sudo apt update && sudo apt upgrade -y这里额外提供两种方案:
- 用Ubuntu自带的包:unattended-upgrades(服务器更推荐)
#bashsudo apt install unattended-upgrades #先下载下来sudo vim /etc/apt/apt.conf.d/50unattended-upgrades #用VIM直接编辑,保存后会自动创建文件#vim:"${distro_id}:${distro_codename}-security"; #保持这个配置Unattended-Upgrade::Automatic-Reboot "true"; #这步可以设置自动重启,注意服务器的话,还是保留False!#bash:sudo vim /etc/apt/apt.conf.d/20auto-upgrades#vim:APT::Periodic::Update-Package-Lists "1"; #每日软件包索引的更新APT::Periodic::Unattended-Upgrade "1"; #每日无人值守#bash:sudo unattended-upgrades --dry-run --debug #测试配置sudo unattended-upgrades -d #手动执行- 用shell脚本自动化配置 先放置脚本,推荐存在/usr/local/sbin/auto-update.sh
NOTE在Linux当中:/usr下,bin通常放置普通命令,sbin通常放置管理员命令,local放自己的命令脚本,软件等等 而更新这类的命令需要root权限,需要sudo提权。我们放在这个目录会更加符合规范和清晰。后续用Linux的cron(定时任务)的时候,用sudo crontab -e 也就是用root权限给我们的脚本提前提权。这样脚本中也不需要每个命令前面都加上sudo了。
#bash:sudo vim /usr/local/sbin/auto-update.sh脚本内容用vim如下填写:
#vim:#!/bin/bash #用于强调是bash运行,必须写
LOG_FILE="/var/log/auto-update.log" #这里我们定义一个LOG_FILE变量来保存日志文件路径。可以在/var/log/auto-update.log里面具体查看(这是Linux默认的日志存放地)
echo "=== $(date) ===" >> "$LOG_FILE" #日志追加写入:当前时间apt update >> "$LOG_FILE" 2>&1 #更新软件包的索引注意2>&1会把错误的信息写在日志里面apt upgrade -y >> "$LOG_FILE" 2>&1 #更新apt autoremove -y >> "$LOG_FILE" 2>&1 #清理不需要的依赖包echo "" >> "$LOG_FILE" #追加空行,用来结束本次更新。方便我们查看知道结束了,当然也可以在“”里面写一些字来区别。#bash:sudo chmod +x /usr/local/sbin/auto-update.sh #用chmod改一下权限sudo crontab -e #配置定时任务#cron:0 1 * * 1 /usr/local/sbin/auto-update.sh #例如周一凌晨1.更新5. SSH快捷连接配置,方便后续主机登录
在传统ssh建立连接的过程中,我们往往需要输入:
#bash:ssh -p 6666 用户名@服务器的公网IP #是不是很麻烦呀,嘻嘻,我们将会简化他首先呢,我们直接编辑本地的SSH配置:
#bash:vim ~/.ssh/config#vim:Host 登录时候的便捷名字:eg:myserver HostName 这里跟上公网IP User 写服务器用什么用户访问的用户名 Port 6666 #之前我们改好的高位端口配置完我们就可以快捷登录:
#bash:ssh myserver注意权限设置600,可以到相应的目录通过:ll查看,如果权限不对立刻更改:(不过一般不会)
#bash:chmod 600 ~/.ssh/config这样我们每次输入:ssh myserver就可以直连服务器了。如果之前安全组有限制IP,记得更改IP,不然会一直卡住。
6. 生成带私钥加密的密钥,用SSH进行密钥连接
这步是为后面启动密钥登录关闭密码登录渠道做铺垫。为什么要这样做,就不得不提密钥的伟大了:
传统的密码登录防不住暴力破解的情况。公网IP长期暴露,每天无时无刻都有自动化脚本扫描和枚举破解我们的密码
这对我们的服务器造成了一定的威胁。密钥的强处就在于公私钥的分层管理架构。公钥存储在服务器上,私钥只在自己的主机上面,除非主机被攻克,否则很难拿到我们的私钥。
在进行登录的时候,服务器会随机向主机发送数字签名认证。主机根据本地私钥,生成签名,发送给服务器。服务器进行数字签名认证,成功了才能登录上,这样来看:密码登录的时候,密码虽然有SSH的加密,但持续暴露在公网上面,但是私钥只保存在我们的主机上面,全程不暴露在网络传输层上。会相对安全。再加上私钥的加密,即使攻克我们的主机,拿到我们的私钥,也难以破解,可谓防御属性大增!
关于加密方式,有以下可以供我们选择,这里推荐的是ed25519
| 方式 | 好处 |
|---|---|
| RSA-4096 | 很老的加密平台,老旧的OpenSSH全部支持 |
| ECDSA(P-256) | 他的密钥更加简短,速度比RSA更加快速在TLS生态有着更广泛的应用 |
| ED25519 | 速度快,密钥短,不依赖外部随机数,对OpenSSH,GIT/GITHUB全方位的支持,更新,0day漏洞少哦! |
| 现在我们直接操作: |
#bash:ssh-keygen -t ed22519 #用ed22519生成密钥当bash日志反馈:Enter file in which to save the key …吧啦吧啦的时候,一致回车,直到 Enter passphrase …吧啦吧啦 的时候,设置我们私钥加密的密码即可。
当然,我们可以在~/.ssh查看我们的私钥文件,不过是加密过的假私钥,嘻嘻。 里面会显示大致如下:
home/用户名/.ssh/├── id_ed25519 #私钥└── id_ed25519_pub #公钥然后我们将公钥上传服务器,这里推荐rsync 更方便,更快捷,有断点续传等功能哦!当然大家也可以用:ssh-copy-id -p 666 用户名@公网IP 的方式。
传输完成后会出现在服务器的:~/.ssh/authorized_keys
下面我们进行检查:在服务器运行哦!
#bash:cat ~/.ssh/authorized_keys再返回主机登录的时候,就会提示PASSPHRASE登录,就代表成功了。
这时候我们在服务器:
#bash:sudo vim /etc/ssh/sshd_config确认配置:
#vim:PubkeyAuthentication yesAuthorizedkeysFile .ssh/authorized_keys还是在服务器,我们看一下服务器当前的SSH配置并重启一下:
#bash:sudo sshd -t #看sudo systemctl restart ssh #启7. 密钥自动管理(keychain + ssh-agent)
关于这两个工具:
| 工具 | 我的理解 |
|---|---|
| ssh-agent | 这是一个后台进程,解密后的密钥就保存在这里哦,他的好处就是写入的是内存而不是硬盘,关机自毁哈哈。其也就是我们输入过的PASSPHRASE密钥,这样我们每次登录就不需要重复输入PASSPHRASE了 |
| Keychain | 他是用来管ssh-agent的。这样我们开启终端不用反复手动启动和添加 |
老样子,先安装:
#bash:sudo apt install keychain然后在主机用VIM编辑器把我们之前编辑过的~/.ssh/config改一下,改成:
#vim:Host 之前起的登录时候的便捷名字 HostName 公网IP User 用户名 Port 6666 #之前改的高位端口 IdentityFile ~/.ssh/id_ed25519 #明确私钥文件的位置,用他 AddKeysToAgent yes #这一步的意思是连接的时候如果发现私钥还没有加载到 ssh-agent里面,自动加入。确认下配置文件的权限设置,确保是600。同时为了让Keychain每次打开终端都自动执行,我们在 ~/.bashrc 文件里编辑:
#bash:vim ~/.bashrc#vim:eval $(keychain --eval --agents ssh id_ed25519) #在文件的末尾加上应用并验证:
#bash:source ~/.bashrcssh-add -l8. 禁止root登录
这一步,我们在服务器上面进行,先用ssh连接服务器,同时把我们要更改的SSH配置文件备份一下:
#bash:ssh 我们之前起的登录时候的便捷名字sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak #把sshd_config 备份一份.bak备份文件sudo vim /etc/ssh/sshd_config这里我们已经进入了文本编辑器编辑这个配置文件。可以发现他有好多预填写的配置,不过都用“#”注释掉了。我们把需要更改设置的配置设置好,把#去掉。有以下的需要配置:
#vim:PermitRootLogin no#bash:sudo systemctl restart sshd #重启一下SSH服务,让配置生效9. 禁止密码登录
这一步还是在服务器当中,还是编辑我们之前8更改的文件,大家确保配置:
#vim:PasswordAuthentication no #禁止密码登录PubkeyAuthentication yes #允许密钥登录(虽然之前设置过,但是还是检查下,不然容易把自己锁在外面)完成后也同8重启SSH服务,让配置生效。
10.限制SSH来源IP白名单
在云安全组放行的SSH高位端口中,eg:6666 设置访问IP来源限制,通常可以有:
- 主机的IP (推荐)
- 主机所属VPC网段
- 交换机的网段
- 所有IP不限制
11.自动化检测暴力破解IP,并对其封禁。fail2ban
考虑到systemd journal是二进制格式文件,不方便我们收集,处理里面的日志进行分析。如果后续有大数据处理的学习需求会很复杂哦,还得导json等等的。所以这里推荐的日志路径是/var/log/auth.log。这是个纯文本日志,更加方便我们去使用和分析。下面分享我的配置经验:
让我先在这里介绍一下fail2ban的运作机制,方便后续步骤的展开。嘻嘻:
fail2ban会持续监控系统日志(/var/log/auth.log 之类的)。如果小坏蛋尝试密码枚举破解,就会因为错误尝试次数过多被封禁IP,阻止小坏蛋IP即所属IP的访问权限。
fail2ban有一个个监狱,负责不同的方向,有SSH的,有NGINX,还有APACHE等等。 我们用[sshd]来限制该配置文件下fail2ban只对ssh访问ip的监控。
而根据fail2ban运作机制,他会通过以下顺序访问:
jail.conf→jail.local→jail.d/*.conf→jail.d/*.local
后面的文件的设置会把前面文件的盖住。
而系统默认可能会在一些jail.d/*.conf文件里写设置。比如/etc/fail2ban/jail.d/defaults-debian.conf。哈哈,在这个文件里就可能给 [sshd]写了backend = systemd,也就是让fail2ban去读systemd的日志。 so.我们不能简单粗暴的在jail.local里面写:logpath = /var/log/auth.log。后面的defaults-debian.conf一旦被读取,backend = systemd就会把我们的设置盖掉。这种情况下fail2ban还是去读journal,根本不看auth.log
所以我们才大费周章的把配置文件放到 jail.d/sshd.local,嘻嘻。
前文中有推荐安装fail2ban,现在我们利用这个工具,进行IP恶意破解封禁设置: 他的默认配置文件位于:/etc/fail2ban/jail.d/defaults-debian.conf 如果出现:
#cat:enabled = truebackend = systemd系统已经让fail2ban读取systemd journal日志了,我们的需求是读取/var/log/auth.log
我们用vim直接创建并编辑我们写的配置文件:地址:/etc/fail2ban/jail.d/sshd.local
#bash:vim /etc/fail2ban/jail.d/sshd.local#vim:[sshd] #这个是fail2ban的一个监狱,用来限制服务于SSH的。就不会管Nginx那些了enabled = true #让fail2ban真正开始工作,服务ssh。port = 6666 # 改成我们设置的高位SSH端口filter = sshd #调用fail2ban内置的SSH规则模板,他能从日志中找出错误的SSH登录日志backend = auto #限制backend(如果没有的话,虽然这个配置文件会覆盖defaults-debian.conf,但是backend还是默认的systemd)logpath = /var/log/auth.log #明确log存储的位置,让fail2ban能够找到maxretry = 5 # 如果5次登录失败就封禁IPfindtime = 10m # 如果在600秒内失败次数超过,直接封!bantime = 1h # 对被封禁的IP采取封禁1小时ignoreip = 我们的主机IP # 我们的IP地址,这里做一个IP白名单,也可以不做(当然这些参数也可以根据大家的喜欢自行定制化)#bash:sudo systemctl restart fail2ban #立即重启fail2bansudo systemctl enable fail2ban #每次重新开机自动启动(服务器一般不需要,但万一要重启呢,所以建议加上)sudo fail2ban-client status #查看fail2ban当前的状态,启动了哪些jail(就是我们之前说的监狱)sudo fail2ban-client status sshd #查看针对于[sshd]的jail的状态。当然,我们可以通过:sudo fail2ban-client set sshd unbanip IP地址 来解封某个误封的IP。还有一些常态化巡检:
#bash:cat /var/log/fail2ban.log #看管理日志sudo journalctl -u fail2ban #如果用的systemd journal可以用这个看sudo fail2ban-client status sshd #看被封禁的IP详细信息sudo fail2ban-client status sshd | grep "Banned IP list" #看封禁IP列表12.Nginx配置Web安全
这个部分和网站与服务器整体加固有关,我打算放到后续更新的文章分享。SSH的访问源只有我们,所以很好做加固,受攻击的攻击面很小。但是我们如果开放网站,把80/443开放的话。危险会巨增,同时加固难度也会变得很难。 之后的文章,关于Nginx配置的时候,我会详细讲解:
也算一个小小的下集预告哈哈
| 配置 | 原理和安全防御的攻击类型 |
|---|---|
| listen 443 ssl + SSL证书 | 通过SSL保证和加密,走HTTPS通道,防御中间人 |
| 80 端口 301 跳转 HTTPS | 80端口走不通啦,强制443走HTTPS,防御小坏蛋进行SSL剥离走http |
| Strict-Transport-Security | 限制一段时间内必须走HTTPS,不接受HTTP请求 |
| X-Frame-Options | SAMEORIGIN通过限制只允许同域名站点嵌入<iframe>、<frame>防御小坏蛋点击劫持 |
| X-Content-Type-Options: nosniff | 禁止浏览器猜测响应内容的 MIME 类型,强制按服务器要求的类型处理,防御 MIME的嗅探攻击和恶意文件伪装执行 |
| Content-Security-Policy | 限制住页面加载资源的来源渠道,防御XSS,数据注入等等 |
| Referrer-Policy | 通过控制浏览器跳转和请求外部资源时发送多少的 Referrer 信息,减少敏感URL 或用户行为泄漏,防御 Referrer 信息泄漏 |
| ssl_protocols TLSv1.2 TLSv1.3 | 禁用存在漏洞的老旧的 TLS 版本,用现代的协议,预防小坏蛋利用旧协议漏洞攻击 |
13.配置文件进行.bak备份
在修改某些配置文件之前,强烈建议大家做好配置文件原始版本的备份:
#bash:sudo cp 原文件 原文件.bak.$(date +%Y%m%d) #$(date +%Y%m%d)可以标注备份的年月日小结
互联网的诞生便利了我们获取信息,和进行学习交流等的途径。但是安全意识应当始终贯彻我们的运维和生活思维中。
本篇文章我分享我在服务器SSH端的防御策略,给大家提供了一套有纵深策略的SSH防御加固体系。后续我还会写一篇分享文章将从网站安全角度出发分享。和大家分享我是如何选择网站的框架和主题还有如何进行安全加固。
总结一下:
大体上来讲:两套大的防火墙。安全组和UFW。只开放必要的端口,同时在安全组或UFW限制来源IP
然后我们限制了SSH登录连接的途径。禁止ROOT,禁止密码。采用密钥。再对私钥加密。
对恶意访问的IP用fail2ban进行封禁策略,这也相当于一个防火墙,不过是软件层,UFW是系统层,而安全组直接在云厂商就阻拦了到不了服务器,哈哈,层层加固。
TIP感谢大家的阅读和学习。文章内容只是我的个人运维观点,仅供参考,不足和错误见谅,也欢迎大家即时向我反馈,嘻嘻。
陕公网安备61020002000144号