curl 自定义域名解析,根据 HTTP 状态码判断网站是否正常

血衫的blog实际上对应着好些个IP,如果直接监控域名,如果某IP挂掉,也不易察觉。以下是我监控的做法,使用自定义域名解析监控:

domain="blog.kelu.org"
port="443"

curl -I -m 10 -o /dev/null -s -w %{http_code} https://$domain --resolve "$domain:$port:10.100.1.1"
  • -I 仅测试HTTP头
  • -m 10 最多查询10s
  • -o /dev/null 屏蔽原有输出信息
  • -s silent 模式,不输出任何东西
  • -w %{http_code} 控制输出
  • –resolve 解析地址

iftop 使用备忘

iftop是类似于top的实时流量监控工具。

界面表示

=>代表发送数据,<= 代表接收数据
TX:发送流量
RX:接收流量
TOTAL:总流量
Cumm:运行iftop到目前时间的总流量
peak:流量峰值
rates:分别表示过去 2s 10s 40s 的平均流量

参数

-i 指定需要检测的网卡, 如果有多个网络接口,则需要注意网络接口的选择,如:# iftop -i eth1
-B 将输出以byte为单位显示网卡流量,默认是bit
-n 将输出的主机信息都通过IP显示,不进行DNS解析 
-N 只显示连接端口号,不显示端口对应的服务名称
-F 显示特定网段的网卡进出流量  如iftop -F 192.168.85.0/24
-h 帮助,显示参数信息
-p 以混杂模式运行iftop,此时iftop可以用作网络嗅探器 ;
-P 显示主机以及端口信息
-m 设置输出界面中最上面的流量刻度最大值,流量刻度分5个大段显示  如:# iftop -m 100M
-f 使用筛选码选择数据包来计数  如iftop -f filter code
-b 不显示流量图形条
-c 指定可选的配置文件   如iftop  -c config file
-t 使用不带ncurses的文本界面,
    以下两个是只和-t一起用的:
    -s num num秒后打印一次文本输出然后退出,-t -s 60组合使用,表示取60秒网络流量输出到终端
    -L num 打印的行数
-f 参数支持tcpdump的语法,可以使用各种过滤条件。

界面参数

P      切换暂停/继续显示
h      在交互界面/状态输出界面之间切换
b      切换是否显示平均流量图形条
B      切换显示2s 10s和40s内的平均流量
T      切换是否显示每个连接的总流量
j/k    向上或向下滚动屏幕显示当前的连接信息
f      编辑筛选码
l      打开iftop输出过滤功能 ,如输入要显示的IP按回车键后屏幕就只显示与这个IP相关的流量信息
L      切换显示流量刻度范围,刻度不同,流量图形条也会不同
q      退出iftop

主机参数

n      使iftop输出结果以IP或主机名的方式显示
s      切换是否显示源主机信息
d      切换是否显示远端目标主机信息
t      切换输出模式,一行或多行

端口显示参数

N      切换显示端口号/端口号对应服务名称
S      切换是否显示本地源主机的端口信息
D      切换是否显示远端目标主机的端口信息
p      切换是否显示端口信息

输出排序参数

1/2/3  通过第一列/第二列/第三列排序
<      根据左边的本地主机名或IP地址进行排序
>      根据远端目标主机的主机名或IP地址进行排序
o      切换是否固定显示当前的连接

命令参考

  1. 启动界面

    iftop -i eth0 -PB -f tcp
    
    • -i 使用网卡eth0
    • -P 显示端口信息
    • -B 显示大B的数据,也就是byte,默认显示小b,bit。
    • -f tcp 过滤只显示tcp数据
  2. 按L,显示流量刻度

  3. 按T,显示总量

  4. 按t,合并发送接收,只显示一行

  5. 按1/2/3,按照 2/10/40s的速度进行排序

  6. 按B,查看最近2s、10s、40s的统计

  7. 按D,不显示远端目标主机的端口信息

  8. 按P,暂停刷新


iptables 使用备忘

转自 http://www.zsythink.net/archives/1199,内容有删减。

一、防火墙

防火墙大体分为主机防火墙和网络防火墙。

主机防火墙:针对于单个主机进行防护。

网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网。

网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙主外(集体), 主机防火墙主内(个人)。

从物理上讲,防火墙可以分为硬件防火墙和软件防火墙。

硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高。

软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低。

二、iptables 概念

