自动化运维-《日常运维手册接入手册》之 服务器端口表

前言:脚本编写不是一蹴而就,需要根据当前场景和实际需求不断测试和调整,最重要的是勇于踏出敢于尝试的这一步。

任务需求:在ansible-vault加密环境下,使用root权限批量将项目上所有服务器的tcp端口过滤掉22, 25, 53, 443,631,9100,10050端口 后显示出来;判断服务器上如果有jps命令的就执行,输出的所有的程序的PID,并显示PID对应的进程,查出各PID对应的端口;如果没有jps命令的服务器就只显示过滤后的端口信息。

1.0版本:

第一步:写一个在ansible上执行的脚本yaml文件

---
- name: 项目名
  hosts: 项目hosts名
  user: 普通用户
  vars_files:
    - "secrets.yml"
  vars:
    ansible_ssh_pass: "{{ lookup('vars', 'dms_password') }}"
    ansible_become_pass: "{{ lookup('vars', 'dms_password') }}"
  tasks:
    - name: just test
      become: yes
      become_user: root
      become_method: sudo
      shell:  netstat -tlnp

第二步执行命令:ansible-playbook -i /etc/ansible/hosts ***.yaml --ask-vault-pass -v
这个是输出项目上所有服务器的tcp端口,然后手动排查系统默认端口,各web服务,中间件和数据库等自己判断,jar应用又下一步来完成统计。

第三步 写个jps-pid-端口的脚本
这里我将错误的脚本和达不到的效果的脚本都列举出来
脚本1:

#!/bin/bash

# 获取 root 用户下的所有 Java 进程的 PID 和名称
PIDS_NAMES=$(sudo jps | awk '{print $1","$2}')

# 遍历每个 PID 和名称,查找对应的端口
for PID_NAME in $PIDS_NAMES; do
   PID=$(echo $PID_NAME | cut -d, -f1)
   NAME=$(echo $PID_NAME | cut -d, -f2)
   echo "PID: $PID, Name: $NAME"

   # 使用 lsof 查找端口
   PORTS=$(sudo lsof -a -p $PID -i -n | grep LISTEN | awk '{print $9}' | cut -d: -f2)
   # 或者使用 netstat 查找端口
   # PORTS=$(sudo netstat -anp | grep $PID | grep LISTEN | awk '{print $4}' | cut -d: -f2)

   echo "Ports: $PORTS"
   echo "----------------------------------------"
done

执行结果:

结论:有的jar程序无法显示出对应的端口

脚本2:

#!/bin/bash

# 执行 jps 命令获取进程信息
jps_output=$(jps -l)

# 提取 PID 和进程名
IFS=$'\n'
for line in $jps_output; do
    pid=$(echo $line | awk '{print $1}')
    process_name=$(echo $line | awk '{print $2}')
    # 使用 netstat 查找 PID 对应的端口
    ports=$(sudo netstat -nlp | awk '$7 ~ /'$pid'/{print $4}' | awk -F ':' '{print $NF}')
    echo "PID: $pid, Process: $process_name, Ports: $ports"
done

执行结果:

结论:无法显示对应端口

脚本3:
在这里加入了一段 自动检查jps和netstat命令是否存在的字段,这个可以选择性的加不加

#!/bin/bash

# 检查jps和netstat命令是否存在
if ! command -v jps &> /dev/null; then
    echo "jps 命令未找到,请确保Java已安装。"
    exit 1
fi

if ! command -v netstat &> /dev/null; then
    echo "netstat 命令未找到,请确保net-tools已安装。"
    exit 1
fi

# 获取所有Java进程的PID和命令行参数
java_processes=$(jps -l)

# 检查jps命令是否成功执行
if [ $? -ne 0 ]; then
    echo "jps 命令执行失败。"
    exit 1
fi

echo "Java进程的PID和命令行参数:"
echo "$java_processes"

# 定义一个函数来查找进程的端口
find_ports_for_pid() {
    local pid=$1
    # 使用netstat和grep查找PID对应的端口
    netstat -tulnp | grep "$pid" | awk '{print $4}'
}

# 遍历所有Java进程
for process in $java_processes; do
    # 提取PID
    pid=$(echo $process | cut -d ' ' -f 1)

    # 打印PID
    echo "查找 PID: $pid 对应的端口..."
    
    # 查找端口
    find_ports_for_pid "$pid"

    # 打印分隔线
    echo "----------"
done

执行结果:

结论:端口没有并排显示,不方便统计

脚本F:

#!/bin/bash

# 执行 jps 命令获取进程信息
jps_output=$(jps -l)

# 提取 PID 和进程名
IFS=$'\n'
for line in $jps_output; do
    pid=$(echo $line | awk '{print $1}')
    process_name=$(echo $line | awk '{print $2}')
    # 使用 netstat 查找 PID 对应的端口
    ports=$(sudo netstat -nlp | awk '$7 ~ /'$pid'/{print $4}' | awk -F ':' '{print $NF}')
    ports_array=($ports)
    ports_str=""
    for port in "${ports_array[@]}"; do
        if [ -n "$ports_str" ]; then
            ports_str="$ports_str,"
        fi
        ports_str="$ports_str$port"
    done
    echo "PID: $pid, Process: $process_name, Ports: $ports_str"
done

执行结果:

结论:完美!

2.0版本:
1.0版本所有步骤,也就是整个需求又自动化工具ansible一键完成。
写一个在ansible上执行的脚本yaml文件

- name: 项目名
  hosts: 项目hosts
  user: 普通用户
  vars_files:
    - "secrets.yml"
  vars:
    ansible_ssh_pass: "{{ lookup('vars', 'dms_password') }}"
    ansible_become_pass: "{{ lookup('vars', 'dms_password') }}"
  tasks:
   - name: Gather filtered TCP ports
     become: yes
     become_user: root
     become_method: sudo
     shell: "netstat -tlnp | grep LISTEN | awk '{print $4}' | cut -d: -f2 | grep -Ev '22|25|53|443|631|9100|10050'"
     register: filtered_ports

   - name: Display filtered TCP ports
     become: yes
     become_user: root
     become_method: sudo
     debug:
       var: filtered_ports.stdout_lines

   - name: Check if jps shell is available
     become: yes
     become_user: root
     become_method: sudo
     shell: "which jps"
     register: jps_check
     failed_when: false

   - name: Gather Java process information
     become: yes
     become_user: root
     become_method: sudo
     shell: "jps -l"
     register: jps_output
     when: jps_check.stdout | length > 0

   - name: Display Java process information
     become: yes
     become_user: root
     become_method: sudo
     debug:
       var: jps_output.stdout_lines
     when: jps_check.stdout | length > 0

   - name: Gather ports for Java processes
     become: yes
     become_user: root
     become_method: sudo
     shell: "lsof -a -p {{ item }} -i -n | grep LISTEN | awk '{print $9}' | cut -d: -f2"
     loop: "{{ jps_output.stdout_lines | map('regex_replace', '^(.*) (.*)$', '\\1') | list }}"
     register: java_process_ports
     when: jps_check.stdout | length > 0

   - name: Display ports for Java processes
     become: yes
     become_user: root
     become_method: sudo
     debug:
       var: java_process_ports.results | map(attribute='stdout_lines') | list
     when: jps_check.stdout | length > 0


执行结果:

这里只能展示最后的结果,没有报错和失败的,上面的输出信息涉及公司隐私

posted @   Linux运维技术栈  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
点击右上角即可分享
微信分享提示