Skip to content

Commit

Permalink
Merge pull request #27 from commjoen/feature/secretsmanager
Browse files Browse the repository at this point in the history
  • Loading branch information
commjoen authored Oct 20, 2021
2 parents aed6791 + 88a76b3 commit c8e3fb8
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 14 deletions.
2 changes: 1 addition & 1 deletion aws/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Are you done playing? Please run `terraform destroy` to clean up.

### Test it

Run `k8s-vault-aws-start.sh` and connect to http://localhost:8080 when it's ready to accept connections (you'll the the line `Forwarding from 127.0.0.1:8080 -> 8080` in your console).
Run `AWS_PROFILE=<your_profile> k8s-vault-aws-start.sh` and connect to http://localhost:8080 when it's ready to accept connections (you'll the the line `Forwarding from 127.0.0.1:8080 -> 8080` in your console).

### Clean it up

Expand Down
26 changes: 24 additions & 2 deletions aws/k8s-vault-aws-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
# set -o pipefail
# set -o nounset

AWS_REGION="eu-west-1"

echo "This is only a script for demoing purposes. You need to have installed: helm, kubectl, jq, vault, grep, cat, sed, and awscli, and is only tested on mac, Debian and Ubuntu"
echo "This script is based on the steps defined in https://learn.hashicorp.com/tutorials/vault/kubernetes-minikube . Vault is awesome!"
echo "This script is based on the steps defined in https://learn.hashicorp.com/tutorials/vault/kubernetes-minikube. Vault is awesome!"

kubectl get configmaps | grep 'secrets-file' &>/dev/null
if [ $? == 0 ]; then
Expand Down Expand Up @@ -97,9 +99,29 @@ kubectl exec vault-0 -- vault write auth/kubernetes/role/secret-challenge \
vault kv put secret/secret-challenge vaultpassword.password="$(openssl rand -base64 16)" &&
vault kv put secret/application vaultpassword.password="$(openssl rand -base64 16)"

echo "Setting up IRSA for the vault service account"
kubectl annotate --overwrite sa vault eks.amazonaws.com/role-arn="$(terraform output -raw irsa_role)"

kubectl apply -f../k8s/secret-challenge-vault-deployment.yml
echo "Add secrets manager driver to EKS"
helm repo add secrets-store-csi-driver https://raw.githubusercontent.com/kubernetes-sigs/secrets-store-csi-driver/master/charts

helm list --namespace kube-system | grep 'csi-secrets-store' &>/dev/null
if [ $? == 0 ]; then
echo "CSI driver is already installed"
else
helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --set enableSecretRotation=true --set rotationPollInterval=60s
fi

echo "Install ACSP"
kubectl apply -f https://raw.githubusercontent.com/aws/secrets-store-csi-driver-provider-aws/main/deployment/aws-provider-installer.yaml

echo "Generate secrets manager challenge secret 2"
aws secretsmanager put-secret-value --secret-id wrongsecret-2 --secret-string "$(openssl rand -base64 24)" --region $AWS_REGION --output json --no-cli-pager

echo "Apply secretsmanager storage volume"
kubectl apply -f./k8s/secret-volume.yml

