概述

IT运维安全主要包括网络层面、系统层面、软件层面、硬件层面。

硬件层面

IDC机房、服务器硬件、IT设备等定期巡检,保证其正常、稳定运行,以防止损失、被盗、高温、静电、电源等

软件层面

Nginx、Java、PHP、MySQL、Web站点、业务系统等软件程序漏洞及BUG,对外访问权限、监听的端口、版本隐藏、软件权限控制、用户名和密码控制

系统层面

操作系统自身版本、BUG漏洞、暴露的端口、服务、系统权限、root用户、禁止ping、指令特权控制

网络层面

大流量冲击、DDoS、ARP攻击、通信中断等,网络层面安全重点关注网络流量、网络连通性。

2023.05 摄于河北邯郸·太极宗师杨露禅

攻击方式

DDoS攻击

DDoS(Distributed Denial of Service,分布式拒绝服务)攻击的主要目的是让指定目标无法提供正常服务,是目前最强大、最难防御的攻击之一。

原理

借助于客户端/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍提高拒绝服务攻击的威力。

  1. 分布式拒绝服务攻击采取的攻击手段就是分布式的,使攻击方式出现了没有规律的情况,且在攻击时使用通常协议和服务;
  2. 攻击数据包时经过伪装的,源IP地址也是伪造的,以使攻击时不会出现拥塞控制。
  3. 攻击目的时让服务器的网络堆栈溢出而崩溃

分类

  1. 基于ARP的攻击
  2. 基于ICMP的攻击
  3. 基于IP的攻击
  4. 基于TCP的攻击
    1. SYN Flood攻击
    2. CC攻击
  5. 基于应用层的攻击
    1. HTTP Flood攻击
    2. Hydra暴力破解攻击

防御

在实际生产环境中,DDoS防御方法通常有如下:

  1. 使用专业抗DDoS防火墙、高防IP等设备;
  2. 构建和部署CDN业务,把站点改造为静态或者伪静态;
  3. 采用高性能的网络设备,升级网络带宽;
  4. 增加服务器数量、升级主机服务器硬件;
  5. 对操作系统和应用服务进行调优。

实例

Hping3

hping3是一款面向TCP/IP的数据包生成和分析工具。可以用于对主机进行路由跟踪、防火墙规则测试、以及使用随机性源头IP发动DDoS攻击。

常用参数:

-c:设置发送数据包的数量
-d:设置每个数据包的大小
-i :设置数据包之间的时间间隔
-w:设置TCP窗口大小
-a:设置发起数据包的源IP地址
-k:保留root权限使用
-q:只输出关键信息到stdout
-p:设置目标端口,缺省为0
-S:表示发送TCP SYN包
-F:表示发送TCP FIN包
-P:表示发送ICMP包
–help:查看帮助信息
–fast:快速扫描模式
–flood:发送数据包并不等待响应(洪水攻击)
–rand-dest:随机化目标IP地址
–rand-source:随机源地址模式
–udp:发送UDP包
–tcp-timestamp:设置TCP包时间戳
–traceroute:扫描路径中的每个路由器

攻击端
# 工具准备
dnf install -y hping3
dnf install -y curl
curl -l 192.168.20.10
# 攻击命令
hping3 -c 1000 -d 120 -S -w 64 -p 80 --flood --rand-source 192.168.20.10

