Участник:Petr-akhlamov/Test
Тестирование и диагностика Samba и ActiveDirectory
Проверка постоянства имени хоста (Check hostname persistance)
Постоянство имени хоста - это сохранение имени компьютера после перезагрузки.
check_hostnamectl() { local retval=0 local static_host= local transient_host= transient_host="$(hostname)" || retval=1 static_host="$(hostnamectl --static)" || retval=1 _command hostnamectl || retval=1 test "$static_host" = "$transient_host" || retval=1 return $retval }
Если значение:
- 0, то постоянство не настроено
- 1, то постоянство работает корректно
Проверка имени хоста в FQDN [не короткое] (Test hostname is FQDN [not short])
FQDN (от англ. Fully Qualified Domain Name — «полностью определённое имя домена», иногда сокращается до «полное имя домена») — имя домена, не имеющее неоднозначностей в определении.
test_hostname() { local host="$HOSTNAME_COMMON" echo $host echo test "$host" != "${host/.}" || return 2 }
Если значение:
- 0, то ...
- 2, то ...
Метод аутентификации системы (System authentication method)
Включение аутентификации доменной системы (Domain system authentication enabled)
Метод системной политики (System policy method)
Включение системных групповых политик (System group policy enabled)
Проверка существующих настроек Kerberos (Check Kerberos configuration exists)
Статус кеша учетных данных Kerberos (Kerberos credential cache status)
Использование связки ключей в качестве кеша учетных данных Kerberos (Using keyring as kerberos credential cache)
Проверка состояния поиска DNS kerberos KDC (Check DNS lookup kerberos KDC status)
Проверка существования кэша учетных данных компьютера (Check machine crendetial cache is exists)
Проверка списка учетных данных компьютера в keytab-файле (Check machine credentials list in keytab)
Проверка конфигурации преобразователя имен (Check nameserver resolver configuration)
Сравнение мира[i] krb5 и первого поискового домена (Compare krb5 realm and first search domain)
Проверка конфигурации Samba (Check Samba configuration)
Сравнение мировмира[i] Samba и krb5 (Compare Samba and krb5 realms)
Проверка мира[i] домена Samba (Check Samba domain realm)
Проверка хост-имени доменного имени FQDN (Check hostname FQDN domainname)
Проверка синхронизации времени (Check time synchronization)
Включение синхронизации времени (Time synchronization enabled)
Проверка доступности серверов имен (Check nameservers availability)
Проверка списка контроллеров домена (Check domain controllers list)
Проверка Kerberos и записей LDAP SRV (Check Kerberos and LDAP SRV-records)
Сравнение имени NetBIOS и имени хоста (Compare NetBIOS name and hostname)
Проверка общих пакетов (Check common packages)
()
Проверка пакетов групповых политик (Check group policy packages)
Проверка пакетов SSSD AD (Check SSSD AD packages)
Проверка пакетов SSD Winbind (Check SSSD Winbind packages)
- !/bin/bash
set -euo pipefail
. shell-terminfo
. shell-getopt
terminfo_init
PROG="domain-diag"
VERSION=0.2.2
verbose=
listcmd=
runcmd=run
logfile=/dev/null
force=
show_usage()
{
echo "Active Directory domain environment diagnostic tool"
echo ""
echo "Usage: $PROG [options] [<check/test-function-name>]"
echo ""
echo "<check/test-function-name> must be a function name from the list of tests"
echo ""
echo "Options:"
echo " -h, --help This message"
echo " -V, --version Display version number"
echo " -v, --verbose Verbose output"
echo " -w, --logfile[=FILE] Write verbose output to file"
echo " -f, --force Force logging to existing file"
echo " -l, --list List of tests"
echo ""
exit 0;
}
print_version()
{
echo "$VERSION"
exit 0;
}
TEMP=$(getopt -n "$PROG" -o "v,V,w::,f,l,h" -l "verbose,version,logfile::,force,list,help" -- "$@") || show_usage
eval set -- "$TEMP"
while :; do
case "$1" in
-h|--help) show_usage
;;
-v|--verbose) verbose=1
;;
-w|--logfile) shift
test -n "$1" && logfile="$1" || logfile="domain-diag.log"
;;
-f|--force) force=1
;;
-l|--list) listcmd=1
;;
-V|--version) print_version "$PROG"
;;
--) shift; break
;;
*) fatal "Unrecognized option: $1"
;;
esac
shift
done
customcmd="$*"
msg_non_root()
{
echo -n "$*: ["
color_text "SKIP" blue
echo "]"
}
msg_fail()
{
echo -n "$*: ["
color_text "FAIL" red
echo "]"
}
msg_warn()
{
echo -n "$*: ["
color_text "WARN" yellow
echo "]"
}
msg_done()
{
echo -n "$*: ["
color_text "DONE" green
echo "]"
}
__command_msg()
{
local p='$'
if test "$1" = '-r'; then
shift
p='#'
fi
color_message "$p $*" bold
}
_command()
{
local retval=0
local x=
local q=
local r=
if test "$1" = '-q'; then
shift
q=1
fi
if test "$1" = '-r'; then
shift
r=1
fi
if test "$1" = '-x'; then
shift
x=1
fi
test -z "$q" && test -z "$r" && __command_msg "$*"
test -z "$q" && test -n "$r" && __command_msg -r "$*"
test -z "$x" || echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eval "$*" || retval=$?
test -z "$x" || echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo
return $retval
}
__header()
{
color_message "===============================================================================" bold white
}
__footer()
{
color_message "===============================================================================" bold white
}
__short_msg()
{
case "$1" in
0) msg_done "$2" ;;
2) msg_warn "$2" ;;
102) msg_non_root "$2" ;;
*) msg_fail "$2" ;;
esac
}
__delimiter()
{
echo "-------------------------------------------------------------------------------"
}
__check_title()
{
color_message "$1" bold white
}
__newline()
{
echo
}
__log()
{
test -z $verbose && tee -a "$logfile" 1>/dev/null 2>&1 ||
tee -a "$logfile"
}
__log_force_print()
{
tee -a "$logfile"
}
print_head()
{
__header | __log
__check_title "| Samba environment diagnostic tool |" | __log
__delimiter | __log
echo "Version: $VERSION" | __log
echo "Date: $(date)" | __log
__delimiter | __log
echo "System information" | __log
echo "Kernel: $(uname -r)" | __log
echo "Branch: $(apt-repo list | cut -d ' ' -f 2 | grep -e '^\[.*\]$' | tail -1 | sed -E 's/\[(.*)\]/\1/')" | __log
__footer | __log
__newline | __log
}
is_root()
{
if test "$(id -u)" != 0; then
return 1
fi
return 0
}
__not_root_skip()
{
local msg=
if test -n "${1+x}" && test "$1" = "-m"; then
shift
msg="$1"
fi
echo -n "Running not by root, SKIP: $msg"
echo
echo
}
run()
{
local retval=126
local func="$1"
local msg
msg=$(printf "| %s |" "$func")
__header | __log
__check_title "$msg" | __log
__delimiter | __log
__newline | __log
$func 2>&1 | __log && retval=0 || retval=$?
__delimiter | __log
__short_msg $retval "$2" | __log_force_print
__footer | __log
__newline | __log
}
check_hostnamectl()
{
local retval=0
local static_host=
local transient_host=
transient_host="$(hostname)" || retval=1
static_host="$(hostnamectl --static)" || retval=1
_command hostnamectl || retval=1
test "$static_host" = "$transient_host" || retval=1
return $retval
}
test_hostname()
{
local host="$HOSTNAME_COMMON"
echo $host
echo
test "$host" != "${host/.}" || return 2
}
check_system_auth()
{
local auth=
auth=$(/usr/sbin/control system-auth)
_command /usr/sbin/control system-auth
_command readlink -f /etc/pam.d/system-auth
_command -x cat /etc/pam.d/system-auth
test -n "$auth" -a "$auth" != "unknown"
}
test_domain_system_auth()
{
test -n "$SYSTEM_AUTH" ||
SYSTEM_AUTH=local
_command /usr/sbin/control system-auth
_command test "$SYSTEM_AUTH" != "local" || return 2
}
is_system_auth_local()
{
test "$SYSTEM_AUTH" = "local"
}
check_system_policy()
{
local policy=
policy=$(/usr/sbin/control system-policy)
_command /usr/sbin/control system-policy
_command readlink -f /etc/pam.d/system-policy
_command -x cat /etc/pam.d/system-policy
test -n "$policy" -a "$policy" != "unknown"
}
test_gpupdate_system_policy()
{
test -n "$SYSTEM_POLICY" ||
SYSTEM_POLICY=local
_command /usr/sbin/control system-policy
_command test "$SYSTEM_POLICY" == "gpupdate" || return 2
}
check_krb5_conf_exists()
{
local retval=0
_command ls -l /etc/krb5.conf
if ! test -e /etc/krb5.conf; then
is_system_auth_local && retval=2 || retval=1
else
_command -x cat /etc/krb5.conf
fi
return $retval
}
check_krb5_conf_ccache()
{
local ccache=
ccache=$(/usr/sbin/control krb5-conf-ccache)
_command /usr/sbin/control krb5-conf-ccache
test -n "$ccache" -a "$ccache" != "unknown"
}
test_keyring_krb5_conf_ccache()
{
local ccache=
ccache=$(/usr/sbin/control krb5-conf-ccache)
_command /usr/sbin/control krb5-conf-ccache
_command test -n "$ccache" -a "$ccache" == "keyring" || return 2
}
check_krb5_conf_kdc_lookup()
{
local retval=0
echo -n "/etc/krb5.conf: dns_lookup_kdc "
if grep -q '^\s*dns_lookup_kdc\s*=\s*\([Tt][Rr][Uu][Ee]\|1\|[Yy][Ee][Ss]\)\s*$' /etc/krb5.conf; then
echo "is enabled"
else
if grep -q '^\s*dns_lookup_kdc\s*=' /etc/krb5.conf; then
echo "is disabled"
retval=1
else
echo "is enabled by default"
retval=2
fi
fi
echo
return $retval
}
check_krb5_keytab_exists()
{
local retval=0
_command ls -l /etc/krb5.keytab
if ! test -e /etc/krb5.keytab; then
is_system_auth_local && retval=2 || retval=1
fi
return $retval
}
check_keytab_credential_list()
{
local retval=0
if ! is_root; then
__not_root_skip && return 102
fi
if ! _command -r klist -ke; then
is_system_auth_local && retval=2 || retval=1
fi
return $retval
}
check_resolv_conf()
{
local retval=0
_command ls -l /etc/resolv.conf
_command -x cat /etc/resolv.conf
}
compare_resolv_conf_with_default_realm()
{
echo "SEARCH_DOMAIN = '$SEARCH_DOMAIN'"
echo "KRB5_DEFAULT_REALM = '$KRB5_DEFAULT_REALM'"
echo
local domain=
local realm=
domain=$(echo "$SEARCH_DOMAIN" | tr '[:upper:]' '[:lower:]')
realm=$(echo "$KRB5_DEFAULT_REALM" | tr '[:upper:]' '[:lower:]')
if test -z "$realm"; then
return 2
fi
test -n "$domain" || return 2
test "$domain" = "$realm" || return 2
}
check_smb_conf()
{
local retval=0
_command ls -l /etc/samba/smb.conf
_command -x grep -v -e "'^\s*[#;]'" -e "'^\s*$'" /etc/samba/smb.conf
_command -x testparm -l -s
}
compare_smb_realm_with_krb5_default_realm()
{
echo "SMB_REALM = '$SMB_REALM'"
echo "KRB5_DEFAULT_REALM = '$KRB5_DEFAULT_REALM'"
echo
test -n "$SMB_REALM" || return 2
test -n "$KRB5_DEFAULT_REALM" || return 2
test "$KRB5_DEFAULT_REALM" = "$SMB_REALM" || return 2
}
test_smb_realm()
{
local retval=0
DOMAIN_REALM="$KRB5_DEFAULT_REALM"
if test -n "$SMB_REALM"; then
DOMAIN_REALM="$SMB_REALM"
DOMAIN_DOMAIN="$(echo "$SMB_REALM" | tr '[:upper:]' '[:lower:]')"
else
test -z "$DOMAIN_REALM" ||
DOMAIN_DOMAIN="$(echo "$DOMAIN_REALM" | tr '[:upper:]' '[:lower:]')"
test -n "$DOMAIN_REALM" ||
DOMAIN_REALM="$(echo "$DOMAIN_DOMAIN" | tr '[:lower:]' '[:upper:]')"
is_system_auth_local && retval=2 || retval=1
fi
echo "DOMAIN_REALM = '$DOMAIN_REALM'"
echo "DOMAIN_DOMAIN = '$DOMAIN_DOMAIN'"
echo
return $retval
}
test_domainname()
{
HOSTNAME_DOMAIN=$(hostname -d)
if test "$HOSTNAME_DOMAIN" = "$HOSTNAME_SHORT" ||
test "$HOSTNAME_DOMAIN" = '(none)' ||
test -z "$HOSTNAME_DOMAIN"; then
HOSTNAME_DOMAIN=
echo "HOSTNAME_DOMAIN = '$HOSTNAME_DOMAIN'"
echo
return 2
fi
if test -z "$DOMAIN_DOMAIN"; then
DOMAIN_DOMAIN="$HOSTNAME_DOMAIN"
test -n "$DOMAIN_REALM" ||
DOMAIN_REALM="$(echo "$DOMAIN_DOMAIN" | tr '[:lower:]' '[:upper:]')"
echo "HOSTNAME_DOMAIN = '$HOSTNAME_DOMAIN'"
echo "Update realm and domain from HOSTNAME_DOMAIN:"
echo " DOMAIN_REALM = '$DOMAIN_REALM'"
echo " DOMAIN_DOMAIN = '$DOMAIN_DOMAIN'"
echo
return 2
fi
echo "HOSTNAME_DOMAIN = '$HOSTNAME_DOMAIN'"
echo
test "$HOSTNAME_DOMAIN" = "$DOMAIN_DOMAIN" || return 1
}
check_time_synchronization()
{
local retval=0
_command timedatectl || return 1
}
test_time_synchronization()
{
local retval=0
local func="test \$(timedatectl show -p NTPSynchronized --value) == \"yes\""
__command_msg "$func"
_command -q "$func" || retval=2
return $retval
}
_check_nameserver()
{
local ns="$1"
if _command ping -c 2 -i2 "$ns"; then
test -z "$DOMAIN_DOMAIN" || _command host "$DOMAIN_DOMAIN" "$ns"
else
return 1
fi
}
check_nameservers()
{
retval1=0
retval2=0
retval3=0
if [ -n "$NAMESERVER1" ]; then
_check_nameserver "$NAMESERVER1" || retval1=1
fi
if [ -n "$NAMESERVER2" ]; then
_check_nameserver "$NAMESERVER2" || retval2=1
fi
if [ -n "$NAMESERVER3" ]; then
_check_nameserver "$NAMESERVER3" || retval3=1
fi
if test "$retval1" = 0 -a "$retval2" = 0 -a "$retval3" = 0; then
return 0;
fi
if test "$retval1" = 1 -a "$retval2" = 1 -a "$retval3" = 1; then
return 1;
fi
return 2
}
_ldap_get_computer()
{
local retval=0
local dc="$1"
local computer="$2"
local filter=""
local domain_dn=
if test -n "${3+x}"; then
filter="$3"
fi
domain_dn=$(echo $DOMAIN_DOMAIN | sed 's/\./,dc=/g' | sed 's/^/dc=/')
local searchcmd="ldapsearch -o nettimeout=30 -Y GSSAPI -N -h $dc -b $domain_dn"
searchcmd="$searchcmd \"(&(ObjectClass=computer)(objectCategory=Computer)(name=$computer))\""
__command_msg "$searchcmd $filter"
_command -q "$searchcmd" "$filter" || retval=2
return $retval
}
_check_domain_controller()
{
local retval=0
local dc="$1"
local computer=
local ldap_computer=
local computer=
local hostname_upper=
hostname_upper=$(echo $HOSTNAME_SHORT | tr '[:lower:]' '[:upper:]')
local domain_upper=
domain_upper=$(echo $DOMAIN_DOMAIN | tr '[:lower:]' '[:upper:]')
local kinit_realm="$hostname_upper\$\@$domain_upper"
if is_root; then
KRB5CCNAME="FILE:/tmp/domain-diag_krb5cc_%{uid}"
_command kinit -k "$kinit_realm" || retval=2
if test "$retval" != "0"; then
is_system_auth_local && return 2 || return 1
fi
fi
computer="$(echo $1 | sed 's/\..*$//')"
_ldap_get_computer "$dc" "$computer" "| grep 'operating\|name:' | cut -d ' ' -f 2 | tr '\n' ' '" || retval=2
__newline
_command kdestroy -A
return $retval
}
check_domain_controllers()
{
local retval=2
local hostcmd="host -t srv _ldap._tcp.$DOMAIN_DOMAIN | cut -d ' ' -f 8"
local resolv_msg=
local controllers_names=
__command_msg "$hostcmd"
controllers_names=$(_command -q "$hostcmd" || retval=2)
echo $controllers_names | sed 's/ /\n/g'
echo
for controller_name in $controllers_names; do
resolv_msg="host $controller_name | sed 's/^.* //g'"
_command "$resolv_msg"
done
for controller_name in $controllers_names; do
# TODO: Add controller check by ip
_check_domain_controller $controller_name && retval=0
done
test -z "$controllers_names" && retval=2
! is_system_auth_local && test $retval != 0 && retval=1
return $retval
}
check_kerberos_and_ldap_srv_records()
{
test -n "$DOMAIN_DOMAIN" || return 1
_command host -t srv "_kerberos._udp.$DOMAIN_DOMAIN"
_command host -t srv "_ldap._tcp.$DOMAIN_DOMAIN"
}
compare_netbios_name()
{
local netbios=
local host=
netbios=$(echo "$SMB_NETBIOS_NAME" | tr '[:upper:]' '[:lower:]')
host=$(echo "$HOSTNAME_SHORT" | tr '[:upper:]' '[:lower:]')
echo "SMB_NETBIOS_NAME = '$SMB_NETBIOS_NAME'"
echo "HOSTNAME_SHORT = '$HOSTNAME_SHORT'"
echo
test "$netbios" = "$host" || return 1
}
check_common_packages()
{
local retval=0
_command rpm -q alterator-auth || retval=1
_command rpm -q libnss-role || retval=1
_command rpm -q libkrb5 || retval=1
_command rpm -q libsmbclient || retval=1
return $retval
}
check_group_policy_packages()
{
local retval=0
_command rpm -q local-policy || retval=1
_command rpm -q gpupdate || retval=1
return $retval
}
check_sssd_ad_packages()
{
local retval=0
_command rpm -q task-auth-ad-sssd || retval=1
return $retval
}
check_sssd_winbind_packages()
{
local retval=0
_command rpm -q task-auth-ad-winbind || retval=2
return $retval
}
list_run()
{
test -z $verbose &&
echo "$1" ||
echo "$1: $2"
}
custom_run()
{
if echo "$customcmd" | tr ' ' '\n' | grep -q "^$1\$"; then
run "$1" "$2"
fi
}
init_log()
{
local log_index
if test -e "$logfile" && test "$logfile" != "/dev/null" && test -z "$force"; then
log_index=$(find . -maxdepth 1 -name "$logfile.*" 2>/dev/null | sort -V | tail -1 | sed -E 's/^.*\.([^.]*)$/\1/' || true)
logfile="$logfile".$(($log_index + 1))
fi
if test "$logfile" != "/dev/null"; then
echo -n > "$logfile"
fi
}
init_vars()
{
local host=
host=$(hostname)
local domain realm
HOSTNAME_COMMON="$host"
HOSTNAME_SHORT=$(hostname -s)
HOSTNAME_FQDN=$(hostname -f)
NAMESERVER1=$(grep "^nameserver\s\+" /etc/resolv.conf | sed -e 's/^nameserver\s\+//' -e 's/\s/\n/' | head -1)
NAMESERVER2=$(grep "^nameserver\s\+" /etc/resolv.conf | sed -e 's/^nameserver\s\+//' -e 's/\s/\n/' | head -2 | tail -1)
NAMESERVER3=$(grep "^nameserver\s\+" /etc/resolv.conf | sed -e 's/^nameserver\s\+//' -e 's/\s/\n/' | head -3 | tail -1)
SMB_REALM=
SMB_NETBIOS_NAME=
if which testparm >/dev/null 2>&1; then
SMB_REALM=$(testparm -l -v -s 2>/dev/null | grep "^\s*realm\s*=" | sed -e 's/^\s*realm\s*=\s*//' -e 's/\s*$//')
SMB_NETBIOS_NAME=$(testparm -l -v -s 2>/dev/null | grep "^\s*netbios name\s*=" | sed -e 's/^\s*netbios name\s*=\s*//' -e 's/\s*$//')
fi
SEARCH_DOMAIN=
if test -f /etc/resolv.conf; then
SEARCH_DOMAIN=$(grep "^search\s\+" /etc/resolv.conf || true | sed -e 's/^search\s\+//' -e 's/\s/\n/' | head -1 )
fi
KRB5_DEFAULT_REALM=
if test -e /etc/krb5.conf; then
KRB5_DEFAULT_REALM=$(grep "^\s*default_realm\s\+" /etc/krb5.conf | sed -e 's/^\s*default_realm\s*=\s*//' -e 's/\s*$//')
fi
domain=$(echo "$SEARCH_DOMAIN" | tr '[:upper:]' '[:lower:]')
realm=$(echo "$KRB5_DEFAULT_REALM" | tr '[:upper:]' '[:lower:]')
DOMAIN_DOMAIN="$domain"
if test -n "$realm"; then
DOMAIN_DOMAIN="$realm"
fi
SYSTEM_AUTH="$(/usr/sbin/control system-auth)"
SYSTEM_POLICY="$(/usr/sbin/control system-policy)"
}
test -z $listcmd || runcmd=list_run
init_log
print_head
init_vars
test -z "$customcmd" || runcmd=custom_run
$runcmd check_hostnamectl "Check hostname persistance"
$runcmd test_hostname "Test hostname is FQDN (not short)"
$runcmd check_system_auth "System authentication method"
$runcmd test_domain_system_auth "Domain system authentication enabled"
$runcmd check_system_policy "System policy method"
$runcmd test_gpupdate_system_policy "System group policy enabled"
$runcmd check_krb5_conf_exists "Check Kerberos configuration exists"
$runcmd check_krb5_conf_ccache "Kerberos credential cache status"
$runcmd test_keyring_krb5_conf_ccache "Using keyring as kerberos credential cache"
$runcmd check_krb5_conf_kdc_lookup "Check DNS lookup kerberos KDC status"
$runcmd check_krb5_keytab_exists "Check machine crendetial cache is exists"
$runcmd check_keytab_credential_list "Check machine credentials list in keytab"
$runcmd check_resolv_conf "Check nameserver resolver configuration"
$runcmd compare_resolv_conf_with_default_realm "Compare krb5 realm and first search domain"
$runcmd check_smb_conf "Check Samba configuration"
$runcmd compare_smb_realm_with_krb5_default_realm "Compare samba and krb5 realms"
$runcmd test_smb_realm "Check Samba domain realm"
$runcmd test_domainname "Check hostname FQDN domainname"
$runcmd check_time_synchronization "Check time synchronization"
$runcmd test_time_synchronization "Time synchronization enabled"
$runcmd check_nameservers "Check nameservers availability"
$runcmd check_domain_controllers "Check domain controllers list"
$runcmd check_kerberos_and_ldap_srv_records "Check Kerberos and LDAP SRV-records"
$runcmd compare_netbios_name "Compare NetBIOS name and hostname"
$runcmd check_common_packages "Check common packages"
$runcmd check_group_policy_packages "Check group policy packages"
$runcmd check_sssd_ad_packages "Check SSSD AD packages"
$runcmd check_sssd_winbind_packages "Check SSSD Winbind packages"
test -f "$logfile" && test -w "$logfile" &&
sed -i 's/\x1b\[[0-9;]*[mGKH]//g' $logfile