首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在默认包管理器v2之外查找侦听网络的过程

在默认包管理器v2之外查找侦听网络的过程
EN

Code Review用户
提问于 2022-08-28 14:44:47
回答 1查看 238关注 0票数 3

这是在默认包管理器之外的网络上查找侦听过程的后续问题

由于使用了/proc,我设法使它变得更快一些,并希望能够实现大多数建议。一些小问题

  • 我们能摆脱这些管道来支持这里的琴弦吗?我试过,但遇到了问题。
  • 我们能摆脱自定义的readarray函数吗?它占用了太多的空间,只使用过一次。一直在努力寻找一个简洁的替代品。
  • 与以前一样,代码需要支持bash 3.2+,因此遗憾的是,没有许多出色的特性可用。

和以前一样,它的工作原理与预期一样。

Improved代码

代码语言:javascript
复制
#!/bin/bash

# finds processes listening in on the network outside outside of the default package manager

usage=$(cat <<-EOF
$(basename "$0").sh [-h] [-f] [-a] [-w] [-v] [-p]

Lists packages listening on the network outside of the default package manager

where:
    -h,  --help                     show this help text
    -f,  --whitelist-file           pick a file[s] containing whitelisted programs
    -w,  --whitelist                explicitly add whitelisted programs
    -W,  --ignore-whitelist         ignore the whitelist, includes env variables
    -v,  --view-whitelist           view the complete whitelist
    -p,  --package-manager          which package-manager to use (rpm, dkpg, ...)
    -P,  --ignore-package-manager   ignores the check for a working package manager

output:
  COMMAND    PATH                PID    USER     FD   TYPE  DEVICE    SIZE/OFF  NODE  NAME
  mattermos  /app/main/mattermo  3351   361000   25u  IPv4  84625698  0t0       TCP   129.240...(ESTABLISHED)

examples:
    List all processes listening on the network
      usit_network_network_listening_processes --list-all 

    List only packages not maintained by the central package manager system
      usit_network_network_listening_processes --list-all 

    Whitelist some processes 
      usit_network_network_listening_processes --whitelist mattermos,systemd
      usit_network_network_listening_processes --whitelist 'mattermos systemd'

    Whitelist some processes using whitelist files
      usit_network_network_listening_processes -f /etc/uio/uio_network_listening_processes_whitelist_01.txt

    Multiple whitelist files is supported
      usit_network_network_listening_processes --whitelist foo.txt,bar.txt

environment variables:
  The following environment variables are available
  
    USIT_LISTENER_WHITELIST
    USIT_LISTENER_WHITELIST_FILES
  
  These form the base for the whitelist and whitelist files respectively. 
  Use a string with spaces or comma [,] as seperator for the values.
EOF
)

fatal() {
    printf "ERROR: $*" >&2
    exit 1
}

# This is a substitute for readarray for older bash versions
# https://stackoverflow.com/a/64793921/1048781
if ! type -t readarray >/dev/null; then
  # Very minimal readarray implementation using read. Does NOT work with lines that contain double-quotes due to eval()
  readarray() {
    local cmd opt t v=MAPFILE
    while [ -n "$1" ]; do
      case "$1" in
      -h|--help) echo "minimal substitute readarray for older bash"; exit; ;;
      -r) shift; opt="$opt -r"; ;;
      -t) shift; t=1; ;;
      -u) 
          shift; 
          if [ -n "$1" ]; then
            opt="$opt -u $1"; 
            shift
          fi
          ;;
      *)
          if [[ "$1" =~ ^[A-Za-z_]+$ ]]; then
            v="$1"
            shift
          else
            echo -en "${C_BOLD}${C_RED}Error: ${C_RESET}Unknown option: '$1'\n" 1>&2
            exit
          fi
          ;;
      esac
    done
    cmd="read $opt"
    eval "$v=()"
    while IFS= eval "$cmd line"; do      
      line=$(echo "$line" | sed -e "s#\([\"\`]\)#\\\\\1#g" )
      eval "${v}+=(\"$line\")"
    done
  }
fi

# Transform long options to short ones
args=()

for arg; do
    case $arg in
    '--whitelist')                args+=(-w) ;;
    '--whitelist-file')           args+=(-f) ;;
    '--ignore-whitelist')         args+=(-W) ;;
    '--ignore-package-manager')   args+=(-P) ;;
    '--view-whitelist')           args+=(-v) ;;
    '--package-manager')          args+=(-p) ;;
    '--help')                     args+=(-h) ;;
    *)                            args+=("$arg") ;;
    esac
done

set -- "${args[@]}"

