From 6aa675257ee551a23e99031765961663c76b10bc Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Wed, 4 Oct 2023 00:36:16 +0200 Subject: [PATCH] initial commit --- .gitignore | 1 + .secrets/.gitignore | 8 +++ Dockerfile.client | 12 +++++ Dockerfile.server | 13 +++++ README.md | 36 +++++++++++++ docker-compose.yml | 54 +++++++++++++++++++ openvpn/client.example.test.conf | 13 +++++ openvpn/server.example.test.conf | 16 ++++++ .../ccd/client.example.test | 1 + .../usr/sbin/entrypoint.sh | 17 ++++++ .../usr/sbin/entrypoint.sh | 40 ++++++++++++++ vpnca.sh | 22 ++++++++ 12 files changed, 233 insertions(+) create mode 100644 .gitignore create mode 100644 .secrets/.gitignore create mode 100644 Dockerfile.client create mode 100644 Dockerfile.server create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 openvpn/client.example.test.conf create mode 100644 openvpn/server.example.test.conf create mode 100644 openvpn/server.example.test/ccd/client.example.test create mode 100644 scripts/client.example.test/usr/sbin/entrypoint.sh create mode 100644 scripts/server.example.test/usr/sbin/entrypoint.sh create mode 100755 vpnca.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b18ce42 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vpnca diff --git a/.secrets/.gitignore b/.secrets/.gitignore new file mode 100644 index 0000000..5c4df25 --- /dev/null +++ b/.secrets/.gitignore @@ -0,0 +1,8 @@ +auth_ldap_base_dn +auth_ldap_bind_dn +auth_ldap_group_base_dn +auth_ldap_group_search_filter +auth_ldap_password +auth_ldap_url +login_password +login_user diff --git a/Dockerfile.client b/Dockerfile.client new file mode 100644 index 0000000..51733c7 --- /dev/null +++ b/Dockerfile.client @@ -0,0 +1,12 @@ +FROM alpine +RUN mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 600 /dev/net/tun +RUN apk update && apk add --no-cache bash openvpn +RUN mkdir -p /etc/openvpn/client/client.example.test +ADD vpnca/pki/ca.crt /etc/openvpn/client/client.example.test +ADD vpnca/pki/issued/client.example.test.crt /etc/openvpn/client/client.example.test +ADD vpnca/pki/private/client.example.test.key /etc/openvpn/client/client.example.test +RUN chmod 600 /etc/openvpn/client/client.example.test/client.example.test.key +ADD openvpn/client.example.test.conf /etc/openvpn/client/client.example.test.conf +ADD scripts/client.example.test/usr/sbin/entrypoint.sh /usr/sbin/entrypoint.sh +RUN chmod 755 /usr/sbin/entrypoint.sh +CMD /usr/sbin/entrypoint.sh diff --git a/Dockerfile.server b/Dockerfile.server new file mode 100644 index 0000000..c849728 --- /dev/null +++ b/Dockerfile.server @@ -0,0 +1,13 @@ +FROM alpine +RUN apk update && apk add --no-cache bash openvpn openvpn-auth-ldap +RUN mkdir -p /etc/openvpn/server/server.example.test/ccd +ADD vpnca/pki/ca.crt /etc/openvpn/server/server.example.test +ADD vpnca/pki/issued/server.example.test.crt /etc/openvpn/server/server.example.test +ADD vpnca/pki/private/server.example.test.key /etc/openvpn/server/server.example.test +ADD vpnca/pki/dh.pem /etc/openvpn/server/server.example.test +RUN chmod 600 /etc/openvpn/server/server.example.test/server.example.test.key +ADD openvpn/server.example.test.conf /etc/openvpn/server/server.example.test.conf +ADD openvpn/server.example.test/ccd /etc/openvpn/server/server.example.test/ccd +ADD scripts/server.example.test/usr/sbin/entrypoint.sh /usr/sbin/entrypoint.sh +RUN chmod 755 /usr/sbin/entrypoint.sh +CMD /usr/sbin/entrypoint.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..bae7e99 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# Dockerized Container Testbed for OpenVPN with CCD and LDAP Auth + +## Build VPN Test Root CA + +```shell +./vpnca.sh +``` + +## Set Secrets for LDAP Access + +In directory `.secrets` create the following files containing LDAP login information: + +- `.secrets/auth_ldap_base_dn`: + Example: `ou=users,dc=example,dc=test` +- `.secrets/auth_ldap_bind_dn`: + Example: `uid=ldap_readonly,dc=example,dc=test` +- `.secrets/auth_ldap_group_base_dn`: + Example: `ou=groups,dc=example,dc=test` +- `.secrets/auth_ldap_group_search_filter`: + Example: `(cn=vpnuser)` +- `.secrets/auth_ldap_password`: + Example: `topsecret123` +- `.secrets/auth_ldap_url`: + Example: `ldap://ldap01.example.test` +- `.secrets/login_password`: + Example: `P4ssw0rd` +- `.secrets/login_user`: + Example: `testuser1` + +## Build and run the Example + +```shell +docker compose build +docker compose up +``` + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..48313a4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,54 @@ +version: '3' + +services: + server: + hostname: server + domainname: example.test + image: openvpn-test-server + build: + dockerfile: Dockerfile.server + restart: always + networks: + - openvpn-test + cap_add: + - NET_ADMIN + secrets: + - auth_ldap_url + - auth_ldap_bind_dn + - auth_ldap_password + - auth_ldap_base_dn + - auth_ldap_group_base_dn + - auth_ldap_group_search_filter + client: + hostname: client + domainname: example.test + image: openvpn-test-client + build: + dockerfile: Dockerfile.client + restart: always + networks: + - openvpn-test + cap_add: + - NET_ADMIN + secrets: + - login_user + - login_password +networks: + openvpn-test: +secrets: + auth_ldap_url: + file: .secrets/auth_ldap_url + auth_ldap_bind_dn: + file: .secrets/auth_ldap_bind_dn + auth_ldap_password: + file: .secrets/auth_ldap_password + auth_ldap_base_dn: + file: .secrets/auth_ldap_base_dn + auth_ldap_group_base_dn: + file: .secrets/auth_ldap_group_base_dn + auth_ldap_group_search_filter: + file: .secrets/auth_ldap_group_search_filter + login_user: + file: .secrets/login_user + login_password: + file: .secrets/login_password diff --git a/openvpn/client.example.test.conf b/openvpn/client.example.test.conf new file mode 100644 index 0000000..95e283e --- /dev/null +++ b/openvpn/client.example.test.conf @@ -0,0 +1,13 @@ +client +verb 3 +dev tun +proto tcp +port 1194 +remote server +resolv-retry infinite +nobind +cipher AES-256-GCM +ca /etc/openvpn/client/client.example.test/ca.crt +cert /etc/openvpn/client/client.example.test/client.example.test.crt +key /etc/openvpn/client/client.example.test/client.example.test.key +auth-user-pass /etc/openvpn/client/client.example.test/login.conf diff --git a/openvpn/server.example.test.conf b/openvpn/server.example.test.conf new file mode 100644 index 0000000..d7ca0eb --- /dev/null +++ b/openvpn/server.example.test.conf @@ -0,0 +1,16 @@ +verb 3 +server 192.168.11.0 255.255.255.0 +dev tun +port 1194 +proto tcp +ca /etc/openvpn/server/server.example.test/ca.crt +cert /etc/openvpn/server/server.example.test/server.example.test.crt +key /etc/openvpn/server/server.example.test/server.example.test.key +dh /etc/openvpn/server/server.example.test/dh.pem +plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so /etc/openvpn/server/server.example.test/auth-ldap.conf +client-config-dir /etc/openvpn/server/server.example.test/ccd +cipher AES-256-GCM +max-clients 4 +client-to-client +topology subnet +push "dhcp-option DOMAIN example.test" diff --git a/openvpn/server.example.test/ccd/client.example.test b/openvpn/server.example.test/ccd/client.example.test new file mode 100644 index 0000000..c2ca6ea --- /dev/null +++ b/openvpn/server.example.test/ccd/client.example.test @@ -0,0 +1 @@ +ifconfig-push 192.168.11.2 255.255.255.255 diff --git a/scripts/client.example.test/usr/sbin/entrypoint.sh b/scripts/client.example.test/usr/sbin/entrypoint.sh new file mode 100644 index 0000000..f58d9ee --- /dev/null +++ b/scripts/client.example.test/usr/sbin/entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/sh +set -e +mkdir -p /dev/net +mknod /dev/net/tun c 10 200 +chmod 600 /dev/net/tun + +login_user=$(cat /run/secrets/login_user) +login_password=$(cat /run/secrets/login_password) + +cat > /etc/openvpn/client/client.example.test/login.conf << EOF +$login_user +$login_password +EOF + +chmod 600 /etc/openvpn/client/client.example.test/login.conf + +/usr/sbin/openvpn --config /etc/openvpn/client/client.example.test.conf diff --git a/scripts/server.example.test/usr/sbin/entrypoint.sh b/scripts/server.example.test/usr/sbin/entrypoint.sh new file mode 100644 index 0000000..d405a0c --- /dev/null +++ b/scripts/server.example.test/usr/sbin/entrypoint.sh @@ -0,0 +1,40 @@ +#!/bin/sh +set -e +mkdir -p /dev/net +mknod /dev/net/tun c 10 200 +chmod 600 /dev/net/tun + +auth_ldap_url=$(cat /run/secrets/auth_ldap_url) +auth_ldap_bind_dn=$(cat /run/secrets/auth_ldap_bind_dn) +auth_ldap_password=$(cat /run/secrets/auth_ldap_password) +auth_ldap_base_dn=$(cat /run/secrets/auth_ldap_base_dn) +auth_ldap_group_base_dn=$(cat /run/secrets/auth_ldap_group_base_dn) +auth_ldap_group_search_filter=$(cat /run/secrets/auth_ldap_group_search_filter) + +cat > /etc/openvpn/server/server.example.test/auth-ldap.conf << EOF + + URL $auth_ldap_url + BindDN $auth_ldap_bind_dn + Password $auth_ldap_password + Timeout 15 + TLSEnable no + FollowReferrals no + + + BaseDN "$auth_ldap_base_dn" + SearchFilter "(uid=%u)" + RequireGroup false + PasswordIsCR false + + RFC2307bis false + UseCompareOperation true + BaseDN "$auth_ldap_group_base_dn" + SearchFilter "$auth_ldap_group_search_filter" + MemberAttribute memberUid + + +EOF + +chmod 600 /etc/openvpn/server/server.example.test/auth-ldap.conf + +/usr/sbin/openvpn --config /etc/openvpn/server/server.example.test.conf diff --git a/vpnca.sh b/vpnca.sh new file mode 100755 index 0000000..c92feb4 --- /dev/null +++ b/vpnca.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +cd "$(dirname "$(readlink -f "$0")")" + +test -f vpnca/pki/ca.crt && { + echo "ERROR: vpnca/pki/ca.crt already exists; aborting (to build a new CA, completely remove ./vpnca)." >&2 ; + exit 1 ; +} + +make-cadir vpnca + +{ + cd vpnca ; + export EASYRSA_BATCH=true ; + ./easyrsa init-pki ; + ./easyrsa gen-dh ; + ./easyrsa --req-cn="VPN Test Root CA" build-ca nopass ; + ./easyrsa build-server-full server.example.test nopass ; + ./easyrsa build-client-full client.example.test nopass ; +}