Problem Statement

The problem statement requires us to host a docker registry. As a part of the challenge two docker images are pushed to the docker registry that we host one of which is a dud. The task at hand is to run both the docker images with an IGNITION_KEY env variable that is obtained as a part of the problem. One of the docker images spits out a secret which needs to be submitted back to solve the challenge.

Solution

A quick google search on hosting a private docker registry should land you in Docker’s official documentation. Docker’s official docs defines a registry as follows

A registry is an instance of the registry image, and runs within Docker

Plain and simple if you already have docker installed on your machine. The only task we have to do now is to pull the registry image and run it in docker.

On fetching the problem set we obtain the following information:

  • credentials: how we will authenticate to your registry before the push
    • user: the username we will be using
    • password: the password we will be using
  • ignition_key: for the container to spit out the solution, you’ll need to set an environment variable IGNITION_KEY to this value
  • trigger_token: pass this to the trigger endpoint

Now we know how to locally setup a docker registry, the next thing to figure out is how to setup authentication because the problem set is clearly giving us credentails and expects to authenticate successfully using those credentials.

Setup basic auth using htpasswd:

  1. Create a password file with the credentials obtained from the problem set.
     mkdir auth
     htpasswd -Bbn <username> <password> > /auth/htpasswd
2. Start the registry with basic authentication.
   ```bash
docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry \
  -v "$(pwd)"/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  registry:2

Exposing the registry to the Internet

The local registry will now be exposed to the internet using ngrok.

ngrok http 5000 # we are running the registry on port 5000

copy the ngrok hostname that is exposed to the internet.

Trigger the push

Send a post request to /\_/push/$trigger_token, the trigger token is obtained as a part of the problem set. The body should include a json with a single key.

{
	"registry_host": "<ngrok-host>"
}

This is a blocking process, it takes sometime to receive the response back. The response should contain the push logs. By looking at the tags we can determine the name of the image.

Pulling and running the docker images

Getting the tags of the images pushed

The registry also exposes a HTTP API which can be used to get the tag names.

  1. Visit http://localhost:5000/v2 this will prompt you to enter the username and password.
  2. Next visit http://localhost:5000/v2/<name>/tags/list. This endpoint will return all the tags for the specified image.

Pulling the images from the registry

Before pulling the images from the registry, we need to authenticate docker client with the registry.

docker login localhost:5000

Enter the username and password when prompted and you should see a response as below.

Username: <username>
Password: <password>
WARNING! Your password will be stored unencrypted in /home/anudeep/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
 
Login Succeeded

Once the login is succeeded, now its time to pull the images.

docker pull localhost:5000/<name>:<tag>

Pull both the tags that we obtained. Run both the images with the IGNITION_KEY env variable which can be obtained from the problem set.

docker run --rm --env IGNITION_KEY=<ignition-key> localhost:5000/<name>:<tag>

One of the two containers should print a secret to the console.

The challenge is solved on submitting the secret.