Skip to content

Commit

Permalink
port google OTP code from kylemanna/openvpn
Browse files Browse the repository at this point in the history
  • Loading branch information
pieterlange committed Dec 19, 2016
1 parent 895a697 commit 04e1276
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 1 deletion.
5 changes: 4 additions & 1 deletion Dockerfile
Expand Up @@ -5,7 +5,7 @@ MAINTAINER Pieter Lange <pieter@ptlc.nl>

RUN echo "http://dl-4.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories && \
echo "http://dl-4.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
apk add --update openvpn iptables bash easy-rsa libintl inotify-tools && \
apk add --update openvpn iptables bash easy-rsa libintl inotify-tools openvpn-auth-pam google-authenticator pamtester && \
apk add --virtual build_deps gettext && \
cp /usr/bin/envsubst /usr/local/bin/envsubst && \
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
Expand Down Expand Up @@ -34,4 +34,7 @@ COPY entrypoint.sh /sbin/entrypoint.sh
COPY watch-portmapping.sh /sbin/watch-portmapping.sh
COPY openvpn.tmpl $OVPN_TEMPLATE

# Add support for OTP authentication using a PAM module
ADD ./otp/openvpn /etc/pam.d/

CMD ["/sbin/entrypoint.sh"]
33 changes: 33 additions & 0 deletions bin/ovpn_otp_user
@@ -0,0 +1,33 @@
#!/bin/bash

#
# Generate OpenVPN users via google authenticator
#

if [ -z $1 ]; then
echo "Usage: ovpn_otp_user USERNAME"
exit 1
fi

# Server name is in the form "udp://vpn.example.com:1194"
if [[ "$OVPN_SERVER_URL" =~ ^((udp|tcp)://)?([0-9a-zA-Z\.\-]+)(:([0-9]+))?$ ]]; then
OVPN_PROTO=${BASH_REMATCH[2]};
OVPN_CN=${BASH_REMATCH[3]};
OVPN_PORT=${BASH_REMATCH[5]};
else
echo "Need to pass in OVPN_SERVER_URL in 'proto://fqdn:port' format"
exit 1
fi

# Ensure the otp folder is present
[ -d /etc/openvpn/otp ] || mkdir -p /etc/openvpn/otp

# Binary is present in image, save an $user.google_authenticator file in /etc/openvpn/otp
if [ "$2" == "interactive" ]; then
# Authenticator will ask for other parameters. User can choose rate limit, token reuse policy and time window policy
# Always use time base OTP otherwise storage for counters must be configured somewhere in volume
google-authenticator --time-based --force -l "${1}@${OVPN_CN}" -s /etc/openvpn/otp/${1}.google_authenticator
else
google-authenticator --time-based --disallow-reuse --force --rate-limit=3 --rate-time=30 --window-size=3 \
-l "${1}@${OVPN_CN}" -s /etc/openvpn/otp/${1}.google_authenticator
fi
5 changes: 5 additions & 0 deletions entrypoint.sh
Expand Up @@ -75,6 +75,11 @@ if [ -r $OVPN_CRL ]; then
addArg "--crl-verify" "$OVPN_CRL"
fi

# Optional OTP authentication support
if [ -n "${OVPN_OTP_AUTH:-}" ]; then
addArg "--plugin" "/usr/lib/openvpn/plugins/openvpn-plugin-auth-pam.so" "openvpn"
fi

if [ $DEBUG ]; then
echo "openvpn.conf:"
cat $OVPN_CONFIG
Expand Down
7 changes: 7 additions & 0 deletions otp/openvpn
@@ -0,0 +1,7 @@
# Uses google authenticator library as PAM module using a single folder for all users tokens
# User root is required to stick with an hardcoded user when trying to determine user id and allow unexisting system users
# See https://github.com/google/google-authenticator/tree/master/libpam#secretpathtosecretfile--usersome-user
auth required pam_google_authenticator.so secret=${OVPN_OTP}/${USER}.google_authenticator user=root

# Accept any user since we're dealing with virtual users there's no need to have a system account (pam_unix.so)
account sufficient pam_permit.so

0 comments on commit 04e1276

Please sign in to comment.