0%

在K8S中部署带有ldap插件的openvpn

在K8S中部署带有ldap插件的openvpn

OpenVPN是一种虚拟专用网络(VPN) 系统,它实施技术以在路由或桥接配置和远程访问设施中创建安全的点对点或站点到站点连接。它实现客户端和服务器应用程序。

由于openvpn本身没带有ldap功能模块,所以需要集成ldap插件,这里部署时选用了开源的openvpn镜像(带有ldap模块)。

GitHub地址:https://github.com/wheelybird/openvpn-server-ldap-otp

下面先附上K8S部署openvpn的yaml文件,然后会一一解释参数的含义

openvpn.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
apiVersion: v1
kind: ConfigMap
metadata:
name: openvpn-config
data:
OVPN_SERVER_CN: '192.168.110.200'
LDAP_URI: 'ldap://192.168.110.200:1389'
LDAP_BASE_DN: 'ou=people,dc=finsiot,dc=com'
LDAP_BIND_USER_DN: 'cn=admin,dc=finsiot,dc=com'
LDAP_BIND_USER_PASS: '123456'
LDAP_LOGIN_ATTRIBUTE: 'uid'
LOG_TO_STDOUT: 'false'
OVPN_PROTOCOL: 'udp'
OVPN_ENABLE_COMPRESSION: 'false'
OVPN_MANAGEMENT_ENABLE: 'true'
#OVPN_MANAGEMENT_PASSWORD: 'admin'
OVPN_MANAGEMENT_NOAUTH: 'true'
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: openvpn
spec:
replicas: 1
selector:
matchLabels:
app: openvpn
template:
metadata:
labels:
app: openvpn
spec:
imagePullSecrets:
- name: docker-registry
containers:
- name: openvpn
resources:
limits:
cpu: "4"
memory: 4Gi
requests:
cpu: "100m"
memory: 100Mi
image: wheelybird/openvpn-ldap-otp:v1.4
imagePullPolicy: Always
securityContext:
privileged: true # 授予容器特权访问
ports:
- containerPort: 1194
- containerPort: 5555
envFrom:
- configMapRef:
name: openvpn-config
volumeMounts:
- mountPath: /etc/openvpn
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: openvpn-pvc
---
apiVersion: v1
kind: Service
metadata:
name: openvpn
spec:
externalIPs:
- 192.168.110.200
selector:
app: openvpn
type: NodePort
ports:
- port: 1194
targetPort: 1194
protocol: UDP
name: udp
- port: 5555
targetPort: 5555
protocol: TCP
name: tcp-management
yaml文件解释说明
1
yaml文件分为三段:全局环境变量、deployment部署文件、service部署文件
全局环境变量

这里按照镜像说明文档中提供的环境变量进行配置的:https://github.com/wheelybird/openvpn-server-ldap-otp

1
2
3
4
5
6
7
8
9
10
11
12
OVPN_SERVER_CN: openvpn的serverIP地址
LDAP_URI: LDAP的SERVER地址
LDAP_BASE_DN: LDAP用户地址
LDAP_BIND_USER_DN: LDAPadmin用户地址
LDAP_BIND_USER_PASS: LDAPadmin的密码
LDAP_LOGIN_ATTRIBUTE: LDAP用户名字段
LOG_TO_STDOUT: 将OpenVPN日志直接发送到标准输出。如果将其设置为false则首先写入日志/etc/openvpn/logs/openvpn.log,尽管一旦 OpenVPN 启动,此文件就会被发送到标准输出。
OVPN_PROTOCOL: openvpn的server提供方式:TCP或者UDP
OVPN_ENABLE_COMPRESSION: 这个是官方建议配置。VORACLE ATTACK利用了 OpenVPN 流量压缩中的一个漏洞,设置为false以此禁用压缩。默认情况下启用压缩以实现向后兼容性 - 如果客户端或服务器的配置已comp-lzo设置而另一个未设置,则隧道将中断。在此容器的先前版本中,压缩设置没有禁用它的选项,因此所有先前的客户端配置都将启用它。
OVPN_MANAGEMENT_ENABLE: 开启管理接口,默认是false。所有管理API请求或者管理页面服务需要通过这个接口访问OPENVPN SERVER
#OVPN_MANAGEMENT_PASSWORD: 这个是管理接口密码,这里注释的原因是因为下面要部署的oepnvpn管理页面不支持输入密码
OVPN_MANAGEMENT_NOAUTH: 默认为false,设置为true则管理接口不用认证就可以访问,和上面的password只能使用其一
deployment
1
2
3
4
5
6
这里用的镜像为 wheelybird/openvpn-ldap-otp的1.4版本,并未使用最新版本,因为这里本地测试最新版本有一些bug。(高版本会出现报错为nslcd: Warning: NSS_LDAP module not loaded: libnss_ldap.so.2: cannot open shared object file: No such file or directory)
容器需要以特权模式运行(因为openvpn有些操作需要最高权限),所以这里加入了特权模式配置securityContext: privileged: true
端口监听为1194和5555,其中1194是openvpnserver的监听端口,5555是management管理api端口。
envFrom配置加载了CONFIGMAP openvpn-config为环境变量,/etc/openvpn则是挂载的数据存储路径,/etc/openvpn中主要存储的是配置文件以及证书文件。

