优秀的编程知识分享平台

网站首页 > 技术文章 正文

Linux 运维 + 网络安全 shell 脚本

nanyue 2025-09-01 10:14:35 技术文章 5 ℃

1)资产与基线快照(主机指纹一键采集)



用途:一键收集主机关键信息(系统/内核/CPU/内存/网卡/IP/路由/磁盘/关键软件版本),作为安全&变更基线。

#!/usr/bin/env bash

# sys_baseline.sh

set -euo pipefail


OUT=${1:-/var/log/sys_baseline_$(hostname)_$(date +%F).txt}

{

echo "=== BASELINE @ $(date '+%F %T') ==="

echo "[System] : $(uname -a)"

echo "[OS Release] : $(cat /etc/os-release 2>/dev/null | tr -d '\r' | paste -sd' ')"

echo "[Kernel] : $(uname -r)"

echo "[Uptime] : $(uptime -p)"

echo "[CPU] : $(lscpu | awk -F: '/Model name|CPU\(s\)/{gsub(/^[ \t]+/,"",$2); print $1":"$2}')"

echo "[Memory] : $(free -h | awk '/Mem:/{print $2" total, "$3" used, "$4" free"}')"

echo "[Disks] :"; lsblk -o NAME,SIZE,TYPE,MOUNTPOINT

echo "[FS Use] :"; df -hT | awk 'NR==1 || $2!="tmpfs"'

echo "[NIC] :"; ip -o -4 addr show | awk '{print $2,$4}'

echo "[Routes] :"; ip route

echo "[Listening] :"; ss -tulpen

echo "[Users] :"; who

echo "[Sudoers] :"; getent group sudo wheel 2>/dev/null

echo "[Packages] :"

if command -v rpm >/dev/null; then rpm -qa | wc -l; fi

if command -v dpkg >/dev/null; then dpkg -l | wc -l; fi

} > "$OUT"


echo "Saved to $OUT"

Xshell 执行示例:

[root@prod-1 ~]# bash sys_baseline.sh

Saved to /var/log/sys_baseline_prod-1_2025-08-23.txt

建议:变更前后各跑一次,或 cron 每周留档。





2)开放端口与异常监听巡检



用途:发现异常监听与非白名单端口。

#!/usr/bin/env bash

# port_audit.sh

set -euo pipefail


WHITELIST=(22 80 443 3306 6379 53) # 按需配置

echo "== Port Audit @ $(date '+%F %T') =="


mapfile -t LISTEN < <(ss -tulnH | awk '{print $5}' | sed -E 's/.*:([0-9]+)$/\1/' | sort -nu)

echo "Listening ports: ${LISTEN[*]}"


declare -A OK

for p in "${WHITELIST[@]}"; do OK["$p"]=1; done


echo "Suspicious ports:"

for p in "${LISTEN[@]}"; do

[[ ${OK[$p]+_} ]] || echo " - $p"

done

Xshell:

[root@prod-1 ~]# bash port_audit.sh

== Port Audit @ 2025-08-23 11:06:18 ==

Listening ports: 22 80 443 9100

Suspicious ports:

- 9100

建议:把白名单做成配置文件,异常端口触发告警。





3)SSH 暴力破解快速告警(auth.log/secure 解析)



用途:统计短时间多次失败的来源 IP,给出阻断建议(结合 fail2ban/nftables)。

#!/usr/bin/env bash

# ssh_bruteforce_watch.sh

set -euo pipefail


LOGFILE=$(ls /var/log/{auth.log,secure} 2>/dev/null | head -n1)

[[ -f "$LOGFILE" ]] || { echo "No auth log!"; exit 1; }


WINDOW_MIN=${1:-15}

THRESHOLD=${2:-10}


echo "== SSH Fail Watch (last ${WINDOW_MIN}m, threshold=${THRESHOLD}) =="


awk -v since="$(date --date="-${WINDOW_MIN} min" '+%b %e %H:%M')" '

BEGIN{months="JanFebMarAprMayJunJulAugSepOctNovDec"}

$0 ~ /sshd/ && $0 ~ /Failed password/ {

# naive time filter by month+day+HH:MM prefix

ts=$1" "$2" "$3

if (ts >= since) {

for(i=1;i<=NF;i++) if($i=="from"){ip=$(i+1)}

if(ip!=""){cnt[ip]++}

}

}

END{

for (i in cnt) if (cnt[i]>'"$THRESHOLD"') printf "%s %d\n", i, cnt[i]

}' "$LOGFILE" | sort -k2nr

