Tho*_*usz 8 server package-management security bash dependencies
我读过 Jay Lacroix 的关于“Mastering Ubuntu Server”的书,他建议删除所有不必要的软件包以减少攻击面。具体来说,他建议运行apt-cache rdepends <package>
以查明是否还有其他软件包取决于我们考虑删除的软件包。
我编写了一个 bash 脚本,列出了所有已安装包的依赖包,但需要很长时间(在 Raspberry Pi 4、8GB 上超过 30 分钟),我想知道是否有更好、更快的解决方案。
#!/bin/bash
readarray -t packages < <(dpkg --get-selections | cut -f1)
for package in ${packages[@]};
do
readarray -t dependents < <(apt-cache rdepends $package | sed -n '3,$s/^\s*//p')
echo "-----------------------------------------------------------------------" | tee -a packages_and_depents.txt
echo "${package} has these dependents on the system of max ${#dependents[@]}:" | tee -a packages_and_depents.txt
echo "-----------------------------------------------------------------------" | tee -a packages_and_depents.txt
for dependent in ${dependents[@]};
do
dpkg --get-selections $dependent 2>/dev/null | tee -a packages_and_depents.txt
done
done
Run Code Online (Sandbox Code Playgroud)
Art*_*ild 12
包dpkg
系统为每个包都有一个字段,指示其Priority。
您可以使用它作为初始过滤器,并且仅在分类为optional
和的包上运行脚本extra
(并省略required
,important
和standard
)。
此外,创建一个额外的数组并for
为每个包运行一个额外的循环似乎没有必要,并且肯定会占用更多的计算能力。
所以我删除了第二个for
循环,而是--installed
直接添加到apt-cache rdepends
命令中。
这可以通过修改脚本来完成,如下所示:
#!/bin/bash
# The command for this line is changed
readarray -t packages < <(dpkg-query -Wf '${Package}${Status}${Priority}\n' | sort -b -k5,5 -k1,1 | grep -v 'required\|important\|standard' | grep 'installed' | awk '{ print $1 }')
for package in ${packages[@]};
do
echo "--------------------------------------------------------" | tee -a packages_and_depents.txt
echo "${package} has these dependents installed on the system:" | tee -a packages_and_depents.txt
echo "--------------------------------------------------------" | tee -a packages_and_depents.txt
# 2nd for loop removed and replaced with `--installed` option
apt-cache --installed rdepends "$package" | tail -n +3 | tee -a packages_and_depents.txt
done
Run Code Online (Sandbox Code Playgroud)
另一种选择是更改整个脚本,因此它不显示所有反向依赖项,而是仅显示那些没有反向依赖项的包的名称(那些是要删除的候选包)。
grep
另外,我认为您可以通过排除名称以lib
(添加)开头的所有包来添加额外的排除grep -v '^lib'
。
最后,可以改进演示文稿,因此脚本在运行时会提供视觉反馈,但最终报告仅写入输出文件。
这是我的脚本的最终版本:
#!/bin/bash
# The command for this line is changed
readarray -t packages < <(dpkg-query -Wf '${Package}${Status}${Priority}\n' | sort -b -k5,5 -k1,1 | grep -v 'required\|important\|standard' | grep -v '^lib' | grep 'installed' | awk '{ print $1 }')
# Write to file
echo "The following packages are not a dependency to any installed package:" > packages_no_depends.txt
# Write to screen
echo "Number of packages: [ ${#packages[@]} ] (priority optional/extra)"
echo ""
i=0
j=0
# Loop that only prints package names with NO reverse dependencies
for package in ${packages[@]};
do
(( j++ ))
echo -e "\033[1AProcessed packages: [ $i/$j ]"
if [[ $(apt-cache --installed rdepends "$package" | tail -n +3 | wc -l) -eq 0 ]]
then
# Write to file
echo " $package" >> packages_no_depends.txt
# Write to screen
echo -e "\033[K Package $package added to the list of non-dependencies\033[1A"
(( i++ ))
fi
done
# Final overview
echo -e "\033[K"
echo "STATUS"
echo "======"
echo " Total packages scanned : $j"
echo " Candidates for removal : $i"
echo " Script execution time : $SECONDS seconds"
Run Code Online (Sandbox Code Playgroud)
参考光标移动的转义码。
编辑:此解决方案主要应考虑布局和演示 - Raffa 的解决方案更有效,因此您可以根据喜好自行组合两者。
根据 Raffa 的意见,这是我的脚本的最终版本:
#!/bin/bash
# Change /path/to
dpkg_file="/path/to/packages_no_depends.txt"
# Write to file
echo "The following packages are not a dependency to any installed package:" > "$dpkg_file"
# Write to screen
echo "Scanning packages ..."
# Function to write non-dependencies to file
dpkg-query -Wf '${Package} ${Status}${Priority}\n' |
grep -v 'required\|important\|standard' |
grep 'installed' |
awk '{ print $1 }' |
xargs apt-cache rdepends --installed |
awk '! /Reverse Depends:/ {
tp = $0
n++
}
/Reverse Depends:/ {
if (n == 1 && NR != 2) {
print " " p
}
n = 0
p = tp
}
END {
if (n == 0) {
print " " p
}
}' >> "$dpkg_file"
# Final overview
echo -e "\nSTATUS\n======"
echo " Total packages scanned : $(dpkg-query -Wf '${Package}${Status}${Priority}\n' | grep -v 'required\|important\|standard' | grep 'installed' | wc -l)"
echo " Candidates for removal : $(tail -n +2 $dpkg_file | wc -l)"
echo " Script execution time : $SECONDS seconds"
Run Code Online (Sandbox Code Playgroud)
根据您在脚本中实现的工具,这应该尽可能快:
dpkg --get-selections |
cut -f1 |
xargs apt-cache rdepends --installed |
awk '! /Reverse Depends:/ {
tp = $0
n++
}
/Reverse Depends:/ {
if (n == 1 && NR != 2) {
print p
}
n = 0
p = tp
}
END {
if (n == 0) {
print p
}
}
'
Run Code Online (Sandbox Code Playgroud)
它应该在输出中列出dpkg --get-selections | cut -f1
未安装的软件包,以反转对系统的依赖关系。
切勿将上述命令的输出提供给软件包删除工具...检查输出并在所有情况下手动处理它。
归档时间: |
|
查看次数: |
3682 次 |
最近记录: |