Files
baim0-learn/nginx/20.Nginx服务器安全相关(下篇.md
T

374 lines
21 KiB
Markdown
Raw Normal View History

2024-03-09 13:38:35 +08:00
## 20.Nginx服务器安全相关(下篇)
进入下篇之后 我们继续沿着这个框架和思路推进
把剩下的两个链 和 2个表学习过关之后 (raw & mangle 表 学习难度较大),我们需要再补充iptables的几个进阶的重要知识点(也顺带扩展一些Linux的网络知识 )
接下来 我们会把 一整套数据包在整个iptables(内核netfilter)中的经过流程 给大家做进一步的清晰化
之后我们开始 iptables结合企业集群的实际情况 学习合理的设置方法 以达到最有价值的效果
(1) POSTROUTING链的学习 -> 数据包<路由后><出站前> (SNAT功能的实现)
我们上篇最后 学习了 iptables数据包传送的 下路路线
走下路的数据包 其实就是走NAT(数据包地址转换)的路线
我们这里再复习总结一下吧
PREROUTING最终判定为下路之后, 数据包经过的路径是 (不考虑数据包中途被丢弃 和其他更高阶的扩展表的情况下 )
\-> PREROUTING -> FORWARD -> POSTROUTING
PREROUTING链的作用:决定目标地址的改变与否 + 上路下路最终判定 (是过滤型防火墙 还是NAT型防火墙 )
FORWARD链的作用:是否允许被防火墙继续转发 + 是否允许使用Linux的路由功能/转发功能
那么POSTROUTING链呢?
我们先给出 POSTROUTING链 的定义和作用吧:
POSTROUING链 : 是内核(防火墙功能)对数据包在经过路由表之后 , 加以处理的最后一个链,其作用是决定数据包是否需要 改变<源地址>
介绍到这里以后 我们不难发现 PREROUTING和POSTROUTING 是一对儿, 一个改变目标地址 一个改变源地址
重要知识点:PREROUTING和POSTROUTING 这两个链 一个负责目标地址 一个负责源地址 这个是iptables定死的规则
不能交叉互换 (比如你想用 POSTROUTING改变目标地址 这是不可能的)
这里有一个问题: 为什么PREROUTING只能改变目标地址, 而POSTROUTING只能改变源地址?
下面会给大家解答
(2)结合内核路由 分析 PRE / POST - routing 链互斥互依的存在含义
在上面学习了 POSTROUTING链之后 ,我们明白了其基本的作用 就是修改数据包的源地址 (在离开操作系统出去之前)
那么上节课最后给大家留下了一个问题 ( 为什么PREROUTING只能改变目标地址, 而POSTROUTING只能改变源地址?)
这种限制 难道仅仅是因为 iptables起的一个规矩而已嘛?
回答自然是否定的
为了讲清楚这个问题 我们需要扩展一下Linux网络传输的知识
我们之前反复提过的 上路 下路 以及链于链的衔接 跳转 等等...
这些其实 都为了说明两方面的含义
第一: 表明了iptables防火墙的 链与链之间的关系 先后顺序
第二: 表明了数据包在内核中 在Linux中 是如何走向的
我们可以把 1 2 3 4 5 6 的连接线(数据包走势)分成如下三个基本类型 以方便大家的理解
<1> 从外面进入到本机的数据包 (1) -> (2)
<2>. 不进入本机的 且需要过路由的数据包 (或者说需要用到地址转换的数据包 ). (1) -> (3) -> (4) -> (6)
<3> 由本机由用户 主动发起出去 离开本机的数据包 (5) - (6)
这三个基本类型的数据包流向 还是比较容易理解的
PRE-ROUTING 和 POST-ROUTING 这一对儿链对于数据包修改的不同 其实就是围绕着路由表的概念 而引起
为了 能继续深入的学习这个部分 我们先插入下一小节的扩展内容 (搞清Linux和路由相关的几个概念)然后再推进
(3)路由/路由表/转发 概念搞清楚 以及和iptables的联系
在继续往下推进学习之前 我们有几个概念 需要先给大家捋清楚 (很重要的几个网络相关的概念 不可以混淆了 不然越学越蒙圈)
第一个要搞清概念: 路由表
比较官方的定义:
路由表是指路由器或者其他互联网网络设备上存储的一张路由信息表,该表中存有到达特定网络终端的路径,在某些情况下,还有一些与这些路径相关的度量。
比较大白话的定义:
路由表在Linux中 首先是一张 可见的 可更改的表, 它的作用 就是当数据包发到Linux的时候 , 系统(或者说内核)就根据这张表中定义好的信息 来决定这个数据包接下来该怎么走
重要知识点:在Linux当中 只要有网络传输的发生 就一定会跟路由表有最直接的联系,包括上面跟大家说的 三种基本数据包流向图 一样都要经过路由表 来决定这个数据包下一步该怎么走
第二个要搞清楚的概念:路由功能 和 路由器
有了路由表之后,Linux就可以遵循这个表中的路由信息 决定数据包的去向了
不过 数据包最终在跨越网段的时候 (发往其他的网络) A B 这个时候 必须借助网关设备才可以到达其他网络
网关设备:是用于连接两个不同网络的媒介, 可以是一个硬件的路由器 (我们平时家里用的那种 小路由器 就是这个功能)也可以是一个开启了 路由功能的 Linux主机
一个开启了路由功能的Linux 就可以作为一个 网关设备使用 (实际上 大米之前所在的两家公司 内部员工上网 就是使用Linux服务器做的 而并不是买的 独立路由设备)
第三个要搞清楚的概念:转发(数据包转发)
数据包转发 是一种网络上对一个数据包进行的特殊处理 可以理解为 是在数据包传输过程中的一种中转 或者说衔接
Linux本身就提供了 数据包转发功能
如何开启?
使能数据转发功能:
echo 1 > /proc/sys/net/ipv4/ip\_forward
禁止数据转发功能:
echo 0 > /proc/sys/net/ipv4/ip\_forward
这个地球Linux人都知道~~~
不过 如下的知识点 你可能不知道
重要知识点: Linux开启了数据包转发功能后,其实起到了两种功效
1) Linux本身 可以转发数据包了 自身就形成了一个 小路由器了 可以用来当网关使用
(既可以让全公司员工实现上互联网, 还可以作为 公司内部不同局域网之间的网关)
2)Linux开启了 数据包抓发功能后, iptables NAT才可以正常使用
也就是说 NAT这种 针对网络地址转换的功能 必须建立在 Linux开启数据包转发功能的基础上
(后面 讲DNAT SNAT的时候 我们会用具体实例 来证明这一点)
综上所述:Linux数据包转发的开启,最少开启了两种功能 : 路由器网关 + 数据包修改(NAT)
有了这几个知识点的巩固之后 我们再回到刚才上一段没有回答大家的问题
PREROUTING 和 POSTROUING 为什么一个只能修改目标 一个只能修改来源
这就是因为 PREROUTING链 是在 数据包过路由表之前 发生的(目标地址的修改)
假如一个数据包 需要被 <转发> 到一个地址去 ,那么一定会先经过路由表的查询之后 才能被转发
比如 : 我们通过iptables实现了一个 NAT的功能 把来自 192.168.56.106的请求,不让它进入本机(56.102) 而是把它转发给 192.168.56.104
如果数据包 在进入路由表查询之前 没有被修改 目标地址 (从102 =》104),那么进入路由表后 就来不及了,因为路由表就已经最终决定了这个包的下一步的去向了
所以说,PREROUTING 实现的修改目标地址 必须在 数据包进入 路由表之前发生, 也就证明了 目标地址的修改 绝不可能放在 路由表之后的 POSTROUTING链再修改 那就没有任何作用了
那么接下来 我们来说一下 为什么 来源地址的修改 只能放在 POSTROUTING才行
源地址的修改 一般情况下 只是作为将 原本的来源地址 修改为本机的IP地址 以此来实现SNAT (后面马上就会讲到)
这种情况下 不可能在过路由之前 就修改为本机一样的IP地址 A-A 这样数据包就没有办法 被Linux判断了
而POSTROUTING是在数据包离开路由表后的行为, 即将要离开本机之前 ,修改源地址,以便数据包可以传回给自己本机(后面)
这样以来 我们就明白了 PREROUTING 和 POSTROUTING的本质了
(4)DNAT 和 SNAT 技术学习
有了前面坚实的基础之后 我们终于可以开始向具体防火墙应用方面推进了
首先我们提出 两种NAT的模型
DNAT & SNAT
我们先来看一下定义吧
DNAT : Destination Network Address Translation目的地址转换
SNAT:Source Network Address Translation 来源地址转换
通过之前篇幅的学习 对于这两个概念的理解就很轻松
iptables 实现两种NAT 就是通过 PREROUTING链 和 POSTROUTING链来实现的
重要的知识点:这里需要提醒初学者一句 NAT技术 是一种网络通用技术 或者也可以说 一种技术标准
并不是iptables 或 Linux内核 所特有的技术. 其他的很多途径都会以各种方式 提供或依赖这种NAT技术. 比如 各种网络硬件设备, 各类负载均衡设备或软件 等等..
接下来 我们来看一下 DNAT & SNAT的企业实际用途
技术学了不是摆设 在工作中用起来 才是正途
iptables DNAT 在企业中用途主要为如下几种 :
(1) 实现内网站点或其他服务的对外发布
解释:公司将内部服务器的某个站点 使用iptables DNAT对外发布 可以实现员工远程连接企业内部资源
比如各种 企业内部的开发人员 DEVOP说 工具站点 监控系统 邮件系统 OA系统 等等. 不过这种实现的网站对外发布 虽然简单方便 但是
会有一定的安全隐患(如果想做足了安全系数 需要在iptables的基础上 做大量的额外工作)
所以说 这种方式的网站发布 目前在企业中 正逐渐被各种其他的高级技术所取代 , 例如 \*\*\*技术(拨号\*\*\*,\*\*\*隧道) , 验证+反向代理 等等
不过 对于那些没有太多安全限制的内部服务的对外发布, 这种iptables DNAT依然是 速度最快的发布方法
(2) 堡垒机(跳板机)的实现 增强安全系数
解释: 堡垒机或者跳板机 是作为集群登陆安全验证的一种 统一化运维管理机制
强制员工先登陆跳板机 进而再登陆后端其他机器
结合iptables DNAT之后 可以通过编写简单的登录脚本 实现快速后端间接登录
由于用户被限制在 跳板机入口登录 所以这种方法即可以实现用户行为追踪 又可以很好的起到保护后端登录安全的目的
(3)服务器本机端口转换
解释:软件服务的端口 都是可以自行修改的 这种借助iptables DNAT改变端口的情况
适用用于 某些情况下 例如 公有云或ISP 只开放特定对外端口的情况下 可以快速实现端口转发
另外 这种端口转发 也会起到一定的安全防护作用,可以将服务上软件的默认端口先用iptables都禁止访问
然后 使用其他端口 DNAT到 这些默认端口来使用
iptables SNAT 在企业中用途主要为 : 转换原地址为公网出口地址 实现企业上网
解释: 如上图的SNAT实现上网的流程为, 员工自己的电脑都只能设置内网IP(192.168...) ,通过IPTABLES的数据包转发功能 (两块网卡 一个连接内网 一个连接公网)
可以将上网的请求 发送到互联网上去(公网),不过 内网IP是无法在 互联网上传送的,并且内网IP的数据包 也没有办法被互联网返回回来
所以 在经过 内核防火墙<下路> 通过路由转发后, 在最后一步的POSTROUTING链 会把数据包的源地址 改变为本机公网网卡的地址
并且在防火墙自身留下一条记录 , 数据包之后就可以成功发送到 互联网的对端了 之后再返回回来的时候,数据包回到Linux网关,再通过之前留下的记录 把数据包再转发给后端的 对应的那个内网IP
这就是完整的 SNAT的流程
重要知识: 我们绝大部分的 所谓的”上网" 都是通过类似这样的SNAT技术实现的 (除非你的电脑 单独拨号 或者直连公网IP 上网)
只要是多人通过一根公网线上网的 都是通过这样的技术实现的 家里 或者 企业中的 路由器做的就是这个事
(5)IPTABLES PRE/POST-ROUTING(D/SNAT) 命令行讲解
接下来 我们就可以对命令行进行详解了 通过如下的几个实例
我们先熟悉一下 最常用的 iptables几个参数
\-t 指定在哪个表下设置规则
\-A 指定一个链 并指定本条规则 是追加到链末尾 (对应的还有一个 -I 将规则放在最前)
\-s 限定来源地址的 符合规则
\-d 限定目标地址的 符合规则
\-j 执行动作和处理
\-p 指定协议
首先 iptables 实现NAT地址端口修改 必须用到Linux的数据包转发功能(之前咱们系讲过)
必须先开启 内核转发数据包功能
echo '1' > /proc/sys/net/ipv4/ip\_forward
(1)PRETOUING 实现目标地址全转发
iptables -t nat -A PREROUTING -d 192.168.56.102 -j DNAT --to-destination 192.168.56.104
解释: 把 数据包目标地址是 192.168.56.102的 全部转发到192.168.56.104
(这种属于全转发 )
(2)PREROUTING 限制来源和端口的 转发
iptables -t nat -A PREROUTING -s 192.168.0.0/16 -p tcp --dport 3333 -j DNAT --to-destination 192.168.56.104:22
解释: 把 来自于192.168.0.0/16网段 且 目标端口为3333的请求 转发到 192.168.56.104:22(端口)
(之前所讲跳板机的用法)
(3)SNAT 实现源地址转换
iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -p tcp -j SNAT --to-source 211.199.xxx.xxx
解释:把来源地址为 172.16/16的数据包 的源地址 改成 211.199.xxx.xxx(网关上的公网地址)
(这就是通过SNAT 实现上网了)
接下来 我们来看一个 设置DNAT的完整实例 以及需要特别注意的地方
我们就用 堡垒机的实例来举例 把ssh到不同端口的请求 转发到不同的后端机器上的22端口
iptables -t nat -A PREROUTING -d 192.168.56.102 -p tcp --dport 3334 -j DNAT --to-destination 192.168.56.105:22
通过的设置,就可以把发送到3333端口的 ssh连接 转发给 192.168.56.104:22了
不过呢… 你可以试一下 这样设置之后 能不能就立刻使用了
ssh 192.168.56.102 -p 3333
\[root@server05 ~\]# ssh 192.168.56.102 -p 3333
...
结果是不通 ... 怎么回事呢??
这里画图给大家解释一下 为什么 (这里非常重要的知识)
绿色是SSH请求发起方, 数据包到达下面的iptables时候, 经过DNAT的转换,目标地址 由102 转变为 104
当前所经过的路径是 A -> B
这里需要特别强调一点 数据包是有去有回的 (很多朋友 都非常容易忽视这个问题 只考虑去 不考虑回)
之后 请求到达 56.104(右边的粉色)之后,104处理完成后 需要将请求 返回回去
这个时候 数据包的 来源地址 依然是 106 , 104 尝试将数据包返回给106 (绿色的部分)
此时 数据包返回会失败为什么呢(尽管是处在同一网段,如果是处在不同网段 那就更不可能发回去了) 因为最原始的数据包 是106(绿色)通过 A->路径发送给102的
在TCP连接建立的基础上说 , 106(绿色)从来就没有给 104(粉色)发起过TCP连接请求 ,绿色发出的TCP请求 还在和102(防火墙机器)建立着链接 等待返回数据呢
就算数据包返回回去 也会被拒收
所以说 这种数据包通过代理(防火墙)转发的形式 , 路线必须遵从 A -> B -> C -> D 这样的顺序发送
以最下方防火墙为中心点, 左右两边 都是半边各自建立最短的直接链接 有去必有回
解决的方法 :
在这里 通过再设一条 SNAT规则 把 来源地址 106(绿色) -> 转成 102(防火墙机器的地址)
这样以来 B路和C路 就形成回路了
完整的解决方案 就是如下 请牢牢记住 , 且这个还经常作为 Linux系统工程师的 面试题 (我本人 曾经被最少 3次面试中 都问过 iptables 如何实现DNAT)
iptables -t nat -A PREROUTING -d 192.168.56.102 -p tcp --dport 3333 -j DNAT --to-destination 192.168.56.104:22
iptables -t nat -A POSTROUTING -d 192.168.56.104 -j SNAT --to-source 192.168.56.102
另外 顺带一提的是 不要忘了打开 Linux内核转发功能
一旦关闭 转发功能 NAT功能就歇菜了!!(不信你可以试试关闭 这里再次验证 NAT功能需要借助内核转发)
echo '1' > /proc/sys/net/ipv4/ip\_forward
最终 我们通过IPTABLES DNAT成功的实现了 堡垒机(跳板机)的功能
(6) IPTABLES FORWARD链学习
五个链中 只剩下这个链了
接下来 咱们来看看FORWARD链具体是干嘛的
还是通过上面这张图 我们来看一下 中间的FORWARD链
FORWARD 咱们上篇介绍过了, 在咱们的课程中 它具备两个含义 咱们再来说一次
(1) 代表了 Linux内核的路由和数据包转发
(2) 代表了 IPTABLES防火墙中 FORWARD功能(FORWARD链)
关于这个FORWARD链它具体的功能 有很多朋友对它的概念 都比较模糊
大概知道是啥意思 但是形不成具体的使用模型 餐不透
那么接下来 咱们来好好捋一捋这个FORWARD链把 (顺带着 咱们也整个捋一捋五链架构)
我们先来看一下 一个数据包 到底什么情况下 才会跟这个FORWARD链发生关系 (才会用到FORWARD链)
首先 我们先把准确的定义 给大家抛出来
FORWARD链 只会跟需要用到 Linux内核转发功能的 数据包 才会发生关系
举几个实际案例来考一考大家学习的成果
(1) 同网段下 从一台机器ping 另外一台机器 会关系到FORWARD链吗?
回答:跟FORWARD链没关系, 因为同网段下 (比如都是192.168.56.0/24的IP地址)用不到路由或Linux转发 走的是直连路由(路由表)
所以 你即便在防火墙下 加上了如下语句 拒绝一个IP使用转发功能 但是依然可以ping通 (但是NAT就不通了哦!!)
iptables -A FORWARD -s 192.168.56.106 -j DROP
\[root@server05 ~\]# ping 192.168.56.102
PING 192.168.56.102 (192.168.56.102) 56(84) bytes of data.
64 bytes from 192.168.56.102: icmp\_seq=1 ttl=64 time=0.252 ms
ssh 192.168.56.102 -p 3333 #(之前NAT堡垒机的例子)
…..
(2)如果是分属两个不同网段的机器,从一台去ping另外一台机器 会用到FORWARD链吗?
机器A(网段A) -> 防火墙 FORWARD DROP/网关(路由转发) -> 机器B(网段B)
回答是:会用到
因为 中间的防火墙机器 这个是充当了 路由器(Linux iptabls 数据包的转发)使用,左右连接两个不同的网络下的机器
那么 数据包经过的时候 会依赖Linux内核的路由功能 (路由功能 即是 数据包转发功能)
所以 这个时候 如果限制了 FORWARD DROP, 那么就ping不通了哦
(3)如果一个数据包 是要经过DNAT 或者 SNAT功能 的时候,——>(数据包的转发功能)-> 会用到FORWARD链吗?
答案是:会用到 , 因为只要是 NAT功能(地址转换) 就必然会用到 Linux的数据包转发 (但是这里 就不属于 使用路由功能了哦 这个要分清楚)
Linux 开启数据包转发的时候 , 把自身用来做一个网关(路由器)连接其他的不同的网络 ,开启NAT
FORWARD -j drop
(4)如果是在防火墙本机上 往外ping一个公网地址 会用到FORWARD链功能吗?
答案是: 不会用到, 因为防火墙本机 向外发送数据包 这个等于是把一个数据包 直接的从本机发送出去,并未用到任何跟本机相关的路由功能(但是会用到路由表 这两个不是一个意思)
通过上面四个例子的问答 我们就应该很容易得出如下的结论了
重要知识点: 只要是 会用到 Linux路由功能 或者Linux数据包转发 的请求(过Linux路由器,过Linux NAT), 就必然会经过 FORWARD链的关卡
接下来 我们进入更深层的 对FORWARD链的探索
我们在命令行 输入一下 iptables 查询
上面这个图中 我们可以看到 在filter表下 有三个链, INPUT FORWARD OUTPUT
也就是说 FORWARD链 是附属于 filter(过滤型) 表下的
然而 对应 我们一直所用的 这张图来说 FORWARD链 是属于 1346 下路的一个关卡
也就是从 单单 上路下路 来看,感觉 好像 FORWARD链 应该是附属在 下路 NAT(也就是数据包修改), 跟上路没什么关系貌似
但是 通过之前的讲解 我们也证实了 即便是走上路的情况下 (不涉及数据包修改 只是数据包传输 )也可能会跟FORWARD链产生关系
比如: Linux 充当网关使用的时候。走的是上路 不是下路 (因为不需要NAT转换地址)但是 由于需要用到转发功能 所以 也会跟FORWARD有直接的关系
知识点总结 : FORWARD FILTER表, 上路 下路(一定 NAT),数据传送 数据转换
所以 我们之后 会在这个图的基础上 提出一个更完整的 IPTABLES架构图 (之前不提出这个 完整架构图 是为了教学的目的 不然一上来就看完整IPTABLES图 会直接晕菜的…