Xshell:

[root@prod-1 ~]# bash ssh_bruteforce_watch.sh 30 20

== SSH Fail Watch (last 30m, threshold=20) ==

203.0.113.10 58

198.51.100.21 25

后续动作(示例):

# 临时阻断(nftables)

nft add rule inet filter input ip saddr 203.0.113.10 drop





4)nftables 最小可信入站策略(一键下发)



用途:快速下发“默认拒绝 + 少量白名单”策略,替代手动敲命令的错误率。

#!/usr/bin/env bash

# nft_minimal_policy.sh

set -euo pipefail


ALLOW_TCP=(22 80 443)

TABLE=inet

CHAIN=input


nft -f - <<EOF

flush ruleset

table $TABLE filter {

chain $CHAIN {

type filter hook input priority 0; policy drop;

ct state established,related accept

iif lo accept

ip protocol icmp accept

ip6 nexthdr icmpv6 accept

$(for p in "${ALLOW_TCP[@]}"; do

echo " tcp dport $p accept"

done)

}

}

EOF

echo "nftables policy applied."

Xshell:

[root@prod-1 ~]# bash nft_minimal_policy.sh

nftables policy applied.

[root@prod-1 ~]# nft list ruleset | sed -n '1,25p'

注意:远程执行前请确认 SSH 端口在白名单里(默认 22)。





5)内核参数安全基线(sysctl 硬化)



用途:一键写入常见安全内核参数并生效(IP 转发、源路由、SYN 攻击等)。

#!/usr/bin/env bash

# sysctl_hardening.sh

set -euo pipefail


CFG=/etc/sysctl.d/99-secure.conf

cat > "$CFG" <<'CONF'

# IPv4

net.ipv4.ip_forward = 0

net.ipv4.conf.all.accept_source_route = 0

net.ipv4.tcp_syncookies = 1

net.ipv4.conf.all.rp_filter = 1

net.ipv4.conf.default.rp_filter = 1

# IPv6(按需)

net.ipv6.conf.all.accept_source_route = 0

# 其他

kernel.kptr_restrict = 1

kernel.randomize_va_space = 2

fs.suid_dumpable = 0

CONF


sysctl --system

echo "Applied: $CFG"

Xshell:

[root@prod-1 ~]# bash sysctl_hardening.sh

* Applying /etc/sysctl.d/99-secure.conf ...

Applied: /etc/sysctl.d/99-secure.conf





6)账号与 SSH 配置体检(空口令/弱配置扫描)



用途:发现空口令账号、PermitRootLogin 等高危 SSH 配置,并输出修复建议。

#!/usr/bin/env bash

# account_ssh_audit.sh

set -euo pipefail


echo "== Empty-password users =="

awk -F: '($2==""){print $1}' /etc/shadow || true


echo -e "\n== SSH config risky options =="

SSHD=/etc/ssh/sshd_config

grep -E '^(#\s*)?(PermitRootLogin|PasswordAuthentication|ChallengeResponseAuthentication|X11Forwarding)' "$SSHD" || true


echo -e "\n== Suggestions =="

cat <<'TIP'

- 禁用 root 远程登录:PermitRootLogin no

- 禁用口令登录(用密钥):PasswordAuthentication no

- 关闭 X11Forwarding:X11Forwarding no

- 使用 AllowUsers/AllowGroups 做白名单

TIP

Xshell:

[root@prod-1 ~]# bash account_ssh_audit.sh

== Empty-password users ==

(none)


== SSH config risky options ==

PermitRootLogin yes

PasswordAuthentication yes


== Suggestions ==

- 禁用 root 远程登录:PermitRootLogin no

...





7)日志打包与异地备份(rsync + 压缩)



用途:将 /var/log 定期压缩并同步到堡垒机/备份机,便于取证与合规。

#!/usr/bin/env bash

# log_backup_rsync.sh

set -euo pipefail


DST_USER=backup

DST_HOST=backup.example.com

DST_DIR=/data/logs/$(hostname)

TAR=/tmp/log_$(hostname)_$(date +%F).tar.gz


tar -czf "$TAR" /var/log

rsync -avz --progress "$TAR" ${DST_USER}@${DST_HOST}:${DST_DIR}/

rm -f "$TAR"

echo "Synced to ${DST_HOST}:${DST_DIR}"

Xshell:

[root@prod-1 ~]# bash log_backup_rsync.sh

sending incremental file list

log_prod-1_2025-08-23.tar.gz

...

Synced to backup.example.com:/data/logs/prod-1

