Linux自签名证书
脚本功能:
利用cfssl工具生成自签名SSL服务器证书
脚本项目地址:点此查看
脚本流程:
- 检查并安装cfssl工具。
- 用户输入CA证书的一些配置信息,如证书过期时间、域名、国家、地区等。
- 创建CA配置文件(ca-config.json)和CA证书签发请求文件(ca-csr.json)。
- 利用cfssl工具生成CA证书(ca.pem)和私钥(ca-key.pem)。
- 用户输入服务器证书的配置信息。
- 创建服务器证书签发请求文件(<domain>-csr.json)。
- 利用cfssl工具生成服务器证书(<domain>.pem)、私钥(<domain>-key.pem)。
脚本内容:
#!/usr/bin/env bash
#===============================================================================
#
# FILE: Generating_ssl.sh
#
# USAGE: bash Generating_ssl.sh
# DESCRIPTION: 基于cfssl工具实现自签名SSL服务器证书
#
# ORGANIZATION: dqzboy.com
# CREATED: 2022
#===============================================================================
## 安装部署cfssl工具
ADD_CFSSL() {
echo
echo "-------------------------------------<提 示>-------------------------------------"
echo " 检查服务器是否安装CFSSL工具!"
echo "-------------------------------------< END >-------------------------------------"
echo
cfsslVer="1.6.3"
if [ -f /usr/local/bin/cfssl ];then
echo "Skip..."
else
wget https://mirrors.chenby.cn/https://github.com/cloudflare/cfssl/releases/download/v${cfsslVer}/cfssl_${cfsslVer}_linux_amd64
mv cfssl_${cfsslVer}_linux_amd64 /usr/local/bin/cfssl
fi
if [ -f /usr/local/bin/cfssl-certinfo ];then
echo "Skip..."
else
wget https://mirrors.chenby.cn/https://github.com/cloudflare/cfssl/releases/download/v${cfsslVer}/cfssl-certinfo_${cfsslVer}_linux_amd64
mv cfssl-certinfo_${cfsslVer}_linux_amd64 /usr/local/bin/cfssl-certinfo
fi
if [ -f /usr/local/bin/cfssljson ];then
echo "Skip..."
else
wget https://mirrors.chenby.cn/https://github.com/cloudflare/cfssl/releases/download/v${cfsslVer}/cfssljson_${cfsslVer}_linux_amd64
mv cfssljson_${cfsslVer}_linux_amd64 /usr/local/bin/cfssljson
fi
# 赋予执行权限
chmod +x /usr/local/bin/cfssl*
cfssl version
}
## 生成CA证书
CA_NAMES() {
mkdir -p /data/cert && cd /data/cert
echo
echo "-------------------------------------<提 示>-------------------------------------"
echo " 直接回车,使用默认值!"
echo "-------------------------------------< END >-------------------------------------"
echo
read -p "请输入证书过期时间[8760h(1年|Default)|19800h(825天)|87600h(10年)]:" input
if [ -z "${input}" ];then
input="16800h"
echo ${input}
fi
echo "-------------------------------------------------------------------------------------"
read -p "请输入域名[不可缺失!]:" inputURL
if [ -z "${inputURL}" ];then
echo "参数为空,退出执行"
exit 1
fi
echo "-------------------------------------------------------------------------------------"
read -p "请输入国家[Default: CN]:" inputC
if [ -z "${inputC}" ];then
inputC="CN"
echo ${inputC}
fi
echo "-------------------------------------------------------------------------------------"
read -p "请输入地区、城市[Default: Shanghai]:" inputL
if [ -z "${inputL}" ];then
inputL="Shanghai"
fi
echo "-------------------------------------------------------------------------------------"
read -p "请输入州、省[Default: Shanghai]:" inputST
if [ -z "${inputST}" ];then
inpuST="Shanghai"
fi
echo "-------------------------------------------------------------------------------------"
read -p "请输入组织名称,公司名称[Default: DEVOPS]:" inputO
if [ -z "${inputO}" ];then
inpuO="DEVOPS"
fi
echo "-------------------------------------------------------------------------------------"
read -p "请输入组织单位名称,公司部门[Default: DEVOPS]:" inputOU
if [ -z "${inputOU}" ];then
inpuOU="DEVOPS"
fi
echo "-------------------------------------------------------------------------------------"
}
CREATE_CA() {
echo "================================================< CA CONFIG >================================================"
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "${input}"
},
"profiles": {
"Server": {
"expiry": "${input}",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"Client": {
"expiry": "${input}",
"usages": [
"signing",
"key encipherment",
"client auth"
]
}
}
}
}
EOF
echo "================================================< CA CSR >================================================"
cat > ca-csr.json <<EOF
{
"CN": "${inputURL}",
"hosts": [
"${inputURL}"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "${inputC}",
"ST": "${inputST}",
"L": "${inputL}",
"O": "${inputO}",
"OU": "${inputOU}"
}
]
}
EOF
echo "==================================================< CA CREATE >=================================================="
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
echo "================================================< CA CREATE DONE >================================================"
}
CREATE_SERVER() {
mkdir -p /data/cert/${inputURL} && cd /data/cert/${inputURL}
echo "================================================< SERVER CSR >================================================"
cat > ${inputURL}-csr.json <<EOF
{
"CN": "${inputURL}",
"hosts": [
"${inputURL}"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "${inputC}",
"ST": "${inputST}",
"L": "${inputL}",
"O": "${inputO}",
"OU": "${inputOU}"
}
]
}
EOF
echo "================================================<SERVER SSL CREATE>================================================"
cfssl gencert -ca=/data/cert/ca.pem -ca-key=/data/cert/ca-key.pem -config=/data/cert/ca-config.json -profile=Server ${inputURL}-csr.json | cfssljson -bare ${inputURL}
echo "================================================< SERVER SSL DONE >================================================"
}
main() {
ADD_CFSSL
CA_NAMES
CREATE_CA
CREATE_SERVER
}
main
Linux资源使用率
脚本功能:
calculate_load.sh:计算当前服务器1分钟、5分钟、15分钟的负载get_cpu-disk.sh:每隔 5 秒检测一次 CPU、内存和磁盘的占用率,并将检测结果输出到终端。可以根据需要修改脚本中的检测间隔和检测内容get_disk_usage_alert.sh:结合磁盘使用率查询和邮件告警两个功能,用于监控服务器磁盘的空间使用情况get_proc_stat.sh:根据进程名或PID或进程命令行参数查询进程,并输出相关进程信息get_top_proc.sh:输出系统当前占用资源(cpu、内存、IO、流量等等)最多的Top10进程get_top_proc_in_oneline.sh:输出系统当前占用资源(cpu、内存)最多的TopN进程
脚本项目地址:点此查看
脚本内容:
- calculate_load.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: calculate_load.sh
#
# USAGE: ./calculate_load.sh
#
# DESCRIPTION: 计算当前服务器1分钟、5分钟、15分钟的负载
#
# ORGANIZATION: dqzboy.com
#===============================================================================
# 获取CPU核心数量
cpu_cores=$(grep -c ^processor /proc/cpuinfo)
# 使用uptime命令获取系统负载平均值
load_averages=$(uptime | awk -F'average:' '{print $2}' | tr -d ',')
# 提取1分钟、5分钟和15分钟的负载值
load_1min=$(echo "$load_averages" | awk '{print $1}')
load_5min=$(echo "$load_averages" | awk '{print $2}')
load_15min=$(echo "$load_averages" | awk '{print $3}')
# 计算load average百分比
load_1min_percentage=$(echo "scale=2; $load_1min / $cpu_cores * 100" | bc)
load_5min_percentage=$(echo "scale=2; $load_5min / $cpu_cores * 100" | bc)
load_15min_percentage=$(echo "scale=2; $load_15min / $cpu_cores * 100" | bc)
calculate_percentage() {
local load_value=$1
local percentage=$(echo "scale=2; $load_value / $cpu_cores * 100" | bc)
# 小于0.01的情况显示为具体值,否则显示两位小数
if (( $(echo "$percentage < 0.01" | bc -l) )); then
echo "$percentage"
else
echo "$(printf "%.2f" $percentage)"
fi
}
# 打印结果
echo "CPU Cores: $cpu_cores"
echo "Load Average (1min): $load_1min, Load Percentage: $(calculate_percentage $load_1min)%"
echo "Load Average (5min): $load_5min, Load Percentage: $(calculate_percentage $load_5min)%"
echo "Load Average (15min): $load_15min, Load Percentage: $(calculate_percentage $load_15min)%"
- get_cpu-disk.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: get_cpu-disk.sh
#
# USAGE: ./get_cpu-disk.sh
#
# DESCRIPTION: 每隔 5 秒检测一次 CPU、内存和磁盘的占用率,并将检测结果输出到终端。可以根据需要修改脚本中的检测间隔和检测内容
#
# ORGANIZATION: dqzboy.com
#===============================================================================
while true
do
# 获取 CPU 占用率
cpu_load=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}')
cpu_load=${cpu_load/.*}
# 获取内存占用率
mem_used=$(free | grep Mem | awk '{print $3/\ * 100.0}')
mem_used=${mem_used/.*}
# 获取磁盘占用率
disk_used=$(df / | awk '/\// {print $5}' | sed 's/%//g')
# 打印资源使用情况
echo "CPU 占用率:$cpu_load%"
echo "内存占用率:$mem_used%"
echo "磁盘占用率:$disk_used%"
# 等待 5 秒
sleep 5
done
- get_disk_usage_alert.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: get_disk usage_alert.sh
#
# USAGE: ./get_disk usage_alert.sh [File_system|Mounted_on]
# ./get_disk usage_alert.sh [-i|-u]
# DESCRIPTION: open_mail_alert字段设置为1时:
# 根据Filesystem(例如:/dev/sda1)或 Mounted on(例如:/data)获取磁盘使用率
# 并输出Disk usage(例如:15%);如果没有输入参数则输出全部Disk usage,Mounted_on信息
#
# open_mail_alert字段设置为0时:
# 监控monitor_mount_dir字段中定义的监控分区,添加到crontab中,当分区超过使用率时,发出邮件告警
# (一般使用QQ邮箱需要使用ssl方式发送邮件,163邮件使用普通方式就OK)
#
# ORGANIZATION: dqzboy.com
#===============================================================================
ok(){
echo "$(date +%F\ %T)|$$|$BASH_LINENO|info|job success: $*"
exit 0
}
die(){
echo "$(date +%F\ %T)|$$|$BASH_LINENO|error|job fail: $*" >&2
exit 1
}
usage() {
cat <<_OO_
USAGE:
$0 [File_system|Mounted_on]
_OO_
}
#邮件告警功能字段定义
open_mail_alert=0 # 0代表关闭邮件告警,开启查询磁盘使用率模式;1代表开启邮件告警,关闭查询磁盘使用率模式;默认为关闭状态,以下邮件信息配置好后方可打开,否则会导致邮件告警失败
mail_from="xxx@qq.com" #定义邮件告警发件人
mail_to="111111@qq.com,222222@qq.com,3333333@126.com" #定义邮件告警收件人,多个告警收件人用逗号分隔(,)
smtp_addr_port="smtp.qq.com:465" #定义smtp地址和端口,如果不指定端口,默认为25
mail_user="xxx@qq.com" #定义发件人用户
mail_password="xxx" #定义发件人密码
ssl_enable=1 #1代表发送告警邮件使用SSL协议,0代表使用普通邮件协议,默认设置为0
monitor_mount_dir="all" #定义需告警的挂载目录,多个挂载目录用竖线分隔(|),如果要监控服务器上所有磁盘需要输入 ALL
alert_limit=60 #设置告警阈值百分比,如果磁盘空间使用等于或超过设置阈值则发出邮件告警
monitoring_interval=5 #设置监控告警间隔,单位为分钟
#获取磁盘使用率函数
disk_usage_info=""
get_disk_usage(){
local filesystem_or_mount="$1"
if [[ -z "$filesystem_or_mount" ]];then
disk_usage_info=$(df|awk 'NR>1{print $(NF-1),$NF}'|sort -r)
echo "$disk_usage_info"
else
local tmp_filesystem_or_mount=${filesystem_or_mount/\/dev\//}
local tmp_mount=$(df $tmp_filesystem_or_mount 2>/dev/null|awk 'NR>1{print $(NF-1)}')
if [[ -z "$tmp_mount" ]];then
df /dev/$tmp_filesystem_or_mount 2>/dev/null|awk 'NR>1{print $(NF-1)}'
else
echo "$tmp_mount"
fi
fi
}
if [[ $open_mail_alert -eq 0 ]];then
#获取磁盘使用率
disk_usage_result=$( get_disk_usage "$1" )
if [[ -z "$disk_usage_result" ]];then
die "Get disk usage fail,please confirm the $1 file_system or mount_on existence"
else
ok "$disk_usage_result"
fi
elif [[ $open_mail_alert -eq 1 ]];then
#安装定期监控
if [[ $1 == "-i" ]];then
#如果开启邮件告警功能执行者必须是root权限
if ! id | grep -Eq '^uid=0\('; then
die "You must use the root user to open the mail alert"
fi
#判断mail程序是否存在
mail_bin=$( which mailx )
if [[ -z "$mail_bin" ]];then
die "You must install the mailx package"
fi
#判断smtp服务器是否可以ping通
smtp_addr=$( echo "$smtp_addr_port"|awk -F ":" '{print $1}' )
ping -c 1 $smtp_addr 1>/dev/null 2>&1
if [[ $? -ne 0 ]];then
die "Please check the SMTP address $smtp_addr connectivity"
fi
#如果开启了SSL协议
if [[ $ssl_enable -eq 1 ]];then
ssl_dir=~/.certs
smtp_addr_port_ssl="smtps://$smtp_addr_port" #添加ssl协议头
#判断openssl程序是否存在
ssl_bin=$( which openssl )
if [[ -z "$ssl_bin" ]];then
die "You must install the openssl package"
fi
#生成smtps所需证书
[[ -d $ssl_dir ]] || mkdir -p $ssl_dir
[[ -s $$ssl_dir/smtps.crt ]] && rm -f $ssl_dir/smtps.crt
echo -n | openssl s_client -connect "$smtp_addr_port" 2>/dev/null| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > $ssl_dir/smtps.crt
if [[ ! -s $ssl_dir/smtps.crt ]];then
die "Failed to generate certificate $ssl_dir/smtps.crt"
fi
certutil -A -n "GeoTrust SSL CA" -t "C,," -d ~/.certs -i $ssl_dir/smtps.crt 1>/dev/null 2>&1
if [[ $? -ne 0 ]];then
die "Failed to certutil1 certificate $ssl_dir/smtps.crt"
fi
certutil -A -n "GeoTrust Global CA" -t "C,," -d ~/.certs -i $ssl_dir/smtps.crt 1>/dev/null 2>&1
if [[ $? -ne 0 ]];then
die "Failed to certutil2 certificate $ssl_dir/smtps.crt"
fi
certutil -L -d $ssl_dir 1>/dev/null 2>&1
if [[ $? -ne 0 ]];then
die "Failed to certutil3 certificate $ssl_dir/smtps.crt"
fi
fi
#添加crontab
cron_file='/var/spool/cron/root'
sciprt_name=$(cd "$(dirname "$0")";pwd)/$(basename "$0")
chmod +x $sciprt_name
echo "*/${monitoring_interval} * * * * $sciprt_name 1>/dev/null 2>&1" >>$cron_file
service crond reload 1>/dev/null 2>&1
ok "Install mail monitoring success"
fi
#卸载定期监控
if [[ $1 == "-u" ]];then
cron_file='/var/spool/cron/root'
sciprt_name=$(basename "$0")
/bin/sed -i '/'${sciprt_name}'/d' $cron_file
service crond reload 1>/dev/null 2>&1
ok "Uninstall mail monitoring success"
fi
#执行监控逻辑
#Get IP ADDRESS
ip=$( /sbin/ifconfig|awk -F ":| +" '{if($0 ~ /inet addr:/ && $4 !~ /127\.0\./){print $4}}' )
#如果monitor_mount_dir值为ALL,则监控服务器全部分区
capital_all=$( echo "$monitor_mount_dir"|tr [a-z] [A-Z] )
if [[ $capital_all == "ALL" ]];then
monitor_mount_dir_tmp=$( df|awk 'BEGIN{monitor_list=""}NR>1{monitor_list=monitor_list"|"$NF}END{print monitor_list}' )
monitor_mount_dir=${monitor_mount_dir_tmp/\|/}
fi
#定义ssl目录
ssl_dir=~/.certs
smtp_addr_port_ssl="smtps://$smtp_addr_port" #添加ssl协议头
if [[ $ssl_enable -eq 1 ]];then
#判断磁盘使用率超过设定阈值,邮件告警通知
for mount_dir in ${monitor_mount_dir//|/ }
do
disk_usage_result=$( get_disk_usage "$mount_dir" )
if [[ ${disk_usage_result/\%/} -ge $alert_limit ]];then
echo "Host name:${HOSTNAME}
IP:$ip
Disk $mount_dir usage $disk_usage_result exceeded limited ${alert_limit}%"|mailx -s "Host name:${HOSTNAME} Disk $mount_dir usage $disk_usage_result exceeded limited ${alert_limit}%" -S ssl-verify=ignore -S smtp-auth=login -S smtp="$smtp_addr_port_ssl" -S from="${mail_from}(Disk Usage Alert)" -S smtp-auth-user="$mail_user" -S smtp-auth-password="$mail_password" -S nss-config-dir="$ssl_dir" $mail_to 2>/dev/null
sleep 3
fi
done
else
#判断磁盘使用率超过设定阈值,邮件告警通知(not ssl)
for mount_dir in ${monitor_mount_dir//|/ }
do
disk_usage_result=$( get_disk_usage "$mount_dir" )
if [[ ${disk_usage_result/\%/} -ge $alert_limit ]];then
echo "Host name:${HOSTNAME}
IP:$ip
Disk $mount_dir usage $disk_usage_result exceeded limited ${alert_limit}%"|mailx -s "Host name:${HOSTNAME} Disk $mount_dir usage $disk_usage_result exceeded limited ${alert_limit}%" -S smtp-auth=login -S smtp="$smtp_addr_port" -S from="${mail_from}(Disk Usage Alert)" -S smtp-auth-user="$mail_user" -S smtp-auth-password="$mail_password" $mail_to 2>/dev/null
sleep 3
fi
done
fi
else
die "open_mail_alert variable must 0 or 1"
fi
- get_proc_stat.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: get_proc_stat.sh
#
# USAGE: ./get_proc_stat.sh [name|pid|arg] [value]
#
# DESCRIPTION: 根据进程名或PID或进程命令行参数查询进程,并输出相关进程信息
#
# ORGANIZATION: dqzboy.com
#===============================================================================
set -o nounset # Treat unset variables as an error
ok () {
echo "$(date +%F\ %T)|$$|$BASH_LINENO|info|job success: $*"
exit 0
}
die () {
echo "$(date +%F\ %T)|$$|$BASH_LINENO|error|job fail: $*" >&2
exit 1
}
usage() {
cat <<_OO_
USAGE:
get_proc_stat.sh [name|pid|arg] [value]
_OO_
exit 1
}
# 通过/proc/下获取文件句柄和进程工作目录
get_pid_stat_proc() {
local pids="$1"
{
shopt -s nullglob
echo "CWD FH"
for pid in ${pids/,/ /}; do
cwd=$(readlink -f "/proc/$pid/cwd")
fds=(/proc/$pid/fd/*)
fd_cnt=${#fds[@]}
[[ -z "$cwd" ]] && cwd="NULL"
(( fd_cnt == 0 )) && fd_cnt="NOACCESS"
echo "$cwd $fd_cnt"
done
} | column -t
}
# 获取指定PID的所有子进程PID
get_chd_pid() {
local chd_pids=$(pgrep -P "$1" | xargs)
for cpid in $chd_pids; do
echo "$cpid"
get_chd_pid "$cpid"
done
}
# 输出进程的所有子进程数量
get_pid_cpid_cnt() {
local pids="$1"
{
shopt -s nullglob
echo "CHD"
for pid in ${pids/,/ }; do
chd=$(get_chd_pid "$pid" | wc -l)
echo "$chd"
done
} | column -t
}
# 汇总输出
get_pid_stat() {
local pids="$1"
if [[ -z "$pids" ]]; then
die "no such process."
fi
# sort pids
pids=$(echo "$pids" | sed s'/,/\n/g' | sort -n | xargs | sed 's/ /,/g')
ps_output=$(ps -p "$pids" -o pid,comm,user,pcpu,rss,stat,lstart)
cwd_output=$(get_pid_stat_proc "$pids")
cpid_output=$(get_pid_cpid_cnt "$pids")
paste <(echo "$ps_output") <(echo "$cwd_output") <(echo "$cpid_output")
}
if [[ $# -eq 2 ]]; then
case $1 in
name) pids=$(pgrep -d, -x "$2") ;;
arg) pids=$(pgrep -d, -f "$2") ;;
pid) pids="$2" ;;
*) usage ;;
esac
get_pid_stat "$pids"
else
usage
fi
- get_top_proc.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: get_top_proc.sh
#
# USAGE: ./get_top_proc.sh
#
# DESCRIPTION: 输出系统当前占用资源(cpu、内存、IO、流量等等)最多的Top10进程
#
# ORGANIZATION: dqzboy.com
#===============================================================================
set -o nounset # Treat unset variables as an error
common_fields="pcpu,pmem,rss,pid,user,args"
IFS="," read -r -a common <<< "$common_fields"
usage() {
cat <<EOF
get_top_proc.sh <cpu|mem> <additional output fields>
by default, output $common_fields fields
EOF
exit 1
}
contains_string() {
local e
for e in "${@:2}"; do
[[ "$e" == "$1" ]] && return 0
done
return 1
}
join() {
local IFS="$1"
shift; echo "$*"
}
if (( $# < 1 )) || (( $# > 2 )) ; then
usage
fi
case $1 in
cpu) sort_field=pcpu ;;
mem) sort_field=rss ;;
*) usage ;;
esac
if [[ $# -eq 1 ]]; then
fields="$common_fields"
else
IFS="," read -r -a extra <<< "$2"
for f in "${extra[@]}";do
contains_string "$f" "${common[@]}" || extra_fields+=("$f")
done
fields="$common_fields,$(join , "${extra_fields[@]}")"
fi
ps -eo "$fields" --sort=-"$sort_field" | head -10
- get_top_proc_in_oneline.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: get_top_proc_in_oneline.sh
#
# USAGE: ./get_top_proc_in_oneline.sh <cpu|mem> <number>
#
# DESCRIPTION: 输出系统当前占用资源(cpu、内存)最多的TopN进程
#
# ORGANIZATION: dqzboy.com
#===============================================================================
set -o nounset # Treat unset variables as an error
fields="pcpu,pmem,comm"
usage() {
cat <<EOF
get_top_proc_in_oneline.sh <cpu|mem> <number of top proc>
EOF
exit 1
}
join() {
local IFS="$1"
shift; echo "$*"
}
if (( $# < 1 )) || (( $# > 2 )) ; then
usage
fi
case $1 in
cpu) sort_field=pcpu ;;
mem) sort_field=rss ;;
*) usage ;;
esac
if [[ $# -eq 2 ]]; then
top_n=$2
else
top_n=6
fi
ps -eo "$fields" --sort=-"$sort_field" | head -$(( top_n + 1 )) | awk 'NR==1 { gsub(/%/,"") } {printf "%s\\n", $0 }'
Linux脚本小工具
脚本功能:
manage_cron_tasks.sh:管理系统上所有用户的定时任务。通过选择是否删除每个用户的定时任务modify_ip.sh:RHEL 8发行版OS 使用nmcli指令自动化修改网卡IP,配合NetworkManager使用base64_menu.sh:用于实现base64加密和解密用户输入的内容
脚本项目地址:点此查看
脚本内容:
- base64_menu.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: base64_menu.sh
#
# USAGE: ./base64_menu.sh
#
# DESCRIPTION: 用于实现base64加密和解密用户输入的内容
#
# ORGANIZATION: Ding Qinzheng www.dqzboy.com
# CREATED: 2023
#===============================================================================
GREEN="3[1;32m"
RESET="3[0m"
PURPLE="3[35m"
BOLD="3[1m"
CYAN="3[1;36m"
RED="3[1;31m"
OUTPUT_FILE="output.txt"
# 加密函数
encrypt() {
read -e -p "$(echo -e ${GREEN}请输入要加密的内容: ${RESET})" text_to_encrypt
if [[ -z "$text_to_encrypt" ]]; then
echo -e "${RED}输入内容不能为空!${RESET}"
return 1
fi
encrypted_text=$(echo -n "$text_to_encrypt" | base64)
echo -e "${CYAN}加密结果为: $encrypted_text${RESET}"
echo "加密内容:$text_to_encrypt 解密内容: $encrypted_text" >> $OUTPUT_FILE
return 0
}
# 解密函数
decrypt() {
read -e -p "$(echo -e ${GREEN}请输入要解密的base64内容: ${RESET})" text_to_decrypt
if [[ -z "$text_to_decrypt" ]]; then
echo -e "${RED}输入内容不能为空!${RESET}"
return 1
fi
decrypted_text=$(echo -n "$text_to_decrypt" | base64 --decode)
echo -e "${CYAN}解密结果为: $decrypted_text${RESET}"
echo "解密内容:$decrypted_text 加密内容: $text_to_decrypt" >> $OUTPUT_FILE
return 0
}
# 脚本主体
while true; do
echo -e "${PURPLE}=====================${RESET}"
echo -e "${PURPLE}= ${BOLD}菜单选项${RESET}${PURPLE} =${RESET}"
echo -e "${PURPLE}=====================${RESET}"
echo -e " ${BOLD}1.${RESET} 加密"
echo -e " ${BOLD}2.${RESET} 解密"
echo -e " ${BOLD}3.${RESET} 退出"
echo -e "${PURPLE}=====================${RESET}"
read -e -p "$(echo -e ${GREEN}选择操作: ${RESET})" option
case "$option" in
1)
encrypt
[[ $? -eq 0 ]] && exit 0 # 如果加密成功则退出脚本
;;
2)
decrypt
[[ $? -eq 0 ]] && exit 0 # 如果解密成功则退出脚本
;;
3)
echo -e "${CYAN}退出程序...${RESET}"
exit 0
;;
*)
echo -e "${RED}无效选项,请重新选择。${RESET}"
;;
esac
done
- manage_cron_tasks.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: manage_cron_tasks.sh
#
# USAGE: ./manage_cron_tasks.sh
#
# DESCRIPTION: 管理系统上所有用户的定时任务。通过选择是否删除每个用户的定时任务
#
# ORGANIZATION: dqzboy.com
# CREATED: 2022
#===============================================================================
# 获取所有用户列表
user_list=$(cut -d: -f1 /etc/passwd)
# 初始化标志变量,用于判断是否有用户有定时任务
has_cron_tasks=false
# 遍历用户列表
for user in $user_list
do
# 查看用户的cron任务
cron_tasks=$(crontab -u $user -l 2>/dev/null)
# 如果用户有定时任务
if [ -n "$cron_tasks" ]; then
has_cron_tasks=true
echo "User: $user"
echo "Cron Tasks:"
echo "$cron_tasks"
echo "====================="
# 询问用户是否删除该用户的定时任务
read -p "Do you want to delete cron tasks for $user? (y/n): " delete_choice
if [ "$delete_choice" == "y" ]; then
# 询问用户删除第几条或全部
read -p "Enter the task number(s) to delete (e.g., 1 3 5 for specific tasks, a for all tasks): " task_numbers
if [ "$task_numbers" == "a" ]; then
# 删除所有定时任务
crontab -r -u $user
echo "All cron tasks deleted for $user."
else
# 备份用户的原始定时任务
original_cron_tasks=$(mktemp)
crontab -u $user -l > "$original_cron_tasks"
# 删除指定定时任务
for task_number in $task_numbers
do
sed -i "${task_number}d" "$original_cron_tasks"
done
# 恢复修改后的定时任务
crontab -u $user "$original_cron_tasks"
rm "$original_cron_tasks"
echo "Selected cron tasks deleted for $user."
fi
fi
fi
done
# 如果所有用户都没有定时任务,则打印提示信息
if [ "$has_cron_tasks" == false ]; then
echo "No cron tasks found for any user."
fi
- modify_ip.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: modify_ip.sh
#
# USAGE: ./modify_ip.sh
#
# DESCRIPTION: RHEL 8发行版OS 使用nmcli指令自动化修改网卡IP,配合NetworkManager使用
#
# ORGANIZATION: dqzboy.com
# CREATED: 2022
#===============================================================================
# 颜色定义
GREEN_LIGHT="3[1;32m"
RED="3[0;31m"
CYAN="3[0;36m"
NC="3[0m" # 恢复默认颜色
# 显示连接服务器的提示
function display_connect_instructions() {
local connect_instructions="${RED}脚本执行完成后,必须使用以下 IP 重新连接服务器!${NC}"
local interface="$1"
local new_ip="$2"
# 构建虚线框
local frame_length=${#connect_instructions}
local frame=""
for ((i=1; i<=frame_length+4; i++)); do
frame+="-"
done
echo -e "${CYAN}+${frame}+${NC}"
echo -e "${CYAN}| ${connect_instructions} ${CYAN}|${NC}"
echo -e "${CYAN}+${frame}+${NC}"
}
# 显示可用的网络接口
function display_interfaces() {
echo "可用的网络接口:"
nmcli device status
}
# 加载并修改 nmcli 连接配置为静态IP
function modify_connection() {
local interface="$1"
local new_ip="$2"
local gateway="$3"
local subnet_mask="$4"
local dns_servers="$5"
nmcli connection modify "$interface" ipv4.addresses "$new_ip/$subnet_mask" ipv4.gateway "$gateway" ipv4.dns "$dns_servers" ipv4.method manual connection.autoconnect yes
# 检查是否执行成功
if [ $? -eq 0 ]; then
echo -e "${GREEN_LIGHT}已将 $interface 的网络配置修改为静态IP:IP地址:$new_ip,网关:$gateway,DNS服务器:$dns_servers${NC}"
else
echo -e "${RED}修改 $interface 的网络配置失败。请检查输入信息和网络接口是否正确,并重新执行脚本。${NC}"
exit 1
fi
}
# 检查用户输入的IP地址和子网掩码格式是否正确
function check_ip_format() {
local ip="$1"
# 使用正则表达式检查IP地址和子网掩码格式
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then
return 0
else
return 1
fi
}
# 提示用户输入网络配置信息
function prompt_for_network_config() {
local interface="$1"
# 循环提示用户输入,直到格式正确
while true; do
read -e -p "$(echo -e "${GREEN_LIGHT}请输入 $interface 的新 IP 地址和子网掩码(格式为IP/子网掩码):${NC}")" new_ip
# 检查用户输入是否是有效的 IP 地址和子网掩码格式
if check_ip_format "$new_ip"; then
break
else
echo -e "${GREEN_LIGHT}错误:无效的 IP 地址和子网掩码格式。请重新输入一个有效的 IPv4 地址和子网掩码。${NC}"
fi
done
read -e -p "$(echo -e "${GREEN_LIGHT}请输入 $interface 的网关地址:${NC}")" gateway
read -e -p "$(echo -e "${GREEN_LIGHT}请输入 $interface 的DNS服务器地址(多个DNS服务器用空格分隔):${NC}")" dns_servers
# 解析用户输入的IP地址和子网掩码
local new_ip_address="$(echo "$new_ip" | cut -d'/' -f1)"
local subnet_mask="$(echo "$new_ip" | cut -d'/' -f2)"
modify_connection "$interface" "$new_ip_address" "$gateway" "$subnet_mask" "$dns_servers"
nmcli con down "$interface" && nmcli con up "$interface"
}
# 获取当前活动的网络接口名称
active_interface=$(nmcli device status | grep -E '\sconnected\s' | awk '{print $1}')
# 提示用户使用修改后的网络配置连接服务器
if [ -n "$active_interface" ]; then
display_connect_instructions "$active_interface" "$new_ip"
prompt_for_network_config "$active_interface"
else
echo -e "${GREEN_LIGHT}错误:未找到活动的网络接口。${NC}"
display_interfaces
exit 1
fi
Linux软件服务
脚本功能:
get_port_info.sh:获取指定服务端口的统计信息uptime-kuma_install.sh:一键部署 uptime-kuma 监控平台工具
脚本项目地址:点此查看
脚本内容:
- get_port_info.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: get_port_info.sh
#
# USAGE: ./get_port_info.sh [-h] [-i ip] -p <port>
#
# DESCRIPTION: 获取指定服务端口的统计信息
#
# ORGANIZATION: dqzboy.com
#===============================================================================
set -o nounset # Treat unset variables as an error
export LC_ALL=C
export LANG=C
usage() {
cat <<EOF
Usage: $0 [-h] [-i ip] -p <port>
EOF
exit 1
}
precheck() {
if ! which ss &> /dev/null; then
echo "ss not found, try install iproute2 package first"
exit 1
fi
if [[ $( id -u ) != 0 ]]; then
echo "$0 should run under root"
exit 1
fi
}
get_service_name(){
local port=$1
local proto=$2
local service=$( grep -E '^[a-z]' /etc/services |
awk -vport=$port -v proto=$proto '{ if ( $2 == port"/"proto ) { print $1; exit 0 } } '
)
[[ -z $service ]] && services="N/A"
echo $service
}
################################################################################
port=
proto=tcp
while getopts "i:p:h" arg; do
case $arg in
i)
ip=$OPTARG
;;
p)
port=$OPTARG
;;
h|?)
usage >&2
exit 1
;;
esac
done
if [[ -z $port ]]; then
usage
fi
precheck
tmpf=$( mktemp )
ss -lant 2>/dev/null | sed -e 's/::/*/' -e 's/:/\t/g' > "$tmpf"
listen_ip=$( awk -vport=$port '{ if ($1 == "LISTEN" && $5 == port) { print $4; } }' "$tmpf" | sort -u | xargs | tr ' ' ',' )
if [[ -z $listen_ip ]]; then
echo -e "Listen ip:\tN/A"
exit 1
fi
echo -e "Listen ip:\t$listen_ip"
echo -e "Protocol:\ttcp"
echo -e "Port:\t$port"
echo -e "Service:\t$( get_service_name $port $proto)"
echo -e "Connections:"
awk -vport=$port '{
if ( $1 != "LISTEN" && $5 == port ) { stat[$1]++ }
}
END {
for (s in stat) { print "\t"s":\t"stat[s] }
} ' "$tmpf"
/bin/rm "$tmpf"
- uptime-kuma_install.sh
#!/usr/bin/env bash
#===============================================================================
#
# FILE: uptime-kuma_install.sh
#
# USAGE: ./uptime-kuma_install.sh
#
# DESCRIPTION: 一键部署 uptime-kuma 监控平台工具
#
# ORGANIZATION: DingQz dqzboy.com
#===============================================================================
SETCOLOR_SKYBLUE="echo -en \\E[1;36m"
SETCOLOR_SUCCESS="echo -en \\E[0;32m"
SETCOLOR_NORMAL="echo -en \\E[0;39m"
SETCOLOR_RED="echo -en \\E[0;31m"
SETCOLOR_YELLOW="echo -en \\E[1;33m"
GREEN="3[1;32m"
RESET="3[0m"
PURPLE="3[35m"
SUCCESS() {
${SETCOLOR_SUCCESS} && echo "------------------------------------< $1 >-------------------------------------" && ${SETCOLOR_NORMAL}
}
SUCCESS1() {
${SETCOLOR_SUCCESS} && echo "$1" && ${SETCOLOR_NORMAL}
}
ERROR() {
${SETCOLOR_RED} && echo "$1" && ${SETCOLOR_NORMAL}
}
INFO() {
${SETCOLOR_SKYBLUE} && echo "------------------------------------ $1 -------------------------------------" && ${SETCOLOR_NORMAL}
}
INFO1() {
${SETCOLOR_SKYBLUE} && echo "$1" && ${SETCOLOR_NORMAL}
}
WARN() {
${SETCOLOR_YELLOW} && echo "$1" && ${SETCOLOR_NORMAL}
}
function CHECK_OS() {
if [ -f /etc/os-release ]; then
. /etc/os-release
else
echo "无法确定发行版"
exit 1
fi
# 根据发行版选择存储库类型
case "$ID" in
"centos")
repo_type="centos"
;;
"debian")
repo_type="debian"
;;
"rhel")
repo_type="rhel"
;;
"ubuntu")
repo_type="ubuntu"
;;
"opencloudos")
repo_type="centos"
;;
"rocky")
repo_type="centos"
;;
*)
WARN "此脚本暂不支持您的系统: $ID"
exit 1
;;
esac
echo "------------------------------------------"
echo "系统发行版: $NAME"
echo "系统版本: $VERSION"
echo "系统ID: $ID"
echo "系统ID Like: $ID_LIKE"
echo "------------------------------------------"
}
function INSTALL_DOCKER() {
# 定义存储库文件名
repo_file="docker-ce.repo"
# 下载存储库文件
url="https://download.docker.com/linux/$repo_type"
if [ "$repo_type" = "centos" ] || [ "$repo_type" = "rhel" ]; then
if ! command -v docker &> /dev/null;then
while [ $attempt -lt $MAX_ATTEMPTS ]; do
attempt=$((attempt + 1))
ERROR "docker 未安装,正在进行安装..."
yum-config-manager --add-repo $url/$repo_file &>/dev/null
yum -y install docker-ce &>/dev/null
# 检查命令的返回值
if [ $? -eq 0 ]; then
success=true
break
fi
echo "docker安装失败,正在尝试重新下载 (尝试次数: $attempt)"
done
if $success; then
SUCCESS1 ">>> $(docker --version)"
systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
systemctl enable docker &>/dev/null
else
ERROR "docker安装失败,请尝试手动安装"
exit 1
fi
else
INFO1 "docker 已安装..."
SUCCESS1 ">>> $(docker --version)"
systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
fi
elif [ "$repo_type" == "ubuntu" ]; then
if ! command -v docker &> /dev/null;then
while [ $attempt -lt $MAX_ATTEMPTS ]; do
attempt=$((attempt + 1))
ERROR "docker 未安装,正在进行安装..."
curl -fsSL $url/gpg | sudo apt-key add - &>/dev/null
add-apt-repository "deb [arch=amd64] $url $(lsb_release -cs) stable" <<< $'\n' &>/dev/null
apt-get -y install docker-ce docker-ce-cli containerd.io &>/dev/null
# 检查命令的返回值
if [ $? -eq 0 ]; then
success=true
break
fi
echo "docker安装失败,正在尝试重新下载 (尝试次数: $attempt)"
done
if $success; then
SUCCESS1 ">>> $(docker --version)"
systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
systemctl enable docker &>/dev/null
else
ERROR "docker安装失败,请尝试手动安装"
exit 1
fi
else
INFO1 "docker 已安装..."
SUCCESS1 ">>> $(docker --version)"
systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
fi
elif [ "$repo_type" == "debian" ]; then
if ! command -v docker &> /dev/null;then
while [ $attempt -lt $MAX_ATTEMPTS ]; do
attempt=$((attempt + 1))
ERROR "docker 未安装,正在进行安装..."
curl -fsSL $url/gpg | sudo apt-key add - &>/dev/null
add-apt-repository "deb [arch=amd64] $url $(lsb_release -cs) stable" <<< $'\n' &>/dev/null
apt-get -y install docker-ce docker-ce-cli containerd.io &>/dev/null
# 检查命令的返回值
if [ $? -eq 0 ]; then
success=true
break
fi
echo "docker安装失败,正在尝试重新下载 (尝试次数: $attempt)"
done
if $success; then
SUCCESS1 ">>> $(docker --version)"
systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
systemctl enable docker &>/dev/null
else
ERROR "docker安装失败,请尝试手动安装"
exit 1
fi
else
INFO1 "docker 已安装..."
SUCCESS1 ">>> $(docker --version)"
systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
fi
else
ERROR "Unsupported operating system."
exit 1
fi
}
function ADD_UPTIME_KUMA() {
SUCCESS "Uptime Kuma"
read -e -p "$(echo -e ${GREEN}"是否部署uptime-kuma监控工具?(y/n): "${RESET})" uptime
if [[ "$uptime" == "y" ]]; then
# 检查是否已经运行了 uptime-kuma 容器
if docker ps -a --format "{{.Names}}" | grep -q "uptime-kuma"; then
WARN "已经运行了uptime-kuma监控工具。"
read -e -p "$(echo -e ${GREEN}"是否停止和删除旧的容器并继续安装?(y/n): "${RESET})" continue_install
if [[ "$continue_install" == "y" ]]; then
docker stop uptime-kuma
docker rm uptime-kuma
INFO1 "已停止和删除旧的uptime-kuma容器。"
else
INFO1 "已取消部署uptime-kuma监控工具。"
exit 0
fi
fi
MAX_TRIES=3
for ((try=1; try<=${MAX_TRIES}; try++)); do
read -e -p "$(echo -e ${GREEN}"请输入监听的端口: "${RESET})" UPTIME_PORT
# 检查端口是否已被占用
if ss -tulwn | grep -q ":${UPTIME_PORT} "; then
ERROR "端口 ${UPTIME_PORT} 已被占用,请尝试其他端口。"
if [ "${try}" -lt "${MAX_TRIES}" ]; then
WARN "您还有 $((${MAX_TRIES} - ${try})) 次尝试机会。"
else
ERROR "您已用尽所有尝试机会。"
exit 1
fi
else
break
fi
done
# 提示用户输入映射的目录
read -e -p "$(echo -e ${GREEN}"请输入数据持久化在宿主机上的目录路径: "${RESET})" MAPPING_DIR
# 检查目录是否存在,如果不存在则创建
if [ ! -d "${MAPPING_DIR}" ]; then
mkdir -p "${MAPPING_DIR}"
INFO1 "目录已创建:${MAPPING_DIR}"
fi
# 启动 Docker 容器
docker run -d --restart=always -p "${UPTIME_PORT}":3001 -v "${MAPPING_DIR}":/app/data --name uptime-kuma louislam/uptime-kuma:1
# 检查 uptime-kuma 容器状态
status_uptime=`docker container inspect -f '{{.State.Running}}' uptime-kuma 2>/dev/null`
# 判断容器状态并打印提示
if [[ "$status_uptime" == "true" ]]; then
SUCCESS "CHECK"
Progress
SUCCESS1 ">>>>> Docker containers are up and running."
INFO1 "uptime-kuma 安装完成,请使用浏览器访问 IP:${UPTIME_PORT} 进行访问。"
else
SUCCESS "CHECK"
Progress
ERROR ">>>>> The following containers are not up"
if [[ "$status_uptime" != "true" ]]; then
ERROR "uptime-kuma 安装过程中出现问题,请检查日志或手动验证容器状态。"
fi
fi
elif [[ "$uptime" == "n" ]]; then
# 取消部署uptime-kuma
WARN "已取消部署uptime-kuma监控工具!"
else
ERROR "选项错误!请重新运行脚本并选择正确的选项。"
exit 1
fi
}
main() {
CHECK_OS
INSTALL_DOCKER
ADD_UPTIME_KUMA
}
main

必须 注册 为本站用户, 登录 后才可以发表评论!