jean-cloud-services/services/ns1.jean-cloud.org/helper_functions.sh

209 lines
5.7 KiB
Bash
Raw Normal View History

2023-09-13 08:46:02 +00:00
set -euo pipefail
2023-09-16 18:17:34 +00:00
. driglibash-base
2023-09-13 08:46:02 +00:00
fakeresolve_ip_list () {
if [ "$#" -ne 1 ] ; then
die "Usage: fakeresolve_ip_list <name>"
fi
2023-09-29 07:51:22 +00:00
grep -oP "^$1[[:space:]]+(IN)?[[:space:]]+A{1,4}[[:space:]]+\K[^;\s]+" "$debian_bind_confdir/$server_zone_file" | tr '\n' ';'
2023-09-13 08:46:02 +00:00
}
prepare () {
# Install dependencies
apt install -y bind9 &>/dev/null
# Create Directories
if [ -n "$keydir" ] ; then
mkdir -p "$keydir"
chown bind:bind "$keydir" -R
chown bind:bind "$debian_bind_confdir" -R
fi
2024-02-22 00:43:01 +00:00
echo 'Sync the git repo'
2024-10-16 09:41:44 +00:00
run sudo -u bind git_update.sh -r main -o "-i $DATA_DIR/gitkey" -d "$debian_bind_confdir" 'ssh://git@git.jean-cloud.net:22529/adrian/dnszones.git'
2023-09-13 08:46:02 +00:00
cd /etc/bind
echo 'Prepare bind: Remove autogenerated part from bind conf files'
2024-06-15 15:59:53 +00:00
rm /etc/bind/*.jnl &>/dev/null || true
2023-09-13 08:46:02 +00:00
sed -i -n "/$autoconf_separator/q;p" "$debian_bind_confdir"/*
echo 'Put the separator back'
for file in $( ls "$debian_bind_confdir"/template.db.* | grep -v '.signed$\|.jbk$\|.jnl$') ; do
echo "$autoconf_separator" >> "$file"
done
}
restart () {
2024-02-22 00:43:01 +00:00
echo 'Check named conf'
2024-06-15 15:59:53 +00:00
run named-checkconf "$debian_bind_confdir/named.conf"
2024-02-22 00:43:01 +00:00
for db_file in $(list_db_files) ; do
2024-04-18 14:22:32 +00:00
domain="$(basename "$db_file")"
domain="${domain:3}"
2024-02-22 00:43:01 +00:00
run named-checkzone "$domain" "$db_file"
done
2023-09-15 08:57:47 +00:00
echo 'Restart named'
systemctl restart named
2023-09-13 08:46:02 +00:00
}
# Function that simulate a DNS resolve by reading bind zone file
# Returns all the record line:
# @ IN A X.X.X.X
fakeresolve () {
if [ "$#" -ne 1 ] ; then
die "Usage: fakeresolve <name>"
fi
name="$1"
zonefile="$debian_bind_confdir/$server_zone_file"
# Split full name if there are dots
shortname="$name"
if [ -n "$(echo "$name" | grep -o '\.')" ] ; then
shortname="$(echo "$name" | grep -Po '^.*(?=\.[^\.]+\.[^\.]+$)' || true)"
fi
2023-09-29 07:51:22 +00:00
grep -v -e '^[[:space:]]*;' "$zonefile" |grep -oP "^[[:space:]]*$shortname\K[[:space:]]*(IN)?[[:space:]]*A{1,4}[[:space:]]*[\S;]+" | sed 's/^/@/'
2023-09-13 08:46:02 +00:00
}
# Function that add DNS record in the right file
addbindline () {
if [ "$#" -ne 2 ] ; then
die "Usage: addbindline <name> <target_cname>"
fi
name="$1"
target="$2"
# extract the truc.com part
domain="$(echo "$name" | grep -o '[^\.]\+\.[^\.]\+$' || true)"
[ -z "$domain" ] && return 0
# extract the subdomain part (www)
shortname="$(echo "$name" | grep -Po '^.*(?=\.[^\.]+\.[^\.]+$)' || true)"
# bind DB file
bindfile="$debian_bind_confdir/db.$domain"
# Only append if db file exists
[ ! -f "$bindfile" ] && return 0
2023-09-15 08:57:47 +00:00
# BTW allow ACME DNS update
token="#JC-ACME $domain"
acme_dns="grant letsencrypt.key. name _acme-challenge.$name. TXT;"
sed -i "s/\([[:space:]]*\)$token/\1$acme_dns\n\1$token/" "$debian_bind_confdir/named.conf.local"
2023-10-16 08:47:35 +00:00
# TODO check if name already existst with a different target
# Hard since we are resolving targets now…
# CNAME are forbiden for empty shortnames, so we must resolve the target IPs
# For performance reasons, we just put plain IP everywhere
# to put aliases in place of ip juste do the following if $shortname is empty:
#line_in_file "$shortname CNAME $target." "$bindfile"
while read line ; do
if [ -n "$shortname" ] ; then
line="$(echo "$line" | sed "s/@/$shortname/")"
fi
line_in_file "$line" "$bindfile"
done < <(fakeresolve "$target")
2023-09-13 08:46:02 +00:00
}
list_template_db_files () {
ls "$debian_bind_confdir"/template.db.*
}
2024-02-22 00:43:01 +00:00
list_db_files () {
ls "$debian_bind_confdir"/db.* | grep -v -e '.jbk$' -e '.signed$' -e '.signed.jnl'
}
2023-09-13 08:46:02 +00:00
create_primary_files () {
# Compact the default SOA
SOA="$(grep -o '^[^;]*' SOA | sed -z -e 's/[[:space:]]\{2,\}/ /g' -e 's/\n/\\n/')"
2023-09-16 18:17:34 +00:00
line_in_file "include \"$DATA_DIR/letsencrypt.key\";" "$debian_bind_confdir/named.conf"
2023-09-13 08:46:02 +00:00
for file in $(list_template_db_files) ; do
domain="$(basename "$file" | sed 's/template.db.//')"
new_db_file="$(echo "$file" | sed 's/template.db./db./')"
# Set the default SOA if needed
sed "s/^;JC_AUTOSOA$/$SOA/" "$file" > "$new_db_file"
2023-09-15 08:57:47 +00:00
# Set serial
serial="$(date '+%s')"
2023-09-29 07:51:22 +00:00
sed -i "s/\(@ SOA [^(]*( \)[0-9]\+/\1$serial/" "$new_db_file"
2023-09-15 08:57:47 +00:00
2024-01-02 16:50:14 +00:00
# Add this dns server if not present
2024-04-18 14:22:32 +00:00
if ! grep -q '[^;].*(IN)?.*NS.*' "$new_db_file" ; then
cat default_ns >> "$new_db_file"
2023-09-13 08:46:02 +00:00
fi
2023-09-15 08:57:47 +00:00
2023-10-31 15:42:06 +00:00
# Add DS record
2024-04-18 14:22:32 +00:00
#if [ -n "$(ls "$DATA_DIR/keys/K$domain"*.key)" ] ; then
2023-10-31 15:42:06 +00:00
#dnssec-dsfromkey "$DATA_DIR/keys/K$domain"*.key | sed "s/${domain}./@/" >> "$new_db_file"
2024-04-18 14:22:32 +00:00
#fi
2023-10-31 15:42:06 +00:00
2023-09-15 08:57:47 +00:00
# Populate named.conf.local
cat >> "$debian_bind_confdir/named.conf.local" <<-EOF
zone "$domain" {
# Zone file
type master;
file "$new_db_file";
# Secondary conf
# https://kb.isc.org/docs/aa-00723
#allow-update { !{!{$secondary_ips};any;}; key update-key; };
allow-transfer { $secondary_ips };
also-notify { $secondary_ips };
notify yes;
# DNSSEC
dnssec-policy default;
inline-signing yes;
key-directory "$DATA_DIR/keys";
# ACME autorizations
update-policy {
#JC-ACME $domain
};
};
EOF
2023-09-13 08:46:02 +00:00
done
echo 'Find every used domain and add them to bind db'
2024-01-02 16:50:14 +00:00
while IFS=';' read -r id username service target
do
2023-09-13 08:46:02 +00:00
addbindline "$service" "$target"
nginxfile="/docker/$service/nginx_server.conf"
if [ -f "$nginxfile" ] ; then
for name in $(extract_domain_nginx_conf.sh "$nginxfile" | template.sh "/docker/$service/.env") ; do
addbindline "$name" "$target"
done
fi
2024-01-02 16:50:14 +00:00
done < <(grep -v '^#' /docker/services.csv)
2023-09-13 08:46:02 +00:00
}
create_secondary_files () {
primary_ips="$(echo "$primary_ips" | sed 's/^;//')"
for file in "$debian_bind_confdir"/template.db.* ; do
2023-09-16 18:17:34 +00:00
file="$(echo "$file" | sed -e 's/template.db.//' -e "s#$debian_bind_confdir#/var/lib/bind/#")"
2023-09-13 08:46:02 +00:00
domain="$(basename "$file")"
echo -n "
zone \"$domain\" {
masters { $primary_ips };
type slave;
file \"$file\";
};" >> "$debian_bind_confdir/named.conf.local"
done
}