第六章·shell编程-企业级实战练习
书写脚本常用监控命令
监控目标/命令
- 本地端口监控
- netstat-lntup
- ss -lntup
- lsof
- 远端端口监控
- telnet
- nc
- nmap
- 进程监控
- ps -ef
- ps aux
- web监控
- curl
- wget
- 数据库
- mysql -uroot -p123 'select ping()'
- 内存
- free -m
- 磁盘
- df -h
- 文件内容
- md5
端口检查
本地检查端口是否开启
## 查看所有端口
[root@zabbix01 ~]# netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:25672 0.0.0.0:* LISTEN 37809/beam.smp
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 544/rpcbind
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 38249/nginx: master
tcp 0 0 0.0.0.0:4369 0.0.0.0:* LISTEN 4122/epmd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 770/sshd
tcp 0 0 0.0.0.0:15672 0.0.0.0:* LISTEN 37809/beam.smp
tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN 37783/postmaster
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 928/master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 38249/nginx: master
tcp6 0 0 :::5672 :::* LISTEN 37809/beam.smp
tcp6 0 0 :::111 :::* LISTEN 544/rpcbind
tcp6 0 0 :::80 :::* LISTEN 38249/nginx: master
tcp6 0 0 :::4369 :::* LISTEN 4122/epmd
tcp6 0 0 :::22 :::* LISTEN 770/sshd
tcp6 0 0 :::5432 :::* LISTEN 37783/postmaster
tcp6 0 0 ::1:25 :::* LISTEN 928/master
tcp6 0 0 :::443 :::* LISTEN 38249/nginx: master
udp 0 0 0.0.0.0:698 0.0.0.0:* 544/rpcbind
udp 0 0 0.0.0.0:111 0.0.0.0:* 544/rpcbind
udp6 0 0 :::698 :::* 544/rpcbind
udp6 0 0 :::111 :::* 544/rpcbind
## 查看指定端口
##错误方式;会过滤包含22所有的端口
[root@zabbix01 ~]# netstat -lntup|grep 22
tcp 0 0 0.0.0.0:4369 0.0.0.0:* LISTEN 4122/epmd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 770/sshd
tcp6 0 0 :::4369 :::* LISTEN 4122/epmd
tcp6 0 0 :::22 :::* LISTEN 770/sshd
## 精确查找端口
##正确方式
[root@zabbix01 ~]# netstat -lntup|grep [s]shd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 770/sshd
tcp6 0 0 :::22 :::* LISTEN 770/sshd
[root@zabbix01 ~]# netstat -lntup|grep -w '22'
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 770/sshd
tcp6 0 0 :::22 :::* LISTEN 770/sshd
[root@zabbix01 ~]# ss -lntup|grep -w 22
tcp LISTEN 0 128 *:22 *:* users:(("sshd",pid=770,fd=3))
tcp LISTEN 0 128 :::22 :::* users:(("sshd",pid=770,fd=4))
##查看命令返回值判断端口是否开启
[root@m01 ~]# netstat -lntup|grep -w '22' &>/dev/null
[root@m01 ~]# echo $?
0
[root@m01 ~]# netstat -lntup|grep -w '10050' &>/dev/null
[root@m01 ~]# echo $?
1
## 转化成数字
[root@zabbix01 ~]# netstat -lntup|grep -w '22'|wc -l
2
## 个人推荐还是使用netstat这个命令,后续我们需要监控TCP的11种状态,也用该命令
#lsof
[root@zabbix01 ~]# lsof -i:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 770 root 3u IPv4 19637 0t0 TCP *:ssh (LISTEN)
sshd 770 root 4u IPv6 19646 0t0 TCP *:ssh (LISTEN)
sshd 25088 root 3u IPv4 491299 0t0 TCP zabbix01:ssh->gateway:61954 (ESTABLISHED)
sshd 80641 root 3u IPv4 291875 0t0 TCP zabbix01:ssh->gateway:54130 (ESTABLISHED)
#ss
[root@zabbix01 ~]# ss -lntup|grep 22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 770 root 3u IPv4 19637 0t0 TCP *:ssh (LISTEN)
sshd 770 root 4u IPv6 19646 0t0 TCP *:ssh (LISTEN)
sshd 25088 root 3u IPv4 491299 0t0 TCP zabbix01:ssh->gateway:61954 (ESTABLISHED)
sshd 80641 root 3u IPv4 291875 0t0 TCP zabbix01:ssh->gateway:54130 (ESTABLISHED)
远端检查端口是否开启
#1.telnet
[root@zabbix01 ~]# telnet 127.0.0.1 22
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4
## 这是一个交互式的,需要我们手动退出,所以适合在命令行使用,不适合脚本中使用
## 当然也有方法能让他不交互。随便ehco一个数交给管道符。
[root@zabbix01 ~]# echo | telnet 127.0.0.1 22
[root@zabbix01 ~]# echo | telnet 127.0.0.1 22 2>/dev/null|grep 'Connected'|wc -l
##使用telnet端口扫描
#!/bin/bash
. /etc/init.d/functions
IP=$1
for port in `seq 65535`;do
{
port_count=`echo ''|telnet $IP $port 2>/dev/null |grep 'Connected'|wc -l`
if [ $port_count -ne 0 ];then
action "$port 端口" /bin/true
fi
} &
done
# 2.nc netcat 网络中的瑞士军刀,功能很牛
[root@zabbix01 ~]# echo |nc 127.0.0.1 22
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
[root@zabbix01 ~]# echo $?
0
-l:创建端口
[root@zabbix01 ~]# nc -l 8888
-k:保持连接
[root@zabbix01 ~]# nc -lk 8888
## 可以跟端口建立连接,传输数据
-u:指定nc使用udp协议(默认tcp)
-s:指定发送数据的源IP地址,适用于多网卡机器
-w:设置超时时间
-z:扫描时不发送任何数据
# 3.nmap也是一个很牛逼的网络扫描工具,一个命令能写一本书
## 扫描IP
nmap 10.0.0.61
## 扫描一个主机的一个端口
nmap -p 22 10.0.0.61
## 扫描一个主机的多个端口
nmap -p 22-1024 10.0.0.61
## 扫描多个主机的多个端口
nmap -p 22-1024 10.0.0.61 baidu.com
进程判断
ps和top命令
[root@web01 ~]# ps -ef|grep [n]ginx
root 12209 1 0 10:42 ? 00:00:00 nginx: master process
/usr/sbin/nginx -c /etc/nginx/nginx.conf
www 12210 12209 0 10:42 ? 00:00:00 nginx: worker process
[root@web01 ~]# ps -ef|grep [n]ginx|wc -l
2
[root@web01 ~]# ps -ef|grep [n]ginx1111|wc -l
0
## 远程进程检测
vim check_process.sh
#!/bin/bash
proc_count=`ssh 172.16.1.7 'ps -ef|grep [n]ginx|wc -l'`
if [ $proc_count -eq 0 ];then
echo 'nginx不存活'
else
echo 'nginx存活'
fi
网络检测
curl命令
# 1.curl命令
-I:只显示响应头信息
-H:修改请求头信息
-v:显示详细的请求过程
-L --location:跟随跳转
-s:不显示头部的统计信息
-X:指定请求方式
-w:取出指定内容,例如:%{http_code}取出状态码
-o:指定输出位置
-A:指定User-Agent
-u:指定用户名密码
## 举例:
## 访问百度
[root@zabbix01 ~]# curl www.baidu.com
## 只显示响应头部信息
[root@zabbix01 ~]# curl -I www.baidu.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: keep-alive
Content-Length: 277
Content-Type: text/html
Date: Wed, 01 Sep 2021 01:24:34 GMT
Etag: "575e1f60-115"
Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
## 只要状态码
[root@zabbix01 ~]# curl -s -w "%{http_code}" -o /dev/null https://roweyy.com
200
[root@zabbix01 ~]# curl -s -w "%{http_code}\n" -o /dev/null https://roweyy.com
200
## 追踪跳转
[root@zabbix01 ~]# curl www.360buy.com
[root@zabbix01 ~]# curl -v www.360buy.com
[root@zabbix01 ~]# curl -v www.360buy.com -L
## -s取消头部信息,一般配合管道符使用
[root@zabbix01 ~]# curl -I https://roweyy.com|awk 'NR==1{print $2}'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
200
[root@zabbix01 ~]# curl -I -s https://roweyy.com|awk 'NR==1{print $2}'
200
## 指定用户名密码
[root@zabbix01 ~]# yum install -y nginx httpd-tools
[root@zabbix01 ~]# htpasswd -b -c /etc/nginx/auth_conf lw lw
[root@zabbix01 ~]# vim /etc/nginx/conf.d/lw.conf
server {
listen 80;
server_name _;
access_log off;
location /nginx_status {
stub_status;
auth_basic "Auth access Blog Input your Passwd!";
auth_basic_user_file auth_conf;
}
}
## 直接访问会报错401没有认证
[root@zabbix01 ~]# curl 10.0.0.61/nginx_status
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>
## 加上用户名密码就可以了
[root@zabbix01 ~]# curl -ulw:lw 10.0.0.61/nginx_status
Active connections: 1
server accepts handled requests
5 5 3
Reading: 0 Writing: 1 Waiting: 0
## 但是我推荐这么访问
[root@zabbix01 ~]# curl http://zls:zls@10.0.0.61/nginx_status
Active connections: 1
server accepts handled requests
6 6 4
Reading: 0 Writing: 1 Waiting: 0
## 访问的时候,可以修改我们自己的User-Agent,偷偷的,不让别人发现
[root@zabbix01 ~]# curl -A zls_chrome https://roweyy.com
wget命令
-O:指定输出位置
-r:递归下载
--debug:类似于curl的-v显示过程
-q:静默输出
--spider:不下载,就访问(爬虫模式)
[root@zabbix01 ~]# wget -r https://nginx.org/en/docs/
[root@zabbix01 ~]# wget -q --spider www.baidu.com
[root@zabbix01 ~]# echo $?
0
[root@zabbix01 ~]# wget -q --spider www.baidu.com/asdasda
[root@zabbix01 ~]# echo $?
8
文件检测
md5
# 获取文件md5值
[root@zabbix01 ~]# md5sum /etc/passwd
38b06c70e862085e22f23838dc873ade /etc/passwd
# 将md5值保存到文件中
[root@zabbix01 ~]# md5sum /etc/passwd > passwd.md5
# 检测md5
[root@zabbix01 ~]# md5sum -c passwd.md5
/etc/passwd: OK
# 如果内容有改动则md5会发生变化
[root@zabbix01 ~]# useradd test_md5
[root@zabbix01 ~]# md5sum -c passwd.md5
/etc/passwd: FAILED
md5sum: WARNING: 1 computed checksum did NOT match
if判断实战
1.监控系统内存,如果不足30%就发送邮件告警通知运维人员
#下载 mailx
[root@m01 ~]# yum install -y mailx
#修改配置文件
[root@m01 ~]# vim /etc/mail.rc
set from=1627556442@qq.com
set smtp=smtps://smtp.qq.com:465
set smtp-auth-user=1627556442@qq.com
set smtp-auth-password=#客户端授权码
set smtp-auth=login
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb/
## 系统内存
# 可用内存
[root@m01 ~]# free -m|awk 'NR==2{print $NF}'
692
# 所有内存
[root@m01 ~]# free -m|awk 'NR==2{print $2}'
972
#编写脚本
[root@m01 ~]# vim check_mem.sh
#!/bin/bash
IP=`ifconfig eth0|awk 'NR==2{print $2}'`
mem_ava=`free -m|awk 'NR==2{print int($NF/$2*100)}'`
mem_info=`free -m|awk 'NR==2{print $NF}'`
if [ $mem_ava -lt 30 ];then
echo -e "IP地址:$IP\n主机名:$HOSTNAME\n内存可用率:低于30%\n当前可用内存:
${mem_info}M" \
|mail -s "${IP}内存检测结果" 133411023@qq.com
fi
使用sendEmail
使用mailx我们会发现无法发送表格邮件,mailx不支持html格式
# 1.下载sendEmail
wget http://test.driverzeng.com/other/sendEmail-v1.56.tar.gz
# 2.安装依赖
yum install perl-Net-SSLeay perl-IO-Socket-SSL -y
# 3.解压
tar xf sendEmail-v1.56.tar.gz
# 4.创建安装目录
[root@m01 ~]# mkdir /app
# 5.移动软件到安装目录中
[root@m01 ~]# mv sendEmail-v1.56 /app/
# 6.添加环境变量
[root@m01 ~]# vim /etc/profile.d/sendEmail.sh
PATH="/app/sendEmail-v1.56:$PATH"
# 7.加载环境变量
[root@m01 ~]# source /etc/profile
## sendEmail选项
-f 112233@qq.com# 发件人邮箱地址
-t 445566@qq.com# 收件人邮箱地址
-s smtp.qq.com# 发件人邮箱的smtp服务器地址
-u 'lw test email'# 邮件标题
-m 'test mail content'# 邮件内容
-a /tmp/data.txt /tmp/1.jpg#发送附件
-xu 112233# 发件人邮箱登录用户名
-xp fdnzuslqhshgkslxj# 发件人邮箱登录密码(QQ邮箱的授权码)
-cc 222222@qq.com# 抄送指定用户
-bcc 333333@qq.com# 加密抄送
-o message-content-type=html# 邮件内容格式为html
-o message-file=FILE# 指定某个文件内容作为邮件内容
-o message-charset=utf8# 邮件内容编码为utf8
-o tls=no#关闭tls握手
## 发送html格式邮件
[root@m01 ~]# cat check_mem.sh
#!/bin/bash
IP=`ifconfig eth0|awk 'NR==2{print $2}'`
mem_ava=`free -m|awk 'NR==2{print int($NF/$2*100)}'`
mem_info=`free -m|awk 'NR==2{print $NF}'`
if [ $mem_ava -gt 30 ];then
cat > mem_info.txt <<EOF
<table border=1px color=red>
<tbody>
<tr bgcolor="#fff000">
<td colspan=7 align=center>内存监控信息</td>
</tr>
<tr>
<td align=center>IP地址</td>
<td align=center>主机名</td>
<td align=center>内存可用率</td>
<td align=center>当前可用内存</td>
</tr>
<tr>
<td align=center>$IP</td>
<td align=center>$HOSTNAME</td>
<td align=center>小于30%</td>
<td align=center>${mem_info}M</td>
</tr>
</tbody>
</table>
EOF
sendEmail -f 1627556442@qq.com \
-t 1627556442@qq.com \
-s smtp.qq.com \
-u "${IP}主机内存检测结果" \
-xu 1627556442 \
-xp tcrvcdgkxxgybiab \
-o message-content-type=html \
-o message-file=mem_info.txt \
-o message-charset=utf8 \
-o tls=no
fi
2.检查nginx服务是否正常,业务是否正常
[root@m01 ~]# cat check_web.sh
#!/bin/bash
. /etc/init.d/functions
domain_name_list=(www.zls.com blog.zls.com php.zls.com)
IP_list=(10.0.0.61 10.0.0.7)
proc_count=`ps -ef|grep [n]ginx|wc -l`
port_80_count=`netstat -lntup|grep -w '80'|wc -l`
port_443_count=`netstat -lntup|grep -w '443'|wc -l`
# 本地
for domain_name in ${domain_name_list[*]};do
http_code=`curl -s -w "%{http_code}" -o /dev/null $domain_name`
if [ $http_code -eq 401 ];then
action "${domain_name}网站正常,但是身份验证不通过" /bin/false
elif [[ $http_code =~ ^[4-5] ]];then
action "${domain_name}网站无法访问" /bin/false
elif [ $proc_count -le 0 ];then
action "nginx进程" /bin/false
elif [ $port_80_count -le 0 ];then
action "nginx的80端口检测" /bin/false
#elif [ $port_443_count -le 0 ];then
# echo 'nginx的443端口不存在'
else
action "${domain_name}网站" /bin/true
fi
done
# 远程
for IP in ${IP_list[*]};do
proc_count=`ssh $IP "ps -ef|grep [n]ginx|wc -l"`
port_80_count=`ssh $IP "netstat -lntup|grep -w '80'|wc -l"`
port_443_count=`ssh $IP "netstat -lntup|grep -w '443'|wc -l"`
for domain_name in ${domain_name_list[*]};do
http_code=`curl -s -w "%{http_code}" -o /dev/null $domain_name`
if [ $http_code -eq 401 ];then
action "${domain_name}网站正常,但是身份验证不通过" /bin/false
elif [[ $http_code =~ ^[4-5] ]];then
action "${domain_name}网站无法访问" /bin/false
elif [ $proc_count -le 0 ];then
action "$IP nginx进程" /bin/false
elif [ $port_80_count -le 0 ];then
action "$IP nginx的80端口检测" /bin/false
#elif [ $port_443_count -le 0 ];then
# echo 'nginx的443端口不存在'
else
action "${domain_name}网站" /bin/true
fi
done
done
Comments | NOTHING