|
#!/bin/bash
|
|
# vim:sw=2:ts=2:et
|
|
|
|
export LC_ALL=C
|
|
export SCLNAME=ruby193
|
|
|
|
usage() {
|
|
[[ $UPLOAD_DISABLED -ne 0 ]] && UPLOAD_INFO=" (feature disabled by configuration)"
|
|
cat <<USAGE
|
|
$0 - configuration and log data collector
|
|
|
|
USAGE: $0 [options]
|
|
|
|
Collects configuration and log data for Foreman, Smart Proxies, backend
|
|
services and system information while removing security information like
|
|
passwords, tokens and keys.
|
|
|
|
This program can be used on Foreman instances, Smart Proxy instances or
|
|
backend services separately.
|
|
|
|
OPTIONS:
|
|
-d DIR Directory to place the tarball in (default /tmp/foreman-XYZ)
|
|
-g Skip generic info (CPU, memory, firewall etc.)
|
|
-a Do not generate a tarball from the resulting directory
|
|
-m NUM Maximum lines to keep for each file (default 5000)
|
|
-j PRG Filter with provided program when creating a tarball
|
|
-p Additionally print password patterns being filtered out
|
|
-q Quiet mode
|
|
-v Verbose mode
|
|
-u Upload tarball$UPLOAD_INFO
|
|
-h Shows this message
|
|
|
|
USAGE
|
|
[[ $UPLOAD_DISABLED -eq 0 ]] && cat <<UPLOADUSAGE
|
|
You may want to upload the tarball (with -u) to our public server via rsync.
|
|
This is a write-only directory (readable only by Foreman core developers)
|
|
Please note that the rsync transmission is UNENCRYPTED.
|
|
|
|
UPLOADUSAGE
|
|
}
|
|
|
|
# filter for patterns like password=XYZ or secret: abc!@#$123
|
|
FILTER_WORDS=(
|
|
password
|
|
PASSWORD
|
|
default_password
|
|
secret
|
|
token
|
|
api_token
|
|
oauth_secret
|
|
keystorePass
|
|
truststorePass
|
|
)
|
|
FILTER_WORDS_STR=$(IFS=$'|'; echo "${FILTER_WORDS[*]}")
|
|
FILTER="s/($FILTER_WORDS_STR)(\s*[:=]\s*)\S+/\1\2\*\*\*\*\*/g"
|
|
|
|
error() {
|
|
echo $* >&2
|
|
}
|
|
|
|
qprintf() {
|
|
[ $QUIET -ne 1 ] && printf "$@"
|
|
}
|
|
|
|
printv() {
|
|
[ $QUIET -ne 1 ] && [ $VERBOSE -eq 1 ] && echo $*
|
|
}
|
|
|
|
clean_stdin() {
|
|
while read -e -t 0.1; do : ; done
|
|
}
|
|
|
|
# add outout of the command and redirect possible errors there
|
|
add_cmd() {
|
|
CMD=$1
|
|
OUT=$2
|
|
printv " - $OUT"
|
|
echo -e "COMMAND> $CMD\n" > "$DIR/$OUT"
|
|
eval $CMD >> "$DIR/$OUT" 2>&1
|
|
}
|
|
|
|
# add and filter if it is a non zero, readable, regular file or symlink (skip otherwise)
|
|
add_files() {
|
|
for FILE in $*; do
|
|
if [ \( -f "$FILE" -o -h "$FILE" \) -a \( -r "$FILE" -a -s "$FILE" \) ]; then
|
|
printv " - $FILE"
|
|
SUBDIR=$(dirname $FILE)
|
|
[ ! -d "$DIR$SUBDIR" ] && mkdir -p "$DIR$SUBDIR"
|
|
tail -n "$MAXLINES" "$FILE" | sed -r "$FILTER" > "$DIR$FILE"
|
|
[ $PRINTPASS -eq 1 ] && grep -E "($FILTER_WORDS_STR)" "$DIR$FILE"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# default values
|
|
DIR=""
|
|
NOGENERIC=0
|
|
NOTAR=0
|
|
MAXLINES=5000
|
|
COMPRESS=""
|
|
PRINTPASS=0
|
|
QUIET=0
|
|
VERBOSE=0
|
|
DEBUG=0
|
|
UPLOAD=0
|
|
UPLOAD_DISABLED=0
|
|
|
|
if type -p xz >/dev/null; then
|
|
COMPRESS="xz -9"
|
|
EXTENSION=".xz"
|
|
elif type -p bzip2 >/dev/null; then
|
|
COMPRESS="bzip2 -9"
|
|
EXTENSION=".bz2"
|
|
elif type -p gzip >/dev/null; then
|
|
COMPRESS="gzip -9"
|
|
EXTENSION=".gz"
|
|
else
|
|
COMPRESS="cat"
|
|
EXTENSION=""
|
|
fi
|
|
|
|
# read optional configuration file with user-defined defaults
|
|
CONF_FILE=/usr/share/foreman/config/foreman-debug.conf
|
|
test -f $CONF_FILE && source $CONF_FILE
|
|
|
|
while getopts "d:gam:j:uqpvhx" opt; do
|
|
case $opt in
|
|
d)
|
|
DIR="$OPTARG"
|
|
;;
|
|
g)
|
|
NOGENERIC=1
|
|
;;
|
|
a)
|
|
NOTAR=1
|
|
;;
|
|
p)
|
|
PRINTPASS=1
|
|
;;
|
|
q)
|
|
QUIET=1
|
|
;;
|
|
v)
|
|
VERBOSE=1
|
|
;;
|
|
m)
|
|
MAXLINES="$OPTARG"
|
|
;;
|
|
j)
|
|
COMPRESS="$OPTARG"
|
|
EXTENSION=".$(echo "$OPTARG" | awk '{ print $1 }')"
|
|
;;
|
|
u)
|
|
UPLOAD=1
|
|
;;
|
|
x)
|
|
# this option is not docummented - use for extra output,
|
|
# skip slow items and to disable root check
|
|
DEBUG=1
|
|
;;
|
|
h)
|
|
usage
|
|
exit
|
|
;;
|
|
?)
|
|
error "Invalid option: $OPTARG"
|
|
usage
|
|
exit
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[ $DEBUG -eq 0 -a $EUID -ne 0 ] && error "This script must be run as root" && exit 1
|
|
|
|
[ $UPLOAD -eq 1 -a $NOTAR -eq 1 ] && error "Options -u and -a cannot be used together" && exit 2
|
|
|
|
# determine distribution family
|
|
if [ -f /etc/debian_version ]; then
|
|
OS=debian
|
|
OS_RELEASE=$(head -n1 /etc/debian_version)
|
|
elif [ -f /etc/redhat-release ]; then
|
|
OS=redhat
|
|
OS_RELEASE=$(head -n1 /etc/redhat-release)
|
|
elif type -p lsb_release >/dev/null; then
|
|
OS=$(lsb_release -si 2>/dev/null)
|
|
OS_RELEASE=$(lsb_release -sr 2>/dev/null)
|
|
elif type -p rpm >/dev/null; then
|
|
OS=$(rpm -q --whatprovides redhat-release --queryformat '%{NAME}')
|
|
OS_RELEASE=$(rpm -q --whatprovides redhat-release --queryformat '%{VERSION}')
|
|
else
|
|
OS=$(uname -s)
|
|
OS_RELEASE="Unknown"
|
|
fi
|
|
printv "Determined $OS distribution"
|
|
|
|
if [ -z "$DIR" ]; then
|
|
DIR=$(mktemp -d foreman-debug-XXXXX -p /tmp)
|
|
[ "$NOTAR" -eq 0 ] && trap "rm -rf $DIR" EXIT
|
|
else
|
|
[ ! -d "$DIR" ] && mkdir -p "$DIR"
|
|
fi
|
|
printv "Directory $DIR created"
|
|
|
|
TARBALL="$DIR.tar$EXTENSION"
|
|
|
|
# GENERIC ARTIFACTS
|
|
|
|
if [ $NOGENERIC -eq 0 ]; then
|
|
printv "Collecting generic system information"
|
|
add_cmd "date" "date"
|
|
add_cmd "lsb_release -a" "lsb_release"
|
|
add_cmd "uname -a" "uname"
|
|
add_cmd "cat /proc/cpuinfo" "cpuinfo"
|
|
add_cmd "cat /proc/meminfo" "meminfo"
|
|
add_cmd "ulimit -a" "ulimit"
|
|
add_cmd "lsmod" "lsmod"
|
|
add_cmd "iptables -L -v -n" "iptables"
|
|
add_cmd "ifconfig -a" "ifconfig"
|
|
add_cmd "route -n" "route"
|
|
add_cmd "netstat -tulpn" "netstat"
|
|
add_cmd "ip a" "ip_a"
|
|
add_cmd "ip r" "ip_r"
|
|
add_cmd "ss -tulpn" "ss"
|
|
add_cmd "cat /etc/hosts" "hosts"
|
|
add_cmd "ping -c1 -W1 localhost" "ping_localhost"
|
|
add_cmd "ping -c1 -W1 $(hostname)" "ping_hostname"
|
|
add_cmd "ping -c1 -W1 $(hostname -f)" "ping_hostname_full"
|
|
type scl &>/dev/null && \
|
|
add_cmd "scl -l" "software_collections"
|
|
|
|
add_cmd "ps auxwwwZ" "process_list"
|
|
add_files /var/log/messages /var/log/audit/audit.log /var/log/syslog
|
|
add_cmd "ausearch -m AVC -m USER_AVC -m SELINUX_ERR | head -n 100" "selinux_first_denials.log"
|
|
add_cmd "ausearch -m AVC -m USER_AVC -m SELINUX_ERR || grep AVC /var/log/audit/audit.log" "selinux_denials.log"
|
|
if [ -f /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
|
|
add_cmd "sepolgen-ifgen &>/dev/null && audit2allow -Ra || audit2allow -a" "selinux_audit2allow"
|
|
add_cmd "semodule -l" "selinux_modules"
|
|
add_cmd "semanage boolean -l" "selinux_booleans"
|
|
add_cmd "semanage fcontext -l" "selinux_fcontext"
|
|
fi
|
|
|
|
if [ "$OS" = "redhat" ]; then
|
|
[ $DEBUG -eq 0 ] && add_cmd "rpm -qa" "installed_packages"
|
|
elif [ "$OS" = "debian" ]; then
|
|
[ $DEBUG -eq 0 ] && add_cmd "dpkg --list" "installed_packages"
|
|
fi
|
|
|
|
fi
|
|
|
|
# FOREMAN RELATED ARTIFACTS
|
|
|
|
printv "Collecting Foreman-related information"
|
|
add_cmd "rpm -qa '*foreman*' || dpkg -l '*foreman*' | sort" "foreman_packages"
|
|
add_cmd "ruby --version" "version_ruby"
|
|
add_cmd "puppet --version" "version_puppet"
|
|
add_cmd "gem list" "gem_list"
|
|
add_cmd "scl enable $SCLNAME 'gem list'" "gem_list_scl"
|
|
add_cmd "bundle --local --gemfile=/usr/share/foreman/Gemfile" "bundle_list"
|
|
add_cmd "facter" "facts"
|
|
add_files /etc/foreman/* /var/log/foreman/*.log*
|
|
add_files /usr/share/foreman/Gemfile*
|
|
add_cmd "virsh list" "virsh_list"
|
|
add_files /etc/libvirt/* /etc/libvirt/storage/* /etc/libvirt/qemu/* /etc/libvirt/qemu/networks
|
|
add_files /var/lib/pgsql/data/*.conf
|
|
add_files /var/lib/puppet/ssl/certs/$(hostname -f).pem /var/lib/puppet/ssl/certs/ca.pem
|
|
add_files /etc/{httpd,apache2}/conf/*
|
|
add_files /etc/{httpd,apache2}/conf.d/*
|
|
add_files /etc/{httpd,apache2}/conf.d/*/*
|
|
add_files /var/log/{httpd,apache2}/*error_log*
|
|
add_files /var/log/{httpd,apache2}/foreman-ssl_access_ssl.log*
|
|
add_cmd "echo \"select id,name,value from settings where name not similar to '%(pass|key|secret)'\" | su postgres -c 'psql foreman'" "foreman_settings_table"
|
|
add_cmd "echo 'select type,name,host,port,account,base_dn,attr_login,onthefly_register,tls from auth_sources' | su postgres -c 'psql foreman'" "foreman_auth_table"
|
|
add_cmd "foreman-selinux-relabel -nv" "foreman_filecontexts"
|
|
|
|
add_files /etc/{sysconfig,default}/foreman
|
|
add_files /etc/{sysconfig,default}/libvirt*
|
|
add_files /etc/sysconfig/pgsql
|
|
add_files "/var/lib/pgsql/data/pg_log/*"
|
|
add_cmd "foreman-rake plugin:list" "plugin_list"
|
|
|
|
# Look for any debug extensions provided by plugins
|
|
if [ -d "/usr/share/foreman/script/foreman-debug.d" ]; then
|
|
for extension in /usr/share/foreman/script/foreman-debug.d/* ; do
|
|
if [ -x "$extension" ]; then
|
|
printv "Processing extension $extension"
|
|
source "$extension" 2>/dev/null
|
|
fi
|
|
done
|
|
fi
|
|
|
|
qprintf "\n\n"
|
|
qprintf "%10s %s\n" "HOSTNAME:" "$(hostname -f 2>/dev/null)"
|
|
qprintf "%10s %s\n" "OS:" "$OS"
|
|
qprintf "%10s %s\n" "RELEASE:" "$OS_RELEASE"
|
|
qprintf "%10s %s\n" "FOREMAN:" "$(cat /usr/share/foreman/VERSION 2>/dev/null)"
|
|
qprintf "%10s %s\n" "RUBY:" "$(ruby --version 2>/dev/null)"
|
|
qprintf "%10s %s\n" "PUPPET:" "$(puppet --version 2>/dev/null)"
|
|
test -f /var/log/audit/audit.log && \
|
|
qprintf "%10s %s\n" "DENIALS:" "$(grep AVC /var/log/audit/audit.log | wc -l)"
|
|
qprintf "\n\n"
|
|
|
|
if [ "$NOTAR" -eq 0 ]; then
|
|
pushd "$DIR" >/dev/null
|
|
tar -c ../$(basename $DIR) 2>/dev/null | $COMPRESS > "$TARBALL"
|
|
popd >/dev/null
|
|
qprintf "%s: %s\n\n" "A debug file has been created" "$TARBALL ($(stat -c %s "$TARBALL") bytes)"
|
|
else
|
|
qprintf "%s: %s\n\n" "A debug directory has been created" "$DIR"
|
|
fi
|
|
|
|
# upload if -u was passed in
|
|
if [ $UPLOAD_DISABLED -eq 0 -a $UPLOAD -eq 1 ]; then
|
|
qprintf "Uploading...\n"
|
|
rsync $TARBALL rsync://theforeman.org/debug-incoming
|
|
qprintf "The tarball has been uploaded, please contact us on our mailing list or IRC\n"
|
|
qprintf "referencing the following URL:\n\n"
|
|
qprintf " http://debugs.theforeman.org/$(basename $TARBALL)\n\n"
|
|
else
|
|
[[ $UPLOAD_DISABLED -eq 0 ]] && qprintf "To upload a tarball to our secure site, please use the -u option.\n"
|
|
fi
|