Netfilter 是 Linux 操作系统核心层内部的一个数据包处理模块,它具有如下功能:

  • 网络地址转换(Network Address Translate)
  • 数据包内容修改
  • 数据包过滤的防火墙功能

iptables 是一个命令行工具,位于用户空间,我们用这个工具操作 netfilter。iptables并没有一个守护进程,所以不是真正意义上的服务。

2014041522224868618.jpg

iptables详解

iptables 有四表五链的概念。我一般这么去理解,表是逻辑上的分类(或简单理解成数据库的表),链是物理上的分类,在数据包生命周期各个阶段的处理。

报文在匹配iptables的规则的时候,是按照固定的顺序进行的,既不是按照表的顺序执行,也不是按照检查点的顺序执行。

structure-of-iptables中做了非常详细的说明。

五链(本机收到的请求报文的流向):

  • 到本机某进程的报文:PREROUTING –> INPUT,具体来说是:

    raw.PREROUTING -> mangle.PREROUTING -> nat.PREROUTING -> mangle.INPUT -> filter.INPUT
    
  • 由本机转发的报文:PREROUTING –> FORWARD –> POSTROUTING,具体来说是:

    raw.PREROUTING -> mangle.PREROUTING -> nat.PREROUTING -> mangle.FORWARD -> filter.FORWARD -> mangle.POSTROUTING -> nat.POSTROUTING
    
  • 由本机的某进程发出报文(通常为响应报文):OUTPUT –> POSTROUTING

    raw.OUTPUT -> mangle.OUTPUT -> nat.OUTPUT -> filter.OUTPUT -> mangle.POSTROUTING ->nat.POSTROUTING
    

四表:

  • filter表:控制本机数据包的进出,可看做防火墙(默认表);内核模块:iptables_filter
  • nat表:network address translation,网络地址转换功能;内核模块:iptable_nat
  • mangle表:拆包并修改标志位,重新封装;iptable_mangle
  • raw表:关闭nat表上启用的连接追踪机制;iptable_raw

表和链之间的包含关系如下:

filter: 
    Chain INPUT
    Chain FORWARD
    Chain OUTPUT

nat:
    Chain PREROUTING
    Chain INPUT
    Chain OUTPUT
    Chain POSTROUTING

mangle:
    Chain PREROUTING
    Chain INPUT
    Chain FORWARD
    Chain OUTPUT
    Chain POSTROUTING

raw:
    Chain PREROUTING
    Chain OUTPUT

image-20201010104549340

为了更方便的管理,我们还可以在某个表里面创建自定义链,将针对某个应用程序所设置的规则放置在这个自定义链中,但是自定义链接不能直接使用,只能被某个默认的链当做动作去调用才能起作用。

三、iptables 规则的增删查改

iptables命令的语法如下:

iptables -t [表名]  
         <-A | I | D | R> 链名 
         [规则编号] 
         [-i | o 网卡名称] 
         [-p 协议] 
         [-s 源ip地址 | 源子网] 
         [--sport 源端口] 
         [-d 目标ip地址 | 目标子网] 
         [--dport 目标端口] 
         <-j target> 
  • -A新增一条规则,该规则增加到规则列表的最后一行,使用该参数时不能使用规则编号

  • -I插入一条规则,如果指定了规则编号,原本该位置上的规则会向后顺序移动,如果没有指定规则编号,将在第一条规则前插入

  • -D从规则列表中删除一条规则,可以输入完整的规则进行删除,也可以直接指定规则编号进行删除

  • -R替换某条规则,规则被替换时不会改变其顺序,必须指定要替换的规则编号

  • 规则编号 规则列表的第一条规则的编号为1

  • -i指定数据包进入的网卡,-o指定数据包输出的网卡

  • -p指定规则应用的协议,可以是tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh

  • -s指定源主机的IP地址或子网地址,格式为address[/mask][,...]

  • -d指定指定目标主机的IP地址或子网地址,格式为address[/mask][,...]

  • -j target
    

    --jump target
    

    决定符合条件的包到何处去。target可以指定另一个链,常用的Target/Jumps包含:

    • ACCEPT表示允许包,即满足匹配条件的包被允许,并且不会再匹配当前链中的其他规则或同一个表内的其他规则,但这个包还会通过其他表中的链
    • DROP表示丢弃包,即将符合条件的包丢弃,不会再向下走。效果就是包被阻塞,不会像发送者返回任何信息。
    • REJECT表示拒绝包,REJECT和DROP类似,在阻塞包时会向发送者返回错误信息。
    • REDIRECT表示将数据包重定向到本机或另一台主机的某个端口,通常用来实现透明代理或对外开放内网的某些服务
    • SNAT源地址转换,即改变数据包的源地址
    • DNAT目标地址转换,即改变数据包的目标的地址
    • LOG将符合规则的数据包相关规则信息记录在日志中,便于管理员分析问题

在iptables的世界中,常用的匹配条件是报文的”源地址”、”目标地址”、”源端口”、”目标端口”等,常用的动作有ACCEPT(接受)、DROP(丢弃)、REJECT(拒绝)。

1 查询规则

标准用法:

iptables -t filter -L INPUT
  • -t: table,选择表,默认 filter表
  • -L: List,显示链,默认 全部链,区分大小写。

iptables详解

显示的信息为:

  • target:规则对应的target,往往表示规则对应的”动作”,即规则匹配成功后需要采取的措施。
  • prot:表示规则对应的协议,是否只针对某些协议应用此规则。
  • opt:表示规则对应的选项。
  • source:表示规则对应的源头地址,可以是一个IP,也可以是一个网段。
  • destination:表示规则对应的目标地址。可以是一个IP,也可以是一个网段。

其它常用参数:

  • -v: 显示更多属性信息
    • pkts:对应规则匹配到的报文的个数。
    • bytes:对应匹配到的报文包的大小总和。
    • in:表示数据包由哪个接口(网卡)流入,我们可以设置通过哪块网卡流入的报文需要匹配当前规则。
    • out:表示数据包由哪个接口(网卡)流出,我们可以设置通过哪块网卡流出的报文需要匹配当前规则。
  • -n: source和destination中不对 IP 地址进行解析,直接显示IP地址。
  • –line-numbers: 显示规则的编号

iptables详解

头部Chain INPUT后面有一串括号括起来的内容,具体含义为:

  • policy表示当前链的默认策略,上图的默认策略为ACCEPT
  • packets表示当前链(上图为INPUT链)默认策略匹配到的包的数量,0 packets表示默认策略匹配到0个包。
  • bytes表示当前链默认策略匹配到的所有包的大小总和。(使用 -x 参数可以显示精确计数值)

2 删除规则

清空 filter 表 INPUT 链的规则:

iptables -F INPUT
  • -F:Flush,清空某链条,默认全部链条。
iptables -t filter -D INPUT 3
  • -D: delete ,删除某行规则。

3 增加规则

注意,规则的前后顺序很重要!匹配到前一条,就会按照前一条的动作执行了,很有可能不会执行后面的规则条目了。

iptables详解

与查询规则类似:

iptables -t filter -I INPUT ! -s xxx.xxx.xxx.xxx/xx -j DROP
  • -t:table,选择表,默认为filter表
  • -I: Insert,插入链的头部
  • -A: Append,插入链的尾部
  • -s: source,源地址
  • -j: jump,条件匹配时的动作
  • !: 条件取反

4 修改规则

实际上修改规则命令我平时几乎不用,宁愿先删除规则,再添加。

iptables详解

iptables -t filter -R INPUT 1 -s xxx.xxx.xxx.xxx -j DROP
  • -R: replace,选择链条 第几条。

5 恢复、保存规则

上文中的iptables的修改都是临时性的,系统重启后就会失效。为了确保重启后规则和我们预设的一致,可以配置一个iptables的rules文件,基于这个文件进行配置变更,通过恢复再保存的方式,进行配置管理。

# 预先将规则写入/etc/iptables.test.rules 文件
echo "/sbin/iptables-restore < /etc/iptables.up.rules" > /etc/network/if-pre-up.d/iptables && chmod +x /etc/network/if-pre-up.d/iptables

iptables-restore < /etc/iptables.test.rules;
iptables-save > /etc/iptables.up.rules;

6、处理动作

处理动作在iptables中被称为target(这样说并不准确,我们暂且这样称呼),动作也可以分为基本动作和扩展动作。

此处列出一些常用的动作,之后的文章会对它们进行详细的示例与总结:

ACCEPT:允许数据包通过。

DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。

REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。

SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。

MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。

DNAT:目标地址转换。

REDIRECT:在本机做端口映射。

LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。

7. 匹配条件