kubectl apply -f./k8s/secret-challenge-vault-deployment.yml
while [[ $(kubectl get pods -l app=secret-challenge -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do echo "waiting for secret-challenge" && sleep 2; done
#kubectl expose deployment secret-challenge --type=LoadBalancer --port=8080
kubectl port-forward \
Expand Down
68 changes: 68 additions & 0 deletions aws/k8s/secret-challenge-vault-deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: secret-challenge
name: secret-challenge
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: secret-challenge
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: "2020-10-28T20:21:04Z"
labels:
app: secret-challenge
name: secret-challenge
spec:
serviceAccountName: vault
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "wrongsecrets-aws-secretsmanager"
containers:
- image: jeroenwillemsen/addo-example:0.0.2-k8s-vault
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
name: secret-challenge
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
env:
- name: SPECIAL_K8S_SECRET
valueFrom:
configMapKeyRef:
name: secrets-file
key: funny.entry
- name: SPECIAL_SPECIAL_K8S_SECRET
valueFrom:
secretKeyRef:
name: funnystuff
key: funnier
- name: VAULT_ADDR
value: "http://vault:8200"
- name: JWT_PATH
value: "/var/run/secrets/kubernetes.io/serviceaccount/token"
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
12 changes: 12 additions & 0 deletions aws/k8s/secret-volume.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
name: wrongsecrets-aws-secretsmanager
spec:
provider: aws
parameters:
objects: |
- objectName: "wrongsecret"
objectType: "secretsmanager"
- objectName: "wrongsecret-2"
objectType: "secretsmanager"
53 changes: 51 additions & 2 deletions aws/secrets.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
###############################
# Secrets manager challenge 1 #
###############################

resource "aws_secretsmanager_secret" "secret" {
name = "wrongsecret"
name = "wrongsecret"
recovery_window_in_days = 0
}

resource "aws_secretsmanager_secret_version" "secret" {
secret_id = aws_secretsmanager_secret.secret.id
secret_string = random_password.password.result
}

resource "random_password" "password" {
length = 24
special = true
override_special = "_%@"
}

resource "aws_secretsmanager_secret_policy" "name" {
resource "aws_secretsmanager_secret_policy" "policy" {
block_public_policy = true
secret_arn = aws_secretsmanager_secret.secret.arn

Expand All @@ -24,3 +40,36 @@ resource "aws_secretsmanager_secret_policy" "name" {
POLICY

}


###############################
# Secrets manager challenge 2 #
###############################

resource "aws_secretsmanager_secret" "secret_2" {
name = "wrongsecret-2"
recovery_window_in_days = 0
}

resource "aws_secretsmanager_secret_policy" "policy_2" {
block_public_policy = true
secret_arn = aws_secretsmanager_secret.secret_2.arn

policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EnableAllPermissions",
"Effect": "Allow",
"Principal": {
"AWS": "${aws_iam_role.irsa_role.arn}"
},
"Action": "secretsmanager:*",
"Resource": "*"
}
]
}
POLICY

}
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public String postController6(@ModelAttribute ChallengeForm challengeForm, Model
@PostMapping("/challenge/7")
public String postController7(@ModelAttribute ChallengeForm challengeForm, Model model) {
log.info("POST received at 7 - serializing form: solution: " + challengeForm.getSolution());
model.addAttribute("challengeNumber", 6);
model.addAttribute("challengeNumber", 7);
if (null != vaultPassword.getPasssword()) {
return handleModel(vaultPassword.getPasssword(), challengeForm.getSolution(), model);
}
Expand All @@ -152,16 +152,16 @@ public String postController7(@ModelAttribute ChallengeForm challengeForm, Model
@PostMapping("/challenge/8")
public String postController8(@ModelAttribute ChallengeForm challengeForm, Model model) {
log.info("POST received at 8 - serializing form: solution: " + challengeForm.getSolution());
model.addAttribute("challengeNumber", 6);
model.addAttribute("challengeNumber", 8);
return handleModel(Constants.newKey, challengeForm.getSolution(), model);
}


private String handleModel(String targetPassword, String given, Model model) {
if (targetPassword.equals(given)) {
model.addAttribute("answerCorrect", "You're answer is correct!");
model.addAttribute("answerCorrect", "Your answer is correct!");
} else {
model.addAttribute("answerCorrect", "You're answer is incorrect, try harder ;-)");
model.addAttribute("answerCorrect", "Your answer is incorrect, try harder ;-)");
}
return "challenge";
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/explanations/challenge10.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
=== Challenge 10: AWS Secrets manager part 2

The AWS secret is now randomized and stored directly in secrets manager. We're still mounting it to the K8s pod via the https://docs.aws.amazon.com/secretsmanager/latest/userguide/integrating_csi_driver.html[CSI driver] though... Can you access it?
3 changes: 3 additions & 0 deletions src/main/resources/explanations/challenge9.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
=== Challenge 9: AWS Secrets manager part 1

Okay, now we're generating an AWS secret through Terraform. What happens in the Terraform state?
6 changes: 4 additions & 2 deletions src/main/resources/templates/challenge.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
<a class="dropdown-item" href="/challenge/6">Challenge 6</a>
<a class="dropdown-item" href="/challenge/7">Challenge 7</a>
<a class="dropdown-item" href="/challenge/8">Challenge 8</a>
<a class="dropdown-item" href="/challenge/9">Challenge 9</a>
<a class="dropdown-item" href="/challenge/10">Challenge 10</a>
</ul>
</li>
</ul>
Expand All @@ -49,15 +51,15 @@
</nav>
<div class="container">
<h1 th:text="'Challenge '+${challengeNumber}"/>
<p th:text="'Welcome to challenge ' + ${challengeNumber} + '. You need to guess the secret that is hidden in the java/docker/k8s/Vault.'"></p>
<p th:text="'Welcome to challenge ' + ${challengeNumber} + '. You need to guess the secret that is hidden in the java, docker, k8s, Vault or AWS.'"></p>
<div class="explanation" th:replace="doc:challenge__${challengeNumber}__.adoc"></div>
<p th:text="${answerCorrect}"></p>
<form action="#" th:action="'/challenge/'+${challengeNumber}" th:object="${challengeForm}" method="post">
<p>Answer to solution : <input type="text" th:field="*{solution}"/></p>
<p><input class="btn btn-primary" type="submit" value="Submit"/> <input class="btn btn-secondary" type="reset" value="Reset"/></p>
</form>

There are 8 challenges (/challenge/1-8), can you solve them all? <br/>
There are 10 challenges (/challenge/1-10), can you solve them all? <br/>
Go back to <a href="/">the main page</a>.
</div>
<script th:src="@{/webjars/jquery/3.2.1/jquery.js}"></script>
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
<a class="dropdown-item" href="/challenge/6">Challenge 6</a>
<a class="dropdown-item" href="/challenge/7">Challenge 7</a>
<a class="dropdown-item" href="/challenge/8">Challenge 8</a>
<a class="dropdown-item" href="/challenge/9">Challenge 9</a>
<a class="dropdown-item" href="/challenge/10">Challenge 10</a>
</ul>
</li>
</ul>
Expand Down Expand Up @@ -60,8 +62,10 @@ <h1 class="display-4"> Welcome </h1>
<a href="challenge/6">Challenge 6</a><br/>
<a href="challenge/7">Challenge 7</a><br/>
<a href="challenge/8">Challenge 8</a><br/>
<a href="challenge/9">Challenge 9</a><br/>
<a href="challenge/10">Challenge 10</a><br/>
</p>
<p>Don't want to wait with Vault? here is <a href="spoil-7">the secret :(</a>.</p>
<p>Don't want to wait for Vault? here is <a href="spoil-7">the secret :(</a>.</p>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/spoil.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<h1>Spoiling secret</h1>
<p th:text="${solution}"></p>

There are 8 challenges (/challenge/1-8), can you solve them all?
There are 10 challenges (/challenge/1-10), can you solve them all?
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void solveChallenge4() throws Exception {
private void solveChallenge(String endpoint, String solution) throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.post("/challenge/1").param("solution", hardcodedPassword))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string(CoreMatchers.containsString("You&#39;re answer is correct!")));
.andExpect(MockMvcResultMatchers.content().string(CoreMatchers.containsString("Your answer is correct!")));
}

private void testSpoil(String endpoint, String soluton) throws Exception {
Expand Down

0 comments on commit c8e3fb8

Please sign in to comment.