Last active
April 6, 2018 06:13
-
-
Save ThinGuy/0f47e7c51227aef1f5bfd631c8877b1f to your computer and use it in GitHub Desktop.
Build a private keyserver in a LXD container
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#Small function to give text status of OK/FAIL to commands | |
tstatus() { | |
RETCODE=$(echo $?) | |
[[ $RETCODE -eq 0 ]] && printf '\e['$(($(tput cols)-10))'G [ \e[32mOK\e[0m ]\n' | |
[[ $RETCODE -eq 1 ]] && printf '\e['$(($(tput cols)-10))'G [\e[31mFAIL\e[0m]\n' | |
return $RETCODE | |
} | |
#Optional - Create LXD profile so container rides on existing MaaS managed subnets | |
#Your subnets will vary as will the parent | |
# If you don't want to use the maas profile, remove the --profile=maas lines from lxc launch below | |
# If you use a traditional LXD bridge, make sure you put a route in on the MaaS subnet page so maas can tell the | |
# nodes how to get there. | |
[[ -n $(lxc 2>/dev/null profile show maas) ]] && { printf "Ensuring LXD profile \"maas\" is up to date"; } || { printf "Creating LXD profile \"maas\" is up to date";lxc profile create maas; } | |
cat << EOF|lxc profile edit maas | |
config: | |
description: MaaS managed LXD profile | |
devices: | |
eth0: | |
maas.subnet.ipv4: 172.27.20.0/23 | |
nictype: bridged | |
parent: br0 | |
type: nic | |
devices: | |
eth1: | |
maas.subnet.ipv4: 172.27.22.0/23 | |
nictype: bridged | |
parent: br1 | |
type: nic | |
root: | |
path: / | |
pool: default | |
type: disk | |
name: maas | |
EOF | |
tstatus | |
#When used with OPM (https://launchpad.net/opm), we are impersonating key server.ubuntu.com | |
export KS_FQDN=keyserver.ubuntu.com | |
printf "Creating LXD container \"${KS_FQDN%%.*}\" \n" | |
#Create LXD Container with local user's ssh key | |
lxc launch ubuntu-daily: ${KS_FQDN%%.*} --profile=maas -c user.user-data="$(printf '#cloud-config\nssh_authorized_keys:\n - '"$(cat ~/.ssh/id_rsa.pub)"'\n')" | |
while [[ -z $(lxc list ${KS_FQDN%%.*} -c4 --format=csv) ]];do printf "\rWaiting for ${KS_FQDN%%.*} to get an ip address...";sleep .5;done | |
export KS_IP=$(lxc list ${KS_FQDN%%.*} -c4 --format=csv|awk '{print $1}') | |
printf "\n${KS_FQDN%%.*} ip address = ${KS_IP}";tstatus | |
printf "\e[2G - Writing proper host file on LXD container ${KS_FQDN%%.*}" | |
cat << EOF|lxc exec ${KS_FQDN%%.*} -- tee 1>/dev/null /etc/hosts | |
127.0.0.1 localhost | |
${KS_IP} ${KS_FQDN} ${KS_FQDN%%.*} | |
# The following lines are desirable for IPv6 capable hosts | |
::1 ip6-localhost ip6-loopback | |
fe00::0 ip6-localnet | |
ff00::0 ip6-mcastprefix | |
ff02::1 ip6-allnodes | |
ff02::2 ip6-allrouters | |
EOF | |
tstatus | |
printf "\e[2G - Running apt update on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- sh -c "DEBIAN_FRONTEND=noninteractive apt 2>/dev/null update" >> /tmp/${0%%*.}.log 2>&1;tstatus | |
printf "\n\e[2G - Installing sks on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- sh -c "DEBIAN_FRONTEND=noninteractive apt 2>/dev/null install sks -yq" >> /tmp/${0%%*.}.log 2>&1;tstatus | |
printf "\e[2G - Installing nginx on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- sh -c "DEBIAN_FRONTEND=noninteractive apt 2>/dev/null install nginx -yq" >> /tmp/${0%%*.}.log 2>&1;tstatus | |
printf "\e[2G - Updating Ubuntu on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- sh -c "DEBIAN_FRONTEND=noninteractive apt 2>/dev/null dist-upgrade -yq" >> /tmp/${0%%*.}.log 2>&1;tstatus | |
printf "\n\e[2G - Stopping SKS Services on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- systemctl stop sks.service;tstatus | |
if [[ -d ${OPM_SKS_DUMP_DIR} ]];then | |
printf "\n\e[2G - Creating device for existing sks-dump directory on LXD container ${KS_FQDN%%.*}" | |
(lxc config device add ${KS_FQDN%%.*} sks-dump disk source=${OPM_SKS_DUMP_DIR} path=/var/lib/sks/dump|sed 's/^.*$/ - &/g' &);tstatus | |
elif [[ -n $(locate -r '^.*sks/dump$') && -d $(locate -r '^.*sks/dump$') ]];then | |
TMP_DUMP=$(locate -r '^.*sks/dump$') | |
if [[ $(find ${TMP_DUMP}/ -type f -iname "*.pgp"|wc -l) -ge 1 ]];then | |
printf "\n\e[2G - Creating device for existing sks-dump directory on LXD container ${KS_FQDN%%.*}" | |
(lxc config device add ${KS_FQDN%%.*} sks-dump disk source=${TMP_DUMP} path=/var/lib/sks/dump|sed 's/^.*$/ - &/g');tstatus | |
fi | |
fi | |
#There are two ways to build the database: | |
#fastbuild: Only an index of the keydump is created | |
# The keydump cannot be removed. | |
# Runtime ~ 30 minutes | |
#normalbuild: All the keydump will be imported in a new database. It takes longer" | |
# and used more disk space, but the server will run faster | |
# (depending on the source/age of the keydump). | |
# The keydump can be removed after the import | |
# Runtime > 1 hour | |
( | |
printf "\n\e[2GBuilding SKS database on LXD container ${KS_FQDN%%.*}\n" | |
printf "\e[2G - Fastbuild will take about 30 mintues.\n" | |
printf "\e[2G - Normalbuild will take over an hour\n\n" | |
printf "\e[2GYou can watch progress from another terminal with the following commands:\n" | |
printf "\n\\e[1mFastbuild:\e[0m\n" | |
printf "\n(\n" | |
printf "[[ -n \$(lxc exec ${KS_FQDN%%.*} -- pgrep -f \"sks fastbuild\" -o) ]] && lxc exec ${KS_FQDN%%.*} -- sh -c 'tail -f --pid=\$(pgrep -f \"sks fastbuild\" -o) /var/log/sks/fastbuild.log' \n" | |
printf "[[ -n \$(lxc exec ${KS_FQDN%%.*} -- pgrep -f \"sks cleandb\" -o) ]] && lxc exec ${KS_FQDN%%.*} -- sh -c 'tail -f --pid=\$(pgrep -f \"sks cleandb\" -o) /var/log/sks/clean.log' \n" | |
printf "[[ -n \$(lxc exec ${KS_FQDN%%.*} -- pgrep -f \"sks pbuild\" -o) ]] && lxc exec ${KS_FQDN%%.*} -- sh -c 'tail -f --pid=\$(pgrep -f \"sks pbuild\" -o) /var/log/sks/pbuild.log' \n" | |
printf ")\n\n" | |
printf "\n\\e[1mNormalbuild: \e[0m\n" | |
printf "\n(\n" | |
printf "[[ -n \$(lxc exec ${KS_FQDN%%.*} -- pgrep -f \"sks build\" -o) ]] && lxc exec ${KS_FQDN%%.*} -- sh -c 'tail -f --pid=\$(pgrep -f \"sks build\" -o) /var/log/sks/build.log' \n" | |
printf "[[ -n \$(lxc exec ${KS_FQDN%%.*} -- pgrep -f \"sks cleandb\" -o) ]] && lxc exec ${KS_FQDN%%.*} -- sh -c 'tail -f --pid=\$(pgrep -f \"sks cleandb\" -o) /var/log/sks/clean.log' \n" | |
printf "[[ -n \$(lxc exec ${KS_FQDN%%.*} -- pgrep -f \"sks pbuild\" -o) ]] && lxc exec ${KS_FQDN%%.*} -- sh -c 'tail -f --pid=\$(pgrep -f \"sks pbuild\" -o) /var/log/sks/pbuild.log' \n" | |
printf ")\n\n" | |
) | |
if [[ $(lxc exec ${KS_FQDN%%.*} -- sh -c "find /var/lib/sks/dump/ -type f -iname '*.pgp' |wc -l") -gt 1 && $(lxc config device list ${KS_FQDN%%.*}) = sks-dump ]];then | |
printf "\e[5G - Performing \"fastbuild\" of SKS database on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- su debian-sks -c 'cd /var/lib/sks/dump;/usr/sbin/sks fastbuild -n 25 -cache 1024';tstatus | |
printf "\e[5G - Cleaning SKS database on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- su debian-sks -c '/usr/sbin/sks cleandb';tstatus | |
printf "\e[5G - Building SKS prefix-tree database on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- su debian-sks -c '/usr/sbin/sks pbuild -cache 100 -ptree_cache 200';tstatus | |
printf "\e[1m\e[5G - SKS database build complete on LXD container ${KS_FQDN%%.*}\e[0m\n" | |
else | |
printf "\e[5G - Performing \"normalbuild\" of SKS database on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- su debian-sks -c 'cd /var/lib/sks/dump;/usr/sbin/sks build /var/lib/sks/dump/*.pgp -n 25 -cache 1024';tstatus | |
printf "\e[5G - Cleaning SKS database on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- su debian-sks -c '/usr/sbin/sks cleandb';tstatus | |
printf "\e[5G - Building SKS prefix-tree database on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- su debian-sks -c '/usr/sbin/sks pbuild -cache 100 -ptree_cache 200';tstatus | |
printf "\e[1m\e[5G - SKS database build complete on LXD container ${KS_FQDN%%.*}\e[0m\n" | |
fi | |
printf "\n\e[2G - Making our key server private\n" | |
printf "\e[4G - Instructing SKS not to talk perform mailsync" | |
printf '# Empty - Do not communicate with other keyservers.\n'|lxc exec ${KS_FQDN%%.*} -- tee 1>/dev/null /etc/sks/mailsync;tstatus | |
printf "\e[4G - Instructing SKS not to talk participate in memberships" | |
printf '# Empty - Do not communicate with other keyservers.\n'|lxc exec ${KS_FQDN%%.*} -- tee 1>/dev/null /etc/sks/membership;tstatus | |
printf "\n\e[2G - Configuring SKS Options on ${KS_FQDN}" | |
cat << EOF | lxc exec ${KS_FQDN%%.*} -- tee 1>/dev/null /etc/sks/sksconf | |
hostname: ${KS_FQDN} | |
pagesize: 16 | |
ptree_pagesize: 16 | |
EOF | |
tstatus | |
printf "\e[2G - Enabling SKS service on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- systemctl enable sks.service >> /tmp/${0%%*.}.log 2>&1;tstatus | |
printf "\e[2G - Setting SKS to autostart on LXD container ${KS_FQDN%%.*}" | |
printf 'initstart=yes\n'|lxc exec ${KS_FQDN%%.*} -- tee 1>/dev/null /etc/default/sks;tstatus | |
printf "\e[2G - Starting SKS service on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- service sks start >> /tmp/${0%%*.}.log | |
lxc exec ${KS_FQDN%%.*} -- systemctl start sks.service >> /tmp/${0%%*.}.log 2>&1;tstatus | |
printf "\n\e[2G - Enabling SKS service to listen on port 80 via nginx" | |
cat <<EOF|lxc exec ${KS_FQDN%%.*} -- tee 1>/dev/null /etc/nginx/sites-available/default | |
server { | |
listen 80 default_server; | |
listen [::]:80 default_server; | |
server_name ${KS_FQDN} ${KS_FQDN%%.*} ${KS_IP} localhost; | |
root /var/www/html; | |
rewrite ^/stats /lookup?op=stats; | |
rewrite ^/s/(.*) /lookup?search=\$1; | |
rewrite ^/search/(.*) /lookup?search=\$1; | |
rewrite ^/g/(.*) /lookup?op=get&search=\$1; | |
rewrite ^/get/(.*) /lookup?op=get&search=\$1; | |
rewrite ^/d/(.*) /lookup?op=get&options=mr&search=\$1; | |
rewrite ^/download/(.*) /lookup?op=get&options=mr&search=\$1; | |
location / { | |
proxy_pass http://127.0.0.1:11371; | |
proxy_pass_header Server; | |
add_header Via "1.1 --keyserver-hostname--:11371 (nginx)"; | |
proxy_ignore_client_abort on; | |
client_max_body_size 8m; | |
} | |
} | |
EOF | |
tstatus | |
printf "\e[2G - Restarting nginx service on LXD container ${KS_FQDN%%.*}" | |
lxc exec ${KS_FQDN%%.*} -- systemctl restart nginx >> /tmp/${0%%*.}.log 2>&1;tstatus | |
sleep 1 | |
printf "\n\e[2G - Importing keys from local keyring to the SKS OpenPGP Server on LXD container ${KS_FQDN%%.*}\n" | |
sleep 1 | |
for k in $(apt-key adv --list-public-keys --with-fingerprint --with-colons|awk -F: '/fpr/{print $(NF-1)}');do | |
KUID="$(apt-key finger ${k}|grep -oP '(?<=uid {18})[^$]+')" | |
printf "\e[4G - Importing key ${k}" | |
apt-key 2>/dev/null adv --send-key --keyserver ${KS_IP} ${k} >> /tmp/${0%%*.}.log 2>&1;tstatus | |
done | |
printf "\n\e[2G - Testing the SKS OpenPGP Server on LXD container ${KS_FQDN%%.*} - Searching for keys that contain Ubuntu\n" | |
printf "\e[4G - Command: \"apt-key adv --batch --search --keyserver ${KS_IP} --search-keys Ubuntu\"\n" | |
apt-key 2>/dev/null adv --batch --search --keyserver ${KS_IP} --search-keys Ubuntu|tail -n10 | |
[[ $? -eq 2 || $? -eq 0 ]] && { printf "\e[$((($(tput cols)-10)-13))G\e[2C - Result";true;tstatus; } || { printf "\e[$((($(tput cols)-10)-13))G\e[2C - Result";false;tstatus; } | |
printf "\n\e[2G - Testing web access to port 80 for ${KS_IP}" | |
[[ $(curl -sSL ${KS_IP}:80|/bin/grep -oP '(?<=title>)[^<]+') = "SKS OpenPGP Public Key Server" ]] && { true;tstatus; } || { false;tstatus; } | |
printf "\n\e[2G - Testing web access to port 11371 for ${KS_IP}" | |
[[ $(curl -sSL ${KS_IP}:11371|/bin/grep -oP '(?<=title>)[^<]+') = "SKS OpenPGP Public Key Server" ]] && { true;tstatus; } || { false;tstatus; } | |
printf "\n\e[2G\e[32mComplete!\e[0m\n" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment