From 8bb13fe34a4d2b471c5d478784268dca4cb19195 Mon Sep 17 00:00:00 2001 From: Aditya Bisht Date: Thu, 10 Aug 2023 22:38:52 +0530 Subject: [PATCH 01/15] Add wireguard.yml --- kubernetes/manifests/wireguard.yml | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 kubernetes/manifests/wireguard.yml diff --git a/kubernetes/manifests/wireguard.yml b/kubernetes/manifests/wireguard.yml new file mode 100644 index 00000000..ff18c9a4 --- /dev/null +++ b/kubernetes/manifests/wireguard.yml @@ -0,0 +1,67 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: wireguard-configmap + namespace: katana +data: + PUID: "1000" + PGID: "1000" + TZ: "America/Mexico_City" + SERVERPORT: "31820" + PEERS: "2" + PEERDNS: "10.0.0.10" + ALLOWEDIPS: "0.0.0.0/0, ::/0" + INTERNAL_SUBNET: "10.13.13.0" +--- +apiVersion: v1 +kind: Pod +metadata: + name: wireguard + namespace: katana + labels: + app: wireguard +spec: + containers: + - name: wireguard + image: linuxserver/wireguard + envFrom: + - configMapRef: + name: wireguard-configmap + securityContext: + capabilities: + add: + - NET_ADMIN + - SYS_MODULE + privileged: true + volumeMounts: + - name: wg-config + mountPath: /config + ports: + - containerPort: 51820 + protocol: UDP + resources: + requests: + memory: "64Mi" + cpu: "100m" + limits: + memory: "128Mi" + cpu: "200m" + volumes: + - name: wg-config + emptyDir: {} +--- +kind: Service +apiVersion: v1 +metadata: + labels: + k8s-app: wireguard + name: wireguard-service + namespace: katana +spec: + type: LoadBalancer + ports: + - port: 51820 + protocol: UDP + targetPort: 51820 + selector: + app: wireguard From 4620d539c05ee3eee6fdd513b57ceafe989ca377 Mon Sep 17 00:00:00 2001 From: Aditya Bisht Date: Thu, 10 Aug 2023 22:38:52 +0530 Subject: [PATCH 02/15] Add wireguard.yml --- kubernetes/manifests/wireguard.yml | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 kubernetes/manifests/wireguard.yml diff --git a/kubernetes/manifests/wireguard.yml b/kubernetes/manifests/wireguard.yml new file mode 100644 index 00000000..ff18c9a4 --- /dev/null +++ b/kubernetes/manifests/wireguard.yml @@ -0,0 +1,67 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: wireguard-configmap + namespace: katana +data: + PUID: "1000" + PGID: "1000" + TZ: "America/Mexico_City" + SERVERPORT: "31820" + PEERS: "2" + PEERDNS: "10.0.0.10" + ALLOWEDIPS: "0.0.0.0/0, ::/0" + INTERNAL_SUBNET: "10.13.13.0" +--- +apiVersion: v1 +kind: Pod +metadata: + name: wireguard + namespace: katana + labels: + app: wireguard +spec: + containers: + - name: wireguard + image: linuxserver/wireguard + envFrom: + - configMapRef: + name: wireguard-configmap + securityContext: + capabilities: + add: + - NET_ADMIN + - SYS_MODULE + privileged: true + volumeMounts: + - name: wg-config + mountPath: /config + ports: + - containerPort: 51820 + protocol: UDP + resources: + requests: + memory: "64Mi" + cpu: "100m" + limits: + memory: "128Mi" + cpu: "200m" + volumes: + - name: wg-config + emptyDir: {} +--- +kind: Service +apiVersion: v1 +metadata: + labels: + k8s-app: wireguard + name: wireguard-service + namespace: katana +spec: + type: LoadBalancer + ports: + - port: 51820 + protocol: UDP + targetPort: 51820 + selector: + app: wireguard From e11e493d2904c9dcf19dcaf7ce9835f22d02cb7f Mon Sep 17 00:00:00 2001 From: Perseus-Jackson477 Date: Wed, 30 Aug 2023 08:44:20 +0530 Subject: [PATCH 03/15] update submodule ref --- katana-services | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katana-services b/katana-services index 34fb4743..7eabff25 160000 --- a/katana-services +++ b/katana-services @@ -1 +1 @@ -Subproject commit 34fb47432e1118a50ca0f6f0a99e858a115b320f +Subproject commit 7eabff255a9b65cde4999af0e50854ca4050ee33 From d6994da4684d8ba33cfca8e6a8aa0d6150a15cf2 Mon Sep 17 00:00:00 2001 From: Perseus-Jackson477 Date: Wed, 30 Aug 2023 08:58:16 +0530 Subject: [PATCH 04/15] update submodule ref --- katana-services | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katana-services b/katana-services index 7eabff25..a79e56b2 160000 --- a/katana-services +++ b/katana-services @@ -1 +1 @@ -Subproject commit 7eabff255a9b65cde4999af0e50854ca4050ee33 +Subproject commit a79e56b2458f84a42fa51d293fa1bce036af57b5 From 531fde38c1c683a8eb42c5d9cb668ac93f057779 Mon Sep 17 00:00:00 2001 From: Perseus-Jackson477 Date: Wed, 30 Aug 2023 09:04:51 +0530 Subject: [PATCH 05/15] update wireguard yml --- kubernetes/manifests/wireguard-lb.yml | 15 +++++ kubernetes/manifests/wireguard.yml | 67 ------------------- kubernetes/templates/runtime/wireguard.yml | 75 ++++++++++++++++++++++ 3 files changed, 90 insertions(+), 67 deletions(-) create mode 100644 kubernetes/manifests/wireguard-lb.yml delete mode 100644 kubernetes/manifests/wireguard.yml create mode 100644 kubernetes/templates/runtime/wireguard.yml diff --git a/kubernetes/manifests/wireguard-lb.yml b/kubernetes/manifests/wireguard-lb.yml new file mode 100644 index 00000000..bdefc85e --- /dev/null +++ b/kubernetes/manifests/wireguard-lb.yml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: wireguard + name: wireguard + namespace: katana +spec: + type: LoadBalancer + ports: + - port: 51820 + protocol: UDP + targetPort: 51820 + selector: + app: wireguard diff --git a/kubernetes/manifests/wireguard.yml b/kubernetes/manifests/wireguard.yml deleted file mode 100644 index ff18c9a4..00000000 --- a/kubernetes/manifests/wireguard.yml +++ /dev/null @@ -1,67 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: wireguard-configmap - namespace: katana -data: - PUID: "1000" - PGID: "1000" - TZ: "America/Mexico_City" - SERVERPORT: "31820" - PEERS: "2" - PEERDNS: "10.0.0.10" - ALLOWEDIPS: "0.0.0.0/0, ::/0" - INTERNAL_SUBNET: "10.13.13.0" ---- -apiVersion: v1 -kind: Pod -metadata: - name: wireguard - namespace: katana - labels: - app: wireguard -spec: - containers: - - name: wireguard - image: linuxserver/wireguard - envFrom: - - configMapRef: - name: wireguard-configmap - securityContext: - capabilities: - add: - - NET_ADMIN - - SYS_MODULE - privileged: true - volumeMounts: - - name: wg-config - mountPath: /config - ports: - - containerPort: 51820 - protocol: UDP - resources: - requests: - memory: "64Mi" - cpu: "100m" - limits: - memory: "128Mi" - cpu: "200m" - volumes: - - name: wg-config - emptyDir: {} ---- -kind: Service -apiVersion: v1 -metadata: - labels: - k8s-app: wireguard - name: wireguard-service - namespace: katana -spec: - type: LoadBalancer - ports: - - port: 51820 - protocol: UDP - targetPort: 51820 - selector: - app: wireguard diff --git a/kubernetes/templates/runtime/wireguard.yml b/kubernetes/templates/runtime/wireguard.yml new file mode 100644 index 00000000..5a5f5866 --- /dev/null +++ b/kubernetes/templates/runtime/wireguard.yml @@ -0,0 +1,75 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: wireguard-configmap + namespace: katana +data: + #REQUIRED VARIABLES + PUID: "1000" # User ID, default 1000 + PGID: "1000" # Group ID + TZ: "Etc/UTC" # Timezone + PEERS: "team1,team2" # Comma separated list of peer names + + #OPTIONAL VARIABLES + SERVERURL: "{{.WireguardIP}}" #if not set, container tries to determine auto and mostly tells wrong, use lb ip here , pass dynamically best + SERVERPORT: "51820" + INTERNAL_SUBNET: "10.13.13.0" #Wireguard tunnel's internal addresses + PEERDNS: "10.0.0.10" + INTERFACE: "katana_wg" + ALLOWEDIPS: "0.0.0.0/0" #This is set for users, they can obv change it, so better to give 0.0.0.0/0 as nahi to append karni padti cheezein + #PERSISTENTKEEPALIVE_PEERS: (optional) , it is set to 25 by default (confirm?) + LOG_CONFS: "true" #optional , true by default + # POSTUP: "echo 1 > /proc/sys/net/ipv4/ip_forward; iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" + POSTUP : "iptables -I OUTPUT -i katana_wg -s 10.13.13.2/32 -j DROP; iptables -I INPUT -i katana_wg -s 10.13.13.2/32 -j DROP" + #iptables -I INPUT -i katana_wg -j DROP; + #-d 10.0.1.42 + #iptables -I OUTPUT -i katana_wg -s 10.13.13.2/32 -j DROP + #POSTDOWN: "iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE" + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: wireguard-deployment + namespace: katana + labels: + app: wireguard +spec: + replicas: 1 + selector: + matchLabels: + app: wireguard + template: + metadata: + labels: + app: wireguard + spec: + containers: + - name: wireguard + image: harbor.katana.local/katana/wireguard + imagePullPolicy: Always + envFrom: + - configMapRef: + name: wireguard-configmap + securityContext: + capabilities: + add: + - NET_ADMIN + - SYS_MODULE + privileged: true + volumeMounts: + - name: wg-config + mountPath: /config + ports: + - containerPort: 51820 + protocol: UDP + resources: + requests: + memory: "64Mi" + cpu: "100m" + limits: + memory: "128Mi" + cpu: "200m" + volumes: + - name: wg-config + emptyDir: {} \ No newline at end of file From 3806fa81bd870d757cea0e4e4068c54caaecc481 Mon Sep 17 00:00:00 2001 From: ashpect Date: Wed, 30 Aug 2023 12:41:34 +0530 Subject: [PATCH 06/15] remove cmd for certs and dynamic lb ip for wireguard --- lib/utils/crypto.go | 142 ++++++++++++++++++++++--- lib/utils/kube.go | 1 + lib/wireguard/setup.go | 53 +++++++++ services/infrasetservice/controller.go | 9 +- services/infrasetservice/helper.go | 6 +- types/deployment.go | 1 + 6 files changed, 197 insertions(+), 15 deletions(-) create mode 100644 lib/wireguard/setup.go 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 } From 070aeda9bed4fc236fe1dbbc26d0216bc9ff58fc Mon Sep 17 00:00:00 2001 From: ashpect Date: Fri, 1 Sep 2023 04:09:34 +0530 Subject: [PATCH 07/15] Get route for pre-existing challenges --- lib/utils/docker.go | 9 +++ .../challengedeployerservice/controller.go | 63 ++++++++++++++++++- services/challengedeployerservice/helper.go | 3 +- services/master/server.go | 1 + 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/lib/utils/docker.go b/lib/utils/docker.go index 42eac8f9..4a899e53 100644 --- a/lib/utils/docker.go +++ b/lib/utils/docker.go @@ -38,6 +38,11 @@ func dockerLogin(username string, password string) { log.Println("Logged into Harbor successfully") } +func CheckDockerfile(_DockerfilePath string) bool { + _, err := os.Stat(_DockerfilePath + "/Dockerfile") + return !os.IsNotExist(err) +} + func BuildDockerImage(_ChallengeName string, _DockerfilePath string) { buf := new(bytes.Buffer) if err := Tar(_DockerfilePath, buf); err != nil { @@ -50,6 +55,10 @@ func BuildDockerImage(_ChallengeName string, _DockerfilePath string) { return } + log.Println(_ChallengeName) + log.Println("dfsdfsdfsdf") + log.Println(_DockerfilePath) + log.Println("Building Docker image, Please wait......") imageBuildResponse, err := cli.ImageBuild( diff --git a/services/challengedeployerservice/controller.go b/services/challengedeployerservice/controller.go index bda33fe1..7aee3aa1 100644 --- a/services/challengedeployerservice/controller.go +++ b/services/challengedeployerservice/controller.go @@ -20,9 +20,68 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func Deploy(c *fiber.Ctx) error { + patch := false + replicas := int32(1) + log.Println("Starting") + //read folder challenge by os + dir, err := os.Open("./challenges") + //loop over all subfolders in the challenge folder + if err != nil { + log.Println("Error in opening challenges folder") + return err + } + defer dir.Close() + //Read all challenges in the folder + fileInfos, err := dir.Readdir(-1) + if err != nil { + log.Println("Error in reading challenges folder") + return err + } + + res := make([][]string, 0) + + //Loop over all folders + for _, fileInfo := range fileInfos { + //check if it is a directory + if fileInfo.IsDir() { + //Get the challenger name + folderName := fileInfo.Name() + log.Println("Folder name is : " + folderName) + //update challenge path to be absolute path + challengePath, _ := os.Getwd() + challengePath = challengePath + "/challenges/" + folderName + log.Println("Challenge path is : " + challengePath) + //check if the folder has a Dockerfile + if utils.CheckDockerfile(challengePath + "/" + folderName) { + + //Update challenge path to get dockerfile + utils.BuildDockerImage(folderName, challengePath+"/"+folderName) + + clusterConfig := g.ClusterConfig + numberOfTeams := clusterConfig.TeamCount + for i := 0; i < int(numberOfTeams); i++ { + log.Println("-----------Deploying challenge for team: " + strconv.Itoa(i) + " --------") + teamName := "katana-team-" + strconv.Itoa(i) + deployment.DeployChallengeToCluster(folderName, teamName, patch, replicas) + url, err := createServiceForChallenge(folderName, teamName, 3000, i) + if err != nil { + res = append(res, []string{teamName, err.Error()}) + } else { + res = append(res, []string{teamName, url}) + } + } + } else { + log.Println("Dockerfile not found in the " + folderName + " challenge folder. Please follow proper format.") + } + } + } + return c.JSON(res) +} + func DeployChallenge(c *fiber.Ctx) error { - challengeType := "web" + //challengeType := "web" folderName := "" patch := false replicas := int32(1) @@ -88,7 +147,7 @@ func DeployChallenge(c *fiber.Ctx) error { } //Copy challenge in pods and etc. - copyChallengeIntoTsuka(challengePath, folderName, challengeType) + //copyChallengeIntoTsuka(challengePath, folderName, challengeType) return c.JSON(res) } diff --git a/services/challengedeployerservice/helper.go b/services/challengedeployerservice/helper.go index cd5bba2e..3c141a29 100644 --- a/services/challengedeployerservice/helper.go +++ b/services/challengedeployerservice/helper.go @@ -5,6 +5,7 @@ import ( "log" "os" "regexp" + "strconv" git "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" @@ -69,7 +70,7 @@ func copyChallengeIntoTsuka(dirPath string, challengeName string, challengeType func createServiceForChallenge(challengeName, teamName string, targetPort int32, teamNumber int) (string, error) { kubeclient, _ := utils.GetKubeClient() - serviceName := challengeName + "-svc" + serviceName := challengeName + "-svc-" + strconv.Itoa(teamNumber) teamNamespace := teamName + "-ns" port := int32(80) selector := map[string]string{ diff --git a/services/master/server.go b/services/master/server.go index 30912308..91a16df4 100644 --- a/services/master/server.go +++ b/services/master/server.go @@ -46,6 +46,7 @@ func Server() error { admin.Post("/login", infraSetService.Login) admin.Get("/createTeams", infraSetService.CreateTeams) admin.Post("/challengeUpdate", challengeDeployerService.ChallengeUpdate) + admin.Get("/deploy", challengeDeployerService.Deploy) admin.Post("/deployChallenge", challengeDeployerService.DeployChallenge) admin.Get("/gitServer", infraSetService.GitServer) admin.Get("/deleteChallenge/:chall_name", challengeDeployerService.DeleteChallenge) From b07beea16242e982a560a0e6b6d2237ff79e4016 Mon Sep 17 00:00:00 2001 From: ashpect Date: Fri, 1 Sep 2023 12:10:41 +0530 Subject: [PATCH 08/15] [wip] remove cmd for certs --- lib/utils/crypto.go | 291 ++++++++++++++++++++++++-------------------- 1 file changed, 160 insertions(+), 131 deletions(-) diff --git a/lib/utils/crypto.go b/lib/utils/crypto.go index 5e69f00e..dc5a747d 100644 --- a/lib/utils/crypto.go +++ b/lib/utils/crypto.go @@ -1,21 +1,11 @@ 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" @@ -33,155 +23,194 @@ func Base64Encode(str string) string { return base64.StdEncoding.EncodeToString([]byte(str)) } -// Generating certificates from domain name func GenerateCerts(domain string, basePath string) error { - log.Println("Cert 1") // Generate ca.key in harbor directory - 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 { + cmd := "openssl genrsa -out " + basePath + "/ca.key 4096" + if err := RunCommand(cmd); err != nil { return err } - log.Println("Cert 2") // Generate ca.crt - 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 { + 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 { return err } - log.Println("Cert 3") // Generate private key - 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 { + cmd = "openssl genrsa -out " + basePath + "/" + domain + ".key 4096" + if err := RunCommand(cmd); err != nil { return err } - log.Println("Cert 4") // Generate certificate signing request - 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 { + 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 { return err } - log.Println("Cert 5") // Generate v3.ext file - 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 { + 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 { return err } - log.Println("Cert 6") // Generate certificate - 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 { + 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 { return err } - log.Println("Cert 7") return nil } +// [DO NOT REMOVE....WIP....] + +// Generating certificates without cmd commands +// func GenerateCerts(domain string, basePath string) error { +// log.Println("Cert 1") +// // Generate ca.key in harbor directory +// caKey, err := rsa.GenerateKey(rand.Reader, 4096) +// if err != nil { +// return err +// } +// caKeyBytes := x509.MarshalPKCS1PrivateKey(caKey) +// caKeyFile, err := os.Create(basePath + "/ca.key") +// if err != nil { +// return err +// } +// defer caKeyFile.Close() +// if err := pem.Encode(caKeyFile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: caKeyBytes}); err != nil { +// return err +// } + +// log.Println("Cert 2") +// // Generate ca.crt +// 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 +// 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 +// 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 +// 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 +// 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 +// } + func HashPassword(password string) (string, error) { pass := []byte(password) hash, err := bcrypt.GenerateFromPassword(pass, bcrypt.MinCost) From 4ed28b46b2f62ba703656713ae4dbe8474897755 Mon Sep 17 00:00:00 2001 From: ashpect Date: Fri, 1 Sep 2023 12:52:51 +0530 Subject: [PATCH 09/15] Write firewall rules in image --- lib/wireguard/firewall.go | 88 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lib/wireguard/firewall.go diff --git a/lib/wireguard/firewall.go b/lib/wireguard/firewall.go new file mode 100644 index 00000000..391864e9 --- /dev/null +++ b/lib/wireguard/firewall.go @@ -0,0 +1,88 @@ +package wireguard + +import ( + "fmt" + "log" + "os" + "strconv" + + g "github.com/sdslabs/katana/configs" +) + +func ApplyFirewall() error { + + //Read challenges folder + dir, err := os.Open("./challenges") + + if err != nil { + log.Println("Error in opening challenges folder") + return err + } + defer dir.Close() + + fileInfos, err := dir.Readdir(-1) + if err != nil { + log.Println("Error in reading challenges folder") + return err + } + + //Store challenge names in a slice + challengeNames := make([]string, 0) + for _, fileInfo := range fileInfos { + if fileInfo.IsDir() { + challengeNames = append(challengeNames, fileInfo.Name()) + } + } + + numberOfTeams := g.ClusterConfig.TeamCount + teamIPs := make([]string, 0) + + baseip := "10.13.13." + //add team ips to teamIPs + for i := 0; i < int(numberOfTeams); i++ { + teamIPs = append(teamIPs, baseip+strconv.Itoa(i+2)+"/32") + } + + //print the teamIPs + log.Println(teamIPs) + + //create a slice of string to store iptables commands + IpTable := make([]string, 0) + + //add iptables rules to block all internet traffic + for i := 0; i < int(numberOfTeams); i++ { + IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -o eth+ -j DROP") + } + + //add iptables rules to allow traffic to nginx service + for i := 0; i < int(numberOfTeams); i++ { + for j := 0; j < len(challengeNames); j++ { + IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d "+challengeNames[j]+"-svc-"+strconv.Itoa(i)+".katana.svc.cluster.local -j ACCEPT") + } + } + + // Print all iptables rules + for i := 0; i < len(IpTable); i++ { + log.Println(IpTable[i]) + } + + //append all iptables rules to a string + finalIprules := "" + for i := 0; i < len(IpTable); i++ { + finalIprules += IpTable[i] + "; " + } + + //Overwrite firewall.conf by this string stored in the root directory + filepath, err := os.Getwd() + if err != nil { + log.Println(err) + } + filepath = filepath + "/katana-services/Wireguard/root/defaults/firewall.conf" + err = os.WriteFile(filepath, []byte(finalIprules), 0644) + if err != nil { + fmt.Println("Error writing to file:", err) + return err + } + + return nil +} From 7f851eff8cc3d8f142e46f9b9821aeef4f8f6f06 Mon Sep 17 00:00:00 2001 From: ashpect Date: Fri, 1 Sep 2023 12:53:37 +0530 Subject: [PATCH 10/15] add sample challenges --- challenges_sample/knock/knock.tar.gz | Bin 0 -> 7914 bytes challenges_sample/knock/knock/Dockerfile | 15 + challenges_sample/knock/knock/challenge.yaml | 26 ++ challenges_sample/knock/knock/index.js | 62 +++ challenges_sample/knock/knock/package.json | 9 + .../knock/knock/public/index.html | 45 +++ challenges_sample/knock/knock/yarn.lock | 352 ++++++++++++++++++ challenges_sample/vmcalc/vmcalc.tar.gz | Bin 0 -> 2855 bytes challenges_sample/vmcalc/vmcalc/.dockerignore | 4 + challenges_sample/vmcalc/vmcalc/Dockerfile | 17 + .../vmcalc/vmcalc/challenge.yaml | 17 + challenges_sample/vmcalc/vmcalc/dist.tar | Bin 0 -> 20480 bytes challenges_sample/vmcalc/vmcalc/flag.txt | 1 + challenges_sample/vmcalc/vmcalc/index.js | 69 ++++ challenges_sample/vmcalc/vmcalc/package.json | 16 + .../vmcalc/vmcalc/views/admin.hbs | 33 ++ .../vmcalc/vmcalc/views/index.hbs | 28 ++ 17 files changed, 694 insertions(+) create mode 100644 challenges_sample/knock/knock.tar.gz create mode 100644 challenges_sample/knock/knock/Dockerfile create mode 100644 challenges_sample/knock/knock/challenge.yaml create mode 100644 challenges_sample/knock/knock/index.js create mode 100644 challenges_sample/knock/knock/package.json create mode 100644 challenges_sample/knock/knock/public/index.html create mode 100644 challenges_sample/knock/knock/yarn.lock create mode 100644 challenges_sample/vmcalc/vmcalc.tar.gz create mode 100644 challenges_sample/vmcalc/vmcalc/.dockerignore create mode 100644 challenges_sample/vmcalc/vmcalc/Dockerfile create mode 100644 challenges_sample/vmcalc/vmcalc/challenge.yaml create mode 100644 challenges_sample/vmcalc/vmcalc/dist.tar create mode 100644 challenges_sample/vmcalc/vmcalc/flag.txt create mode 100644 challenges_sample/vmcalc/vmcalc/index.js create mode 100644 challenges_sample/vmcalc/vmcalc/package.json create mode 100644 challenges_sample/vmcalc/vmcalc/views/admin.hbs create mode 100644 challenges_sample/vmcalc/vmcalc/views/index.hbs diff --git a/challenges_sample/knock/knock.tar.gz b/challenges_sample/knock/knock.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2895b7f4d129e82887cf47217f2842701ea61715 GIT binary patch literal 7914 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 Ux8vLK?YQaqA0WV)dH`Gi04{QNG5`Po literal 0 HcmV?d00001 diff --git a/challenges_sample/knock/knock/Dockerfile b/challenges_sample/knock/knock/Dockerfile new file mode 100644 index 00000000..f14059ae --- /dev/null +++ b/challenges_sample/knock/knock/Dockerfile @@ -0,0 +1,15 @@ +FROM node:17.4.0-buster-slim + +RUN mkdir -p /app + +WORKDIR /app + +COPY package.json . + +RUN yarn + +COPY . . + +USER node + +CMD ["node", "index.js"] diff --git a/challenges_sample/knock/knock/challenge.yaml b/challenges_sample/knock/knock/challenge.yaml new file mode 100644 index 00000000..60edf523 --- /dev/null +++ b/challenges_sample/knock/knock/challenge.yaml @@ -0,0 +1,26 @@ +name: knock-knock +author: BrownieInMotion +description: |- + Knock knock? Who's there? Another pastebin!! + + ${link_main_0} + +flag: dice{1_d00r_y0u_d00r_w3_a11_d00r_f0r_1_d00r} + +provide: + - ./index.js + - ./Dockerfile + +containers: + main: + build: . + ports: + - 3000 + environment: + FLAG: "dice{1_d00r_y0u_d00r_w3_a11_d00r_f0r_1_d00r}" + +expose: + main: + - target: 3000 + http: knock-knock + healthContent: Create Paste diff --git a/challenges_sample/knock/knock/index.js b/challenges_sample/knock/knock/index.js new file mode 100644 index 00000000..82844e68 --- /dev/null +++ b/challenges_sample/knock/knock/index.js @@ -0,0 +1,62 @@ +const crypto = require('crypto'); + +class Database { + constructor() { + this.notes = []; + this.secret = `secret-${crypto.randomUUID}`; + } + + createNote({ data }) { + const id = this.notes.length; + this.notes.push(data); + return { + id, + token: this.generateToken(id), + }; + } + + getNote({ id, token }) { + if (token !== this.generateToken(id)) return { error: 'invalid token' }; + if (id >= this.notes.length) return { error: 'note not found' }; + return { data: this.notes[id] }; + } + + generateToken(id) { + return crypto + .createHmac('sha256', this.secret) + .update(id.toString()) + .digest('hex'); + } +} + +const db = new Database(); +db.createNote({ data: process.env.FLAG }); + +const express = require('express'); +const app = express(); + +app.use(express.urlencoded({ extended: false })); +app.use(express.static('public')); + +app.post('/create', (req, res) => { + const data = req.body.data ?? 'no data provided.'; + const { id, token } = db.createNote({ data: data.toString() }); + res.redirect(`/note?id=${id}&token=${token}`); +}); + +app.get('/note', (req, res) => { + const { id, token } = req.query; + const note = db.getNote({ + id: parseInt(id ?? '-1'), + token: (token ?? '').toString(), + }); + if (note.error) { + res.send(note.error); + } else { + res.send(note.data); + } +}); + +app.listen(3000, () => { + console.log('listening on port 3000'); +}); diff --git a/challenges_sample/knock/knock/package.json b/challenges_sample/knock/knock/package.json new file mode 100644 index 00000000..d4227a06 --- /dev/null +++ b/challenges_sample/knock/knock/package.json @@ -0,0 +1,9 @@ +{ + "name": "knock-knock", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "express": "^4.17.2" + } +} diff --git a/challenges_sample/knock/knock/public/index.html b/challenges_sample/knock/knock/public/index.html new file mode 100644 index 00000000..526b2dc5 --- /dev/null +++ b/challenges_sample/knock/knock/public/index.html @@ -0,0 +1,45 @@ + + +
+

