#!/bin/bash # # vim: set et ts=4: # # run-lxc.sh # sets up an lxc environment for ospf over openvpn # must be run as root as lxc requires root privileges # make sure lxc is started before running this script # # copyright (c) 2019 Philippe Kueck # set -xe rpm -q lxc lxc-templates bridge-utils busybox sampleurl="https://www.unixadm.org/needful-things/openvpn-ospf" lxcdir="/var/lib/lxc" tmp=$(mktemp -d) trap "rm -rf ${tmp}" 0 1 2 15 declare -A aldebaran declare -A beteigeuze declare -A castor # node configuration aldebaran=( ["server"]="sagittarius aquarius draco" ["eth0"]="10.10.1.1" ["eth1"]="192.168.1.1 fd01:c0:a801::1" ) beteigeuze=( ["server"]="columba" ["client"]="sagittarius" ["eth0"]="10.20.2.2" ["eth1"]="192.168.2.1 fd01:c0:a802::1" ) castor=( ["client"]="columba aquarius" ["eth0"]="10.30.3.3" ["eth1"]="192.168.3.1 fd01:c0:a803::1" ) # create a dummy virtual interface for the node's interconnection brctl show ospfovpn0 2>/dev/null || brctl addbr ospfovpn0 ip link set ospfovpn0 up # start from scratch, create a centos-lxc as template lxc-destroy -n ospf_over_openvpn || true lxc-create -n ospf_over_openvpn -t download -- -d centos -r 7 -a amd64 # install openvpn and frr thislx="${lxcdir}/ospf_over_openvpn" mount --bind /dev "${thislx}/rootfs/dev" yum -c "${thislx}/rootfs/etc/yum.conf" --installroot="${thislx}/rootfs" \ install -y \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \ https://reposerv.unixadm.org/rhel/7/ux/x86_64/ux-release-0.18-1.el7.noarch.rpm chroot "${thislx}/rootfs" rpm --import \ /etc/pki/rpm-gpg/RPM-GPG-KEY-UNIXADM /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 yum -c "${thislx}/rootfs/etc/yum.conf" --installroot="${thislx}/rootfs" \ upgrade -y yum -c "${thislx}/rootfs/etc/yum.conf" --installroot="${thislx}/rootfs" \ install -y openvpn frr wireshark umount "${thislx}/rootfs/dev" # configure the lxc container to # - use the dummy virtual interface # - add another dummy interface for the local network # - allow creating tun devices sed -i -r -e 's/^(lxc\.net\.0\.link)\s*=.*/\1 = ospfovpn0/' \ "${thislx}/config" cat >> "${thislx}/config" < "${thislx}/rootfs/etc/sysconfig/network-scripts/ifcfg-${i}" <> "${thislx}/rootfs/etc/sysconfig/network-scripts/ifcfg-${i}" < "${thislx}/rootfs/etc/sysconfig/network-scripts/route-eth0" } # function to setup the node's vpn configurations setup_vpn() { thislx="${lxcdir}/$1" declare -nl ptr="$1" for role in ${!ptr[@]}; do case "${role}" in server|client) ;; *) continue ;; esac for vpn in ${ptr[$role]}; do # generate shared key on the fly [[ -e "${tmp}/${vpn}.key" ]] || \ openvpn --genkey --secret "${tmp}/${vpn}.key" install -m0600 "${tmp}/${vpn}.key" \ "${thislx}/rootfs/etc/openvpn/${role}/${vpn}.key" # fetch vpn config from my website install -Dm0600 \ <(curl -s "${sampleurl}/${1}-${vpn}.conf") \ "${thislx}/rootfs/etc/openvpn/${role}/${vpn}.conf" # systemctl enable openvpn-$role@$vpn.service ln -s "/usr/lib/systemd/system/openvpn-${role}@.service" \ "${thislx}/rootfs/etc/systemd/system/multi-user.target.wants/openvpn-${role}@${vpn}.service" done done } # function to setup the node's frr configuration setup_frr() { thislx="${lxcdir}/$1" for service in zebra ospfd ospf6d; do install -Dm0600 -o 92 -g 92 \ <(curl -s "${sampleurl}/${1}-${service}.conf") \ "${thislx}/rootfs/etc/frr/${service}.conf" done # systemctl enable zebra ospfd ospf6d ln -s "/usr/lib/systemd/system/zebra.service" \ "${thislx}/rootfs/etc/systemd/system/multi-user.target.wants/zebra.service" mkdir -p "${thislx}/rootfs/etc/systemd/system/zebra.service.wants" for service in ospfd ospf6d; do ln -s "/usr/lib/systemd/system/${service}.service" \ "${thislx}/rootfs/etc/systemd/system/zebra.service.wants/${service}.service" done } for node in aldebaran beteigeuze castor; do # start from scratch, create container from the tiny busybox template lxc-destroy -n ${node} || true lxc-create -n ${node} -t busybox # ... and hardlink the rootfs from the ospf_over_openvpn template rm -rf "${lxcdir}/${node}/rootfs" cp -dprl "${lxcdir}/ospf_over_openvpn/rootfs" "${lxcdir}/${node}/rootfs" # adapt lxc's configuration file sed -i -n -r -e '/^lxc\.(uts\.name|rootfs\.path)/p' \ "${lxcdir}/${node}/config" sed -r -e '/^lxc\.(uts\.name|rootfs\.path|net\.[0-9]\.hwaddr)/d' \ "${lxcdir}/ospf_over_openvpn/config" >> "${lxcdir}/${node}/config" setup_network ${node} setup_vpn ${node} setup_frr ${node} lxc-start -n ${node} done