diff --git a/network/dnscrypt-wrapper/README b/network/dnscrypt-wrapper/README index 4e30bb92d3..b21182469a 100644 --- a/network/dnscrypt-wrapper/README +++ b/network/dnscrypt-wrapper/README @@ -1,2 +1,5 @@ dnscrypt-wrapper is a server-side DNSCrypt proxy that adds DNSCrypt support to any name resolver. + +Be sure to read README.Slackware for information on configuring/running +dnscrypt-wrapper as a daemon! diff --git a/network/dnscrypt-wrapper/README.Slackware b/network/dnscrypt-wrapper/README.Slackware new file mode 100644 index 0000000000..0c162404a3 --- /dev/null +++ b/network/dnscrypt-wrapper/README.Slackware @@ -0,0 +1,48 @@ +Setup + +An init script and configuration file have been provided to run +dnscrypt-wrapper as a daemon. To configure dnscrypt-wrapper, edit +/etc/default/dnscrypt-wrapper with the desired settings. By default +dnscrypt-wrapper will run on 0.0.0.0 (all interfaces), port 53, forwarding DNS +queries to 8.8.8.8:53 (Google's DNS server). + +The configuration file is setup to use a dnscrypt user by default, and to +chroot into that user's home directory to maximize security. In order to use +the default configuration you should create a dnscrypt user and group with the +following commands: + + groupadd -g 293 dnscrypt + useradd -u 293 -g 293 -c "DNSCrypt" -d /run/dnscrypt -s /bin/false dnscrypt + +If you decide to use another user you should edit the CHROOTDIR and USER +options in /etc/default/dnscrypt-wrapper (there are example settings provided +for the user 'nobody'). + +dnscrypt-wrapper requires both provider and cryptographic public and secret +keys, and a provider certificate. These can all be generated manually (see +/usr/doc/dnscrypt-wrapper-@VERSION@/README.md ), or they can be generated +automatically by configuring /etc/default/dnscrypt-wrapper and running + + /etc/rc.d/rc.dnscrypt-wrapper generate-keys + /etc/rc.d/rc.dnscrypt-wrapper generate-cert + +You will need to note the provider key fingerprint(s) when running that +command, since clients will need it for verification. + +In order for clients to forward queries through dnscrypt-wrapper, they will +need to run dnscrypt-proxy configured to connect to the server running +dnscrypt-wrapper. + +To start dnscrypt-wrapper automatically at system start, add the following to +/etc/rc.d/rc.local: + + if [ -x /etc/rc.d/rc.dnscrypt-wrapper ]; then + /etc/rc.d/rc.dnscrypt-wrapper start + fi + +To properly stop dnscrypt-wrapper on system shutdown, add the following to +/etc/rc.d/rc.local_shutdown: + + if [ -x /etc/rc.d/rc.dnscrypt-wrapper ]; then + /etc/rc.d/rc.dnscrypt-wrapper stop + fi diff --git a/network/dnscrypt-wrapper/dnscrypt-wrapper.8 b/network/dnscrypt-wrapper/dnscrypt-wrapper.8 new file mode 100644 index 0000000000..66eb6c2802 --- /dev/null +++ b/network/dnscrypt-wrapper/dnscrypt-wrapper.8 @@ -0,0 +1,62 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. +.TH DNSCRYPT-WRAPPER "8" "October 2014" "dnscrypt-wrapper 0.1.12" "System Administration Utilities" +.SH NAME +dnscrypt-wrapper \- A server-side DNSCrypt proxy that adds DNSCrypt support to any name resolver. +.SH SYNOPSIS +.B dnscrypt-wrapper +[\fIoptions\fR] +.SH DESCRIPTION +.TP +\fB\-h\fR, \fB\-\-help\fR +show this help message and exit +.TP +\fB\-v\fR, \fB\-\-version\fR +show version info +.TP +\fB\-a\fR, \fB\-\-listen\-address=\fR +local address to listen (default: 0.0.0.0:53) +.TP +\fB\-r\fR, \fB\-\-resolver\-address=\fR +upstream dns resolver server () +.TP +\fB\-u\fR, \fB\-\-user=\fR +run as given user +.TP +\fB\-d\fR, \fB\-\-daemonize\fR +run as daemon (default: off) +.TP +\fB\-p\fR, \fB\-\-pidfile=\fR +pid stored file +.TP +\fB\-V\fR, \fB\-\-verbose\fR +show verbose logs (specify more \fB\-VVV\fR to increase verbosity) +.TP +\fB\-l\fR, \fB\-\-logfile=\fR +log file path (default: stdout) +.TP +\fB\-\-gen\-provider\-keypair\fR +generate provider key pair +.TP +\fB\-\-crypt\-publickey\-file=\fR +crypt public key file +.TP +\fB\-\-crypt\-secretkey\-file=\fR +crypt secret key file +.TP +\fB\-\-gen\-crypt\-keypair\fR +generate crypt key pair +.TP +\fB\-\-provider\-publickey\-file=\fR +provider public key file +.TP +\fB\-\-provider\-secretkey\-file=\fR +provider secret key file +.TP +\fB\-\-gen\-cert\-file\fR +generate pre\-signed certificate +.TP +\fB\-\-provider\-name=\fR +provider name +.TP +\fB\-\-provider\-cert\-file=\fR +use this to self\-serve cert file diff --git a/network/dnscrypt-wrapper/dnscrypt-wrapper.SlackBuild b/network/dnscrypt-wrapper/dnscrypt-wrapper.SlackBuild index 281868c49b..27d69d0bab 100644 --- a/network/dnscrypt-wrapper/dnscrypt-wrapper.SlackBuild +++ b/network/dnscrypt-wrapper/dnscrypt-wrapper.SlackBuild @@ -22,9 +22,12 @@ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# Thanks to Larry Hajali for the logrotate configuration and the help2man +# suggestion. + PRGNAM=dnscrypt-wrapper VERSION=${VERSION:-0.1.12} -BUILD=${BUILD:-1} +BUILD=${BUILD:-2} TAG=${TAG:-_SBo} if [ -z "$ARCH" ]; then @@ -106,14 +109,26 @@ make install BINDIR=$PKG/usr/bin find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \ | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true +# Man page made by help2man +mkdir -p $PKG/usr/man/man8 +gzip -9c $CWD/$PRGNAM.8 > $PKG/usr/man/man8/$PRGNAM.8.gz + +mkdir -p $PKG/var/{lib,run,log}/$PRGNAM $PKG/etc/default +chmod 0700 $PKG/var/{lib,run,log}/$PRGNAM +sed "s/@VERSION@/$VERSION/" $CWD/$PRGNAM.default > $PKG/etc/default/$PRGNAM.new +install -D -m 0755 $CWD/rc.$PRGNAM $PKG/etc/rc.d/rc.$PRGNAM.new +install -D -m 0644 $CWD/$PRGNAM.logrotate $PKG/etc/logrotate.d/$PRGNAM.new + mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION cp -a \ COPYING DOCS README.md TODO \ $PKG/usr/doc/$PRGNAM-$VERSION +sed "s/@VERSION@/$VERSION/g" $CWD/README.Slackware > $PKG/usr/doc/$PRGNAM-$VERSION/README.Slackware cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild mkdir -p $PKG/install cat $CWD/slack-desc > $PKG/install/slack-desc +cat $CWD/doinst.sh > $PKG/install/doinst.sh cd $PKG /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz} diff --git a/network/dnscrypt-wrapper/dnscrypt-wrapper.default b/network/dnscrypt-wrapper/dnscrypt-wrapper.default new file mode 100644 index 0000000000..4d97d997d2 --- /dev/null +++ b/network/dnscrypt-wrapper/dnscrypt-wrapper.default @@ -0,0 +1,70 @@ +# /etc/default/dnscrypt-wrapper + +# This file contains the configuration settings for dnscrypt-wrapper. In the +# unusual event that you may wish to run multiple instances on the same +# machine, this file supports configuring and running multiple instances (see +# the bottom of this file for a sample secondary configuration). + +# CHROOTDIR should be the same path as the USER's home directory. +# For the standard dnscrypt user this should be "/run/dnscrypt". For nobody, +# this should be "/". +CHROOTDIR[0]="/run/dnscrypt" +#CHROOTDIR[0]="/" + +# The address and (optional) port to listen on. The default port is 53. +LISTENADDRESS[0]="0.0.0.0:53" + +# The pid file for this instance. PIDFILE must always be specified for each +# instance! +PIDFILE[0]="/var/run/dnscrypt-wrapper/dnscrypt-wrapper-0.pid" + +# Runs the daemon as the following user and chroots to that user's home +# directory (this is a security feature -- it is best not to change this!) +USER[0]="dnscrypt" +#USER[0]="nobody" + +# If DNSCRYPTDIR is set, it will look for files crypt_public.key, +# crypt_secret.key, public.key, and secret.key in the specified directory. +# CRYPTPUBLICKEYFILE, CRYPTSECRETKEYFILE, PROVIDERPUBLICKEYFILE and +# PROVIDERSECRETKEYFILE will be ignored. +DNSCRYPTDIR[0]="/var/lib/dnscrypt-wrapper" + +# Or, if DNSCRYPTDIR is unset, you can specify those files manually. +#CRYPTPUBLICKEYFILE[0]="/var/lib/dnscrypt-wrapper/crypt_public.key" +#CRYPTSECRETKEYFILE[0]="/var/lib/dnscrypt-wrapper/crypt_secret.key" +#PROVIDERPUBLICKEYFILE[0]="/var/lib/dnscrypt-wrapper/public.key" +#PROVIDERSECRETKEYFILE[0]="/var/lib/dnscrypt-wrapper/secret.key" + +# PROVIDERNAME is the fully qualified domain name that identifies the server. +# For a LAN service the first example should work (you should replace hostname +# with your actual hostname since it will be used by clients). For a public +# service you should use a real domain like the second example. +PROVIDERNAME[0]="2.dnscrypt-cert.hostname.localdomain" +#PROVIDERNAME[0]="2.dnscrypt-cert.example.com" + +# PROVIDERCERTFILE is the location of the pre-signed certificate generated. If +# you are running a public service, it may be desirable to omit this option and +# instead store the generated pre-signed certificate (binary string) in a TXT +# record for your provider name (set by PROVIDERNAME above) so that the +# certificate will be provided by a nameserver instead of directly by +# dnscrypt-wrapper. See /usr/doc/dnscrypt-wrapper-@VERSION@/README.md for more. +PROVIDERCERTFILE[0]="/var/lib/dnscrypt-wrapper/dnscrypt.cert" + +# The address of the DNS resolver to use to forward requests. You will probably +# want to change this! If you run your own nameserver (or forwarder) you should +# point it there. You may wish to use the nameserver from /etc/resolv.conf. +RESOLVERADDRESS[0]="8.8.8.8:53" + +# Where to log. +LOGFILE[0]="/var/log/dnscrypt-wrapper/dnscrypt-wrapper.log" + +# A simple example configuration for a second instance +#CHROOTDIR[1]="/run/dnscrypt" +#LISTENADDRESS[1]="0.0.0.0:5353" +#PIDFILE[1]="/var/run/dnscrypt-wrapper/dnscrypt-wrapper-1.pid" +#USER[1]="dnscrypt" +#DNSCRYPTDIR[1]="/var/lib/dnscrypt-wrapper/1" +#PROVIDERNAME[1]="2.dnscrypt-cert.hostname.localdomain" +#PROVIDERCERTFILE[1]="/var/lib/dnscrypt-wrapper/1/dnscrypt.cert" +#RESOLVERADDRESS[1]="8.8.8.8:53" +#LOGFILE[1]="/var/log/dnscrypt-wrapper/dnscrypt-wrapper-1.log" diff --git a/network/dnscrypt-wrapper/dnscrypt-wrapper.logrotate b/network/dnscrypt-wrapper/dnscrypt-wrapper.logrotate new file mode 100644 index 0000000000..509e1ab02f --- /dev/null +++ b/network/dnscrypt-wrapper/dnscrypt-wrapper.logrotate @@ -0,0 +1,9 @@ +/var/log/dnscrypt-wrapper/*log { + weekly + rotate 7 + copytruncate + delaycompress + compress + notifempty + missingok +} diff --git a/network/dnscrypt-wrapper/doinst.sh b/network/dnscrypt-wrapper/doinst.sh new file mode 100644 index 0000000000..2ef019c771 --- /dev/null +++ b/network/dnscrypt-wrapper/doinst.sh @@ -0,0 +1,27 @@ +config() { + NEW="$1" + OLD="$(dirname $NEW)/$(basename $NEW .new)" + # If there's no config file by that name, mv it over: + if [ ! -r $OLD ]; then + mv $NEW $OLD + elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then + # toss the redundant copy + rm $NEW + fi + # Otherwise, we leave the .new copy for the admin to consider... +} + +preserve_perms() { + NEW="$1" + OLD="$(dirname $NEW)/$(basename $NEW .new)" + if [ -e $OLD ]; then + cp -a $OLD ${NEW}.incoming + cat $NEW > ${NEW}.incoming + mv ${NEW}.incoming $NEW + fi + config $NEW +} + +preserve_perms etc/rc.d/rc.dnscrypt-wrapper.new +config etc/default/dnscrypt-wrapper.new +config etc/logrotate.d/dnscrypt-wrapper.new diff --git a/network/dnscrypt-wrapper/rc.dnscrypt-wrapper b/network/dnscrypt-wrapper/rc.dnscrypt-wrapper new file mode 100644 index 0000000000..4f84021dd3 --- /dev/null +++ b/network/dnscrypt-wrapper/rc.dnscrypt-wrapper @@ -0,0 +1,262 @@ +#!/bin/bash + +CONFIGFILE="/etc/default/dnscrypt-wrapper" +DAEMON="/usr/bin/dnscrypt-wrapper" + +. $CONFIGFILE + +start_instance() { + if [ -z ${PIDFILE[$1]} ]; then + echo "No configuration for instance $1 found!" + return + fi + if [ -r ${PIDFILE[$1]} ]; then + PID=$(cat ${PIDFILE[$1]}) + if [ -z "$PID" ] || ! kill -0 $PID ; then + echo "Removing stale PID file..." + rm -f ${PIDFILE[$1]} + else + echo "dnscrypt-wrapper (instance $1) already running!" + return + fi + fi + + # dnscrypt-wrapper will NOT work without this. /dev/urandom is required in + # the chroot. + if [ -n "${CHROOTDIR[$1]}" ]; then + if [ "$(readlink -f ${CHROOTDIR[$1]})" != "/" ]; then + if [ ! -d ${CHROOTDIR[$1]} ]; then + mkdir -p ${CHROOTDIR[$1]} + chmod 755 ${CHROOTDIR[$1]} + fi + if [ ! -d ${CHROOTDIR[$1]}/dev ]; then + mkdir -p ${CHROOTDIR[$1]}/dev + chmod 755 ${CHROOTDIR[$1]}/dev + fi + if [ ! -c ${CHROOTDIR[$1]}/dev/urandom ]; then + mknod -m 666 ${CHROOTDIR[$1]}/dev/urandom c 1 9 + fi + fi + fi + + OPTIONS="-d" + if [ -n "${LISTENADDRESS[$1]}" ]; then + OPTIONS="${OPTIONS} --listen-address=${LISTENADDRESS[$1]}" + fi + if [ -n "${PIDFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --pidfile=${PIDFILE[$1]}" + fi + if [ -n "${USER[$1]}" ]; then + OPTIONS="${OPTIONS} --user=${USER[$1]}" + fi + if [ -n "${DNSCRYPTDIR[$1]}" ]; then + OPTIONS="${OPTIONS} --crypt-publickey-file=${DNSCRYPTDIR[$1]}/crypt_public.key" + OPTIONS="${OPTIONS} --crypt-secretkey-file=${DNSCRYPTDIR[$1]}/crypt_secret.key" + OPTIONS="${OPTIONS} --provider-publickey-file=${DNSCRYPTDIR[$1]}/public.key" + OPTIONS="${OPTIONS} --provider-secretkey-file=${DNSCRYPTDIR[$1]}/secret.key" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${CRYPTPUBLICKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --crypt-publickey-file=${CRYPTPUBLICKEYFILE[$1]}" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${CRYPTSECRETKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --crypt-secretkey-file=${CRYPTSECRETKEYFILE[$1]}" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${PROVIDERPUBLICKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --provider-publickey-file=${PROVIDERPUBLICKEYFILE[$1]}" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${PROVIDERSECRETKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --provider-secretkey-file=${PROVIDERSECRETKEYFILE[$1]}" + fi + if [ -n "${RESOLVERADDRESS[$1]}" ]; then + OPTIONS="${OPTIONS} --resolver-address=${RESOLVERADDRESS[$1]}" + fi + if [ -n "${PROVIDERNAME[$1]}" ]; then + OPTIONS="${OPTIONS} --provider-name=${PROVIDERNAME[$1]}" + fi + if [ -n "${PROVIDERCERTFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --provider-cert-file=${PROVIDERCERTFILE[$1]}" + fi + if [ -n "${LOGFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --logfile=${LOGFILE[$1]}" + fi + $DAEMON $OPTIONS +} + +stop_instance() { + if [ -z ${PIDFILE[$1]} ]; then + echo "No configuration for instance $1 found!" + return + fi + if [ ! -r ${PIDFILE[$1]} ]; then + echo "dnscrypt-wrapper (instance $1) is not running!" + return + fi + echo "Stopping dnscrypt-wrapper (instance $1)..." + kill $(cat ${PIDFILE[$1]}) + rm -f ${PIDFILE[$1]} +} + +status_instance() { + if [ -z ${PIDFILE[$1]} ]; then + echo "No configuration for instance $1 found!" + return + fi + if [ ! -r ${PIDFILE[$1]} ]; then + echo "dnscrypt-wrapper (instance $1) is not running." + return + fi + PID=$(cat ${PIDFILE[$1]}) + if [ -z "$PID" ]; then + echo "PID file is empty! dnscrypt-wrapper (instance $1) does not appear to be running, but there is a stale PID file." + elif kill -0 $PID ; then + echo "dnscrypt-wrapper (instance $1) is running." + else + echo "dnscrypt-wrapper (instance $1) is not running, but there is a stale PID file." + fi +} + +generate-keys_instance() { + if [ -z ${PIDFILE[$1]} ]; then + echo "No configuration for instance $1 found!" + return + fi + if [ -z ${DNSCRYPTDIR[$1]} ]; then + echo "DNSCRYPTDIR not set for instance $1! Either set DNSCRYPTDIR or generate keys manually." + return + fi + ( + echo "Generating keys for instance $1. You should record the fingerprint, since this will be used by clients." + cd ${DNSCRYPTDIR[$1]} + rm -f crypt_secret.key crypt_public.key public.key secret.key + $DAEMON --gen-provider-keypair + $DAEMON --gen-crypt-keypair + chmod 0600 crypt_secret.key crypt_public.key public.key secret.key + ) +} + +generate-cert_instance() { + if [ -z ${PIDFILE[$1]} ]; then + echo "No configuration for instance $1 found!" + return + fi + if [ -z ${PROVIDERCERTFILE[$1]} ]; then + echo "PROVIDERCERTFILE for instance $1 not set! Set PROVIDERCERTFILE before generating a certificate." + return + fi + OPTIONS="" + if [ -n "${DNSCRYPTDIR[$1]}" ]; then + OPTIONS="${OPTIONS} --crypt-publickey-file=${DNSCRYPTDIR[$1]}/crypt_public.key" + OPTIONS="${OPTIONS} --crypt-secretkey-file=${DNSCRYPTDIR[$1]}/crypt_secret.key" + OPTIONS="${OPTIONS} --provider-publickey-file=${DNSCRYPTDIR[$1]}/public.key" + OPTIONS="${OPTIONS} --provider-secretkey-file=${DNSCRYPTDIR[$1]}/secret.key" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${CRYPTPUBLICKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --crypt-publickey-file=${CRYPTPUBLICKEYFILE[$1]}" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${CRYPTSECRETKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --crypt-secretkey-file=${CRYPTSECRETKEYFILE[$1]}" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${PROVIDERPUBLICKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --provider-publickey-file=${PROVIDERPUBLICKEYFILE[$1]}" + fi + if [ -z "${DNSCRYPTDIR[$1]}" ] && [ -n "${PROVIDERSECRETKEYFILE[$1]}" ]; then + OPTIONS="${OPTIONS} --provider-secretkey-file=${PROVIDERSECRETKEYFILE[$1]}" + fi + ( + echo "Generating certificate for instance $1." + mkdir /tmp/dnscrypt-wrapper-$$ + cd /tmp/dnscrypt-wrapper-$$ + $DAEMON $OPTIONS --gen-cert-file + chmod 0600 dnscrypt.cert + mv -f dnscrypt.cert ${PROVIDERCERTFILE[$1]} + cd / + rmdir /tmp/dnscrypt-wrapper-$$ + ) +} + +start() { + for i in `/usr/bin/seq 0 $((${#PIDFILE[@]}-1))` + do + start_instance $i + done +} + +stop() { + for i in `/usr/bin/seq 0 $((${#PIDFILE[@]}-1))` + do + stop_instance $i + done +} + +status() { + for i in `/usr/bin/seq 0 $((${#PIDFILE[@]}-1))` + do + status_instance $i + done +} + +generate-keys() { + for i in `/usr/bin/seq 0 $((${#PIDFILE[@]}-1))` + do + generate-keys_instance $i + done +} + +generate-cert() { + for i in `/usr/bin/seq 0 $((${#PIDFILE[@]}-1))` + do + generate-cert_instance $i + done +} + +case "$1" in + 'start') + start + ;; + 'stop') + stop + ;; + 'restart') + stop + start + ;; + 'status') + status + ;; + 'generate-keys') + generate-keys + ;; + 'generate-cert') + generate-cert + ;; + *_start) + INSTANCE=`echo $1 | /bin/cut -d '_' -f 1` + start_instance $INSTANCE + ;; + *_stop) + INSTANCE=`echo $1 | /bin/cut -d '_' -f 1` + stop_instance $INSTANCE + ;; + *_restart) + INSTANCE=`echo $1 | /bin/cut -d '_' -f 1` + stop_instance $INSTANCE + sleep 1 + start_instance $INSTANCE + ;; + *_status) + INSTANCE=`echo $1 | /bin/cut -d '_' -f 1` + status_instance $INSTANCE + ;; + *_generate-keys) + INSTANCE=`echo $1 | /bin/cut -d '_' -f 1` + generate-keys_instance $INSTANCE + ;; + *_generate-cert) + INSTANCE=`echo $1 | /bin/cut -d '_' -f 1` + generate-cert_instance $INSTANCE + ;; + *) + echo "Usage: $0 {start|stop|restart|status|generate-keys|generate-cert|#_start|#_stop|#_restart|#_status|#_generate-keys|#_generate-cert}" + exit 1 + ;; +esac