Create Paste

+
+ + +
+
diff --git a/challenges_sample/knock/knock/yarn.lock b/challenges_sample/knock/knock/yarn.lock new file mode 100644 index 00000000..1dd58a8c --- /dev/null +++ b/challenges_sample/knock/knock/yarn.lock @@ -0,0 +1,352 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.7: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +body-parser@1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +express@^4.17.2: + version "4.17.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" + integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.6" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= diff --git a/challenges_sample/vmcalc/vmcalc.tar.gz b/challenges_sample/vmcalc/vmcalc.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..bbb690f8bba3a44296e5c720583badcf6b07e65e GIT binary patch literal 2855 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 crypto.createHash('sha256').update(data).digest('hex'); + +const app = express(); + +app.set("view engine", "hbs"); + +app.use(express.urlencoded({ extended: false })); + +app.get("/", (req, res) => res.render("index")); +app.post("/", (req, res) => { + const { calc } = req.body; + + if(!calc) { + return res.render("index"); + } + + let result; + try { + result = vm.run(`return ${calc}`); + } + catch(err) { + console.log(err); + return res.render("index", { result: "There was an error running your calculation!"}); + } + + if(typeof result !== "number") { + return res.render("index", { result: "Nice try..."}); + } + + res.render("index", { result }); +}); + +app.get("/admin", (req, res) => res.render("admin")); + +app.post("/admin", async (req, res) => { + let { user, pass } = req.body; + if(!user || !pass || typeof user !== "string" || typeof pass !== "string") { + return res.render("admin", { error: "Missing username or password!" }); + } + + let hash = sha256(pass); + if(users.filter(u => u.user === user && u.pass === hash)[0] !== undefined) { + res.render("admin", { flag: await fsp.readFile("flag.txt") }); + } + else { + res.render("admin", { error: "Incorrect username or password!" }); + } +}); + +app.listen(PORT, () => console.log(`vm-calc listening on port ${PORT}`)); \ No newline at end of file diff --git a/challenges_sample/vmcalc/vmcalc/package.json b/challenges_sample/vmcalc/vmcalc/package.json new file mode 100644 index 00000000..859d2aa3 --- /dev/null +++ b/challenges_sample/vmcalc/vmcalc/package.json @@ -0,0 +1,16 @@ +{ + "name": "vm-calc", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Strellic", + "license": "ISC", + "dependencies": { + "express": "^4.17.2", + "hbs": "^4.2.0", + "vm2": "^3.9.5" + } +} diff --git a/challenges_sample/vmcalc/vmcalc/views/admin.hbs b/challenges_sample/vmcalc/vmcalc/views/admin.hbs new file mode 100644 index 00000000..b2fc9dd9 --- /dev/null +++ b/challenges_sample/vmcalc/vmcalc/views/admin.hbs @@ -0,0 +1,33 @@ + + + + vm-calc | admin + + + +
+ +