防御端
# 准备目标
dnf install httpd tcpdump -y
systemctl enable --now httpd
firewall-cmd --permanent --add-service=http
firewall-cmd --reload
# 查看网络状态,有大量随机IP产生的SYN——RECV状态
[root@client ~]# netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 192.168.20.10:22 192.168.20.1:48397 ESTABLISHED
tcp 0 52 192.168.20.10:22 192.168.20.1:48547 ESTABLISHED
tcp6 0 0 :::80 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 192.168.20.10:80 254.182.59.69:62761 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.70.188.121:45359 SYN_RECV
tcp6 0 0 192.168.20.10:80 250.44.133.136:52495 SYN_RECV
tcp6 0 0 192.168.20.10:80 250.153.82.250:51361 SYN_RECV
tcp6 0 0 192.168.20.10:80 252.12.85.79:21534 SYN_RECV
tcp6 0 0 192.168.20.10:80 241.56.60.70:35306 SYN_RECV
tcp6 0 0 192.168.20.10:80 252.106.32.27:50753 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.221.153.53:21519 SYN_RECV
tcp6 0 0 192.168.20.10:80 254.70.43.179:13237 SYN_RECV
tcp6 0 0 192.168.20.10:80 252.72.156.251:47133 SYN_RECV
tcp6 0 0 192.168.20.10:80 247.26.161.182:21455 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.204.141.116:52585 SYN_RECV
tcp6 0 0 192.168.20.10:80 250.124.8.76:13265 SYN_RECV
tcp6 0 0 192.168.20.10:80 252.82.68.126:15169 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.238.219.102:36672 SYN_RECV
tcp6 0 0 192.168.20.10:80 254.56.14.234:1275 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.29.44.82:1165 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.66.253.203:13181 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.205.24.116:43387 SYN_RECV
tcp6 0 0 192.168.20.10:80 247.59.42.4:16845 SYN_RECV
tcp6 0 0 192.168.20.10:80 254.73.81.8:54042 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.24.247.205:50123 SYN_RECV
tcp6 0 0 192.168.20.10:80 250.128.12.194:43317 SYN_RECV
tcp6 0 0 192.168.20.10:80 252.136.180.83:64686 SYN_RECV
tcp6 0 0 192.168.20.10:80 252.184.71.14:45271 SYN_RECV
tcp6 0 0 192.168.20.10:80 246.40.36.183:23153 SYN_RECV
tcp6 0 0 192.168.20.10:80 254.14.82.189:48945 SYN_RECV
tcp6 0 0 192.168.20.10:80 252.120.110.133:49484 SYN_RECV
tcp6 0 0 192.168.20.10:80 241.136.140.14:4805 SYN_RECV
tcp6 0 0 192.168.20.10:80 254.252.107.11:57425 SYN_RECV
# 主机CPU也被打满

ApacheBench

ApacheBech是Apache的开发的httpd压力测试工具,简称AB压测工具。其原理就是创建多个并发连接对某一URL地址进行访问。ab每一次GET都会和目的端握手,不会复用同一个TCP连接,在很小的时间内发送了10000次GET请求,并建立10000次,产生10000个会话。

# 安装
dnf install -y httpd-tools
# 参数
[root@share ~]# ab -h
Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:
-n requests 用于指定压力测试总共的执行次数
-c concurrency 用于指定压力测试的并发数
-t timelimit 等待响应的最大时间(单位:秒)
-s timeout 超时时间,默认30秒
-b windowsize TCP发送/接收的缓冲大小(单位:字节)
-B address 测试目标地址
-p postfile 发送POST请求时需要上传的文件,此外还必须设置-T参数
-u putfile 发送PUT请求时需要上传的文件,此外还必须设置-T参数
-T content-type 用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain
-v verbosity 指定打印帮助信息的冗余级别
-w 以HTML表格形式打印结果
-i 使用HEAD请求代替GET请求
-x attributes 插入字符串作为table标签的属性
-y attributes 插入字符串作为tr标签的属性
-z attributes 插入字符串作为td标签的属性
-C attribute 添加cookie信息,例如:"Apache=1234"(可以重复该参数选项以添加多个)
-H attribute 添加任意的请求头,例如:"Accept-Encoding: gzip",请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个)
-A attribute 添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开
-P attribute 添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开
-X proxy:port 指定使用的代理服务器和端口号,例如:"126.10.10.3:88"
-V 打印版本号并退出
-k 使用HTTP的KeepAlive特性
-d 不显示百分比
-S 不显示预估和警告信息
-q Do not show progress when doing more than 150 requests
-l Accept variable document length (use this for dynamic pages)
-g filename 输出结果信息到gnuplot格式的文件中
-e filename 输出结果信息到CSV格式的文件中
-r 指定接收到错误信息时不退出程序
-m method 方法名称
-h 显示用法信息,其实就是ab -help
-I Disable TLS Server Name Indication (SNI) extension
-Z ciphersuite 使用指定SSL/TLS指纹(See openssl ciphers)
-f protocol 指定SSL/TLS协议版本(SSL2, TLS1, TLS1.1, TLS1.2, TLS1.3 or ALL)
-E certfile 使用指定客户端证书私钥和证书链
攻击端
# 对测试端发起持续1000秒的10000并发连接访问
[root@share ~]# ab -c 10000 -n 10000 http://192.168.20.10/
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.20.10 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software: Apache/2.4.57#目标版本
Server Hostname: 192.168.20.10#目标地址
Server Port: 80# 目标端口

Document Path: /# 站点根目录
Document Length: 7620 bytes# 返回的分页大小