建议:SSH 免密 + crontab -e 定期执行。





8)安全补丁巡检与一键升级(YUM/DNF/APT)



用途:检查并按需安装安全更新(生产建议先演练后放行)。

#!/usr/bin/env bash

# sec_update_check.sh

set -euo pipefail


if command -v dnf >/dev/null; then

echo "== DNF Security Check =="

dnf check-update --security || true

# 升级(谨慎):

# dnf update --security -y

elif command -v yum >/dev/null; then

echo "== YUM Security Check =="

yum --security check-update || true

# yum --security update -y

elif command -v apt >/dev/null; then

echo "== APT Security Check =="

apt update

apt list --upgradable 2>/dev/null | grep -i security || true

# apt upgrade -y

else

echo "No supported package manager found."

fi

Xshell:

[root@prod-1 ~]# bash sec_update_check.sh

== APT Security Check ==

Hit:1 http://...

Listing... security updates:

openssl/now 3.0.12...





9)关键路径完整性巡检(哈希快照对比)



用途:对 /etc、/usr/local/bin 等关键路径做SHA256 快照,用于发现异常改动(轻量 AIDE 替代)。

#!/usr/bin/env bash

# integrity_snapshot.sh

set -euo pipefail


TARGETS=("/etc" "/usr/local/bin")

DB=/var/lib/integrity.sha256


if [[ ! -f "$DB" ]]; then

echo "[*] Building baseline to $DB ..."

(for d in "${TARGETS[@]}"; do

find "$d" -type f -xdev -printf "%p\0"

done | xargs -0 sha256sum) > "$DB"

echo "Baseline created."

exit 0

fi


echo "[*] Comparing with baseline..."

TMP=$(mktemp)

(for d in "${TARGETS[@]}"; do

find "$d" -type f -xdev -printf "%p\0"

done | xargs -0 sha256sum) > "$TMP"


echo "== Modified files =="

comm -12 <(cut -d' ' -f3- "$DB" | sort) <(cut -d' ' -f3- "$TMP" | sort) >/dev/null

diff <(sort "$DB") <(sort "$TMP") | grep -E '^[<>]' || echo "None"


rm -f "$TMP"

Xshell:

[root@prod-1 ~]# bash integrity_snapshot.sh

[*] Building baseline to /var/lib/integrity.sha256 ...

Baseline created.


[root@prod-1 ~]# bash integrity_snapshot.sh

[*] Comparing with baseline...

== Modified files ==

< d41d8cd... /etc/ssh/sshd_config

> 1a2b3c4... /etc/ssh/sshd_config

建议:首次运行生成基线,后续定时对比并告警。





10)TLS 证书过期巡检(支持多域名)



用途:扫描一组 HTTPS 站点证书剩余天数,临近过期告警。

#!/usr/bin/env bash

# tls_expiry_check.sh

set -euo pipefail


DOMAINS=(

"example.com:443"

"api.example.com:443"

)


WARN_DAYS=${1:-30}


check() {

local hostport="$1"

end_date=$(echo | timeout 5 openssl s_client -servername "${hostport%:*}" -connect "$hostport" 2>/dev/null \

| openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2) || { echo "$hostport FAILED"; return; }

end_ts=$(date -d "$end_date" +%s)

now_ts=$(date +%s)

left_days=$(( (end_ts - now_ts) / 86400 ))

echo "$hostport => $left_days days"

if (( left_days <= WARN_DAYS )); then

echo "WARN: $hostport cert expires in $left_days days"

fi

}


for d in "${DOMAINS[@]}"; do

check "$d"

done

Xshell:

[root@prod-1 ~]# bash tls_expiry_check.sh 20

example.com:443 => 45 days

api.example.com:443 => 12 days

WARN: api.example.com:443 cert expires in 12 days

建议:结合企业通知(mail/钉钉/飞书 Webhook)发告警即可。





上线与运维建议

  • 目录与权限:将脚本统一放入 /opt/sec-scripts,仅对运维组可写(chmod 750、chown root:secops)。
  • 统一日志:所有脚本输出重定向到 /var/log/secops/*.log,便于审计。
  • 定时任务:用 crontab 或 systemd timer 统一调度,关键任务避免在整点拥塞时间运行。
  • 幂等性:配置类脚本(nftables/sysctl)需可重复执行且可回滚(保留原配置备份)。
  • 最小化变更:生产环境先在灰度/测试环境验证,再小流量放量。
  • 合规:涉及防火墙/账号策略变更须走变更流程并记录审计单号。
最近发表
标签列表