Browse Source
new: [bind] add charm
new: [bind] add charm
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>pull/29/head
Valentin Lab
2 years ago
16 changed files with 890 additions and 0 deletions
-
93bind/README.org
-
7bind/build/Dockerfile
-
120bind/hooks/init
-
50bind/hooks/log_rotate-relation-joined
-
331bind/lib/common
-
27bind/metadata.yaml
-
12bind/src/etc/bind/db.0
-
13bind/src/etc/bind/db.127
-
12bind/src/etc/bind/db.255
-
14bind/src/etc/bind/db.empty
-
14bind/src/etc/bind/db.local
-
88bind/src/etc/bind/db.root
-
3bind/src/etc/bind/named.conf
-
30bind/src/etc/bind/named.conf.default-zones
-
56bind/src/etc/bind/named.conf.options
-
20bind/src/etc/bind/zones.rfc1918
@ -0,0 +1,93 @@ |
|||
# -*- ispell-local-dictionary: "english" -*- |
|||
|
|||
#+TITLE: Bind v9 Domain name server |
|||
|
|||
|
|||
* Usage |
|||
|
|||
** Example =compose.yml= |
|||
|
|||
#+begin_src yaml |
|||
dns: |
|||
charm: bind |
|||
|
|||
options: |
|||
vars: |
|||
## these vars are a facility to allow using `$var` in domain defs |
|||
myip: 1.2.3.4 |
|||
zones: |
|||
## __all__ will be applied to all domains defined here |
|||
__all__: |
|||
ns: |
|||
## '_' is translated to '@' in BIND v9 zone definition, which in |
|||
## in turn refers to the current domain being defined. |
|||
_: (dns.mycompany.com,sdns1.ovh.net,ns6.gandi.net) |
|||
mx: |
|||
_: (1 ,(5 alt(1,2),10 alt(3,4)).)aspmx.l.google.com. |
|||
mycompany.com: |
|||
mx: |
|||
news: 10 news |
|||
|
|||
## Names will generate IN A/CNAME depending if an IP is detected or a name |
|||
name: |
|||
## key and values can be expanded, the syntax uses the same logic |
|||
## than shell expansion with `{`, `}` and `,`. So this: |
|||
## `(_,dns,core(,-01))` will demux to `_ dns core core-01`, so all |
|||
## these keys will receive the following value. |
|||
(_,dns,core(,-01)): $myip |
|||
core-02: 4.5.6.7 |
|||
|
|||
## You can specify after a space, a TTL that will be applied to all |
|||
## definitions inside the section: |
|||
name 3h: |
|||
## `www` required not to be an IP by zonecheck |
|||
(www,admin,smtp,beta,alpha,erp(,-beta)): core-01 |
|||
news: 77.32.131.26 |
|||
r.news: r.mailin.fr. |
|||
img.news: img.mailin.fr. |
|||
|
|||
spf 3h: |
|||
## Remember that this is YAML that also offer nice syntaxic |
|||
## feature to avoid repeating values. |
|||
_: &spf >- |
|||
v=spf1 a |
|||
a:smtp.free.fr |
|||
a:smtp.mycompany.com |
|||
include:spf.sendinblue.com |
|||
mx ?all |
|||
txt 3h: |
|||
_: |
|||
- *spf |
|||
- Sendinblue-code:xxx |
|||
- google-site-verification=yyy |
|||
|
|||
news: "v=spf1 include:spf.sendinblue.com mx ~all" |
|||
mail._domainkey(,.news): |
|||
"k=rsa;p=zzz" |
|||
|
|||
_dmarc.news: >- |
|||
v=DMARC1; |
|||
p=none; |
|||
sp=none; |
|||
rua=mailto:dmarc@mailinblue.com!10m; |
|||
ruf=mailto:dmarc@mailinblue.com!10m; |
|||
rf=afrf; |
|||
pct=100; |
|||
ri=86400 |
|||
|
|||
(othercompany.com,other-company.com): |
|||
name: |
|||
(_,www,mail): $myip |
|||
(admin,beta): www |
|||
#+end_src |
|||
|
|||
|
|||
* Persistence |
|||
|
|||
backup will keep: |
|||
- /etc/bind/rndc.key |
|||
- /etc/bind/.db.$DOMAIN files keeping a hash of the configuration along |
|||
with the given serial that matches the zone file. This is to be sure to |
|||
advertise the same serial after a recovery. |
|||
|
|||
|
@ -0,0 +1,7 @@ |
|||
FROM alpine:3.12.0 |
|||
|
|||
RUN apk add --no-cache bind |
|||
|
|||
EXPOSE 53 |
|||
|
|||
CMD ["named", "-c", "/etc/bind/named.conf", "-g", "-u", "named"] |
@ -0,0 +1,120 @@ |
|||
#!/bin/bash |
|||
|
|||
## Init is run on host |
|||
## For now it is run every time the script is launched, but |
|||
## it should be launched only once after build. |
|||
|
|||
## Accessible variables are: |
|||
## - SERVICE_NAME Name of current service |
|||
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any |
|||
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service |
|||
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service |
|||
|
|||
|
|||
. lib/common |
|||
|
|||
set -e |
|||
|
|||
|
|||
## |
|||
## "${BIND_CONFIG_DIR}"/bind.keys |
|||
## |
|||
|
|||
## https://www.isc.org/bind-keys/ |
|||
|
|||
config_hash=$(docker inspect "$DOCKER_BASE_IMAGE" --format '{{ .Id }}') |
|||
if ! [ -e "${SERVICE_CONFIGSTORE}${BIND_CONFIG_DIR}"/bind.keys ]; then |
|||
mkdir -p "${SERVICE_CONFIGSTORE}${BIND_CONFIG_DIR}" |
|||
## From alpine install |
|||
ln -sf ../../usr/share/dnssec-root/bind-dnssec-root.keys \ |
|||
"${SERVICE_CONFIGSTORE}${BIND_CONFIG_DIR}"/bind.keys |
|||
fi |
|||
|
|||
|
|||
## |
|||
## "${BIND_CONFIG_DIR}"/rndc.key |
|||
## |
|||
|
|||
|
|||
if [ -d "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key ]; then |
|||
## When deleting file and docker is still running, due to named |
|||
## stopping and docker force-restart, this file will be recreated |
|||
## as a directory To avoid issues, if we detect this condition, |
|||
## let's just remove the directory |
|||
|
|||
rmdir "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key |
|||
fi |
|||
|
|||
if ! [ -e "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key ]; then |
|||
mkdir -p "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/ |
|||
docker run --rm -v "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}:${BIND_CONFIG_DIR}" \ |
|||
"$DOCKER_BASE_IMAGE" rndc-confgen -b 256 -a |
|||
if ! [ -e "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key ]; then |
|||
err "RNDC key-file generation failed." |
|||
exit 1 |
|||
fi |
|||
fi |
|||
config_hash=$(e "$config_hash" "$(cat "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key)") |
|||
|
|||
init-config-add " |
|||
$SERVICE_NAME: |
|||
volumes: |
|||
- \"$SERVICE_DATASTORE${BIND_CONFIG_DIR}/rndc.key:${BIND_CONFIG_DIR}/rndc.key:ro\" |
|||
" |
|||
|
|||
|
|||
## |
|||
## "${BIND_CONFIG_DIR}"/named.conf and others |
|||
## |
|||
|
|||
|
|||
|
|||
cd src |
|||
cfg_files=("${BIND_CONFIG_DIR#/}"/{zones.rfc1918,{db,named}.*}) |
|||
for file in "${cfg_files[@]}"; do |
|||
if ! diff "$file" "$SERVICE_CONFIGSTORE"/"$file" >/dev/null 2>&1; then |
|||
cp -v "$file" "$SERVICE_CONFIGSTORE"/"$file" >&2 || exit 1 |
|||
else |
|||
echo "File $file already up to date." >&2 |
|||
fi |
|||
done |
|||
config_hash=$(p0 "$config_hash" "$(cat "${cfg_files[@]}")" | md5_compat) |
|||
cd .. |
|||
|
|||
## |
|||
## user requested zones |
|||
## |
|||
|
|||
vars_cfg=$(options-get vars 2>/dev/null) || true |
|||
zones_cfg=$(options-get zones 2>/dev/null) || true |
|||
|
|||
if [ -n "$zones_cfg" ]; then |
|||
## will update config_hash |
|||
bind:cfg:generate "$zones_cfg" "$vars_cfg" |
|||
fi |
|||
|
|||
|
|||
uid=$(docker_get_uid "$SERVICE_NAME" "named") |
|||
|
|||
dirs=(/{etc,var/{log,cache}}/bind ) |
|||
host_dirs=() |
|||
for dir in "${dirs[@]}"; do |
|||
host_dirs+=("$SERVICE_DATASTORE$dir") |
|||
done |
|||
host_dirs+=("$SERVICE_CONFIGSTORE"/etc/bind) |
|||
|
|||
mkdir -p "${host_dirs[@]}" |
|||
find "${host_dirs[@]}" \! -user "$uid" -or -type l -print0 | while read-0 f; do |
|||
chown -v "$uid" "$f" || exit 1 |
|||
done |
|||
|
|||
|
|||
## |
|||
## Final |
|||
## |
|||
|
|||
init-config-add " |
|||
$MASTER_BASE_SERVICE_NAME: |
|||
labels: |
|||
- compose.config_hash=$config_hash |
|||
" |
@ -0,0 +1,50 @@ |
|||
#!/bin/bash |
|||
|
|||
## Should be executable N time in a row with same result. |
|||
|
|||
. lib/common |
|||
|
|||
set -e |
|||
|
|||
named_uid=$(docker_get_uid "$SERVICE_NAME" "named") |
|||
|
|||
LOGS=/var/log/bind |
|||
mkdir -p "$SERVICE_DATASTORE/$LOGS" |
|||
chown -R "$named_uid" "$SERVICE_DATASTORE/$LOGS" |
|||
|
|||
rotated_count=$(relation-get rotated-count 2>/dev/null) || true |
|||
rotated_count=${rotated_count:-52} |
|||
|
|||
## XXXvlab: a lot of this intelligence should be moved away into ``logrotate`` charm |
|||
DST="$CONFIGSTORE/$TARGET_SERVICE_NAME/etc/logrotate.d/$SERVICE_NAME" |
|||
file_put "$DST" <<EOF |
|||
/var/log/docker/$SERVICE_NAME/*.log |
|||
{ |
|||
weekly |
|||
missingok |
|||
dateext |
|||
dateyesterday |
|||
dateformat _%Y-%m-%d |
|||
extension .log |
|||
rotate $rotated_count |
|||
compress |
|||
delaycompress |
|||
notifempty |
|||
create 640 |
|||
sharedscripts |
|||
postrotate |
|||
dc exec $SERVICE_NAME /usr/sbin/rndc reconfig > /dev/null 2>/dev/null || true |
|||
endscript |
|||
} |
|||
EOF |
|||
|
|||
config-add "\ |
|||
services: |
|||
$MASTER_TARGET_SERVICE_NAME: |
|||
volumes: |
|||
- $DST:/etc/logrotate.d/docker-${SERVICE_NAME}:ro |
|||
- $SERVICE_DATASTORE$LOGS:/var/log/docker/$SERVICE_NAME:rw |
|||
$MASTER_BASE_SERVICE_NAME: |
|||
volumes: |
|||
- $SERVICE_DATASTORE$LOGS:$LOGS:rw |
|||
" |
@ -0,0 +1,331 @@ |
|||
# -*- mode: shell-script -*- |
|||
|
|||
BIND_CONFIG_DIR=/etc/bind |
|||
|
|||
|
|||
## Generate bind config files in $cfgdir from YAML configuration $cfg |
|||
bind:cfg:generate() { |
|||
local cfg="$1" vars="$2" zone_file include_zone_statements all_domain \ |
|||
domains expanded_domains zone_cfg |
|||
|
|||
## __all__ domain is treated here like a normal domain |
|||
|
|||
expanded_domains="" |
|||
while read-0 domain zone_cfg; do |
|||
if ! [[ "$domain" =~ ^[a-z0-9_\(\),.-]+$ ]]; then |
|||
err "Invalid domain '$domain' as key in ${WHITE}zones${NORMAL} records." |
|||
return 1 |
|||
fi |
|||
domains=() |
|||
bind:parse:expand-in "$domain" domains "$vars" || return 1 |
|||
for domain in "${domains[@]}"; do |
|||
expanded_domains=$(merge_yaml_str "$expanded_domains" \ |
|||
"$(yaml_key_val_str "$domain" "$zone_cfg")") |
|||
done |
|||
done < <(e "$cfg" | shyaml key-values-0) |
|||
|
|||
## __all__ domain is merged in other domain domain |
|||
|
|||
all_domain=$(e "$expanded_domains" | shyaml get-value "__all__") |
|||
resolved_domains="" |
|||
while read-0 domain zone_cfg; do |
|||
if [ "$domain" == "__all__" ]; then |
|||
continue |
|||
fi |
|||
resolved_domains=$(merge_yaml_str \ |
|||
"$resolved_domains" \ |
|||
"$(yaml_key_val_str "$domain" "$all_domain")" \ |
|||
"$(yaml_key_val_str "$domain" "$zone_cfg")") |
|||
done < <(e "$expanded_domains" | shyaml key-values-0) |
|||
|
|||
include_zone_statements= |
|||
while read-0 domain zone_cfg; do |
|||
info "Considering ${WHITE}$domain${NORMAL} zone configuration" |
|||
zone_file="${BIND_CONFIG_DIR}/db.${domain}" |
|||
zone_hash_file="${BIND_CONFIG_DIR}/.db.${domain}.hash" |
|||
zone_def=$(bind:content:zone_definition \ |
|||
"$domain" "$zone_cfg" "$vars") || return 1 |
|||
zone_def_hash=$(H "$zone_def") |
|||
|
|||
## We need to store the last serial as well as the last hash in |
|||
## the datastore to allow a full restore (will correct serials) |
|||
## without discontinuity of services. |
|||
|
|||
current_hash= |
|||
current_serial= |
|||
if [ -e "${SERVICE_DATASTORE}${zone_hash_file}" ]; then |
|||
current_hash_content="$(cat "${SERVICE_DATASTORE}${zone_hash_file}")" || true |
|||
current_hash=${current_hash_content% *} |
|||
current_serial=${current_hash_content#* } |
|||
echo " found a previous hash file with serial: $current_serial" >&2 |
|||
fi |
|||
|
|||
if [ "$current_hash" == "$zone_def_hash" ]; then ## no need to change full serial |
|||
echo " can use previous serial as zone definition seems to have not changed" >&2 |
|||
serial=${current_serial} |
|||
else |
|||
echo " needs a new serial as zone definition seems to have changed" >&2 |
|||
date=$(date +%Y%m%d) |
|||
if [ "$date" == "${current_serial:0:8}" ]; then |
|||
serial="$date$(printf "%02d" "$((${current_serial: -2:2} + 1))")" |
|||
echo " increment serial to $serial" >&2 |
|||
else |
|||
serial="${date}00" |
|||
echo " first definition for the current date" >&2 |
|||
fi |
|||
fi |
|||
zone_def=$(e "$zone_def" | sed -r "s/%%SERIAL%%/$serial/g") |
|||
if ! [ -e "${SERVICE_CONFIGSTORE}${zone_file}" ] || |
|||
[ "$zone_def" != "$(cat "${SERVICE_CONFIGSTORE}${zone_file}")" ]; then |
|||
echo " ${DARKYELLOW}writing${NORMAL} zone def file to config with serial $serial." >&2 |
|||
e "${zone_def}" > "${SERVICE_CONFIGSTORE}${zone_file}" |
|||
else |
|||
echo " zone def already available in config with serial $serial." >&2 |
|||
fi |
|||
if ! [ -e "${SERVICE_DATASTORE}${zone_hash_file}" ] || |
|||
[ "$zone_def_hash $serial" != "$(cat "${SERVICE_DATASTORE}${zone_hash_file}")" ]; then |
|||
echo " ${DARKYELLOW}writing${NORMAL} zone file hash to data with serial $serial." >&2 |
|||
e "$zone_def_hash $serial" > "${SERVICE_DATASTORE}${zone_hash_file}" |
|||
else |
|||
echo " zone def hash already available in data with serial $serial." >&2 |
|||
fi |
|||
|
|||
include_zone_statements+=$( |
|||
bind:content:include_zone_statement "$domain" "${zone_file}" |
|||
)$'\n' |
|||
config_hash=$(p0 "$config_hash" "$zone_def_hash" | md5_compat) || exit 1 |
|||
done < <(e "$resolved_domains" | shyaml key-values-0) |
|||
|
|||
e "$include_zone_statements" > "${SERVICE_CONFIGSTORE}${BIND_CONFIG_DIR}/named.conf.local" |
|||
} |
|||
|
|||
|
|||
bind:content:include_zone_statement() { |
|||
local domain="$1" zone_file="$2" |
|||
|
|||
cat <<EOF |
|||
zone "${domain}" { |
|||
type master; |
|||
notify yes; |
|||
file "${zone_file}"; |
|||
}; |
|||
EOF |
|||
|
|||
} |
|||
|
|||
bind:check:is_time() { |
|||
local label="$1" value="$2" |
|||
if ! [[ "$value" =~ ^[0-9smhdw]+$ ]]; then |
|||
err "Invalid value for $label: '$value'." >&2 |
|||
echo " Please use a number of seconds or use one-character time units (IE: 1w, 1h30, 3600)" >&2 |
|||
return 1 |
|||
fi |
|||
return 0 |
|||
} |
|||
|
|||
bind:parse:expand-in() { |
|||
local value="$1" aname="$2" vars="$3" |
|||
|
|||
if ! [[ "$value" =~ ^[a-z0-9_\(\)\ \$,.-]+$ ]]; then |
|||
err "Invalid value '$value' to expand." |
|||
return 1 |
|||
fi |
|||
declare -n cur="$aname" |
|||
if [[ "$value" == *","* ]]; then |
|||
value="${value//\(/\{}" |
|||
value="${value//\)/\}}" |
|||
value="${value// /\\ }" |
|||
else |
|||
value="\"$value\"" |
|||
fi |
|||
|
|||
value="${value//\$/\$_vars_}" |
|||
while read-0 label v; do |
|||
local "_vars_$label"="$v" |
|||
done < <(e "$vars" | shyaml key-values-0) |
|||
eval "cur+=($value)" || { |
|||
err "Couldn't eval '$value'." |
|||
return 1 |
|||
} |
|||
} |
|||
|
|||
bind:content:zone_definition() { |
|||
local domain="$1" zone_cfg="$2" vars_cfg="$3" \ |
|||
vtype cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" |
|||
if [ -e "$cache_file" ]; then |
|||
# debug "$FUNCNAME: cache hit ($*)" |
|||
cat "$cache_file" |
|||
return 0 |
|||
fi |
|||
|
|||
## Zone definition is created with %%SERIAL%% as placeholder in |
|||
## the serial number intended final emplacement. This allows to |
|||
## check the output's hash of this function to decide if we need |
|||
## to change the serial. |
|||
|
|||
zone_cfg=$(merge_yaml_str " |
|||
\$ttl: 1w |
|||
soa: |
|||
email: dns@${domain} |
|||
refresh: 8h |
|||
retry: 4h |
|||
expire: 1w |
|||
ttl: 1d |
|||
ns: |
|||
_: dns |
|||
" "$zone_cfg") || return 1 |
|||
|
|||
vars_cfg=$(merge_yaml_str " |
|||
mydomain: \"$domain\" |
|||
" "$vars_cfg") || return 1 |
|||
|
|||
while read-0 key subcfg; do |
|||
# echo "KEY: $key" >&2 |
|||
# echo "SUBCONFIG:" >&2 |
|||
# echo "$subcfg" | prefix " | " >&2 |
|||
declare -A decls |
|||
ttl= |
|||
if [[ "$key" == *" "* ]]; then |
|||
ttl=${key#* } |
|||
key=${key%% *} |
|||
fi |
|||
case "$key" in |
|||
"\$"*) |
|||
case "$key" in |
|||
"\$ttl") |
|||
bind:check:is_time ttl "$subcfg" || return 1 |
|||
;; |
|||
*) |
|||
echo "Unsupported variable '${key}'." >&2 |
|||
return 1 |
|||
esac |
|||
decls[vars]+="${key^^} $subcfg"$'\n' |
|||
;; |
|||
soa) |
|||
soa_values="$(printf "%-12s ; %s" "%%SERIAL%%" "serial")"$'\n' |
|||
for k in refresh retry expire ttl; do |
|||
value=$(e "$subcfg" | shyaml get-value "$k" 2>/dev/null) || { |
|||
err "Couldn't find any value for '$k' in '${domain}''s 'soa' config." |
|||
return 1 |
|||
} |
|||
bind:check:is_time "soa.$k" "$value" || { |
|||
err "Error while reading soa definition of domain '$domain'." |
|||
return 1 |
|||
} |
|||
soa_values+="$(printf "%-12s ; %s" "$value" "$k")"$'\n' |
|||
done |
|||
email=$(e "$subcfg" | shyaml get-value "email" 2>/dev/null) || { |
|||
err "Couldn't find any value for 'email' in '${domain}''s 'soa' config." |
|||
return 1 |
|||
} |
|||
soa_values="$(e "$soa_values" | prefix " ")" |
|||
decls[soa]+="$(printf "%-28s IN SOA %s. %s. (" "@" "${domain}" "${email/@/.}")"$'\n' |
|||
decls[soa]+="${soa_values}"$'\n'")"$'\n' |
|||
|
|||
;; |
|||
ns|mx|name|spf|txt) |
|||
while read-0 name name_cfg; do |
|||
if ! [[ "$name" =~ ^[a-z0-9_\(\),.-]+$ ]]; then |
|||
err "Invalid name '$name' in ${domain}'s $key records." |
|||
return 1 |
|||
fi |
|||
names=() |
|||
bind:parse:expand-in "$name" names "$vars_cfg" || return 1 |
|||
## values |
|||
vtype=$(e "$name_cfg" | shyaml get-type) |
|||
# echo TYPE: $vtype >&2 |
|||
values=() |
|||
case "$vtype" in |
|||
"sequence") |
|||
array_read-0 values < <(e "$name_cfg" | shyaml get-values-0) |
|||
;; |
|||
"str") |
|||
values=("$(e "$name_cfg" | shyaml get-value)") |
|||
;; |
|||
*) |
|||
err "Unsupported type '$vtype' of '$key' in $domain's zone definition." |
|||
exit 1 |
|||
;; |
|||
esac |
|||
values_expanded=() |
|||
for value in "${values[@]}"; do |
|||
case "$key" in |
|||
ns|name) |
|||
if ! [[ "$value" =~ ^[a-z0-9_\$\(\),.-]+$ ]]; then |
|||
err "Invalid value '$value' in ${domain}'s $key records for '$name'." |
|||
return 1 |
|||
fi |
|||
## Append in values_expanded |
|||
bind:parse:expand-in "$value" values_expanded "$vars_cfg" || return 1 |
|||
;; |
|||
mx) |
|||
## space is allowed (actually mandatory) |
|||
if ! [[ "$value" =~ ^[a-z0-9_\$\(\),.\ -]+$ ]]; then |
|||
err "Invalid value '$value' in ${domain}'s $key records for '$name'." |
|||
return 1 |
|||
fi |
|||
## Append in values_expanded |
|||
bind:parse:expand-in "$value" values_expanded "$vars_cfg" || return 1 |
|||
;; |
|||
spf|txt) |
|||
## No expansion for them |
|||
values_expanded+=("\"$value\"") |
|||
;; |
|||
esac |
|||
done |
|||
|
|||
for name in "${names[@]}"; do |
|||
[ "$name" == "_" ] && name="@" |
|||
|
|||
for value in "${values_expanded[@]}"; do |
|||
rkey="$key" |
|||
if [ "$key" == "name" ]; then |
|||
if [[ "$value" =~ ^([0-9]{1,3}\.){3,3}[0-9]{1,3}$ ]]; then |
|||
rkey="a" |
|||
elif [[ "$value" =~ ^([a-z0-9-]+\.?)+$ ]]; then |
|||
rkey="cname" |
|||
elif [ -z "$value" ]; then |
|||
err "Empty value for 'name' '$name', was '${values[@]}' before evaluation" |
|||
echo " in '$domain' zone definition." >&2 |
|||
return 1 |
|||
else |
|||
err "Unrecognised value for 'name': '$value'." |
|||
echo " in '$domain' zone definition." >&2 |
|||
return 1 |
|||
fi |
|||
fi |
|||
if [ -z "$value" ]; then |
|||
err "Empty value for 'name' '$name'." |
|||
echo " in '$domain' zone definition." >&2 |
|||
return 1 |
|||
fi |
|||
decls[$rkey]+=$(printf "%-15s %-12s IN %s %s" "$name" "$ttl" "${rkey^^}" "$value")$'\n' |
|||
done |
|||
done |
|||
done < <(e "$subcfg" | shyaml key-values-0) |
|||
;; |
|||
*) |
|||
err "Unknown keyword '$key' in '$domain' zone definition." |
|||
return 1 |
|||
esac |
|||
done < <(e "$zone_cfg" | shyaml key-values-0) |
|||
for k in vars soa ns mx a cname spf txt; do |
|||
[ -z "${decls[$k]}" ] && continue |
|||
if [ "$k" != "vars" ]; then |
|||
echo |
|||
echo |
|||
echo ";; $k" |
|||
echo |
|||
fi |
|||
echo "${decls[$k]}" | grep -v "^$" | { |
|||
case "$k" in |
|||
a|ns|cname|spf|txt|vars) |
|||
sort |
|||
;; |
|||
soa|mx) |
|||
cat |
|||
;; |
|||
esac |
|||
} |
|||
done | tee "$cache_file" |
|||
} |
@ -0,0 +1,27 @@ |
|||
name: bind |
|||
summary: "BIND v9 Domain Name Server" |
|||
maintainer: "Valentin Lab <valentin.lab@kalysto.org>" |
|||
inherit: base-0k |
|||
description: | |
|||
Installs a Domain Name Server. |
|||
config-resources: |
|||
- /etc/bind |
|||
data-resources: |
|||
- /var/log/bind |
|||
- /var/cache/bind |
|||
|
|||
|
|||
uses: |
|||
log-rotate: |
|||
#constraint: required | recommended | optional |
|||
#auto: pair | summon | none ## default: pair |
|||
constraint: recommended |
|||
auto: pair |
|||
solves: |
|||
unmanaged-logs: "in docker logs" |
|||
#default-options: |
|||
backup: |
|||
constraint: recommended |
|||
auto: pair |
|||
solves: |
|||
backup: "Automatic regular backup" |
@ -0,0 +1,12 @@ |
|||
; |
|||
; BIND reverse data file for broadcast zone |
|||
; |
|||
$TTL 604800 |
|||
@ IN SOA localhost. root.localhost. ( |
|||
1 ; Serial |
|||
604800 ; Refresh |
|||
86400 ; Retry |
|||
2419200 ; Expire |
|||
604800 ) ; Negative Cache TTL |
|||
; |
|||
@ IN NS localhost. |
@ -0,0 +1,13 @@ |
|||
; |
|||
; BIND reverse data file for local loopback interface |
|||
; |
|||
$TTL 604800 |
|||
@ IN SOA localhost. root.localhost. ( |
|||
1 ; Serial |
|||
604800 ; Refresh |
|||
86400 ; Retry |
|||
2419200 ; Expire |
|||
604800 ) ; Negative Cache TTL |
|||
; |
|||
@ IN NS localhost. |
|||
1.0.0 IN PTR localhost. |
@ -0,0 +1,12 @@ |
|||
; |
|||
; BIND reverse data file for broadcast zone |
|||
; |
|||
$TTL 604800 |
|||
@ IN SOA localhost. root.localhost. ( |
|||
1 ; Serial |
|||
604800 ; Refresh |
|||
86400 ; Retry |
|||
2419200 ; Expire |
|||
604800 ) ; Negative Cache TTL |
|||
; |
|||
@ IN NS localhost. |
@ -0,0 +1,14 @@ |
|||
; BIND reverse data file for empty rfc1918 zone |
|||
; |
|||
; DO NOT EDIT THIS FILE - it is used for multiple zones. |
|||
; Instead, copy it, edit named.conf, and use that copy. |
|||
; |
|||
$TTL 86400 |
|||
@ IN SOA localhost. root.localhost. ( |
|||
1 ; Serial |
|||
604800 ; Refresh |
|||
86400 ; Retry |
|||
2419200 ; Expire |
|||
86400 ) ; Negative Cache TTL |
|||
; |
|||
@ IN NS localhost. |
@ -0,0 +1,14 @@ |
|||
; |
|||
; BIND data file for local loopback interface |
|||
; |
|||
$TTL 604800 |
|||
@ IN SOA localhost. root.localhost. ( |
|||
2 ; Serial |
|||
604800 ; Refresh |
|||
86400 ; Retry |
|||
2419200 ; Expire |
|||
604800 ) ; Negative Cache TTL |
|||
; |
|||
@ IN NS localhost. |
|||
@ IN A 127.0.0.1 |
|||
@ IN AAAA ::1 |
@ -0,0 +1,88 @@ |
|||
; This file holds the information on root name servers needed to |
|||
; initialize cache of Internet domain name servers |
|||
; (e.g. reference this file in the "cache . <file>" |
|||
; configuration file of BIND domain name servers). |
|||
; |
|||
; This file is made available by InterNIC |
|||
; under anonymous FTP as |
|||
; file /domain/named.cache |
|||
; on server FTP.INTERNIC.NET |
|||
; -OR- RS.INTERNIC.NET |
|||
; |
|||
; last update: Jan 3, 2013 |
|||
; related version of root zone: 2013010300 |
|||
; |
|||
; formerly NS.INTERNIC.NET |
|||
; |
|||
. 3600000 IN NS A.ROOT-SERVERS.NET. |
|||
A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4 |
|||
A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:BA3E::2:30 |
|||
; |
|||
; FORMERLY NS1.ISI.EDU |
|||
; |
|||
. 3600000 NS B.ROOT-SERVERS.NET. |
|||
B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201 |
|||
; |
|||
; FORMERLY C.PSI.NET |
|||
; |
|||
. 3600000 NS C.ROOT-SERVERS.NET. |
|||
C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12 |
|||
; |
|||
; FORMERLY TERP.UMD.EDU |
|||
; |
|||
. 3600000 NS D.ROOT-SERVERS.NET. |
|||
D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13 |
|||
D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2D::D |
|||
; |
|||
; FORMERLY NS.NASA.GOV |
|||
; |
|||
. 3600000 NS E.ROOT-SERVERS.NET. |
|||
E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10 |
|||
; |
|||
; FORMERLY NS.ISC.ORG |
|||
; |
|||
. 3600000 NS F.ROOT-SERVERS.NET. |
|||
F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241 |
|||
F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2F::F |
|||
; |
|||
; FORMERLY NS.NIC.DDN.MIL |
|||
; |
|||
. 3600000 NS G.ROOT-SERVERS.NET. |
|||
G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4 |
|||
; |
|||
; FORMERLY AOS.ARL.ARMY.MIL |
|||
; |
|||
. 3600000 NS H.ROOT-SERVERS.NET. |
|||
H.ROOT-SERVERS.NET. 3600000 A 128.63.2.53 |
|||
H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::803F:235 |
|||
; |
|||
; FORMERLY NIC.NORDU.NET |
|||
; |
|||
. 3600000 NS I.ROOT-SERVERS.NET. |
|||
I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17 |
|||
I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7FE::53 |
|||
; |
|||
; OPERATED BY VERISIGN, INC. |
|||
; |
|||
. 3600000 NS J.ROOT-SERVERS.NET. |
|||
J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30 |
|||
J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:C27::2:30 |
|||
; |
|||
; OPERATED BY RIPE NCC |
|||
; |
|||
. 3600000 NS K.ROOT-SERVERS.NET. |
|||
K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129 |
|||
K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7FD::1 |
|||
; |
|||
; OPERATED BY ICANN |
|||
; |
|||
. 3600000 NS L.ROOT-SERVERS.NET. |
|||
L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42 |
|||
L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:3::42 |
|||
; |
|||
; OPERATED BY WIDE |
|||
; |
|||
. 3600000 NS M.ROOT-SERVERS.NET. |
|||
M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33 |
|||
M.ROOT-SERVERS.NET. 3600000 AAAA 2001:DC3::35 |
|||
; End of File |
@ -0,0 +1,3 @@ |
|||
include "/etc/bind/named.conf.options"; |
|||
include "/etc/bind/named.conf.local"; |
|||
include "/etc/bind/named.conf.default-zones"; |
@ -0,0 +1,30 @@ |
|||
// prime the server with knowledge of the root servers |
|||
zone "." { |
|||
type hint; |
|||
file "/etc/bind/db.root"; |
|||
}; |
|||
|
|||
// be authoritative for the localhost forward and reverse zones, and for |
|||
// broadcast zones as per RFC 1912 |
|||
|
|||
zone "localhost" { |
|||
type master; |
|||
file "/etc/bind/db.local"; |
|||
}; |
|||
|
|||
zone "127.in-addr.arpa" { |
|||
type master; |
|||
file "/etc/bind/db.127"; |
|||
}; |
|||
|
|||
zone "0.in-addr.arpa" { |
|||
type master; |
|||
file "/etc/bind/db.0"; |
|||
}; |
|||
|
|||
zone "255.in-addr.arpa" { |
|||
type master; |
|||
file "/etc/bind/db.255"; |
|||
}; |
|||
|
|||
|
@ -0,0 +1,56 @@ |
|||
options { |
|||
directory "/var/cache/bind"; |
|||
|
|||
// If there is a firewall between you and nameservers you want |
|||
// to talk to, you may need to fix the firewall to allow multiple |
|||
// ports to talk. See http://www.kb.cert.org/vuls/id/800113 |
|||
|
|||
// If your ISP provided one or more IP addresses for stable |
|||
// nameservers, you probably want to use them as forwarders. |
|||
// Uncomment the following block, and insert the addresses replacing |
|||
// the all-0's placeholder. |
|||
|
|||
// forwarders { |
|||
// 0.0.0.0; |
|||
// }; |
|||
|
|||
//======================================================================== |
|||
// If BIND logs error messages about the root key being expired, |
|||
// you will need to update your keys. See https://www.isc.org/bind-keys |
|||
//======================================================================== |
|||
dnssec-validation auto; |
|||
|
|||
auth-nxdomain no; # conform to RFC1035 |
|||
// listen-on-v6 { any; }; |
|||
|
|||
// allow-recursion yes; |
|||
allow-recursion { 127.0.0.1; 172.210/16; 172.18/16; 51.255.66.199;}; |
|||
allow-recursion-on { any;}; |
|||
|
|||
|
|||
}; |
|||
|
|||
|
|||
logging { |
|||
channel warning |
|||
{ |
|||
file "/var/log/bind/dns.warnings.log"; |
|||
severity warning; |
|||
print-category yes; |
|||
print-severity yes; |
|||
print-time yes; |
|||
}; |
|||
|
|||
channel general_dns |
|||
{ |
|||
file "/var/log/bind/dns.log"; |
|||
severity info; |
|||
print-category yes; |
|||
print-severity yes; |
|||
print-time yes; |
|||
}; |
|||
|
|||
category default { warning; } ; |
|||
category queries { general_dns; } ; |
|||
}; |
|||
|
@ -0,0 +1,20 @@ |
|||
zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
|
|||
zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
zone "31.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
|||
|
|||
zone "168.192.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue