From dda15e243f483b737cf30beeb18c21d1039c7f88 Mon Sep 17 00:00:00 2001 From: Alexis Ducastel Date: Tue, 8 Mar 2016 16:34:32 +0100 Subject: [PATCH] Adding OpenVPN stacks with ldap, http basi and http digest authentication backends --- templates/openvpn-httpbasic/0/README.md | 5 + .../openvpn-httpbasic/0/docker-compose.yml | 33 ++++ .../openvpn-httpbasic/0/rancher-compose.yml | 123 ++++++++++++++ .../catalogIcon-openvpn-httpbasic.png | Bin 0 -> 6975 bytes templates/openvpn-httpbasic/config.yml | 6 + templates/openvpn-httpdigest/0/README.md | 5 + .../openvpn-httpdigest/0/docker-compose.yml | 33 ++++ .../openvpn-httpdigest/0/rancher-compose.yml | 123 ++++++++++++++ .../catalogIcon-openvpn-httpdigest.png | Bin 0 -> 6975 bytes templates/openvpn-httpdigest/config.yml | 6 + templates/openvpn-ldap/0/README.md | 5 + templates/openvpn-ldap/0/docker-compose.yml | 37 +++++ templates/openvpn-ldap/0/rancher-compose.yml | 151 ++++++++++++++++++ .../openvpn-ldap/catalogIcon-openvpn-ldap.png | Bin 0 -> 6975 bytes templates/openvpn-ldap/config.yml | 6 + 15 files changed, 533 insertions(+) create mode 100644 templates/openvpn-httpbasic/0/README.md create mode 100644 templates/openvpn-httpbasic/0/docker-compose.yml create mode 100644 templates/openvpn-httpbasic/0/rancher-compose.yml create mode 100644 templates/openvpn-httpbasic/catalogIcon-openvpn-httpbasic.png create mode 100644 templates/openvpn-httpbasic/config.yml create mode 100644 templates/openvpn-httpdigest/0/README.md create mode 100644 templates/openvpn-httpdigest/0/docker-compose.yml create mode 100644 templates/openvpn-httpdigest/0/rancher-compose.yml create mode 100644 templates/openvpn-httpdigest/catalogIcon-openvpn-httpdigest.png create mode 100644 templates/openvpn-httpdigest/config.yml create mode 100644 templates/openvpn-ldap/0/README.md create mode 100644 templates/openvpn-ldap/0/docker-compose.yml create mode 100644 templates/openvpn-ldap/0/rancher-compose.yml create mode 100644 templates/openvpn-ldap/catalogIcon-openvpn-ldap.png create mode 100644 templates/openvpn-ldap/config.yml diff --git a/templates/openvpn-httpbasic/0/README.md b/templates/openvpn-httpbasic/0/README.md new file mode 100644 index 0000000..a817732 --- /dev/null +++ b/templates/openvpn-httpbasic/0/README.md @@ -0,0 +1,5 @@ +# OpenVPN + +OpenVPN stack made to give access to Rancher network with HTTP Basic authentication. + +OpenVPN version: 1.0-0 \ No newline at end of file diff --git a/templates/openvpn-httpbasic/0/docker-compose.yml b/templates/openvpn-httpbasic/0/docker-compose.yml new file mode 100644 index 0000000..1340a63 --- /dev/null +++ b/templates/openvpn-httpbasic/0/docker-compose.yml @@ -0,0 +1,33 @@ +openvpn-httpbasic-data: + labels: + io.rancher.container.start_once: 'true' + entrypoint: + - /bin/true + image: busybox + volumes: + - /etc/openvpn/ + +openvpn-httpbasic-server: + ports: + - 1194:1194/tcp + environment: + AUTH_METHOD: httpbasic + AUTH_HTTPBASIC_URL: ${AUTH_HTTPBASIC_URL} + CERT_COUNTRY: ${CERT_COUNTRY} + CERT_PROVINCE: ${CERT_PROVINCE} + CERT_CITY: ${CERT_CITY} + CERT_ORG: ${CERT_ORG} + CERT_EMAIL: ${CERT_EMAIL} + CERT_OU: ${CERT_OU} + REMOTE_IP: ${REMOTE_IP} + REMOTE_PORT: ${REMOTE_PORT} + VPNPOOL_NETWORK: ${VPNPOOL_NETWORK} + VPNPOOL_CIDR: ${VPNPOOL_CIDR} + OPENVPN_EXTRACONF: ${OPENVPN_EXTRACONF} + labels: + io.rancher.sidekicks: openvpn-httpbasic-data + io.rancher.container.pull_image: always + image: mdns/rancher-openvpn:1.0 + privileged: true + volumes_from: + - openvpn-httpbasic-data diff --git a/templates/openvpn-httpbasic/0/rancher-compose.yml b/templates/openvpn-httpbasic/0/rancher-compose.yml new file mode 100644 index 0000000..ece8c66 --- /dev/null +++ b/templates/openvpn-httpbasic/0/rancher-compose.yml @@ -0,0 +1,123 @@ +.catalog: + name: OpenVPN HTTP Basic + version: 1.0-0 + description: | + OpenVPN for Rancher with HTTP Basic authentication + minimum_rancher_version: v0.56.0 + maintainer: "Alexis Ducastel " + uuid: openvpn-httpbasic-0 + questions: + + - variable: "AUTH_HTTPBASIC_URL" + description: "HTTP server url used for authentication, ex: http[s]://hostname[:port]" + label: "HTTP Server URL:" + required: true + default: "http[s]://hostname[:port]" + type: "string" + + - variable: "REMOTE_IP" + description: "Ip address or hostname that will be set in client configuration, you can leave default values and replace them in client config later" + label: "OpenVPN server endpoint address:" + required: true + default: "IP-address-or-hostname" + type: "string" + + - variable: "REMOTE_PORT" + description: "TCP port that will be set in client configuration, you can leave default values and replace them in client config later" + label: "OpenVPN server endpoint port :" + required: true + default: "1194" + type: "string" + + - variable: "VPNPOOL_NETWORK" + description: "VPN subnet for OpenVPN to draw client addresses from" + label: "Network pool:" + required: true + default: "10.43.0.0" + type: "string" + + - variable: "VPNPOOL_CIDR" + description: "CIDR netmask for VPN subnet" + label: "CIDR netmask:" + required: true + default: "16" + type: "enum" + options: + - 16 + - 17 + - 18 + - 19 + - 20 + - 21 + - 22 + - 23 + - 24 + - 25 + - 26 + - 27 + - 28 + - 29 + - 30 + + + - variable: "CERT_COUNTRY" + description: "Country code part of VPN CA (2 digits only)" + label: "Certificate Country code :" + required: true + default: "US" + type: "string" + + - variable: "CERT_PROVINCE" + description: "Province part of VPN CA" + label: "Certificate Province:" + required: true + default: "AL" + type: "string" + + + - variable: "CERT_CITY" + description: "City part of VPN CA " + label: "Certificate City:" + required: true + default: "Birmingham" + type: "string" + + - variable: "CERT_ORG" + description: "Organization part of VPN CA " + label: "Certificate Organization:" + required: true + default: "ACME" + type: "string" + + - variable: "CERT_OU" + description: "Organizational Unit part of VPN CA " + label: "Certificate OU:" + required: true + default: "IT" + type: "string" + + - variable: "CERT_EMAIL" + description: "Email part of VPN CA " + label: "Certificate Email:" + required: true + default: "foo@example.com" + type: "string" + + - variable: "OPENVPN_EXTRACONF" + description: "Optionnal custom OpenVPN config line, for example to push your own custom route" + label: "OpenVPN custom config:" + required: false + default: "" + type: "string" + +openvpn-httpbasic-data: + scale: 1 +openvpn-httpbasic-server: + scale: 1 + health_check: + port: 1194 + interval: 30000 + unhealthy_threshold: 5 + strategy: none + healthy_threshold: 2 + response_timeout: 2000 diff --git a/templates/openvpn-httpbasic/catalogIcon-openvpn-httpbasic.png b/templates/openvpn-httpbasic/catalogIcon-openvpn-httpbasic.png new file mode 100644 index 0000000000000000000000000000000000000000..2707a93d23aa413c042bb6d5912f2b0fa749abee GIT binary patch literal 6975 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 \ No newline at end of file diff --git a/templates/openvpn-httpdigest/0/README.md b/templates/openvpn-httpdigest/0/README.md new file mode 100644 index 0000000..6744d70 --- /dev/null +++ b/templates/openvpn-httpdigest/0/README.md @@ -0,0 +1,5 @@ +# OpenVPN + +OpenVPN stack made to give access to Rancher network with HTTP Digest authentication. + +OpenVPN version: 1.0-0 \ No newline at end of file diff --git a/templates/openvpn-httpdigest/0/docker-compose.yml b/templates/openvpn-httpdigest/0/docker-compose.yml new file mode 100644 index 0000000..ec38e8b --- /dev/null +++ b/templates/openvpn-httpdigest/0/docker-compose.yml @@ -0,0 +1,33 @@ +openvpn-httpdigest-data: + labels: + io.rancher.container.start_once: 'true' + entrypoint: + - /bin/true + image: busybox + volumes: + - /etc/openvpn/ + +openvpn-httpdigest-server: + ports: + - 1194:1194/tcp + environment: + AUTH_METHOD: httpdigest + AUTH_HTTPDIGEST_URL: ${AUTH_HTTPDIGEST_URL} + CERT_COUNTRY: ${CERT_COUNTRY} + CERT_PROVINCE: ${CERT_PROVINCE} + CERT_CITY: ${CERT_CITY} + CERT_ORG: ${CERT_ORG} + CERT_EMAIL: ${CERT_EMAIL} + CERT_OU: ${CERT_OU} + REMOTE_IP: ${REMOTE_IP} + REMOTE_PORT: ${REMOTE_PORT} + VPNPOOL_NETWORK: ${VPNPOOL_NETWORK} + VPNPOOL_CIDR: ${VPNPOOL_CIDR} + OPENVPN_EXTRACONF: ${OPENVPN_EXTRACONF} + labels: + io.rancher.sidekicks: openvpn-httpdigest-data + io.rancher.container.pull_image: always + image: mdns/rancher-openvpn:1.0 + privileged: true + volumes_from: + - openvpn-httpdigest-data diff --git a/templates/openvpn-httpdigest/0/rancher-compose.yml b/templates/openvpn-httpdigest/0/rancher-compose.yml new file mode 100644 index 0000000..42575da --- /dev/null +++ b/templates/openvpn-httpdigest/0/rancher-compose.yml @@ -0,0 +1,123 @@ +.catalog: + name: OpenVPN HTTP Digest + version: 1.0-0 + description: | + OpenVPN for Rancher with HTTP Digest authentication + minimum_rancher_version: v0.56.0 + maintainer: "Alexis Ducastel " + uuid: openvpn-httpdigest-0 + questions: + + - variable: "AUTH_HTTPDIGEST_URL" + description: "HTTP server url used for authentication, ex: http[s]://hostname[:port]" + label: "HTTP Server URL:" + required: true + default: "http[s]://hostname[:port]" + type: "string" + + - variable: "REMOTE_IP" + description: "Ip address or hostname that will be set in client configuration, you can leave default values and replace them in client config later" + label: "OpenVPN server endpoint address:" + required: true + default: "IP-address-or-hostname" + type: "string" + + - variable: "REMOTE_PORT" + description: "TCP port that will be set in client configuration, you can leave default values and replace them in client config later" + label: "OpenVPN server endpoint port :" + required: true + default: "1194" + type: "string" + + - variable: "VPNPOOL_NETWORK" + description: "VPN subnet for OpenVPN to draw client addresses from" + label: "Network pool:" + required: true + default: "10.43.0.0" + type: "string" + + - variable: "VPNPOOL_CIDR" + description: "CIDR netmask for VPN subnet" + label: "CIDR netmask:" + required: true + default: "16" + type: "enum" + options: + - 16 + - 17 + - 18 + - 19 + - 20 + - 21 + - 22 + - 23 + - 24 + - 25 + - 26 + - 27 + - 28 + - 29 + - 30 + + + - variable: "CERT_COUNTRY" + description: "Country code part of VPN CA (2 digits only)" + label: "Certificate Country code :" + required: true + default: "US" + type: "string" + + - variable: "CERT_PROVINCE" + description: "Province part of VPN CA" + label: "Certificate Province:" + required: true + default: "AL" + type: "string" + + + - variable: "CERT_CITY" + description: "City part of VPN CA " + label: "Certificate City:" + required: true + default: "Birmingham" + type: "string" + + - variable: "CERT_ORG" + description: "Organization part of VPN CA " + label: "Certificate Organization:" + required: true + default: "ACME" + type: "string" + + - variable: "CERT_OU" + description: "Organizational Unit part of VPN CA " + label: "Certificate OU:" + required: true + default: "IT" + type: "string" + + - variable: "CERT_EMAIL" + description: "Email part of VPN CA " + label: "Certificate Email:" + required: true + default: "foo@example.com" + type: "string" + + - variable: "OPENVPN_EXTRACONF" + description: "Optionnal custom OpenVPN config line, for example to push your own custom route" + label: "OpenVPN custom config:" + required: false + default: "" + type: "string" + +openvpn-httpdigest-data: + scale: 1 +openvpn-httpdigest-server: + scale: 1 + health_check: + port: 1194 + interval: 30000 + unhealthy_threshold: 5 + strategy: none + healthy_threshold: 2 + response_timeout: 2000 diff --git a/templates/openvpn-httpdigest/catalogIcon-openvpn-httpdigest.png b/templates/openvpn-httpdigest/catalogIcon-openvpn-httpdigest.png new file mode 100644 index 0000000000000000000000000000000000000000..2707a93d23aa413c042bb6d5912f2b0fa749abee GIT binary patch literal 6975 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 \ No newline at end of file diff --git a/templates/openvpn-ldap/0/README.md b/templates/openvpn-ldap/0/README.md new file mode 100644 index 0000000..fb8ed27 --- /dev/null +++ b/templates/openvpn-ldap/0/README.md @@ -0,0 +1,5 @@ +# OpenVPN + +OpenVPN stack made to give access to Rancher network with LDAP authentication. + +OpenVPN version: 1.0-0 \ No newline at end of file diff --git a/templates/openvpn-ldap/0/docker-compose.yml b/templates/openvpn-ldap/0/docker-compose.yml new file mode 100644 index 0000000..1ec17f6 --- /dev/null +++ b/templates/openvpn-ldap/0/docker-compose.yml @@ -0,0 +1,37 @@ +openvpn-ldap-data: + labels: + io.rancher.container.start_once: 'true' + entrypoint: + - /bin/true + image: busybox + volumes: + - /etc/openvpn/ + +openvpn-ldap-server: + ports: + - 1194:1194/tcp + environment: + AUTH_METHOD: ldap + AUTH_LDAP_URL: ${AUTH_LDAP_URL} + AUTH_LDAP_BASEDN: ${AUTH_LDAP_BASEDN} + AUTH_LDAP_SEARCH: ${AUTH_LDAP_SEARCH} + AUTH_LDAP_BINDDN: ${AUTH_LDAP_BINDDN} + AUTH_LDAP_BINDPWD: ${AUTH_LDAP_BINDPWD} + CERT_COUNTRY: ${CERT_COUNTRY} + CERT_PROVINCE: ${CERT_PROVINCE} + CERT_CITY: ${CERT_CITY} + CERT_ORG: ${CERT_ORG} + CERT_EMAIL: ${CERT_EMAIL} + CERT_OU: ${CERT_OU} + REMOTE_IP: ${REMOTE_IP} + REMOTE_PORT: ${REMOTE_PORT} + VPNPOOL_NETWORK: ${VPNPOOL_NETWORK} + VPNPOOL_CIDR: ${VPNPOOL_CIDR} + OPENVPN_EXTRACONF: ${OPENVPN_EXTRACONF} + labels: + io.rancher.sidekicks: openvpn-ldap-data + io.rancher.container.pull_image: always + image: mdns/rancher-openvpn:1.0 + privileged: true + volumes_from: + - openvpn-ldap-data diff --git a/templates/openvpn-ldap/0/rancher-compose.yml b/templates/openvpn-ldap/0/rancher-compose.yml new file mode 100644 index 0000000..b78ba7e --- /dev/null +++ b/templates/openvpn-ldap/0/rancher-compose.yml @@ -0,0 +1,151 @@ +.catalog: + name: OpenVPN LDAP + version: 1.0-0 + description: | + OpenVPN for Rancher with LDAP authentication + minimum_rancher_version: v0.56.0 + maintainer: "Alexis Ducastel " + uuid: openvpn-ldap-0 + questions: + + - variable: "AUTH_LDAP_URL" + description: "LDAP server url, ex: ldap[s]://hostname[:port]" + label: "LDAP URL:" + required: true + default: "ldap[s]://hostname[:port]" + type: "string" + + - variable: "AUTH_LDAP_BASEDN" + description: "Base DN for searching user dn" + label: "LDAP Base DN:" + required: true + default: "dc=acme,dc=tld" + type: "string" + + - variable: "AUTH_LDAP_SEARCH" + description: "LDAP Search request, with a parameter $username, ex : (uid=$username) or more complex example : (|(uid=$username)(mail=$username))" + label: "LDAP Search:" + required: true + default: "(uid=$username)" + type: "string" + + - variable: "AUTH_LDAP_BINDDN" + description: "(Optionnal) Bind DN to perfrom search operation, leave blank if not required. Ex : cn=admin,dc=acme,dc=tld" + label: "LDAP Bind DN:" + required: false + default: "" + type: "string" + + - variable: "AUTH_LDAP_BINDPWD" + description: "(Optionnal) Bind password to perfrom search operation, leave blank if not required" + label: "LDAP Bind password:" + required: false + default: "" + type: "password" + + - variable: "REMOTE_IP" + description: "Ip address or hostname that will be set in client configuration, you can leave default values and replace them in client config later" + label: "OpenVPN server endpoint address:" + required: true + default: "IP-address-or-hostname" + type: "string" + + - variable: "REMOTE_PORT" + description: "TCP port that will be set in client configuration, you can leave default values and replace them in client config later" + label: "OpenVPN server endpoint port :" + required: true + default: "1194" + type: "string" + + - variable: "VPNPOOL_NETWORK" + description: "VPN subnet for OpenVPN to draw client addresses from" + label: "Network pool:" + required: true + default: "10.43.0.0" + type: "string" + + - variable: "VPNPOOL_CIDR" + description: "CIDR netmask for VPN subnet" + label: "CIDR netmask:" + required: true + default: "16" + type: "enum" + options: + - 16 + - 17 + - 18 + - 19 + - 20 + - 21 + - 22 + - 23 + - 24 + - 25 + - 26 + - 27 + - 28 + - 29 + - 30 + + + - variable: "CERT_COUNTRY" + description: "Country code part of VPN CA (2 digits only)" + label: "Certificate Country code :" + required: true + default: "US" + type: "string" + + - variable: "CERT_PROVINCE" + description: "Province part of VPN CA" + label: "Certificate Province:" + required: true + default: "AL" + type: "string" + + + - variable: "CERT_CITY" + description: "City part of VPN CA " + label: "Certificate City:" + required: true + default: "Birmingham" + type: "string" + + - variable: "CERT_ORG" + description: "Organization part of VPN CA " + label: "Certificate Organization:" + required: true + default: "ACME" + type: "string" + + - variable: "CERT_OU" + description: "Organizational Unit part of VPN CA " + label: "Certificate OU:" + required: true + default: "IT" + type: "string" + + - variable: "CERT_EMAIL" + description: "Email part of VPN CA " + label: "Certificate Email:" + required: true + default: "foo@example.com" + type: "string" + + - variable: "OPENVPN_EXTRACONF" + description: "Optionnal custom OpenVPN config line, for example to push your own custom route" + label: "OpenVPN custom config:" + required: false + default: "" + type: "string" + +openvpn-ldap-data: + scale: 1 +openvpn-ldap-server: + scale: 1 + health_check: + port: 1194 + interval: 30000 + unhealthy_threshold: 5 + strategy: none + healthy_threshold: 2 + response_timeout: 2000 diff --git a/templates/openvpn-ldap/catalogIcon-openvpn-ldap.png b/templates/openvpn-ldap/catalogIcon-openvpn-ldap.png new file mode 100644 index 0000000000000000000000000000000000000000..2707a93d23aa413c042bb6d5912f2b0fa749abee GIT binary patch literal 6975 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 \ No newline at end of file