@media screen and (min-width: 580px) { .flotantewhatsapp{ display:none; } }

Compartir por WhatsApp

Instalar OpenVpn Server en Kubernetes

Instalar OpenVpn Server en Kubernetes

Vamos a implementar un sistema VPN con contenedores. En este caso, os explicamos como generar un servidor VPN a través de un clúster de Kubernetes fácilmente.

Lo primero hablaremos un poco de Helm, que es un gestor de paquetes para Kubernetes y es lo que vamos a usar.

La principal función de Helm es definir, instalar y actualizar aplicaciones complejas de Kubernetes. Helm es mantenido por la CNCF en colaboración con Microsoft, Google, Bitnami y la comunidad de Helm.

PROYECTO HELM: https://helm.sh/

instalar-openvpn-server-en-kubernetes-1

El objetivo principal de esto es facilitar el acceso a los servicios de kubernetes a desarrolladores de aplicaciones, por ejemplo. También podría usarse para cualquier servicio al que solo se deba acceder a través de una VPN o como una VPN estándar.

Como podéis prever, nos vamos conectar a la red de nuestro clúster Kubernetes, no a la red corporativa.

Instalar Helm en Debian

Instalamos snap:
raulunzue@KBMASTER:~$ sudo apt update
raulunzue@KBMASTER:~# sudo apt-get install snap

Instalamos Helm:

raulunzue@KBMASTER:~$ sudo snap install helm --classic
helm 3.1.2 from Snapcrafters installed

Configuración de OpenVpn Server con Kubernetes

Comprobamos el estado del cluster:
raulunzue@KBMASTER:~$ kubectl get node
NAME STATUS ROLES AGE VERSION
kbmaster Ready master 71d v1.17.4
kubernetes01 Ready 46h v1.17.4
kubernetes02 Ready 71d v1.17.4

Comprobamos la external IP del cluster, en mi caso no la tiene:
raulunzue@KBMASTER:~$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world-deployment-elblogdenegu NodePort 10.96.198.40 80:31910/TCP 63s
kubernetes ClusterIP 10.96.0.1 443/TCP 71d

Por defecto, el cluster sólo es accesible de forma interna, así que tendremos que habilitar el acceso externo:

raulunzue@KBMASTER:~$ kubectl proxy
Starting to serve on 127.0.0.1:8001

Agregamos un repo como root:

root@KBMASTER:~# helm repo add stable http://storage.googleapis.com/kubernetes-charts
"stable" has been added to your repositories

Actualizamos los repos:

raulunzue@KBMASTER:~$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈ Happy Helming!⎈

He instalamos:

raulunzue@KBMASTER:~$ helm install stable/openvpn --generate-name
NAME: openvpn-1584572359
LAST DEPLOYED: Wed Mar 18 23:59:23 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
OpenVPN is now starting.

Please be aware that certificate generation is variable and may take some time (minutes).

Check pod status with the command:

POD_NAME=$(kubectl get pods --namespace "default" -l app=openvpn -o jsonpath='{ .items[0].metadata.name }') && kubectl --namespace "default" logs $POD_NAME --follow

LoadBalancer ingress creation can take some time as well. Check service status with the command:

kubectl --namespace "default" get svc

Once the external IP is available and all the server certificates are generated create client key .ovpn files by pasting the following into a shell:

POD_NAME=$(kubectl get pods --namespace "default" -l "app=openvpn,release=openvpn-1584572359" -o jsonpath='{ .items[0].metadata.name }')
SERVICE_NAME=$(kubectl get svc --namespace "default" -l "app=openvpn,release=openvpn-1584572359" -o jsonpath='{ .items[0].metadata.name }')
SERVICE_IP=$(kubectl get svc --namespace "default" "$SERVICE_NAME" -o go-template='{{ range $k, $v := (index .status.loadBalancer.ingress 0)}}{{ $v }}{{end}}')
KEY_NAME=kubeVPN
kubectl --namespace "default" exec -it "$POD_NAME" /etc/openvpn/setup/newClientCert.sh "$KEY_NAME" "$SERVICE_IP"
kubectl --namespace "default" exec -it "$POD_NAME" cat "/etc/openvpn/certs/pki/$KEY_NAME.ovpn" > "$KEY_NAME.ovpn"

Revoking certificates works just as easy:
KEY_NAME=
POD_NAME=$(kubectl get pods -n "default" -l "app=openvpn,release=openvpn-1584572359" -o jsonpath='{.items[0].metadata.name}')
kubectl -n "default" exec -it "$POD_NAME" /etc/openvpn/setup/revokeClientCert.sh $KEY_NAME