备注:这个版本问题需要后面研究一下,但目前的1.4是可以正常使用且未发现任何BUG的,最新版本运行有问题且直接通过官方dockerfile打出来也是不对的,如果后续有更新需求可能需要等作者在github更新或者手动更新调试。
service
1
2
这里service主要定义了两个端口1194和5555,需要注意的是由于上面环境变量定义了openvpn为udp端口监听,所以这里svc开放的也是udp,5555则是tcp
externalIPs定义了Kubernetes的入口ip以及端口(192.168.110.200:1194、192.168.110.200:5555)

client客户端连接

服务器端运行之后会将密钥文件打印至前台,大致格式如下:

image-20230602174240266

需要将#———- Start of client.ovpn ———-到#———- End of client.ovpn ———-之间的所有字符复制写入为kubeVPN.ovpn文件。

并下载openvpn客户端程序,将kubeVPN.ovpn文件放入到openvpn客户端安装目录的config目录下,然后连接时输入ldap账号密码即可

image-20230602174435634

openvpn-monitor部署

openvpnmonitor是开源的openvpn图形管理工具,有展示和简单的管理功能,这里附上部署的相关说明,其他类似monitor的图形web服务部署也基本一致,主要就是需要在部署运行时指定其openvpn的ip以及management的端口号,如果有密码认证还需要额外输入密码。

openvpn-monitor.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
apiVersion: v1
kind: ConfigMap
metadata:
name: openvpn-monitor-config
data:
OPENVPNMONITOR_DEFAULT_DATETIMEFORMAT: '"%%d/%%m/%%Y"'
OPENVPNMONITOR_DEFAULT_LATITUDE: '-37'
OPENVPNMONITOR_DEFAULT_LOGO: 'logo.jpg'
OPENVPNMONITOR_DEFAULT_LONGITUDE: '144'
OPENVPNMONITOR_DEFAULT_MAPS: 'True'
OPENVPNMONITOR_DEFAULT_MAPSHEIGHT: '500'
OPENVPNMONITOR_DEFAULT_SITE: 'Test'
OPENVPNMONITOR_SITES_0_ALIAS: 'TCP'
OPENVPNMONITOR_SITES_0_HOST: '192.168.110.200'
OPENVPNMONITOR_SITES_0_NAME: 'TCP'
OPENVPNMONITOR_SITES_0_PORT: '5555'
OPENVPNMONITOR_SITES_0_SHOWDISCONNECT: 'True'
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: openvpn-monitor
spec:
replicas: 1
selector:
matchLabels:
app: openvpn-monitor
template:
metadata:
labels:
app: openvpn-monitor
spec:
imagePullSecrets:
- name: docker-registry
containers:
- name: openvpn-monitor
resources:
limits:
cpu: "4"
memory: 4Gi
requests:
cpu: "100m"
memory: 100Mi
image: ruimarinho/openvpn-monitor
imagePullPolicy: Always
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: openvpn-monitor-config
---
apiVersion: v1
kind: Service
metadata:
name: openvpn-monitor
spec:
selector:
app: openvpn-monitor
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
name: tcp
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: openvpn-monitor
spec:
rules:
- host: openvpn-monitor.dev.finsiot.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: openvpn-monitor
port:
number: 80

部署文件说明

1
2
3
4
5
6
7
8
9
这里svc和ingress没有什么需要说明的,就是定义80端口以及域名。deployment使用的是dockerhub以及提供好的镜像ruimarinho/openvpn-monitor。
主要需要说明的是传入的环境变量openvpn-monitor-config。
环境变量中只有下面几个是需要修改的:
OPENVPNMONITOR_SITES_0_ALIAS: 'TCP' TCP或者UDP,这个是openvpn的连接方式
OPENVPNMONITOR_SITES_0_HOST: '192.168.110.200' openvpn服务器端IP
OPENVPNMONITOR_SITES_0_NAME: 'TCP' #名称
OPENVPNMONITOR_SITES_0_PORT: '5555' #management的端口
OPENVPNMONITOR_SITES_0_SHOWDISCONNECT: 'True' # DISCONNECT按钮显示,可以手动将用户踢下线。
备注:其他就没有需要特别说明的,但这个服务本身没有支持传入密码的变量,所以上面的OPENVPN在启用management的端口时是没有设置认证密码的。