# The '//,/ ' allows us to input variables using , seperator as well as SPACE
whitelist=()
whitelist_files=()
read -ar whitelist <<< "${USIT_LISTENER_WHITELIST//,/ }"
read -ar whitelist_files <<< "${USIT_LISTENER_WHITELIST_FILES//,/ }"
view_whitelist=false
ignore_whitelist=false
ignore_package_manager=false
while getopts ":w:f:p:vPWh" flag; do
    case "${flag}" in
    h)
        echo "$usage"
        exit 0
        ;;
    v) view_whitelist=true ;;
    W) ignore_whitelist=true ;;
    P) ignore_package_manager=true ;;
    w) read -ra parts <<< "${OPTARG//,/ }"
       whitelist+=("${parts[@]}")
       ;;
    f) read -ra parts <<< "${OPTARG//,/ }"
       whitelist_files+=("${parts[@]}")
       ;;
    p) package_manager=${OPTARG} ;;
    \?)
        fatal "illegal option: -%s${OPTARG} \n\n$usage\n\n"
        ;;
    esac
done

# -i : This option filters only processes whith an IPv[46] address:
# -P : This option inhibits the conversion of port numbers to port names for network files.
# -n : This option inhibits the conversion of network numbers to host names for network files.
# -l : This option inhibits the conversion of user ID numbers to login names.
# +M : Enables the reporting of portmapper registrations for local TCP and UDP ports.
# The awk filters only unique PID's by  _[val] looks up val in the hash _(a regular variable).
# NR > 1 is used to skip the header
network_listening_processes=$(
  lsof -Pnl +M -i | 
    awk 'NR>1 && !seen[$1]++ { print }' 
)
# we use the realpath -m to extract the execution path from the process id (pid)
network_listening_processes_with_path=$(
    while read -r a pid b; do
        printf "%s %s %s %s\n" "$a" "'$(realpath -m /proc/"$pid"/exe)'" "$pid" "$b"
    done <<< "${network_listening_processes[@]}"
)
if "${ignore_whitelist}" && "${ignore_package_manager}"; then
    echo "${network_listening_processes_with_path}" | column -t
    exit
fi

function is_in_array {
    local array="$1[@]"
    local seeking="${!2}"
    local result=1
    for element in "${!array}"; do
        if [[ $element == "$seeking" ]]; then
            result=0
            break
        fi
    done
    return $result
}

function is_empty_array {
    local array="$1[@]"
    for element in "${!array}"; do
        return 1
    done
    return 0
}

function print_array {
    local array="$1[@]"
    for element in "${!array}"; do
        echo "${element}"
    done
}

# Block of code for getting the correct package manager
is_in_standard_repo_rpm() {
    rpm -qf "${1}" &>/dev/null
}
is_in_standard_repo_dpkg() {
    dpkg -S "${1}" &>/dev/null
}
is_in_standard_repo_any() {
    local package="${1}"
    return 1
}
if "${ignore_package_manager}"; then
    package_manager="any"
else
    dpkg_equivalents=("dpkg" "apt" "")
    rpm_equivalents=("rpm" "yum" "dnf" "")
    if is_in_array dpkg_equivalents package_manager && dpkg --version &>/dev/null; then
        package_manager="dpkg"
    elif is_in_array rpm_equivalents package_manager && rpm --version &>/dev/null; then
        package_manager="rpm"
    else
        fatal "No supported package manager found! Try specifying one with -p --package-manager"
    fi
fi
is_in_standard_repo () {
    is_in_standard_repo_$package_manager "${!1}"
}

# block of code for handling the whitelist
if "${ignore_whitelist}"; then
    whitelist=()
else
    if ! is_empty_array whitelist_files; then
        readarray -t whitelist_from_file < <(sort -u "${whitelist_files[@]}")
        whitelist+=("${whitelist_from_file[@]}")
    fi
fi
if "${view_whitelist}"; then
    ! is_empty_array whitelist && print_array whitelist
    exit
fi

# Finally we list every process not in the default packagen_manager
# Which is listening on the network
while IFS= read -r line; do
    programname=$(awk '{print $1}' <<< "${line}")
    path=$(awk '{print $2}' <<< "${line}")
    path_without_quotes=$(sed 's/^.\(.*\).$/\1/' <<< "${path}")
    if ! is_in_standard_repo path_without_quotes && ! is_in_array whitelist programname; then
        echo "${line}"
    fi
done <<< "${network_listening_processes_with_path}" | column -t
EN

回答 1

Code Review用户

回答已采纳

发布于 2022-08-28 16:25:03

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/279233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档