include internal pki
This commit is contained in:
parent
f7c5a66992
commit
6d96f1f927
7 changed files with 1589 additions and 604 deletions
|
@ -11,4 +11,16 @@ const (
|
||||||
stringDateFormat = "2006-01-02 15:04:05"
|
stringDateFormat = "2006-01-02 15:04:05"
|
||||||
|
|
||||||
KubeNamespaceFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
|
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"
|
||||||
|
)
|
|
@ -3,18 +3,13 @@ package backend
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dgryski/dgoogauth"
|
"github.com/dgryski/dgoogauth"
|
||||||
"github.com/google/uuid"
|
// "github.com/google/uuid"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
@ -23,52 +18,11 @@ import (
|
||||||
"k8s.io/client-go/rest"
|
"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"
|
var namespace = "default"
|
||||||
|
|
||||||
type OpenVPNPKI struct {
|
func (openVPNPKI *OpenVPNPKI) KubeRun() (err error) {
|
||||||
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) {
|
|
||||||
if _, err := os.Stat(KubeNamespaceFilePath); err == nil {
|
if _, err := os.Stat(KubeNamespaceFilePath); err == nil {
|
||||||
file, err := ioutil.ReadFile(KubeNamespaceFilePath)
|
file, err := os.ReadFile(KubeNamespaceFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -80,7 +34,7 @@ func (openVPNPKI *OpenVPNPKI) Run() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = openVPNPKI.initPKI()
|
err = openVPNPKI.InitPKI()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -90,18 +44,6 @@ func (openVPNPKI *OpenVPNPKI) Run() (err error) {
|
||||||
log.Error(err)
|
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()
|
err = openVPNPKI.updateFilesFromSecrets()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
@ -131,243 +73,243 @@ func (openVPNPKI *OpenVPNPKI) initKubeClient() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) initPKI() (err error) {
|
// func (openVPNPKI *OpenVPNPKI) initPKI() (err error) {
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretCA); res {
|
// if res, _ := openVPNPKI.secretCheckExists(secretCA); res {
|
||||||
cert, err := openVPNPKI.secretGetClientCert(secretCA)
|
// cert, err := openVPNPKI.secretGetClientCert(secretCA)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
openVPNPKI.CAPrivKeyPEM = cert.PrivKeyPEM
|
// openVPNPKI.CAPrivKeyPEM = cert.PrivKeyPEM
|
||||||
openVPNPKI.CAPrivKeyRSA = cert.PrivKeyRSA
|
// openVPNPKI.CAPrivKeyRSA = cert.PrivKeyRSA
|
||||||
openVPNPKI.CACertPEM = cert.CertPEM
|
// openVPNPKI.CACertPEM = cert.CertPEM
|
||||||
openVPNPKI.CACert = cert.Cert
|
// openVPNPKI.CACert = cert.Cert
|
||||||
} else {
|
// } else {
|
||||||
openVPNPKI.CAPrivKeyPEM, err = GenPrivKey()
|
// openVPNPKI.CAPrivKeyPEM, err = GenPrivKey()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
openVPNPKI.CAPrivKeyRSA, err = DecodePrivKey(openVPNPKI.CAPrivKeyPEM.Bytes())
|
// openVPNPKI.CAPrivKeyRSA, err = DecodePrivKey(openVPNPKI.CAPrivKeyPEM.Bytes())
|
||||||
|
|
||||||
openVPNPKI.CACertPEM, _ = GenCA(openVPNPKI.CAPrivKeyRSA)
|
// openVPNPKI.CACertPEM, _ = GenCA(openVPNPKI.CAPrivKeyRSA)
|
||||||
openVPNPKI.CACert, err = DecodeCert(openVPNPKI.CACertPEM.Bytes())
|
// openVPNPKI.CACert, err = DecodeCert(openVPNPKI.CACertPEM.Bytes())
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{Name: secretCA}
|
// secretMetaData := metav1.ObjectMeta{Name: secretCA}
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
// secretData := map[string][]byte{
|
||||||
certFileName: openVPNPKI.CACertPEM.Bytes(),
|
// certFileName: openVPNPKI.CACertPEM.Bytes(),
|
||||||
privKeyFileName: openVPNPKI.CAPrivKeyPEM.Bytes(),
|
// privKeyFileName: openVPNPKI.CAPrivKeyPEM.Bytes(),
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretServer); res {
|
// if res, _ := openVPNPKI.secretCheckExists(secretServer); res {
|
||||||
cert, err := openVPNPKI.secretGetClientCert(secretServer)
|
// cert, err := openVPNPKI.secretGetClientCert(secretServer)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
openVPNPKI.ServerPrivKeyPEM = cert.PrivKeyPEM
|
// openVPNPKI.ServerPrivKeyPEM = cert.PrivKeyPEM
|
||||||
openVPNPKI.ServerPrivKeyRSA = cert.PrivKeyRSA
|
// openVPNPKI.ServerPrivKeyRSA = cert.PrivKeyRSA
|
||||||
openVPNPKI.ServerCertPEM = cert.CertPEM
|
// openVPNPKI.ServerCertPEM = cert.CertPEM
|
||||||
openVPNPKI.ServerCert = cert.Cert
|
// openVPNPKI.ServerCert = cert.Cert
|
||||||
} else {
|
// } else {
|
||||||
openVPNPKI.ServerPrivKeyPEM, err = GenPrivKey()
|
// openVPNPKI.ServerPrivKeyPEM, err = GenPrivKey()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
openVPNPKI.ServerPrivKeyRSA, err = DecodePrivKey(openVPNPKI.ServerPrivKeyPEM.Bytes())
|
// openVPNPKI.ServerPrivKeyRSA, err = DecodePrivKey(openVPNPKI.ServerPrivKeyPEM.Bytes())
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
openVPNPKI.ServerCertPEM, _ = GenServerCert(openVPNPKI.ServerPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, "server")
|
// openVPNPKI.ServerCertPEM, _ = GenServerCert(openVPNPKI.ServerPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, "server")
|
||||||
openVPNPKI.ServerCert, err = DecodeCert(openVPNPKI.ServerCertPEM.Bytes())
|
// openVPNPKI.ServerCert, err = DecodeCert(openVPNPKI.ServerCertPEM.Bytes())
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{
|
// secretMetaData := metav1.ObjectMeta{
|
||||||
Name: secretServer,
|
// Name: secretServer,
|
||||||
Labels: map[string]string{
|
// Labels: map[string]string{
|
||||||
"index.txt": "",
|
// "index.txt": "",
|
||||||
"name": "server",
|
// "name": "server",
|
||||||
"type": "serverAuth",
|
// "type": "serverAuth",
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
// secretData := map[string][]byte{
|
||||||
certFileName: openVPNPKI.ServerCertPEM.Bytes(),
|
// certFileName: openVPNPKI.ServerCertPEM.Bytes(),
|
||||||
privKeyFileName: openVPNPKI.ServerPrivKeyPEM.Bytes(),
|
// privKeyFileName: openVPNPKI.ServerPrivKeyPEM.Bytes(),
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) indexTxtUpdate() (err error) {
|
// func (openVPNPKI *OpenVPNPKI) indexTxtUpdate() (err error) {
|
||||||
secrets, err := openVPNPKI.secretsGetByLabels("index.txt=")
|
// secrets, err := openVPNPKI.secretsGetByLabels("index.txt=")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
var indexTxt string
|
// var indexTxt string
|
||||||
for _, secret := range secrets.Items {
|
// for _, secret := range secrets.Items {
|
||||||
certPEM := bytes.NewBuffer(secret.Data[certFileName])
|
// certPEM := bytes.NewBuffer(secret.Data[certFileName])
|
||||||
log.Trace("indexTxtUpdate:" + secret.Name)
|
// log.Trace("indexTxtUpdate:" + secret.Name)
|
||||||
cert, err := DecodeCert(certPEM.Bytes())
|
// cert, err := DecodeCert(certPEM.Bytes())
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
log.Trace(cert.Subject.CommonName)
|
// log.Trace(cert.Subject.CommonName)
|
||||||
|
|
||||||
if secret.Annotations["revokedAt"] == "" {
|
// 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"])
|
// 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()) {
|
// } 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"])
|
// 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 {
|
// } 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"])
|
// 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 {
|
// if res, _ := openVPNPKI.secretCheckExists(secretIndexTxt); !res {
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
||||||
} else {
|
// } else {
|
||||||
err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
// err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
||||||
}
|
// }
|
||||||
|
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) updateIndexTxtOnDisk() (err error) {
|
func (openVPNPKI *OpenVPNPKI) updateIndexTxtOnDisk() (err error) {
|
||||||
secret, err := openVPNPKI.secretGetByName(secretIndexTxt)
|
secret, err := openVPNPKI.secretGetByName(secretIndexTxt)
|
||||||
indexTxt := secret.Data["index.txt"]
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaGenCRL() (err error) {
|
// func (openVPNPKI *OpenVPNPKI) easyrsaGenCRL() (err error) {
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
// err = openVPNPKI.indexTxtUpdate()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
secrets, err := openVPNPKI.secretsGetByLabels("index.txt=,type=clientAuth")
|
// secrets, err := openVPNPKI.secretsGetByLabels("index.txt=,type=clientAuth")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
var revoked []*RevokedCert
|
// var revoked []*RevokedCert
|
||||||
|
|
||||||
for _, secret := range secrets.Items {
|
// for _, secret := range secrets.Items {
|
||||||
if secret.Annotations["revokedAt"] != "" {
|
// if secret.Annotations["revokedAt"] != "" {
|
||||||
revokedAt, err := time.Parse(indexTxtDateFormat, secret.Annotations["revokedAt"])
|
// revokedAt, err := time.Parse(indexTxtDateFormat, secret.Annotations["revokedAt"])
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Warning(err)
|
// log.Warning(err)
|
||||||
}
|
// }
|
||||||
cert, err := DecodeCert(secret.Data[certFileName])
|
// cert, err := DecodeCert(secret.Data[certFileName])
|
||||||
revoked = append(revoked, &RevokedCert{RevokedTime: revokedAt, Cert: cert})
|
// revoked = append(revoked, &RevokedCert{RevokedTime: revokedAt, Cert: cert})
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
crl, err := GenCRL(revoked, openVPNPKI.CACert, openVPNPKI.CAPrivKeyRSA)
|
// crl, err := GenCRL(revoked, openVPNPKI.CACert, openVPNPKI.CAPrivKeyRSA)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{Name: secretCRL}
|
// secretMetaData := metav1.ObjectMeta{Name: secretCRL}
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
// secretData := map[string][]byte{
|
||||||
"crl.pem": crl.Bytes(),
|
// "crl.pem": crl.Bytes(),
|
||||||
}
|
// }
|
||||||
|
|
||||||
//err = openVPNPKI.secretCreate(secretMetaData, secretData)
|
// //err = openVPNPKI.secretCreate(secretMetaData, secretData)
|
||||||
|
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretCRL); !res {
|
// if res, _ := openVPNPKI.secretCheckExists(secretCRL); !res {
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
||||||
} else {
|
// } else {
|
||||||
err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
// err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
||||||
}
|
// }
|
||||||
|
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) EasyrsaBuildClient(commonName string) (err error) {
|
// func (openVPNPKI *OpenVPNPKI) EasyrsaBuildClient(commonName string) (err error) {
|
||||||
// check certificate exists
|
// // check certificate exists
|
||||||
_, err = openVPNPKI.secretGetByLabels("name=" + commonName)
|
// _, err = openVPNPKI.secretGetByLabels("name=" + commonName)
|
||||||
if err == nil {
|
// if err == nil {
|
||||||
return errors.New(fmt.Sprintf("certificate for user (%s) already exists", commonName))
|
// return errors.New(fmt.Sprintf("certificate for user (%s) already exists", commonName))
|
||||||
}
|
// }
|
||||||
|
|
||||||
clientPrivKeyPEM, err := GenPrivKey()
|
// clientPrivKeyPEM, err := GenPrivKey()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
clientPrivKeyRSA, err := DecodePrivKey(clientPrivKeyPEM.Bytes())
|
// clientPrivKeyRSA, err := DecodePrivKey(clientPrivKeyPEM.Bytes())
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
clientCertPEM, _ := GenClientCert(clientPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, commonName)
|
// clientCertPEM, _ := GenClientCert(clientPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, commonName)
|
||||||
clientCert, err := DecodeCert(clientCertPEM.Bytes())
|
// clientCert, err := DecodeCert(clientCertPEM.Bytes())
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{
|
// secretMetaData := metav1.ObjectMeta{
|
||||||
Name: fmt.Sprintf(secretClientTmpl, clientCert.SerialNumber),
|
// Name: fmt.Sprintf(secretClientTmpl, clientCert.SerialNumber),
|
||||||
Labels: map[string]string{
|
// Labels: map[string]string{
|
||||||
"index.txt": "",
|
// "index.txt": "",
|
||||||
"type": "clientAuth",
|
// "type": "clientAuth",
|
||||||
"name": commonName,
|
// "name": commonName,
|
||||||
"app.kubernetes.io/managed-by": "ovpn-admin",
|
// "app.kubernetes.io/managed-by": "ovpn-admin",
|
||||||
},
|
// },
|
||||||
Annotations: map[string]string{
|
// Annotations: map[string]string{
|
||||||
"commonName": commonName,
|
// "commonName": commonName,
|
||||||
"notBefore": clientCert.NotBefore.Format(indexTxtDateFormat),
|
// "notBefore": clientCert.NotBefore.Format(indexTxtDateFormat),
|
||||||
"notAfter": clientCert.NotAfter.Format(indexTxtDateFormat),
|
// "notAfter": clientCert.NotAfter.Format(indexTxtDateFormat),
|
||||||
"revokedAt": "",
|
// "revokedAt": "",
|
||||||
"serialNumber": fmt.Sprintf("%d", clientCert.SerialNumber),
|
// "serialNumber": fmt.Sprintf("%d", clientCert.SerialNumber),
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
// secretData := map[string][]byte{
|
||||||
certFileName: clientCertPEM.Bytes(),
|
// certFileName: clientCertPEM.Bytes(),
|
||||||
privKeyFileName: clientPrivKeyPEM.Bytes(),
|
// privKeyFileName: clientPrivKeyPEM.Bytes(),
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
// err = openVPNPKI.indexTxtUpdate()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
// err = openVPNPKI.updateIndexTxtOnDisk()
|
||||||
|
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaGetCACert() string {
|
// func (openVPNPKI *OpenVPNPKI) easyrsaGetCACert() string {
|
||||||
return openVPNPKI.CACertPEM.String()
|
// return openVPNPKI.CACertPEM.String()
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) EasyrsaGetClientCert(commonName string) (cert, key string) {
|
func (openVPNPKI *OpenVPNPKI) EasyrsaGetClientCert(commonName string) (cert, key string) {
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
||||||
|
@ -381,148 +323,148 @@ func (openVPNPKI *OpenVPNPKI) EasyrsaGetClientCert(commonName string) (cert, key
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) EasyrsaRevoke(commonName string) (err error) {
|
// func (openVPNPKI *OpenVPNPKI) EasyrsaRevoke(commonName string) (err error) {
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
if secret.Annotations["revokedAt"] != "" {
|
// if secret.Annotations["revokedAt"] != "" {
|
||||||
log.Warnf("user (%s) already revoked", commonName)
|
// log.Warnf("user (%s) already revoked", commonName)
|
||||||
return
|
// 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{})
|
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
// err = openVPNPKI.indexTxtUpdate()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
// err = openVPNPKI.updateIndexTxtOnDisk()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
// err = openVPNPKI.easyrsaGenCRL()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
// err = openVPNPKI.updateCRLOnDisk()
|
||||||
|
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) EasyrsaUnrevoke(commonName string) (err error) {
|
// func (openVPNPKI *OpenVPNPKI) EasyrsaUnrevoke(commonName string) (err error) {
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
secret.Annotations["revokedAt"] = ""
|
// secret.Annotations["revokedAt"] = ""
|
||||||
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
// err = openVPNPKI.indexTxtUpdate()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
// err = openVPNPKI.updateIndexTxtOnDisk()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
// err = openVPNPKI.easyrsaGenCRL()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
// err = openVPNPKI.updateCRLOnDisk()
|
||||||
|
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) EasyrsaRotate(commonName string) (err error) {
|
// func (openVPNPKI *OpenVPNPKI) EasyrsaRotate(commonName string) (err error) {
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
// uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
||||||
secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
|
// secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
|
||||||
secret.Labels["name"] = "REVOKED" + commonName
|
// secret.Labels["name"] = "REVOKED" + commonName
|
||||||
secret.Labels["revokedForever"] = "true"
|
// secret.Labels["revokedForever"] = "true"
|
||||||
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.EasyrsaBuildClient(commonName)
|
// err = openVPNPKI.EasyrsaBuildClient(commonName)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
// err = openVPNPKI.indexTxtUpdate()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
// err = openVPNPKI.updateIndexTxtOnDisk()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
// err = openVPNPKI.easyrsaGenCRL()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
// err = openVPNPKI.updateCRLOnDisk()
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
func (openVPNPKI *OpenVPNPKI) EasyrsaDelete(commonName string) (err error) {
|
// func (openVPNPKI *OpenVPNPKI) EasyrsaDelete(commonName string) (err error) {
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
// secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
// uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
||||||
secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
|
// secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
|
||||||
secret.Labels["name"] = "REVOKED-" + commonName + "-" + uniqHash
|
// secret.Labels["name"] = "REVOKED-" + commonName + "-" + uniqHash
|
||||||
secret.Labels["revokedForever"] = "true"
|
// secret.Labels["revokedForever"] = "true"
|
||||||
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
// _, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
// err = openVPNPKI.indexTxtUpdate()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
// err = openVPNPKI.updateIndexTxtOnDisk()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
// err = openVPNPKI.easyrsaGenCRL()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Error(err)
|
// log.Error(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
// err = openVPNPKI.updateCRLOnDisk()
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretGetClientCert(name string) (cert ClientCert, err error) {
|
func (openVPNPKI *OpenVPNPKI) secretGetClientCert(name string) (cert ClientCert, err error) {
|
||||||
secret, err := openVPNPKI.secretGetByName(name)
|
secret, err := openVPNPKI.secretGetByName(name)
|
||||||
|
@ -546,12 +488,12 @@ func (openVPNPKI *OpenVPNPKI) secretGetClientCert(name string) (cert ClientCert,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
|
func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
|
||||||
ca, err := openVPNPKI.secretGetClientCert(secretCA)
|
ca, err := openVPNPKI.getExistCert(secretCA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := openVPNPKI.secretGetClientCert(secretServer)
|
server, err := openVPNPKI.getExistCert(secretServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -568,27 +510,27 @@ func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
|
||||||
err = os.MkdirAll(fmt.Sprintf("%s/pki/private", *EasyrsaDirPath), 0755)
|
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 {
|
if err != nil {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -600,45 +542,45 @@ func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
|
||||||
func (openVPNPKI *OpenVPNPKI) updateCRLOnDisk() (err error) {
|
func (openVPNPKI *OpenVPNPKI) updateCRLOnDisk() (err error) {
|
||||||
secret, err := openVPNPKI.secretGetByName(secretCRL)
|
secret, err := openVPNPKI.secretGetByName(secretCRL)
|
||||||
crl := secret.Data["crl.pem"]
|
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 {
|
if err != nil {
|
||||||
log.Errorf("error write crl.pem:%s", err.Error())
|
log.Errorf("error write crl.pem:%s", err.Error())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretGenTaKeyAndDHParam() (err error) {
|
// func (openVPNPKI *OpenVPNPKI) secretGenTaKeyAndDHParam() (err error) {
|
||||||
taKeyPath := "/tmp/ta.key"
|
// taKeyPath := "/tmp/ta.key"
|
||||||
cmd := exec.Command("bash", "-c", fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s", taKeyPath))
|
// cmd := exec.Command("bash", "-c", fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s", taKeyPath))
|
||||||
stdout, err := cmd.CombinedOutput()
|
// stdout, err := cmd.CombinedOutput()
|
||||||
log.Info(fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s: %s", taKeyPath, string(stdout)))
|
// log.Info(fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s: %s", taKeyPath, string(stdout)))
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
taKey, err := ioutil.ReadFile(taKeyPath)
|
// taKey, err := os.ReadFile(taKeyPath)
|
||||||
|
|
||||||
dhparamPath := "/tmp/dh.pem"
|
// dhparamPath := "/tmp/dh.pem"
|
||||||
cmd = exec.Command("bash", "-c", fmt.Sprintf("openssl dhparam -out %s 2048", dhparamPath))
|
// cmd = exec.Command("bash", "-c", fmt.Sprintf("openssl dhparam -out %s 2048", dhparamPath))
|
||||||
_, err = cmd.CombinedOutput()
|
// _, err = cmd.CombinedOutput()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
dhparam, err := ioutil.ReadFile(dhparamPath)
|
// dhparam, err := os.ReadFile(dhparamPath)
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{Name: secretDHandTA}
|
// secretMetaData := metav1.ObjectMeta{Name: secretDHandTA}
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
// secretData := map[string][]byte{
|
||||||
"ta.key": taKey,
|
// "ta.key": taKey,
|
||||||
"dh.pem": dhparam,
|
// "dh.pem": dhparam,
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
// err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
// ccd
|
// ccd
|
||||||
|
|
||||||
|
@ -690,7 +632,7 @@ func (openVPNPKI *OpenVPNPKI) updateCcdOnDisk() error {
|
||||||
for _, secret := range secrets.Items {
|
for _, secret := range secrets.Items {
|
||||||
ccd := secret.Data["ccd"]
|
ccd := secret.Data["ccd"]
|
||||||
if len(ccd) > 0 {
|
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 {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
ou "github.com/pashcovich/openvpn-user/src"
|
ou "github.com/pashcovich/openvpn-user/src"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@ -280,7 +279,7 @@ func (oAdmin *OvpnAdmin) usersList() []OpenvpnClient {
|
||||||
apochNow := time.Now().Unix()
|
apochNow := time.Now().Unix()
|
||||||
|
|
||||||
for _, line := range IndexTxtParser(fRead(*IndexTxtPath)) {
|
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
|
totalCerts += 1
|
||||||
ovpnClient := OpenvpnClient{Identity: line.Identity, ExpirationDate: parseDateToString(indexTxtDateLayout, line.ExpirationDate, stringDateFormat)}
|
ovpnClient := OpenvpnClient{Identity: line.Identity, ExpirationDate: parseDateToString(indexTxtDateLayout, line.ExpirationDate, stringDateFormat)}
|
||||||
switch {
|
switch {
|
||||||
|
@ -365,33 +364,28 @@ func (oAdmin *OvpnAdmin) userCreate(username, password string) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *StorageBackend == "kubernetes.secrets" {
|
err := oAdmin.PKI.BuildKeyPairClient(username)
|
||||||
err := oAdmin.KubeClient.EasyrsaBuildClient(username)
|
if err != nil {
|
||||||
if err != nil {
|
log.Error(err)
|
||||||
log.Error(err)
|
return err.Error(), err
|
||||||
return err.Error(), err
|
}
|
||||||
}
|
|
||||||
if oAdmin.ExtraAuth {
|
if oAdmin.ExtraAuth {
|
||||||
|
switch *StorageBackend {
|
||||||
|
case "kubernetes.secrets":
|
||||||
err = oAdmin.KubeClient.updatePasswordSecret(username, []byte(password))
|
err = oAdmin.KubeClient.updatePasswordSecret(username, []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), err
|
return err.Error(), err
|
||||||
}
|
}
|
||||||
}
|
case "filesystems":
|
||||||
} 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 {
|
|
||||||
_, err := oAdmin.OUser.CreateUser(username, password)
|
_, err := oAdmin.OUser.CreateUser(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), err
|
return err.Error(), err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("Certificate for user %s issued", username)
|
log.Infof("Certificate for user %s issued", username)
|
||||||
|
|
||||||
//oAdmin.clients = oAdmin.usersList()
|
|
||||||
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,13 +403,13 @@ func (oAdmin *OvpnAdmin) userChangePassword(username, password string) (error, s
|
||||||
log.Warningf("userChangePassword: %s", err.Error())
|
log.Warningf("userChangePassword: %s", err.Error())
|
||||||
return err, err.Error()
|
return err, err.Error()
|
||||||
}
|
}
|
||||||
|
switch *StorageBackend {
|
||||||
if *StorageBackend == "kubernetes.secrets" {
|
case "kubernetes.secrets":
|
||||||
err := oAdmin.KubeClient.updatePasswordSecret(username, []byte(password))
|
err := oAdmin.KubeClient.updatePasswordSecret(username, []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, err.Error()
|
return err, err.Error()
|
||||||
}
|
}
|
||||||
} else {
|
case "filesystem":
|
||||||
msg, err := oAdmin.OUser.ChangeUserPassword(username, password)
|
msg, err := oAdmin.OUser.ChangeUserPassword(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, msg
|
return err, msg
|
||||||
|
@ -630,19 +624,13 @@ func (oAdmin *OvpnAdmin) getUserStatistic(username string) []ClientStatus {
|
||||||
func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
|
func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
|
||||||
log.Infof("Revoke certificate for user %s", username)
|
log.Infof("Revoke certificate for user %s", username)
|
||||||
if checkUserExist(username) {
|
if checkUserExist(username) {
|
||||||
// check certificate valid flag 'V'
|
err := oAdmin.PKI.CertificateRevoke(username)
|
||||||
if *StorageBackend == "kubernetes.secrets" {
|
if err != nil {
|
||||||
err := oAdmin.KubeClient.EasyrsaRevoke(username)
|
log.Error(err)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if oAdmin.ExtraAuth {
|
if *StorageBackend == "filesystem" {
|
||||||
if oAdmin.OUser.CheckUserExistent(username) {
|
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
|
||||||
revokeMsg, revokeErr := oAdmin.OUser.RevokedUser(username)
|
revokeMsg, revokeErr := oAdmin.OUser.RevokedUser(username)
|
||||||
log.Debug(revokeMsg)
|
log.Debug(revokeMsg)
|
||||||
log.Debug(revokeErr)
|
log.Debug(revokeErr)
|
||||||
|
@ -652,7 +640,6 @@ func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crlFix()
|
|
||||||
userConnected, userConnectedTo := isUserConnected(username, oAdmin.activeClients)
|
userConnected, userConnectedTo := isUserConnected(username, oAdmin.activeClients)
|
||||||
log.Tracef("User %s connected: %t", username, userConnected)
|
log.Tracef("User %s connected: %t", username, userConnected)
|
||||||
if userConnected {
|
if userConnected {
|
||||||
|
@ -671,67 +658,23 @@ func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
|
||||||
|
|
||||||
func (oAdmin *OvpnAdmin) userUnrevoke(username string) (error, string) {
|
func (oAdmin *OvpnAdmin) userUnrevoke(username string) (error, string) {
|
||||||
if checkUserExist(username) {
|
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"
|
err := oAdmin.PKI.CertificateUnRevoke(username)
|
||||||
usersFromIndexTxt[i].RevocationDate = ""
|
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 *StorageBackend == "filesystem" {
|
||||||
if err != nil {
|
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
|
||||||
log.Error(err)
|
restoreMsg, restoreErr := oAdmin.OUser.RestoreUser(username)
|
||||||
}
|
log.Debug(restoreMsg)
|
||||||
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))
|
log.Debug(restoreErr)
|
||||||
if err != nil {
|
if restoreErr != nil {
|
||||||
log.Error(err)
|
return restoreErr, ""
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := fWrite(*IndexTxtPath, renderIndexTxt(usersFromIndexTxt))
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
crlFix()
|
|
||||||
oAdmin.clients = oAdmin.usersList()
|
oAdmin.clients = oAdmin.usersList()
|
||||||
return nil, fmt.Sprintf("{\"msg\":\"User %s successfully unrevoked\"}", username)
|
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) {
|
func (oAdmin *OvpnAdmin) userRotate(username, newPassword string) (error, string) {
|
||||||
if checkUserExist(username) {
|
if checkUserExist(username) {
|
||||||
if *StorageBackend == "kubernetes.secrets" {
|
err := oAdmin.PKI.CertificateRotate(username)
|
||||||
err := oAdmin.KubeClient.EasyrsaRotate(username)
|
if err != nil {
|
||||||
if err != nil {
|
log.Error(err)
|
||||||
log.Error(err)
|
}
|
||||||
}
|
|
||||||
} else {
|
if *StorageBackend == "filesystem" {
|
||||||
|
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
|
||||||
var oldUserIndex, newUserIndex int
|
deleteMsg, deleteErr := oAdmin.OUser.DeleteUser(username, true)
|
||||||
var oldUserSerial string
|
log.Debug(deleteMsg)
|
||||||
|
log.Debug(deleteErr)
|
||||||
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
if deleteErr != nil {
|
||||||
|
return deleteErr, ""
|
||||||
usersFromIndexTxt := IndexTxtParser(fRead(*IndexTxtPath))
|
}
|
||||||
for i := range usersFromIndexTxt {
|
log.Debug(deleteMsg)
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
crlFix()
|
|
||||||
oAdmin.clients = oAdmin.usersList()
|
oAdmin.clients = oAdmin.usersList()
|
||||||
return nil, fmt.Sprintf("{\"msg\":\"User %s successfully rotated\"}", username)
|
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)
|
return fmt.Errorf("user \"%s\" not found", username), fmt.Sprintf("{\"msg\":\"User \"%s\" not found\"}", username)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (oAdmin *OvpnAdmin) userDelete(username string) (error, string) {
|
func (oAdmin *OvpnAdmin) userDelete(username string) (error, string) {
|
||||||
if checkUserExist(username) {
|
if checkUserExist(username) {
|
||||||
if *StorageBackend == "kubernetes.secrets" {
|
err := oAdmin.PKI.CertificateDelAfterRevoke(username)
|
||||||
err := oAdmin.KubeClient.EasyrsaDelete(username)
|
if err != nil {
|
||||||
if err != nil {
|
log.Error(err)
|
||||||
log.Error(err)
|
}
|
||||||
}
|
|
||||||
} else {
|
if *StorageBackend == "filesystem" {
|
||||||
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
if oAdmin.ExtraAuth && oAdmin.OUser.CheckUserExistent(username) {
|
||||||
usersFromIndexTxt := IndexTxtParser(fRead(*IndexTxtPath))
|
deleteMsg, deleteErr := oAdmin.OUser.DeleteUser(username, true)
|
||||||
for i := range usersFromIndexTxt {
|
log.Debug(deleteMsg)
|
||||||
if usersFromIndexTxt[i].DistinguishedName == "/CN="+username {
|
log.Debug(deleteErr)
|
||||||
usersFromIndexTxt[i].DistinguishedName = "/CN=REVOKED-" + username + "-" + uniqHash
|
if deleteErr != nil {
|
||||||
break
|
return deleteErr, ""
|
||||||
}
|
}
|
||||||
}
|
log.Debug(deleteMsg)
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
crlFix()
|
|
||||||
oAdmin.clients = oAdmin.usersList()
|
oAdmin.clients = oAdmin.usersList()
|
||||||
return nil, fmt.Sprintf("{\"msg\":\"User %s successfully deleted\"}", username)
|
return nil, fmt.Sprintf("{\"msg\":\"User %s successfully deleted\"}", username)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,12 @@ package backend
|
||||||
import (
|
import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"sync"
|
"sync"
|
||||||
|
"bytes"
|
||||||
|
"time"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
"github.com/pashcovich/openvpn-user/src"
|
"github.com/pashcovich/openvpn-user/src"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
@ -19,12 +24,13 @@ type OvpnAdmin struct {
|
||||||
PromRegistry *prometheus.Registry
|
PromRegistry *prometheus.Registry
|
||||||
OUser *src.OpenvpnUser
|
OUser *src.OpenvpnUser
|
||||||
KubeClient *OpenVPNPKI
|
KubeClient *OpenVPNPKI
|
||||||
|
PKI *OpenVPNPKI
|
||||||
MgmtInterfaces map[string]string
|
MgmtInterfaces map[string]string
|
||||||
Templates fs.FS
|
Templates fs.FS
|
||||||
Modules []string
|
Modules []string
|
||||||
mgmtStatusTimeFormat string
|
mgmtStatusTimeFormat string
|
||||||
CreateUserMutex *sync.Mutex
|
CreateUserMutex *sync.Mutex
|
||||||
ExtraAuth bool
|
ExtraAuth bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type OpenvpnServer struct {
|
type OpenvpnServer struct {
|
||||||
|
@ -86,3 +92,32 @@ type ClientStatus struct {
|
||||||
LastRefFormatted string
|
LastRefFormatted string
|
||||||
ConnectedTo 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
1083
backend/pki.go
Normal file
File diff suppressed because it is too large
Load diff
|
@ -5,12 +5,13 @@ import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"context"
|
"context"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"database/sql"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/fs"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
|
@ -24,7 +25,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
"database/sql"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -209,7 +209,7 @@ func getOvpnServerHostsFromKubeApi() ([]OpenvpnServer, error) {
|
||||||
|
|
||||||
func getOvpnCaCertExpireDate() time.Time {
|
func getOvpnCaCertExpireDate() time.Time {
|
||||||
caCertPath := *EasyrsaDirPath + "/pki/ca.crt"
|
caCertPath := *EasyrsaDirPath + "/pki/ca.crt"
|
||||||
caCert, err := ioutil.ReadFile(caCertPath)
|
caCert, err := os.ReadFile(caCertPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("error read file %s: %s", caCertPath, err.Error())
|
log.Errorf("error read file %s: %s", caCertPath, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -278,13 +278,27 @@ func fExist(path string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fRead(path string) string {
|
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 {
|
if err != nil {
|
||||||
log.Warning(err)
|
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 {
|
func fCreate(path string) error {
|
||||||
|
@ -301,7 +315,15 @@ func fCreate(path string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fWrite(path, content 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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -395,7 +417,7 @@ func fDownload(path, url string, basicAuth bool) error {
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -572,4 +594,18 @@ func IsModuleEnabled(desiredModule string, listModules []string) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
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
|
||||||
}
|
}
|
9
main.go
9
main.go
|
@ -50,9 +50,16 @@ func main() {
|
||||||
ovpnAdmin := new(backend.OvpnAdmin)
|
ovpnAdmin := new(backend.OvpnAdmin)
|
||||||
ovpnAdmin.OUser = new(ou.OpenvpnUser)
|
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" {
|
if *backend.StorageBackend == "kubernetes.secrets" {
|
||||||
|
// TODO: Check
|
||||||
ovpnAdmin.KubeClient = new(backend.OpenVPNPKI)
|
ovpnAdmin.KubeClient = new(backend.OpenVPNPKI)
|
||||||
err := ovpnAdmin.KubeClient.Run()
|
err := ovpnAdmin.KubeClient.KubeRun()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue