Browse Source

feat: add

master
yaokl 2 years ago
parent
commit
b233d11f0b
  1. 26
      shell/aliyun.sh
  2. 457
      shell/init/init_centos.sh
  3. 338
      shell/k8s/diagnose_k8s.sh
  4. 2
      shell/library.sh
  5. 66
      shell/poorjson.sh
  6. 955
      shell/test/ssl-cert-check.sh
  7. 102
      shell/wakuag.sh
  8. 0
      shell/系统信息/get_proc_mem.sh
  9. 45
      shell/系统信息/show_pid_openfile.sh

26
shell/aliyun.sh

@ -0,0 +1,26 @@
if ps aux | grep -i '[a]liyun'; then
curl http://update.aegis.aliyun.com/download/uninstall.sh | bash
curl http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash
pkill aliyun-service
rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service
rm -rf /usr/local/aegis*
systemctl stop aliyun.service
systemctl disable aliyun.service
service bcm-agent stop
yum remove bcm-agent -y
apt-get remove bcm-agent -y
elif ps aux | grep -i '[y]unjing'; then
/usr/local/qcloud/stargate/admin/uninstall.sh
/usr/local/qcloud/YunJing/uninst.sh
/usr/local/qcloud/monitor/barad/admin/uninstall.sh
fi
if [ -f /usr/local/cloudmonitor/wrapper/bin/cloudmonitor.sh ]; then
/usr/local/cloudmonitor/wrapper/bin/cloudmonitor.sh stop && /usr/local/cloudmonitor/wrapper/bin/cloudmonitor.sh remove && rm -rf /usr/local/cloudmonitor
else
export ARCH=amd64
if [ -f /usr/local/cloudmonitor/CmsGoAgent.linux-${ARCH} ]; then
/usr/local/cloudmonitor/CmsGoAgent.linux-${ARCH} stop && /usr/local/cloudmonitor/CmsGoAgent.linux-${ARCH} uninstall && rm -rf /usr/local/cloudmonitor
else
echo "ali cloud monitor not running"
fi
fi

457
shell/init/init_centos.sh

@ -0,0 +1,457 @@
#!/usr/bin/env bash
# Disable selinux
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
setenforce 0
# Disable swap
swapoff -a && sysctl -w vm.swappiness=0
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
# Disable firewalld
for target in firewalld python-firewall firewalld-filesystem iptables; do
systemctl stop $target &>/dev/null || true
systemctl disable $target &>/dev/null || true
done
# repo
[ -f /etc/yum.repos.d/CentOS-Base.repo ] && sed -e 's!^#baseurl=!baseurl=!g' \
-e 's!^mirrorlist=!#mirrorlist=!g' \
-e 's!mirror.centos.org!mirrors.aliyun.com!g' \
-i /etc/yum.repos.d/CentOS-Base.repo
yum install -y epel-release
[ -f /etc/yum.repos.d/epel.repo ] && sed -e 's!^mirrorlist=!#mirrorlist=!g' \
-e 's!^metalink=!#metalink=!g' \
-e 's!^#baseurl=!baseurl=!g' \
-e 's!//download.*/pub!//mirrors.aliyun.com!g' \
-e 's!http://mirrors\.aliyun!https://mirrors.aliyun!g' \
-i /etc/yum.repos.d/epel.repo
# Change limits
[ ! -f /etc/security/limits.conf_bak ] && cp /etc/security/limits.conf{,_bak}
cat << EOF >> /etc/security/limits.conf
## Kainstall managed start
root soft nofile 655360
root hard nofile 655360
root soft nproc 655360
root hard nproc 655360
root soft core unlimited
root hard core unlimited
* soft nofile 655360
* hard nofile 655360
* soft nproc 655360
* hard nproc 655360
* soft core unlimited
* hard core unlimited
## Kainstall managed end
EOF
[ -f /etc/security/limits.d/20-nproc.conf ] && sed -i 's#4096#655360#g' /etc/security/limits.d/20-nproc.conf
cat << EOF >> /etc/systemd/system.conf
## Kainstall managed start
DefaultLimitCORE=infinity
DefaultLimitNOFILE=655360
DefaultLimitNPROC=655360
DefaultTasksMax=75%
## Kainstall managed end
EOF
# Change sysctl
cat << EOF > /etc/sysctl.d/99-kube.conf
# https://www.kernel.org/doc/Documentation/sysctl/
#############################################################################################
# 调整虚拟内存
#############################################################################################
# Default: 30
# 0 - 任何情况下都不使用swap。
# 1 - 除非内存不足(OOM),否则不使用swap。
vm.swappiness = 0
# 内存分配策略
#0 - 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
#1 - 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
#2 - 表示内核允许分配超过所有物理内存和交换空间总和的内存
vm.overcommit_memory=1
# OOM时处理
# 1关闭,等于0时,表示当内存耗尽时,内核会触发OOM killer杀掉最耗内存的进程。
vm.panic_on_oom=0
# vm.dirty_background_ratio 用于调整内核如何处理必须刷新到磁盘的脏页。
# Default value is 10.
# 该值是系统内存总量的百分比,在许多情况下将此值设置为5是合适的。
# 此设置不应设置为零。
vm.dirty_background_ratio = 5
# 内核强制同步操作将其刷新到磁盘之前允许的脏页总数
# 也可以通过更改 vm.dirty_ratio 的值(将其增加到默认值30以上(也占系统内存的百分比))来增加
# 推荐 vm.dirty_ratio 的值在60到80之间。
vm.dirty_ratio = 60
# vm.max_map_count 计算当前的内存映射文件数。
# mmap 限制(vm.max_map_count)的最小值是打开文件的ulimit数量(cat /proc/sys/fs/file-max)。
# 每128KB系统内存 map_count应该大约为1。 因此,在32GB系统上,max_map_count为262144。
# Default: 65530
vm.max_map_count = 2097152
#############################################################################################
# 调整文件
#############################################################################################
fs.may_detach_mounts = 1
# 增加文件句柄和inode缓存的大小,并限制核心转储。
fs.file-max = 2097152
fs.nr_open = 2097152
fs.suid_dumpable = 0
# 文件监控
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=524288
fs.inotify.max_queued_events=16384
#############################################################################################
# 调整网络设置
#############################################################################################
# 为每个套接字的发送和接收缓冲区分配的默认内存量。
net.core.wmem_default = 25165824
net.core.rmem_default = 25165824
# 为每个套接字的发送和接收缓冲区分配的最大内存量。
net.core.wmem_max = 25165824
net.core.rmem_max = 25165824
# 除了套接字设置外,发送和接收缓冲区的大小
# 必须使用net.ipv4.tcp_wmem和net.ipv4.tcp_rmem参数分别设置TCP套接字。
# 使用三个以空格分隔的整数设置这些整数,分别指定最小,默认和最大大小。
# 最大大小不能大于使用net.core.wmem_max和net.core.rmem_max为所有套接字指定的值。
# 合理的设置是最小4KiB,默认64KiB和最大2MiB缓冲区。
net.ipv4.tcp_wmem = 20480 12582912 25165824
net.ipv4.tcp_rmem = 20480 12582912 25165824
# 增加最大可分配的总缓冲区空间
# 以页为单位(4096字节)进行度量
net.ipv4.tcp_mem = 65536 25165824 262144
net.ipv4.udp_mem = 65536 25165824 262144
# 为每个套接字的发送和接收缓冲区分配的最小内存量。
net.ipv4.udp_wmem_min = 16384
net.ipv4.udp_rmem_min = 16384
# 启用TCP窗口缩放,客户端可以更有效地传输数据,并允许在代理方缓冲该数据。
net.ipv4.tcp_window_scaling = 1
# 提高同时接受连接数。
net.ipv4.tcp_max_syn_backlog = 10240
# 将net.core.netdev_max_backlog的值增加到大于默认值1000
# 可以帮助突发网络流量,特别是在使用数千兆位网络连接速度时,
# 通过允许更多的数据包排队等待内核处理它们。
net.core.netdev_max_backlog = 65536
# 增加选项内存缓冲区的最大数量
net.core.optmem_max = 25165824
# 被动TCP连接的SYNACK次数。
net.ipv4.tcp_synack_retries = 2
# 允许的本地端口范围。
net.ipv4.ip_local_port_range = 2048 65535
# 防止TCP时间等待
# Default: net.ipv4.tcp_rfc1337 = 0
net.ipv4.tcp_rfc1337 = 1
# 减少tcp_fin_timeout连接的时间默认值
net.ipv4.tcp_fin_timeout = 15
# 积压套接字的最大数量。
# Default is 128.
net.core.somaxconn = 32768
# 打开syncookies以进行SYN洪水攻击保护。
net.ipv4.tcp_syncookies = 1
# 避免Smurf攻击
# 发送伪装的ICMP数据包,目的地址设为某个网络的广播地址,源地址设为要攻击的目的主机,
# 使所有收到此ICMP数据包的主机都将对目的主机发出一个回应,使被攻击主机在某一段时间内收到成千上万的数据包
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 为icmp错误消息打开保护
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 启用自动缩放窗口。
# 如果延迟证明合理,这将允许TCP缓冲区超过其通常的最大值64K。
net.ipv4.tcp_window_scaling = 1
# 打开并记录欺骗,源路由和重定向数据包
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# 告诉内核有多少个未附加的TCP套接字维护用户文件句柄。 万一超过这个数字,
# 孤立的连接会立即重置,并显示警告。
# Default: net.ipv4.tcp_max_orphans = 65536
net.ipv4.tcp_max_orphans = 65536
# 不要在关闭连接时缓存指标
net.ipv4.tcp_no_metrics_save = 1
# 启用RFC1323中定义的时间戳记:
# Default: net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_timestamps = 1
# 启用选择确认。
# Default: net.ipv4.tcp_sack = 1
net.ipv4.tcp_sack = 1
# 增加 tcp-time-wait 存储桶池大小,以防止简单的DOS攻击。
# net.ipv4.tcp_tw_recycle 已从Linux 4.12中删除。请改用net.ipv4.tcp_tw_reuse。
net.ipv4.tcp_max_tw_buckets = 14400
net.ipv4.tcp_tw_reuse = 1
# accept_source_route 选项使网络接口接受设置了严格源路由(SSR)或松散源路由(LSR)选项的数据包。
# 以下设置将丢弃设置了SSR或LSR选项的数据包。
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# 打开反向路径过滤
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 禁用ICMP重定向接受
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# 禁止发送所有IPv4 ICMP重定向数据包。
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# 开启IP转发.
net.ipv4.ip_forward = 1
# 禁止IPv6
net.ipv6.conf.lo.disable_ipv6=1
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
# 要求iptables不对bridge的数据进行处理
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1
# arp缓存
# 存在于 ARP 高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行。缺省值是 128
net.ipv4.neigh.default.gc_thresh1=2048
# 保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒。缺省值是 512
net.ipv4.neigh.default.gc_thresh2=4096
# 保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是 1024
net.ipv4.neigh.default.gc_thresh3=8192
# 持久连接
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 10
# conntrack表
net.nf_conntrack_max=1048576
net.netfilter.nf_conntrack_max=1048576
net.netfilter.nf_conntrack_buckets=262144
net.netfilter.nf_conntrack_tcp_timeout_fin_wait=30
net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
net.netfilter.nf_conntrack_tcp_timeout_close_wait=15
net.netfilter.nf_conntrack_tcp_timeout_established=300
#############################################################################################
# 调整内核参数
#############################################################################################
# 地址空间布局随机化(ASLR)是一种用于操作系统的内存保护过程,可防止缓冲区溢出攻击。
# 这有助于确保与系统上正在运行的进程相关联的内存地址不可预测,
# 因此,与这些流程相关的缺陷或漏洞将更加难以利用。
# Accepted values: 0 = 关闭, 1 = 保守随机化, 2 = 完全随机化
kernel.randomize_va_space = 2
# 调高 PID 数量
kernel.pid_max = 65536
kernel.threads-max=30938
# coredump
kernel.core_pattern=core
# 决定了检测到soft lockup时是否自动panic,缺省值是0
kernel.softlockup_all_cpu_backtrace=1
kernel.softlockup_panic=1
EOF
# history
cat << EOF >> /etc/bashrc
## Kainstall managed start
# history actions record,include action time, user, login ip
HISTFILESIZE=5000
HISTSIZE=5000
USER_IP=\$(who -u am i 2>/dev/null | awk '{print \$NF}' | sed -e 's/[()]//g')
if [ -z \$USER_IP ]
then
USER_IP=\$(hostname -i)
fi
HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S \$USER_IP:\$(whoami) "
export HISTFILESIZE HISTSIZE HISTTIMEFORMAT
# PS1
PS1='\[\033[0m\]\[\033[1;36m\][\u\[\033[0m\]@\[\033[1;32m\]\h\[\033[0m\] \[\033[1;31m\]\w\[\033[0m\]\[\033[1;36m\]]\[\033[33;1m\]\\$ \[\033[0m\]'
## Kainstall managed end
EOF
# journal
mkdir -p /var/log/journal /etc/systemd/journald.conf.d
cat << EOF > /etc/systemd/journald.conf.d/99-prophet.conf
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 3 周
MaxRetentionSec=3week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
# motd
cat << EOF > /etc/profile.d/zz-ssh-login-info.sh
#!/bin/sh
#
# @Time : 2020-02-04
# @Author : lework
# @Desc : ssh login banner
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
shopt -q login_shell && : || return 0
# os
upSeconds="\$(cut -d. -f1 /proc/uptime)"
secs=\$((\${upSeconds}%60))
mins=\$((\${upSeconds}/60%60))
hours=\$((\${upSeconds}/3600%24))
days=\$((\${upSeconds}/86400))
UPTIME_INFO=\$(printf "%d days, %02dh %02dm %02ds" "\$days" "\$hours" "\$mins" "\$secs")
if [ -f /etc/redhat-release ] ; then
PRETTY_NAME=\$(< /etc/redhat-release)
elif [ -f /etc/debian_version ]; then
DIST_VER=\$(</etc/debian_version)
PRETTY_NAME="\$(grep PRETTY_NAME /etc/os-release | sed -e 's/PRETTY_NAME=//g' -e 's/"//g') (\$DIST_VER)"
else
PRETTY_NAME=\$(cat /etc/*-release | grep "PRETTY_NAME" | sed -e 's/PRETTY_NAME=//g' -e 's/"//g')
fi
if [[ -d "/system/app/" && -d "/system/priv-app" ]]; then
model="\$(getprop ro.product.brand) \$(getprop ro.product.model)"
elif [[ -f /sys/devices/virtual/dmi/id/product_name ||
-f /sys/devices/virtual/dmi/id/product_version ]]; then
model="\$(< /sys/devices/virtual/dmi/id/product_name)"
model+=" \$(< /sys/devices/virtual/dmi/id/product_version)"
elif [[ -f /sys/firmware/devicetree/base/model ]]; then
model="\$(< /sys/firmware/devicetree/base/model)"
elif [[ -f /tmp/sysinfo/model ]]; then
model="\$(< /tmp/sysinfo/model)"
fi
MODEL_INFO=\${model}
KERNEL=\$(uname -srmo)
USER_NUM=\$(who -u | wc -l)
RUNNING=\$(ps ax | wc -l | tr -d " ")
# disk
totaldisk=\$(df -h -x devtmpfs -x tmpfs -x debugfs -x aufs -x overlay --total 2>/dev/null | tail -1)
disktotal=\$(awk '{print \$2}' <<< "\${totaldisk}")
diskused=\$(awk '{print \$3}' <<< "\${totaldisk}")
diskusedper=\$(awk '{print \$5}' <<< "\${totaldisk}")
DISK_INFO="\033[0;33m\${diskused}\033[0m of \033[1;34m\${disktotal}\033[0m disk space used (\033[0;33m\${diskusedper}\033[0m)"
# cpu
cpu=\$(awk -F':' '/^model name/ {print \$2}' /proc/cpuinfo | uniq | sed -e 's/^[ \t]*//')
cpun=\$(grep -c '^processor' /proc/cpuinfo)
cpuc=\$(grep '^cpu cores' /proc/cpuinfo | tail -1 | awk '{print \$4}')
cpup=\$(grep '^physical id' /proc/cpuinfo | wc -l)
CPU_INFO="\${cpu} \${cpup}P \${cpuc}C \${cpun}L"
# get the load averages
read one five fifteen rest < /proc/loadavg
LOADAVG_INFO="\033[0;33m\${one}\033[0m / \${five} / \${fifteen} with \033[1;34m\$(( cpun*cpuc ))\033[0m core(s) at \033[1;34m\$(grep '^cpu MHz' /proc/cpuinfo | tail -1 | awk '{print \$4}')\033 MHz"
# mem
MEM_INFO="\$(cat /proc/meminfo | awk '/MemTotal:/{total=\$2/1024/1024;next} /MemAvailable:/{use=total-\$2/1024/1024; printf("\033[0;33m%.2fGiB\033[0m of \033[1;34m%.2fGiB\033[0m RAM used (\033[0;33m%.2f%%\033[0m)",use,total,(use/total)*100);}')"
# network
# extranet_ip=" and \$(curl -s ip.cip.cc)"
IP_INFO="\$(ip a | grep glo | awk '{print \$2}' | head -1 | cut -f1 -d/)\${extranet_ip:-}"
# Container info
CONTAINER_INFO="\$(sudo /usr/bin/crictl ps -a -o yaml 2> /dev/null | awk '/^ state: /{gsub("CONTAINER_", "", \$NF) ++S[\$NF]}END{for(m in S) printf "%s%s:%s ",substr(m,1,1),tolower(substr(m,2)),S[m]}')Images:\$(sudo /usr/bin/crictl images -q 2> /dev/null | wc -l)"
# info
echo -e "
Information as of: \033[1;34m\$(date +"%Y-%m-%d %T")\033[0m
\033[0;1;31mProduct\033[0m............: \${MODEL_INFO}
\033[0;1;31mOS\033[0m.................: \${PRETTY_NAME}
\033[0;1;31mKernel\033[0m.............: \${KERNEL}
\033[0;1;31mCPU\033[0m................: \${CPU_INFO}
\033[0;1;31mHostname\033[0m...........: \033[1;34m\$(hostname)\033[0m
\033[0;1;31mIP Addresses\033[0m.......: \033[1;34m\${IP_INFO}\033[0m
\033[0;1;31mUptime\033[0m.............: \033[0;33m\${UPTIME_INFO}\033[0m
\033[0;1;31mMemory\033[0m.............: \${MEM_INFO}
\033[0;1;31mLoad Averages\033[0m......: \${LOADAVG_INFO}
\033[0;1;31mDisk Usage\033[0m.........: \${DISK_INFO}
\033[0;1;31mUsers online\033[0m.......: \033[1;34m\${USER_NUM}\033[0m
\033[0;1;31mRunning Processes\033[0m..: \033[1;34m\${RUNNING}\033[0m
\033[0;1;31mContainer Info\033[0m.....: \${CONTAINER_INFO}
"
EOF
chmod +x /etc/profile.d/zz-ssh-login-info.sh
echo 'ALL ALL=(ALL) NOPASSWD:/usr/bin/crictl' > /etc/sudoers.d/crictl
# time sync
ntpd --help >/dev/null 2>&1 && yum remove -y ntp
yum install -y chrony
[ ! -f /etc/chrony.conf_bak ] && cp /etc/chrony.conf{,_bak} #备份默认配置
cat << EOF > /etc/chrony.conf
server ntp.aliyun.com iburst
server cn.ntp.org.cn iburst
server ntp.shu.edu.cn iburst
server 0.cn.pool.ntp.org iburst
server 1.cn.pool.ntp.org iburst
server 2.cn.pool.ntp.org iburst
server 3.cn.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
logdir /var/log/chrony
EOF
timedatectl set-timezone Asia/Shanghai
chronyd -q -t 1 'server cn.pool.ntp.org iburst maxsamples 1'
systemctl enable chronyd
systemctl start chronyd
chronyc sources -v
chronyc sourcestats
hwclock --systohc
# package
yum install -y curl wget
# ipvs
yum install -y ipvsadm ipset sysstat conntrack libseccomp
module=(
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
overlay
nf_conntrack
br_netfilter
)
[ -f /etc/modules-load.d/ipvs.conf ] && cp -f /etc/modules-load.d/ipvs.conf{,_bak}
for kernel_module in "${module[@]}";do
/sbin/modinfo -F filename "$kernel_module" |& grep -qv ERROR && echo "$kernel_module" >> /etc/modules-load.d/ipvs.conf
done
systemctl restart systemd-modules-load
systemctl enable systemd-modules-load
sysctl --system
# audit
yum install -y audit audit-libs
cat << EOF >> /etc/audit/rules.d/audit.rules
## Kainstall managed start
# Ignore errors
-i
# SYSCALL
-a always,exit -F arch=b64 -S kill,tkill,tgkill -F a1=9 -F key=trace_kill_9
-a always,exit -F arch=b64 -S kill,tkill,tgkill -F a1=15 -F key=trace_kill_15
# docker
-w /usr/bin/dockerd -k docker
-w /var/lib/docker -k docker
-w /etc/docker -k docker
-w /usr/lib/systemd/system/docker.service -k docker
-w /etc/systemd/system/docker.service -k docker
-w /usr/lib/systemd/system/docker.socket -k docker
-w /etc/default/docker -k docker
-w /etc/sysconfig/docker -k docker
-w /etc/docker/daemon.json -k docker
# containerd
-w /usr/bin/containerd -k containerd
-w /var/lib/containerd -k containerd
-w /usr/lib/systemd/system/containerd.service -k containerd
-w /etc/containerd/config.toml -k containerd
# cri-o
-w /usr/bin/crio -k cri-o
-w /etc/crio -k cri-o
# runc
-w /usr/bin/runc -k runc
# kube
-w /usr/bin/kubeadm -k kubeadm
-w /usr/bin/kubelet -k kubelet
-w /usr/bin/kubectl -k kubectl
-w /var/lib/kubelet -k kubelet
-w /etc/kubernetes -k kubernetes
## Kainstall managed end
EOF
chmod 600 /etc/audit/rules.d/audit.rules
sed -i 's#max_log_file =.*#max_log_file = 80#g' /etc/audit/auditd.conf
if [ -f /usr/libexec/initscripts/legacy-actions/auditd/restart ]; then
/usr/libexec/initscripts/legacy-actions/auditd/restart
else
systemctl stop auditd && systemctl start auditd
fi
systemctl enable auditd

338
shell/k8s/diagnose_k8s.sh

@ -0,0 +1,338 @@
#!/usr/bin/env bash
set -x
current_dir=$(pwd)
timestamp=$(date +%s)
diagnose_dir=/tmp/diagnose_${timestamp}
mkdir -p $diagnose_dir
is_ps_hang=false
run() {
echo
echo "-----------------run $@------------------"
timeout 10s $@
if [ "$?" != "0" ]; then
echo "failed to collect info: $@"
fi
echo "------------End of ${1}----------------"
}
os_env()
{
grep -q "Ubuntu" /etc/os-release && export OS="Ubuntu" && return
grep -q "SUSE" /etc/os-release && export OS="SUSE" && return
grep -q "Red Hat" /etc/os-release && export OS="RedHat" && return
grep -q "CentOS Linux" /etc/os-release && export OS="CentOS" && return
grep -q "Kylin Linux" /etc/os-release && export OS="CentOS" && return
grep -q "Aliyun Linux" /etc/os-release && export OS="AliyunOS" && return
grep -q "Alibaba Group Enterprise Linux" /etc/os-release && export OS="AliOS" && return
echo "unknown os... exit."
exit 1
}
dist() {
cat /etc/issue*
}
command_exists() {
command -v "$@" > /dev/null 2>&1
}
# Service status
service_status() {
run service firewalld status | tee $diagnose_dir/service_status
run service ntpd status | tee $diagnose_dir/service_status
run service chronyd status | tee $diagnose_dir/service_status
}
#system info
system_info() {
# mkdir -p ${diagnose_dir}/system_info
run uname -a | tee -a ${diagnose_dir}/system_info
run uname -r | tee -a ${diagnose_dir}/system_info
run dist | tee -a ${diagnose_dir}/system_info
if command_exists lsb_release; then
run lsb_release | tee -a ${diagnose_dir}/system_info
fi
run ulimit -a | tee -a ${diagnose_dir}/system_info
run sysctl -a | tee -a ${diagnose_dir}/system_info
}
#network
network_info() {
# mkdir -p ${diagnose_dir}/network_info
#run ifconfig
run ip --details ad show | tee -a ${diagnose_dir}/network_info
run ip --details link show | tee -a ${diagnose_dir}/network_info
run ip route show | tee -a ${diagnose_dir}/network_info
run iptables-save | tee -a ${diagnose_dir}/network_info
netstat -nt | tee -a ${diagnose_dir}/network_info
netstat -nu | tee -a ${diagnose_dir}/network_info
netstat -ln | tee -a ${diagnose_dir}/network_info
}
# check ps -ef command is hung
check_ps_hang() {
echo "check if ps -ef command hang" | tee -a ${diagnose_dir}/ps_command_status
checkD=$(timeout -s 9 2 ps -ef)
if [ "$?" != "0" ]; then
echo "ps -ef command is hung" | tee -a ${diagnose_dir}/ps_command_status
is_ps_hang=true
echo "start to check which process lead to ps -ef command hang" | tee -a ${diagnose_dir}/ps_command_status
for f in `find /proc/*/task -name status`
do
checkD=$(cat $f|grep "State.*D")
if [ "$?" == "0" ]; then
cmdline=$(echo ${f%%status}"cmdline")
pid=$(echo ${f%%status}"")
stack=$(echo ${f%%status}"stack")
timeout -s 9 2 cat $cmdline
if [ "$?" != "0" ]; then
echo "process $pid is in State D and lead to ps -ef process hang,stack info:" | tee -a ${diagnose_dir}/ps_command_status
cat $stack | tee -a ${diagnose_dir}/ps_command_status
fi
fi
done
echo "finish to check which process lead to ps -ef command hang" | tee -a ${diagnose_dir}/ps_command_status
else
echo "ps -ef command works fine" | tee -a ${diagnose_dir}/ps_command_status
fi
}
#system status
system_status() {
#mkdir -p ${diagnose_dir}/system_status
run uptime | tee -a ${diagnose_dir}/system_status
run top -b -n 1 | tee -a ${diagnose_dir}/system_status
if [ "$is_ps_hang" == "false" ]; then
run ps -ef | tee -a ${diagnose_dir}/system_status
else
echo "ps -ef command hang, skip [ps -ef] check" | tee -a ${diagnose_dir}/system_status
fi
run netstat -nt | tee -a ${diagnose_dir}/system_status
run netstat -nu | tee -a ${diagnose_dir}/system_status
run netstat -ln | tee -a ${diagnose_dir}/system_status
run df -h | tee -a ${diagnose_dir}/system_status
run cat /proc/mounts | tee -a ${diagnose_dir}/system_status
if [ "$is_ps_hang" == "false" ]; then
run pstree -al | tee -a ${diagnose_dir}/system_status
else
echo "ps -ef command hang, skip [pstree -al] check" | tee -a ${diagnose_dir}/system_status
fi
run lsof | tee -a ${diagnose_dir}/system_status
(
cd /proc
find -maxdepth 1 -type d -name '[0-9]*' \
-exec bash -c "ls {}/fd/ | wc -l | tr '\n' ' '" \; \
-printf "fds (PID = %P), command: " \
-exec bash -c "tr '\0' ' ' < {}/cmdline" \; \
-exec echo \; | sort -rn | head | tee -a ${diagnose_dir}/system_status
)
}
daemon_status() {
run systemctl status docker -l | tee -a ${diagnose_dir}/docker_status
run systemctl status containerd -l | tee -a ${diagnose_dir}/containerd_status
run systemctl status container-storaged -l | tee -a ${diagnose_dir}/container-storaged_status
run systemctl status kubelet -l | tee -a ${diagnose_dir}/kubelet_status
}
docker_status() {
#mkdir -p ${diagnose_dir}/docker_status
echo "check dockerd process"
if [ "$is_ps_hang" == "false" ]; then
run ps -ef|grep -E 'dockerd|docker daemon'|grep -v grep| tee -a ${diagnose_dir}/docker_status
else
echo "ps -ef command hang, skip [ps -ef|grep -E 'dockerd|docker daemon'] check" | tee -a ${diagnose_dir}/docker_status
fi
#docker info
run docker info | tee -a ${diagnose_dir}/docker_status
run docker version | tee -a ${diagnose_dir}/docker_status
sudo kill -SIGUSR1 $(cat /var/run/docker.pid)
cp /var/run/docker/libcontainerd/containerd/events.log ${diagnose_dir}/containerd_events.log
sleep 10
cp /var/run/docker/*.log ${diagnose_dir}
}
showlog() {
local file=$1
if [ -f "$file" ]; then
tail -n 200 $file
fi
}
#collect log
common_logs() {
log_tail_lines=10000
mkdir -p ${diagnose_dir}/logs
run dmesg -T | tail -n ${log_tail_lines} | tee ${diagnose_dir}/logs/dmesg.log
tail -c 500M /var/log/messages &> ${diagnose_dir}/logs/messages
pidof systemd && journalctl -n ${log_tail_lines} -u docker.service &> ${diagnose_dir}/logs/docker.log || tail -n ${log_tail_lines} /var/log/upstart/docker.log &> ${diagnose_dir}/logs/docker.log
}
archive() {
tar -zcvf ${current_dir}/diagnose_${timestamp}.tar.gz ${diagnose_dir}
echo "please get diagnose_${timestamp}.tar.gz for diagnostics"
}
varlogmessage(){
grep cloud-init /var/log/messages > $diagnose_dir/varlogmessage.log
}
cluster_dump(){
kubectl cluster-info dump > $diagnose_dir/cluster_dump.log
}
events(){
kubectl get events > $diagnose_dir/events.log
}
core_component() {
local comp="$1"
local label="$2"
mkdir -p $diagnose_dir/cs/$comp/
local pods=`kubectl get -n kube-system po -l $label=$comp | awk '{print $1}'|grep -v NAME`
for po in ${pods}
do
kubectl logs -n kube-system ${po} &> $diagnose_dir/cs/${comp}/${po}.log
done
}
etcd() {
journalctl -u etcd -xe &> $diagnose_dir/cs/etcd.log
}
storageplugins() {
mkdir -p ${diagnose_dir}/storage/
cp /var/log/alicloud/* ${diagnose_dir}/storage/
}
sandbox_runtime_status() {
if [[ ! -z $(pidof dockerd) || -z $(pidof containerd) ]]; then
return 0
fi
wget http://aliacs-k8s-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/public/diagnose/sandbox-runtime-status.tgz -q -O ${diagnose_dir}/sandbox-runtime-status.tgz
tar -xzvf ${diagnose_dir}/sandbox-runtime-status.tgz -C ${diagnose_dir}
pushd ${diagnose_dir}/sandbox-runtime-status
bash script_collect.sh >> $diagnose_dir/sandbox_runtime.status
popd
}
upload_oss() {
if [[ "$UPLOAD_OSS" == "" ]]; then
return 0
fi
bucket_path=${UPLOAD_OSS}
diagnose_file=diagnose_${timestamp}.tar.gz
if ! command_exists ossutil; then
curl -o /usr/local/bin/ossutil http://gosspublic.alicdn.com/ossutil/1.6.10/ossutil64
chmod u+x /usr/local/bin/ossutil
fi
region=$(curl http://100.100.100.200/latest/meta-data/region-id)
endpoint="oss-$region.aliyuncs.com"
if [[ "$ACCESS_KEY_ID" == "" ]]; then
roleName=$(curl 100.100.100.200/latest/meta-data/ram/security-credentials/)
echo "
[Credentials]
language = CH
endpoint = $endpoint
[AkService]
ecsAk=http://100.100.100.200/latest/meta-data/Ram/security-credentials/$roleName" > ./config
else
echo "
[Credentials]
language = CH
endpoint = $endpoint
accessKeyID = $ACCESS_KEY_ID
accessKeySecret = $ACCESS_KEY_SECRET
" > ./config
fi
bucket_name=${bucket_path%%/*}
oss_endpoint=$(ossutil stat oss://$bucket_name --config-file ./config | grep ExtranetEndpoint | awk '{print $3}')
if [[ "$oss_endpoint" != "" ]]; then
endpoint=$oss_endpoint
fi
ossutil cp ./${diagnose_file} oss://$bucket_path/$diagnose_file --config-file ./config --endpoint $endpoint
if [[ "$OSS_PUBLIC_LINK" != "" ]]; then
ossutil sign --timeout 7200 oss://$bucket_path/$diagnose_file --config-file ./config --endpoint $endpoint
fi
}
parse_args() {
while
[[ $# -gt 0 ]]
do
key="$1"
case $key in
--oss)
export UPLOAD_OSS=$2
shift
;;
--oss-public-link)
export OSS_PUBLIC_LINK="true"
;;
--access-key-id)
export ACCESS_KEY_ID=$2
shift
;;
--access-key-secret)
export ACCESS_KEY_SECRET=$2
shift
;;
*)
echo "unknown option [$key]"
;;
esac
shift
done
}
pd_collect() {
os_env
system_info
service_status
network_info
check_ps_hang
system_status
docker_status
sandbox_runtime_status
common_logs
varlogmessage
core_component "cloud-controller-manager" "app"
core_component "kube-apiserver" "component"
core_component "kube-controller-manager" "component"
core_component "kube-scheduler" "component"
events
storageplugins
etcd
cluster_dump
archive
}
parse_args "$@"
pd_collect
upload_oss
echo "请上传 diagnose_${timestamp}.tar.gz"

2
shell/library.sh

@ -803,4 +803,4 @@ function utils::quote() {
else else
echo "$@" echo "$@"
fi fi
} }

66
shell/poorjson.sh

@ -0,0 +1,66 @@
#!/bin/sh
# A POSIX compatible JSON parser within 60 lines of code (without comments)
# Usage example:
# $ echo '{ "key1" : { "key2": {}, "key3": [null, true, false, "value"]}}' | ./poorjson.sh '"key1"' '"key3"' 3
# $ "value"
# shellcheck disable=SC2015
__JNUM='\(-\?\(0\|[1-9][0-9]*\)\(\.[0-9]\+\)\?\([eE][+-]\?[0-9]\+\)\?\)'
__JSTR='\("\([^[:cntrl:]"]\|\\["\\\/bfnrt]\|u[0-9]{4}\)*"\)'
_TOKEN="" _TMP="" __JTOK="$__JSTR\|$__JNUM\|true\|false\|null\|[][}{,:]"
_is_match() { [ "$1" = "$2" ] || [ "$1" = \* ] || [ "$1" = . ]; }
_eof_error() { echo "Unexpected EOF after \"$_TOKEN\""; exit 1; }
_token_error() { echo "Unexpected token \"$_TOKEN\""; exit 1; }
_jread() {
read -r _TOKEN || _eof_error
[ "$1" = . ] && echo "$_TOKEN"
}
_jarr() {
if _is_match "$1" 0; then _jval "$@"; else _jval; fi || {
[ "$_TOKEN" = ']' ] && return || _token_error
}
while :; do
_jread "$1";
case $_TOKEN in "]") return 0;;
",") [ "$1" -ge 0 ] 2>/dev/null && _TMP=$(( $1 - 1)) && shift && set -- "$_TMP" "$@";;
*) _token_error;;
esac
if _is_match "$1" 0; then _jval "$@"; else _jval; fi || _token_error
done
}
_jobj() {
_jread "$1"; [ "$_TOKEN" = "}" ] && return 0
while :; do
_TMP=$_TOKEN
case $_TMP in '"'*'"')
_jread "$1"
[ "$_TOKEN" = ":" ] || _token_error
if _is_match "$1" "$_TMP"; then _jval "$@"; else _jval; fi || _token_error
_jread "$1"
[ "$_TOKEN" = "}" ] && return 0
[ "$_TOKEN" != "," ] && _token_error
_jread "$1"
continue
;;
esac
_token_error
done
}
_jval() {
[ "$#" -eq 0 ] || [ "$*" = . ] || shift
_jread "$1"
case $_TOKEN in '{') _jobj "$@";;
"[") _jarr "$@";;
true|false|null|-*|[0-9]*|'"'*'"') [ "$1" = \* ] && echo "$_TOKEN"; :;;
*) return 1;;
esac
}
sed -e "s/\($__JTOK\)/\n\1\n/g" | sed -e "/^\s*$/d;/$__JTOK/!{q255};" | { _jval "" "$@" . && ! read -r; } || {
echo "JSON string invalid."
exit 1
}

955
shell/test/ssl-cert-check.sh

@ -0,0 +1,955 @@
#!/usr/bin/env bash
PROGRAMVERSION=4.14
#
# Program: SSL Certificate Check <ssl-cert-check>
#
# Source code home: https://github.com/Matty9191/ssl-cert-check
#
# Documentation: http://prefetch.net/articles/checkcertificate.html
#
# Author: Matty < matty at prefetch dot net >
#
# Last Updated: 11-12-2020
#
# Revision History:
#
# Version 4.14
# - Fixed HOST / PORT discovery @mhow2
#
# Version 4.13
# - Reverted the file checking logic which breaks $RETCODE
#
# Version 4.12
# - Fixed various logic errors and typos -- Daniel Lewart
#
# Version 4.10
# - Replace tabs with spaces
# - More shllcheck cleanup work
# - Remove unused DEBUG variable
# - Fixed an innocuous whitespace bug in TLSFLAG variable creation
# - Set the default TLS version to 1.1 (can be overridden with -v)
# - Switched openssl CLI options to use an array. The reasons why
# are documented here: http://mywiki.wooledge.org/BashFAQ/050
#
# Version 4.9
# - Add a signal handler to call the cleanup funtion
# if the script doesn't exit() cleanly -- Timothe Litt
#
# Version 4.8
# - More mail client fixes
#
# Version 4.7
# - Revert SENDER to ""
# - More shellcheck cleanup
#
# Version 4.6
# - Fixed programming logic error
#
# Version 4.5
# - Re-work mailx support for FreeBSD
# - More shellcheck fixes
#
# Version 4.4
# - Use command -v instead of which utility to satisfy shellcheck.
# - Fix unquoted MAIL and MAILMODE variables in help output
# - More shellcheck fixes
#
# Version 4.3
# - Fixed a typo in the program version
#
# Version 4.2
# - Change CERTDAYS to CERTDIFF in the e-mail subject.
#
# Version 4.1
# - Fix usage output
#
# Version 4.0
# - Updated the script syntax to align with UNIX shell programming
# - Check for DNS resolution failures
# - First round of updates to make shellcheck happy
# - Rework the logic to call mailx.
# - Print the version with the "-V" option.
# - Define the version in the PROGRAMVERSION variable
#
# Version 3.31
# - Fixed the test for the -servername flag -- Kitson Consulting.
#
# Version 3.30
# - Use highest returncode for Nagios output -- Marcel Pennewiss
# - Set RETCODE to 3 (unknown) if a certificate file does not exist -- Marcel Pennewiss
# - Add a "-d" option to specify a directory or file mask pattern -- Marcel Pennewiss
# - Add a "-N" option to create summarized Nagios output -- Marcel Pennewiss
# - Cleaned up many formatting -- Marcel Pennewiss
#
# Versione 3.29a
# - Added option to specify email sender address
#
# Version 3.29
# - Add the openssl -servername flag if it shows up in help.
#
# Version 3.28
# - Added a DEBUG option to assist with debugging folks who use the script
#
# Version 3.27
# - Allow white spaces to exist in the certificate file list
# - Add an additional check to pick up bad / non-existent certificates
# - Add a check to look for the existence of a mail program. Error out if it's not present.
# - Enable the TLS -servername extension by default - Juergen Knaack & Johan Denoyer
#
# Version 3.26
# - Allow the certificate type (PEM, DER, NET) to be passed on the command line
#
# Version 3.25
# - Check for "no route to host" errors -- Dan Doyle
# - Set RETCODE to 3 (unknown) if a connection error occurs -- Dan Doyle
# - Documentation fixes
#
# Version 3.24
# - Utilize the -clcerts option to limit the results to client certificates - Eitan Katznelson
#
# Version 3.23
# - Fixed typo in date2julian routine -- Ken Cook
#
# Version 3.22
# - Change the validation option to "-V"
# - Add a "-v" option to specify a specific protocol version (ssl2, ssl3 or tls)
#
# Version 3.21
# - Adjust e-mail checking to avoid exiting if notifications aren't enabled -- Nick Anderson
# - Added the number of days until expiration to the Nagios output -- Nick Anderson
#
# Version 3.20
# - Fixed a bug in certificate length checking -- Tim Nowaczyk
#
# Version 3.19
# - Added check to verify the certificate retrieved is valid
#
# Version 3.18
# - Add support for connecting to FTP servers -- Paul A Sand
#
# Version 3.17
# - Add support for connecting to imap servers -- Joerg Pareigis
#
# Version 3.16
# - Add support for connecting to the mail sbmission port -- Luis E. Munoz
#
# Version 3.15
# - Adjusted the file checking logic to use the correct certificate -- Maciej Szudejko
# - Add sbin to the default search paths for OpenBSD compatibility -- Alex Popov
# - Use cut instead of substring processing to ensure compatibility -- Alex Popov
#
# Version 3.14
# - Fixed the Common Name parser to handle DN's where the CN is not the last item
# eg. EmailAddr -- Jason Brothers
# - Added the ability to grab the serial number -- Jason Brothers
# - Added the "-b" option to print results without a header -- Jason Brothers
# - Added the "-v" option for certificate validation -- Jason Brothers
#
# Version 3.13
# - Updated the subject line to include the hostname as well as
# the common name embedded in the X509 certificate (if it's
# available) -- idea proposed by Mike Burns
#
# Version 3.12
# - Updated the license to allow redistribution and modification
#
# Version 3.11
# - Added ability to comment out lines in files passed
# to the "-f" option -- Brett Stauner
# - Fixed comment next to file processing logic
#
# Version 3.10
# - Fixed POP3 port -- Simon Matter
#
# Version 3.9
# - Switched binary location logic to use which utility
#
# Version 3.8
# - Fixed display on 80 column displays
# - Cleaned up the formatting
#
# Version 3.7
# - Fixed bug in NAGIOS tests -- Ben Allen
#
# Version 3.6
# - Added support for certificates stored in PKCS#12 databases -- Ken Gallo
# - Cleaned up comments
# - Adjusted variables to be more consistent
#
# Version 3.5
# - Added support for NAGIOS -- Quanah Gibson-Mount
# - Added additional checks for mail -- Quanah Gibson-Mount
# - Convert tabs to spaces -- Quanah Gibson-Mount
# - Cleaned up usage() routine
# - Added additional checks for openssl
#
# Version 3.4
# - Added a missing "{" to line 364 -- Ken Gallo
# - Move mktemp to the start of the main body to avoid errors
# - Adjusted default binary paths to make sure the script just works
# w/ Solaris, BSD and Linux hosts
#
# Version 3.3
# - Added common name from X.509 certificate file to E-mail body / header -- Doug Curtis
# - Fixed several documentation errors
# - Use mktemp to create temporary files
# - Convert printf, sed and awk to variables
# - Check for printf, sed, awk and mktemp binaries
# - Add additional logic to make sure mktemp returned a valid temporary file
#
# Version 3.2
# - Added option to list certificates in the file passed to "-f".
#
# Version 3.1
# - Added handling for starttls for smtp -- Marco Amrein
# - Added handling for starttls for pop3 (without s) -- Marco Amrein
# - Removed extra spacing at end of script
#
# Version 3.0
# - Added "-i" option to print certificate issuer
# - Removed $0 from Subject line of outbound e-mails
# - Fixed some typographical errors
# - Removed redundant "-b" option
#
# Version 2.0
# - Fixed an issue with e-mails formatting incorrectly
# - Added additional space to host column -- Darren-Perot Spruell
# - Replaced GNU date dependency with CHRIS F. A. JOHNSON's
# date2julian shell function. This routine can be found on
# page 170 of Chris's book "Shell Scripting Recipes: A
# Problem-Solution Approach," ISBN #1590594711. Julian function
# was created based on a post to comp.unix.shell by Tapani Tarvainen.
# - Cleaned up function descriptions
# - Removed several lines of redundant code
# - Adjusted the help message
#
# Version 1.1
# - Added "-c" flag to report expiration status of a PEM encoded
# certificate -- Hampus Lundqvist
# - Updated the prints messages to display the reason a connection
# failed (connection refused, connection timeout, bad cert, etc)
# - Updated the GNU date checking routines
# - Added checks for each binary required
# - Added checks for connection timeouts
# - Added checks for GNU date
# - Added a "-h" option
# - Cleaned up the documentation
#
# Version 1.0
# Initial Release
#
# Purpose:
# ssl-cert-check checks to see if a digital certificate in X.509 format
# has expired. ssl-cert-check can be run in interactive and batch mode,
# and provides facilities to alarm if a certificate is about to expire.
#
# License:
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Requirements:
# Requires openssl
#
# Installation:
# Copy the shell script to a suitable location
#
# Tested platforms:
# -- Solaris 9 using /bin/bash
# -- Solaris 10 using /bin/bash
# -- OS X 10.4.2 using /bin/bash
# -- OpenBSD using /bin/sh
# -- FreeBSD using /bin/sh
# -- Centos Linux 3, 4, 5 & 6 using /bin/bash
# -- Redhat Enterprise Linux 3, 4, 5 & 6 using /bin/bash
# -- Gentoo using /bin/bash
#
# Usage:
# Refer to the usage() sub-routine, or invoke ssl-cert-check
# with the "-h" option.
#
# Examples:
# Please refer to the following site for documentation and examples:
# http://prefetch.net/articles/checkcertificate.html
# Cleanup temp files if they exist
trap cleanup EXIT INT TERM QUIT
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/ssl/bin:/usr/sfw/bin
export PATH
# Who to page when an expired certificate is detected (cmdline: -e)
ADMIN="root"
# Email sender address for alarm notifications
SENDER=""
# Number of days in the warning threshhold (cmdline: -x)
WARNDAYS=30
# If QUIET is set to TRUE, don't print anything on the console (cmdline: -q)
QUIET="FALSE"
# Don't send E-mail by default (cmdline: -a)
ALARM="FALSE"
# Don't run as a Nagios plugin by default (cmdline: -n)
NAGIOS="FALSE"
# Don't summarize Nagios output by default (cmdline: -N)
NAGIOSSUMMARY="FALSE"
# NULL out the PKCSDBPASSWD variable for later use (cmdline: -k)
PKCSDBPASSWD=""
# Type of certificate (PEM, DER, NET) (cmdline: -t)
CERTTYPE="pem"
# Location of system binaries
AWK=$(command -v awk)
DATE=$(command -v date)
GREP=$(command -v grep)
OPENSSL=$(command -v openssl)
PRINTF=$(command -v printf)
SED=$(command -v sed)
MKTEMP=$(command -v mktemp)
FIND=$(command -v find)
# Try to find a mail client
if [ -f /usr/bin/mailx ]; then
MAIL="/usr/bin/mailx"
MAILMODE="mailx"
elif [ -f /bin/mail ]; then
MAIL="/bin/mail"
MAILMODE="mail"
elif [ -f /usr/bin/mail ]; then
MAIL="/usr/bin/mail"
MAILMODE="mail"
elif [ -f /sbin/mail ]; then
MAIL="/sbin/mail"
MAILMODE="mail"
elif [ -f /usr/sbin/mail ]; then
MAIL="/usr/sbin/mail"
MAILMODE="mail"
elif [ -f /usr/sbin/sendmail ]; then
MAIL="/usr/sbin/sendmail"
MAILMODE="sendmail"
else
MAIL="cantfindit"
MAILMODE="cantfindit"
fi
# Return code used by nagios. Initialize to 0.
RETCODE=0
# Certificate counters and minimum difference. Initialize to 0.
SUMMARY_VALID=0
SUMMARY_WILL_EXPIRE=0
SUMMARY_EXPIRED=0
SUMMARY_MIN_DIFF=0
SUMMARY_MIN_DATE=
SUMMARY_MIN_HOST=
SUMMARY_MIN_PORT=
# Set the default umask to be somewhat restrictive
umask 077
#####################################################
# Purpose: Remove temporary files if the script doesn't
# exit() cleanly
#####################################################
cleanup() {
if [ -f "${CERT_TMP}" ]; then
rm -f "${CERT_TMP}"
fi
if [ -f "${ERROR_TMP}" ]; then
rm -f "${ERROR_TMP}"
fi
}
#####################################################
### Send email
### Accepts three parameters:
### $1 -> sender email address
### $2 -> email to send mail
### $3 -> Subject
### $4 -> Message
#####################################################
send_mail() {
FROM="${1}"
TO="${2}"
SUBJECT="${3}"
MSG="${4}"
case "${MAILMODE}" in
"mail")
echo "$MSG" | "${MAIL}" -r "$FROM" -s "$SUBJECT" "$TO"
;;
"mailx")
echo "$MSG" | "${MAIL}" -s "$SUBJECT" "$TO"
;;
"sendmail")
(echo "Subject:$SUBJECT" && echo "TO:$TO" && echo "FROM:$FROM" && echo "$MSG") | "${MAIL}" "$TO"
;;
"*")
echo "ERROR: You enabled automated alerts, but the mail binary could not be found."
echo "FIX: Please modify the \${MAIL} and \${MAILMODE} variable in the program header."
exit 1
;;
esac
}
#############################################################################
# Purpose: Convert a date from MONTH-DAY-YEAR to Julian format
# Acknowledgements: Code was adapted from examples in the book
# "Shell Scripting Recipes: A Problem-Solution Approach"
# ( ISBN 1590594711 )
# Arguments:
# $1 -> Month (e.g., 06)
# $2 -> Day (e.g., 08)
# $3 -> Year (e.g., 2006)
#############################################################################
date2julian() {
if [ "${1}" != "" ] && [ "${2}" != "" ] && [ "${3}" != "" ]; then
## Since leap years add aday at the end of February,
## calculations are done from 1 March 0000 (a fictional year)
d2j_tmpmonth=$((12 * $3 + $1 - 3))
## If it is not yet March, the year is changed to the previous year
d2j_tmpyear=$(( d2j_tmpmonth / 12))
## The number of days from 1 March 0000 is calculated
## and the number of days from 1 Jan. 4713BC is added
echo $(( (734 * d2j_tmpmonth + 15) / 24
- 2 * d2j_tmpyear + d2j_tmpyear/4
- d2j_tmpyear/100 + d2j_tmpyear/400 + $2 + 1721119 ))
else
echo 0
fi
}
#############################################################################
# Purpose: Convert a string month into an integer representation
# Arguments:
# $1 -> Month name (e.g., Sep)
#############################################################################
getmonth()
{
case ${1} in
Jan) echo 1 ;;
Feb) echo 2 ;;
Mar) echo 3 ;;
Apr) echo 4 ;;
May) echo 5 ;;
Jun) echo 6 ;;
Jul) echo 7 ;;
Aug) echo 8 ;;
Sep) echo 9 ;;
Oct) echo 10 ;;
Nov) echo 11 ;;
Dec) echo 12 ;;
*) echo 0 ;;
esac
}
#############################################################################
# Purpose: Calculate the number of seconds between two dates
# Arguments:
# $1 -> Date #1
# $2 -> Date #2
#############################################################################
date_diff()
{
if [ "${1}" != "" ] && [ "${2}" != "" ]; then
echo $((${2} - ${1}))
else
echo 0
fi
}
#####################################################################
# Purpose: Print a line with the expiraton interval
# Arguments:
# $1 -> Hostname
# $2 -> TCP Port
# $3 -> Status of certification (e.g., expired or valid)
# $4 -> Date when certificate will expire
# $5 -> Days left until the certificate will expire
# $6 -> Issuer of the certificate
# $7 -> Common Name
# $8 -> Serial Number
#####################################################################
prints()
{
if [ "${NAGIOSSUMMARY}" = "TRUE" ]; then
return
fi
if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]; then
MIN_DATE=$(echo "$4" | "${AWK}" '{ printf "%3s %2d %4d", $1, $2, $4 }')
if [ "${NAGIOS}" = "TRUE" ]; then
${PRINTF} "%-35s %-17s %-8s %-11s %s\n" "$1:$2" "$6" "$3" "$MIN_DATE" "|days=$5"
else
${PRINTF} "%-35s %-17s %-8s %-11s %4d\n" "$1:$2" "$6" "$3" "$MIN_DATE" "$5"
fi
elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" = "TRUE" ]; then
${PRINTF} "%-35s %-35s %-32s %-17s\n" "$1:$2" "$7" "$8" "$6"
elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]; then
MIN_DATE=$(echo "$4" | "${AWK}" '{ printf "%3s %2d, %4d", $1, $2, $4 }')
if [ "${NAGIOS}" = "TRUE" ]; then
${PRINTF} "%-47s %-12s %-12s %s\n" "$1:$2" "$3" "$MIN_DATE" "|days=$5"
else
${PRINTF} "%-47s %-12s %-12s %4d\n" "$1:$2" "$3" "$MIN_DATE" "$5"
fi
elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" = "TRUE" ]; then
${PRINTF} "%-35s %-35s %-32s\n" "$1:$2" "$7" "$8"
fi
}
####################################################
# Purpose: Print a heading with the relevant columns
# Arguments:
# None
####################################################
print_heading()
{
if [ "${NOHEADER}" != "TRUE" ]; then
if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]; then
${PRINTF} "\n%-35s %-17s %-8s %-11s %-4s\n" "Host" "Issuer" "Status" "Expires" "Days"
echo "----------------------------------- ----------------- -------- ----------- ----"
elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" = "TRUE" ]; then
${PRINTF} "\n%-35s %-35s %-32s %-17s\n" "Host" "Common Name" "Serial #" "Issuer"
echo "----------------------------------- ----------------------------------- -------------------------------- -----------------"
elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]; then
${PRINTF} "\n%-47s %-12s %-12s %-4s\n" "Host" "Status" "Expires" "Days"
echo "----------------------------------------------- ------------ ------------ ----"
elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" = "TRUE" ]; then
${PRINTF} "\n%-35s %-35s %-32s\n" "Host" "Common Name" "Serial #"
echo "----------------------------------- ----------------------------------- --------------------------------"
fi
fi
}
####################################################
# Purpose: Print a summary for nagios
# Arguments:
# None
####################################################
print_summary()
{
if [ "${NAGIOSSUMMARY}" != "TRUE" ]; then
return
fi
if [ ${SUMMARY_WILL_EXPIRE} -eq 0 ] && [ ${SUMMARY_EXPIRED} -eq 0 ]; then
${PRINTF} "%s valid certificate(s)|days=%s\n" "${SUMMARY_VALID}" "${SUMMARY_MIN_DIFF}"
elif [ ${SUMMARY_EXPIRED} -ne 0 ]; then
${PRINTF} "%s certificate(s) expired (%s:%s on %s)|days=%s\n" "${SUMMARY_EXPIRED}" "${SUMMARY_MIN_HOST}" "${SUMMARY_MIN_PORT}" "${SUMMARY_MIN_DATE}" "${SUMMARY_MIN_DIFF}"
elif [ ${SUMMARY_WILL_EXPIRE} -ne 0 ]; then
${PRINTF} "%s certificate(s) will expire (%s:%s on %s)|days=%s\n" "${SUMMARY_WILL_EXPIRE}" "${SUMMARY_MIN_HOST}" "${SUMMARY_MIN_PORT}" "${SUMMARY_MIN_DATE}" "${SUMMARY_MIN_DIFF}"
fi
}
#############################################################
# Purpose: Set returncode to value if current value is lower
# Arguments:
# $1 -> New returncorde
#############################################################
set_returncode()
{
if [ "${RETCODE}" -lt "${1}" ]; then
RETCODE="${1}"
fi
}
########################################################################
# Purpose: Set certificate counters and informations for nagios summary
# Arguments:
# $1 -> Status of certificate (0: valid, 1: will expire, 2: expired)
# $2 -> Hostname
# $3 -> TCP Port
# $4 -> Date when certificate will expire
# $5 -> Days left until the certificate will expire
########################################################################
set_summary()
{
if [ "${1}" -eq 0 ]; then
SUMMARY_VALID=$((SUMMARY_VALID+1))
elif [ "${1}" -eq 1 ]; then
SUMMARY_WILL_EXPIRE=$((SUMMARY_WILL_EXPIRE+1))
else
SUMMARY_EXPIRED=$((SUMMARY_EXPIRED+1))
fi
if [ "${5}" -lt "${SUMMARY_MIN_DIFF}" ] || [ "${SUMMARY_MIN_DIFF}" -eq 0 ]; then
SUMMARY_MIN_DATE="${4}"
SUMMARY_MIN_DIFF="${5}"
SUMMARY_MIN_HOST="${2}"
SUMMARY_MIN_PORT="${3}"
fi
}
##########################################
# Purpose: Describe how the script works
# Arguments:
# None
##########################################
usage()
{
echo "Usage: $0 [ -e email address ] [-E sender email address] [ -x days ] [-q] [-a] [-b] [-h] [-i] [-n] [-N] [-v]"
echo " { [ -s common_name ] && [ -p port] } || { [ -f cert_file ] } || { [ -c cert file ] } || { [ -d cert dir ] }"
echo ""
echo " -a : Send a warning message through E-mail"
echo " -b : Will not print header"
echo " -c cert file : Print the expiration date for the PEM or PKCS12 formatted certificate in cert file"
echo " -d cert directory : Print the expiration date for the PEM or PKCS12 formatted certificates in cert directory"
echo " -e E-mail address : E-mail address to send expiration notices"
echo " -E E-mail sender : E-mail address of the sender"
echo " -f cert file : File with a list of FQDNs and ports"
echo " -h : Print this screen"
echo " -i : Print the issuer of the certificate"
echo " -k password : PKCS12 file password"
echo " -n : Run as a Nagios plugin"
echo " -N : Run as a Nagios plugin and output one line summary (implies -n, requires -f or -d)"
echo " -p port : Port to connect to (interactive mode)"
echo " -q : Don't print anything on the console"
echo " -s commmon name : Server to connect to (interactive mode)"
echo " -S : Print validation information"
echo " -t type : Specify the certificate type"
echo " -V : Print version information"
echo " -x days : Certificate expiration interval (eg. if cert_date < days)"
echo ""
}
##########################################################################
# Purpose: Connect to a server ($1) and port ($2) to see if a certificate
# has expired
# Arguments:
# $1 -> Server name
# $2 -> TCP port to connect to
##########################################################################
check_server_status() {
PORT="$2"
case "$PORT" in
smtp|25|submission|587) TLSFLAG="-starttls smtp";;
pop3|110) TLSFLAG="-starttls pop3";;
imap|143) TLSFLAG="-starttls imap";;
ftp|21) TLSFLAG="-starttls ftp";;
xmpp|5222) TLSFLAG="-starttls xmpp";;
xmpp-server|5269) TLSFLAG="-starttls xmpp-server";;
irc|194) TLSFLAG="-starttls irc";;
postgres|5432) TLSFLAG="-starttls postgres";;
mysql|3306) TLSFLAG="-starttls mysql";;
lmtp|24) TLSFLAG="-starttls lmtp";;
nntp|119) TLSFLAG="-starttls nntp";;
sieve|4190) TLSFLAG="-starttls sieve";;
ldap|389) TLSFLAG="-starttls ldap";;
*) TLSFLAG="";;
esac
if [ "${TLSSERVERNAME}" = "FALSE" ]; then
OPTIONS="-connect ${1}:${2} $TLSFLAG"
else
OPTIONS="-connect ${1}:${2} -servername ${1} $TLSFLAG"
fi
echo "" | "${OPENSSL}" s_client $OPTIONS 2> "${ERROR_TMP}" 1> "${CERT_TMP}"
if "${GREP}" -i "Connection refused" "${ERROR_TMP}" > /dev/null; then
prints "${1}" "${2}" "Connection refused" "Unknown"
set_returncode 3
elif "${GREP}" -i "No route to host" "${ERROR_TMP}" > /dev/null; then
prints "${1}" "${2}" "No route to host" "Unknown"
set_returncode 3
elif "${GREP}" -i "gethostbyname failure" "${ERROR_TMP}" > /dev/null; then
prints "${1}" "${2}" "Cannot resolve domain" "Unknown"
set_returncode 3
elif "${GREP}" -i "Operation timed out" "${ERROR_TMP}" > /dev/null; then
prints "${1}" "${2}" "Operation timed out" "Unknown"
set_returncode 3
elif "${GREP}" -i "ssl handshake failure" "${ERROR_TMP}" > /dev/null; then
prints "${1}" "${2}" "SSL handshake failed" "Unknown"
set_returncode 3
elif "${GREP}" -i "connect: Connection timed out" "${ERROR_TMP}" > /dev/null; then
prints "${1}" "${2}" "Connection timed out" "Unknown"
set_returncode 3
elif "${GREP}" -i "Name or service not known" "${ERROR_TMP}" > /dev/null; then
prints "${1}" "${2}" "Unable to resolve the DNS name ${1}" "Unknown"
set_returncode 3
else
check_file_status "${CERT_TMP}" "${1}" "${2}"
fi
}
#####################################################
### Check the expiration status of a certificate file
### Accepts three parameters:
### $1 -> certificate file to process
### $2 -> Server name
### $3 -> Port number of certificate
#####################################################
check_file_status() {
CERTFILE="${1}"
HOST="${2}"
PORT="${3}"
### Check to make sure the certificate file exists
if [ ! -r "${CERTFILE}" ] || [ ! -s "${CERTFILE}" ]; then
echo "ERROR: The file named ${CERTFILE} is unreadable or doesn't exist"
echo "ERROR: Please check to make sure the certificate for ${HOST}:${PORT} is valid"
set_returncode 3
return
fi
### Grab the expiration date from the X.509 certificate
if [ "${PKCSDBPASSWD}" != "" ]; then
# Extract the certificate from the PKCS#12 database, and
# send the informational message to /dev/null
"${OPENSSL}" pkcs12 -nokeys -in "${CERTFILE}" \
-out "${CERT_TMP}" -clcerts -password pass:"${PKCSDBPASSWD}" 2> /dev/null
# Extract the expiration date from the certificate
CERTDATE=$("${OPENSSL}" x509 -in "${CERT_TMP}" -enddate -noout | \
"${SED}" 's/notAfter\=//')
# Extract the issuer from the certificate
CERTISSUER=$("${OPENSSL}" x509 -in "${CERT_TMP}" -issuer -noout | \
"${AWK}" 'BEGIN {RS=", " } $0 ~ /^O =/
{ print substr($0,5,17)}')
### Grab the common name (CN) from the X.509 certificate
COMMONNAME=$("${OPENSSL}" x509 -in "${CERT_TMP}" -subject -noout | \
"${SED}" -e 's/.*CN = //' | \
"${SED}" -e 's/, .*//')
### Grab the serial number from the X.509 certificate
SERIAL=$("${OPENSSL}" x509 -in "${CERT_TMP}" -serial -noout | \
"${SED}" -e 's/serial=//')
else
# Extract the expiration date from the ceriticate
CERTDATE=$("${OPENSSL}" x509 -in "${CERTFILE}" -enddate -noout -inform "${CERTTYPE}" | \
"${SED}" 's/notAfter\=//')
# Extract the issuer from the certificate
CERTISSUER=$("${OPENSSL}" x509 -in "${CERTFILE}" -issuer -noout -inform "${CERTTYPE}" | \
"${AWK}" 'BEGIN {RS=", " } $0 ~ /^O =/ { print substr($0,5,17)}')
### Grab the common name (CN) from the X.509 certificate
COMMONNAME=$("${OPENSSL}" x509 -in "${CERTFILE}" -subject -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/.*CN = //' | \
"${SED}" -e 's/, .*//')
### Grab the serial number from the X.509 certificate
SERIAL=$("${OPENSSL}" x509 -in "${CERTFILE}" -serial -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/serial=//')
fi
### Split the result into parameters, and pass the relevant pieces to date2julian
set -- ${CERTDATE}
MONTH=$(getmonth "${1}")
# Convert the date to seconds, and get the diff between NOW and the expiration date
CERTJULIAN=$(date2julian "${MONTH#0}" "${2#0}" "${4}")
CERTDIFF=$(date_diff "${NOWJULIAN}" "${CERTJULIAN}")
if [ "${CERTDIFF}" -lt 0 ]; then
if [ "${ALARM}" = "TRUE" ]; then
send_mail "${SENDER}" "${ADMIN}" "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" \
"The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!"
fi
prints "${HOST}" "${PORT}" "Expired" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
RETCODE_LOCAL=2
elif [ "${CERTDIFF}" -lt "${WARNDAYS}" ]; then
if [ "${ALARM}" = "TRUE" ]; then
send_mail "${SENDER}" "${ADMIN}" "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire in ${CERTDIFF}-days or less" \
"The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire on ${CERTDATE}"
fi
prints "${HOST}" "${PORT}" "Expiring" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
RETCODE_LOCAL=1
else
prints "${HOST}" "${PORT}" "Valid" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
RETCODE_LOCAL=0
fi
set_returncode "${RETCODE_LOCAL}"
MIN_DATE=$(echo "${CERTDATE}" | "${AWK}" '{ print $1, $2, $4 }')
set_summary "${RETCODE_LOCAL}" "${HOST}" "${PORT}" "${MIN_DATE}" "${CERTDIFF}"
}
#################################
### Start of main program
#################################
while getopts abc:d:e:E:f:hik:nNp:qs:St:Vx: option
do
case "${option}" in
a) ALARM="TRUE";;
b) NOHEADER="TRUE";;
c) CERTFILE=${OPTARG};;
d) CERTDIRECTORY=${OPTARG};;
e) ADMIN=${OPTARG};;
E) SENDER=${OPTARG};;
f) SERVERFILE=$OPTARG;;
h) usage
exit 1;;
i) ISSUER="TRUE";;
k) PKCSDBPASSWD=${OPTARG};;
n) NAGIOS="TRUE";;
N) NAGIOS="TRUE"
NAGIOSSUMMARY="TRUE";;
p) PORT=$OPTARG;;
q) QUIET="TRUE";;
s) HOST=$OPTARG;;
S) VALIDATION="TRUE";;
t) CERTTYPE=$OPTARG;;
V) echo "${PROGRAMVERSION}"
exit 0
;;
x) WARNDAYS=$OPTARG;;
\?) usage
exit 1;;
esac
done
### Check to make sure a openssl utility is available
if [ ! -f "${OPENSSL}" ]; then
echo "ERROR: The openssl binary does not exist in ${OPENSSL}."
echo "FIX: Please modify the \${OPENSSL} variable in the program header."
exit 1
fi
### Check to make sure a date utility is available
if [ ! -f "${DATE}" ]; then
echo "ERROR: The date binary does not exist in ${DATE} ."
echo "FIX: Please modify the \${DATE} variable in the program header."
exit 1
fi
### Check to make sure a grep and find utility is available
if [ ! -f "${GREP}" ] || [ ! -f "${FIND}" ]; then
echo "ERROR: Unable to locate the grep and find binary."
echo "FIX: Please modify the \${GREP} and \${FIND} variables in the program header."
exit 1
fi
### Check to make sure the mktemp and printf utilities are available
if [ ! -f "${MKTEMP}" ] || [ -z "${PRINTF}" ]; then
echo "ERROR: Unable to locate the mktemp or printf binary."
echo "FIX: Please modify the \${MKTEMP} and \${PRINTF} variables in the program header."
exit 1
fi
### Check to make sure the sed and awk binaries are available
if [ ! -f "${SED}" ] || [ ! -f "${AWK}" ]; then
echo "ERROR: Unable to locate the sed or awk binary."
echo "FIX: Please modify the \${SED} and \${AWK} variables in the program header."
exit 1
fi
### Check to make sure a mail client is available it automated notifications are requested
if [ "${ALARM}" = "TRUE" ] && [ ! -f "${MAIL}" ]; then
echo "ERROR: You enabled automated alerts, but the mail binary could not be found."
echo "FIX: Please modify the ${MAIL} variable in the program header."
exit 1
fi
# Send along the servername when TLS is used
if ${OPENSSL} s_client -help 2>&1 | grep '-servername' > /dev/null; then
TLSSERVERNAME="TRUE"
else
TLSSERVERNAME="FALSE"
fi
# Place to stash temporary files
CERT_TMP=$($MKTEMP /var/tmp/cert.XXXXXX)
ERROR_TMP=$($MKTEMP /var/tmp/error.XXXXXX)
### Baseline the dates so we have something to compare to
MONTH=$(${DATE} "+%m")
DAY=$(${DATE} "+%d")
YEAR=$(${DATE} "+%Y")
NOWJULIAN=$(date2julian "${MONTH#0}" "${DAY#0}" "${YEAR}")
### Touch the files prior to using them
if [ -n "${CERT_TMP}" ] && [ -n "${ERROR_TMP}" ]; then
touch "${CERT_TMP}" "${ERROR_TMP}"
else
echo "ERROR: Problem creating temporary files"
echo "FIX: Check that mktemp works on your system"
exit 1
fi
### If a HOST was passed on the cmdline, use that value
if [ "${HOST}" != "" ]; then
print_heading
check_server_status "${HOST}" "${PORT:=443}"
print_summary
### If a file is passed to the "-f" option on the command line, check
### each certificate or server / port combination in the file to see if
### they are about to expire
elif [ -f "${SERVERFILE}" ]; then
print_heading
IFS=$'\n'
for LINE in $(grep -E -v '(^#|^$)' "${SERVERFILE}")
do
HOST=${LINE%% *}
PORT=${LINE##* }
IFS=" "
if [ "$PORT" = "FILE" ]; then
check_file_status "${HOST}" "FILE" "${HOST}"
else
check_server_status "${HOST}" "${PORT}"
fi
done
IFS="${OLDIFS}"
print_summary
### Check to see if the certificate in CERTFILE is about to expire
elif [ "${CERTFILE}" != "" ]; then
print_heading
check_file_status "${CERTFILE}" "FILE" "${CERTFILE}"
print_summary
### Check to see if the certificates in CERTDIRECTORY are about to expire
elif [ "${CERTDIRECTORY}" != "" ] && ("${FIND}" -L "${CERTDIRECTORY}" -type f > /dev/null 2>&1); then
print_heading
for FILE in $("${FIND}" -L "${CERTDIRECTORY}" -type f); do
check_file_status "${FILE}" "FILE" "${FILE}"
done
print_summary
### There was an error, so print a detailed usage message and exit
else
usage
exit 1
fi
### Exit with a success indicator
if [ "${NAGIOS}" = "TRUE" ]; then
exit "${RETCODE}"
else
exit 0
fi

102
shell/wakuag.sh

@ -0,0 +1,102 @@
downloads()
{
if [ -f "/usr/bin/curl" ]
then
echo $1,$2
http_code=`curl -I -m 10 -o /dev/null -s -w %{http_code} $1`
if [ "$http_code" -eq "200" ]
then
curl --connect-timeout 10 --retry 100 $1 > $2
elif [ "$http_code" -eq "405" ]
then
curl --connect-timeout 10 --retry 100 $1 > $2
else
curl --connect-timeout 10 --retry 100 $3 > $2
fi
elif [ -f "/usr/bin/cd1" ]
then
http_code = `cd1 -I -m 10 -o /dev/null -s -w %{http_code} $1`
if [ "$http_code" -eq "200" ]
then
cd1 --connect-timeout 10 --retry 100 $1 > $2
elif [ "$http_code" -eq "405" ]
then
cd1 --connect-timeout 10 --retry 100 $1 > $2
else
cd1 --connect-timeout 10 --retry 100 $3 > $2
fi
elif [ -f "/usr/bin/wget" ]
then
wget --timeout=10 --tries=100 -O $2 $1
if [ $? -ne 0 ]
then
wget --timeout=10 --tries=100 -O $2 $3
fi
elif [ -f "/usr/bin/wd1" ]
then
wd1 --timeout=10 --tries=100 -O $2 $1
if [ $? -eq 0 ]
then
wd1 --timeout=10 --tries=100 -O $2 $3
fi
fi
}
function clean_cron(){
chattr -R -ia /var/spool/cron
tntrecht -R -ia /var/spool/cron
chattr -ia /etc/crontab
tntrecht -ia /etc/crontab
chattr -R -ia /etc/cron.d
tntrecht -R -ia /etc/cron.d
chattr -R -ia /var/spool/cron/crontabs
tntrecht -R -ia /var/spool/cron/crontabs
crontab -r
rm -rf /var/spool/cron/*
rm -rf /etc/cron.d/*
rm -rf /var/spool/cron/crontabs
rm -rf /etc/crontab
}
function lock_cron()
{
chattr -R +ia /var/spool/cron
tntrecht -R +ia /var/spool/cron
touch /etc/crontab
chattr +ia /etc/crontab
tntrecht +ia /etc/crontab
chattr -R +ia /var/spool/cron/crontabs
tntrecht -R +ia /var/spool/cron/crontabs
chattr -R +ia /etc/cron.d
tntrecht -R +ia /etc/cron.d
}
function CheckAboutSomeKeys(){
if [ -f "/root/.ssh/id_rsa" ]
then
echo 'found: /root/.ssh/id_rsa'
fi
if [ -f "/home/*/.ssh/id_rsa" ]
then
echo 'found: /home/*/.ssh/id_rsa'
fi
if [ -f "/root/.aws/credentials" ]
then
echo 'found: /root/.aws/credentials'
fi
if [ -f "/home/*/.aws/credentials" ]
then
echo 'found: /home/*/.aws/credentials'
fi
}
## 内网互信主机执行命令
if [ -f /root/.ssh/known_hosts ] && [ -f /root/.ssh/id_rsa.pub ]; then
for h in $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do
ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h 'hostname' &
done
fi

0
shell/get_proc_mem.sh → shell/系统信息/get_proc_mem.sh

45
shell/系统信息/show_pid_openfile.sh

@ -0,0 +1,45 @@
#!/bin/env bash
###################################################################
#Script Name : show_pid_openfile.sh
#Description : Show Pid OpenFile Top 10.
#Create Date : 2021-07-29
#Author : lework
#Email : lework@yeah.net
###################################################################
function printbar() {
title=$1
value=$2
tput setaf $((1+ ${value} % 7))
printf " %10s " "${title}"
eval "printf '█%.0s' {1..${value}}"
printf " %s %s\n\n" ${value}
tput sgr0
}
while true
do
# Show a title
tput clear
printf " %10s " ""
tput setaf 7; tput smul;
printf "%s\n\n" "Show Pid OpenFile Top 10 ($(date +%T))"
tput rmul
data=""
for proc in $(find /proc/ -maxdepth 1 -type d -name "[0-9]*")
do
fd=$(ls $proc/fd 2>/dev/null | wc -l)
if [[ $fd -gt 1 ]]; then
pid=$(echo $proc | awk -F/ '{print $3}')
data="${data}\n${pid} ${fd}"
fi
done
echo -e ${data} | sort -k2 -n -r | head -10 | while read line
do
printbar $line
done
sleep 10
done
Loading…
Cancel
Save