This repository contains Infrastructure as Code (IaC) for spinning up isolated Kali Linux penetration testing environments in AWS with integrated S3 storage using Terraform. Supports multiple simultaneous projects with complete isolation.
opfor-iac/
βββ storage/ # Reusable storage module (S3, IAM)
βββ instance/ # Reusable instance module (EC2, Security Groups)
βββ projects/ # Project-specific configurations
β βββ client-acme/ # Example: ACME Corp assessment
β β βββ storage/ # β symlink to ../../storage
β β βββ instance/ # β symlink to ../../instance
β β βββ storage.tfvars # Client-specific storage config
β β βββ instance.tfvars # Client-specific instance config
β β βββ deploy.sh # Deployment helper script
β β βββ README.md # Project-specific documentation
β βββ client-beta/ # Example: Beta Corp assessment
β βββ ...
βββ create-project.sh # Script to create new projects
βββ README.md # This file
- Multi-project isolation - Complete separation between client assessments
- Persistent storage - S3 buckets survive instance destruction
- Cost optimization - Destroy expensive compute, keep cheap storage
- Pre-configured tools - Kali Linux with penetration testing toolkit
- S3 filesystem mounting - Assessment data automatically stored in S3
- Security-focused - Encrypted storage, IAM roles, restricted access
The infrastructure uses a modular approach with shared components for multiple projects:
- S3 bucket for assessment data with folder structure
- IAM roles for secure S3 access from Kali instances
- Lifecycle policies for cost optimization
- Long-lived - persists across multiple Kali deployments
This repository contains Infrastructure as Code (IaC) for spinning up a Kali Linux penetration testing environment in AWS with integrated S3 storage using Terraform.
The infrastructure is split into two components for better lifecycle management:
- S3 bucket for assessment data with folder structure
- IAM roles for secure S3 access from Kali instances
- Lifecycle policies for cost optimization
- Long-lived - persists across multiple Kali deployments
- Kali Linux EC2 instance with pre-configured tools
- Security groups optimized for pentest operations
- S3 filesystem mounting for seamless data access
- Short-lived - create/destroy as needed
- Separated storage and compute for cost optimization
- Automated S3 mounting at
/mnt/assessment/on Kali box - Pre-configured penetration testing tools
- VNC and RDP access for GUI operations
- Assessment folder structure (scope, reconnaissance, vulnerabilities, etc.)
- Encrypted storage and secure IAM access
- SSH key pair generation for secure access
- Terraform >= 1.0
- AWS CLI configured with appropriate credentials
- AWS account with appropriate permissions
- VNC client (for GUI access) - recommended: RealVNC, TightVNC, or macOS built-in Screen Sharing
Use the automated script to create a new client project:
./create-project.sh client-nameThis will:
- Create a new project directory under
projects/client-name/ - Set up symlinks to the shared storage and instance modules
- Generate client-specific configuration files
- Create deployment helper scripts
Navigate to your project directory and use the deployment helper:
cd projects/client-name/
./deploy.shThe helper script will guide you through:
- Storage deployment - Creates S3 bucket and IAM roles
- Instance configuration - Updates variables for your specific needs
- Instance deployment - Launches the Kali Linux environment
After deployment completes:
-
SSH Access:
ssh -i client-name-key.pem kali@<public-ip>
-
VNC Access (for GUI):
- Connect to
<public-ip>:5901 - Default VNC password:
kali123
- Connect to
-
Assessment Data:
- Located at
/mnt/assessment/on the Kali instance - Automatically backed up to S3
- Located at
If you prefer manual deployment or need to understand the underlying process:
-
Navigate to storage directory
cd storage/ -
Configure your variables
cp terraform.tfvars.example terraform.tfvars # Edit with your client/assessment name -
Deploy storage
terraform init terraform plan terraform apply
-
Note the outputs - you'll need these for the instance deployment:
terraform output
This creates the temporary Kali box that mounts your persistent storage.
-
Navigate to instance directory
cd ../instance/ -
Configure variables
cp terraform.tfvars.example terraform.tfvars # Edit with storage outputs and your preferencesImportant: Use the storage outputs in your instance terraform.tfvars:
s3_bucket_name = "output-from-storage-module" s3_instance_profile_name = "output-from-storage-module"
-
Deploy instance
terraform init terraform plan terraform apply
SSH Access (Recommended):
ssh -i keys/opfor-kali-key.pem kali@<public-ip>VNC Access (GUI):
- Host:
<public-ip> - Port:
5901 - Password: Your
kali_passwordfrom terraform.tfvars
Assessment Data:
- Mounted at:
/mnt/assessment/ - Folders: scope/, reconnaissance/, vulnerabilities/, exploitation/, reports/, evidence/
- Usage: Files saved here persist even when instance is destroyed
# Example workflow on Kali box
cd /mnt/assessment/
# Store target information
echo "10.0.0.0/24" > scope/targets.txt
# Run reconnaissance
nmap -oA reconnaissance/network-scan 10.0.0.0/24
# Store vulnerability scan results
nuclei -l scope/targets.txt -o vulnerabilities/nuclei-results.txt
# Draft reports
vim reports/assessment-findings.md- Latest Kali Linux AMI
- Desktop environment (XFCE)
- VNC server (TightVNC)
- RDP server (xrdp)
- Web Application Testing: gobuster, ffuf, nikto, sqlmap, wpscan
- Network Scanning: nmap, rustscan, massdns
- Vulnerability Scanning: nuclei, OpenVAS
- Subdomain Enumeration: subfinder, amass
- HTTP Toolkit: httpx
- Wordlists: SecLists collection
- Post-Exploitation: impacket, crackmapexec
- Python 3 + pip
- Go programming language
- Node.js + npm
- Docker + Docker Compose
- Git, vim, tmux
- t3.micro: Minimal testing (free tier eligible)
- t3.small: Light penetration testing
- t3.medium: Recommended for most use cases
- t3.large/xlarge: Heavy workloads or multiple concurrent tasks
0.0.0.0/0). For production use, restrict access to your IP:
allowed_ssh_cidr_blocks = ["YOUR.IP.ADDRESS/32"]- Default: 50GB encrypted EBS volume
- Adjustable via
root_volume_sizevariable - Automatically deleted when instance is terminated
ssh -i keys/opfor-kali-key.pem kali@<public-ip>- Host:
<public-ip> - Port:
5901 - Password: Set via
kali_passwordvariable - URL:
vnc://<public-ip>:5901
- Host:
<public-ip> - Port:
3389 - Username:
kali - Password: Set via
kali_passwordvariable
/home/kali/
βββ Desktop/ # Desktop shortcuts
βββ Documents/ # Documentation
βββ Downloads/ # Downloaded files
βββ Tools/ # Custom tools and scripts
βββ Wordlists/ # SecLists and custom wordlists
βββ Scripts/ # Utility scripts
βββ Reports/ # Penetration testing reports
- Change default passwords immediately after deployment
- Restrict source IP ranges in security groups
- Use SSH key authentication instead of passwords
- Enable MFA on your AWS account
- Regularly update the system and tools
- Monitor costs to avoid unexpected charges
- Terminate instances when not in use
Approximate monthly costs (us-east-1):
- t3.micro: ~$8.50/month (free tier eligible)
- t3.small: ~$17/month
- t3.medium: ~$34/month
- t3.large: ~$67/month
Additional costs:
- EBS Storage (50GB): ~$5/month
- Elastic IP: Free when attached to running instance
- Data Transfer: Varies based on usage
When you're done with your penetration testing, clean up all resources to avoid ongoing charges:
-
Save any important data first
# SSH into the instance and backup reports/scripts ssh -i keys/opfor-kali-key.pem kali@<public-ip> # Copy important files to your local machine scp -i keys/opfor-kali-key.pem -r kali@<public-ip>:/home/kali/Reports/ ./local-reports/
-
Destroy all infrastructure
terraform destroy
- Type
yeswhen prompted - This will permanently delete ALL resources
- Cannot be undone!
- Type
-
Clean up local files (optional)
# Remove Terraform state and keys rm -rf .terraform/ rm -f terraform.tfstate* rm -rf keys/ # Keep configuration for future use # Keep: terraform.tfvars, *.tf files
Stop instance (keeps data, stops compute charges):
aws ec2 stop-instances --instance-ids $(terraform output -raw kali_box_instance_id)Start stopped instance:
aws ec2 start-instances --instance-ids $(terraform output -raw kali_box_instance_id)Remove only specific resources:
# Remove only the EC2 instance (keeps security groups, keys, etc.)
terraform destroy -target=aws_instance.kali_box
# Remove only the Elastic IP
terraform destroy -target=aws_eip.kali_eipAfter running terraform destroy, verify all resources are removed:
# Check for any remaining EC2 instances
aws ec2 describe-instances --filters "Name=tag:Name,Values=opfor-kali-box" --query 'Reservations[*].Instances[*].[InstanceId,State.Name]' --output table
# Check for any remaining security groups
aws ec2 describe-security-groups --filters "Name=group-name,Values=opfor-kali-*" --output table
# Check for any remaining key pairs
aws ec2 describe-key-pairs --filters "Name=key-name,Values=opfor-kali-key" --output table
# Check for any remaining Elastic IPs
aws ec2 describe-addresses --filters "Name=tag:Name,Values=opfor-kali-eip" --output tableIf any resources remain, manually delete them through the AWS Console or CLI to avoid ongoing charges.
After successful deployment, Terraform provides:
- Public IP address
- SSH connection command
- VNC connection details
- Instance ID and other metadata
# Check if the instance is running
aws ec2 describe-instances --filters "Name=tag:Name,Values=opfor-kali-box"
# Verify key permissions
chmod 600 keys/opfor-kali-key.pem
# Test connectivity
telnet <public-ip> 22# SSH into the box and check VNC status
ssh -i keys/opfor-kali-key.pem kali@<public-ip>
sudo systemctl status vncserver@1
# Restart VNC if needed
sudo systemctl restart vncserver@1
# Check if port is listening
sudo netstat -tlnp | grep 5901- Wait 10-15 minutes for full initialization
- Check AWS Console for instance status
- Verify security group rules allow your IP
- Check CloudWatch logs for any errors
# Check instance type (should match your terraform.tfvars)
aws ec2 describe-instances --instance-ids <instance-id>
# Stop instance when not in use (will lose data on ephemeral storage)
aws ec2 stop-instances --instance-ids <instance-id>
# Terminate when done (PERMANENT - will destroy all data)
terraform destroy# Check current infrastructure status
terraform show
# View all outputs
terraform output
# Get specific output (e.g., public IP)
terraform output kali_box_public_ip
# Refresh state (useful if you made manual changes)
terraform refresh
# Import existing resources (if needed)
terraform import aws_instance.kali_box <instance-id>This repository includes a Makefile for common operations:
# Show all available commands
make help
# Initialize and validate
make init
make validate
# Plan and apply changes
make plan
make apply
# Quick SSH connection
make ssh
# Show VNC connection info
make vnc
# Check infrastructure status
make status
# Clean up everything
make destroy# Check instance status
aws ec2 describe-instances --filters "Name=tag:Name,Values=opfor-kali-box" --query 'Reservations[*].Instances[*].[InstanceId,State.Name,PublicIpAddress]' --output table
# Stop instance (keeps EBS volume, stops billing for compute)
aws ec2 stop-instances --instance-ids <instance-id>
# Start stopped instance
aws ec2 start-instances --instance-ids <instance-id>
# View instance console output (useful for debugging boot issues)
aws ec2 get-console-output --instance-id <instance-id>
# Check CloudWatch logs
aws logs describe-log-groups --log-group-name-prefix "/aws/ec2"-
Use appropriate instance types:
t3.micro: ~$8.50/month (free tier eligible for first year)t3.small: ~$17/month (good for light testing)t3.medium: ~$34/month (recommended for regular use)
-
Stop instances when not in use:
# Stop (preserves data on EBS) aws ec2 stop-instances --instance-ids <instance-id> # Start when needed aws ec2 start-instances --instance-ids <instance-id>
-
Use Spot Instances for cost savings (advanced):
- Add to variables.tf and main.tf for ~70% cost reduction
- Risk: Instance can be terminated by AWS
-
Monitor costs:
# Set up billing alerts in AWS Console # Use AWS Cost Explorer to track spending # Consider AWS Budgets for automatic alerts
| Component | Cost |
|---|---|
| t3.micro instance | $8.50 |
| t3.medium instance | $34.00 |
| EBS storage (50GB) | $5.00 |
| Elastic IP (attached) | $0.00 |
| Data transfer (estimated) | $1-10 |
Total estimated range: $14-50/month depending on instance type and usage
# Check system status
sudo systemctl status vncserver@1
sudo systemctl status xrdp
# Restart VNC server
sudo systemctl restart vncserver@1
# Update all tools
sudo apt update && sudo apt upgrade -y
# Show installed tools
/home/kali/Scripts/pentest-toolkit.shYou can run multiple client assessments simultaneously:
# Create projects for different clients
./create-project.sh acme-corp
./create-project.sh beta-industries
./create-project.sh gamma-solutions
# Deploy each project independently
cd projects/acme-corp/ && ./deploy.sh
cd projects/beta-industries/ && ./deploy.sh
cd projects/gamma-solutions/ && ./deploy.shEach project gets:
- Isolated S3 bucket - Complete data separation
- Independent infrastructure - Deploy/destroy separately
- Custom configuration - Different instance types, regions, etc.
- Project-specific documentation - Client context and scope
# List all projects
ls -la projects/
# Check project status
cd projects/client-name/
terraform plan # in both storage/ and instance/
# Archive completed assessments
mv projects/completed-client/ archive/
# Clean up individual projects
cd projects/client-name/
terraform destroy # Destroys instances but preserves S3 dataFor larger penetration testing teams:
-
Regional Distribution:
# Create projects in different AWS regions ./create-project.sh client-west-coast # Edit projects/client-west-coast/storage.tfvars (set aws_region = "us-west-2")
-
Team Collaboration:
- Use Terraform remote state (S3 backend)
- Implement proper IAM role separation
- Share project credentials securely
-
Automated Reporting:
- S3 data can be processed by Lambda functions
- Generate automated compliance reports
- Integration with finding management tools
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
This infrastructure is designed for authorized penetration testing only. Users are responsible for:
- Compliance with applicable laws and regulations
- Proper authorization before testing any systems
- Securing their AWS environment
- Managing costs and resource usage
This project is licensed under the MIT License - see the LICENSE file for details.
For issues and questions:
- Check the troubleshooting section
- Review AWS CloudWatch logs
- Open an issue in this repository