Files
labs/lab-3/LAB-REPORT.md

199 lines
8.2 KiB
Markdown
Raw Normal View History

2025-06-07 14:04:07 -07:00
# Lab 3
## Prep
- [x] Gitea set up
- [x] MFA set up
- [x] Add git ignore
- [x] Secrets/Token Management
- [x] Consider secret-scanning
- [x] Added git-leaks on pre-commit hook
2025-06-12 15:09:24 -07:00
- [x] Create & Connect to a Git repository
- [x] https://code.wizards.cafe
2025-06-07 14:38:38 -07:00
- [x] Modify and make a second commit
2025-06-12 15:09:24 -07:00
![image of terminal](./assets/prep-console.png)
2025-06-09 21:31:41 -07:00
- [x] Test to see if gitea actions works
2025-06-10 10:54:13 -07:00
- [x] Have an existing s3 bucket
2025-06-09 21:31:41 -07:00
## Resources
- [x] [Capital One Data Breach](./assets/Capital%20One%20Data%20Breach%20—%202019.%20Introduction%20_%20by%20Tanner%20Jones%20_%20Nerd%20For%20Tech%20_%20Medium.pdf)
2025-06-10 10:54:13 -07:00
- [x] [Grant IAM User Access to Only One S3 Bucket](./assets/Grant%20IAM%20User%20Access%20to%20Only%20One%20S3%20Bucket%20_%20Medium.pdf)
2025-06-09 21:31:41 -07:00
- [ ] [IAM Bucket Policies](./assets/From%20IAM%20to%20Bucket%20Policies_%20A%20Comprehensive%20Guide%20to%20S3%20Access%20Control%20with%20Console,%20CLI,%20and%20Terraform%20_%20by%20Mohasina%20Clt%20_%20Medium.pdf)
- [ ] [Dumping S3 Buckets!](https://www.youtube.com/watch?v=ITSZ8743MUk)
## Lab
2025-06-11 11:02:42 -07:00
- [x] create a custom IAM Policy
- [x] create an IAM Role for EC2
2025-06-12 15:09:24 -07:00
![trust relationships](./assets/trust-relationships.jpg)
![permissions](./assets/permissions.jpg)
2025-06-11 11:02:42 -07:00
- [x] Attach the Role to your EC2 Instance
- [x] Verify is3 access from the EC2 Instance
2025-06-11 13:17:22 -07:00
* HTTPS outbound was not set up
* I did not check outbound rules (even when the lab explicitly called this out)
because it mentioned lab 2, so my assumption was that it had already been set up
(it was not). When connection to s3 failed I double checked lab 3 instructions
2025-06-12 15:09:24 -07:00
![screenshot of listing s3 contents](./assets/s3-access-screenshot.jpg)
2025-06-09 21:31:41 -07:00
2025-06-11 11:02:42 -07:00
### Stretch
2025-06-11 19:58:10 -07:00
- [x] Create a bucket policy that blocks all public access but allows your IAM role
2025-06-13 21:24:32 -07:00
- [x] Implmented: [guide](https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/)
2025-06-12 15:09:24 -07:00
2025-06-12 15:09:24 -07:00
<<<<<<< HEAD
2025-06-12 15:09:24 -07:00
![restrict to role](./assets/restrict-to-role.jpg)
2025-06-12 15:09:24 -07:00
=======
![restrict to role](./assets/restrict-to-role.png)
>>>>>>> 1437cee (Add resume pdf & html)
2025-06-12 15:09:24 -07:00
- [x] **Experiment** with requiring MFA or VPC conditions.
- [x] MFA conditions
2025-06-13 21:24:32 -07:00
* MFA did not work out of the box after setting it in the s3 bucket policy.
The ways I found you can configure MFA:
* [stackoverflow](https://stackoverflow.com/questions/34795780/how-to-use-mfa-with-aws-cli)
* [official guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
* [x] via cli roles - I set up a new set of role-trust relationships.
* Update s3 Role:
* Update action: sts:assumerole
* Update principle (for user -- could not target group)
* Add condition (MFA bool must be true)
* Commands referenced: I set up a script that looks like this
2025-06-12 15:09:24 -07:00
```bash
MFA_TOKEN=$1
if [ -z "$1" ]; then
echo "Error: Run with MFA token!"
exit 1
fi
if [ -z $BW_AWS_ACCOUNT_SECRET_ID ]; then
echo "env var BW_AWS_ACCOUNT_SECRET_ID must be set!"
exit 1
fi
AWS_SECRETS=$(bw get item $BW_AWS_ACCOUNT_SECRET_ID)
export AWS_ACCESS_KEY_ID=$(echo "$AWS_SECRETS" | jq -r '.fields[0].value')
export AWS_SECRET_ACCESS_KEY=$(echo "$AWS_SECRETS" | jq '.fields[1].value' | tr -d '"')
SESSION_OUTPUT=$(aws sts assume-role --role-arn $S3_ROLE --role-session-name $SESSION_TYPE --serial-number $MFA_IDENTIFIER --token-code $MFA_TOKEN)
#echo $SESSION_OUTPUT
export AWS_SESSION_TOKEN=$(echo "$SESSION_OUTPUT" | jq '.Credentials.SessionToken' | tr -d '"')
export AWS_ACCESS_KEY_ID=$(echo "$SESSION_OUTPUT" | jq '.Credentials.AccessKeyId' | tr -d '"')
export AWS_SECRET_ACCESS_KEY=$(echo "$SESSION_OUTPUT" | jq '.Credentials.SecretAccessKey' | tr -d '"')
#echo $AWS_SESSION_TOKEN
#echo $AWS_ACCESS_KEY_ID
#echo $AWS_SECRET_ACCESS_KEY
aws s3 ls s3://witch-lab-3
```
2025-06-13 21:24:32 -07:00
* configuration via ~/.aws/credentials
* 1Password CLI with AWS Plugin
* I use bitwarden, which also has an AWS Plugin
* I've seen a lot more recommendations (TBH it's more like 2 vs 0)
for 1password for password credential setup. Wonder why?
2025-06-12 15:09:24 -07:00
- [x] **Host a static site**
- [x] Enable a static website hosting (`index.html`)
- [x] Configure route 53 alias or CNAME for `resume.<yourdomain>` to the bucket endpoint.
- [x] Deploy CloudFront with ACM certificate for HTTPS
* see: [resume](https://resume.wizards.cafe)
2025-06-12 15:09:24 -07:00
<<<<<<< HEAD
2025-06-12 15:09:24 -07:00
- [ ] **Private "Invite-Only" Resume Hosting**
1. [ ] **Pre-signed URLs**
2025-06-11 13:17:22 -07:00
`aws s3 presign s3://<YOUR_BUCKET_NAME>/resume.pdf --expires-in 3600`
2025-06-12 15:09:24 -07:00
=======
* Cloudflare Edge Certificate -> Cloudfront -> S3 Bucket
* In this step, I disabled "static website hosting" on the s3 bucket
2025-06-13 21:24:32 -07:00
* This was actually maddening to set up. For reasons I can't understand even
after Google Searching and ChatGPTing, my s3 bucket is under us-east-2
and Cloudfront kept redirecting me to the us-east-1 for some reason. I don't like
switching up regions under AWS because this way it's easy to forget what region
you created a specific service in because they're hidden depending on what
region is active at the moment.
2025-06-12 15:09:24 -07:00
**Private "Invite-Only" Resume Hosting**
2025-06-13 21:24:32 -07:00
- [x] **Pre-signed URLs**
`aws s3 presign s3://<YOUR_BUCKET_NAME>/resume.pdf --expires-in 3600`
(see: presigned url screenshot)
2025-06-12 15:09:24 -07:00
![presigned url](./assets/create-presigned-url.jpg)
>>>>>>> 1437cee (Add resume pdf & html)
2025-06-11 13:17:22 -07:00
2025-06-11 19:58:10 -07:00
### Further Exploration
2025-06-13 21:24:32 -07:00
- [ ] Snapshots & AMIs
2025-06-11 19:58:10 -07:00
- [ ] Create an EBS snapshot of `/dev/xvda`
- [ ] Register/create an AMI from that snapshot
2025-06-13 21:24:32 -07:00
- [x] How do you "version" a server with snapshots? Why is this useful?
**Cattle, not pets**
This is useful for following the concept for treating your servers as
"cattle, not pets". Being able to keep versioned snapshots of your machines
means there's nothing special about your currently running server.
If it goes down (or you need to shoot it down), you can restore it on
another machine from an older snapshot.
Or if you needed to suddenly scale your operation from 1 machine to many,
where each machine needed the exact same configuration set as the other
(all need fail2ban installed, etc. etc,) -- you can do that with
an AMI image.
2025-06-11 19:58:10 -07:00
- [ ] Launch a new instance from your AMI
2025-06-13 21:24:32 -07:00
- [ ] Linux & Security Tooling
- [ ] `ss -tulpn`, `lsof`, `auditctl` to inspect services and audit
- [ ] Install & run:
- [ ] nmap localhost
- [ ] tcpdump - c 20 -ni eth0
- [ ] lynis audit system
- [ ] fail2ban-client status
- [ ] OSSEC/Wazuh or ClamAV
- [ ] Scripting & Automation
2025-06-11 19:58:10 -07:00
- [ ] Bash: report world-writable files
- [ ] Python with boto3: list snapshots, start/stop instances
2025-06-13 21:24:32 -07:00
- [ ] Convert to terraform
- [ ] IAM Role
- [ ] IAM Policy
- [ ] IAM Group
- [ ] EC2 Instance
- [ ] S3 Bucket
2025-06-11 19:58:10 -07:00
2025-06-11 13:17:22 -07:00
## Further Reading
- [ ]
- [ ]
- [ ]
## Reflection
* What I built
2025-06-13 21:24:32 -07:00
* A secured s3 bucket for secure content that can only be accessed via multi-factor authentication
Good for storing particularly sensitive information.
* A minimal HTML website served from an S3 bucket
2025-06-11 13:17:22 -07:00
* Challenges
2025-06-12 15:09:24 -07:00
* The stretch goal for setting up s3 + mfa was a bit of a pain:
2025-06-13 21:24:32 -07:00
* Groups cannot be used as the principal in a trust relationship, breaking my mental model
of the ideal way to onboard/offboard engineers by simply removing them from groups
(although I may have set up the IAM permissions in an inefficient way. I ended up having to
assign a user as the principal of the trust relationship for my s3 role.)
* Issues between setting up Cloudflare -> CloudFront -> s3 bucket
* I think adding an extra service (Cloudflare, where I host my domain) added a little bit of complexity, though
my main issue was figuring out how to set up the ACM cert -> CloudFront distribution -> S3.
Most of the instructions I was able to parse through with ChatGPT -- I have to say I had a much
better reading through those instructions than with the official AWS docs, which led me through
nested links (understandably, because there seem to be multiple ways of doing everything).
2025-06-12 15:09:24 -07:00
2025-06-11 13:17:22 -07:00
* Security concerns
On scale and security at scale
2025-06-11 11:02:42 -07:00
## Terms
2025-06-09 21:31:41 -07:00
### Identity Access Management
```mermaid
graph LR
IAMPolicy -- attaches to --> IAMIdentity
ExplainIAMIdentity[users, groups of users, roles, AWS resources]:::aside
ExplainIAMIdentity -.-> IAMIdentity
2025-06-12 09:56:16 -07:00
classDef aside stroke-dasharray: 5 5, stroke-width:2px;
2025-06-11 11:02:42 -07:00
```
2025-06-13 21:24:32 -07:00
![Identity Access Management](./assets/mermaid.jpg)