当一条规则中存在多个匹配条件时,报文必须同时满足这些条件,才算做被规则匹配。

  1. IP地址 -s/-d

    可以使用”叹号”进行取反,也能够同时指定多个IP地址,使用”逗号”隔开。地址包括源地址 -s 和目的地址 -d

    iptables -t filter -I INPUT ! -s 10.0.0.0/16 -j DROP
    
  2. 协议类型 -p

    -p: 默认为全部,支持 tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh

  3. 网卡接口 -i/-o

    -i选项只能用于PREROUTING链、INPUT链、FORWARD链,它只是用于判断报文是从哪个网卡流入的,所以只能在上图中”数据流入流向”的链中与FORWARD链中存在,OUTPUT链与POSTROUTING链,都不能使用-i选项。

    当主机有多块网卡时,可以使用-o选项,匹配报文将由哪块网卡流出。-o选项只能用于FORWARD链、OUTPUT链、POSTROUTING链中。

  4. 扩展匹配

    基本匹配条件我们可以直接使用,而如果想要使用扩展匹配条件,需要指定相应的扩展模块。

    1. 端口 –dport/–sport,使用模块tcp。

      -p tcp -m tcp --dport 22:25
      

      -m tcp表示使用tcp扩展模块(模块同名可省)

    2. multiport 可指定多个离散的端口

      -p tcp -m kultiport --dports 22,36,88
      
    3. iprange 指定”一段连续的IP地址范围”

      iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP
      iptables -t filter -I OUTPUT -m iprange --dst-range 192.168.1.127-192.168.1.146 -j DROP
      iptables -t filter -I INPUT -m iprange ! --src-range 192.168.1.127-192.168.1.146 -j DROP
      
    4. string 指定要匹配的字符串

      iptables -t flilter -I INPUT -m string --algo bm --string "ooxx" -j ACCEPT
      
    5. time 规定时间

      很少用

      iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
      iptables -t filter -I OUTPUT -p tcp --dport 443 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
      iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --weekdays 6,7 -j REJECT
      iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --monthdays 22,23 -j REJECT
      iptables -t filter -I OUTPUT -p tcp --dport 80  -m time ! --monthdays 22,23 -j REJECT
      iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays 6,7 -j REJECT
      iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --weekdays 5 --monthdays 22,23,24,25,26,27,28 -j REJECT
      iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --datestart 2017-12-24 --datestop 2017-12-27 -j REJECT
      
    6. connlimit,限制每个IP地址同时链接到server端的链接数量

      iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
      iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j REJECT
      iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 27 -j REJECT
      
      • connlimit-above 连接数
      • connlimit-mask 掩码
    7. limit,使用令牌桶算法,对”报文到达速率”限制。

      iptables -t filter -I INPUT -p icmp -m limit --limit-burst 3 --limit 10/minute -j ACCEPT
      iptables -t filter -A INPUT -p icmp -j REJECT
      
      • limit 10/minute: 1分钟生成10个令牌放行。
        • minute
        • second
        • hour
        • day
      • –limit-burst 3:最多同时存在3个令牌。
    8. tcp-flags,根据tcp请求头标志位限制。

      很少用,不解释了。

      iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT
      iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECT
      iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECT
      iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags ALL SYN,ACK -j REJECT
      
    9. udp 很少用,不解释了。

    10. icmp 很少用,不解释了。

    11. state 常用。

      iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
      

      对于state模块的连接而言,”连接”其中的报文可以分为5种状态,报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED

      NEW:连接中的第一个包,状态就是NEW,我们可以理解为新连接的第一个包的状态为NEW。

      ESTABLISHED:我们可以把NEW状态包后面的包的状态理解为ESTABLISHED,表示连接已建立

      RELATED:关联包

      INVALID:无法识别,或者这个包没有任何状态

      UNTRACKED:报文未被追踪,无法找到相关的连接。

    12. recent,用于限制一段时间内的连接数。recent模块在 iptables 里面维护了一个地址列表,这个地址列表可以通过”–set”、”–update”、”–rcheck”、”–remove”四种方法来修改列表。

      本部分参考链接

      –name 设定列表名称,即设置跟踪数据库的文件名. 默认DEFAULT; –rsource 源地址,此为默认。 只进行数据库中信息的匹配,并不会对已存在的数据做任何变更操作; –rdest 目的地址; –seconds 指定时间内. 当事件发生时,只会匹配数据库中前”几秒”内的记录,–seconds必须与–rcheck或–update参数共用; –hitcount 命中次数. hits匹配重复发生次数,必须与–rcheck或–update参数共用; –set 将地址添加进列表,并更新信息,包含地址加入的时间戳。 即将符合条件的来源数据添加到数据库中,但如果来源端数据已经存在,则更新数据库中的记录信息; –rcheck 检查地址是否在列表,以第一个匹配开始计算时间; –update 和rcheck类似,以最后一个匹配计算时间。 如果来源端的数据已存在,则将其更新;若不存在,则不做任何处理; –remove 在列表里删除相应地址,后跟列表名称及地址。如果来源端数据已存在,则将其删除,若不存在,则不做任何处理;

      例1:限制无法ssh直接连接服务器,需先用较大包ping一下,此时在15秒内才可以连接上:

      iptables -P INPUT DROP
      iptables -A INPUT -s 127.0.0.1/32 -j ACCEPT
      iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
      iptables -A INPUT -p icmp --icmp-type 8 -m length --length 128 -m recent --set --name SSHOPEN --rsource -j ACCEPT
      iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
      iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 15 --name SSHOPEN --rsource -j ACCEPT
      

      例2: 限制每ip在一分钟内最多对服务器只能有8个http连接

      iptables -I INPUT -p tcp --dport 80 -d 192.168.10.10 -m state --state NEW -m recent --name httpuser --set
      iptables -A INPUT -m recent --update --name httpuser --seconds 60 --hitcount 9 -j LOG --log-prefix 'HTTP attack: '
      iptables -A INPUT -m recent --update --name httpuser --seconds 60 --hitcount 9 -j DROP
      

      例3: SSH连接,每个IP每小时只限连接5次

      -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 3600 --hitcount 5 -j DROP
      -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --set -j ACCEPT
      

      或:

      -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT                            //必须添加这个前提条件才能生效!
      -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --set
      -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 3600 --hitcount 5 -j DROP
      

      例4: SSH 开门暗语

      # 记录日志,前缀SSHOPEN:
      iptables -A INPUT -p tcp --dport 50001 --syn -j LOG --log-prefix "SSHOPEN: "
             
      # 目标端口tcp 50001的新数据设定列表为sshopen返回TCP重置,并记录源地址。
      iptables -A INPUT -p tcp --dport 50001 --syn -m recent --set --name sshopen --rsource -j REJECT --reject-with tcp-reset
             
      # 开启SSH端口,15秒内允许记录的源地址登录SSH。
      iptables -A INPUT -p tcp --dport 22 --syn -m recent --rcheck --seconds 15 --name sshopen --rsource -j ACCEPT
             
      #开门钥匙
      nc host 50001
      telnet host 50001
      nmap -sS host 50001
      

      例5: SSH 开门暗语2

      #记录日志,前缀SSHOPEN:
      iptables -A INPUT -p icmp --icmp-type 8 -m length --length 78 -j LOG --log-prefix "SSHOPEN: "
             
      #指定数据包78字节,包含IP头部20字节,ICMP头部8字节
      iptables -A INPUT -p icmp --icmp-type 8 -m length --length 78 -m recent --set --name sshopen --rsource -j ACCEPT
             
      iptables -A INPUT -p tcp --dport 22 --syn -m recent --rcheck --seconds 15 --name sshopen --rsource -j ACCEPT
             
      #开门钥匙
      ping -s 50 ip    #linux主机的ip
      ping -l 50 ip     #windows主机的ip
      

