├── openvpn.conf ├── Dockerfile ├── LICENSE ├── entrypoint.sh └── README.md /openvpn.conf: -------------------------------------------------------------------------------- 1 | server {{OVPN_NETWORK}} {{OVPN_SUBNET}} 2 | verb 3 3 | 4 | pkcs12 {{OVPN_CERTS}} 5 | dh {{OVPN_DH}} 6 | 7 | key-direction 0 8 | keepalive 10 60 9 | persist-key 10 | persist-tun 11 | 12 | proto {{OVPN_PROTO}} 13 | port 1194 14 | dev tun0 15 | status /tmp/openvpn-status.log 16 | 17 | user nobody 18 | group nogroup 19 | 20 | {{MORE_OPTS}} 21 | 22 | push "route {{OVPN_K8S_SERVICE_NETWORK}} {{OVPN_K8S_SERVICE_SUBNET}}" 23 | {{POD_CONF}} 24 | push "dhcp-option DOMAIN {{OVPN_K8S_DOMAIN}}" 25 | push "dhcp-option DNS {{OVPN_K8S_DNS}}" 26 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.2 2 | MAINTAINER Jaka Hudoklin 3 | 4 | # Install openvpn 5 | RUN echo "http://dl-4.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories && \ 6 | apk add --update openvpn iptables bash && \ 7 | rm -rf /tmp/* /var/tmp/* /var/cache/apk/* 8 | 9 | # Configuration files 10 | ENV OVPN_CONFIG /etc/openvpn/openvpn.conf 11 | ADD openvpn.conf /etc/openvpn/openvpn.conf 12 | 13 | # Expose tcp and udp port 14 | EXPOSE 1194/tcp 15 | EXPOSE 1194/udp 16 | 17 | WORKDIR /etc/openvpn 18 | 19 | # entry point takes care of setting conf values 20 | COPY entrypoint.sh /sbin/entrypoint.sh 21 | 22 | CMD ["/sbin/entrypoint.sh"] 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Jaka Hudoklin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$DEBUG" == "1" ]; then 4 | set -x 5 | fi 6 | 7 | set -e 8 | 9 | MORE_OPTS="${MORE_OPTS:-}" 10 | OVPN_NETWORK="${OVPN_NETWORK:-10.140.0.0}" 11 | OVPN_SUBNET="${OVPN_SUBNET:-255.255.0.0}" 12 | OVPN_PROTO="${OVPN_PROTO:-udp}" 13 | OVPN_NATDEVICE="${OVPN_NATDEVICE:-eth0}" 14 | #OVPN_K8S_SERVICE_NETWORK 15 | #OVPN_K8S_SERVICE_SUBNET 16 | OVPN_K8S_DOMAIN="${OVPN_KUBE_DOMAIN:-cluster.local}" 17 | #OVPN_K8S_DNS 18 | OVPN_DH="${OVPN_DH:-/etc/openvpn/pki/dh.pem}" 19 | OVPN_CERTS="${OVPN_CERTS:-/etc/openvpn/pki/certs.p12}" 20 | 21 | if [ -z "${OVPN_K8S_SERVICE_NETWORK}" ]; then 22 | echo "Service network not specified" 23 | exit 1 24 | fi 25 | 26 | if [ -z "${OVPN_K8S_SERVICE_SUBNET}" ]; then 27 | echo "Service subnet not specified" 28 | exit 1 29 | fi 30 | 31 | if [ -z "${OVPN_K8S_DNS}" ]; then 32 | echo "DNS server not specified" 33 | exit 1 34 | fi 35 | 36 | if [ ! -z "${OVPN_K8S_POD_NETWORK}" -a ! -z "${OVPN_K8S_POD_SUBNET}" ]; then 37 | POD_CONF="push \"route ${OVPN_K8S_POD_NETWORK} ${OVPN_K8S_POD_SUBNET}\"" 38 | else 39 | POD_CONF="" 40 | fi 41 | 42 | sed 's|{{OVPN_NETWORK}}|'"${OVPN_NETWORK}"'|' -i "${OVPN_CONFIG}" 43 | sed 's|{{OVPN_SUBNET}}|'"${OVPN_SUBNET}"'|' -i "${OVPN_CONFIG}" 44 | sed 's|{{OVPN_PROTO}}|'"${OVPN_PROTO}"'|' -i "${OVPN_CONFIG}" 45 | sed 's|{{OVPN_DH}}|'"${OVPN_DH}"'|' -i "${OVPN_CONFIG}" 46 | sed 's|{{OVPN_CERTS}}|'"${OVPN_CERTS}"'|' -i "${OVPN_CONFIG}" 47 | sed 's|{{OVPN_K8S_SERVICE_NETWORK}}|'"${OVPN_K8S_SERVICE_NETWORK}"'|' -i "${OVPN_CONFIG}" 48 | sed 's|{{OVPN_K8S_SERVICE_SUBNET}}|'"${OVPN_K8S_SERVICE_SUBNET}"'|' -i "${OVPN_CONFIG}" 49 | sed 's|{{OVPN_K8S_DOMAIN}}|'"${OVPN_K8S_DOMAIN}"'|' -i "${OVPN_CONFIG}" 50 | sed 's|{{OVPN_K8S_DNS}}|'"${OVPN_K8S_DNS}"'|' -i "${OVPN_CONFIG}" 51 | 52 | sed 's|{{POD_CONF}}|'"${POD_CONF}"'|' -i "${OVPN_CONFIG}" 53 | sed 's|{{MORE_OPTS}}|'"${MORE_OPTS}"'|' -i "${OVPN_CONFIG}" 54 | 55 | iptables -t nat -A POSTROUTING -s ${OVPN_NETWORK}/${OVPN_SUBNET} -o ${OVPN_NATDEVICE} -j MASQUERADE 56 | 57 | mkdir -p /dev/net 58 | if [ ! -c /dev/net/tun ]; then 59 | mknod /dev/net/tun c 10 200 60 | fi 61 | 62 | if [ "$DEBUG" == "1" ]; then 63 | echo ========== ${OVPN_CONFIG} ========== 64 | cat "${OVPN_CONFIG}" 65 | echo ==================================== 66 | fi 67 | 68 | exec openvpn --config ${OVPN_CONFIG} 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # offlinehacker/openvpn-k8s 2 | 3 | - [Introduction](#introduction) 4 | - [Contributing](#contributing) 5 | - [Prerequisites](#prerequisites) 6 | - [Installation](#installation) 7 | - [Quick Start](#quick-start) 8 | - [Configuration Parameters](#configuration-parameters) 9 | 10 | # Introduction 11 | 12 | Dockerfile to run [openvpn](https://openvpn.net/) inside [kubernetes](http://kubernetes.io/). 13 | 14 | # Contributing 15 | 16 | If you find this image useful you can help by doing one of the following: 17 | 18 | - *Send a Pull Request*: you can add new features to the docker image, which will be integrated into the official image. 19 | - *Report a Bug*: if you notice a bug, please issue a bug report at [Issues](https://github.com/offlinehacker/openvpn-k8s/issues), so we can fix it as soon as possible. 20 | 21 | # Installation 22 | 23 | Automated builds of the image are available on [Dockerhub](https://hub.docker.com/r/offlinehacker/openvpn-k8s) and is the recommended method of installation. 24 | 25 | ```bash 26 | docker pull offlinehacker/openvpn-k8s:latest 27 | ``` 28 | 29 | Alternatively you can build the image locally. 30 | 31 | ```bash 32 | git clone https://github.com/offlinehacker/openvpn-k8s.git 33 | cd openvpn 34 | docker build -t offlinehacker/openvpn-k8s . 35 | ``` 36 | 37 | # Quick Start 38 | 39 | This image was created to simply have openvpn access to kubernetes cluster. 40 | 41 | First you will need to create [secret volume](http://kubernetes.io/v1.1/docs/user-guide/secrets.html) with dh params and server certificate in pkcs12 format. 42 | 43 | - Create kubernetes secret volume: 44 | 45 | `openvpn-secrets.yaml` file: 46 | 47 | ``` 48 | apiVersion: v1 49 | kind: Secret 50 | metadata: 51 | name: openvpn 52 | data: 53 | dh.pem: 54 | certs.p12: 55 | ``` 56 | 57 | kubectl create -f openvpn-secrets.yaml 58 | 59 | - Create kubernetes replication controller: 60 | 61 | `openvpn-controller.yaml` file: 62 | 63 | ``` 64 | apiVersion: v1 65 | kind: ReplicationController 66 | metadata: 67 | name: openvpn 68 | labels: 69 | name: openvpn 70 | spec: 71 | replicas: 2 72 | selector: 73 | name: openvpn 74 | template: 75 | metadata: 76 | labels: 77 | name: openvpn 78 | spec: 79 | containers: 80 | - name: openvpn 81 | image: offlinehacker/openvpn-k8s 82 | securityContext: 83 | capabilities: 84 | add: 85 | - NET_ADMIN 86 | env: 87 | - name: OVPN_NETWORK 88 | value: 10.240.0.0 89 | - name: OVPN_SUBNET 90 | value: 255.255.0.0 91 | - name: OVPN_PROTO 92 | value: tcp 93 | - name: OVPN_K8S_SERVICE_NETWORK 94 | value: 10.241.240.0 95 | - name: OVPN_K8S_SERVICE_SUBNET 96 | value: 255.255.240.0 97 | - name: OVPN_K8S_DNS 98 | value: 10.241.240.10 99 | ports: 100 | - name: openvpn 101 | containerPort: 1194 102 | volumeMounts: 103 | - mountPath: /etc/openvpn/pki 104 | name: openvpn 105 | volumes: 106 | - name: openvpn 107 | secret: 108 | secretName: openvpn 109 | ``` 110 | 111 | - Create kubernetes service: 112 | 113 | `openvpn-service.yaml` file: 114 | 115 | ``` 116 | kind: Service 117 | apiVersion: v1 118 | metadata: 119 | name: openvpn 120 | spec: 121 | ports: 122 | - name: openvpn 123 | port: 1194 124 | targetPort: 1194 125 | selector: 126 | name: openvpn 127 | type: LoadBalancer 128 | ``` 129 | 130 | kubectl create -f openvpn-service.yaml 131 | 132 | # Configuration Parameters 133 | 134 | Below is the complete list of available options that can be used to customize your packetbeat container instance. 135 | 136 | - **OVPN_NETWORK**: Network allocated for openvpn clients (default: 10.240.0.0). 137 | - **OVPN_SUBNET**: Network subnet allocated for openvpn client (default: 255.255.0.0). 138 | - **OVPN_PROTO**: Protocol used by openvpn tcp or udp (default: udp). 139 | - **OVPN_NATDEVICE**: Device connected to kuberentes service network (default: eth0). 140 | - **OVPN_K8S_SERVICE_NETWORK**: Kubernetes service network (required). 141 | - **OVPN_K8S_SERVICE_SUBNET**: Kubernetes service network subnet (required). 142 | - **OVPN_K8S_DOMAIN**: Kuberentes cluster domain (default: cluster.local). 143 | - **OVPN_K8S_DNS**: Kuberentes cluster dns server (required). 144 | - **OVPN_K8S_DH**: Openvpn dh.pem file path (default: /etc/openvpn/pki/dh.pem). 145 | - **OVPN_K8S_CERTS**: Openvpn certs.p12 file path (default: /etc/openvpn/pki/certs.p12). 146 | - **MORE_OPTS**: Misc Openvpn options, one per line, for example `duplicate-cn` 147 | - **OVPN_K8S_POD_NETWORK**: Kubernetes pod network (optional). 148 | - **OVPN_K8S_POD_SUBNET**: Kubernetes pod network subnet (optional). 149 | --------------------------------------------------------------------------------