Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various improvements mostly related to Docker usage #25

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
FROM alpine:3.10
FROM python:3.8.3-slim AS builder

WORKDIR /

RUN apk update && apk add --no-cache \
curl git \
automake autoconf libtool gcc musl-dev make linux-headers \
gettext openssl-dev libxml2-dev lz4-dev libproxy-dev \
py2-lxml py2-requests py2-pip \
&& rm -rf /var/cache/apk/*
RUN pip install pyotp
RUN apt-get update && apt-get install -y --no-install-recommends \
curl automake autoconf libtool make \
libxml2-dev zlib1g-dev libssl-dev pkg-config


RUN mkdir -p /usr/local/sbin
RUN curl -o /usr/local/sbin/vpnc-script http://git.infradead.org/users/dwmw2/vpnc-scripts.git/blob_plain/HEAD:/vpnc-script
RUN chmod +x /usr/local/sbin/vpnc-script

RUN git clone -b "v8.10" --single-branch --depth=1 https://gitlab.com/openconnect/openconnect.git
WORKDIR /openconnect
RUN curl -L -o /tmp/openconnect.tar.gz https://gitlab.com/openconnect/openconnect/-/archive/v8.10/openconnect-v8.10.tar.gz
RUN tar xvzf /tmp/openconnect.tar.gz
WORKDIR /openconnect-v8.10
RUN ./autogen.sh
RUN ./configure --without-gnutls --with-vpnc-script=/usr/local/sbin/vpnc-script
RUN ./configure --without-gnutls --disable-nls --with-vpnc-script=/usr/local/sbin/vpnc-script
RUN make check
RUN make
RUN make install

RUN curl -o /usr/local/sbin/vpnc-script https://gitlab.com/openconnect/vpnc-scripts/-/raw/master/vpnc-script
RUN chmod +x /usr/local/sbin/vpnc-script

FROM python:3.8.3-slim

RUN pip install pyotp requests lxml
RUN set -x \
&& apt-get update \
&& apt-get install -y libxml2 net-tools \
&& apt-get clean
COPY --from=builder /usr/local /usr/local
RUN ldconfig

COPY gp-okta.py /usr/local/bin

CMD ["/openconnect/gp-okta/gp-okta.py","/openconnect/gp-okta/gp-okta.conf"]
CMD ["python", "-u", "/usr/local/bin/gp-okta.py", "/etc/gp-okta.conf"]
5 changes: 5 additions & 0 deletions gp-okta.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ gateway = NEWYORK1-GW
#totp.google = ABCDEFGHIJKLMNOP
#totp.symantec = ABCDEFGHIJKLMNOP

# --- this is for storing a single one-time password. Not very useful
# in a config file, but potentially very useful for overriding with
# GP_TOTP_CODE in the environment.
#totp_code =

# --- certificates
# any defined "*_cert" is path to readable and unencrypted certificate file.
# "vpn_url_cert" and "okta_url_cert" are used to verify relevant URLs.
Expand Down
10 changes: 7 additions & 3 deletions gp-okta.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,9 @@ def okta_mfa_totp(conf, factor, state_token):
secret = conf.get_value('totp.{0}'.format(provider))
code = None
if not secret:
code = input('{0} TOTP: '.format(provider)).strip()
code = conf.get_value('totp_code')
if not code:
code = input('{0} TOTP: '.format(provider)).strip()
else:
if not have_pyotp:
err('Need pyotp package, consider doing \'pip install pyotp\' (or similar)')
Expand Down Expand Up @@ -863,8 +865,10 @@ def run_openconnect(conf, do_portal_auth, urls, saml_username, cookies):
cp = subprocess.Popen(ecmd, stdin=pp.stdout, stdout=sys.stdout)
if pp.stdout is not None:
pp.stdout.close()
# Do not abort on SIGINT. openconnect will perform proper exit & cleanup
signal.signal(signal.SIGINT, signal.SIG_IGN)
# Do not abort on SIGINT or SIGTERM; pass signal to openconnect so
# it can perform proper exit & cleanup
signal.signal(signal.SIGINT, lambda signum, frame: cp.terminate())
signal.signal(signal.SIGTERM, lambda signum, frame: cp.terminate())
cp.communicate()
if conf.certs:
try:
Expand Down
65 changes: 33 additions & 32 deletions run-docker.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
#!/usr/bin/env bash

conf_username=`grep username gp-okta.conf | awk -F \= '{print $2}' | tr -d " "`
conf_password=`grep password gp-okta.conf | awk -F \= '{print $2}' | tr -d " "`
totp_okta=`grep totp.okta gp-okta.conf | awk -F \= '{print $2}' | tr -d " "`
totp_google=`grep totp.google gp-okta.conf | awk -F \= '{print $2}' | tr -d " "`

haystack="okta google"

if [[ -z "${totp_okta}" && -z "${totp_google}" ]]; then
read -p "Enter Second auth numbers (okta or google), (prepend with needed provider e.g okta_1234): " totp
if [[ "${totp}" ]]; then
totp_choice=`echo ${totp} | awk -F _ '{ print $1 }'`
totp_numbers=`echo ${totp} | awk -F _ '{ print $2 }'`
if [[ -n "echo $haystack|grep $totp_choice" ]]; then
echo "${totp_choice}"
if [[ "${totp_numbers}" && ${totp_choice} ]]; then
sed -i "s/totp.${totp_choice}.*/totp.${totp_choice} = ${totp_numbers}/g" gp-okta.conf
fi
else
echo "Unsupported second auth choosed"
exit 1
fi

