mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-03-11 09:04:54 +00:00
349 lines
9.5 KiB
Bash
Executable File
349 lines
9.5 KiB
Bash
Executable File
#!/bin/bash
|
|
#Todo: IPv6
|
|
#Todo: Other service types than gnudip (generic update URL)
|
|
#Todo: GET WAN IP from Router via UPnP if supported
|
|
|
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
|
|
|
#static values
|
|
WGET=$(which wget)
|
|
WGETOPTIONS="-4 -o /dev/null -t 3 -T 3"
|
|
EMPTYSTRING="none"
|
|
NOIP="0.0.0.0"
|
|
#how often do we poll for IP changes if we are behind a NAT?
|
|
UPDATEMINUTES=5
|
|
#if we do not have a IP check URL, how often should we do a "blind" update
|
|
UPDATEMINUTESUNKNOWN=3600
|
|
TOOLNAME=ez-ipupdate
|
|
UPDATE_TOOL=$(which ${TOOLNAME})
|
|
|
|
#Dirs and filenames
|
|
CFGDIR="/etc/${TOOLNAME}/"
|
|
CFG="${CFGDIR}${TOOLNAME}.conf"
|
|
CFG_disabled="${CFGDIR}${TOOLNAME}.inactive"
|
|
IPFILE="${CFGDIR}${TOOLNAME}.currentIP"
|
|
STATUSFILE="${CFGDIR}${TOOLNAME}.status"
|
|
LASTUPDATE="${CFGDIR}/last-update"
|
|
HELPERCFG="${CFGDIR}${TOOLNAME}-plinth.cfg"
|
|
CRONJOB="/etc/cron.d/${TOOLNAME}"
|
|
PIDFILE="/var/run/ez-ipupdate.pid"
|
|
|
|
doGetOpt()
|
|
{
|
|
basicauth=0
|
|
ignoreCertError=0
|
|
|
|
while getopts ":s:d:u:p:I:U:c:b:" opt; do
|
|
case $opt in
|
|
s)
|
|
server=$OPTARG
|
|
;;
|
|
d)
|
|
host=$OPTARG
|
|
;;
|
|
u)
|
|
user=$OPTARG
|
|
;;
|
|
p)
|
|
pass=$OPTARG
|
|
;;
|
|
I)
|
|
if [ "$OPTARG" != "$EMPTYSTRING" ];then
|
|
ipurl=$OPTARG
|
|
else
|
|
ipurl=""
|
|
fi
|
|
;;
|
|
U)
|
|
if [ "$OPTARG" != "$EMPTYSTRING" ];then
|
|
updateurl=$OPTARG
|
|
else
|
|
updateurl=""
|
|
fi
|
|
;;
|
|
b)
|
|
basicauth=$OPTARG
|
|
;;
|
|
c)
|
|
ignoreCertError=$OPTARG
|
|
;;
|
|
\?)
|
|
echo "Invalid option: -$OPTARG" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
doWriteCFG()
|
|
{
|
|
mkdir $CFGDIR 2> /dev/null
|
|
#always write to the inactive config - needs to be enabled via "start" command later
|
|
file=$CFG_disabled
|
|
|
|
#reset the last update time
|
|
echo 0 > $LASTUPDATE
|
|
|
|
#reset the last updated IP
|
|
echo "0.0.0.0" > $IPFILE
|
|
|
|
#reset last update (if there is one)
|
|
rm $STATUSFILE 2> /dev/null
|
|
|
|
#find the interface (always the default gateway interface)
|
|
default_interface=`ip route |grep default |awk '{print $5}'`
|
|
|
|
#store the given options in ez-ipupdate compatible config file
|
|
echo "host=$host" > $file
|
|
echo "server=$server" >> $file
|
|
echo "user=${user}:${pass}" >> $file
|
|
echo "service-type=gnudip" >> $file
|
|
echo "retrys=3" >> $file
|
|
echo "wildcard" >> $file
|
|
|
|
#store UPDATE URL params
|
|
echo "POSTURL $updateurl" > $HELPERCFG
|
|
echo "POSTAUTH $basicauth" >> $HELPERCFG
|
|
echo "POSTSSLIGNORE $ignoreCertError" >> $HELPERCFG
|
|
|
|
#check if we are behind a NAT Router
|
|
echo "IPURL $ipurl" >> $HELPERCFG
|
|
if [ -z $ipurl ];then
|
|
echo "NAT unknown" >> $HELPERCFG
|
|
else
|
|
doGetWANIP
|
|
ISGLOBAL=`ip addr ls $default_interface | grep $wanip`
|
|
if [ -z $ISGLOBAL ];then
|
|
#we are behind NAT
|
|
echo "NAT yes" >> $HELPERCFG
|
|
else
|
|
#we are directly connected
|
|
echo "NAT no" >> $HELPERCFG
|
|
#if this file is added ez-ipupdate will take ip form this interface
|
|
echo "interface=$default_interface" >> $file
|
|
#if this line is added to config file, ez-ipupdate will be launched on startup via init.d
|
|
echo "daemon" >> $file
|
|
echo "execute=$0 success" >> $file
|
|
fi
|
|
fi
|
|
}
|
|
|
|
doReadCFG()
|
|
{
|
|
host=""
|
|
server=""
|
|
user=""
|
|
pass=""
|
|
ipurl=""
|
|
file=""
|
|
[ -f $CFG_disabled ] && file=$CFG_disabled
|
|
[ -f $CFG ] && file=$CFG
|
|
|
|
if [ ! -z $file ];then
|
|
host=`cat $file 2> /dev/null |grep host |cut -d = -f 2`
|
|
server=`cat $file 2> /dev/null |grep server |cut -d = -f 2 |grep -v ^\'\'`
|
|
user=`cat $file 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1 `
|
|
pass=`cat $file 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2`
|
|
fi
|
|
|
|
if [ ! -z $HELPERCFG ];then
|
|
ipurl=`cat $HELPERCFG 2> /dev/null |grep ^IPURL |awk '{print $2}' |grep -v ^\'\'`
|
|
updateurl=`cat $HELPERCFG 2> /dev/null |grep POSTURL |awk '{print $2}' |grep -v ^\'\'`
|
|
basicauth=`cat $HELPERCFG 2> /dev/null |grep POSTAUTH |awk '{print $2}' |grep -v ^\'\'`
|
|
ignoreCertError=`cat $HELPERCFG 2> /dev/null |grep POSTSSLIGNORE |awk '{print $2}' |grep -v ^\'\'`
|
|
fi
|
|
}
|
|
|
|
doStatus()
|
|
{
|
|
PROC=`pgrep ${TOOLNAME}`
|
|
if [ -f $CRONJOB ];then
|
|
echo enabled
|
|
elif [ ! -z $PROC ];then
|
|
echo enabled
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $server ];then
|
|
echo $server
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $host ];then
|
|
echo $host
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $user ];then
|
|
echo $user
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $pass ];then
|
|
echo $pass
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $ipurl ];then
|
|
echo $ipurl
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $updateurl ];then
|
|
echo $updateurl
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $basicauth ];then
|
|
echo $basicauth
|
|
else
|
|
echo disabled
|
|
fi
|
|
if [ ! -z $ignoreCertError ];then
|
|
echo $ignoreCertError
|
|
else
|
|
echo disabled
|
|
fi
|
|
}
|
|
|
|
doGetWANIP()
|
|
{
|
|
if [ ! -z $ipurl ];then
|
|
outfile=`mktemp`
|
|
$WGET $WGETOPTIONS -O $outfile $ipurl
|
|
wanip=`cat $outfile`
|
|
rm $outfile
|
|
[ -z $wanip ] && wanip=${NOIP}
|
|
else
|
|
#no WAN IP found because of missing check URL
|
|
wanip=${NOIP}
|
|
fi
|
|
}
|
|
|
|
doUpdate()
|
|
{
|
|
if [ ! -z $server ];then
|
|
start-stop-daemon -S -x ${UPDATE_TOOL} -m -p ${PIDFILE} -- -c $file
|
|
fi
|
|
|
|
if [ ! -z $updateurl ];then
|
|
echo "todo"
|
|
fi
|
|
}
|
|
|
|
cmd=$1
|
|
shift
|
|
case $cmd in
|
|
configure)
|
|
doGetOpt $@
|
|
doWriteCFG
|
|
;;
|
|
start)
|
|
if [ "$(cat $HELPERCFG |grep ^NAT | awk '{print $2}')" = "no" ];then
|
|
if [ -f $CFG -a ! -z $(cat $file 2> /dev/null |grep server |cut -d = -f 2 |grep -v ^\'\')];then
|
|
mv $CFG_disabled $CFG
|
|
/etc/init.d/${TOOLNAME} start
|
|
fi
|
|
if [ ! -z $(cat $HELPERCFG |grep ^POSTURL | awk '{print $2}') ];then
|
|
echo "*/${UPDATEMINUTES} * * * * root $0 update" > $CRONJOB
|
|
$0 update
|
|
fi
|
|
else
|
|
echo "*/${UPDATEMINUTES} * * * * root $0 update" > $CRONJOB
|
|
$0 update
|
|
fi
|
|
;;
|
|
get-nat)
|
|
NAT=`cat $HELPERCFG 2> /dev/null |grep ^NAT | awk '{print $2}'`
|
|
[ -z $NAT ] && NAT="unknown"
|
|
echo $NAT
|
|
;;
|
|
update)
|
|
doReadCFG
|
|
oldip=`cat $IPFILE`
|
|
doGetWANIP
|
|
echo $wanip > $IPFILE
|
|
cfgfile="/tmp/none"
|
|
[ -f $CFG_disabled ] && cfgfile=$CFG_disabled
|
|
[ -f $CFG ] && cfgfile=$CFG
|
|
cat $file |grep -v execute > ${cfgfile}.tmp
|
|
mv ${cfgfile}.tmp ${cfgfile}
|
|
echo "execute=$0 success ${wanip}" >> $cfgfile
|
|
#if we know our WAN IP, only update if IP changes
|
|
if [ "${oldip}" != "${wanip}" -a "${wanip}" != ${NOIP} ];then
|
|
doUpdate
|
|
fi
|
|
#if we don't know our WAN IP do a blind update once a hour
|
|
if [ "${wanip}" = ${NOIP} ];then
|
|
uptime=`cat /proc/uptime |cut -d . -f 1`
|
|
LAST=0
|
|
[ -f ${LASTUPDATE} ] && LAST=`cat $LASTUPDATE`
|
|
diff=`expr $uptime - $LAST`
|
|
if [ $diff -gt $UPDATEMINUTESUNKNOWN ];then
|
|
doUpdate
|
|
fi
|
|
fi
|
|
;;
|
|
stop)
|
|
rm $CRONJOB 2> /dev/null
|
|
/etc/init.d/${TOOLNAME} stop
|
|
kill $(cat ${PIDFILE}) 2> /dev/null
|
|
mv $CFG $CFG_disabled
|
|
;;
|
|
success)
|
|
date=`date`
|
|
echo "last update done ($date)" > $STATUSFILE
|
|
cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE
|
|
#if called from cronjob, the current IP is given as parameter
|
|
if [ $# -eq 1 ];then
|
|
echo $1 > $IPFILE
|
|
else
|
|
#if called from ez-ipupdate daemon, no WAN IP is given as parameter
|
|
doGetWANIP
|
|
echo $wanip > $IPFILE
|
|
fi
|
|
;;
|
|
failed)
|
|
date=`date`
|
|
echo "last update failed ($date)" > $STATUSFILE
|
|
;;
|
|
get-last-success)
|
|
if [ -f $STATUSFILE ];then
|
|
cat $STATUSFILE
|
|
else
|
|
echo "no successful update recorded since last config change"
|
|
fi
|
|
;;
|
|
status)
|
|
doReadCFG
|
|
doStatus
|
|
;;
|
|
get-timer)
|
|
echo $UPDATEMINUTES
|
|
;;
|
|
clean)
|
|
rm ${CFGDIR}/*
|
|
rm $CRONJOB
|
|
;;
|
|
*)
|
|
echo "usage: status|configure <options>|start|stop|update|get-nat|clean|success [updated IP]|failed"
|
|
echo ""
|
|
echo "options are:"
|
|
echo "-s <server> Gnudip Server address"
|
|
echo "-d <domain> Domain to be updated"
|
|
echo "-u <user> Account username"
|
|
echo "-p <password> Account Password"
|
|
echo "-I <IP check URL> A URL which returns the IP of the client who is requesting"
|
|
echo "-U <update URL> The update URL (a HTTP GET on this URL will be done)"
|
|
echo "-c <1|0> disable SSL check on Update URL"
|
|
echo "-b <1|0> use HTTP basic auth on Update URL"
|
|
echo ""
|
|
echo "update do a one time update"
|
|
echo "clean delete configuration"
|
|
echo "success store update success and optional the updated IP"
|
|
echo "failed store update failure"
|
|
echo "get-nat return the detected nat type"
|
|
;;
|
|
esac
|
|
exit 0
|