diff --git a/lib/utils/crypto.go b/lib/utils/crypto.go index 3c4e5024..5e69f00e 100644 --- a/lib/utils/crypto.go +++ b/lib/utils/crypto.go @@ -1,11 +1,21 @@ package utils import ( + "crypto/ecdsa" + "crypto/elliptic" "crypto/md5" + "crypto/rand" "crypto/sha256" + "crypto/x509" + "crypto/x509/pkix" "encoding/base64" "encoding/hex" + "encoding/pem" "fmt" + "log" + "math/big" + "os" + "time" "github.com/xdg-go/pbkdf2" "golang.org/x/crypto/bcrypt" @@ -25,42 +35,150 @@ func Base64Encode(str string) string { // Generating certificates from domain name func GenerateCerts(domain string, basePath string) error { + log.Println("Cert 1") // Generate ca.key in harbor directory - cmd := "openssl genrsa -traditional -out " + basePath + "/ca.key 4096" - if err := RunCommand(cmd); err != nil { + caKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + if err != nil { + return err + } + caKeyBytes, err := x509.MarshalECPrivateKey(caKey) + if err != nil { + return err + } + caKeyFile, err := os.Create(basePath + "/ca.key") + if err != nil { + return err + } + defer caKeyFile.Close() + if err := pem.Encode(caKeyFile, &pem.Block{Type: "EC PRIVATE KEY", Bytes: caKeyBytes}); err != nil { return err } + log.Println("Cert 2") // Generate ca.crt - cmd = "openssl req -x509 -new -nodes -sha512 -days 3650 -subj '/C=IN/ST=Delhi/L=Delhi/O=Katana/CN=" + domain + "' -key " + basePath + "/ca.key -out " + basePath + "/ca.crt" - if err := RunCommand(cmd); err != nil { + caTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + Country: []string{"IN"}, + Organization: []string{"Katana"}, + OrganizationalUnit: []string{"Katana CA"}, + Locality: []string{"Delhi"}, + Province: []string{"Delhi"}, + CommonName: domain, + }, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(10, 0, 0), // 10 years validity + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + }, + BasicConstraintsValid: true, + IsCA: true, + } + caBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, &caKey.PublicKey, caKey) + if err != nil { + return err + } + caCertFile, err := os.Create(basePath + "/ca.crt") + if err != nil { + return err + } + defer caCertFile.Close() + if err := pem.Encode(caCertFile, &pem.Block{Type: "CERTIFICATE", Bytes: caBytes}); err != nil { return err } + log.Println("Cert 3") // Generate private key - cmd = "openssl genrsa -traditional -out " + basePath + "/" + domain + ".key 4096" - if err := RunCommand(cmd); err != nil { + privateKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + if err != nil { + return err + } + privateKeyFile, err := os.Create(basePath + "/" + domain + ".key") + if err != nil { + return err + } + defer privateKeyFile.Close() + privateKeyBytes, err := x509.MarshalECPrivateKey(privateKey) + if err != nil { + return err + } + if err := pem.Encode(privateKeyFile, &pem.Block{Type: "EC PRIVATE KEY", Bytes: privateKeyBytes}); err != nil { return err } + log.Println("Cert 4") // Generate certificate signing request - cmd = "openssl req -sha512 -new -subj '/C=IN/ST=Delhi/L=Delhi/O=Katana/CN=" + domain + "' -key " + basePath + "/" + domain + ".key -out " + basePath + "/" + domain + ".csr" - if err := RunCommand(cmd); err != nil { + csrTemplate := &x509.CertificateRequest{ + Subject: pkix.Name{ + Country: []string{"IN"}, + Organization: []string{"Katana"}, + OrganizationalUnit: []string{"Katana"}, + Locality: []string{"Delhi"}, + Province: []string{"Delhi"}, + CommonName: domain, + }, + DNSNames: []string{domain}, + } + csrBytes, err := x509.CreateCertificateRequest(rand.Reader, csrTemplate, privateKey) + if err != nil { + return err + } + csrFile, err := os.Create(basePath + "/" + domain + ".csr") + if err != nil { + return err + } + defer csrFile.Close() + if err := pem.Encode(csrFile, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes}); err != nil { return err } + log.Println("Cert 5") // Generate v3.ext file - cmd = "echo 'authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment\nextendedKeyUsage = serverAuth\nsubjectAltName = @alt_names\n[alt_names]\nDNS.1=" + domain + "' > " + basePath + "/v3.ext" - if err := RunCommand(cmd); err != nil { + extFileContent := fmt.Sprintf("authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth\nsubjectAltName=DNS:%s", domain) + extFile, err := os.Create(basePath + "/v3.ext") + if err != nil { + return err + } + defer extFile.Close() + if _, err := extFile.WriteString(extFileContent); err != nil { return err } + log.Println("Cert 6") // Generate certificate - cmd = "openssl x509 -req -sha512 -days 3650 -extfile " + basePath + "/v3.ext -CA " + basePath + "/ca.crt -CAkey " + basePath + "/ca.key -CAcreateserial -in " + basePath + "/" + domain + ".csr -out " + basePath + "/" + domain + ".crt" - if err := RunCommand(cmd); err != nil { + certTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(2), + Subject: pkix.Name{ + Country: []string{"IN"}, + Organization: []string{"Katana"}, + OrganizationalUnit: []string{"Katana"}, + Locality: []string{"Delhi"}, + Province: []string{"Delhi"}, + CommonName: domain, + }, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(10, 0, 0), // 10 years validity + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + }, + BasicConstraintsValid: true, + } + certBytes, err := x509.CreateCertificate(rand.Reader, certTemplate, caTemplate, &privateKey.PublicKey, caKey) + if err != nil { + return err + } + certFile, err := os.Create(basePath + "/" + domain + ".crt") + if err != nil { + return err + } + defer certFile.Close() + if err := pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes}); err != nil { return err } + log.Println("Cert 7") return nil } diff --git a/lib/utils/kube.go b/lib/utils/kube.go index 42ce990d..5d28bece 100644 --- a/lib/utils/kube.go +++ b/lib/utils/kube.go @@ -210,6 +210,7 @@ func DeploymentConfig() types.ManifestConfig { HarborCrt: "", HarborCaCrt: "", HarborIP: "", + WireguardIP: "", NodeAffinityValue: "", } diff --git a/lib/wireguard/setup.go b/lib/wireguard/setup.go new file mode 100644 index 00000000..0abcc7f0 --- /dev/null +++ b/lib/wireguard/setup.go @@ -0,0 +1,53 @@ +package wireguard + +import ( + "bytes" + "context" + "html/template" + "log" + "path/filepath" + + "github.com/sdslabs/katana/configs" + "github.com/sdslabs/katana/lib/deployment" + "github.com/sdslabs/katana/lib/utils" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func SetupWireguard() error { + kubeConfig, _ := utils.GetKubeConfig() + kubeClient, _ := utils.GetKubeClient() + + namespace := "katana" + + manifest := &bytes.Buffer{} + + tmpl, err := template.ParseFiles(filepath.Join(configs.ClusterConfig.TemplatedManifestDir, "runtime", "wireguard.yml")) + if err != nil { + return err + } + + deploymentConfig := utils.DeploymentConfig() + + serviceName := "wireguard" + + service, err := kubeClient.CoreV1().Services(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{}) + if err != nil { + return err + } + + wireguard_lbIP := service.Status.LoadBalancer.Ingress + + //print the wireguard_lbIP + log.Println(wireguard_lbIP[0].IP) + deploymentConfig.WireguardIP = wireguard_lbIP[0].IP + + if err := tmpl.Execute(manifest, deploymentConfig); err != nil { + return err + } + + if err = deployment.ApplyManifest(kubeConfig, kubeClient, manifest.Bytes(), namespace); err != nil { + return err + } + + return nil +} diff --git a/services/infrasetservice/controller.go b/services/infrasetservice/controller.go index 6a266768..06575084 100644 --- a/services/infrasetservice/controller.go +++ b/services/infrasetservice/controller.go @@ -20,6 +20,7 @@ import ( "github.com/sdslabs/katana/lib/mongo" "github.com/sdslabs/katana/lib/mysql" utils "github.com/sdslabs/katana/lib/utils" + "github.com/sdslabs/katana/lib/wireguard" "github.com/sdslabs/katana/types" coreV1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -37,8 +38,9 @@ func InfraSet(c *fiber.Ctx) error { log.Fatal(err) } + log.Println("Creating harbor certs ...") generateCertsforHarbor() - + log.Println("Created harbor certs ...") if err = deployment.DeployCluster(config, kubeclient); err != nil { log.Fatal(err) } @@ -50,6 +52,11 @@ func InfraSet(c *fiber.Ctx) error { buildKatanaServices() + err = wireguard.SetupWireguard() + if err != nil { + log.Fatal(err) + } + return c.SendString("Infrastructure setup completed") } diff --git a/services/infrasetservice/helper.go b/services/infrasetservice/helper.go index c42bbdd0..929f66dd 100644 --- a/services/infrasetservice/helper.go +++ b/services/infrasetservice/helper.go @@ -19,6 +19,7 @@ func generateCertsforHarbor() { path, _ := os.Getwd() path = path + "/lib/harbor/certs" + log.Println("CHECK 1") // Delete the directory if it already exists if _, err := os.Stat(path); os.IsExist(err) { errDir := os.RemoveAll(path) @@ -26,18 +27,19 @@ func generateCertsforHarbor() { log.Fatal(err) } } - + log.Println("CHECK 2") if _, err := os.Stat(path); os.IsNotExist(err) { errDir := os.Mkdir(path, 0755) if errDir != nil { log.Fatal(err) } } - + log.Println("CHECK 3") // Generate the certificates if err := utils.GenerateCerts("harbor.katana.local", path); err != nil { log.Fatal(err) } + log.Println("CHECK 4") } func createTeamCredentials(teamNumber int) (string, types.CTFTeam) { diff --git a/types/deployment.go b/types/deployment.go index 4237db42..3ec33920 100644 --- a/types/deployment.go +++ b/types/deployment.go @@ -25,6 +25,7 @@ type ManifestConfig struct { HarborCrt string HarborCaCrt string HarborIP string + WireguardIP string NodeAffinityValue string }