跳到主要内容

Iptables 实践指南

· 阅读需 8 分钟

iptables

1. 表与链

  • iptables是4表伍链
  • 4表:filter表 nat表 raw表 mangle表
  • 伍链:INPUT OUTPUT FORWARD PREROUTING POSTROUTING

2. 表的说明

2.1 filter表
  • 防火墙:屏蔽或准许 端口 ip
filter表强调:主要和主机自身相关,真正负责主机防火墙功能(过滤流入流出主机的数据包)filter表示iptables默认使用的表,这个表定义了三个链(chains)企业工作场景:主机防火墙
INPUT负责过滤所有目标地址是本机地址的数据包,通俗来说:就是过滤进入主机的数据包
FORWARD负责转发刘静主机的数据包。起转发的作用,和NAT关系很大,后面会详细介绍LVS NAT模式,net.ipv4.ip_forward=0
OUTPUT处理所有源地址是本机地址的数据包,通俗来讲:就是处理从主机发出的数据包。
2.2 nat表
  • 实现nat功能
    • 实现共享上网(内网服务器上外网)
    • 端口映射和ip映射
nat负责网络地址转换的,即来源与目的IP地址和port的转换。
应用:和主机本身无关,一般用于局域网共享上网或者特殊的端口转换服务相关。
工作场景:
1. 用于企业路由(zebra)或网关(iptables),共享上网(POSTROUTING)
2. 做内部外部IP地址一对一映射(dmz),硬件防火墙映射IP到内部服务器,ftp服务(PREROUTING)
3. WEB,单个端口的映射,直接映射80端口(PREOUTING)这个表定义了3个链,nat功能相当于网络的acl控制。和网络交换机acl类似。
OUTPUT和主机放出去的数据包有关,改变主机发出数据包的目的地址。
PREROUTING在数据包到达防火墙时,进行路由判断之前执行的规则,作用是改变数据包的目的地址、目的端口等
例如:把公网IP:XXX.XXX.XXX.XXX映射到局域网的XX.XX.XX.XX服务器上。
如果是web服务,可以将80转换为局域网的服务器9000端口上
POSTROUTING在数据包离开防火墙时进行路由判断之后执行的规则,作用改变数据包的源地址,源端口等。
例如:默认笔记本和虚拟机都是局域网地址,在出网的时候被路由器将源地址改为了公网地址。
生产应用:局域网共享上网。

3. 环境准备及命令

3.1 iptables 服务安装,环境配置
# 安装服务
yum install -y iptables-servicesR

# 加载防火墙相关模块到内核中
cat >>/etc/rc.local<<EOF
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
EOF

# 关闭系统自带的firewalld防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service

# 启动iptables,并添加开机自动启
systemctl start iptables.service
systemctl enable iptables.service
3.2 iptables 相关命令
# 查看iptables规则
iptables -nL

参数含义
-L显示表中的所有规则
-n不要把端口或ip反向解析为服务名或域名
-t指定表 不指定时默认是filter表
-Aappend追加 加入准许类规则 使用-A
-Ddelete 删除 -D INPUT 1
-Iinsert 拒绝类规则放在所有规则最上面 拒绝类 -I

参数含义
-p协议protocal tcp/udp/icmp/all
--dport目标端口 dest destination 指定端口 加上协议-p tcp
--sport源端口 source源
-s--source 源ip
-d--destination 目标ip
-m指定模块 multiport
-iinput 输入的时候 从哪个网卡进来
-ooutput输出的时候 从哪个网卡出去

参数含义
-j满足条件后的动作:DROP/ACCEPT/REJECT
DROP REJECT 拒绝
DROP 把数据丢掉 不会返回信息给 用户
REJECT 拒绝 返回拒绝信息

参数含义
-F清除所有规则,不会处理默认的规则
-X删除用户自定义的链
-Z链的计数器清零 (数据包计数器与数据包字节计数器)

3.3 配置filter表规则
  • 正式配置之前先清空规则
iptables -F
iptables -X
iptables -Z
3.3.1 禁止访问22端口
iptables -t filter -I INPUT -p tcp --dport 22 -j DROP
3.3.2 显示规则编号
iptables -nL --lint-number
3.3.3 删除第1编号的规则
iptables -D INPUT 1   # 精确删除规则,可以用此方法
3.3.4 封ip 屏蔽某个ip(属于源ip)
iptables -I INPUT -s 10.0.0.7 -j DROP
3.3.5 禁止网段连入(禁止10.0.0.0/24网段访问 8888 端口)
iptables -I INPUT -s 10.0.0.0/24 -p tcp --dport 8888 -j DROP
3.3.6 只允许指定网段连入(允许10.0.0.0网段)
# 方法1:利用 ! 
# 只准许 10.0.0.0/24 访问,除了10.0.0.0/24 都拒绝
iptables -I INPUT ! -s 10.0.0.0/24 -j DROP

# 方法2: 修改链默认规则 修改为拒绝 添加准许
# 先配置准许规则,再修改默认规则,不然会将自己屏蔽
iptables -A INPUT -s 10.0.0.0/24 -j ACCEPT
iptables -P INPUT DROP

# 将默认规则改回允许
iptables -P INPUT ACCEPT
3.3.7 指定多个端口拒绝访问(拒绝8888 9999)
iptables -I INPUT -P tcp --dport 8888 -j DROP
iptables -I INPUT -p tco --dport 9999 -j DROP
3.3.8 同时指定多个端口拒绝访问(拒绝80和443)
iptables -I INPUT -p tcp -m multiport 80,443 -j DROP
3.3.9 同时指定连续端口拒绝访问(1到1024)
# 如果是连续端口,可以不加-m multiport
iptables -I INPUT -p tcp --dport 1:1024 -j DROP

4. 匹配ICMP类型

  • ICMP (Internet Control Message Protocol) Internet控制报文协议 ping
  • 整个网站的核心部分可以拒绝ping
4.1 通过防火墙规则,控制禁止被ping
iptables -I INPUT -p icmp --icmp-type 8 -j DROP
4.2 通过内核参数,控制禁止被ping
# 修改为1,禁止被ping;修改为0,允许被ping
[root@m01 ~]# cat /etc/sysctl.conf
#/proc/sys/net/ipv4/icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 1

# sysctl -p 生效
[root@m01 ~]# sysctl -p
net.ipv4.icmp_echo_ignore_all = 1
4.3 匹配网络状态(TCP/IP连接状态)
  • -m state --state

    NEW:已经或将启动新的连接

    ESTABLISHED:已建立的连接

    RELATED:正在启动的新连接

    INVALID:非法或无法识别的

    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
4.4 限制并发及速率
  • -m limit 限制模块
# 前5个正常,之后按每6秒的速度生成数据包,--limit-burst后不接数字时默认为5
iptables -I INPUT -p icmp -m limit --limit 10/minute --limit-burst 5 -j ACCEPT
iptables -A INPUT -p tcp --dport -j ACCEPT
iptables -P INPUT DROP

5. 防火墙规则的保存与恢复

  • iptables-save 默认输出到屏幕,后接文件可备份规则到文件

  • iptables-restore 后接文件标准输入 可恢复规则

    # 写入到/etc/sysconfig/iptables
    iptables-save >/etc/sysconfig/iptables

    # 从备份文件恢复规则
    iptables-restore </etc/sysconfig/iptables

    # systemctl restart iptables 时将默认从/etc/sysconfig/iptables读取配置,如果手动用iptables-restore恢复可以指定任意备份文件

6. 实际生产用法

# 允许22端口访问
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 允许本机回环lo接口数据流量流出与流入
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# 放行80 443端口
iptables -A INPUT -m multiport -p tcp --dport 443,80 -j ACCEPT

# 配置默认规则
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 允许需要的网段访问,包括VPN网段
iptables -A INPUT -s 10.0.0.0/24 -j ACCEPT
iptables -A INPUT -s 172.16.1.0/24 -j ACCEPT

# 添加网络状态
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 配置完成后保存配置
iptables-save >/root/online.iptables

7. nat

  • 共享上网
  • 端口转发/端口映射
  • ip映射
7.1 查看nat表
iptables -t nat -nL
7.2 共享上网
# 修改的是POSTROUTING链      源ip是172.16.1.0/24  经过防火墙处理  修改为10.0.0.61
iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j SNAT --to-source 10.0.0.61

# 修改eth0,将ONBOOT=yes改为NOBOOT=no