else
echo "Something failed with parsing second auth"
exit 1
fi

fi
conf_username=$(grep "^username" gp-okta.conf | awk -F \= '{print $2}' | tr -d " ")
conf_password=$(grep "^password" gp-okta.conf | awk -F \= '{print $2}' | tr -d " ")

### detect where username is filled in
if [[ "${conf_username}" ]]; then
Expand All @@ -45,20 +19,47 @@ fi

if [[ -z "${conf_password}" && -z "${GP_PASSWORD}" ]]; then
read -s -p "Enter Okta password: " GP_PASSWORD
echo
fi

echo
# If no TOTP secrets are specified, prompt for OTP.
totp_secrets=$(grep "^totp." gp-okta.conf | awk -F \= '{print $2}' | tr -d " ")
if [[ -z "${totp_secrets}" ]]; then
read -p "Enter MFA OTP code: " totp
fi

echo

docker run \
-d \
--name=gp-okta \
--rm \
--privileged \
--net=host \
--cap-add=NET_ADMIN \
--device /dev/net/tun \
-e GP_PASSWORD=${GP_PASSWORD} \
-e GP_USERNAME=${GP_USERNAME} \
-e GP_PASSWORD=${GP_PASSWORD} \
-e GP_TOTP_CODE=${totp} \
-e GP_EXECUTE=1 \
-e GP_OPENCONNECT_CMD=/usr/local/sbin/openconnect \
-v /etc/resolv.conf:/etc/resolv.conf \
-v ${PWD}:/openconnect/gp-okta \
gp-okta
-v ${PWD}/gp-okta.conf:/etc/gp-okta.conf \
gp-okta \
> /dev/null

# Watch output for successful, for a little while at least
( timeout 30 docker logs -f gp-okta & ) | sed '/ESP tunnel connected/q'

# If container is gone, something went awry
echo
echo
if [ -z "$(docker ps -q -f name=gp-okta)" ]; then
echo
echo
echo "VPN failed to start!"
exit 1
else
echo "VPN running"
exit 0
fi
16 changes: 16 additions & 0 deletions stop-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

container=$(docker ps -q -f name=gp-okta)
if [ -z "${container}" ]; then
echo "VPN is not running!"
exit 1
fi

# Watch output for close-down output
( timeout 30 docker logs -f --since 0s gp-okta & )

docker stop gp-okta > /dev/null

echo
echo
echo "VPN stopped."