Creating a Proxy Server on AWS with Terraform: A Step-by-Step Guide
Dec 14th, 2023In this blog post, we’ll walk through setting up a proxy server on an AWS EC2 instance using Terraform and configuring it with Apache. This setup is useful for redirecting web traffic, enhancing security, or accessing services within a private network.
Apache configuration script
We are going to launch an EC2 instance with Terraform and automatically execute a bash script setup-proxy.sh
to configure Apache.
This script effectively turns the Apache server into a proxy that redirects HTTP traffic to a specified URL over HTTPS. The key lies in the ProxyPass
and ProxyPassReverse
directives, which handle the forwarding and response modification, respectively. Additionally, by using mod_ssl
and configuring SSL settings, it ensures that the traffic between the proxy and the backend server remains encrypted, enhancing security.
Please note that every situation is different, and the effectiveness and appropriateness of this setup may vary depending on your specific requirements and the unique characteristics of your network environment.
Let’s break down what each part of the script does.
yum update -y
yum install -y httpd mod_ssl
yum update -y
: This command updates the package manager’s database on the server. It ensures that you have the latest updates and security patches.yum install -y httpd mod_ssl
: Installshttpd
, the Apache HTTP Server, andmod_ssl
, an Apache module that provides SSL/TLS support.
cat <<'EOF' > /etc/httpd/conf.d/proxy.conf
<VirtualHost *:80>
<Proxy *>
Require all granted
</Proxy>
ProxyPass / https://target-url.com/
ProxyPassReverse / https://target-url.com/
SSLProxyEngine On
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
SSLProxyVerify none
</VirtualHost>
EOF
This block creates a new configuration file for Apache:
<VirtualHost *:80>
: This line begins the definition of a virtual host listening on port 80 (HTTP).Require all granted
: This allows all traffic to pass through the proxy.ProxyPass / https://target-url.com/
: This line tells Apache to forward all requests received at the root path to the target URL.ProxyPassReverse / https://target-url.com/
: This line ensures that any redirection instructions received from the backend server are modified to point to the proxy, maintaining the illusion that the proxy is the origin of the data.SSLProxyEngine On
: Enables SSL/TLS for the proxy.SSLProxyCheckPeerCN off
,SSLProxyCheckPeerName off
,SSLProxyCheckPeerExpire off
: These directives disable various checks for the SSL certificates of the proxied requests. It’s important in scenarios where the backend services use self-signed or non-standard certificates.SSLProxyVerify none
: Disables SSL verification entirely.
systemctl enable httpd # start automatically at system's boot
systemctl start httpd # start immediately
And we finish by enabling and starting Apache.
Configure a security group
After setting up the Apache configuration for our proxy server, it’s crucial to ensure that the server is secure and accessible as intended. This leads us to the next essential component of our setup: defining the security group rules in AWS using Terraform.
Here we assume that the proxy should only be accessible from the VPC. Feel free to change the rules to match your exact use case.
resource "aws_security_group" "proxy" {
vpc_id = "XXXXXX" # your VPC id
name = "proxy-security-group"
# Allow all outbound traffic.
egress {
from_port = 0
protocol = "-1"
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
# Allow inbound SSH (port 22), HTTP (port 80), and HTTPS (port 443) traffic from the VPC's IP range.
ingress {
from_port = 22
protocol = "tcp"
to_port = 22
cidr_blocks = ["10.0.0.0/8"]
}
ingress {
from_port = 80
protocol = "tcp"
to_port = 80
cidr_blocks = ["10.0.0.0/8"]
}
ingress {
from_port = 443
protocol = "tcp"
to_port = 443
cidr_blocks = ["10.0.0.0/8"]
}
tags = { Name = "proxy-security-group" }
}
Create a key pair
We need a SSH key pair to create the EC2 instance.
In the Terminal, use the ssh-keygen
command to generate a new SSH key pair.
You’ll be asked to enter a file name. If you don’t specify a file, the keys will be saved in the default location (~/.ssh/id_rsa
for the private key and ~/.ssh/id_rsa.pub
for the public key), which is usually fine.
Once the key is generated, navigate to the directory where the key is saved. If you didn’t specify a path, it should be in ~/.ssh/
.
You need to access the public key, which will have an extension .pub
.
cat ~/path/to/your-key.pub
Copy the entire output of the public key; it will start with ssh-rsa
followed by a long string of characters.
We are now ready to import the public key in AWS:
resource "aws_key_pair" "ec2" {
# this is how the key will be identified in AWS
key_name = "imported-key"
# The public key portion of the key pair
public_key = "ssh-rsa XXXXXXXX"
}
Define the EC2 Instance
With the security group in place and the SSH key pair created, we are now ready to define the AWS EC2 instance that will serve as our proxy server.
resource "aws_instance" "proxy" {
ami = "ami-0ed961fa828560210"
instance_type = "t2.micro"
key_name = aws_key_pair.ec2.key_name
subnet_id = "xxx"
vpc_security_group_ids = [aws_security_group.proxy.id]
user_data = file("setup-proxy.sh")
tags = {Name = "proxy"}
}
A few comments about this code:
ami
: you can use this one (which is a basic small linux), or use another onet2.micro
is chosen here, which is a good starting point for small-scale applications and testing purposes.subnet_id
: the id of the subnet in which you want to start your instancekey_name
: Refers to the SSH key pair for secure access to the instance. This is the key pair we created earlier.user_data
: This is a script that runs when the instance is first started. In our setup, it refers tosetup-proxy.sh
, which configures Apache as a proxy.
Deploy the Configuration
-
Initialize Terraform: Run
terraform init
in your project directory to initialize Terraform and download necessary plugins. -
Apply the Configuration: Run
terraform apply
to apply the configuration. Terraform will show you a plan and ask for confirmation before making changes. -
Access the Instance: Type the IP address the browser to check that the web proxy is working.
Debugging tools
SSH into the instance: Once the instance is up, you can access it using SSH and the key pair you created. For example:
ssh -i /path/to/your-key.pem ec2-user@your-instance-ip
Verify the Proxy: After logging in, you can verify that Apache is running and configured as a proxy by checking the status of the Apache service and reviewing the proxy configuration.
systemctl status httpd
Verify Apache Configuration: The next step is to verify the Apache configuration, particularly the proxy settings you’ve defined.
cat /etc/httpd/conf.d/proxy.conf
Review logs: Finally, check Apache’s log files for any errors or warnings that might indicate problems with the proxy setup. Apache’s log files are typically located in /var/log/httpd/
. The error log file is usually named error_log
or error.log
.
cat /var/log/httpd/error_log