1 安装helm3.0
略过
2 下载charts
git clone https://hub.fastgit.org/helm/charts.git
3 安装openvpn
安装openvpn需要持久卷,没有可以安装一个nfs的默认存储类
3.1 进入openvpn目录
cd /root/helm/charts/stable/openvpn
3.2 修改configmap
cd /root/helm/charts/stable/openvpn/templates
vi config-openvpn.yaml
3.2.1 修改configure.sh
在最后一行exec ...
前加入以下行
# 加入ldap插件
apk add openvpn-auth-ldap --update-cache --repository http://dl-4.alpinelinux.org/alpine/edge/main/
# 开启ip转发
sysctl -w net.ipv4.ip_forward=1
3.2.2 修改openvpn.conf
在最后加入以下行,开启ldap
和客户端忽略cert
plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so "/etc/openvpn/setup/auth-ldap.conf uid=%u"
client-cert-not-required
3.2.3 加入新配置文件auth-ldap.conf
<LDAP>
URL ldap://你的ldapurl
BindDN 你的用来登陆验证的ldap账号
Password ldap账号密码
Timeout 15
TLSEnable no
FollowReferrals no
</LDAP>
<Authorization>
BaseDN "ldap用户的基础路径"
SearchFilter "uid=%u"
RequireGroup true
<Group>
BaseDN "组的base目录"
SearchFilter "(cn=openvpn)"
MemberAttribute uniqueMember
</Group>
</Authorization>
3.2.4 最终配置
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "openvpn.fullname" . }}
labels:
app: {{ template "openvpn.name" . }}
chart: {{ template "openvpn.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
auth-ldap.conf: |-
<LDAP>
URL ldap://10.247.30.15
BindDN cn=readonly,dc=mindflow,dc=com
Password mindflowreadonly
Timeout 15
TLSEnable no
FollowReferrals no
</LDAP>
<Authorization>
BaseDN "ou=users,dc=mindflow,dc=com"
SearchFilter "uid=%u"
RequireGroup true
<Group>
BaseDN "ou=confluence-jira,ou=group,dc=mindflow,dc=com"
SearchFilter "(cn=研发部)"
MemberAttribute uniqueMember
</Group>
</Authorization>
setup-certs.sh: |-
#!/bin/bash
EASY_RSA_LOC="/etc/openvpn/certs"
cd $EASY_RSA_LOC
SERVER_CERT="${EASY_RSA_LOC}/pki/issued/server.crt"
if [ -e "$SERVER_CERT" ]
then
echo "found existing certs - reusing"
{{- if .Values.openvpn.useCrl }}
if [ ! -e ${EASY_RSA_LOC}/crl.pem ]
then
echo "generating missed crl file"
./easyrsa gen-crl
cp ${EASY_RSA_LOC}/pki/crl.pem ${EASY_RSA_LOC}/crl.pem
chmod 644 ${EASY_RSA_LOC}/crl.pem
fi
{{- end }}
{{- if .Values.openvpn.taKey }}
if [ ! -e ${EASY_RSA_LOC}/pki/ta.key ]
then
echo "generating missed ta.key"
openvpn --genkey --secret ${EASY_RSA_LOC}/pki/ta.key
fi
{{- end }}
else
cp -R /usr/share/easy-rsa/* $EASY_RSA_LOC
./easyrsa init-pki
echo "ca\n" | ./easyrsa build-ca nopass
./easyrsa build-server-full server nopass
./easyrsa gen-dh
{{- if .Values.openvpn.useCrl }}
./easyrsa gen-crl
cp ${EASY_RSA_LOC}/pki/crl.pem ${EASY_RSA_LOC}/crl.pem # Note: the pki/ directory is inaccessible after openvpn drops privileges, so we cp crl.pem to ${EASY_RSA_LOC} to allow CRL updates without a restart
chmod 644 ${EASY_RSA_LOC}/crl.pem
{{- end }}
{{- if .Values.openvpn.taKey }}
openvpn --genkey --secret ${EASY_RSA_LOC}/pki/ta.key
{{- end }}
fi
newClientCert.sh: |-
#!/bin/bash
EASY_RSA_LOC="/etc/openvpn/certs"
cd $EASY_RSA_LOC
MY_IP_ADDR="$2"
./easyrsa build-client-full $1 nopass
cat >${EASY_RSA_LOC}/pki/$1.ovpn <<EOF
client
nobind
dev tun
{{- if eq .Values.service.type "NodePort" }}
remote ${MY_IP_ADDR} {{ .Values.service.nodePort }} {{ .Values.openvpn.OVPN_PROTO }}
{{- else }}
remote ${MY_IP_ADDR} {{ .Values.service.externalPort }} {{ .Values.openvpn.OVPN_PROTO }}
{{- end }}
{{ if .Values.openvpn.cipher }}
cipher {{ .Values.openvpn.cipher }}
{{- end }}
{{ if .Values.openvpn.redirectGateway }}
redirect-gateway def1
{{- end }}
{{ if .Values.openvpn.clientConf }}
{{ indent 6 .Values.openvpn.clientConf }}
{{- end }}
<key>
`cat ${EASY_RSA_LOC}/pki/private/$1.key`
</key>
<cert>
`cat ${EASY_RSA_LOC}/pki/issued/$1.crt`
</cert>
<ca>
`cat ${EASY_RSA_LOC}/pki/ca.crt`
</ca>
{{- if .Values.openvpn.taKey }}
<tls-auth>
`cat ${EASY_RSA_LOC}/pki/ta.key`
</tls-auth>
key-direction 1
{{- end }}
EOF
cat pki/$1.ovpn
revokeClientCert.sh: |-
#!/bin/bash
EASY_RSA_LOC="/etc/openvpn/certs"
cd $EASY_RSA_LOC
./easyrsa revoke $1
./easyrsa gen-crl
cp ${EASY_RSA_LOC}/pki/crl.pem ${EASY_RSA_LOC}
chmod 644 ${EASY_RSA_LOC}/crl.pem
configure.sh: |-
#!/bin/sh
cidr2mask() {
# Number of args to shift, 255..255, first non-255 byte, zeroes
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
[ $1 -gt 1 ] && shift "$1" || shift
echo ${1-0}.${2-0}.${3-0}.${4-0}
}
cidr2net() {
local i ip mask netOctets octets
ip="${1%/*}"
mask="${1#*/}"
octets=$(echo "$ip" | tr '.' '\n')
for octet in $octets; do
i=$((i+1))
if [ $i -le $(( mask / 8)) ]; then
netOctets="$netOctets.$octet"
elif [ $i -eq $(( mask / 8 +1 )) ]; then
netOctets="$netOctets.$((((octet / ((256 / ((2**((mask % 8)))))))) * ((256 / ((2**((mask % 8))))))))"
else
netOctets="$netOctets.0"
fi
done
echo ${netOctets#.}
}
/etc/openvpn/setup/setup-certs.sh
{{ if .Values.openvpn.istio.enabled }}
iptables -t nat -A PREROUTING -s {{ .Values.openvpn.OVPN_NETWORK }}/{{ .Values.openvpn.OVPN_SUBNET }} -i tun0 -p tcp -j REDIRECT --to-ports {{ .Values.openvpn.istio.proxy.port }}
{{ end }}
{{ range .Values.openvpn.iptablesExtra }}
iptables {{ . }}
{{ end }}
iptables -t nat -A POSTROUTING -s {{ .Values.openvpn.OVPN_NETWORK }}/{{ .Values.openvpn.OVPN_SUBNET }} -o eth0 -j MASQUERADE
mkdir -p /dev/net
if [ ! -c /dev/net/tun ]; then
mknod /dev/net/tun c 10 200
fi
if [ "$DEBUG" == "1" ]; then
echo ========== ${OVPN_CONFIG} ==========
cat "${OVPN_CONFIG}"
echo ====================================
fi
intAndIP="$(ip route get 8.8.8.8 | awk '/8.8.8.8/ {print $5 "-" $7}')"
int="${intAndIP%-*}"
ip="${intAndIP#*-}"
cidr="$(ip addr show dev "$int" | awk -vip="$ip" '($2 ~ ip) {print $2}')"
NETWORK="$(cidr2net $cidr)"
NETMASK="$(cidr2mask ${cidr#*/})"
DNS=$(cat /etc/resolv.conf | grep -v '^#' | grep nameserver | awk '{print $2}')
SEARCH=$(cat /etc/resolv.conf | grep -v '^#' | grep search | awk '{$1=""; print $0}')
FORMATTED_SEARCH=""
for DOMAIN in $SEARCH; do
FORMATTED_SEARCH="${FORMATTED_SEARCH}push \"dhcp-option DOMAIN-SEARCH ${DOMAIN}\"\n"
done
cp -f /etc/openvpn/setup/openvpn.conf /etc/openvpn/
sed 's|OVPN_K8S_SEARCH|'"${FORMATTED_SEARCH}"'|' -i /etc/openvpn/openvpn.conf
sed 's|OVPN_K8S_DNS|'"${DNS}"'|' -i /etc/openvpn/openvpn.conf
sed 's|NETWORK|'"${NETWORK}"'|' -i /etc/openvpn/openvpn.conf
sed 's|NETMASK|'"${NETMASK}"'|' -i /etc/openvpn/openvpn.conf
apk add openvpn-auth-ldap --update-cache --repository http://dl-4.alpinelinux.org/alpine/edge/main/
sysctl -w net.ipv4.ip_forward=1
exec openvpn --config /etc/openvpn/openvpn.conf
openvpn.conf: |-
server {{ .Values.openvpn.OVPN_NETWORK }} {{ .Values.openvpn.OVPN_SUBNET }}
verb 3
{{ if .Values.openvpn.useCrl }}
crl-verify /etc/openvpn/certs/crl.pem
{{ end }}
key /etc/openvpn/certs/pki/private/server.key
ca /etc/openvpn/certs/pki/ca.crt
cert /etc/openvpn/certs/pki/issued/server.crt
dh /etc/openvpn/certs/pki/dh.pem
{{ if .Values.openvpn.taKey }}
tls-auth /etc/openvpn/certs/pki/ta.key 0
{{ end }}
{{ if .Values.openvpn.cipher }}
cipher {{ .Values.openvpn.cipher }}
{{ end }}
key-direction 0
keepalive 10 60
persist-key
persist-tun
proto {{ .Values.openvpn.OVPN_PROTO }}
port {{ .Values.service.internalPort }}
dev tun0
status /tmp/openvpn-status.log
user nobody
group nogroup
{{ if .Values.openvpn.ccd.enabled }}
client-config-dir /etc/openvpn/ccd
{{ end }}
{{ if .Values.openvpn.DEFAULT_ROUTE_ENABLED }}
push "route NETWORK NETMASK"
{{ end }}
{{ if and (.Values.openvpn.OVPN_K8S_POD_NETWORK) (.Values.openvpn.OVPN_K8S_POD_SUBNET) }}
push "route {{ .Values.openvpn.OVPN_K8S_POD_NETWORK }} {{ .Values.openvpn.OVPN_K8S_POD_SUBNET }}"
{{ end }}
{{ if and (.Values.openvpn.OVPN_K8S_SVC_NETWORK) (.Values.openvpn.OVPN_K8S_SVC_SUBNET) }}
push "route {{ .Values.openvpn.OVPN_K8S_SVC_NETWORK }} {{ .Values.openvpn.OVPN_K8S_SVC_SUBNET }}"
{{ end }}
{{ if .Values.openvpn.dhcpOptionDomain }}
OVPN_K8S_SEARCH
{{ end }}
push "dhcp-option DNS OVPN_K8S_DNS"
plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so "/etc/openvpn/setup/auth-ldap.conf uid=%u"
client-cert-not-required
{{- if .Values.openvpn.serverConf }}
{{ indent 6 .Values.openvpn.serverConf }}
{{- end -}}
3.3 修改deployment
cd /root/helm/charts/stable/openvpn/templates
vi openvpn-deployment.yaml
3.3.1 修改主机权限
在securityContext
内加入privileged
,加入后的效果如下
...
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
...
4 启动openvpn服务
-
输入下方命令进行启动
cd /root/helm/charts/stable helm install openvpn openvpn/ -n ops
-
查看运行日志
kubectl logs -f $(kubectl get pod -n ops | grep openvpn | awk '{print $1}') -n ops
5 ovpn连接文件
5.1 创建ovpn
-
输入下方命令进入pod
kubectl exec -it $(kubectl get pod -n ops | grep openvpn | awk '{print $1}') sh -n ops
-
进入后输入以下命令会创建ovpn文件
cd /etc/openvpn/setup/ sh newClientCert.sh client名 连接的IP
-
下载ovpn文件
cd /etc/openvpn/certs/pki sz client名.ovpn
5.2 修改ovpn
-
将
redirect-gateway def1
删除(这行的意思是所有的流量都走vpn,如果有需要可以不删除) -
将
<key>
和<cert>
标签删除,注意<ca>
千万不要删除 -
修改端口并加入ldap的配置使用用户名密码
ns-cert-type server auth-user-pass
最终ovpn文件类似如下:
client
nobind
dev tun
remote 192.168.101.202 30803 tcp
ns-cert-type server
auth-user-pass
<ca>
-----BEGIN CERTIFICATE-----
很长一串的秘钥
-----END CERTIFICATE-----
</ca>
导入openvpn-client连接即可