Copy the resulting $KEY_NAME.ovpn file to your open vpn client (ex: in tunnelblick, just double click on the file). Do this for each user that needs to connect to the VPN. Change KEY_NAME for each additional user.

Como veis nos suelta un “churro” con las instrucciones a seguir. Y ya se ha generado un pod y servicio, que está esperando la configuración:

raulunzue@KBMASTER:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-deployment-elblogdenegu-6dbbf956cf-hxds8 1/1 Running 5 47d
hello-world-deployment-elblogdenegu-6dbbf956cf-rg882 1/1 Running 1 2d
openvpn-1584572359-f76bbc4c8-4f9ln 0/1 Pending 0 3m47s
raulunzue@KBMASTER:~$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world-deployment-elblogdenegu NodePort 10.96.198.40 80:31910/TCP 15m
kubernetes ClusterIP 10.96.0.1 443/TCP 71d
openvpn-1584572359 LoadBalancer 10.96.243.251 443:32592/TCP 3m57s

Así que proseguimos con las instrucciones. Averiguamos la versión de release de nuestro pod:

raulunzue@KBMASTER:~$ kubectl get pods -o json

instalar-openvpn-server-en-kubernetes-2

Y lanzamos el comando modificando $HELM_RELEASE:

POD_NAME=$(kubectl get pods -l "app=openvpn,release=$HELM_RELEASE" -o jsonpath='{.items[0].metadata.name}') && kubectl logs "$POD_NAME" --follow

POD_NAME=$(kubectl get pods -l "app=openvpn,release=openvpn-1584572359" -o jsonpath='{.items[0].metadata.name}') && kubectl logs "$POD_NAME" --follow

El proceso puede tardar MINUTOS, así que paciencia.

raulunzue@KBMASTER:~$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world-deployment-elblogdenegu NodePort 10.96.198.40 80:31910/TCP 39m
kubernetes ClusterIP 10.96.0.1 443/TCP 71d
openvpn-1584572359 LoadBalancer 10.96.243.251 443:32592/TCP 27m

Luego tendremos que lanzar el siguiente script para generar la Client KEY:

#!/bin/bash

if [ $# -ne 3 ] then
echo "Usage: $0 "
exit
fi

KEY_NAME=$1
NAMESPACE=$2
HELM_RELEASE=$3
POD_NAME=$(kubectl get pods -n "$NAMESPACE" -l "app=openvpn,release=$HELM_RELEASE" -o jsonpath='{.items[0].metadata.name}')
SERVICE_NAME=$(kubectl get svc -n "$NAMESPACE" -l "app=openvpn,release=$HELM_RELEASE" -o jsonpath='{.items[0].metadata.name}')
SERVICE_IP=$(kubectl get svc -n "$NAMESPACE" "$SERVICE_NAME" -o go-template='{{range $k, $v := (index .status.loadBalancer.ingress 0)}}{{$v}}{{end}}')
kubectl -n "$NAMESPACE" exec -it "$POD_NAME" /etc/openvpn/setup/newClientCert.sh "$KEY_NAME" "$SERVICE_IP"
kubectl -n "$NAMESPACE" exec -it "$POD_NAME" cat "/etc/openvpn/certs/pki/$KEY_NAME.ovpn" > "$KEY_NAME.ovpn"

Si necesitamos revocarlo:

#!/bin/bash

if [ $# -ne 3 ] then
echo "Usage: $0 "
exit
fi

KEY_NAME=$1
NAMESPACE=$2
HELM_RELEASE=$3
POD_NAME=$(kubectl get pods -n "$NAMESPACE" -l "app=openvpn,release=$HELM_RELEASE" -o jsonpath='{.items[0].metadata.name}')
kubectl -n "$NAMESPACE" exec -it "$POD_NAME" /etc/openvpn/setup/revokeClientCert.sh $KEY_NAME

Y ya tenemos nuestro OpenVPN server sobre Kubernetes.

Para más info: https://hub.kubeapps.com/charts/stable/openvpn/4.2.1

¿Te ha gustado la entrada SÍGUENOS EN TWITTER?

¿Te ha gustado la entrada SÍGUENOS EN TWITTER O INVITANOS A UN CAFE?

El Blog de Negu

Acerca de Raul Unzue Pulido

Administrador de sistemas virtuales e infraestructuras IT, linuxero y entusiasta de la tecnología.

Compruebe también

implementar-soc-instalar-thehive-cortex-y-misp-5

Implementar SOC: Instalar TheHive, Cortex y MISP

Implementar SOC: Instalar TheHive, Cortex y MISP En otras entradas hablamos de lo que es …

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

quince − doce =

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.

ACEPTAR
Aviso de cookies
Blog Maquinas Virtuales - El Blog de Negu