Concurrency Level: 10000# 并发连接数1000
Time taken for tests: 24.744 seconds# 执行时长
Complete requests: 10000# 完成并发
Failed requests: 7# 失败请求
(Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
Non-2xx responses: 9993 # 返回2XX正常信号值的次数
Total transferred: 78914721 bytes # 数据传输量
HTML transferred: 76146660 bytes
Requests per second: 404.13 [#/sec] (mean)#每秒平均请求数
Time per request: 24744.438 [ms] (mean)#每次并发请求时间
Time per request: 2.474 [ms] (mean, across all concurrent requests)#每个请求实际运行平均时间
Transfer rate: 3114.44 [Kbytes/sec] received#传输速率

Connection Times (ms)#压力测试时的连接处理时间
min mean[+/-sd] median max
Connect: 0 1137 969.1 1158 3391
Processing: 36 1917 1834.5 1256 23316
Waiting: 1 1898 1743.3 1252 6453
Total: 186 3055 2113.1 2519 23316

Percentage of the requests served within a certain time (ms)#在一定时间内的请求响应时间占比
50% 2519
66% 3947
75% 4442
80% 4883
90% 6193
95% 6923
98% 7233
99% 7283
100% 23316 (longest request)

防火墙

防火墙主要用于对数据包进行过滤,从而对用户访问进行控制。Netfilter/iptables是Linux自带的防火墙工具,功能强大、使用灵活。Iptables主要工作在OSI的二、三、四层。

虽然Netfilter/iptables IP信息包过滤系统其实是由Netfilter和ipatables两个组件构成。Netfilter组件是内核的一部分,由信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。iptables组件时一种工具,用来插入、修改和出去信息包过滤表中过的规则。

iptables

表与链功能

iptables防火墙的规则链分为三种:

  1. 输入input: 用来过滤目的地址时本机的连接
  2. 转发forward:用来过滤目的地址和源地址都不是本机的连接
  3. 输出output:用来过滤源地址时本机的连接

数据包流程

iptables防火墙可以对数据包进行过滤和限制,数据包先经过PREOUTING,由该链确定数据包走向

  1. 如果目的地址是本地,则发送到INPUT
  2. 若满足PREROUTING的NAT表上的转发规则,则发送给FORWARD,然后在经过POSTROUTING发送出去;
  3. 主机发送数据包则通过OUTPUT发送
  4. PREROUTING和POSTRUOITNG指的是数据包的流向

四表五链

filter表

iptables fileter是iptables防火墙的默认表,具有以下三种内建链

  1. INPUT链
  2. OUTPUT链
  3. FORWARD链
NAT表

NAT就是当内网主机访问外网,内网主机的数据包要通过路由器时,路由器将数据包中的源内网IP地址改为路由器上的公网IP地址,同时记录下该数据包的消息。反之,当外网的数据经过路由发往内网主机时,数据包中的目的IP修改为内网IP。

它具有3个内建链:

  1. PREROUTING链
  2. POSTROUTING链
  3. OUTPUT链
Mangle表

iptables mangle表用于指定如何处理数据包,他能改变TCP头中的QoS位。

它具有5个内建链:

  1. PREROUTING链
  2. POSTROUTING链
  3. OUTPUT链
  4. INPUT链
  5. FORWARD链
RAW表

iptables raw表用于处理异常,它具有2个内建链

  1. PREROUTING
  2. OUTPUT

使用规则

常用命令

-A 追加规则–>iptables -A INPUT
-D 删除规则–>iptables -D INPUT 1(编号)
-R 修改规则–>iptables -R INPUT 1 -s 192.168.12.0 -j DROP 取代现行规则,顺序不变(1是位置)
-I 插入规则–>iptables -I INPUT 1 –dport 80 -j ACCEPT 插入一条规则,原本位置上的规则将会往后移动一个顺位
-L 查看规则–>iptables -L INPUT 列出规则链中的所有规则
-N 新的规则–>iptables -N allowed 定义新的规则
-E 重命名链
-F 清空所有规则
-Z 清除链中使用的规则
-P 设置默认规则

匹配条件

-p 协议 例:iptables -A INPUT -p tcp
-s 源地址 例:iptables -A INPUT -s 192.168.1.1
-d 目的地址 例:iptables -A INPUT -d 192.168.12.1
–sport 源端口 例:iptables -A INPUT -p tcp –sport 22
–dport 目的端口 例:iptables -A INPUT -p tcp –dport 22
-i 指定入口网卡 例:iptables -A INPUT -i eth0
-o 指定出口网卡 例:iptables -A FORWARD -o eth0
-j 指定要进行的处理动作

常用动作

DROP 丢弃
REJECT 明示拒绝
ACCEPT 接受
SNAT 基于源地址的转换
DNAT 基于目标地址转换
MASQUERADE 动态伪装
MASQUERADE:源地址伪装
REDIRECT:重定向:主要用于实现端口重定向
MARK:打防火墙标记的
RETURN:返回 在自定义链执行完毕后使用返回,来返回原规则链。

案例演示

# 清空现有规则
iptables -F
# 设置默认规则为拒绝所有连结
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# 允许环回访问
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 允许其他主机ping自己主机
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
# 从内部 ping 到任何外部服务器
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

# 允许SSH连接
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 允许访问其他服务器SSH
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 允许http流量流入
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# 允许http流量流出
iptables -A OUTPUT -o eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# 允许https流量流入
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
# 允许https流量流出
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
# 限制并发流量为25
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# 端口转发,将442端口流量转发到22端口
iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22
# 如果您执行上述操作,您还需要明确允许端口 422 上的传入连接。
iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT

Firewalld

Firewalld是一款动态防火墙管理工具,是为了解决iptables的每一次规则变更都需要卸载和重新加载内核模块的问题,其底层仍然是使用iptables作为防火墙规则管理入口。

规则区域

Firewalld使用区和服务的概念来简化流量管理。zones 是预定义的规则集。网络接口和源可以分配给区。允许的流量取决于您计算机连接到的网络,并分配了这个网络的安全级别。防火墙服务是预定义的规则,覆盖了允许特定服务进入流量的所有必要设置,并在区中应用。

[root@Testnode ~]# firewall-cmd --get-zones
block dmz docker drop external home internal nm-shared public trusted work

Firewalld在区域方面遵循严格的原则:

  1. 流量只进入一个区域。
  2. 流量只流出一个区域。
  3. 区域定义了一个信任级别。
  4. 默认情况下,允许区域内流量(在同一区域中)。
  5. 默认情况下,拒绝区域内流量(从区域到区域)。

/usr/lib/firewalld/zones/ 目录存储预定义的区域,您可以立即将它们应用到任何可用的网络接口。只有在修改后,这些文件才会被拷贝到 /etc/firewalld/zones/ 目录中。预定义区的默认设置如下:

  • block

    适用于:任何传入的网络连接都会被拒绝,并对 IPv4 显示 icmp-host-prohibited 消息,对 IPv6 显示 icmp6-adm-prohibited 消息。接受:只接受从系统内启动的网络连接。

  • dmz

    适用于:DMZ 中可公开访问,且对内部网络有有限访问的计算机。接受: 只接受所选的传入连接。

  • drop

    适用于:任何传入的网络数据包都被丢弃,没有任何通知。接受:只有传出的网络连接。

  • external

    适用于:启用了伪装的外部网络,尤其适用于路由器。不信任网络上其他计算机的情况。接受: 只接受所选的传入连接。

  • home

    适用于:您主要信任网络上其他计算机的家庭环境。接受: 只接受所选的传入连接。

  • internal

    适用于:您主要信任网络上其他计算机的内部网络。接受: 只接受所选的传入连接。

  • public

    适用于:您不信任网络上其他计算机的公共区域。接受: 只接受所选的传入连接。

  • trusted

    接受:所有网络连接。

  • work

    适用于:您主要信任网络上其他计算机的工作环境。接受: 只接受所选的传入连接。

这些区中的一个被设置为 default 区。当接口连接被添加到 NetworkManager 中时,它们会被分配到默认区。安装时,firewalld 中的默认区域是 public 区域。您可以更改默认区域。

规则文件

firewalld 区配置文件包含区的信息。这些区描述、服务、端口、协议、icmp-blocks、masquerade、forward-ports 和丰富的语言规则采用 XML 文件格式。文件名必须是 *zone-name*.xml,其中 zone-name 的长度限制为 17 个字符。区域配置文件位于 /usr/lib/firewalld/zones//etc/firewalld/zones/ 目录中。

以下示例展示了允许 TCPUDP 协议的一个服务(SSH)和一个端口范围的配置:

<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>My Zone</short>
<description>Here you can describe the characteristic features of the zone.</description>
<service name="ssh"/>
<port protocol="udp" port="1025-65535"/>
<port protocol="tcp" port="1025-65535"/>
</zone>

使用案例

  1. 检查 firewalld 中的服务是否没有被允许:

    # firewall-cmd --list-services
    ssh dhcpv6-client
  2. 列出 firewalld 中所有预定义的服务:

    # firewall-cmd --get-services
    RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry ...
  3. 将服务添加到 firewalld 允许的服务的列表中:

    # firewall-cmd --add-service=<service_name>
  4. 使新设置具有持久性:

    # firewall-cmd --runtime-to-permanent
  5. 列出所有永久防火墙规则:

    # firewall-cmd --list-all --permanent
    public
    target: default
    icmp-block-inversion: no
    interfaces:
    sources:
    services: cockpit dhcpv6-client ssh
    ports:
    protocols:
    forward: no
    masquerade: no
    forward-ports:
    source-ports:
    icmp-blocks:
    rich rules:
  6. 检查 firewalld 服务的永久配置的有效性。

    # firewall-cmd --check-config
    success