四、自定义链

自定义链是为了更好管理iptables规则而存在的。自定义链并不能直接使用,被默认链引用才能够使用。

  1. 创建自定义链

    iptables -t filter -N KELU
    
  2. 引用自定义链

    iptables -t filter -I INPUT -p tcp --dport 80 -j KELU
    
  3. 重命名自定义链

    iptables -E KELU YUKI
    
  4. 删除自定义链

    删除自定义链需要满足两个条件

    1、自定义链没有被引用

    2、自定义链中没有任何规则

    iptables -X KELU
    

五、iptables 动作

ACCEPT、DROP、REJECT、LOG、SNAT、DNAT、MASQUERADE、REDIRECT

前三个没什么好记录的。如果想要NAT功能能够正常使用,需要开启Linux主机的核心转发功能。

echo 1 > /proc/sys/net/ipv4/ip_forward

LOG

LOG动作会将报文的相关信息记录在/var/log/message文件中,LOG动作只负责记录匹配到的报文的相关信息,不负责对报文的其他处理。一般放到链条的最后,记录被拒绝的请求。

LOG动作也有自己的选项

  • –log-level选项可以指定记录日志的日志级别,可用级别有emerg,alert,crit,error,warning,notice,info,debug。
  • –log-prefix选项可以给记录到的相关信息添加”标签”之类的信息,以便区分各种记录到的报文信息,方便在分析时进行过滤。
  • 注:–log-prefix对应的值不能超过29个字符。
# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables input denied: " --log-level 7
-A FORWARD -m limit --limit 5/min -j LOG --log-prefix "iptables forward denied: " --log-level 7

SNAT

网络内部的主机可以借助SNAT隐藏自己的IP地址,共享公网IP

iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j  SNAT --to-source 192.168.1.146

DNAT

配置DNAT,可以通过公网IP访问局域网内的服务。

iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 8080 -j DNAT --to-destination 10.1.0.1:80
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP

MASQUERADE

可以把MASQUERADE理解为动态的、自动化的SNAT,如果没有动态SNAT的需求,没有必要使用MASQUERADE,因为SNAT更加高效。

当我们拨号网上时,每次分配的IP地址往往不同,不会长期分给我们一个固定的IP地址,如果这时,我们想要让内网主机共享公网IP上网,就会很麻烦,因为每次IP地址发生变化以后,我们都要重新配置SNAT规则,这样显示不是很人性化,我们通过MASQUERADE即可解决这个问题,MASQUERADE会动态的将源地址转换为可用的IP地址,其实与SNAT实现的功能完全一致,都是修改源地址,只不过SNAT需要指明将报文的源地址改为哪个IP,而MASQUERADE则不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址

iptables -t nat -I POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE

REDIRECT

使用REDIRECT动作可以在本机上进行端口映射

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

参考资料


如何获取容器的 pid 信息

共有两种场景,一种是想知道容器的pid,第二种通过宿主机确定了某pid,想确定属于哪个容器。

对于场景一:

docker inspect <CONTAINER ID> 可以获取容器的pid。配合以下命令可以快速得到容器的pid:

1595217719704

该方法得到的容器内的 pid=1 的进程。

image-20200719171414650

对于场景二:

使用脚本 DingGuodong/LinuxBashShellScriptForOps

该脚本可以查找进程树:

1.查找pid所对应的容器id,并打印容器的详细信息

2.获取此进程的进程树和含有命令行的进程树

image-20200719171524191

参考资料


在shell脚本中使用系统 alias - xspace

原文:在shell脚本中使用alias,有改动。

Linux shell有交互式与非交互式两种工作模式。我们日常使用shell输入命令得到结果的方式是交互式的方式,而shell脚本使用的是非交互式方式。

shell提供了alias功能来简化我们的日常操作,使得我们可以为一个复杂的命令取一个简单的名字,从而提高我们的工作效率。在交互式模式下,shell的alias扩展功能是打开的,因此我们可以键入自己定义的alias别名来执行对应的命令。

但是,在非交互式模式下alias扩展功能默认是关闭的,此时仍然可以定义alias别名,但是shell不会将alias别名扩展成对应的命令,而是将alias别名本身当作命令执行,如果shell内置命令和PATH中均没有与alias别名同名的命令,则shell会“抱怨”找不到指定的命令。

那么,有没有办法在非交互式模式下启用alias扩展呢?答案是使用shell内置命令shopt命令来开启alias扩展选项。shopt是shell的内置命令,可以控制shell功能选项的开启和关闭,从而控制shell的行为。shopt的使用方式如下:

shopt -s opt_name         Enable (``set``) opt_name.
shopt -u opt_name         Disable (``unset``) opt_name.
shopt opt_name          Show current status of opt_name.

alias扩展功能的选项名称是expand_aliases,我们可以在交互式模式下查看此选项是否开启:

sw@gentoo ~ $ shopt expand_aliases
expand_aliases on
sw@gentoo ~ $

在非交互式模式下alias扩展功能默认是关闭的,但是我们可以用shopt来将其开启。

如果我们要让执行shell脚本的子shell读取.bashrc的话,有两种方式可以达到这样的效果

  1. 给shell脚本第一行的解释器加上参数

    #!/bin/bash --login
    
  2. 在脚本中主动source ~/.bashrc


比较kube-proxy模式 iptables或IPVS? - tigera

这是calico母公司的一篇分享博客。讲得挺好,转载过来。机翻警告⚠️

kube-proxy 是 Kubernetes部署的关键组件。它的作用是使发往service 的流量(通过群集IP和节点端口)负载均衡到正确的后端 Pod。Kube-proxy可以三种模式之一运行,每种模式都使用不同的数据平面技术实现: userspaceiptablesIPVS