# 修改eth1,增加GATEWEY=172.16.1.61;增加DNS1=223.5.5.5

#重启网卡

# 修改/etc/sysctl.conf
net.ipv4.ip_forward = 1

# 重新载入sysctl变量
sysctl -p
7.3 端口映射
# 将10.0.0.61的9000 转发为 172.16.1.7:22
iptables -t nat -A PREROUTING -d 10.0.0.61 -p tcp --dport 9000 -j DNAT --to-destination 172.16.1.7:22

# 测试 [d:\~]$ ssh root@10.0.0.61 9000 相当于ssh root@172.16.1.7 22
7.4 ip映射
# 将10.0.0.62 映射为 172.16.1.7
iptables -t nat -A PREROUTING -d 10.0.0.62 -j DNAT --to-destination 172.16.1.7

文件上传(下)

· 阅读需 11 分钟

服务器命名规则

第一种类型:上传文件名和服务器命名一致

第二种类型:上传文件名和服务器命名不一致(随机,时间日期命名等)

上传漏洞总结

  • 任意文件上传 (没有任何校验)
  • 绕过js校验上传 (校验发生在前端)
  • 绕过后端校验上传 (校验发生在后端)
    • 绕过文件类型校验
    • 绕过扩展名校验
    • 绕过文件头校验
  • 结合解析漏洞上传 (中间件解析漏洞造成)
  • 其他类型

文件上传检测类型

1.客户端 javascript检测(通常为检测文件扩展名)

2.服务端文件头检测

3.服务端MIME类型检测(检测Content-Type内容)

4.服务端目录路径检测 (检测跟path参数相关的内容)

5.服务端文件扩展名检测

6.服务端文件内容检测 (检测内容是否合法或含有恶意代码)

客户端javascript检测

  • 首先判断是否为 JS 本地验证
如果浏览器页面没有刷新或者打开burp抓包没有抓到包就已经有验证结果即可证明为前端JS本地验证。

服务端文件头检测

  • 什么是文件头:
文件头就是为了描述一个文件的一些重要的属性,比如图片的长度、宽度、像素尺寸等,当程序打开文件时读取这些属性对文件进行处理。

getimagesize()函数

getimagesize()函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回FALSE并产生一条错误信息。

语法:
getimagesize( string filename )例子:
<?php $array = getimagesize("images/flower_1.jpg"); print_r($array); \?>浏览器显示如下:

浏览器显示如下:
Array ([0] => 350 [1]=> 318[2]=>2[3] => width="350" height="318"[bits] =>8 [channels] => 3 [mime] => image/jpeg)返回结果说明

索引О给出的是图像宽度的像素值
索引1给出的是图像高度的像素值
索引2给出的是图像的类型,返回的是数字,其中1= GIF,2 = JPG,3= PNG,4 = SWF,5= PSD,6= BMP,7= TIFF(intel byte order),8=TIFF(motorola byte order),9= JPC,10=JP2,11=JPX,12=JB2,13= swc,14 =IFF,15 = WBMP,16= XBM
索引3给出的是一个宽度和高度的字符串,可以直接用于HTML的<image>标签

索引 bits给出的是图像的每种颜色的位数,二进制格式
索引channels给出的是图像的通道值,RGB图像默认是3
索引mime给出的是图像的MIME信息,此信息可以用来在HTTPContent-type头信息中发送正确的信息,如: header("Content-type:image/jpeg");

绕过文件头检测

Web应用程序在校验文件类型、文件扩展名的同时,也会校验文件头,从而进一步确定文件的类型。针对这种情况,可以通过在上传的一句话木马文件的开头加入特定的文件头从而绕过这种校验方式。
文件类型对应的文件头
jpegJPGGraphic File
jpgJPGGraphic File
pngJPGGraphic File
gifGIF 89A
zipZip Compressed
docMS Compound Document v1 or Lotus APProach APRfile
xlsMS Compound Document v1 or Lotus APProach APRfile
xltMS Compound Document v1 or Lotus APProach APRfile
pptMS Compound Document v1 or Lotus APProach APRfile
aprMS Compound Document v1 or Lotus APProach APRfile

服务端MIME类型检测(Content -Type)

  • MIME的作用和定义目录
使客户端软件,区分不同种类的数据,例如WEB浏览器就是通过MIME类型来判断文件是GIF图片,还是可打印的PostScript文件。
WEB服务器使用MIME来说明发送数据的种类,WEB客户端使用MIME来说明希望接收到的数据种类。
Tomcat的安装目录\conf\web.xml中定义了大量的MIME类型。
Apache的安装目录\conf\mime.types中定义了大量的MIME类型,httpd.conf中也定义了一些特殊的MIME类型。
  • 常见的MIME类型
text/plain(纯文本)
text/html (HTML文档)
text/javascript(js代码)
application/xhtml+xml (XHTML文档)
image/gif (GIF图像)
image/jpeg (JPEG图像)│
image/png ( PNG图像)
video/mpeg (MPEG动画)
application/octet-stream (二进制数据)
application/pdf (PDF文档)
  • 绕过方法:
例: burp抓包后修改content-Type:image/gif

或更改为其他的图片格式。因为图片格式往往是准许上传的。 I

图片

服务端文件扩展名检测

  • 黑名单检测--安全性比白名单低很多,攻击手法也比白名单多。
绕过方式:
(1)文件名大小写绕过
例如 AsP,pHp
(2)名单列表绕过
用名单列表里没有的名单进行攻击,比如黑名单里没有asa或cer之类
(3)特殊文件名绕过
比如发送的http包里把文件名改成test.asp.或test.asp_(下划线为空格),这种命名方式在windows系统里是不被允许的,所以需要在burp进行修改,然后绕过验证后,会被windows系统自动去掉后面的.和空格,但要注意unix/linux系统没有这个特性。
(4)0x00截断绕过
是test.asp .jpg(asp后面为Ox00) ,type=gettype(name) //而在gettype()函数里处理方式是从后往前扫描扩展名,所以判断为jpg, if(type==jpg)
(5).htaccess文件攻击 配合名单列表绕过。上传一个自定义的.htaccess
(6)解析调用/漏洞绕过
这类漏洞直接配合上传一个代码注入过的非黑名单文件即可,再利用解析调用/漏洞
(7) apache的配置文件httpd.conf中AddType application/x-httpd-php .php .phtml开启,这样phtml也可以当成php解析。

  • 白名单检测―一相对难过很多,但是也不一定绝对安全。
绕过方式:
(1)0x00截断绕过
用像test.asp%00.jpg的方式进行截断,属于白名单文件,再利用服务端代码的检测逻辑漏洞进行攻击。


00截断

0x00,%00,/00之类的截断,都是一样的,只是不同表示而已

在url中%00表示ascll码中的0,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束

0x开头表示16进制,0在十六进制中是00,0x00就是%00解码成的16进制用burp抓包,在需要截断的位置添加了一个空格,空格是为了占位,方便修改00。然后打开hex,(空格的16进制为0x20)修改16进制内容,把20改成00即可。
  • 00截断限制条件
    • 1.php版本小于5.3.4
    • 2.php的magic_quotes_gpc为OFF状态

::$data

必须是windows,必须是php
1.php

php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持"::$DATA"之前的文件名

他的目的就是不检查后缀名

解析调用/漏洞绕过

这类漏洞直接配合上传一个代码注入过的白名单文件即可,再利用解析调用/漏洞

.htaccess文件攻击,通过一个.htaccess文件调用php的解析器去解析任意文件,无论文件名是什么样子,都可以被以php的方式来解析。建一个.htaccess文件,里面的内容如下

SetHandler application/x-httpd-php
  • .htaccess
<FileMatch "1">

SetHandler application/x-httpd-php

</FileMatch>

服务端文件文件检测

  • (检测内容是否合法或含有恶意代码)
如果文件内容检测设置的比较严格,那么上传攻击将变得非常困难,也可以说它是再代码层检测的最后一道关卡,如果它被突破了,就算没有代码层的漏洞,也给后面利用应用层的解析漏洞带来了机会。

一般用图片马,有waf要求一句话代码能过waf。

绕过二次渲染

绕过二次渲染:

1.攻击函数本身,通过上传不完整图片让其渲染函数暴露,然后攻击之。
2.对文件加载器进行溢出攻击。

怎么看是否被二次渲染:上传一张图片马,下载到本地,打开看看如果代码还在就没有被二次渲染

编辑器漏洞

动态的网站后台基本都是有编辑器的,主要利用编辑器的上传按钮辅助拿shell。编辑器因为有一个技术团队维护,所以安全性比很多网站自带的上传按钮高很多,主要是配合解析漏洞来突破。总体流程:先找编辑器后台或目录,确定编辑器种类和版本,然后百度找对应版本的漏洞利用,一般是配合解析漏洞。

查找编辑器目录

  • 目录扫描
  • 蜘蛛爬行
  • 谷歌语法

目录扫描

关注一些重点目录

editor         edit
Fckeditor ewebeditor
admin/editor upload.asp
upfile.asp up.html

蜘蛛爬行

爬行可以很容易的爬到图片上传等目录,然后可以通过图片上传目录的路径判断编辑器类型。

Ewebeditor通常上传图片目录:
uploadfiles/2019092512321313131.jpg(以时间戳命名)

Fck通常上传图片目录
Userfile/images/x.jpg

谷歌语法

site: xxx.com  
inurl:editor
inurl:fckeditor
inurl:ewebeditor

编辑器文件上传

  • 1.FCKeditor编辑器
  • 2.EWEBeditor编辑器
  • 3.其他编辑器

FCKeditor编辑器利用

利用方式有手工利用和工具利用,其利用的核心思路都是一样,因为很多网站的编辑器路径如果不做修改都是一样的,所以收集很多编辑器路径直接加在url后面即可进行测试,工具也是用的这个思路。

下面列出一些常见的fckeditor路径
FCKeditor编辑器页面:
FCKeditor/_samples/default.html
查看文件上传路径:
fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/
查看FCK版本:
FCKeditor/_whatsnew.html
查看FCK版本:
/editor/dialog/fck_about.html
爆物理路径php:
/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php
爆绝对路径aspx
/editor/filemanager/browser/default/browser.html?type=Image&connector=connectors/aspx/connector.aspx
爆路径:
http:///editor/filemanager/connectors/asp/connector.asp?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/
JSP上传1
/editor/filemanager/browser/default/browser.html?Connector=connectors/jsp/connector
JSP上传2
/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector.jsp
目录浏览1
/editor/filemanager/browser/default/browser.html?Type=File&Connector=../../connectors/asp/connector.asp
目录浏览2
/editor/filemanager/browser/default/browser.html?type=Image&connector=connectors/asp/connector.asp
目录浏览3
/editor/filemanager/browser/default/connectors/aspx/connector.aspx?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=%2F
Asp创文件夹1
/editor/filemanager/connectors/asp/connector.asp?Command=CreateFolder&Type=Image&CurrentFolder=/qing.asp&NewFolderName=x.asp
Asp创文件夹2
/editor/filemanager/connectors/asp/connector.asp?Command=CreateFolder&Type=Image&CurrentFolder=%2Fshell.asp&NewFolderName=z&uuid=1244789975684

Asp创文件夹3
/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=CreateFolder&CurrentFolder=/&Type=Image&NewFolderName=shell.asp"
上传页面1
/editor/filemanager/browser/default/connectors/test.html
上传页面2
/editor/filemanager/upload/test.html
上传页面3
/editor/filemanager/connectors/test.html
上传页面4
/editor/filemanager/connectors/uploadtest.html
目录浏览3
/editor/filemanager/browser/default/connectors/jsp/connector?Command=GetFoldersAndFiles&Type=&CurrentFolder=%2F
Joomla fck包含
/editor/filemanager/browser/default/browser.html?Type=Image&amp;Connector=../../../../../etc/passwd

EWEBeditor编辑器利用

  • 进后台
  • 尝试弱口令:admin admin/ admin 123456/ admin123 admin888......
  • 下载默认数据库:ewebeditor/db/ewebeditor.mdb或ewebeditor/db/%23ewebeditor.mdb
  • Burp抓包爆破
  • 利用注入点进行注入得到密码
  • 修改上传类型/自己添加上传样式-添加上传按钮-上传
  • 在后台修改上传样式如果加入asp需要写aaspsp的形式,因为程序有代码把asp替换为空。通常可以加cer等。修改样式没有提交按钮,可以在页面hmtl编辑中自己手动添加一个提交按钮。也可以新建一个样式。#

文件上传防御

  • 上传目录禁止执行权限

  • 判断文件类型

  • 使用随机数改写文件名和文件路径

  • 单独设置文件服务器的域名

  • 二次渲染

Tomcat多实例部署及故障排查

· 阅读需 8 分钟

1. 单台虚拟机部署3个tomcat多实例jpress-v3.0.6

1.1 解压tomcat包

[root@tomcat tomcat]# tar xf /app/tools/apache-tomcat-8.5.50.tar.gz 

1.2 复制3个tomcat实例

[root@tomcat tomcat]# cp -r apache-tomcat-8.5.50/ tomcat_8081
[root@tomcat tomcat]# cp -r apache-tomcat-8.5.50/ tomcat_8082
[root@tomcat tomcat]# cp -r apache-tomcat-8.5.50/ tomcat_8083

1.3 修改3个tomcat实例的端口,进行区分

[root@tomcat tomcat]# sed -i.bak 's#8080#8081#g' tomcat_8081/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8005#8006#g' tomcat_8081/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8009#8010#g' tomcat_8081/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8080#8082#g' tomcat_8082/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8005#8007#g' tomcat_8082/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8009#8011#g' tomcat_8082/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8080#8083#g' tomcat_8083/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8005#8008#g' tomcat_8083/conf/server.xml
[root@tomcat tomcat]# sed -i.bak 's#8009#8012#g' tomcat_8083/conf/server.xml

1.4 将3个tomcat实例包移动到/app下

[root@tomcat tomcat]# mv tomcat_808* /app/

1.5 启动3个tomcat实例

[root@tomcat tomcat]# /app/tomcat_8081/bin/startup.sh 
Using CATALINA_BASE: /app/tomcat_8081
Using CATALINA_HOME: /app/tomcat_8081
Using CATALINA_TMPDIR: /app/tomcat_8081/temp
Using JRE_HOME: /app/jdk
Using CLASSPATH: /app/tomcat_8081/bin/bootstrap.jar:/app/tomcat_8081/bin.jar
Tomcat started.
[root@tomcat tomcat]# /app/tomcat_8082/bin/startup.sh
Using CATALINA_BASE: /app/tomcat_8082
Using CATALINA_HOME: /app/tomcat_8082
Using CATALINA_TMPDIR: /app/tomcat_8082/temp
Using JRE_HOME: /app/jdk
Using CLASSPATH: /app/tomcat_8082/bin/bootstrap.jar:/app/tomcat_8082/bin.jar
Tomcat started.
[root@tomcat tomcat]# /app/tomcat_8083/bin/startup.sh
Using CATALINA_BASE: /app/tomcat_8083
Using CATALINA_HOME: /app/tomcat_8083
Using CATALINA_TMPDIR: /app/tomcat_8083/temp
Using JRE_HOME: /app/jdk
Using CLASSPATH: /app/tomcat_8083/bin/bootstrap.jar:/app/tomcat_8083/bin.jar
Tomcat started.

1.6 查看3个tomcat实例的端口

[root@tomcat webapps]# ss -lntup | grep java
tcp LISTEN 0 1 ::ffff:127.0.0.1:8007 :::* users:(("java",pid=58100,fd=79))
tcp LISTEN 0 1 ::ffff:127.0.0.1:8008 :::* users:(("java",pid=58157,fd=79))
tcp LISTEN 0 100 :::8010 :::* users:(("java",pid=58041,fd=58))
tcp LISTEN 0 100 :::8011 :::* users:(("java",pid=58100,fd=58))
tcp LISTEN 0 100 :::8012 :::* users:(("java",pid=58157,fd=58))
tcp LISTEN 0 100 :::8081 :::* users:(("java",pid=58041,fd=53))
tcp LISTEN 0 100 :::8082 :::* users:(("java",pid=58100,fd=53))
tcp LISTEN 0 100 :::8083 :::* users:(("java",pid=58157,fd=53))
tcp LISTEN 0 1 ::ffff:127.0.0.1:8006 :::* users:(("java",pid=58041,fd=79))

1.7 分别部署3个tomcat实例的jpress-v3.0.6

软件包存放路径为:/app/tomcat_8081/webapps/

1.8 远程数据库部署

# 创建3个数据库
mysql> create database jpress_8081;
mysql> create database jpress_8082;
mysql> create database jpress_8083;

# 创建用户jpress并授权
mysql> grant all on *.* to jpress@'%' identified by '123456';

