06·Shell编程-企业级实战练习

2022-09-26 10:38:59 浏览数 (1)

  • 书写脚本常用监控命令
  • if判断实战
  • if判断独家练习

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


书写脚本常用监控命令

监控目标

命令

本地端口监控

netstat -lntup

ss -lntup

lsof

远端端口监控

telnet

nc

nmap

进程监控

ps -ef

ps aux

web监控

curl

wget

数据库

mysql -uroot -p123 -e 'select ping()'

内存

free -m

磁盘

df -h

文件内容

md5


本地检查端口是否开启

代码语言:javascript复制
## 查看所有端口
[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

## 查看指定端口
[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 -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@zabbix01 ~]# netstat -lntup|grep -w '22'|wc -l
2

## 个人推荐还是使用netstat这个命令,后续我们需要监控TCP的11种状态,也用该命令
[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)

远端检查端口是否开启

代码语言:javascript复制
#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
## 这是一个交互式的,需要我们手动退出,所以适合在命令行使用,不适合脚本中使用
## 当然也有方法能让他不交互。
[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
## 太麻烦,不推荐


# 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命令

ps命令top命令还有htop命令我们已经在基础阶段讲完了,并且讲的很详细,如果忘记了请访问:进程管理


curl命令

代码语言:javascript复制
# 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://blog.driverzeng.com
200
[root@zabbix01 ~]# curl -s -w "%{http_code}n" -o /dev/null https://blog.driverzeng.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://blog.driverzeng.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://blog.driverzeng.com|awk 'NR==1{print $2}'
200

## 指定用户名密码
[root@zabbix01 ~]# yum install -y nginx httpd-tools
[root@zabbix01 ~]# htpasswd -b -c /etc/nginx/auth_conf zls zls
[root@zabbix01 ~]# vim /etc/nginx/conf.d/zls.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 -uzls:zls 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://blog.driverzeng.com


wget命令

代码语言:javascript复制
-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命令

代码语言:javascript复制
# 获取文件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%就发送邮件告警通知运维人员

代码语言:javascript复制
#1.服务端配置邮件功能
[root@backup /]# yum install mailx -y
[root@backup /]# vim /etc/mail.rc
set from=253097001@qq.com
set smtp=smtps://smtp.qq.com:465
set smtp-auth-user=253097001@qq.com
set smtp-auth-password=#客户端授权码
set smtp-auth=login
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb/

#2.内存检测
[root@zabbix01 ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           3934         189        2270          11        1473        3297
Swap:          1023           0        1023

2.检查nginx服务是否正常,业务是否正常

3.rsync服务管理脚本

代码语言:javascript复制
# 1.rsync配置文件
uid = rsync
gid = rsync
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
pid file = /var/run/rsyncd.pid
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[backup]
comment = welcome to oldboyedu backup!
path = /backup

# 2.服务启动
rsync --daemon

# 3.关闭
kill -3 `cat /var/run/rsyncd.pid`

# 4.重启
kill -3 `cat /var/run/rsyncd.pid`
sleep 1
rsync --daemon

# 5.管理开机自启
[Unit]            # 依赖关系
[Service]       # 服务开关重启命令
[Install]        # 服务的运行级别

## 分析sshd启动脚本
[root@zabbix01 ~]# systemctl cat sshd
# /usr/lib/systemd/system/sshd.service                           # 脚本位置
[Unit]                                                                                          # 依赖关系标签
Description=OpenSSH server daemon                               # 描述,可有可无
Documentation=man:sshd(8) man:sshd_config(5)        # man帮助,可有可无
After=network.target sshd-keygen.service                        # 在指定服务之后启动,依赖:network 和 ssh-keygen
Wants=sshd-keygen.service                                                  # 必须要启动的前置服务 ssh-keygen

[Service]                                                                                     # 服务管理命令标签
Type=notify                                                                               # 以 fork 方式从父进程创建子进程,创建后父进程会立即退出
EnvironmentFile=/etc/sysconfig/sshd                               # 指定环境变量文件
ExecStart=/usr/sbin/sshd -D $OPTIONS                          # 启动命令
ExecReload=/bin/kill -HUP $MAINPID                            # 重新加载命令
KillMode=process                                                                    #  因为没写 ExecStop,所以写了KillMode如果关闭直接杀sshd进程
Restart=on-failure                                                                   # 失败之后重启
RestartSec=42s                                                                         # 重启时间42s

[Install]                                                                                       # 运行级别标签
WantedBy=multi-user.target                                                  # 第三运行级别,也就是多用户级别



## Type 了解
Type:定义启动时的进程行为。它有以下几种值。
Type=simple:默认值,执行ExecStart指定的命令,启动主进程
Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
Type=dbus:当前服务通过D-Bus启动
Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
Type=idle:若有其他任务执行完毕,当前服务才会运行

## Restart值
Restart:定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog


### CentOS6管理开机自启动
chkconfig
## 三大规则:
# 1.脚本要放在/etc/init.d/
# 2.脚本前几行必须要有chkconfig要求的格式,虽然是注释
# chkconfig: 2345 99 98     ## 在2 3 4 5 运行级别,开机启动顺序99,关机关闭顺序98
# 3.加入chkconfig管理
chkconfig --add rsyncd

if判断独家练习

这个是根据我上家公司的一个企业级需求:请监控Linux系统中重要的文件,如果文件内容被改动,权限被修改,通过发邮件的方式,告知运维人员需要尽快处理,并且要告知运维人员,是哪里被改动了,如果是内容,请告知运维人员,第几行的内容。

需求解析:

代码语言:javascript复制
1.监控文件
2.监控内容
3.监控权限
4.发送邮件
    - 时间
    - 主机
    - IP
    - 文件位置
    - 第几行
    - 什么权限
5.如果是创建了用户,请告诉运维人员,什么时间创建了什么用户?uid gid 等...

需要用到的知识点:

代码语言:javascript复制
1.md5
2.grep -f
3.mailx
4.变量
5.if判断
6.条件表达式

0 人点赞