parent
7f1da70b9d
commit
b26d0968e1
@ -0,0 +1,2 @@ |
||||
name: ovpn-admin |
||||
version: 1.0.0 |
@ -0,0 +1 @@ |
||||
helm chart example |
@ -0,0 +1,88 @@ |
||||
{{ $openvpnNetwork := required "A valid .Values.openvpn.subnet entry required!" .Values.openvpn.subnet }} |
||||
{{ $openvpnNetworkAddress := index (splitList "/" $openvpnNetwork) 0 }} |
||||
{{ $openvpnNetworkNetmask := index (splitList "/" $openvpnNetwork) 1 }} |
||||
--- |
||||
apiVersion: v1 |
||||
kind: ConfigMap |
||||
metadata: |
||||
name: openvpn |
||||
data: |
||||
openvpn.conf: |- |
||||
user nobody |
||||
group nogroup |
||||
|
||||
mode server |
||||
tls-server |
||||
# dev-type tun |
||||
dev tun |
||||
proto tcp-server |
||||
port 1194 |
||||
# local 127.0.0.1 |
||||
management 127.0.0.1 8989 |
||||
|
||||
tun-mtu 1500 |
||||
mssfix |
||||
# only udp |
||||
#fragment 1300 |
||||
|
||||
keepalive 10 60 |
||||
client-to-client |
||||
persist-key |
||||
persist-tun |
||||
|
||||
cipher AES-128-CBC |
||||
duplicate-cn |
||||
|
||||
server {{ $openvpnNetworkAddress }} {{ $openvpnNetworkNetmask }} |
||||
|
||||
topology subnet |
||||
push "topology subnet" |
||||
push "route-metric 9999" |
||||
|
||||
verb 4 |
||||
|
||||
ifconfig-pool-persist /tmp/openvpn.ipp |
||||
status /tmp/openvpn.status |
||||
|
||||
key-direction 0 |
||||
|
||||
ca /etc/openvpn/certs/pki/ca.crt |
||||
key /etc/openvpn/certs/pki/private/server.key |
||||
cert /etc/openvpn/certs/pki/issued/server.crt |
||||
dh /etc/openvpn/certs/pki/dh.pem |
||||
crl-verify /etc/openvpn/certs/pki/crl.pem |
||||
tls-auth /etc/openvpn/certs/pki/ta.key |
||||
client-config-dir /etc/openvpn/ccd |
||||
|
||||
entrypoint.sh: |- |
||||
#!/bin/sh |
||||
set -x |
||||
|
||||
iptables -t nat -A POSTROUTING -s {{ $openvpnNetworkAddress }}/{{ $openvpnNetworkNetmask }} ! -d {{ $openvpnNetworkAddress }}/{{ $openvpnNetworkNetmask }} -j MASQUERADE |
||||
|
||||
mkdir -p /dev/net |
||||
if [ ! -c /dev/net/tun ]; then |
||||
mknod /dev/net/tun c 10 200 |
||||
fi |
||||
|
||||
wait_file() { |
||||
file_path="$1" |
||||
while true; do |
||||
if [ -f $file_path ]; then |
||||
break |
||||
fi |
||||
echo "wait $file_path" |
||||
sleep 2 |
||||
done |
||||
} |
||||
|
||||
easyrsa_path="/etc/openvpn/certs" |
||||
|
||||
wait_file "$easyrsa_path/pki/ca.crt" |
||||
wait_file "$easyrsa_path/pki/private/server.key" |
||||
wait_file "$easyrsa_path/pki/issued/server.crt" |
||||
wait_file "$easyrsa_path/pki/ta.key" |
||||
wait_file "$easyrsa_path/pki/dh.pem" |
||||
wait_file "$easyrsa_path/pki/crl.pem" |
||||
|
||||
openvpn --config /etc/openvpn/openvpn.conf |
@ -0,0 +1,117 @@ |
||||
--- |
||||
apiVersion: apps/v1 |
||||
kind: Deployment |
||||
metadata: |
||||
name: openvpn |
||||
spec: |
||||
selector: |
||||
matchLabels: |
||||
app: openvpn |
||||
template: |
||||
metadata: |
||||
labels: |
||||
app: openvpn |
||||
spec: |
||||
{{- if .Values.openvpn.nodeSelector }} |
||||
nodeSelector: |
||||
{{- .Values.openvpn.nodeSelector | toYaml | indent 8 | printf "\n%s" }} |
||||
{{- end }} |
||||
{{- if .Values.openvpn.tolerations }} |
||||
tolerations: |
||||
{{- .Values.openvpn.tolerations | toYaml | indent 8 | printf "\n%s" }} |
||||
{{- end }} |
||||
terminationGracePeriodSeconds: 0 |
||||
serviceAccountName: openvpn |
||||
containers: |
||||
- name: ovpn-admin |
||||
image: {{ .Values.ovpnAdmin.image }} |
||||
command: |
||||
- /bin/sh |
||||
- -c |
||||
- /app/ovpn-admin |
||||
--storage.backend="kubernetes.secrets" |
||||
--listen.host="0.0.0.0" |
||||
--listen.port="8000" |
||||
--role="master" |
||||
{{- if hasKey .Values.openvpn "inlet" }} |
||||
{{- if eq .Values.openvpn.inlet "LoadBalancer" }} |
||||
--ovpn.server.behindLB |
||||
--ovpn.service="openvpn-external" |
||||
{{- end }} |
||||
{{- end }} |
||||
--mgmt=main="127.0.0.1:8989" |
||||
--ccd --ccd.path="/mnt/ccd" |
||||
--easyrsa.path="/mnt/certs" |
||||
{{- $externalHost := "" }} |
||||
{{- if hasKey .Values.openvpn "inlet" }} |
||||
{{- if eq .Values.openvpn.inlet "ExternalIP" }}{{ $externalHost = .Values.openvpn.externalIP }}{{- end }} |
||||
{{- end }} |
||||
{{- if hasKey .Values.openvpn "externalHost" }}{{ $externalHost = .Values.openvpn.externalHost }}{{- end }} |
||||
{{- if ne $externalHost "" }} |
||||
--ovpn.server="{{ $externalHost }}:{{ .Values.openvpn.externalPort | default 5416 | quote }}:tcp" |
||||
{{- end }} |
||||
ports: |
||||
- name: ovpn-admin |
||||
protocol: TCP |
||||
containerPort: 8000 |
||||
volumeMounts: |
||||
- name: certs |
||||
mountPath: /mnt/certs |
||||
- name: ccd |
||||
mountPath: /mnt/ccd |
||||
- name: openvpn |
||||
image: {{ .Values.openvpn.image }} |
||||
command: [ '/entrypoint.sh' ] |
||||
# imagePullPolicy: Always |
||||
securityContext: |
||||
allowPrivilegeEscalation: false |
||||
capabilities: |
||||
add: |
||||
- NET_ADMIN |
||||
- NET_RAW |
||||
- MKNOD |
||||
- SETGID |
||||
- SETUID |
||||
drop: |
||||
- ALL |
||||
ports: |
||||
- name: openvpn-tcp |
||||
protocol: TCP |
||||
containerPort: 1194 |
||||
{{- if eq .Values.openvpn.inlet "HostPort" }} |
||||
hostPort: {{ .Values.openvpn.hostPort }} |
||||
{{- end }} |
||||
volumeMounts: |
||||
- name: tmp |
||||
mountPath: /tmp |
||||
- name: dev-net |
||||
mountPath: /dev/net |
||||
- name: certs |
||||
mountPath: /etc/openvpn/certs |
||||
- name: ccd |
||||
mountPath: /etc/openvpn/ccd |
||||
- name: config |
||||
mountPath: /etc/openvpn/openvpn.conf |
||||
subPath: openvpn.conf |
||||
readOnly: true |
||||
- name: entrypoint |
||||
mountPath: /entrypoint.sh |
||||
subPath: entrypoint.sh |
||||
readOnly: true |
||||
volumes: |
||||
- name: tmp |
||||
emptyDir: {} |
||||
- name: dev-net |
||||
emptyDir: {} |
||||
- name: certs |
||||
emptyDir: {} |
||||
- name: ccd |
||||
emptyDir: {} |
||||
- name: config |
||||
configMap: |
||||
name: openvpn |
||||
defaultMode: 0644 |
||||
- name: entrypoint |
||||
configMap: |
||||
name: openvpn |
||||
defaultMode: 0755 |
@ -0,0 +1,39 @@ |
||||
--- |
||||
apiVersion: networking.k8s.io/v1 |
||||
kind: Ingress |
||||
metadata: |
||||
name: ovpn-admin |
||||
annotations: |
||||
kubernetes.io/ingress.class: nginx |
||||
nginx.ingress.kubernetes.io/backend-protocol: HTTP |
||||
nginx.ingress.kubernetes.io/auth-type: basic |
||||
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required" |
||||
nginx.ingress.kubernetes.io/auth-secret: basic-auth |
||||
spec: |
||||
tls: |
||||
- hosts: |
||||
- {{ .Values.domain }} |
||||
secretName: ingress-tls |
||||
rules: |
||||
- host: {{ .Values.domain }} |
||||
http: |
||||
paths: |
||||
- path: / |
||||
pathType: Prefix |
||||
backend: |
||||
service: |
||||
name: ovpn-admin |
||||
port: |
||||
name: http |
||||
--- |
||||
apiVersion: cert-manager.io/v1 |
||||
kind: Certificate |
||||
metadata: |
||||
name: ovpn-admin |
||||
spec: |
||||
secretName: ingress-tls |
||||
dnsNames: |
||||
- {{ .Values.domain }} |
||||
issuerRef: |
||||
name: letsencrypt |
||||
kind: ClusterIssuer |
@ -0,0 +1,36 @@ |
||||
--- |
||||
apiVersion: v1 |
||||
kind: ServiceAccount |
||||
metadata: |
||||
name: openvpn |
||||
--- |
||||
apiVersion: rbac.authorization.k8s.io/v1 |
||||
kind: Role |
||||
metadata: |
||||
name: openvpn |
||||
rules: |
||||
- apiGroups: |
||||
- "" |
||||
resources: |
||||
- services |
||||
verbs: |
||||
- get |
||||
- list |
||||
- apiGroups: |
||||
- "" |
||||
resources: |
||||
- secrets |
||||
verbs: |
||||
- "*" |
||||
--- |
||||
apiVersion: rbac.authorization.k8s.io/v1 |
||||
kind: RoleBinding |
||||
metadata: |
||||
name: openvpn |
||||
roleRef: |
||||
apiGroup: rbac.authorization.k8s.io |
||||
kind: Role |
||||
name: openvpn |
||||
subjects: |
||||
- kind: ServiceAccount |
||||
name: openvpn |
@ -0,0 +1,8 @@ |
||||
--- |
||||
apiVersion: v1 |
||||
kind: Secret |
||||
metadata: |
||||
name: basic-auth |
||||
type: Opaque |
||||
data: |
||||
auth: {{ print .Values.ovpnAdmin.basicAuth.user ":{PLAIN}" .Values.ovpnAdmin.basicAuth.password | b64enc | quote }} |
@ -0,0 +1,57 @@ |
||||
--- |
||||
apiVersion: v1 |
||||
kind: Service |
||||
metadata: |
||||
name: ovpn-admin |
||||
spec: |
||||
clusterIP: None |
||||
ports: |
||||
- name: http |
||||
port: 8000 |
||||
protocol: TCP |
||||
targetPort: 8000 |
||||
selector: |
||||
app: openvpn |
||||
--- |
||||
{{- if hasKey .Values.openvpn "inlet" }} |
||||
|
||||
{{- if eq .Values.openvpn.inlet "LoadBalancer" }} |
||||
--- |
||||
apiVersion: v1 |
||||
kind: Service |
||||
metadata: |
||||
name: openvpn-external |
||||
spec: |
||||
externalTrafficPolicy: Local |
||||
type: LoadBalancer |
||||
ports: |
||||
- name: openvpn-tcp |
||||
protocol: TCP |
||||
port: {{ .Values.openvpn.externalPort | default 1194 }} |
||||
targetPort: openvpn-tcp |
||||
selector: |
||||
app: openvpn |
||||
{{- else if eq .Values.openvpn.inlet "ExternalIP" }} |
||||
--- |
||||
apiVersion: v1 |
||||
kind: Service |
||||
metadata: |
||||
name: openvpn-external |
||||
spec: |
||||
type: ClusterIP |
||||
externalIPs: |
||||
- {{ .Values.openvpn.externalIP }} |
||||
ports: |
||||
- name: openvpn-tcp |
||||
port: {{ .Values.openvpn.externalPort | default 1194 }} |
||||
protocol: TCP |
||||
targetPort: openvpn-tcp |
||||
selector: |
||||
app: openvpn |
||||
{{- else if eq .Values.openvpn.inlet "HostPort" }} |
||||
--- |
||||
{{- else }} |
||||
{{- cat "Unsupported inlet type" .inlet | fail }} |
||||
{{- end }} |
||||
|
||||
{{- end }} |
@ -0,0 +1,26 @@ |
||||
domain: changeme |
||||
ovpnAdmin: |
||||
image: changeme |
||||
basicAuth: |
||||
user: admin |
||||
password: changeme |
||||
openvpn: |
||||
image: changeme |
||||
subnet: 172.16.200.0/255.255.255.0 |
||||
# nodeSelector: |
||||
# node-role.kubernetes.io/master: "" |
||||
# tolerations: |
||||
# - effect: NoSchedule |
||||
# key: node-role.kubernetes.io/master |
||||
# |
||||
# // LoadBalancer or ExternalIP or HostPort |
||||
inlet: HostPort |
||||
# |
||||
# If inlet: ExternalIP |
||||
# externalIP: 1.2.3.4 |
||||
# externalPort: 1194 |
||||
# |
||||
# If inlet: HostPort |
||||
hostPort: 1194 |
||||
# Domain or ip for connect to OpenVPN server |
||||
# externalHost: 1.2.3.4 |
Loading…
Reference in new issue