File tree 4 files changed +49
-1
lines changed 4 files changed +49
-1
lines changed Original file line number Diff line number Diff line change @@ -5,7 +5,7 @@ MAINTAINER Pieter Lange <pieter@ptlc.nl>
5
5
6
6
RUN echo "http://dl-4.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories && \
7
7
echo "http://dl-4.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
8
- apk add --update openvpn iptables bash easy-rsa libintl inotify-tools && \
8
+ apk add --update openvpn iptables bash easy-rsa libintl inotify-tools openvpn-auth-pam google-authenticator pamtester && \
9
9
apk add --virtual build_deps gettext && \
10
10
cp /usr/bin/envsubst /usr/local/bin/envsubst && \
11
11
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
@@ -34,4 +34,7 @@ COPY entrypoint.sh /sbin/entrypoint.sh
34
34
COPY watch-portmapping.sh /sbin/watch-portmapping.sh
35
35
COPY openvpn.tmpl $OVPN_TEMPLATE
36
36
37
+ # Add support for OTP authentication using a PAM module
38
+ ADD ./otp/openvpn /etc/pam.d/
39
+
37
40
CMD ["/sbin/entrypoint.sh" ]
Original file line number Diff line number Diff line change
1
+ #! /bin/bash
2
+
3
+ #
4
+ # Generate OpenVPN users via google authenticator
5
+ #
6
+
7
+ if [ -z $1 ]; then
8
+ echo " Usage: ovpn_otp_user USERNAME"
9
+ exit 1
10
+ fi
11
+
12
+ # Server name is in the form "udp://vpn.example.com:1194"
13
+ if [[ " $OVPN_SERVER_URL " =~ ^(( udp| tcp):// )? ([0 - 9 a- zA- Z\.\- ]+ )(: ([0 - 9 ]+ )) ? $ ]]; then
14
+ OVPN_PROTO=${BASH_REMATCH[2]} ;
15
+ OVPN_CN=${BASH_REMATCH[3]} ;
16
+ OVPN_PORT=${BASH_REMATCH[5]} ;
17
+ else
18
+ echo " Need to pass in OVPN_SERVER_URL in 'proto://fqdn:port' format"
19
+ exit 1
20
+ fi
21
+
22
+ # Ensure the otp folder is present
23
+ [ -d /etc/openvpn/otp ] || mkdir -p /etc/openvpn/otp
24
+
25
+ # Binary is present in image, save an $user.google_authenticator file in /etc/openvpn/otp
26
+ if [ " $2 " == " interactive" ]; then
27
+ # Authenticator will ask for other parameters. User can choose rate limit, token reuse policy and time window policy
28
+ # Always use time base OTP otherwise storage for counters must be configured somewhere in volume
29
+ google-authenticator --time-based --force -l " ${1} @${OVPN_CN} " -s /etc/openvpn/otp/${1} .google_authenticator
30
+ else
31
+ google-authenticator --time-based --disallow-reuse --force --rate-limit=3 --rate-time=30 --window-size=3 \
32
+ -l " ${1} @${OVPN_CN} " -s /etc/openvpn/otp/${1} .google_authenticator
33
+ fi
Original file line number Diff line number Diff line change @@ -76,6 +76,11 @@ if [ -r $OVPN_CRL ]; then
76
76
addArg " --crl-verify" " $OVPN_CRL "
77
77
fi
78
78
79
+ # Optional OTP authentication support
80
+ if [ -d " ${OVPN_OTP_AUTH:- } " ]; then
81
+ addArg " --plugin" " /usr/lib/openvpn/plugins/openvpn-plugin-auth-pam.so" " openvpn"
82
+ fi
83
+
79
84
if [ $DEBUG ]; then
80
85
echo " openvpn.conf:"
81
86
cat $OVPN_CONFIG
Original file line number Diff line number Diff line change
1
+ # Uses google authenticator library as PAM module using a single folder for all users tokens
2
+ # User root is required to stick with an hardcoded user when trying to determine user id and allow unexisting system users
3
+ # See https://github.com/google/google-authenticator/tree/master/libpam#secretpathtosecretfile--usersome-user
4
+ auth required pam_google_authenticator.so secret=${OVPN_OTP}/${USER}.google_authenticator user=root
5
+
6
+ # Accept any user since we're dealing with virtual users there's no need to have a system account (pam_unix.so)
7
+ account sufficient pam_permit.so
You can’t perform that action at this time.
0 commit comments