Skip to content

Instantly share code, notes, and snippets.

@ThinGuy
Last active April 6, 2018 06:13
Show Gist options
  • Save ThinGuy/0f47e7c51227aef1f5bfd631c8877b1f to your computer and use it in GitHub Desktop.
Save ThinGuy/0f47e7c51227aef1f5bfd631c8877b1f to your computer and use it in GitHub Desktop.
Build a private keyserver in a LXD container
#!/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