Files
webgui/etc/rc.d/rc.library.source
2023-06-27 01:50:27 +02:00

198 lines
5.2 KiB
Plaintext

# Library file: /etc/rc.d/rc.library.source
# Used by nfsd, ntpd, rpc, samba, nginx, sshd, avahidaemon, show_interfaces
#
# bergware - updated for Unraid, June 2023
WIREGUARD="/etc/wireguard"
NETWORK_INI="/var/local/emhttp/network.ini"
EXTRA="/boot/config/network-extra.cfg"
IPv() {
t=${1//[^:]}
[[ ${#t} -le 1 ]] && echo 4 || echo 6
}
this() {
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')
now=();
for addr in $(awk '$1=="listen" && $2~/^[0-9]|\[/ && $0~/http2; #.*$/{print $2}' $SERVERS 2>/dev/null); do
# extract ipv4 / ipv6 address
[[ $(IPv $addr) == 4 ]] && addr=${addr%:*} || addr=${addr#*[} addr=${addr%]*}
now+=($addr)
done
# return addresses
echo ${now[@]}
;;
esac
}
scan() {
grep -Pom1 "^$1=\"?\K[^\"]+" $2
}
good() {
data=;
for i in ${bind[@]}; do
[[ $i == $1 || ${1:0:4} == fe80 ]] && data=$1
done
if [[ -n $2 ]]; then
for i in ${nets[@]}; do
[[ $i == $2 || ${2:0:4} == fe80 ]] && data=$2
done
fi
echo $data
}
show() {
case $# in
1) ip -br addr show to $1 2>/dev/null|awk '{print $1;exit}';;
2) ip -br addr show $1 $2 2>/dev/null|awk '$3 !~ "^fe80" {print $3;exit}';;
3) ip -br $1 addr show $2 $3 2>/dev/null|awk '$3 !~ "^fe80" {print $3;exit}';;
esac
}
sub() {
if [[ $CALLER == smb && -z $deny6 ]]; then
# replace netmask
[[ $(IPv $1) == 4 ]] && echo ${1/\/32/\/24} || echo ${1/\/128/\/64}
else
# remove netmask
echo ${1/\/*}
fi
}
remove() {
[[ $# -eq 0 ]] && return
for i in ${!bind[@]}; do
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
done
}
isname() {
[[ -z ${1//[^.:]} || ${1//[^.:]} == . ]] && return 0 || return 1
}
extra_name() {
for net in $include_interfaces; do
if $(isname $net); then
# net is an interface name, validate
[[ $CALLER != ntp && -n $(show dev $net) && -z $(good $net) ]] && bind+=($net)
else
# net is an IP address, convert to name
net=$(show $net)
[[ $CALLER != ntp && -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
remove $net
else
# net is an IP address, convert to name and remove
remove $(show $net)
fi
done
}
extra_addr() {
for net in $include_interfaces; do
if $(isname $net); then
# net is an interface name, get IP addresses
net4=$(show -4 dev $net)
net6=$(show -6 dev $net)
else
# net is an IP address, validate
net4=$(show -4 to $net)
net6=$(show -6 to $net)
fi
[[ $CALLER != ntp && -n $net4 && -z $(good $(sub $net4)) ]] && ipv4=yes bind+=($(sub $net4))
[[ $CALLER != ntp && -n $net6 && -z $(good $(sub $net6)) ]] && ipv6=yes bind+=($(sub $net6))
done
for net in $exclude_interfaces; do
if $(isname $net); then
# net is an interface name, get IP addresses
remove $(sub $(show -4 dev $net))
remove $(sub $(show -6 dev $net))
else
# net is an IP address
remove $(sub $(show to $net))
fi
done
}
check() {
# quick check
[[ -n $bind ]] && return 0;
# preset return values
bind=(); ipv4=no; ipv6=no; family=any;
# active ipv4 interfaces (including wireguard)
nets=()
while IFS='\n' read -r net; do
net=($net)
net1=$(sub ${net[1]})
if [[ "avahi show" =~ $CALLER ]]; then
[[ -n $net && -z $(good $net $net1) ]] && bind+=($net)
[[ -n $net1 ]] && ipv4=yes nets+=($net1)
else
# exclude wireguard tunnels for ntp
[[ $CALLER == ntp ]] && name=$(show $net1) || name=
[[ ${name:0:2} != wg && -n $net1 && -z $(good $net1) ]] && ipv4=yes bind+=($net1)
fi
done <<< $(ip -br -4 addr|awk '/^(br|bond|eth|wg)[0-9]+(\.[0-9]+)?/ {print $1,$3}')
# active ipv6 interfaces (including wireguard)
nets=()
while IFS='\n' read -r net; do
net=($net)
net1=$(sub ${net[1]})
if [[ "avahi show" =~ $CALLER ]]; then
[[ -n $net && -z $(good $net $net1) ]] && bind+=($net)
[[ -n $net1 ]] && ipv6=yes nets+=($net1)
else
# exclude wireguard tunnels for ntp
[[ $CALLER == ntp ]] && name=$(show $net1) || name=
[[ ${name:0:2} != wg && -n $net1 && -z $(good $net1) ]] && ipv6=yes bind+=($net1)
fi
done <<< $(ip -br -6 addr|awk '/^(br|bond|eth|wg)[0-9]+(\.[0-9]+)?/ && $3 !~ "^fe80" {print $1,$3}')
# 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 $EXTRA ]]; then
. <(/usr/bin/fromdos <$EXTRA)
if [[ "avahi show" =~ $CALLER ]]; then
extra_name
else
extra_addr
fi
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
}