Skip to content

Instantly share code, notes, and snippets.

@sebastianknopf
Last active June 8, 2026 09:04
Show Gist options
  • Select an option

  • Save sebastianknopf/7e9031a585baf80dfd606acd0cce4c75 to your computer and use it in GitHub Desktop.

Select an option

Save sebastianknopf/7e9031a585baf80dfd606acd0cce4c75 to your computer and use it in GitHub Desktop.
mthk-setup

mthk-setup

This utility script generates X509 certificates out of the PKCS12 certificate issued by Mobilithek for client and server authentification. Optinally, the certificates can be installed at the correct location depending on your Linux distribution used. The setup is also able to generate a virtual host with Apache or Nginx.

Prerequisites

  • Linux distributed OS
  • OpenSSL for certificate and key extraction
  • Apache/Nginx for generating a VHost

Usage

Extract certificate, chain and unprotected key: ./mthk-setup <pkcs12-file>

Extract and install certificates: ./mthk-setup --install <pkcs12-file>

Extract, install and create reverse proxy at port 443: ./mthk-setup --install <pkcs12-file> <hostname> <target-port>

Extract, install and create reverse proxy at different port: ./mthk-setup --install <pkcs12-file> <hostname> <target-port> <external-port>

Links

#!/usr/bin/env bash
set -euo pipefail
###############################################################################
# Usage
###############################################################################
usage() {
cat <<EOF
Usage:
Extract certificate, chain and unprotected key:
$0 <pkcs12-file>
Extract and install certificates:
$0 --install <pkcs12-file>
Extract, install and create reverse proxy at port 443:
$0 --install <pkcs12-file> <hostname> <target-port>
Extract, install and create reverse proxy at different port:
$0 --install <pkcs12-file> <hostname> <target-port> <external-port>
EOF
}
###############################################################################
# Parameter
###############################################################################
INSTALL_MODE=false
if [[ "${1:-}" == "--install" ]]; then
INSTALL_MODE=true
shift
fi
if [[ $# -ne 1 && $# -ne 3 && $# -ne 4 ]]; then
usage
exit 1
fi
P12_FILE="$1"
if [[ ! -f "$P12_FILE" ]]; then
echo "File not found: $P12_FILE"
exit 1
fi
CREATE_VHOST=false
if [[ $# -ge 3 ]]; then
CREATE_VHOST=true
HOSTNAME="$2"
TARGET_PORT="$3"
EXTERNAL_PORT="${4:-443}"
fi
if ! $INSTALL_MODE && $CREATE_VHOST; then
echo "Reverse proxy creation requires --install."
usage
exit 1
fi
P12_DIR="$(cd "$(dirname "$P12_FILE")" && pwd)"
P12_NAME="$(basename "$P12_FILE")"
P12_BASE="${P12_NAME%.*}"
OUTPUT_CERT="${P12_DIR}/${P12_BASE}.crt"
OUTPUT_CHAIN="${P12_DIR}/${P12_BASE}-chain.pem"
OUTPUT_KEY="${P12_DIR}/${P12_BASE}.key"
###############################################################################
# Root Check
###############################################################################
if $INSTALL_MODE && [[ $EUID -ne 0 ]]; then
echo "Please run as root when using --install."
exit 1
fi
###############################################################################
# Password
###############################################################################
read -rsp "PKCS12 Password: " P12_PASSWORD
echo
export P12_PASSWORD
# Prevent interactive prompts when exporting the encrypted private key.
KEY_EXPORT_PASSWORD="mthk-setup"
export KEY_EXPORT_PASSWORD
###############################################################################
# Workdir
###############################################################################
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
###############################################################################
# Install Paths and Detection
###############################################################################
if $INSTALL_MODE; then
if [[ -f /etc/debian_version ]]; then
DISTRO="debian"
SSL_CERT_DIR="/etc/ssl/certs"
SSL_KEY_DIR="/etc/ssl/private"
elif [[ -f /etc/redhat-release ]]; then
DISTRO="rhel"
SSL_CERT_DIR="/etc/pki/tls/certs"
SSL_KEY_DIR="/etc/pki/tls/private"
elif grep -qi suse /etc/os-release 2>/dev/null; then
DISTRO="suse"
SSL_CERT_DIR="/etc/ssl/certs"
SSL_KEY_DIR="/etc/ssl/private"
else
echo "Unsupported Linux distribution"
exit 1
fi
M2M_CERT="${SSL_CERT_DIR}/mobilithek.info-m2m.crt"
M2M_CHAIN="${SSL_CERT_DIR}/mobilithek.info-ca-chain.pem"
M2M_KEY="${SSL_KEY_DIR}/mobilithek.info-m2m.key"
WEBSERVER=""
APACHE_FOUND=false
NGINX_FOUND=false
if command -v apache2 >/dev/null 2>&1 || command -v httpd >/dev/null 2>&1; then
APACHE_FOUND=true
fi
if command -v nginx >/dev/null 2>&1; then
NGINX_FOUND=true
fi
if $CREATE_VHOST; then
if $APACHE_FOUND && $NGINX_FOUND; then
echo
echo "Both Apache and Nginx detected."
echo
select ws in apache nginx; do
WEBSERVER="$ws"
break
done
elif $APACHE_FOUND; then
WEBSERVER="apache"
elif $NGINX_FOUND; then
WEBSERVER="nginx"
else
echo "Neither Apache nor Nginx found."
exit 1
fi
fi
fi
###############################################################################
# Extract Client Certificate
###############################################################################
echo "Extracting certificate..."
openssl pkcs12 \
-in "$P12_FILE" \
-passin env:P12_PASSWORD \
-clcerts \
-nokeys \
-out "${TMPDIR}/m2m.crt"
###############################################################################
# Extract Certificate Chain
###############################################################################
echo "Extracting certificate chain..."
openssl pkcs12 \
-in "$P12_FILE" \
-passin env:P12_PASSWORD \
-cacerts \
-nokeys \
-out "${TMPDIR}/m2m-chain.pem"
###############################################################################
# Extract Private Key
###############################################################################
echo "Extracting private key..."
openssl pkcs12 \
-in "$P12_FILE" \
-passin env:P12_PASSWORD \
-passout env:KEY_EXPORT_PASSWORD \
-nocerts \
-out "${TMPDIR}/encrypted.key"
###############################################################################
# Remove Password
###############################################################################
echo "Removing passphrase..."
openssl rsa \
-in "${TMPDIR}/encrypted.key" \
-passin env:KEY_EXPORT_PASSWORD \
-out "${TMPDIR}/m2m.key"
###############################################################################
# Export
###############################################################################
echo "Writing extracted files next to PKCS12 file..."
install -m 644 \
"${TMPDIR}/m2m.crt" \
"$OUTPUT_CERT"
install -m 644 \
"${TMPDIR}/m2m-chain.pem" \
"$OUTPUT_CHAIN"
install -m 600 \
"${TMPDIR}/m2m.key" \
"$OUTPUT_KEY"
###############################################################################
# Install
###############################################################################
if $INSTALL_MODE; then
echo "Installing certificates..."
install -o root -g root -m 644 \
"$OUTPUT_CERT" \
"$M2M_CERT"
install -o root -g root -m 644 \
"$OUTPUT_CHAIN" \
"$M2M_CHAIN"
install -o root -g root -m 600 \
"$OUTPUT_KEY" \
"$M2M_KEY"
fi
###############################################################################
# Create VHost
###############################################################################
if $INSTALL_MODE && $CREATE_VHOST; then
echo "Creating ${WEBSERVER} virtual host..."
if [[ "$WEBSERVER" == "apache" ]]; then
if [[ "$DISTRO" == "debian" ]]; then
VHOST_FILE="/etc/apache2/sites-available/${HOSTNAME}.conf"
else
VHOST_FILE="/etc/httpd/conf.d/${HOSTNAME}.conf"
fi
cat > "$VHOST_FILE" <<EOF
Listen ${EXTERNAL_PORT}
<VirtualHost *:${EXTERNAL_PORT}>
ServerName ${HOSTNAME}
SSLEngine on
SSLCertificateFile ${M2M_CERT}
SSLCertificateKeyFile ${M2M_KEY}
SSLVerifyClient require
SSLVerifyDepth 5
SSLCACertificateFile ${M2M_CHAIN}
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:${TARGET_PORT}/
ProxyPassReverse / http://127.0.0.1:${TARGET_PORT}/
ErrorLog \${APACHE_LOG_DIR}/${HOSTNAME}_error.log
CustomLog \${APACHE_LOG_DIR}/${HOSTNAME}_access.log combined
</VirtualHost>
EOF
else
if [[ "$DISTRO" == "debian" ]]; then
VHOST_FILE="/etc/nginx/sites-available/${HOSTNAME}.conf"
else
VHOST_FILE="/etc/nginx/conf.d/${HOSTNAME}.conf"
fi
cat > "$VHOST_FILE" <<EOF
server {
listen ${EXTERNAL_PORT} ssl;
server_name ${HOSTNAME};
ssl_certificate ${M2M_CERT};
ssl_certificate_key ${M2M_KEY};
ssl_client_certificate ${M2M_CHAIN};
ssl_verify_client on;
location / {
proxy_pass http://127.0.0.1:${TARGET_PORT};
proxy_set_header Host \$host;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
fi
fi
###############################################################################
# Summary
###############################################################################
echo
echo "=========================================================="
echo "Operation completed"
echo "=========================================================="
echo
echo "Extracted Certificate:"
echo " ${OUTPUT_CERT}"
echo
echo "Extracted Certificate Chain:"
echo " ${OUTPUT_CHAIN}"
echo
echo "Extracted Private Key (unencrypted):"
echo " ${OUTPUT_KEY}"
if $INSTALL_MODE; then
echo
echo "Installed Certificate:"
echo " ${M2M_CERT}"
echo
echo "Installed Certificate Chain:"
echo " ${M2M_CHAIN}"
echo
echo "Installed Private Key:"
echo " ${M2M_KEY}"
if $CREATE_VHOST; then
echo
echo "Virtual Host:"
echo " ${VHOST_FILE}"
echo
if [[ "$WEBSERVER" == "apache" ]]; then
if [[ "$DISTRO" == "debian" ]]; then
cat <<EOF
Activate Site:
a2enmod ssl
a2enmod proxy
a2enmod proxy_http
a2ensite ${HOSTNAME}
Validate:
apachectl configtest
Reload:
systemctl reload apache2
EOF
else
cat <<EOF
Validate:
apachectl configtest
Reload:
systemctl reload httpd
EOF
fi
else
if [[ "$DISTRO" == "debian" ]]; then
cat <<EOF
Enable Site:
ln -sf \
/etc/nginx/sites-available/${HOSTNAME}.conf \
/etc/nginx/sites-enabled/${HOSTNAME}.conf
Validate:
nginx -t
Reload:
systemctl reload nginx
EOF
else
cat <<EOF
Validate:
nginx -t
Reload:
systemctl reload nginx
EOF
fi
fi
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment