407 lines
14 KiB
Bash
Executable File
407 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
# postinst script for #PACKAGE#
|
|
#
|
|
# see: dh_installdeb(1)
|
|
|
|
set -xe
|
|
|
|
# summary of how this script can be called:
|
|
# * <postinst> `configure' <most-recently-configured-version>
|
|
# * <old-postinst> `abort-upgrade' <new version>
|
|
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
|
# <new-version>
|
|
# * <postinst> `abort-remove'
|
|
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
|
# <failed-install-package> <version> `removing'
|
|
# <conflicting-package> <version>
|
|
# for details, see https://www.debian.org/doc/debian-policy/ or
|
|
# the debian-policy package
|
|
|
|
case "$1" in
|
|
configure)
|
|
|
|
|
|
## START gather all the info from the box and generate the variabels
|
|
IFCONFIG="etc/network/interfaces"
|
|
UDEVCONFIG="etc/udev/rules.d/70-persistent-net.rules"
|
|
FRRCONFIG="etc/frr/frr.conf.wit"
|
|
IPSECCONFIG="etc/ipsec.conf.wit"
|
|
IPSECSECRETS="etc/ipsec.secrets"
|
|
SWANCTLCONFIG="etc/swanctl/conf.d/wit-swanctl.conf"
|
|
SYSCTLTWEAKS="etc/sysctl.d/10-frr.conf"
|
|
DOMAINNAME=$(hostname -d)
|
|
|
|
|
|
dig_txt() {
|
|
TMPDIG=$(dig txt +short $1)
|
|
[ -z ${TMPDIG} ] && exit 2
|
|
TMPDIG=${TMPDIG//\//\\\/}
|
|
TMPDIG=${TMPDIG//\"/} #" fix the god damn syntax highlighter
|
|
echo ${TMPDIG}
|
|
}
|
|
|
|
dig_a() {
|
|
TMPDIG=$(dig a +short $1)
|
|
[ -z ${TMPDIG} ] && exit 2
|
|
echo ${TMPDIG}
|
|
}
|
|
|
|
dig_aaaa() {
|
|
TMPDIG=$(dig aaaa +short $1)
|
|
[ -z ${TMPDIG} ] && exit 2
|
|
echo ${TMPDIG}
|
|
}
|
|
|
|
|
|
LOOPBACKv4=$(dig_a ${HOSTNAME})
|
|
LOOPBACKv6=$(dig_aaaa ${HOSTNAME})
|
|
NODEASN=$(dig_txt asn.${HOSTNAME})
|
|
|
|
|
|
## END variables
|
|
|
|
|
|
## START nic config compile
|
|
|
|
|
|
# write loopback config
|
|
cat <<-EOF >>$IFCONFIG
|
|
auto lo
|
|
iface lo inet loopback
|
|
|
|
iface lo inet static
|
|
address ${LOOPBACKv4}/32
|
|
|
|
iface lo inet6 static
|
|
address ${LOOPBACKv6}/128
|
|
|
|
|
|
EOF
|
|
|
|
BASTIONPUBLICIP=$(dig_a public.${HOSTNAME}) || true
|
|
if [[ ! -z $BASTIONPUBLICIP ]]; then
|
|
cat <<-EOF >>$IFCONFIG
|
|
iface lo inet static
|
|
address ${BASTIONPUBLICIP}/32
|
|
|
|
|
|
EOF
|
|
fi
|
|
|
|
|
|
|
|
# gathering defined interfaces
|
|
for if in mgmt mgmtgw ipmigw feth up ibgp gre customer; do
|
|
for i in {1..4}; do #### for now we support/count only to 4 interfaces of each type, we can just raise this to whatever number we want (exeption mgmt)
|
|
ifname=${if}${i}
|
|
ifalias=$(dig_txt name.${ifname}.${HOSTNAME}) || true ## still thinking how to do this cleaner
|
|
|
|
|
|
if [[ $ifname = gre? ]] && [[ ! -z $ifalias ]]; then
|
|
ifmtu=$(dig_txt mtu.${ifname}.${HOSTNAME})
|
|
local=$(dig_txt local.${ifname}.${HOSTNAME})
|
|
localasn=$(dig_txt localasn.${ifname}.${HOSTNAME})
|
|
remote=$(dig_txt remote.${ifname}.${HOSTNAME})
|
|
|
|
|
|
## for the GRE tunnel to not have to deal with ibgp/full-mesh or reflectors prepending a private AS
|
|
FRR_GRE_ASN="$localasn"
|
|
|
|
|
|
## build FRR interface config to enable ND adv for ipv6 unmanaged
|
|
FRR_IFS="${FRR_IFS}interface $ifname\n"
|
|
FRR_IFS="${FRR_IFS} description $ifalias\n"
|
|
FRR_IFS="${FRR_IFS} ipv6 nd ra-interval 10\n"
|
|
FRR_IFS="${FRR_IFS} no ipv6 nd suppress-ra\n!\n"
|
|
|
|
|
|
## build FRR neightbor interfaces
|
|
FRR_EDGE_NEIGH=" !!! neighbor $ifname interface peer-group GRE\n$FRR_EDGE_NEIGH"
|
|
|
|
|
|
## build regular linux network interface config
|
|
cat <<-EOF >>$IFCONFIG
|
|
auto $ifname
|
|
iface $ifname inet manual
|
|
## $ifalias
|
|
pre-up ip tunnel add $ifname mode gre local $local remote $remote
|
|
down ip tunnel del $ifname
|
|
mtu $ifmtu
|
|
|
|
|
|
EOF
|
|
|
|
fi
|
|
|
|
|
|
## blow we deal with real physical interfaces
|
|
## it is crucial that this `ifmac` block is above the rest, since if no mac is returned it will skip the loop and prevent the package install to fail
|
|
if [[ $ifname = mgmt1 ]] || [[ $ifname = mgmtgw1 ]] || [[ $ifname = ipmigw1 ]] ## we only support a single interface of these types and they are handled slightly differently in DNS
|
|
then
|
|
ifmac=$(dig_txt mac.${if}.${HOSTNAME}) || continue ## at this point skip the rest of the loop for interfaces that do not have a mac defined (those are basically not configured)
|
|
else
|
|
ifmac=$(dig_txt mac.${ifname}.${HOSTNAME}) || continue ## at this point skip the rest of the loop for interfaces that do not have a mac defined
|
|
fi
|
|
echo 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="'${ifmac}'", ATTR{type}=="1", NAME="'${ifname}'"' >>$UDEVCONFIG
|
|
|
|
|
|
if [[ $ifname = up? ]] || [[ $ifname = customer? ]]; then
|
|
|
|
ipv4=$(dig_txt ipv4.$ifname.${HOSTNAME})
|
|
ipv6=$(dig_txt ipv6.$ifname.${HOSTNAME})
|
|
peerv4=$(dig_txt peerv4.$ifname.${HOSTNAME}) || true ## we dont know if we will always have both available
|
|
peerv6=$(dig_txt peerv6.$ifname.${HOSTNAME}) || true ## we dont know if we will always have both available
|
|
|
|
|
|
if [[ $ifname = up? ]]; then
|
|
[ -z $peerv4 ] || FRR_EDGE_NEIGH=" !!! neighbor $peerv4 peer-group eBGPv4\n$FRR_EDGE_NEIGH"
|
|
[ -z $peerv6 ] || FRR_EDGE_NEIGH=" !!! neighbor $peerv6 peer-group eBGPv6\n$FRR_EDGE_NEIGH"
|
|
elif [[ $ifname = customer? ]]; then
|
|
[ -z $peerv4 ] || FRR_EDGE_NEIGH=" !!! neighbor $peerv4 peer-group CUSTOMERv4\n$FRR_EDGE_NEIGH"
|
|
[ -z $peerv6 ] || FRR_EDGE_NEIGH=" !!! neighbor $peerv6 peer-group CUSTOMERv6\n$FRR_EDGE_NEIGH"
|
|
fi
|
|
|
|
cat <<-EOF >>$IFCONFIG
|
|
auto $ifname
|
|
iface $ifname inet static
|
|
address ${ipv4/\\/}
|
|
mtu 9000
|
|
|
|
iface $ifname inet6 static
|
|
address ${ipv6/\\/}
|
|
dad-attempts 0
|
|
|
|
|
|
EOF
|
|
|
|
fi
|
|
|
|
|
|
if [[ $ifname = ibgp? ]]; then
|
|
|
|
## build FRR interface config to enable ND adv for ipv6 unmanaged
|
|
FRR_IFS="${FRR_IFS}interface $ifname\n"
|
|
FRR_IFS="${FRR_IFS} ipv6 nd ra-interval 10\n"
|
|
FRR_IFS="${FRR_IFS} no ipv6 nd suppress-ra\n!\n"
|
|
|
|
|
|
## build FRR neightbor interfaces
|
|
FRR_EDGE_NEIGH=" !!! neighbor $ifname interface peer-group iBGP\n$FRR_EDGE_NEIGH"
|
|
|
|
cat <<-EOF >>$IFCONFIG
|
|
auto $ifname
|
|
iface $ifname inet manual
|
|
mtu 9000
|
|
|
|
|
|
EOF
|
|
fi
|
|
|
|
|
|
if [[ $ifname = feth? ]]; then
|
|
cat <<-EOF >>$IFCONFIG
|
|
auto $ifname
|
|
iface $ifname inet manual
|
|
mtu 9000
|
|
|
|
|
|
EOF
|
|
fi
|
|
|
|
|
|
if [[ $ifname = mgmt1 ]]; then ## only 1 mgmt interface supported for now
|
|
cat <<-EOF >>$IFCONFIG
|
|
auto $ifname
|
|
iface $ifname inet6 auto
|
|
iface $ifname inet dhcp
|
|
pre-up /bin/ip link add mgmt type vrf table mgmt
|
|
pre-up /bin/ip link set up dev mgmt
|
|
pre-up /bin/ip link set master mgmt dev $ifname
|
|
post-down /bin/ip link del dev mgmt
|
|
|
|
|
|
EOF
|
|
fi
|
|
|
|
|
|
if [[ $ifname = mgmtgw1 ]] || [[ $ifname = ipmigw1 ]]; then ## only 1 mgmt interface supported for now
|
|
|
|
ipv4=$(dig_txt ipv4.$if.${HOSTNAME})
|
|
ipv6=$(dig_txt ipv6.$if.${HOSTNAME})
|
|
|
|
cat <<-EOF >>$IFCONFIG
|
|
auto ${ifname}
|
|
iface ${ifname} inet static
|
|
address ${ipv4/\\/}
|
|
|
|
iface ${ifname} inet6 static
|
|
address ${ipv6/\\/}
|
|
|
|
|
|
EOF
|
|
|
|
FRR_IFS="${FRR_IFS}interface ${ifname}\n"
|
|
FRR_IFS="${FRR_IFS} description $ifalias\n"
|
|
FRR_IFS="${FRR_IFS} ipv6 nd other-config-flag\n"
|
|
FRR_IFS="${FRR_IFS} ipv6 nd prefix ${ipv6}\n"
|
|
FRR_IFS="${FRR_IFS} ipv6 nd ra-interval 10\n"
|
|
FRR_IFS="${FRR_IFS} no ipv6 nd suppress-ra\n!\n\n"
|
|
|
|
[[ $ifname = mgmtgw1 ]] && listnum=10
|
|
[[ $ifname = ipmigw1 ]] && listnum=20
|
|
FRR_IFS="${FRR_IFS}ipv6 prefix-list MGMT seq $listnum permit ${ipv6}\n"
|
|
|
|
fi
|
|
|
|
|
|
done
|
|
done
|
|
|
|
## STOP nic config compile
|
|
|
|
|
|
## START compiling frr and ipsec dynamic config blocks
|
|
|
|
## compile public IP space prefix lists, this is what's going to be advertised out the upstream provider
|
|
i=1
|
|
while true; do
|
|
TEMP="$(dig_txt $i.ipv4.public.prefixlist.$DOMAINNAME)" || break
|
|
TEMPAGGS=" !!! aggregate-address ${TEMP}\n"
|
|
FRR_IPV4_EDGE_SUMMARIES_AGGREGATS="${FRR_IPV4_EDGE_SUMMARIES_AGGREGATS}${TEMPAGGS}"
|
|
TEMPSUM="!!! ip prefix-list WITv4-SUMMARIES seq $((i*5)) permit ${TEMP}\n"
|
|
FRR_IPV4_EDGE_SUMMARIES_PFLIST="${FRR_IPV4_EDGE_SUMMARIES_PFLIST}${TEMPSUM}"
|
|
let i+=1
|
|
done
|
|
|
|
i=1
|
|
while true; do
|
|
TEMP="$(dig_txt $i.ipv6.public.prefixlist.$DOMAINNAME)" || break
|
|
TEMPAGGS=" !!! aggregate-address ${TEMP}\n"
|
|
FRR_IPV6_EDGE_SUMMARIES_AGGREGATS="${FRR_IPV6_EDGE_SUMMARIES_AGGREGATS}${TEMPAGGS}"
|
|
TEMPSUM="!!! ipv6 prefix-list WITv6-SUMMARIES seq $((i*5)) permit ${TEMP}\n"
|
|
FRR_IPV6_EDGE_SUMMARIES_PFLIST="${FRR_IPV6_EDGE_SUMMARIES_PFLIST}${TEMPSUM}"
|
|
let i+=1
|
|
done
|
|
|
|
|
|
## compile customer IP blocks that we accept. this in theory should be a combination of *all* public blocks used accross regions while limiting it a smaller subnet size
|
|
i=1
|
|
while true; do
|
|
TEMP="$(dig_txt $i.ipv4.customers.prefixlist.$DOMAINNAME)" || break
|
|
TEMPSUM="ip prefix-list WITv4-CUSTOMERS seq $((i*5)) permit ${TEMP} ge 25\n"
|
|
FRR_IPV4_CUSTOMERS_PFLIST="${FRR_IPV4_CUSTOMERS_PFLIST}${TEMPSUM}"
|
|
let i+=1
|
|
done
|
|
|
|
i=1
|
|
while true; do
|
|
TEMP="$(dig_txt $i.ipv6.customers.prefixlist.$DOMAINNAME)" || break
|
|
TEMPSUM="ipv6 prefix-list WITv6-CUSTOMERS seq $((i*5)) permit ${TEMP} ge 64\n"
|
|
FRR_IPV6_CUSTOMERS_PFLIST="${FRR_IPV6_CUSTOMERS_PFLIST}${TEMPSUM}"
|
|
let i+=1
|
|
done
|
|
|
|
|
|
## compile loopback IP blocks that we wanna accept to be injected into the bgp
|
|
i=1
|
|
while true; do
|
|
TEMP="$(dig_txt $i.ipv4.loopback.prefixlist.$DOMAINNAME)" || break
|
|
TEMPSUM="ip prefix-list LOOPBACKv4 seq $((i*5)) permit ${TEMP} ge 32\n"
|
|
FRR_IPV4_LOOPBACK_PFLIST="${FRR_IPV4_LOOPBACK_PFLIST}${TEMPSUM}"
|
|
[ -z $IPSEC_IPV4_SUBNETS ] || IPSEC_IPV4_SUBNETS="${IPSEC_IPV4_SUBNETS},"
|
|
IPSEC_IPV4_SUBNETS="${IPSEC_IPV4_SUBNETS}${TEMP}"
|
|
let i+=1
|
|
done
|
|
|
|
i=1
|
|
while true; do
|
|
TEMP="$(dig_txt $i.ipv6.loopback.prefixlist.$DOMAINNAME)" || break
|
|
TEMPSUM="ipv6 prefix-list LOOPBACKv6 seq $((i*5)) permit ${TEMP} ge 128\n"
|
|
FRR_IPV6_LOOPBACK_PFLIST="${FRR_IPV6_LOOPBACK_PFLIST}${TEMPSUM}"
|
|
[ -z $IPSEC_IPV6_SUBNETS ] || IPSEC_IPV6_SUBNETS="${IPSEC_IPV6_SUBNETS},"
|
|
IPSEC_IPV6_SUBNETS="${IPSEC_IPV6_SUBNETS}${TEMP}"
|
|
let i+=1
|
|
done
|
|
|
|
[ -z $IPSEC_IPV4_SUBNETS ] && exit 2
|
|
[ -z $IPSEC_IPV6_SUBNETS ] && exit 2
|
|
|
|
## STOP compiling frr config
|
|
|
|
|
|
## START writing config files
|
|
|
|
|
|
# set frr config
|
|
sed -i \
|
|
-e "s/^!!! FRR_IFS/$FRR_IFS/" \
|
|
-e "s/^ !!! FRR_EDGE_NEIGH/$FRR_EDGE_NEIGH/" \
|
|
-e "s/^ !!! FRR_IPV4_EDGE_SUMMARIES_AGGREGATS/$FRR_IPV4_EDGE_SUMMARIES_AGGREGATS/" \
|
|
-e "s/^ !!! FRR_IPV6_EDGE_SUMMARIES_AGGREGATS/$FRR_IPV6_EDGE_SUMMARIES_AGGREGATS/" \
|
|
-e "s/^!!! FRR_IPV4_EDGE_SUMMARIES_PFLIST/$FRR_IPV4_EDGE_SUMMARIES_PFLIST/" \
|
|
-e "s/^!!! FRR_IPV6_EDGE_SUMMARIES_PFLIST/$FRR_IPV6_EDGE_SUMMARIES_PFLIST/" \
|
|
-e "s/^!!! FRR_IPV4_CUSTOMERS_PFLIST/$FRR_IPV4_CUSTOMERS_PFLIST/" \
|
|
-e "s/^!!! FRR_IPV6_CUSTOMERS_PFLIST/$FRR_IPV6_CUSTOMERS_PFLIST/" \
|
|
-e "s/^!!! FRR_IPV4_LOOPBACK_PFLIST/$FRR_IPV4_LOOPBACK_PFLIST/" \
|
|
-e "s/^!!! FRR_IPV6_LOOPBACK_PFLIST/$FRR_IPV6_LOOPBACK_PFLIST/" \
|
|
-e "s/BASTION-PUBLIC-IP/$BASTIONPUBLICIP/" \
|
|
-e "s/FRR_GRE_ASN/${FRR_GRE_ASN:=$NODEASN}/" \
|
|
-e "s/FRRROUTERID/${LOOPBACKv4}/" \
|
|
-e "s/LOOPBACK-IPV6/${LOOPBACKv6}/" \
|
|
-e "s/NODEASN/${NODEASN}/" \
|
|
$FRRCONFIG
|
|
[ -z $FRR_EDGE_NEIGH ] || sed -i -e 's/!!! //' $FRRCONFIG
|
|
[ -z $BASTIONPUBLICIP ] || sed -i -e 's/!!BASTION //' $FRRCONFIG
|
|
|
|
|
|
|
|
# set ipsec config
|
|
for IPSECCONFIGFILE in $IPSECCONFIG $SWANCTLCONFIG
|
|
do
|
|
sed -i \
|
|
-e "s/FQHOSTNAME/${HOSTNAME}/" \
|
|
-e "s/LOOPBACKv4/${LOOPBACKv4}\/32/" \
|
|
-e "s/LOOPBACKv6/${LOOPBACKv6}\/128/" \
|
|
-e "s/IPSEC_IPV4_SUBNETS/$IPSEC_IPV4_SUBNETS/" \
|
|
-e "s/IPSEC_IPV6_SUBNETS/$IPSEC_IPV6_SUBNETS/" \
|
|
$IPSECCONFIGFILE
|
|
done
|
|
|
|
cat <<-EOF >$IPSECSECRETS
|
|
# dynamic file, content is overwritten by wit-network-config. I'm sorry but divertion is not working due to apparmor blocking it to this place and didn't wanna deal with that
|
|
: RSA ${HOSTNAME}.key
|
|
EOF
|
|
|
|
## END config file section
|
|
|
|
|
|
## START configuring services as we need it
|
|
|
|
systemctl enable firewall
|
|
systemctl restart firewall
|
|
systemctl restart ssh
|
|
systemctl reload strongswan || true ## in case we kick-start or done have it enabled for some reason
|
|
|
|
sysctl -p $SYSCTLTWEAKS
|
|
|
|
## END services section
|
|
|
|
|
|
;;
|
|
|
|
abort-upgrade|abort-remove|abort-deconfigure)
|
|
;;
|
|
|
|
*)
|
|
echo "postinst called with unknown argument \`$1'" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# dh_installdeb will replace this with shell code automatically
|
|
# generated by other debhelper scripts.
|
|
|
|
#DEBHELPER#
|
|
|
|
exit 0
|