This project provides the hosting, networking, storage, the infrastructure tu run IPA. Before starting with this setup please clone and build IPA as we'll need it to generate keys for the infrastructure to work.
Currently, we have only included instructions for AWS, but the intent is to expand to other clouds in the future.
This project uses the following frameworks:
EKSCTL is used to manage the AWS EKS infrastructure. Creating the K8s cluster, setting the instance type, etc.
Minikube is a local K8s cluster you can use for dev. Docker Desktop works fine to create a local Minikube and IPA images on different platforms.
Helm is used to deploy changes to the cluster created by EKSCTL. Because of this we generally don't use kubectl to apply changes, but to observe the state of the cluster.
You will need a set of keys, certificates and a network.toml
to start each helper. These files are expected to be placed in the config
folder. You will need to create this folder and fill it with the files we'll create in this section.
mkdir <CONFIG_DIR>
The following binaries require you to compile the IPA project (not ipa-infra) in release mode.
cd <IPA project>
cargo build --bin helper --release --no-default-features --features "web-app real-world-infra compact-gate"
A script is provided to generate the keys and certificates for a sharded environment. Choose a number of shards to setup per helper.
python3 scripts/create-sharded-conf.py -b <CONFIG_DIR> -s <SHARD_COUNT>
Filenames and folders follow a convention used by this next tool which will create the network.toml
file.
# go to the release folder
cd target/release/
./helper sharded-confgen --keys-dir <CONFIG_DIR> --shard-count <SHARD_COUNT> --shards-port 1443 --mpc-port 443
You should be ready now. Here's how the config folder looks like for 4 shards:
$ tree config
config
├── ghcr_auth.json
├── helper1
│ ├── shard0
│ │ ├── h1-helper-shard-0.h1-helper-shard.default.svc.cluster.local.key
│ │ ├── h1-helper-shard-0.h1-helper-shard.default.svc.cluster.local.pem
│ │ ├── h1-helper-shard-0.h1-helper-shard.default.svc.cluster.local_mk.key
│ │ └── h1-helper-shard-0.h1-helper-shard.default.svc.cluster.local_mk.pub
│ ├── shard1
│ │ ├── h1-helper-shard-1.h1-helper-shard.default.svc.cluster.local.key
│ │ ├── h1-helper-shard-1.h1-helper-shard.default.svc.cluster.local.pem
...
├── helper2
│ ├── shard0
│ │ ├── h2-helper-shard-0.h2-helper-shard.default.svc.cluster.local.key
│ │ ├── h2-helper-shard-0.h2-helper-shard.default.svc.cluster.local.pem
│ │ ├── h2-helper-shard-0.h2-helper-shard.default.svc.cluster.local_mk.key
...
│ └── shard3
│ ├── h3-helper-shard-3.h3-helper-shard.default.svc.cluster.local.key
│ ├── h3-helper-shard-3.h3-helper-shard.default.svc.cluster.local.pem
│ ├── h3-helper-shard-3.h3-helper-shard.default.svc.cluster.local_mk.key
│ └── h3-helper-shard-3.h3-helper-shard.default.svc.cluster.local_mk.pub
└── network.toml
The workflow to run IPA is a follows. First you setup and prepare a cluster, then you submit a query and finally you scale down the cluster once you're done.
Each helper is separated using Helm's .Release.Name
as a differentiator. This is useful to test all helpers in a single cluster, but shouldn't be necessary for the real case scenario when each helper runs on a separate cluster. You will see Release Name in many templates.
To start your query, first you will want to scale the cluster to match the SHARD_COUNT. For example:
./scale.sh 4
To helm install and uninstall all helpers and report collector you can run.
./install.sh <SHARD_COUNT>
You can use the connect-to
script to "ssh" into the report collector or any of the helpers. E.g.
./connect-to.py rc
./connect-to.py h2 3
Once inside the RC you can use the following commands to submit a IPA hybrid query:
report_collector --output-file ipa_inputs.txt gen-hybrid-inputs --count 100 --max-conversion-value 5 --max-breakdown-key 5 --seed 15913844266827317901 --quiet
in_the_clear --input-file ipa_inputs.txt --output-file ipa_output_in_the_clear.json --quiet
crypto_util hybrid-encrypt --input-file ipa_inputs.txt --output-dir . --network /etc/ipa/network.toml
report_collector --network /etc/ipa/network.toml --output-file ipa_output.json --shard-count 4 --wait 2 malicious-hybrid --count 100 --enc-input-file1 helper1.enc --enc-input-file2 helper2.enc --enc-input-file3 helper3.enc --max-breakdown-key 5 --with-dp 0
Since creating these files takes a very long time, you might want to copy a pre-generated file (from a bastion) into the report collector.
To scale down the cluster just run the following commands
./uninstall.sh
./scale 1
Following are some example commands you can try out.
The following gets details about all pods. You can use this to know if the server is up and running or understand any problems.
kubectl describe pods
The next one is used to get information about the nodes (the hosts) that run IPA code.
kubectl describe nodes
The following commands are examples on how to get logs about different shards and the entirety of a helper.
kubectl logs h1-helper-shard-0 --tail=100 -f
kubectl logs h2-helper-shard-19 --tail=10000 -f
kubectl logs -l app=h1-helper-shard --tail=100 -f
kubectl logs -l app=h2-helper-shard --tail=100 -f
For the last commands you might need to add the option --max-log-requests=<shard-count>
.
The following prints the EKS node groups, useful to check the current scale of the system or instance types.
eksctl get nodegroup --cluster open-helpers
Cd into the ipa-infra
directory and run the following to start a single helper.
helm install <release-name> .
# Example
helm install h1 .
The command should take a few seconds to start a helper with the default values.yaml
If you need to copy files, say from the report collector image to the bastion (your current host), you can run:
kubectl cp helper3_10M.enc default/report-collector-deployment-686b69c48b-7fq9j:/helper3_10M.enc
The following instructions pertain the IPA project but since the Docker images are also used by this project, sample instructions are included here.
Remember to replace <TAG>
with something useful to you.
cd <ipa project>
docker build -t ghcr.io/private-attribution/ipa/ipa-helper:<TAG> -f docker/helper.Dockerfile .
docker build -t ghcr.io/private-attribution/ipa/rc:<TAG> -f docker/report_collector.Dockerfile .
docker push ghcr.io/private-attribution/ipa/ipa-helper:<TAG>
docker push ghcr.io/private-attribution/ipa/rc:<TAG>
After this you will need to modify values.yaml
to use your docker image.
An EKSCTL template is included in the /eksctl
folder to create the cluster.
If you want to make changes to the cluster, you can deploy a cluster upgrade.
eksctl upgrade cluster -f eksctl/cluster-config.yaml
If you want to modify the Helper Instance Types there are 2 options, one way is to modify the EC2 Launch Template associated with that nodegroup. Another way is to delete and create the node groups using EKSCTL:
eksctl delete nodegroup -f eksctl/cluster-config.yaml --include="helper*" --exclude="rc"
The above command will thankfully only do a dryrun, be sure to check what it's
planning to do and re-run with -approve
. Then, to re-create the node groups:
eksctl create nodegroup -f eksctl/cluster-config.yaml --include="helper*" --exclude="rc"
Check the EKSCTL docs for more information.
What if my cluster is stuck on a IPA Query?
You can simply restart it using ./restart-helpers.sh
K8s DNS (CoreDNS) presented some challenges, hence including some helpful commands here:
If you want t edit the DNS config
kubectl -n kube-system edit configmap coredns
The following commands get the configuration.
kubectl get pods -n kube-system
kubectl get configmap coredns -n kube-system -o yaml
aws eks describe-addon --cluster-name open-helpers --addon-name coredns
Restarting DNS:
kubectl rollout restart -n kube-system deployment/coredns
Scaling the DNS pods:
kubectl scale deployment.apps/coredns -n kube-system --replicas=0
kubectl scale deployment.apps/coredns -n kube-system --replicas=20
We use Github repository (GHCR) to keep Docker images used by the templates in this package which are automatically created on each push to main using Github Actions. GHCR requires a token to be able to pull images.
The template expects the GHCR token to be stored in config/ghcr_auth.json
and
be of the following form:
{"auths":{"ghcr.io":{"auth":"<USERNAME + TOKEN>"}}}
``
To generate that value you will need to concatenate your username with your
token and base64 the results:
echo -n ":" | base64
# Local Setup
The following setup is only necessary for your local development.
### Minikube
In Prod you will use an existing K8s cluster, but locally you will want to start your own local Minikube:
minikube start
You will need an IPA Docker image. To load the image into your Minikube:
minikube image load ipa:current
The image tag needs to match Helm's `values.yaml`.