generated from smedev/Template-for-SMEServer-Core-Package
	
		
			
	
	
		
			159 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			159 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | #!/bin/bash | ||
|  | 
 | ||
|  | #---------------------------------------------------------------------- | ||
|  | # copyright (C) 2022 Koozali SME Server | ||
|  | #                | ||
|  | # This program is free software; you can redistribute it and/or modify | ||
|  | # it under the terms of the GNU General Public License as published by | ||
|  | # the Free Software Foundation; either version 2 of the License, or | ||
|  | # (at your option) any later version. | ||
|  | #                | ||
|  | # This program is distributed in the hope that it will be useful, | ||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||
|  | # GNU General Public License for more details. | ||
|  | #                | ||
|  | # You should have received a copy of the GNU General Public License | ||
|  | # along with this program; if not, write to the Free Software | ||
|  | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA | ||
|  | #  | ||
|  | #---------------------------------------------------------------------- | ||
|  | 
 | ||
|  | event=$1 | ||
|  | fqdn=$2 | ||
|  | todo=$3 | ||
|  | domainlist="" | ||
|  | 
 | ||
|  | case $todo in | ||
|  |   disabled|enabled) | ||
|  |         # | ||
|  |         ;; | ||
|  |   *) | ||
|  | 	todo="all" | ||
|  | 	;; | ||
|  | esac | ||
|  | 
 | ||
|  | if [[ ! -z "$fqdn"  ]] | ||
|  |   then | ||
|  |   # if fqdn not empty just use this one | ||
|  |   domainlist="$fqdn" | ||
|  | elif [[ ! -z "$event" ]] && [[ "$event" == *"domain"* ]] | ||
|  |   then | ||
|  |   # else if event *domains* => all domains | ||
|  |   domainlist=$(perl -Mesmith::DomainsDB -e 'my $domains = esmith::DomainsDB->open; my @DOM = $domains->get_all_by_prop(type=>"domain"); print( join(" " , map { $_->key } @DOM)) ') | ||
|  | elif [[ ! -z "$event" ]] && [[ "$event" == *"host"* ]] | ||
|  |   then | ||
|  |   # else if event *hosts* => all hosts | ||
|  |   domainlist=$(perl -Mesmith::HostsDB -e 'my $domains = esmith::HostsDB->open; my @DOM = $domains->get_all_by_prop(type=>"host"); print( join(" " , map { $_->key } @DOM)) ') | ||
|  | else | ||
|  |   # else all domain and hosts | ||
|  |   domains=$(perl -Mesmith::DomainsDB -e 'my $domains = esmith::DomainsDB->open; my @DOM = $domains->get_all_by_prop(type=>"domain"); print( join(" " , map { $_->key } @DOM)) ') | ||
|  |   hosts=$(perl -Mesmith::HostsDB -e 'my $domains = esmith::HostsDB->open; my @DOM = $domains->get_all_by_prop(type=>"host"); print( join(" " , map { $_->key } @DOM)) ') | ||
|  |   domainlist="$domains $hosts" | ||
|  | fi | ||
|  | domainlist=$(echo $domainlist |sort|uniq) | ||
|  | 
 | ||