vm-calc | admin

+

Log into the admin account here.

+
+ +
+

Login:

+ {{#if error}} +

Error: {{error}}

+ {{/if}} + {{#if flag}} +

Flag: {{flag}}

+ {{/if}} + +
+ + + +
+
+ + \ No newline at end of file diff --git a/challenges_sample/vmcalc/vmcalc/views/index.hbs b/challenges_sample/vmcalc/vmcalc/views/index.hbs new file mode 100644 index 00000000..b23ea779 --- /dev/null +++ b/challenges_sample/vmcalc/vmcalc/views/index.hbs @@ -0,0 +1,28 @@ + + + + vm-calc + + + +
+ +

vm-calc

+

A simple and very secure online calculator!

+
+ +
+

Enter math expression here:

+
+ + +
+ {{#if result}} +

Result: {{result}}

+ {{/if}} +
+ + \ No newline at end of file From 7b03e42e3e80ac757bc2121a1d6834ac95f3d2ad Mon Sep 17 00:00:00 2001 From: ashpect Date: Fri, 1 Sep 2023 15:25:39 +0530 Subject: [PATCH 11/15] Wireguard finishup --- kubernetes/templates/runtime/wireguard.yml | 2 +- lib/utils/kube.go | 83 +++++++++++++++ lib/wireguard/setup.go | 111 ++++++++++++++++++++- services/infrasetservice/controller.go | 5 + 4 files changed, 198 insertions(+), 3 deletions(-) diff --git a/kubernetes/templates/runtime/wireguard.yml b/kubernetes/templates/runtime/wireguard.yml index 5a5f5866..aae6e8ab 100644 --- a/kubernetes/templates/runtime/wireguard.yml +++ b/kubernetes/templates/runtime/wireguard.yml @@ -8,7 +8,7 @@ data: PUID: "1000" # User ID, default 1000 PGID: "1000" # Group ID TZ: "Etc/UTC" # Timezone - PEERS: "team1,team2" # Comma separated list of peer names + PEERS: "2" # Comma separated list of peer names #OPTIONAL VARIABLES SERVERURL: "{{.WireguardIP}}" #if not set, container tries to determine auto and mostly tells wrong, use lb ip here , pass dynamically best diff --git a/lib/utils/kube.go b/lib/utils/kube.go index 5d28bece..5703d555 100644 --- a/lib/utils/kube.go +++ b/lib/utils/kube.go @@ -3,6 +3,7 @@ package utils import ( "bytes" "context" + "fmt" "io/ioutil" "log" "os" @@ -94,6 +95,88 @@ func GetMongoIP() string { return service.Spec.ClusterIP } +func CopyFromPod(podName string, containerName string, pathInPod string, localFilePath string, ns ...string) error { + config, err := GetKubeConfig() + if err != nil { + return err + } + + client, err := GetKubeClient() + if err != nil { + return err + } + + namespace := "katana" + if len(ns) > 0 { + namespace = ns[0] + } + + pod, err := client.CoreV1().Pods(namespace).Get(context.TODO(), podName, metav1.GetOptions{}) + if err != nil { + log.Printf("Error getting pod: %s\n", err) + } + + // Find the container in the pod + var container *corev1.Container + for _, c := range pod.Spec.Containers { + if c.Name == containerName { + container = &c + break + } + } + + if container == nil { + log.Printf("Container not found in pod\n") + err = fmt.Errorf("container not found in pod") + return err + } + + // Create a stream to the container + req := client.CoreV1().RESTClient().Post(). + Resource("pods"). + Name(podName). + Namespace(namespace). + SubResource("exec"). + Param("container", containerName) + + req.VersionedParams(&corev1.PodExecOptions{ + Container: containerName, + Command: []string{"cat", pathInPod}, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: false, + }, scheme.ParameterCodec) + + exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL()) + if err != nil { + log.Printf("Error creating executor: %s\n", err) + return err + } + + localFile, err := os.Create(localFilePath) + if err != nil { + log.Printf("Error creating local file: %s\n", err) + return err + } + defer localFile.Close() + + // Stream the file + err = exec.Stream(remotecommand.StreamOptions{ + Stdin: nil, + Stdout: localFile, + Stderr: os.Stderr, + Tty: false, + }) + if err != nil { + log.Printf("Error streaming the file: %s\n", err) + return err + } + + log.Println("File copied successfully") + return nil +} + func CopyIntoPod(podName string, containerName string, pathInPod string, localFilePath string, ns ...string) error { config, err := GetKubeConfig() if err != nil { diff --git a/lib/wireguard/setup.go b/lib/wireguard/setup.go index 0abcc7f0..b87052ea 100644 --- a/lib/wireguard/setup.go +++ b/lib/wireguard/setup.go @@ -3,14 +3,20 @@ package wireguard import ( "bytes" "context" + "fmt" "html/template" "log" + "os" "path/filepath" + "strconv" + "time" "github.com/sdslabs/katana/configs" "github.com/sdslabs/katana/lib/deployment" "github.com/sdslabs/katana/lib/utils" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" ) func SetupWireguard() error { @@ -37,8 +43,6 @@ func SetupWireguard() error { 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 { @@ -49,5 +53,108 @@ func SetupWireguard() error { return err } + noOfTeams := int(configs.ClusterConfig.TeamCount) + + configPath, err := os.Getwd() + if err != nil { + log.Println(err) + return err + } + configPath = configPath + "/peer_configs" + _, err = os.Stat(configPath) + if os.IsNotExist(err) { + err = os.MkdirAll(configPath, os.ModePerm) + if err != nil { + fmt.Printf("Error creating folder: %v\n", err) + } else { + fmt.Println("peer_configs folder created successfully.") + } + } else if err != nil { + fmt.Printf("Error checking folder existence: %v\n", err) + } + + for i := 0; i < noOfTeams; i++ { + if err := GetConfigFiles(strconv.Itoa(i + 1)); err != nil { + return err + } + } + return nil } + +func GetConfigFiles(team_number string) error { + + client, _ := utils.GetKubeClient() + + deploymentNames := []string{ + "wireguard-deployment", + } + namespace := "katana" + + for _, deploymentName := range deploymentNames { + if err := utils.WaitForDeploymentReady(client, deploymentName, namespace); err != nil { + log.Printf("Error testing deployment '%s': %v\n", deploymentName, err) + } + } + + //get pod in the wireguard deployment + pods, err := client.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ + LabelSelector: "app=wireguard", + }) + if err != nil { + log.Printf("Error getting pod: %s\n", err) + } + + wireguardPod := pods.Items[0] + wireguardContainer := wireguardPod.Spec.Containers[0] + + pathInPod := "/config/peer" + team_number + "/peer" + team_number + ".conf" + localFilePath := "./peer_configs/peer" + team_number + ".conf" + + //wait for container ready + time.Sleep(1 * time.Minute) + // if err := waitForContainerRunning(client, wireguardPod.Name, wireguardContainer.Name, namespace, 10*time.Minute); err != nil { + // log.Printf("Error waiting for container to become running: %v\n", err) + // } + + if err := utils.CopyFromPod(wireguardPod.Name, wireguardContainer.Name, pathInPod, localFilePath, namespace); err != nil { + log.Println(err) + return err + } + + return nil + +} + +// [WIP] : Replace time.Sleep with waitForContainerRunning +func waitForContainerRunning(client *kubernetes.Clientset, podName, containerName, namespace string, timeout time.Duration) error { + startTime := time.Now() + for { + // Get the pod + pod, err := client.CoreV1().Pods(namespace).Get(context.TODO(), podName, metav1.GetOptions{}) + if err != nil { + return err + } + + // Find the container in the pod + var containerStatus *corev1.ContainerStatus + for _, status := range pod.Status.ContainerStatuses { + if status.Name == containerName { + containerStatus = &status + break + } + } + + if containerStatus != nil && containerStatus.State.Running != nil { + return nil // Container is in the "Running" state + } + + // Check if the timeout has been reached + if time.Since(startTime) >= timeout { + return fmt.Errorf("timed out waiting for container to become running") + } + + // Sleep for a while before checking again + time.Sleep(1 * time.Second) // Adjust the sleep duration as needed + } +} diff --git a/services/infrasetservice/controller.go b/services/infrasetservice/controller.go index 06575084..93146165 100644 --- a/services/infrasetservice/controller.go +++ b/services/infrasetservice/controller.go @@ -50,6 +50,11 @@ func InfraSet(c *fiber.Ctx) error { log.Fatal(err) } + err = wireguard.ApplyFirewall() + if err != nil { + log.Fatal(err) + } + buildKatanaServices() err = wireguard.SetupWireguard() From fbf7bd89b2e675040b73325c23c16a7e6a69ff06 Mon Sep 17 00:00:00 2001 From: ashpect Date: Wed, 18 Oct 2023 02:21:01 +0530 Subject: [PATCH 12/15] update --- lib/wireguard/firewall.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/wireguard/firewall.go b/lib/wireguard/firewall.go index 391864e9..1c37d447 100644 --- a/lib/wireguard/firewall.go +++ b/lib/wireguard/firewall.go @@ -54,10 +54,17 @@ func ApplyFirewall() error { IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -o eth+ -j DROP") } - //add iptables rules to allow traffic to nginx service + //add iptables rules to allow traffic to challenges service for i := 0; i < int(numberOfTeams); i++ { for j := 0; j < len(challengeNames); j++ { - IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d "+challengeNames[j]+"-svc-"+strconv.Itoa(i)+".katana.svc.cluster.local -j ACCEPT") + IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d "+challengeNames[j]+"-svc-"+strconv.Itoa(i)+"katana-team-"+strconv.Itoa(i)+"-ns.svc.cluster.local -j ACCEPT") + } + } + + //add iptables rules to allow access to masterpod + for i := 0; i < int(numberOfTeams); i++ { + for j := 0; j < len(challengeNames); j++ { + IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d ctfteam.katana-team-"+strconv.Itoa(i)+"-ns.svc.cluster.local -j ACCEPT") } } From ae679ded48c4ca70fe72a041e280930ef53db4cd Mon Sep 17 00:00:00 2001 From: ashpect Date: Wed, 18 Oct 2023 05:29:08 +0530 Subject: [PATCH 13/15] fix --- kubernetes/templates/runtime/teams.yml | 14 +++++++++++++- lib/wireguard/firewall.go | 18 +++++------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/kubernetes/templates/runtime/teams.yml b/kubernetes/templates/runtime/teams.yml index b47b7e1c..82c4683c 100644 --- a/kubernetes/templates/runtime/teams.yml +++ b/kubernetes/templates/runtime/teams.yml @@ -52,4 +52,16 @@ spec: valueFrom: configMapKeyRef: name: teamvm-config - key: ssh_password \ No newline at end of file + key: ssh_password +--- +apiVersion: v1 +kind: Service +metadata: + name: tsuka-svc +spec: + selector: + app: {{.TeamLabel}} + ports: + - protocol: TCP + port: 22 + type: ClusterIP \ No newline at end of file diff --git a/lib/wireguard/firewall.go b/lib/wireguard/firewall.go index 1c37d447..ba78798f 100644 --- a/lib/wireguard/firewall.go +++ b/lib/wireguard/firewall.go @@ -43,9 +43,6 @@ func ApplyFirewall() error { teamIPs = append(teamIPs, baseip+strconv.Itoa(i+2)+"/32") } - //print the teamIPs - log.Println(teamIPs) - //create a slice of string to store iptables commands IpTable := make([]string, 0) @@ -54,23 +51,18 @@ func ApplyFirewall() error { IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -o eth+ -j DROP") } - //add iptables rules to allow traffic to challenges service + //add iptables rules to allow traffic to all challenges service for i := 0; i < int(numberOfTeams); i++ { for j := 0; j < len(challengeNames); j++ { - IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d "+challengeNames[j]+"-svc-"+strconv.Itoa(i)+"katana-team-"+strconv.Itoa(i)+"-ns.svc.cluster.local -j ACCEPT") + for k := 0; k < int(numberOfTeams); k++ { + IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d "+challengeNames[j]+"-svc-"+strconv.Itoa(k)+".katana-team-"+strconv.Itoa(k)+"-ns.svc.cluster.local -j ACCEPT") + } } } //add iptables rules to allow access to masterpod for i := 0; i < int(numberOfTeams); i++ { - for j := 0; j < len(challengeNames); j++ { - IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d ctfteam.katana-team-"+strconv.Itoa(i)+"-ns.svc.cluster.local -j ACCEPT") - } - } - - // Print all iptables rules - for i := 0; i < len(IpTable); i++ { - log.Println(IpTable[i]) + IpTable = append(IpTable, "iptables -I FORWARD -s "+teamIPs[i]+" -d tsuka-svc.katana-team-"+strconv.Itoa(i)+"-ns.svc.cluster.local -j ACCEPT") } //append all iptables rules to a string From 20912bdd796387d430cffea1df29d762846f0628 Mon Sep 17 00:00:00 2001 From: ashpect Date: Thu, 21 Dec 2023 01:29:49 +0530 Subject: [PATCH 14/15] update crypto.go --- lib/utils/crypto.go | 160 ++++---------------------------------------- 1 file changed, 12 insertions(+), 148 deletions(-) diff --git a/lib/utils/crypto.go b/lib/utils/crypto.go index dc5a747d..f7a50ae4 100644 --- a/lib/utils/crypto.go +++ b/lib/utils/crypto.go @@ -30,12 +30,24 @@ func GenerateCerts(domain string, basePath string) error { return err } + // using -traditional flag to get PKCS#1 [different header], otherwise 500 Internal Error + cmd = "openssl rsa -in " + basePath + "/ca.key -out " + basePath + "/ca.key -traditional" + if err := RunCommand(cmd); err != nil { + return err + } + // 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 { return err } + // using -traditional flag to get PKCS#1 [different header], otherwise 500 Internal Error + cmd = "openssl rsa -in " + basePath + "/" + domain + ".key -out " + basePath + "/" + domain + ".key -traditional" + if err := RunCommand(cmd); err != nil { + return err + } + // Generate private key cmd = "openssl genrsa -out " + basePath + "/" + domain + ".key 4096" if err := RunCommand(cmd); err != nil { @@ -63,154 +75,6 @@ func GenerateCerts(domain string, basePath string) error { return nil } -// [DO NOT REMOVE....WIP....] - -// Generating certificates without cmd commands -// func GenerateCerts(domain string, basePath string) error { -// log.Println("Cert 1") -// // Generate ca.key in harbor directory -// caKey, err := rsa.GenerateKey(rand.Reader, 4096) -// if err != nil { -// return err -// } -// caKeyBytes := x509.MarshalPKCS1PrivateKey(caKey) -// caKeyFile, err := os.Create(basePath + "/ca.key") -// if err != nil { -// return err -// } -// defer caKeyFile.Close() -// if err := pem.Encode(caKeyFile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: caKeyBytes}); err != nil { -// return err -// } - -// log.Println("Cert 2") -// // Generate ca.crt -// 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 -// 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 -// 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 -// 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 -// 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 -// } - func HashPassword(password string) (string, error) { pass := []byte(password) hash, err := bcrypt.GenerateFromPassword(pass, bcrypt.MinCost) From fdf9d518ed2b24f8fd42411911b50f085387faa1 Mon Sep 17 00:00:00 2001 From: Perseus-Jackson477 Date: Fri, 22 Dec 2023 03:03:36 +0530 Subject: [PATCH 15/15] some bug fixes and minor updates --- lib/harbor/api.go | 2 +- lib/utils/docker.go | 1 - lib/wireguard/setup.go | 36 +----------------------------- services/infrasetservice/helper.go | 14 +++++++++++- 4 files changed, 15 insertions(+), 38 deletions(-) diff --git a/lib/harbor/api.go b/lib/harbor/api.go index 24ed505d..7207931f 100644 --- a/lib/harbor/api.go +++ b/lib/harbor/api.go @@ -56,7 +56,7 @@ func setAdminPassword() error { resp, _ = httpClient.Do(req) if resp.StatusCode != 200 { - return fmt.Errorf("error changing admin password") + return fmt.Errorf("error changing admin password, response code is %d", resp.StatusCode) } return nil diff --git a/lib/utils/docker.go b/lib/utils/docker.go index 4a899e53..48c51e85 100644 --- a/lib/utils/docker.go +++ b/lib/utils/docker.go @@ -56,7 +56,6 @@ func BuildDockerImage(_ChallengeName string, _DockerfilePath string) { } log.Println(_ChallengeName) - log.Println("dfsdfsdfsdf") log.Println(_DockerfilePath) log.Println("Building Docker image, Please wait......") diff --git a/lib/wireguard/setup.go b/lib/wireguard/setup.go index b87052ea..45be9c98 100644 --- a/lib/wireguard/setup.go +++ b/lib/wireguard/setup.go @@ -14,9 +14,7 @@ import ( "github.com/sdslabs/katana/configs" "github.com/sdslabs/katana/lib/deployment" "github.com/sdslabs/katana/lib/utils" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" ) func SetupWireguard() error { @@ -113,6 +111,7 @@ func GetConfigFiles(team_number string) error { //wait for container ready time.Sleep(1 * time.Minute) + // [TODO] : Replace time.Sleep with waitForContainerRunning // if err := waitForContainerRunning(client, wireguardPod.Name, wireguardContainer.Name, namespace, 10*time.Minute); err != nil { // log.Printf("Error waiting for container to become running: %v\n", err) // } @@ -125,36 +124,3 @@ func GetConfigFiles(team_number string) error { return nil } - -// [WIP] : Replace time.Sleep with waitForContainerRunning -func waitForContainerRunning(client *kubernetes.Clientset, podName, containerName, namespace string, timeout time.Duration) error { - startTime := time.Now() - for { - // Get the pod - pod, err := client.CoreV1().Pods(namespace).Get(context.TODO(), podName, metav1.GetOptions{}) - if err != nil { - return err - } - - // Find the container in the pod - var containerStatus *corev1.ContainerStatus - for _, status := range pod.Status.ContainerStatuses { - if status.Name == containerName { - containerStatus = &status - break - } - } - - if containerStatus != nil && containerStatus.State.Running != nil { - return nil // Container is in the "Running" state - } - - // Check if the timeout has been reached - if time.Since(startTime) >= timeout { - return fmt.Errorf("timed out waiting for container to become running") - } - - // Sleep for a while before checking again - time.Sleep(1 * time.Second) // Adjust the sleep duration as needed - } -} diff --git a/services/infrasetservice/helper.go b/services/infrasetservice/helper.go index 929f66dd..71b344ce 100644 --- a/services/infrasetservice/helper.go +++ b/services/infrasetservice/helper.go @@ -97,6 +97,9 @@ func envVariables(gogs string, pwd string, podNamespace string) { func buildKatanaServices() { katanaDir, err := utils.GetKatanaRootPath() + if err != nil { + log.Fatal(err) + } katanaServicesDir := katanaDir + "/katana-services" services, err := os.ReadDir(katanaServicesDir) @@ -105,7 +108,16 @@ func buildKatanaServices() { } for _, service := range services { - if service.Name() == ".github" { + + invalidServiceNames := []string{".github", ".git", ".gitignore"} + found := false + for _, invalidName := range invalidServiceNames { + if service.Name() == invalidName { + found = true + break + } + } + if found { continue } if service.IsDir() {