userspace非常陈旧,缓慢,不建议使用!但是,如何权衡使用iptables还是IPVS模式呢?在本文中,我们将比较两者,评估它们在真正的微服务环境中的性能,并解释何时选择一个与另一个。

首先,我们将从两种模式的背景知识入手,然后深入了解下面的测试和结果…

背景:iptables代理模式

iptables是一种Linux内核功能,旨在成为高效的防火墙,并具有足够的灵活性来处理各种常见的数据包操作和过滤需求。它允许将灵活的规则序列附加到内核的数据包处理管道中的各种钩子上。在iptables模式下,kube-proxy 将规则附加到“ NAT pre-routing” 钩子上以实现 NAT和负载平衡功能。它的工作原理很简单,并且与其他也使用 iptables 进行过滤的程序(例如Calico!)一同运行而不互相影响。

但是,kube-proxy 下增加的iptables条目空间复杂度是 O(n),条目数在 service的数量和每个 service 背后的 Pod的数量增长而成比例地增长。

背景:IPVS代理模式

IPVS是专门用于负载平衡的Linux内核功能。在IPVS模式下,kube-proxy 对IPVS负载均衡器进行编程,而不是使用iptables。IPVS 专 为负载均衡大量服务而设计;它优化了API和查找目标的方式,而不是顺序查找。

IPVS模式下的kube-proxy的连接处理的计算复杂度为O(1)。换句话说,在大多数情况下,其连接处理性能将保持恒定,与群集大小无关。

此外,作为专用的负载平衡器,IPVS拥有多种不同的调度算法,例如循环调度,最短期望延迟,最少连接和各种哈希方法。iptables 中的 kube-proxy 只能使用随机等价选择算法。

IPVS的一个潜在缺点是,与正常情况下的数据包相比,由IPVS处理的数据包通过iptables filter hooks的路径非常不同。如果您打算将IPVS与其他使用iptables的程序一起使用,则需要研究它们是否可以一起正常工作。

性能比较

名义上kube-proxy在iptables模式下的连接处理为O(n),在IPVS模式下为O(1)。但是,在微服务场景中的实际表现怎么样呢?

在大多数情况下,在应用程序和微服务的上下文中,当涉及到kube-proxy的性能时,您可能会关心两个关键属性:

  1. 对往返响应时间的影响。 当一个微服务对另一个微服务进行API调用时,第一个微服务平均向第二个微服务发送请求并从第二个微服务接收响应的时间为多长时间?
  2. 对总CPU使用率的影响。 在支持微服务(包括kube-proxy)所需的所有进程中,运行微服务时主机的总CPU使用量是多少,包括用户空间和内核/系统使用情况?

为了说明这一点,我们在专用节点上运行一个专门用来发请求的pod,它每秒生成1000个请求,所有的请求打到一个service上,这个service后边挂着10个pod。然后,我们在iptables和IPVS模式下,使用若干个的Kubernetes service(每个服务有10个Pod支持),最多10,000个service(带有100,000个endpoints)来测量客户端节点上的性能。对于微服务,我们使用了用golang编写的简单测试工具作为客户端微服务,并用标准NGINX作为服务器微服务的后端容器。

往返响应时间

考虑往返响应时间时,了解连接和请求之间的区别很重要。通常,大多数微服务将使用持久性或“ keepalive”连接,这意味着每个连接可在多个请求中重用,而不是每个请求都需要一个新的连接。这很重要,因为大多数新连接都需要通过网络进行三向TCP握手(这需要时间),Linux网络堆栈中的更多处理(这需要更多时间和CPU)。

为了说明这些差异,我们在有和没有保持连接的情况下进行了测试。对于保持连接,我们使用了NGINX的默认配置,该配置使每个连接保持活动状态,最多可重复使用100个请求。请参见下图,请注意,响应时间越短越好。

img

图表显示了两个关键事项:

  • 在获得超过1,000个服务(10,000个后端Pod)之前,iptables和IPVS之间的平均往返响应时间的差异微不足道。
  • 仅当不使用keepalive连接时,才能确定平均往返响应时间的差异。即当为每个请求使用新连接时。

对于iptables和IPVS模式,kube-proxy的响应时间开销与建立连接相关,而不是与您在这些连接上发送的数据包或请求的数量有关。这是因为Linux使用的连接跟踪(conntrack)能够非常有效地将数据包与现有连接进行匹配。如果数据包在conntrack中匹配,则无需通过kube-proxy的iptables或IPVS规则来确定如何处理它。Linux conntrack是您的朋友! (几乎所有时间……。请关注我们的下一篇博客文章“当Linux conntrack不是您的朋友时!”)