2. 故障案例:tomcat负载高排查方法

2.1 找出问题进程

# 利用top命令找到CPU/MEM(根据实际需求选择)找到负载最高的进程,并记录PID号,如下例中则为58100
[root@tomcat ~]# top
top - 19:50:00 up 16:26, 2 users, load average: 0.02, 0.04, 0.05
Tasks: 106 total, 1 running, 105 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.2 us, 0.0 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 2028116 total, 64292 free, 1338380 used, 625444 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 472492 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
58100 root 20 0 3159080 354528 13684 S 0.3 17.5 0:22.81 java
1 root 20 0 125972 4468 2620 S 0.0 0.2 0:17.71 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:01.62 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root rt 0 0 0 0 S 0.0 0.0 0:00.29 migration/0
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root 20 0 0 0 0 S 0.0 0.0 0:04.11 rcu_sched
10 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 lru-add-drain

2.2 通过进程PID找出是哪个java问题线程

# 利用top -Hp  PID 查找负载最高的线程,如下例中的58111
[root@tomcat ~]# top -Hp 58100
top - 19:53:13 up 16:29, 2 users, load average: 0.00, 0.02, 0.05
Threads: 85 total, 0 running, 85 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.2 us, 0.3 sy, 0.0 ni, 98.3 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
KiB Mem : 2028116 total, 73444 free, 1345008 used, 609664 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 466180 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
58111 root 20 0 3159080 354588 13684 S 0.7 17.5 0:02.33 java
58100 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
58101 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.55 java
58102 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.25 java
58103 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.23 java
58104 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.62 java
58105 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.01 java
58106 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.01 java
58107 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
58108 root 20 0 3159080 354588 13684 S 0.0 17.5 0:06.92 java
58109 root 20 0 3159080 354588 13684 S 0.0 17.5 0:01.58 java
58110 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
58112 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.20 java
58113 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
58114 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.13 java
58115 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.13 java
58119 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.37 java
58130 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.16 java
58131 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.13 java
58132 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.07 java
58133 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.12 java
58144 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.15 java
58145 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.14 java
58146 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
58147 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.13 java
60193 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
60196 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
60198 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.00 java
60201 root 20 0 3159080 354588 13684 S 0.0 17.5 0:00.02 java

2.3 将问题线程的pid号转换为16进制

[root@tomcat ~]# echo 'obase=16;58111' | bc
E2FF

2.4 利用jstack配合grep过滤出并显示问题进程的详细信息

# jstack 问题进程PID | grep -i 问题线程PID(16进制数)
[root@tomcat ~]# jstack 58100 | grep -i E2FF
"VM Periodic Task Thread" os_prio=0 tid=0x00007efc3c0c5800 nid=0xe2ff waiting on condition
说明:筛选出的信息可以提供开发人员查看排查问题

2.5 利用jmap显示对应PID的jvm内存使用情况

[root@tomcat ~]# jmap -heap 58100
Attaching to process ID 58100, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.241-b07

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 520093696 (496.0MB)
NewSize = 11010048 (10.5MB)
MaxNewSize = 173015040 (165.0MB)
OldSize = 22544384 (21.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
capacity = 125304832 (119.5MB)
used = 61121864 (58.29035186767578MB)
free = 64182968 (61.20964813232422MB)
48.77853712776216% used
From Space:
capacity = 23068672 (22.0MB)
used = 10506912 (10.020172119140625MB)
free = 12561760 (11.979827880859375MB)
45.54623690518466% used
To Space:
capacity = 22544384 (21.5MB)
used = 0 (0.0MB)
free = 22544384 (21.5MB)
0.0% used
PS Old Generation
capacity = 35651584 (34.0MB)
used = 13678312 (13.044654846191406MB)
free = 21973272 (20.955345153808594MB)
38.36663190056296% used

25267 interned Strings occupying 2605064 bytes.

2.6 导出jvm内存内容

[root@tomcat ~]# jmap -dump:format=b,file=/root/tomcat.bin 58100
Dumping heap to /root/tomcat.bin ...
File exists
[root@tomcat ~]# ll /root/tomcat.bin
-rw------- 1 root root 69961630 Feb 10 17:48 /root/tomcat.bin

2.7 导出的文件可以用MemoryAnalyzer打开进行分析