我编写了这个脚本来查找$ WWWUSER具有写权限的所有文件/目录。首先,我将剩余的匹配项存储在临时文件中。我新的必须有一种不使用文件的方式,所以这是我的“解决方案”。它有效,但速度很慢。有什么提示吗?
更新 在包含大约7k目录和30k文件(~8k白名单)的目录结构上,脚本大约需要15分钟...(ext3文件系统,UW320 SCSI硬盘)。
#!/usr/bin/env bash
# Checks the webroot for files owned by www daemon and
# writable at the same time. This is only needed by some files
# So we'll check with a whitelist
WWWROOT=/var/www
WWWUSER=www-data
WHITELIST=(/wp-content/uploads
/wp-content/cache
/sitemap.xml
)
OLDIFS=$IFS
IFS=$'\n'
LIST=($(find $WWWROOT -perm /u+w -user $WWWUSER -o -perm /g+w -group $WWWUSER))
IFS=$OLDIFS
arraycount=-1
whitelist_matches=0
for matchedentry in "${LIST[@]}"; do
arraycount=$(($arraycount+1))
for whitelistedentry in "${WHITELIST[@]}"; do
if [ $(echo $matchedentry | grep -c "$whitelistedentry") -gt 0 ]; then
unset LIST[$arraycount]
whitelist_matches=$(($whitelist_matches+1))
fi
done
LISTCOUNT=${#LIST[@]}
done
if [ $(echo $LISTCOUNT) -gt 0 ]; then
for item in "${LIST[@]}"; do
echo -e "$item\r"
done
echo "$LISTCOUNT items are writable by '$WWWUSER' ($whitelist_matches whitelisted)."
else
echo "No writable items found ($whitelist_matches whitelisted)."
fi
答案 0 :(得分:1)
还有另一种可能性。将白名单更改为正则表达式模式,您可以使用= ~bash正则表达式运算符(版本3及更高版本)快速匹配列表中任何找到的单词: 如果($字=〜$图案) $ pattern可能是 “^(whitelistentry1 | whitelistentry2 | whitelistentry3 | ...)$”
答案 1 :(得分:1)
(我没有设置方便对它进行测试,但应该工作......)
#!/usr/bin/env bash
# Checks the webroot for files owned by www daemon and
# writable at the same time. This is only needed by some files
# So we'll check with a whitelist
WWWROOT=/var/www
WWWUSER=www-data
WHITELIST="(/wp-content/uploads|/wp-content/cache|/sitemap.xml)"
listcount=0
whitelist_matches=0
while IFS="" read -r matchedentry; do
if [[ "$matchedentry" =~ $WHITELIST ]]; then
((whitelist_matches++))
else
echo -e "$matchedentry\r"
((listcount++))
fi
done < <(find "$WWWROOT" -perm /u+w -user $WWWUSER -o -perm /g+w -group $WWWUSER)
if (( $listcount > 0 )); then
echo "$listcount items are writable by '$WWWUSER' ($whitelist_matches whitelisted)."
else
echo "No writable items found ($whitelist_matches whitelisted)."
fi
编辑:我已经将丹尼斯威廉姆森的数学建议纳入其中;另外,这是一种从数组开始构建WHITELIST模式的方法:
WHITELIST_ARRAY=(/wp-content/uploads
/wp-content/cache
/sitemap.xml
)
WHITELIST=""
for entry in "${WHITELIST_ARRAY[@]}"; do
WHITELIST+="|$entry"
done
WHITELIST="(${WHITELIST#|})" # this removes the stray "|" from the front, and adds parens
Edit2:Sorpigal关于消除新进程的评论让我思考 - 我怀疑这个版本的大部分加速都来自于每个扫描文件没有运行〜grep
的〜{40}调用,而只是稍微移除了数组操作,但我想到如果你不需要最后的总数,你可以删除主while循环并用它替换它:
find "$WWWROOT" -perm /u+w -user $WWWUSER -o -perm /g+w -group $WWWUSER | grep -v "$WHITELIST"
...它运行grep
,但只运行一次(并通过该单个实例运行整个文件列表),一旦启动grep
将能够扫描文件列表比bash循环快......