mirror of
https://github.com/unraid/webgui.git
synced 2026-01-03 16:14:54 -06:00
186 lines
4.7 KiB
Bash
186 lines
4.7 KiB
Bash
#!/bin/bash
|
|
#
|
|
# script: rc.library.source
|
|
#
|
|
# Library used by nfsd, ntpd, rpc, samba, nginx, sshd, avahidaemon, show_interfaces
|
|
#
|
|
# Bergware - created for Unraid OS, December 2023
|
|
# Bergware - updated May 2025
|
|
|
|
WIREGUARD="/etc/wireguard"
|
|
NETWORK_INI="/var/local/emhttp/network.ini"
|
|
NETWORK_EXTRA="/boot/config/network-extra.cfg"
|
|
|
|
var(){
|
|
if [[ $# -eq 3 ]]; then
|
|
[[ -r "$3" ]] && sed -n "/^\[$1\]\$/,/^\[/p" "$3" | grep -Pom1 "^$2=\"\K[^\"]+"
|
|
elif [[ $# -eq 2 ]]; then
|
|
[[ -r "$2" ]] && grep -Pom1 "^$1=\"\K[^\"]+" "$2"
|
|
fi
|
|
}
|
|
|
|
ipv(){
|
|
local t=${1//[^:]}
|
|
[[ ${#t} -le 1 ]] && echo 4 || echo 6
|
|
}
|
|
|
|
this(){
|
|
local MAP ADDR
|
|
case $CALLER in
|
|
'avahi')
|
|
grep -Pom1 "^$1=\K.*" $CONF ;;
|
|
'smb')
|
|
grep -Pom1 "^$1 = \K.*" $CONF ;;
|
|
'ntp'|'ssh')
|
|
grep -Po "^$1 \K\S+" $CONF | tr '\n' ' ' | sed 's/ $//' ;;
|
|
'nfs')
|
|
grep -Pom1 "^RPC_NFSD_OPTS=\"$OPTIONS \K[^\"]+" $NFS ;;
|
|
'rpc')
|
|
grep -Pom1 "^RPCBIND_OPTS=\"\K[^\"]+" $RPC ;;
|
|
'nginx')
|
|
grep -Po "^NGINX_BIND=\"\K[^\"]+" ${INI%.*} 2>/dev/null ;;
|
|
esac
|
|
}
|
|
|
|
scan(){
|
|
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
|
}
|
|
|
|
good(){
|
|
local TAG BAD
|
|
for TAG in ${BIND[@]}; do
|
|
[[ -z $1 || $1 == $TAG || ${1:0:4} == fe80 ]] && BAD=1 && break
|
|
done
|
|
echo $BAD
|
|
}
|
|
|
|
show(){
|
|
case $# in
|
|
1) ip -br addr show scope global primary -deprecated to $1 2>/dev/null | awk '{gsub("@.+","",$1);print $1;exit}' ;;
|
|
2) ip -br addr show scope global primary -deprecated $1 $2 2>/dev/null | awk '{$1=$2="";print;exit}' | sed -r 's/ metric [0-9]+//g' ;;
|
|
esac
|
|
}
|
|
|
|
unmask(){
|
|
if [[ $CALLER != smb ]]; then
|
|
# remove netmask
|
|
echo ${1/\/*}
|
|
elif [[ $(ipv $1) == 4 ]]; then
|
|
# replace netmask
|
|
echo ${1/\/32/\/24}
|
|
elif [[ -z $DENY6 ]]; then
|
|
# IPv6 only when netbios is disabled
|
|
echo ${1/\/128/\/64}
|
|
fi
|
|
}
|
|
|
|
remove(){
|
|
local i ADDR
|
|
for ADDR in $@; do
|
|
ADDR=$(unmask $ADDR)
|
|
[[ -z $ADDR ]] && continue
|
|
for i in ${!BIND[@]}; do
|
|
[[ $ADDR == ${BIND[$i]} ]] && unset 'BIND[i]'
|
|
done
|
|
done
|
|
}
|
|
|
|
isname(){
|
|
[[ -z ${1//[^.:]} || ${1//[^.:]} == . ]] && return 0 || return 1
|
|
}
|
|
|
|
add_name(){
|
|
local NET
|
|
for NET in $include_interfaces; do
|
|
if $(isname $NET); then
|
|
# NET is an interface name, validate
|
|
[[ -n $(show dev $NET) && -z $(good $NET) ]] && BIND+=($NET)
|
|
else
|
|
# NET is an IP address, convert to name
|
|
NET=$(show $NET)
|
|
[[ -n $NET && -z $(good $NET) ]] && BIND+=($NET)
|
|
fi
|
|
done
|
|
for NET in $exclude_interfaces; do
|
|
if $(isname $NET); then
|
|
# NET is an interface name
|
|
remove "$NET"
|
|
else
|
|
# NET is an IP address, convert to name
|
|
remove "$(show $NET)"
|
|
fi
|
|
done
|
|
}
|
|
|
|
add_addr(){
|
|
local NET MAP ADDR
|
|
for NET in $include_interfaces; do
|
|
if $(isname $NET); then
|
|
# NET is an interface name, get IP addresses
|
|
MAP="$(show dev $NET)"
|
|
else
|
|
# NET is an IP address, validate
|
|
MAP="$(show to $NET)"
|
|
fi
|
|
for ADDR in $MAP; do
|
|
ADDR=$(unmask $ADDR)
|
|
[[ -z $(good $ADDR) ]] && BIND+=($ADDR) || continue
|
|
[[ $(ipv $ADDR) == 4 ]] && IPV4=yes || IPV6=yes
|
|
done
|
|
done
|
|
for NET in $exclude_interfaces; do
|
|
if $(isname $NET); then
|
|
# NET is an interface name, get IP addresses
|
|
remove "$(show dev $NET)"
|
|
else
|
|
# NET is an IP address
|
|
remove "$(show to $NET)"
|
|
fi
|
|
done
|
|
}
|
|
|
|
check(){
|
|
# quick check
|
|
[[ -n $BIND ]] && return 0;
|
|
# preset return values
|
|
BIND=(); IPV4=no; IPV6=no; FAMILY=any;
|
|
# read active interfaces (including wireguard tunnels)
|
|
while IFS=$'\n' read -r NET; do
|
|
NET=($NET)
|
|
if [[ ${NET:0:2} == wg ]]; then
|
|
# skip wireguard tunnel if NTP or VPN type
|
|
[[ $CALLER == ntp || $(grep -Pom1 '^TYPE:1="\K[^"]+' $WIREGUARD/$NET.cfg) == 8 ]] && continue
|
|
fi
|
|
for ADDR in ${NET[@]/$NET}; do
|
|
ADDR=$(unmask $ADDR)
|
|
if [[ "ntp avahi show" =~ "$CALLER" ]]; then
|
|
[[ -z $(good $NET) ]] && BIND+=($NET)
|
|
else
|
|
[[ -z $(good $ADDR) ]] && BIND+=($ADDR) || continue
|
|
fi
|
|
[[ $(ipv $ADDR) == 4 ]] && IPV4=yes || IPV6=yes
|
|
done
|
|
done <<< $(ip -br addr show scope global primary -deprecated | awk '$1~"^(br|bond|eth|wlan|wg)[0-9]+(.[0-9]+)?" && $3!="" {gsub("@.+","",$1);$2="";print}' | sed -r 's/ metric [0-9]+//g' | sort)
|
|
# add loopback interface
|
|
if [[ "smb nfs" =~ "$CALLER" ]]; then
|
|
[[ $IPV4 == yes ]] && BIND+=(127.0.0.1)
|
|
[[ $IPV6 == yes ]] && BIND+=(::1)
|
|
fi
|
|
# add user defined interfaces
|
|
if [[ -f $NETWORK_EXTRA && $CALLER != ntp ]]; then
|
|
. <(fromdos <$NETWORK_EXTRA)
|
|
[[ "avahi show" =~ "$CALLER" ]] && add_name || add_addr
|
|
fi
|
|
if [[ $CALLER == ssh ]]; then
|
|
# BIND stays array
|
|
BIND=(${BIND[@]})
|
|
[[ $IPV4 == yes && $IPV6 == no ]] && FAMILY=inet
|
|
[[ $IPV6 == yes && $IPV4 == no ]] && FAMILY=inet6
|
|
else
|
|
# convert array to string
|
|
BIND=${BIND[@]}
|
|
[[ $CALLER == avahi ]] && BIND=${BIND// /,}
|
|
fi
|
|
return 0
|
|
}
|