include internal pki

This commit is contained in:
Sprait 2023-11-20 10:55:37 +00:00
parent f7c5a66992
commit 6d96f1f927
7 changed files with 1589 additions and 604 deletions

View File

@ -11,4 +11,16 @@ const (
stringDateFormat = "2006-01-02 15:04:05"
KubeNamespaceFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
)
secretCA = "openvpn-pki-ca"
secretServer = "openvpn-pki-server"
secretClientTmpl = "openvpn-pki-%d"
secretCRL = "openvpn-pki-crl"
secretIndexTxt = "openvpn-pki-index-txt"
secretDHandTA = "openvpn-pki-dh-and-ta"
certFileName = "tls.crt"
privKeyFileName = "tls.key"
//<year><month><day><hour><minute><second>Z
indexTxtDateFormat = "060102150405Z"
)

View File

@ -3,18 +3,13 @@ package backend
import (
"bytes"
"context"
"crypto/rsa"
"crypto/x509"
"errors"
"fmt"
"github.com/dgryski/dgoogauth"
"github.com/google/uuid"
// "github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
"io/ioutil"
"os"
"os/exec"
"strings"
"time"
log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
@ -23,52 +18,11 @@ import (
"k8s.io/client-go/rest"
)
const (
secretCA = "openvpn-pki-ca"
secretServer = "openvpn-pki-server"
secretClientTmpl = "openvpn-pki-%d"
secretCRL = "openvpn-pki-crl"
secretIndexTxt = "openvpn-pki-index-txt"
secretDHandTA = "openvpn-pki-dh-and-ta"
certFileName = "tls.crt"
privKeyFileName = "tls.key"
)
//<year><month><day><hour><minute><second>Z
const indexTxtDateFormat = "060102150405Z"
var namespace = "default"
type OpenVPNPKI struct {
CAPrivKeyRSA *rsa.PrivateKey
CAPrivKeyPEM *bytes.Buffer
CACert *x509.Certificate
CACertPEM *bytes.Buffer
ServerPrivKeyRSA *rsa.PrivateKey
ServerPrivKeyPEM *bytes.Buffer
ServerCert *x509.Certificate
ServerCertPEM *bytes.Buffer
ClientCerts []ClientCert
RevokedCerts []RevokedCert
KubeClient *kubernetes.Clientset
}
type ClientCert struct {
PrivKeyRSA *rsa.PrivateKey
PrivKeyPEM *bytes.Buffer
Cert *x509.Certificate
CertPEM *bytes.Buffer
}
type RevokedCert struct {
RevokedTime time.Time `json:"revokedTime"`
CommonName string `json:"commonName"`
Cert *x509.Certificate `json:"cert"`
}
func (openVPNPKI *OpenVPNPKI) Run() (err error) {
func (openVPNPKI *OpenVPNPKI) KubeRun() (err error) {
if _, err := os.Stat(KubeNamespaceFilePath); err == nil {
file, err := ioutil.ReadFile(KubeNamespaceFilePath)
file, err := os.ReadFile(KubeNamespaceFilePath)
if err != nil {
return err
}
@ -80,7 +34,7 @@ func (openVPNPKI *OpenVPNPKI) Run() (err error) {
return
}
err = openVPNPKI.initPKI()
err = openVPNPKI.InitPKI()
if err != nil {
return
}
@ -90,18 +44,6 @@ func (openVPNPKI *OpenVPNPKI) Run() (err error) {
log.Error(err)
}
err = openVPNPKI.easyrsaGenCRL()
if err != nil {
log.Error(err)
}
if res, _ := openVPNPKI.secretCheckExists(secretDHandTA); !res {
err := openVPNPKI.secretGenTaKeyAndDHParam()
if err != nil {
log.Error(err)
}
}
err = openVPNPKI.updateFilesFromSecrets()
if err != nil {
log.Error(err)
@ -131,243 +73,243 @@ func (openVPNPKI *OpenVPNPKI) initKubeClient() (err error) {
return
}
func (openVPNPKI *OpenVPNPKI) initPKI() (err error) {
if res, _ := openVPNPKI.secretCheckExists(secretCA); res {
cert, err := openVPNPKI.secretGetClientCert(secretCA)
if err != nil {
return err
}
// func (openVPNPKI *OpenVPNPKI) initPKI() (err error) {
// if res, _ := openVPNPKI.secretCheckExists(secretCA); res {
// cert, err := openVPNPKI.secretGetClientCert(secretCA)
// if err != nil {
// return err
// }
openVPNPKI.CAPrivKeyPEM = cert.PrivKeyPEM
openVPNPKI.CAPrivKeyRSA = cert.PrivKeyRSA
openVPNPKI.CACertPEM = cert.CertPEM
openVPNPKI.CACert = cert.Cert
} else {
openVPNPKI.CAPrivKeyPEM, err = GenPrivKey()
if err != nil {
return
}
openVPNPKI.CAPrivKeyRSA, err = DecodePrivKey(openVPNPKI.CAPrivKeyPEM.Bytes())
// openVPNPKI.CAPrivKeyPEM = cert.PrivKeyPEM
// openVPNPKI.CAPrivKeyRSA = cert.PrivKeyRSA
// openVPNPKI.CACertPEM = cert.CertPEM
// openVPNPKI.CACert = cert.Cert
// } else {
// openVPNPKI.CAPrivKeyPEM, err = GenPrivKey()
// if err != nil {
// return
// }
// openVPNPKI.CAPrivKeyRSA, err = DecodePrivKey(openVPNPKI.CAPrivKeyPEM.Bytes())
openVPNPKI.CACertPEM, _ = GenCA(openVPNPKI.CAPrivKeyRSA)
openVPNPKI.CACert, err = DecodeCert(openVPNPKI.CACertPEM.Bytes())
if err != nil {
return
}
// openVPNPKI.CACertPEM, _ = GenCA(openVPNPKI.CAPrivKeyRSA)
// openVPNPKI.CACert, err = DecodeCert(openVPNPKI.CACertPEM.Bytes())
// if err != nil {
// return
// }
secretMetaData := metav1.ObjectMeta{Name: secretCA}
// secretMetaData := metav1.ObjectMeta{Name: secretCA}
secretData := map[string][]byte{
certFileName: openVPNPKI.CACertPEM.Bytes(),
privKeyFileName: openVPNPKI.CAPrivKeyPEM.Bytes(),
}
// secretData := map[string][]byte{
// certFileName: openVPNPKI.CACertPEM.Bytes(),
// privKeyFileName: openVPNPKI.CAPrivKeyPEM.Bytes(),
// }
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
if err != nil {
return
}
}
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
// if err != nil {
// return
// }
// }
if res, _ := openVPNPKI.secretCheckExists(secretServer); res {
cert, err := openVPNPKI.secretGetClientCert(secretServer)
if err != nil {
return err
}
// if res, _ := openVPNPKI.secretCheckExists(secretServer); res {
// cert, err := openVPNPKI.secretGetClientCert(secretServer)
// if err != nil {
// return err
// }
openVPNPKI.ServerPrivKeyPEM = cert.PrivKeyPEM
openVPNPKI.ServerPrivKeyRSA = cert.PrivKeyRSA
openVPNPKI.ServerCertPEM = cert.CertPEM
openVPNPKI.ServerCert = cert.Cert
} else {
openVPNPKI.ServerPrivKeyPEM, err = GenPrivKey()
if err != nil {
return
}
// openVPNPKI.ServerPrivKeyPEM = cert.PrivKeyPEM
// openVPNPKI.ServerPrivKeyRSA = cert.PrivKeyRSA
// openVPNPKI.ServerCertPEM = cert.CertPEM
// openVPNPKI.ServerCert = cert.Cert
// } else {
// openVPNPKI.ServerPrivKeyPEM, err = GenPrivKey()
// if err != nil {
// return
// }
openVPNPKI.ServerPrivKeyRSA, err = DecodePrivKey(openVPNPKI.ServerPrivKeyPEM.Bytes())
if err != nil {
return
}
// openVPNPKI.ServerPrivKeyRSA, err = DecodePrivKey(openVPNPKI.ServerPrivKeyPEM.Bytes())
// if err != nil {
// return
// }
openVPNPKI.ServerCertPEM, _ = GenServerCert(openVPNPKI.ServerPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, "server")
openVPNPKI.ServerCert, err = DecodeCert(openVPNPKI.ServerCertPEM.Bytes())
// openVPNPKI.ServerCertPEM, _ = GenServerCert(openVPNPKI.ServerPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, "server")
// openVPNPKI.ServerCert, err = DecodeCert(openVPNPKI.ServerCertPEM.Bytes())
secretMetaData := metav1.ObjectMeta{
Name: secretServer,
Labels: map[string]string{
"index.txt": "",
"name": "server",
"type": "serverAuth",
},
}
// secretMetaData := metav1.ObjectMeta{
// Name: secretServer,
// Labels: map[string]string{
// "index.txt": "",
// "name": "server",
// "type": "serverAuth",
// },
// }
secretData := map[string][]byte{
certFileName: openVPNPKI.ServerCertPEM.Bytes(),
privKeyFileName: openVPNPKI.ServerPrivKeyPEM.Bytes(),
}
// secretData := map[string][]byte{
// certFileName: openVPNPKI.ServerCertPEM.Bytes(),
// privKeyFileName: openVPNPKI.ServerPrivKeyPEM.Bytes(),
// }
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
if err != nil {
return
}
}
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
// if err != nil {
// return
// }
// }
return
}
// return
// }
func (openVPNPKI *OpenVPNPKI) indexTxtUpdate() (err error) {
secrets, err := openVPNPKI.secretsGetByLabels("index.txt=")
if err != nil {
return
}
// func (openVPNPKI *OpenVPNPKI) indexTxtUpdate() (err error) {
// secrets, err := openVPNPKI.secretsGetByLabels("index.txt=")
// if err != nil {
// return
// }
var indexTxt string
for _, secret := range secrets.Items {
certPEM := bytes.NewBuffer(secret.Data[certFileName])
log.Trace("indexTxtUpdate:" + secret.Name)
cert, err := DecodeCert(certPEM.Bytes())
if err != nil {
return nil
}
// var indexTxt string
// for _, secret := range secrets.Items {
// certPEM := bytes.NewBuffer(secret.Data[certFileName])
// log.Trace("indexTxtUpdate:" + secret.Name)
// cert, err := DecodeCert(certPEM.Bytes())
// if err != nil {
// return nil
// }
log.Trace(cert.Subject.CommonName)
// log.Trace(cert.Subject.CommonName)
if secret.Annotations["revokedAt"] == "" {
indexTxt += fmt.Sprintf("%s\t%s\t\t%s\t%s\t%s\n", "V", cert.NotAfter.Format(indexTxtDateFormat), fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
} else if cert.NotAfter.Before(time.Now()) {
indexTxt += fmt.Sprintf("%s\t%s\t\t%s\t%s\t%s\n", "E", cert.NotAfter.Format(indexTxtDateFormat), fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
} else {
indexTxt += fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t%s\n", "R", cert.NotAfter.Format(indexTxtDateFormat), secret.Annotations["revokedAt"], fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
}
// if secret.Annotations["revokedAt"] == "" {
// indexTxt += fmt.Sprintf("%s\t%s\t\t%s\t%s\t%s\n", "V", cert.NotAfter.Format(indexTxtDateFormat), fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
// } else if cert.NotAfter.Before(time.Now()) {
// indexTxt += fmt.Sprintf("%s\t%s\t\t%s\t%s\t%s\n", "E", cert.NotAfter.Format(indexTxtDateFormat), fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
// } else {
// indexTxt += fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t%s\n", "R", cert.NotAfter.Format(indexTxtDateFormat), secret.Annotations["revokedAt"], fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
// }
}
// }
secretMetaData := metav1.ObjectMeta{Name: secretIndexTxt}
// secretMetaData := metav1.ObjectMeta{Name: secretIndexTxt}
secretData := map[string][]byte{"index.txt": []byte(indexTxt)}
// secretData := map[string][]byte{"index.txt": []byte(indexTxt)}
if res, _ := openVPNPKI.secretCheckExists(secretIndexTxt); !res {
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
} else {
err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
}
// if res, _ := openVPNPKI.secretCheckExists(secretIndexTxt); !res {
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
// } else {
// err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
// }
return
}
// return
// }
func (openVPNPKI *OpenVPNPKI) updateIndexTxtOnDisk() (err error) {
secret, err := openVPNPKI.secretGetByName(secretIndexTxt)
indexTxt := secret.Data["index.txt"]
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/index.txt", *EasyrsaDirPath), indexTxt, 0600)
err = fWriteRaw(fmt.Sprintf("%s/pki/index.txt", *EasyrsaDirPath), indexTxt, 0600)
return
}
func (openVPNPKI *OpenVPNPKI) easyrsaGenCRL() (err error) {
err = openVPNPKI.indexTxtUpdate()
if err != nil {
return
}
// func (openVPNPKI *OpenVPNPKI) easyrsaGenCRL() (err error) {
// err = openVPNPKI.indexTxtUpdate()
// if err != nil {
// return
// }
secrets, err := openVPNPKI.secretsGetByLabels("index.txt=,type=clientAuth")
if err != nil {
return
}
// secrets, err := openVPNPKI.secretsGetByLabels("index.txt=,type=clientAuth")
// if err != nil {
// return
// }
var revoked []*RevokedCert
// var revoked []*RevokedCert
for _, secret := range secrets.Items {
if secret.Annotations["revokedAt"] != "" {
revokedAt, err := time.Parse(indexTxtDateFormat, secret.Annotations["revokedAt"])
if err != nil {
log.Warning(err)
}
cert, err := DecodeCert(secret.Data[certFileName])
revoked = append(revoked, &RevokedCert{RevokedTime: revokedAt, Cert: cert})
}
}
// for _, secret := range secrets.Items {
// if secret.Annotations["revokedAt"] != "" {
// revokedAt, err := time.Parse(indexTxtDateFormat, secret.Annotations["revokedAt"])
// if err != nil {
// log.Warning(err)
// }
// cert, err := DecodeCert(secret.Data[certFileName])
// revoked = append(revoked, &RevokedCert{RevokedTime: revokedAt, Cert: cert})
// }
// }
crl, err := GenCRL(revoked, openVPNPKI.CACert, openVPNPKI.CAPrivKeyRSA)
if err != nil {
return
}
// crl, err := GenCRL(revoked, openVPNPKI.CACert, openVPNPKI.CAPrivKeyRSA)
// if err != nil {
// return
// }
secretMetaData := metav1.ObjectMeta{Name: secretCRL}
// secretMetaData := metav1.ObjectMeta{Name: secretCRL}
secretData := map[string][]byte{
"crl.pem": crl.Bytes(),
}
// secretData := map[string][]byte{
// "crl.pem": crl.Bytes(),
// }
//err = openVPNPKI.secretCreate(secretMetaData, secretData)
// //err = openVPNPKI.secretCreate(secretMetaData, secretData)
if res, _ := openVPNPKI.secretCheckExists(secretCRL); !res {
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
} else {
err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
}
// if res, _ := openVPNPKI.secretCheckExists(secretCRL); !res {
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
// } else {
// err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
// }
return
}
// return
// }
func (openVPNPKI *OpenVPNPKI) EasyrsaBuildClient(commonName string) (err error) {
// check certificate exists
_, err = openVPNPKI.secretGetByLabels("name=" + commonName)
if err == nil {
return errors.New(fmt.Sprintf("certificate for user (%s) already exists", commonName))
}
// func (openVPNPKI *OpenVPNPKI) EasyrsaBuildClient(commonName string) (err error) {
// // check certificate exists
// _, err = openVPNPKI.secretGetByLabels("name=" + commonName)
// if err == nil {
// return errors.New(fmt.Sprintf("certificate for user (%s) already exists", commonName))
// }
clientPrivKeyPEM, err := GenPrivKey()
if err != nil {
return
}
// clientPrivKeyPEM, err := GenPrivKey()
// if err != nil {
// return
// }
clientPrivKeyRSA, err := DecodePrivKey(clientPrivKeyPEM.Bytes())
if err != nil {
return
}
// clientPrivKeyRSA, err := DecodePrivKey(clientPrivKeyPEM.Bytes())
// if err != nil {
// return
// }
clientCertPEM, _ := GenClientCert(clientPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, commonName)
clientCert, err := DecodeCert(clientCertPEM.Bytes())
// clientCertPEM, _ := GenClientCert(clientPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, commonName)
// clientCert, err := DecodeCert(clientCertPEM.Bytes())
secretMetaData := metav1.ObjectMeta{
Name: fmt.Sprintf(secretClientTmpl, clientCert.SerialNumber),
Labels: map[string]string{
"index.txt": "",
"type": "clientAuth",
"name": commonName,
"app.kubernetes.io/managed-by": "ovpn-admin",
},
Annotations: map[string]string{
"commonName": commonName,
"notBefore": clientCert.NotBefore.Format(indexTxtDateFormat),
"notAfter": clientCert.NotAfter.Format(indexTxtDateFormat),
"revokedAt": "",
"serialNumber": fmt.Sprintf("%d", clientCert.SerialNumber),
},
}
// secretMetaData := metav1.ObjectMeta{
// Name: fmt.Sprintf(secretClientTmpl, clientCert.SerialNumber),
// Labels: map[string]string{
// "index.txt": "",
// "type": "clientAuth",
// "name": commonName,
// "app.kubernetes.io/managed-by": "ovpn-admin",
// },
// Annotations: map[string]string{
// "commonName": commonName,
// "notBefore": clientCert.NotBefore.Format(indexTxtDateFormat),
// "notAfter": clientCert.NotAfter.Format(indexTxtDateFormat),
// "revokedAt": "",
// "serialNumber": fmt.Sprintf("%d", clientCert.SerialNumber),
// },
// }
secretData := map[string][]byte{
certFileName: clientCertPEM.Bytes(),
privKeyFileName: clientPrivKeyPEM.Bytes(),
}
// secretData := map[string][]byte{
// certFileName: clientCertPEM.Bytes(),
// privKeyFileName: clientPrivKeyPEM.Bytes(),
// }
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
if err != nil {
return
}
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
// if err != nil {
// return
// }
err = openVPNPKI.indexTxtUpdate()
if err != nil {
return
}
// err = openVPNPKI.indexTxtUpdate()
// if err != nil {
// return
// }
err = openVPNPKI.updateIndexTxtOnDisk()
// err = openVPNPKI.updateIndexTxtOnDisk()
return
}
// return
// }
func (openVPNPKI *OpenVPNPKI) easyrsaGetCACert() string {
return openVPNPKI.CACertPEM.String()
}
// func (openVPNPKI *OpenVPNPKI) easyrsaGetCACert() string {
// return openVPNPKI.CACertPEM.String()
// }
func (openVPNPKI *OpenVPNPKI) EasyrsaGetClientCert(commonName string) (cert, key string) {
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
@ -381,148 +323,148 @@ func (openVPNPKI *OpenVPNPKI) EasyrsaGetClientCert(commonName string) (cert, key
return
}
func (openVPNPKI *OpenVPNPKI) EasyrsaRevoke(commonName string) (err error) {
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
if err != nil {
log.Error(err)
}
// func (openVPNPKI *OpenVPNPKI) EasyrsaRevoke(commonName string) (err error) {
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
// if err != nil {
// log.Error(err)
// }
if secret.Annotations["revokedAt"] != "" {
log.Warnf("user (%s) already revoked", commonName)
return
}
// if secret.Annotations["revokedAt"] != "" {
// log.Warnf("user (%s) already revoked", commonName)
// return
// }
secret.Annotations["revokedAt"] = time.Now().Format(indexTxtDateFormat)
// secret.Annotations["revokedAt"] = time.Now().Format(indexTxtDateFormat)
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
if err != nil {
return
}
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
// if err != nil {
// return
// }
err = openVPNPKI.indexTxtUpdate()
if err != nil {
return
}
// err = openVPNPKI.indexTxtUpdate()
// if err != nil {
// return
// }
err = openVPNPKI.updateIndexTxtOnDisk()
if err != nil {
return
}
// err = openVPNPKI.updateIndexTxtOnDisk()
// if err != nil {
// return
// }
err = openVPNPKI.easyrsaGenCRL()
if err != nil {
log.Error(err)
}
// err = openVPNPKI.easyrsaGenCRL()
// if err != nil {
// log.Error(err)
// }
err = openVPNPKI.updateCRLOnDisk()
// err = openVPNPKI.updateCRLOnDisk()
return
}
// return
// }
func (openVPNPKI *OpenVPNPKI) EasyrsaUnrevoke(commonName string) (err error) {
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
if err != nil {
log.Error(err)
}
// func (openVPNPKI *OpenVPNPKI) EasyrsaUnrevoke(commonName string) (err error) {
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
// if err != nil {
// log.Error(err)
// }
secret.Annotations["revokedAt"] = ""
// secret.Annotations["revokedAt"] = ""
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
if err != nil {
return
}
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
// if err != nil {
// return
// }
err = openVPNPKI.indexTxtUpdate()
if err != nil {
return
}
// err = openVPNPKI.indexTxtUpdate()
// if err != nil {
// return
// }
err = openVPNPKI.updateIndexTxtOnDisk()
if err != nil {
return
}
// err = openVPNPKI.updateIndexTxtOnDisk()
// if err != nil {
// return
// }
err = openVPNPKI.easyrsaGenCRL()
if err != nil {
log.Error(err)
}
// err = openVPNPKI.easyrsaGenCRL()
// if err != nil {
// log.Error(err)
// }
err = openVPNPKI.updateCRLOnDisk()
// err = openVPNPKI.updateCRLOnDisk()
return
}
// return
// }
func (openVPNPKI *OpenVPNPKI) EasyrsaRotate(commonName string) (err error) {
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
if err != nil {
log.Error(err)
}
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
secret.Labels["name"] = "REVOKED" + commonName
secret.Labels["revokedForever"] = "true"
// func (openVPNPKI *OpenVPNPKI) EasyrsaRotate(commonName string) (err error) {
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
// if err != nil {
// log.Error(err)
// }
// uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
// secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
// secret.Labels["name"] = "REVOKED" + commonName
// secret.Labels["revokedForever"] = "true"
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
if err != nil {
return
}
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
// if err != nil {
// return
// }
err = openVPNPKI.EasyrsaBuildClient(commonName)
if err != nil {
return
}
// err = openVPNPKI.EasyrsaBuildClient(commonName)
// if err != nil {
// return
// }
err = openVPNPKI.indexTxtUpdate()
if err != nil {
return
}
// err = openVPNPKI.indexTxtUpdate()
// if err != nil {
// return
// }
err = openVPNPKI.updateIndexTxtOnDisk()
if err != nil {
return
}
// err = openVPNPKI.updateIndexTxtOnDisk()
// if err != nil {
// return
// }
err = openVPNPKI.easyrsaGenCRL()
if err != nil {
log.Error(err)
}
// err = openVPNPKI.easyrsaGenCRL()
// if err != nil {
// log.Error(err)
// }
err = openVPNPKI.updateCRLOnDisk()
return
}
func (openVPNPKI *OpenVPNPKI) EasyrsaDelete(commonName string) (err error) {
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
if err != nil {
log.Error(err)
}
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
secret.Labels["name"] = "REVOKED-" + commonName + "-" + uniqHash
secret.Labels["revokedForever"] = "true"
// err = openVPNPKI.updateCRLOnDisk()
// return
// }
// func (openVPNPKI *OpenVPNPKI) EasyrsaDelete(commonName string) (err error) {
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
// if err != nil {
// log.Error(err)
// }
// uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
// secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
// secret.Labels["name"] = "REVOKED-" + commonName + "-" + uniqHash
// secret.Labels["revokedForever"] = "true"
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
if err != nil {
return
}
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
// if err != nil {
// return
// }
err = openVPNPKI.indexTxtUpdate()
if err != nil {
return
}
// err = openVPNPKI.indexTxtUpdate()
// if err != nil {
// return
// }
err = openVPNPKI.updateIndexTxtOnDisk()
if err != nil {
return
}
// err = openVPNPKI.updateIndexTxtOnDisk()
// if err != nil {
// return
// }
err = openVPNPKI.easyrsaGenCRL()
if err != nil {
log.Error(err)
}
// err = openVPNPKI.easyrsaGenCRL()
// if err != nil {
// log.Error(err)
// }
err = openVPNPKI.updateCRLOnDisk()
return
}
// err = openVPNPKI.updateCRLOnDisk()
// return
// }
func (openVPNPKI *OpenVPNPKI) secretGetClientCert(name string) (cert ClientCert, err error) {
secret, err := openVPNPKI.secretGetByName(name)
@ -546,12 +488,12 @@ func (openVPNPKI *OpenVPNPKI) secretGetClientCert(name string) (cert ClientCert,
}
func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
ca, err := openVPNPKI.secretGetClientCert(secretCA)
ca, err := openVPNPKI.getExistCert(secretCA)
if err != nil {
return
}
server, err := openVPNPKI.secretGetClientCert(secretServer)
server, err := openVPNPKI.getExistCert(secretServer)
if err != nil {
return
}
@ -568,27 +510,27 @@ func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
err = os.MkdirAll(fmt.Sprintf("%s/pki/private", *EasyrsaDirPath), 0755)
}
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/ca.crt", *EasyrsaDirPath), ca.CertPEM.Bytes(), 0600)
err = os.WriteFile(fmt.Sprintf("%s/pki/ca.crt", *EasyrsaDirPath), ca.CertPEM.Bytes(), 0600)
if err != nil {
return
}
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/issued/server.crt", *EasyrsaDirPath), server.CertPEM.Bytes(), 0600)
err = os.WriteFile(fmt.Sprintf("%s/pki/issued/server.crt", *EasyrsaDirPath), server.CertPEM.Bytes(), 0600)
if err != nil {
return
}
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/private/server.key", *EasyrsaDirPath), server.PrivKeyPEM.Bytes(), 0600)
err = os.WriteFile(fmt.Sprintf("%s/pki/private/server.key", *EasyrsaDirPath), server.PrivKeyPEM.Bytes(), 0600)
if err != nil {
return
}
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/ta.key", *EasyrsaDirPath), takey, 0600)
err = os.WriteFile(fmt.Sprintf("%s/pki/ta.key", *EasyrsaDirPath), takey, 0600)
if err != nil {
return
}
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/dh.pem", *EasyrsaDirPath), dhparam, 0600)
err = os.WriteFile(fmt.Sprintf("%s/pki/dh.pem", *EasyrsaDirPath), dhparam, 0600)
if err != nil {
return
}
@ -600,45 +542,45 @@ func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
func (openVPNPKI *OpenVPNPKI) updateCRLOnDisk() (err error) {
secret, err := openVPNPKI.secretGetByName(secretCRL)
crl := secret.Data["crl.pem"]
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/crl.pem", *EasyrsaDirPath), crl, 0644)
err = os.WriteFile(fmt.Sprintf("%s/pki/crl.pem", *EasyrsaDirPath), crl, 0644)
if err != nil {
log.Errorf("error write crl.pem:%s", err.Error())
}
return
}
func (openVPNPKI *OpenVPNPKI) secretGenTaKeyAndDHParam() (err error) {
taKeyPath := "/tmp/ta.key"
cmd := exec.Command("bash", "-c", fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s", taKeyPath))
stdout, err := cmd.CombinedOutput()
log.Info(fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s: %s", taKeyPath, string(stdout)))
if err != nil {
return
}
taKey, err := ioutil.ReadFile(taKeyPath)
// func (openVPNPKI *OpenVPNPKI) secretGenTaKeyAndDHParam() (err error) {
// taKeyPath := "/tmp/ta.key"
// cmd := exec.Command("bash", "-c", fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s", taKeyPath))
// stdout, err := cmd.CombinedOutput()
// log.Info(fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s: %s", taKeyPath, string(stdout)))
// if err != nil {
// return
// }
// taKey, err := os.ReadFile(taKeyPath)
dhparamPath := "/tmp/dh.pem"
cmd = exec.Command("bash", "-c", fmt.Sprintf("openssl dhparam -out %s 2048", dhparamPath))
_, err = cmd.CombinedOutput()
if err != nil {
return
}
dhparam, err := ioutil.ReadFile(dhparamPath)
// dhparamPath := "/tmp/dh.pem"
// cmd = exec.Command("bash", "-c", fmt.Sprintf("openssl dhparam -out %s 2048", dhparamPath))
// _, err = cmd.CombinedOutput()
// if err != nil {
// return
// }
// dhparam, err := os.ReadFile(dhparamPath)
secretMetaData := metav1.ObjectMeta{Name: secretDHandTA}
// secretMetaData := metav1.ObjectMeta{Name: secretDHandTA}
secretData := map[string][]byte{
"ta.key": taKey,
"dh.pem": dhparam,
}
// secretData := map[string][]byte{
// "ta.key": taKey,
// "dh.pem": dhparam,
// }
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
if err != nil {
return
}
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
// if err != nil {
// return
// }
return
}
// return
// }
// ccd
@ -690,7 +632,7 @@ func (openVPNPKI *OpenVPNPKI) updateCcdOnDisk() error {
for _, secret := range secrets.Items {
ccd := secret.Data["ccd"]
if len(ccd) > 0 {
err = ioutil.WriteFile(fmt.Sprintf("%s/%s", *CcdDir, secret.Labels["name"]), ccd, 0644)
err = os.WriteFile(fmt.Sprintf("%s/%s", *CcdDir, secret.Labels["name"]), ccd, 0644)
if err != nil {
log.Error(err)
}

View File

@ -14,7 +14,6 @@ import (
"text/template"
"time"
"github.com/google/uuid"
ou "github.com/pashcovich/openvpn-user/src"
log "github.com/sirupsen/logrus"
)
@ -280,7 +279,7 @@ func (oAdmin *OvpnAdmin) usersList() []OpenvpnClient {
apochNow := time.Now().Unix()
for _, line := range IndexTxtParser(fRead(*IndexTxtPath)) {
if line.Identity != "server" && !strings.Contains(line.Identity, "REVOKED") {
if line.Identity != "server" && line.Identity != "ca" && !strings.Contains(line.Identity, "REVOKED") {
totalCerts += 1
ovpnClient := OpenvpnClient{Identity: line.Identity, ExpirationDate: parseDateToString(indexTxtDateLayout, line.ExpirationDate, stringDateFormat)}
switch {
@ -365,33 +364,28 @@ func (oAdmin *OvpnAdmin) userCreate(username, password string) (string, error) {
}
}
if *StorageBackend == "kubernetes.secrets" {
err := oAdmin.KubeClient.EasyrsaBuildClient(username)
if err != nil {
log.Error(err)
return err.Error(), err
}
if oAdmin.ExtraAuth {
err := oAdmin.PKI.BuildKeyPairClient(username)
if err != nil {
log.Error(err)
return err.Error(), err
}
if oAdmin.ExtraAuth {
switch *StorageBackend {
case "kubernetes.secrets":
err = oAdmin.KubeClient.updatePasswordSecret(username, []byte(password))
if err != nil {
return err.Error(), err
}
}
} else {
o := runBash(fmt.Sprintf("cd %s && %s build-client-full %s nopass 1>/dev/null", *EasyrsaDirPath, *EasyrsaBinPath, username))
log.Debug(o)
if oAdmin.ExtraAuth {
case "filesystems":
_, err := oAdmin.OUser.CreateUser(username, password)
if err != nil {
return err.Error(), err
}
}
}
log.Infof("Certificate for user %s issued", username)
//oAdmin.clients = oAdmin.usersList()
return "", nil
}
@ -409,13 +403,13 @@ func (oAdmin *OvpnAdmin) userChangePassword(username, password string) (error, s
log.Warningf("userChangePassword: %s", err.Error())
return err, err.Error()
}
if *StorageBackend == "kubernetes.secrets" {
switch *StorageBackend {
case "kubernetes.secrets":
err := oAdmin.KubeClient.updatePasswordSecret(username, []byte(password))
if err != nil {
return err, err.Error()
}
} else {
case "filesystem":
msg, err := oAdmin.OUser.ChangeUserPassword(username, password)
if err != nil {
return err, msg
@ -630,19 +624,13 @@ func (oAdmin *OvpnAdmin) getUserStatistic(username string) []ClientStatus {
func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
log.Infof("Revoke certificate for user %s", username)
if checkUserExist(username) {
// check certificate valid flag 'V'
if *StorageBackend == "kubernetes.secrets" {
err := oAdmin.KubeClient.EasyrsaRevoke(username)
if err != nil {
log.Error(err)
}
} else {
o := runBash(fmt.Sprintf("cd %[1]s && echo yes | %[2]s revoke %[3]s 1>/dev/null && %[2]s gen-crl 1>/dev/null", *EasyrsaDirPath, *EasyrsaBinPath, username))
log.Debugln(o)
err := oAdmin.PKI.CertificateRevoke(username)
if err != nil {
log.Error(err)
}
if oAdmin.ExtraAuth {
if oAdmin.OUser.CheckUserExistent(username) {
if *StorageBackend == "filesystem" {
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
revokeMsg, revokeErr := oAdmin.OUser.RevokedUser(username)
log.Debug(revokeMsg)
log.Debug(revokeErr)
@ -652,7 +640,6 @@ func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
}
}
crlFix()
userConnected, userConnectedTo := isUserConnected(username, oAdmin.activeClients)
log.Tracef("User %s connected: %t", username, userConnected)
if userConnected {
@ -671,67 +658,23 @@ func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
func (oAdmin *OvpnAdmin) userUnrevoke(username string) (error, string) {
if checkUserExist(username) {
if *StorageBackend == "kubernetes.secrets" {
err := oAdmin.KubeClient.EasyrsaUnrevoke(username)
if err != nil {
log.Error(err)
}
} else {
// check certificate revoked flag 'R'
usersFromIndexTxt := IndexTxtParser(fRead(*IndexTxtPath))
for i := range usersFromIndexTxt {
if usersFromIndexTxt[i].DistinguishedName == "/CN="+username {
if usersFromIndexTxt[i].Flag == "R" {
usersFromIndexTxt[i].Flag = "V"
usersFromIndexTxt[i].RevocationDate = ""
err := oAdmin.PKI.CertificateUnRevoke(username)
if err != nil {
log.Error(err)
}
err := fMove(fmt.Sprintf("%s/pki/revoked/certs_by_serial/%s.crt", *EasyrsaDirPath, usersFromIndexTxt[i].SerialNumber), fmt.Sprintf("%s/pki/issued/%s.crt", *EasyrsaDirPath, username))
if err != nil {
log.Error(err)
}
err = fMove(fmt.Sprintf("%s/pki/revoked/certs_by_serial/%s.crt", *EasyrsaDirPath, usersFromIndexTxt[i].SerialNumber), fmt.Sprintf("%s/pki/certs_by_serial/%s.pem", *EasyrsaDirPath, usersFromIndexTxt[i].SerialNumber))
if err != nil {
log.Error(err)
}
err = fMove(fmt.Sprintf("%s/pki/revoked/private_by_serial/%s.key", *EasyrsaDirPath, usersFromIndexTxt[i].SerialNumber), fmt.Sprintf("%s/pki/private/%s.key", *EasyrsaDirPath, username))
if err != nil {
log.Error(err)
}
err = fMove(fmt.Sprintf("%s/pki/revoked/reqs_by_serial/%s.req", *EasyrsaDirPath, usersFromIndexTxt[i].SerialNumber), fmt.Sprintf("%s/pki/reqs/%s.req", *EasyrsaDirPath, username))
if err != nil {
log.Error(err)
}
err = fWrite(*IndexTxtPath, renderIndexTxt(usersFromIndexTxt))
if err != nil {
log.Error(err)
}
_ = runBash(fmt.Sprintf("cd %s && %s gen-crl 1>/dev/null", *EasyrsaDirPath, *EasyrsaBinPath))
if oAdmin.ExtraAuth {
if oAdmin.OUser.CheckUserExistent(username) {
restoreMsg, restoreErr := oAdmin.OUser.RestoreUser(username)
log.Debug(restoreMsg)
log.Debug(restoreErr)
if restoreErr != nil {
return restoreErr, ""
}
}
}
crlFix()
break
}
if *StorageBackend == "filesystem" {
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
restoreMsg, restoreErr := oAdmin.OUser.RestoreUser(username)
log.Debug(restoreMsg)
log.Debug(restoreErr)
if restoreErr != nil {
return restoreErr, ""
}
}
err := fWrite(*IndexTxtPath, renderIndexTxt(usersFromIndexTxt))
if err != nil {
log.Error(err)
}
}
crlFix()
oAdmin.clients = oAdmin.usersList()
return nil, fmt.Sprintf("{\"msg\":\"User %s successfully unrevoked\"}", username)
}
@ -740,119 +683,46 @@ func (oAdmin *OvpnAdmin) userUnrevoke(username string) (error, string) {
func (oAdmin *OvpnAdmin) userRotate(username, newPassword string) (error, string) {
if checkUserExist(username) {
if *StorageBackend == "kubernetes.secrets" {
err := oAdmin.KubeClient.EasyrsaRotate(username)
if err != nil {
log.Error(err)
}
} else {
var oldUserIndex, newUserIndex int
var oldUserSerial string
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
usersFromIndexTxt := IndexTxtParser(fRead(*IndexTxtPath))
for i := range usersFromIndexTxt {
if usersFromIndexTxt[i].DistinguishedName == "/CN="+username {
oldUserSerial = usersFromIndexTxt[i].SerialNumber
usersFromIndexTxt[i].DistinguishedName = "/CN=REVOKED-" + username + "-" + uniqHash
oldUserIndex = i
break
}
}
err := fWrite(*IndexTxtPath, renderIndexTxt(usersFromIndexTxt))
if err != nil {
log.Error(err)
}
if oAdmin.ExtraAuth {
if oAdmin.OUser.CheckUserExistent(username) {
deleteMsg, deleteErr := oAdmin.OUser.DeleteUser(username, true)
log.Debug(deleteMsg)
log.Debug(deleteErr)
if deleteErr != nil {
return deleteErr, ""
}
log.Debug(deleteMsg)
}
}
userCreateMessage, userCreateError := oAdmin.userCreate(username, newPassword)
if userCreateError != nil {
usersFromIndexTxt = IndexTxtParser(fRead(*IndexTxtPath))
for i := range usersFromIndexTxt {
if usersFromIndexTxt[i].SerialNumber == oldUserSerial {
usersFromIndexTxt[i].DistinguishedName = "/CN=" + username
break
}
}
err = fWrite(*IndexTxtPath, renderIndexTxt(usersFromIndexTxt))
if err != nil {
log.Error(err)
}
return fmt.Errorf("error rotaing user due: %s", userCreateMessage), userCreateMessage
}
usersFromIndexTxt = IndexTxtParser(fRead(*IndexTxtPath))
for i := range usersFromIndexTxt {
if usersFromIndexTxt[i].DistinguishedName == "/CN="+username {
newUserIndex = i
}
if usersFromIndexTxt[i].SerialNumber == oldUserSerial {
oldUserIndex = i
}
}
usersFromIndexTxt[oldUserIndex], usersFromIndexTxt[newUserIndex] = usersFromIndexTxt[newUserIndex], usersFromIndexTxt[oldUserIndex]
err = fWrite(*IndexTxtPath, renderIndexTxt(usersFromIndexTxt))
if err != nil {
log.Error(err)
}
_ = runBash(fmt.Sprintf("cd %s && %s gen-crl 1>/dev/null", *EasyrsaDirPath, *EasyrsaBinPath))
err := oAdmin.PKI.CertificateRotate(username)
if err != nil {
log.Error(err)
}
if *StorageBackend == "filesystem" {
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
deleteMsg, deleteErr := oAdmin.OUser.DeleteUser(username, true)
log.Debug(deleteMsg)
log.Debug(deleteErr)
if deleteErr != nil {
return deleteErr, ""
}
log.Debug(deleteMsg)
}
}
crlFix()
oAdmin.clients = oAdmin.usersList()
return nil, fmt.Sprintf("{\"msg\":\"User %s successfully rotated\"}", username)
}
return fmt.Errorf("user \"%s\" not found", username), fmt.Sprintf("{\"msg\":\"User \"%s\" not found\"}", username)
}
}
func (oAdmin *OvpnAdmin) userDelete(username string) (error, string) {
if checkUserExist(username) {
if *StorageBackend == "kubernetes.secrets" {
err := oAdmin.KubeClient.EasyrsaDelete(username)
if err != nil {
log.Error(err)
}
} else {
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
usersFromIndexTxt := IndexTxtParser(fRead(*IndexTxtPath))
for i := range usersFromIndexTxt {
if usersFromIndexTxt[i].DistinguishedName == "/CN="+username {
usersFromIndexTxt[i].DistinguishedName = "/CN=REVOKED-" + username + "-" + uniqHash
break
}
}
if oAdmin.ExtraAuth {
if oAdmin.OUser.CheckUserExistent(username) {
deleteMsg, deleteErr := oAdmin.OUser.DeleteUser(username, true)
log.Debug(deleteMsg)
log.Debug(deleteErr)
if deleteErr != nil {
log.Debug(deleteErr)
return deleteErr, ""
}
}
}
err := fWrite(*IndexTxtPath, renderIndexTxt(usersFromIndexTxt))
if err != nil {
log.Error(err)
}
_ = runBash(fmt.Sprintf("cd %s && %s gen-crl 1>/dev/null ", *EasyrsaDirPath, *EasyrsaBinPath))
err := oAdmin.PKI.CertificateDelAfterRevoke(username)
if err != nil {
log.Error(err)
}
if *StorageBackend == "filesystem" {
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
deleteMsg, deleteErr := oAdmin.OUser.DeleteUser(username, true)
log.Debug(deleteMsg)
log.Debug(deleteErr)
if deleteErr != nil {
return deleteErr, ""
}
log.Debug(deleteMsg)
}
}
crlFix()
oAdmin.clients = oAdmin.usersList()
return nil, fmt.Sprintf("{\"msg\":\"User %s successfully deleted\"}", username)
}

View File

@ -3,7 +3,12 @@ package backend
import (
"io/fs"
"sync"
"bytes"
"time"
"crypto/rsa"
"crypto/x509"
"k8s.io/client-go/kubernetes"
"github.com/pashcovich/openvpn-user/src"
"github.com/prometheus/client_golang/prometheus"
)
@ -19,12 +24,13 @@ type OvpnAdmin struct {
PromRegistry *prometheus.Registry
OUser *src.OpenvpnUser
KubeClient *OpenVPNPKI
PKI *OpenVPNPKI
MgmtInterfaces map[string]string
Templates fs.FS
Modules []string
mgmtStatusTimeFormat string
CreateUserMutex *sync.Mutex
ExtraAuth bool
ExtraAuth bool
}
type OpenvpnServer struct {
@ -86,3 +92,32 @@ type ClientStatus struct {
LastRefFormatted string
ConnectedTo string
}
type OpenVPNPKI struct {
CAPrivKeyRSA *rsa.PrivateKey
CAPrivKeyPEM *bytes.Buffer
CACert *x509.Certificate
CACertPEM *bytes.Buffer
ServerPrivKeyRSA *rsa.PrivateKey
ServerPrivKeyPEM *bytes.Buffer
ServerCert *x509.Certificate
ServerCertPEM *bytes.Buffer
TaKey *bytes.Buffer
DhParam *bytes.Buffer
ClientCerts []ClientCert
RevokedCerts []RevokedCert
KubeClient *kubernetes.Clientset
}
type ClientCert struct {
PrivKeyRSA *rsa.PrivateKey
PrivKeyPEM *bytes.Buffer
Cert *x509.Certificate
CertPEM *bytes.Buffer
}
type RevokedCert struct {
RevokedTime time.Time `json:"revokedTime"`
CommonName string `json:"commonName"`
Cert *x509.Certificate `json:"cert"`
}

1083
backend/pki.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,12 +5,13 @@ import (
"compress/gzip"
"context"
"crypto/x509"
"database/sql"
"encoding/pem"
"errors"
"fmt"
log "github.com/sirupsen/logrus"
"io"
"io/ioutil"
"io/fs"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
@ -24,7 +25,6 @@ import (
"strings"
"time"
"unicode/utf8"
"database/sql"
)
var (
@ -209,7 +209,7 @@ func getOvpnServerHostsFromKubeApi() ([]OpenvpnServer, error) {
func getOvpnCaCertExpireDate() time.Time {
caCertPath := *EasyrsaDirPath + "/pki/ca.crt"
caCert, err := ioutil.ReadFile(caCertPath)
caCert, err := os.ReadFile(caCertPath)
if err != nil {
log.Errorf("error read file %s: %s", caCertPath, err.Error())
}
@ -278,13 +278,27 @@ func fExist(path string) bool {
}
func fRead(path string) string {
content, err := ioutil.ReadFile(path)
content := fReadRaw(path)
return string(content)
}
func fReadRaw(path string) []byte {
content, err := os.ReadFile(path)
if err != nil {
log.Warning(err)
return ""
return nil
}
return string(content)
return content
}
func fReadDir(path string) []fs.DirEntry {
files, err := os.ReadDir(path)
if err != nil {
log.Warning(err)
}
return files
}
func fCreate(path string) error {
@ -301,7 +315,15 @@ func fCreate(path string) error {
}
func fWrite(path, content string) error {
err := ioutil.WriteFile(path, []byte(content), 0644)
err := fWriteRaw(path, []byte(content), 0644)
if err != nil {
log.Fatal(err)
}
return nil
}
func fWriteRaw(path string, rawContent []byte, perm fs.FileMode) error {
err := os.WriteFile(path, []byte(rawContent), perm)
if err != nil {
log.Fatal(err)
}
@ -395,7 +417,7 @@ func fDownload(path, url string, basicAuth bool) error {
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
@ -572,4 +594,18 @@ func IsModuleEnabled(desiredModule string, listModules []string) bool {
}
}
return false
}
func GetSerialNumberByUser(username string) string {
var serialNumberInTxt string
usersFromIndexTxt := IndexTxtParser(fRead(*IndexTxtPath))
for i := range usersFromIndexTxt {
if usersFromIndexTxt[i].DistinguishedName == "/CN="+username {
if usersFromIndexTxt[i].Flag == "R" {
serialNumberInTxt = usersFromIndexTxt[i].SerialNumber
break
}
}
}
return serialNumberInTxt
}

View File

@ -50,9 +50,16 @@ func main() {
ovpnAdmin := new(backend.OvpnAdmin)
ovpnAdmin.OUser = new(ou.OpenvpnUser)
ovpnAdmin.PKI = new(backend.OpenVPNPKI)
err := ovpnAdmin.PKI.InitPKI()
if err != nil {
log.Error(err)
}
if *backend.StorageBackend == "kubernetes.secrets" {
// TODO: Check
ovpnAdmin.KubeClient = new(backend.OpenVPNPKI)
err := ovpnAdmin.KubeClient.Run()
err := ovpnAdmin.KubeClient.KubeRun()
if err != nil {
log.Error(err)
}