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
|
|
|
|
|
}
|