值得注意的是,在此示例中,对于“服务器”微服务,我们使用NGINX Pod服务于一个小的静态响应主体。许多微服务需要做的工作远远超过此,这将导致相应的响应时间更长,这意味着与该图表相比,用于kube-proxy处理的增量将占响应时间的百分比较小。

最后有一个奇怪的解释:如果IPVS中新连接的处理是O(1)复杂性,为什么在10,000个服务上IPVS的非Keepalive响应时间会变慢?我们需要做更多的挖掘工作才能真正深入了解此问题,但其中一个因素是,由于主机上CPU使用率的增加,整个系统的运行速度会变慢。这使我们很好地讨论了下一个主题。

总CPU

为了说明总的CPU使用率,下表重点介绍了不使用持久/ keepalive连接的最坏情况,在这种情况下,kube-proxy连接的处理开销影响最大。

img

图表显示了两个关键事项:

  • iptables和IPVS之间的CPU使用率差异不明显,直到获得超过1,000个服务(带有10,000个后端Pod)为止。
  • 在10,000个服务(具有100,000个后端pod)的情况下,使用iptables的CPU的增加量约为内核的35%,而使用IPVS的CPU的增加量约为内核的8%。

影响此CPU使用模式的主要因素有两个。

第一个贡献者是默认情况下,kube-proxy以30秒的间隔对所有服务进行内核重新编程。这解释了为什么IPVS模式在CPU上会略有增加,即使IPVS对新连接的处理名义上的复杂度为O(1)。此外,在较旧内核版本中对iptables进行重新编程的API比现在慢得多。因此,如果您在iptables模式下使用带有kube-proxy的较旧内核,则CPU增长将比该图表还要高。

第二个原因是kube-proxy使用iptables或IPVS处理新连接所花费的时间。对于iptables,名义上是O(n)。在大量服务中,这极大地影响了CPU使用率。例如,在10,000个服务(带有100,000个后端Pod)上,iptables为每个新连接执行约20,000个规则。请记住,尽管在此图表中,我们显示的是微服务的最坏情况,该微服务针对每个请求使用新的连接。如果我们使用NGINX的默认keepalive(每个连接100个请求),那么kube-proxy的iptables规则执行的频率将减少100倍,从而大大减少了使用iptables而不是IPVS可能对CPU造成的影响,降低到接近内核的2%。

值得注意的是,本示例中使用的“客户端”微服务只是丢弃了从“服务器”微服务收到的每个响应。真正的微服务将需要做的工作远不止于此,这将增加此图表中的基本CPU使用率,但不会改变与服务数量相关的CPU绝对增加量。

结论

kube-proxy的IPVS模式可扩展到超过1,000个服务,可以提供一些不错的性能改进。您的工作量可能会有所不同,但是作为一般指南,对于使用持久性“ keepalive”风格连接且在现代内核上运行的微服务,其收益可能相对较小。对于不使用持久连接的微服务,或者在较旧的内核上运行时,将kube-proxy切换到IPVS模式将是一个不错的选择。

与性能无关,如果您需要比kube-proxy的iptables模式随机负载平衡更复杂的负载平衡调度算法,则还应该考虑使用IPVS模式。

如果不确定IPVS是否会为您取胜,请在iptables模式下坚持使用kube-proxy。它在生产中进行了更多的强化,尽管它并不完美,但您可以说这是默认设置,这是有原因的。

后记:比较kube-proxy和Calico对iptables的使用

在本文中,我们已经看到kube-proxy对iptables的使用会如何在非常大的范围内导致性能影响。有时我会被问到为什么Calico没有同样的挑战。答案是,Calico对iptables的使用与kube-proxy的显着不同。Kube-proxy使用非常长的规则链,该规则链与群集大小大致成比例增长,而Calico使用非常短的优化规则链并广泛使用ipset,ipset的查找与大小无关。

为了更好地理解这一点,下表显示了kube-proxy与Calico每次连接执行的iptables规则的平均数量,假设集群中的节点平均托管30个Pod,集群中的每个Pod平均拥有3个网络策略适用于它。

img

即使在具有10,000个服务和100,000个后端Pod的完全扩展集群中运行时,Calico每个连接也只能执行与kube-proxy在200个后端Pod上执行20个服务时大致相同数量的iptables规则。换句话说,Calico对iptables的使用规模!