DEV Community

Cover image for Find The Cube
Ari Kalfus
Ari Kalfus

Posted on • Edited on

Find The Cube

Can you solve the five challenges in the first set and Find The Cube?

https://findthecube.com/

This is my first take at a security capture-the-flag challenge platform. I don't want to talk too much about the challenges to avoid giving things away. You are looking at beginner web and cipher challenges. That's not to say they are easy!

This is a Nuxt project running in a Docker container - two containers of the image, actually - load balanced behind Nginx. The simpler times of software deployment, before Kubernetes and ECS/EKS. If I get enough traffic to warrant the stupid ALB costs, I'll throw up an ALB and set an auto-scaling group to add and remove servers based on CPU utilization. I put the app, infrastructure, and deployment pipeline together in one week.

The repository is private but there is a CI/CD no-downtime deployment process. So fancy! I use goss to test the built image along with the docker/build-push-action. The end of my ci.yml GitHub Action workflow looks like this:

- name: Cache
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-buildx-

      - name: Build the Docker image
        uses: docker/build-push-action@v2
        with:
          push: false
          tags: ${{ env.IMAGE_NAME }}:test
          load: true
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache
          build-args: |
            BROWSER_BASE_URL=https://findthecube.com

      - name: Test the image
        run: dgoss run ${{ env.IMAGE_NAME }}:test
Enter fullscreen mode Exit fullscreen mode

The deployment is where it gets fun. I use Amazon's aws-actions/configure-aws-credentials action to configure credentials to my AWS account. I then build a new image and push it to my registry, then use an Systems Manager Run Command (aws ssm send-command) to stop the containers, pull the new image, and restart the containers.

- name: Configure AWS Credentials
  uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-east-1

// ...

- name: Update Server Deployment
  run: |
    instanceid=$(aws ec2 describe-instances --filters 'Name=tag:Name,Values=TheCube' --query 'Reservations[*].Instances[*].InstanceId' --output text)
    aws ssm send-command --document-name "AWS-RunShellScript" --targets "Key=InstanceIds,Values=${instanceid}" --cli-input-json file://__scripts/updateDockerImageDeployment.json
Enter fullscreen mode Exit fullscreen mode

The /__scripts/updateDockerImageDeployment.json file is the bit of JSON which is the bash script to run on the servers targeted in my aws ssm call.

{
  "Parameters": {
    "commands": [
      "#!/bin/bash",
      "set -eu",
      "docker pull .../artis3n/thecube:latest",
      "docker stop thecube1",
      "docker rm thecube1",
      "docker run --name thecube1 -d --restart unless-stopped -p 3000:3000 .../artis3n/thecube:latest",
      "docker stop thecube2",
      "docker rm thecube2",
      "docker run --name thecube2 -d --restart unless-stopped -p 3001:3000 .../artis3n/thecube:latest",
      "docker image prune -f"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

This makes it super easy to push updates to the server. I publish a new release on GitHub, a new deployment is triggered, updates are pushed to the server, bam a couple minutes after the release the new version is live.

Good luck! Find the cube.

Be gentle on the last challenge, it is on a lone t2.medium server! If it gets too busy I'll set up an auto-scaling group.

Top comments (0)