|  | #list from pihole install script; only ipv4 ones | ||
|  | #here we select our  | ||
|  | dns=$(/sbin/e-smith/db configuration getprop letesencrypt dnscheck||echo "https://cloudflare-dns.com/dns-query,8.8.8.8,8.8.4.4,1.1.1.1,1.0.0.1,208.67.222.222,208.67.220.220,4.2.2.1,4.2.2.2,8.20.247.20,84.200.69.80,84.200.70.40,9.9.9.10,149.112.112.10") | ||
|  | # from https://stackoverflow.com/questions/10586153/how-to-split-a-string-into-an-array-in-bash | ||
|  | IFS=', ' read -r -a DNS <<< "$dns" | ||
|  | RANDOM=$$$(date +%s) | ||
|  | x=1 | ||
|  | #TODO: if only one element skip the random selection | ||
|  | while [ $x -le 5 ]; do | ||
|  | mydns=${DNS[ $RANDOM % ${#DNS[@]} ]} | ||
|  | if [[ $mydns == http* ]] ; then | ||
|  |   curl -s $mydns >/dev/null  | ||
|  |   if [[ "$?" == "0" ]]; then | ||
|  |     break | ||
|  |   fi | ||
|  | else | ||
|  |   nc -z  -w2 $mydns 53 | ||
|  |   if [[ "$?" == "0" ]]; then | ||
|  |     break | ||
|  |   fi | ||
|  | fi | ||
|  | x=$(( $x + 1 )) | ||
|  | #in case of failure defaulting on a dns over https after 5 | ||
|  | mydns="https://cloudflare-dns.com/dns-query" | ||
|  | done | ||
|  | echo "External DNS Server  : $mydns" | ||
|  | 
 | ||
|  | MYFORCEDIP=$(/sbin/e-smith/db configuration getprop letesencrypt ExternalIP) | ||
|  | # check if gateway or server only | ||
|  | MYMODE=$(/sbin/e-smith/db configuration get SystemMode) | ||
|  | # check our external ip if gateway, internal else | ||
|  | LOCALIP=$(/sbin/e-smith/db configuration get InternalIP) | ||
|  | MYIP=$LOCALIP | ||
|  | # check the ip suggested by external world that point to us. | ||
|  | MYEXTIP=$(/usr/sbin/e-smith/getmyip) | ||
|  | 
 | ||
|  | if [ -z "$MYFORCEDIP" ]; then | ||
|  |   # we do not expect that a server-only has an ip routable on internet as firewall is not designed for that | ||
|  |   # but in case, we handle the situation as for ExternalIP in servergateway mode, please write ad hoc rules for masq if you do so... | ||
|  |   if [[ "$MYMODE" == "servergateway"  ]] ; then | ||
|  |     MYIP=$(/sbin/e-smith/db configuration get ExternalIP); | ||
|  |   fi | ||
|  |   if [[ "$MYIP" != "$MYEXTIP"  ]] ; then | ||
|  |     echo "External Interface IP: $MYIP" | ||
|  |     echo "Detected Wan IP      : $MYEXTIP" | ||
|  |     echo "You seem to be behind a firewall, using the external IP obtained with our test $MYEXTIP" | ||
|  |     MYIP=$MYEXTIP | ||
|  |   fi | ||
|  | else | ||
|  |   MYIP=$MYFORCEDIP | ||
|  | fi | ||
|  | 
 | ||
|  | echo "=============================================================================================" | ||
|  | OUTPUT="Domain\tStatus\tMYIP\tA\tLE_status\tLE_previous" | ||
|  | # TODO all : check disabled and enabled ; active : check enabled and undef only | ||
|  | 
 | ||
|  | for DOMAIN in  $domainlist  | ||
|  |    do | ||
|  |    # is it a host, a domain or should we ignore it | ||
|  |    TYPE=$(/sbin/e-smith/db domains gettype $DOMAIN || /sbin/e-smith/db hosts gettype $DOMAIN ) | ||
|  |    if [[ "$TYPE" == "domain" ]] ; then  | ||
|  | 	TYPE="domains" | ||
|  |    elif [[ "$TYPE" == "host" ]] ; then | ||
|  |         TYPE="hosts" | ||
|  |    else | ||
|  | 	echo "$DOMAIN is not in domains and not in hosts ($TYPE)" | ||
|  | 	continue | ||
|  |    fi | ||
|  |    # do we have a priority ? | ||
|  |    currentstate=$(/sbin/e-smith/db $TYPE getprop $DOMAIN letsencryptSSLcert || echo "disabled") | ||
|  |    if [ "$currentstate" != "$todo" -a "$todo" != "all" ] ; then | ||
|  | 	#echo "$DOMAIN skipping, only checking $todo $TYPE" | ||
|  | 	continue | ||
|  |    fi | ||
|  |    # https://stackoverflow.com/questions/15268987/bash-based-regex-domain-name-validation  | ||
|  |    if ( !  echo $DOMAIN| grep -P -q '(?=^.{4,253}$)(^(?:[a-zA-Z0-9](?:(?:[a-zA-Z0-9\-]){0,61}[a-zA-Z0-9])?\.)+([a-zA-Z]{2,}|xn--[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])$)' -Z ) ; then | ||
|  | 	if [[ "$currentstate" == "disabled" ]]; then continue; fi | ||
|  |         echo "$DOMAIN is not a RFC compliant domain, disabling" | ||
|  | 	/sbin/e-smith/db $TYPE setprop $DOMAIN letsencryptSSLcert disabled | ||
|  |         /sbin/e-smith/db $TYPE delprop $DOMAIN letsencryptMYIP | ||
|  |         continue | ||
|  |    fi | ||
|  |    THISDOMIP=$(/usr/bin/q A @$mydns $DOMAIN -f json |jq -r 'first(.Answers[].A  | select( . != null )) // null' 2>/dev/null || /usr/bin/q A @$LOCALIP $DOMAIN -f json |jq -r 'first(.Answers[].A  | select( . != null )) // null' 2>/dev/null  ) | ||
|  |    previous=$(/sbin/e-smith/db $TYPE getprop $DOMAIN letsencryptSSLcert||echo 'undefined'); | ||
|  |    # if it does not resolve, next | ||
|  |    if [[ "$THISDOMIP" == ""  ]] | ||
|  |         then | ||
|  |         OUTPUT="$OUTPUT\n$DOMAIN\tNOK\t$MYIP\tnoip\tdisabled\t$previous" | ||
|  |         /sbin/e-smith/db $TYPE setprop $DOMAIN letsencryptSSLcert disabled | ||
|  |         /sbin/e-smith/db $TYPE delprop $DOMAIN letsencryptMYIP | ||
|  |         continue; | ||
|  |    fi | ||
|  |    if [[ "$MYIP" == "$THISDOMIP" ]] | ||
|  |         then | ||
|  |         OUTPUT="$OUTPUT\n$DOMAIN\tOK\t$MYIP\t$THISDOMIP\tenabled\t$previous" | ||
|  |         /sbin/e-smith/db $TYPE setprop $DOMAIN letsencryptSSLcert enabled letsencryptMYIP $THISDOMIP | ||
|  |    else | ||
|  |         OUTPUT="$OUTPUT\n$DOMAIN\tNOK\t$MYIP\t$THISDOMIP\tdisabled\t$previous" | ||
|  |         /sbin/e-smith/db $TYPE setprop $DOMAIN letsencryptSSLcert disabled letsencryptMYIP $THISDOMIP | ||
|  |    fi | ||
|  |    sleep 1 | ||
|  | done | ||
|  | printf "%b" $OUTPUT |column -t -s $'\t'  |