From 9b36f6b40bb21c942f50a0adeea485f630602b41 Mon Sep 17 00:00:00 2001 From: Alexandre <44178713+alexbelgium@users.noreply.github.com> Date: Mon, 2 Oct 2023 21:33:02 +0200 Subject: [PATCH] Improved smb code --- .templates/00-smb_mounts.sh | 159 ++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 78 deletions(-) diff --git a/.templates/00-smb_mounts.sh b/.templates/00-smb_mounts.sh index 138a697c6..86db5c7b1 100755 --- a/.templates/00-smb_mounts.sh +++ b/.templates/00-smb_mounts.sh @@ -5,19 +5,23 @@ #################### # MOUNT SMB SHARES # #################### + if bashio::config.has_value 'networkdisks'; then echo 'Mounting smb share(s)...' - # Define variables + #################### + # Define variables # + #################### + + # Set variables MOREDISKS=$(bashio::config 'networkdisks') - CIFS_USERNAME=$(bashio::config 'cifsusername') - CIFS_PASSWORD=$(bashio::config 'cifspassword') + USERNAME=$(bashio::config 'cifsusername') + PASSWORD=$(bashio::config 'cifspassword') SMBVERS="" SMBDEFAULT="" SECVERS="" - CHARSET="" - DOMAINVAR="" + CHARSET=",iocharset=utf8" # Clean data MOREDISKS=${MOREDISKS// \/\//,\/\/} @@ -28,8 +32,10 @@ if bashio::config.has_value 'networkdisks'; then if bashio::config.has_value 'cifsdomain'; then echo "... using domain $(bashio::config 'cifsdomain')" DOMAIN=",domain=$(bashio::config 'cifsdomain')" + DOMAINCLIENT=",--workgroup=$(bashio::config 'cifsdomain')" else DOMAIN="" + DOMAINCLIENT="" fi # Is UID/GID set @@ -42,7 +48,10 @@ if bashio::config.has_value 'networkdisks'; then PGID=",gid=$(id -g)" fi - # Mounting disks + ################## + # Mounting disks # + ################## + # shellcheck disable=SC2086 for disk in ${MOREDISKS//,/ }; do # Separate comma separated values @@ -54,93 +63,87 @@ if bashio::config.has_value 'networkdisks'; then diskname="${diskname##*/}" # Get only last part of the name MOUNTED=false + # Start echo "... mounting $disk" # Data validation if [[ ! "$disk" =~ ^.*+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[/]+.*+$ ]]; then - bashio::log.fatal "The structure of your \"networkdisks\" option : \"$disk\" doesn't seem correct, please use a structure like //123.12.12.12/sharedfolder,//123.12.12.12/sharedfolder2. If you don't use it, you can simply remove the text, this will avoid this error message in the future." - break 2 + bashio::log.fatal "... the structure of your \"networkdisks\" option : \"$disk\" doesn't seem correct, please use a structure like //123.12.12.12/sharedfolder,//123.12.12.12/sharedfolder2. If you don't use it, you can simply remove the text, this will avoid this error message in the future." + continue fi # Prepare mount point mkdir -p /mnt/"$diskname" chown root:root /mnt/"$diskname" - - # Extract ip part of server for further manipulation - server="$(echo "$disk" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")" - - # Does server exists - if command -v "nc" &>/dev/null; then - # test if smb port is open - if ! nc -w 1 -z "$server" 445 2>/dev/null; then - # test with ping also if different port is used - echo "... warning : SMB port not opened, trying ping" - if ! ping -w 1 -c 1 "$server" >/dev/null; then - # Try smbclient (last as slowest) - echo "... warning : ping not successful, trying smbclient" - if ! smbclient -t 1 -L "$server" -N &>/dev/null; then - bashio::log.fatal "... your server $server from $disk doesn't seem reachable, script will stop" - break - fi - fi - fi - fi - + # Quickly try to mount with defaults - mount -t cifs -o "rw,file_mode=0775,dir_mode=0775,username=$CIFS_USERNAME,password=${CIFS_PASSWORD},nobrl$SMBVERS$SECVERS$PUID$PGID$CHARSET$DOMAINVAR" "$disk" /mnt/"$diskname" 2>ERRORCODE \ - && MOUNTED=true && MOUNTOPTIONS="$SMBVERS$SECVERS$PUID$PGID$CHARSET$DOMAINVAR" || MOUNTED=false + mount -t cifs -o "rw,file_mode=0775,dir_mode=0775,username=$USERNAME,password=${PASSWORD},nobrl$SMBVERS$SECVERS$PUID$PGID$CHARSET$DOMAIN" "$disk" /mnt/"$diskname" 2>ERRORCODE \ + && MOUNTED=true && MOUNTOPTIONS="$SMBVERS$SECVERS$PUID$PGID$CHARSET$DOMAIN" || MOUNTED=false # Deeper analysis if failed if [ "$MOUNTED" = false ]; then - # Detect smb version - # Try smbv1 - if smbclient -t 2 -L "$server" -m NT1 -N &>/dev/null; then - echo "... only SMBv1 is supported, trying it" - SMBDEFAULT=",vers=1.0" - fi + # Extract ip part of server for further manipulation + server="$(echo "$disk" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")" - # Detect sec vers + # Does server exists + echo "... testing that $server is reachable" + output="$(nmap -F $server -T5 -oG -)" + if ! echo "$output" | grep 445/open &>/dev/null; then + if echo "$output" | grep /open &>/dev/null; then + if ! smbclient -t 1 -L "$server" -N "$DOMAINCLIENT" &>/dev/null; then + bashio::log.fatal "... fatal : $server is reachable but SMB port not opened, stopping script" + continue + else + bashio::warning "... fatal : $server not reachable but SMB connects, you have strange security in place" + fi + else + bashio::log.fatal "... fatal : $server not reachable, is it correct" + continue + fi + fi - # if Fail test different smb and sec versions - echo "... looking for the optimal parameters for mounting" - if [ "$MOUNTED" = false ]; then + # Are credentials correct + echo "... testing credentials" + if ! smbclient -t 2 -L $disk -U $USERNAME%$PASSWORD "$DOMAINCLIENT" &>/dev/null; then + bashio::log.fatal "Incorrect Username or Password! Script will stop." + continue + fi - # Test with domain, remove otherwise - #################################### - for DOMAINVAR in "$DOMAIN" ",domain=WORKGROUP" ""; do + # Should there be a workgroup + echo "... testing credentials" + if ! smbclient -t 2 -L $disk -N "$DOMAINCLIENT" &>/dev/null; then + bashio::log.fatal "A workgroup must perhaps be specified" + continue + fi - # Test with PUIDPGID, remove otherwise - ###################################### - for PUIDPGID in "$PUID$PGID" "$PUID$PGID,forceuid,forcegid" ""; do + # What is the SMB version + echo "... detecting SMB version" + # Extracting SMB versions and normalize output + SMBVERS="$(nmap --script smb-protocols "$server" -p 445 2>1 | awk '/ [0-9]/' | awk '{print $NF}' | cut -c -3 | sort -V | tail -n 1 || true)" + # Manage output + if [ -n "$SMBVERS" ]; then + echo "... SMB version $SMBVERS detected" + SMBVERS=",vers=$SMBVERS" + elif smbclient -t 2 -L "$server" -m NT1 -N "$DOMAINCLIENT" &>/dev/null; then + echo "... only SMBv1 is supported, this can lead to issues" + SECVERS=",sec=ntlm" + SMBVERS=",vers=1.0" + else + echo "... couldn't detect, default used" + SMBVERS="" + fi - # Test with iocharset utf8, remove otherwise - ############################################ - for CHARSET in ",iocharset=utf8" ""; do - - # Test with different SMB versions - ################################## - for SMBVERS in "$SMBDEFAULT" ",vers=3" ",vers=3.2" ",vers=3.0" ",vers=2.1" ",nodfs"; do - - # Test with different security versions - ####################################### - for SECVERS in "" ",sec=ntlmv2" ",sec=ntlm" ",sec=ntlmv2i" ",sec=ntlmssp" ",sec=ntlmsspi" ",sec=krb5i" ",sec=krb5"; do - if [ "$MOUNTED" = false ]; then - mount -t cifs -o "rw,file_mode=0775,dir_mode=0775,username=$CIFS_USERNAME,password=${CIFS_PASSWORD},nobrl$SMBVERS$SECVERS$PUIDPGID$CHARSET$DOMAINVAR" "$disk" /mnt/"$diskname" 2>ERRORCODE \ - && MOUNTED=true && MOUNTOPTIONS="$SMBVERS$SECVERS$PUIDPGID$CHARSET$DOMAINVAR" || MOUNTED=false - fi - done - - done - - done - - done - - done - fi - - fi + # Test with different security versions + ####################################### + for SECVERS in "" ",sec=ntlmv2" ",sec=ntlm" ",sec=ntlmv2i" ",sec=ntlmssp" ",sec=ntlmsspi" ",sec=krb5i" ",sec=krb5"; do + if [ "$MOUNTED" = false ]; then + mount -t cifs -o "rw,file_mode=0775,dir_mode=0775,username=$USERNAME,password=${PASSWORD},nobrl$SMBVERS$SECVERS$PUIDPGID$CHARSET$DOMAIN" "$disk" /mnt/"$diskname" 2>ERRORCODE \ + && MOUNTED=true && MOUNTOPTIONS="$SMBVERS$SECVERS$PUIDPGID$CHARSET$DOMAIN" || MOUNTED=false + fi + done + + fi # Messages if [ "$MOUNTED" = true ] && mountpoint -q /mnt/"$diskname"; then @@ -153,7 +156,7 @@ if bashio::config.has_value 'networkdisks'; then # Test for serverino # shellcheck disable=SC2015 touch "/mnt/$diskname/testaze" && mv "/mnt/$diskname/testaze" "/mnt/$diskname/testaze2" && rm "/mnt/$diskname/testaze2" || - (umount "/mnt/$diskname" && mount -t cifs -o "iocharset=utf8,rw,file_mode=0775,dir_mode=0775,username=$CIFS_USERNAME,password=${CIFS_PASSWORD}$MOUNTOPTIONS,noserverino" "$disk" /mnt/"$diskname" && bashio::log.warning "noserverino option used") + (umount "/mnt/$diskname" && mount -t cifs -o "iocharset=utf8,rw,file_mode=0775,dir_mode=0775,username=$USERNAME,password=${PASSWORD}$MOUNTOPTIONS,noserverino" "$disk" /mnt/"$diskname" && bashio::log.warning "noserverino option used") # Alert if smbv1 if [[ "$MOUNTOPTIONS" == *"1.0"* ]]; then @@ -164,14 +167,14 @@ if bashio::config.has_value 'networkdisks'; then else # Mounting failed messages - bashio::log.fatal "Error, unable to mount $disk to /mnt/$diskname with username $CIFS_USERNAME, $CIFS_PASSWORD. Please check your remote share path, username, password, domain, try putting 0 in UID and GID" + bashio::log.fatal "Error, unable to mount $disk to /mnt/$diskname with username $USERNAME, $PASSWORD. Please check your remote share path, username, password, domain, try putting 0 in UID and GID" bashio::log.fatal "Here is some debugging info :" # Provide debugging info - smbclient -t 5 -L $disk -U "$CIFS_USERNAME%$CIFS_PASSWORD" + smbclient -t 5 -L $disk -U "$USERNAME%$PASSWORD" # Error code - mount -t cifs -o "rw,file_mode=0775,dir_mode=0775,username=$CIFS_USERNAME,password=${CIFS_PASSWORD},nobrl$DOMAINVAR" "$disk" /mnt/"$diskname" 2>ERRORCODE || MOUNTED=false + mount -t cifs -o "rw,file_mode=0775,dir_mode=0775,username=$USERNAME,password=${PASSWORD},nobrl$DOMAIN" "$disk" /mnt/"$diskname" 2>ERRORCODE || MOUNTED=false bashio::log.fatal "Error read : $(