https://github.com/aaronamran/aws-secure-apache-web-server
Practical project of setting up a Linux Web Server in AWS cloud by deploying Apache on an Ubuntu EC2 Instance, configuring DNS and installing a free SSL certificate
https://github.com/aaronamran/aws-secure-apache-web-server
aws-ec2 ubuntu
Last synced: 5 months ago
JSON representation
Practical project of setting up a Linux Web Server in AWS cloud by deploying Apache on an Ubuntu EC2 Instance, configuring DNS and installing a free SSL certificate
- Host: GitHub
- URL: https://github.com/aaronamran/aws-secure-apache-web-server
- Owner: aaronamran
- License: mit
- Created: 2025-02-07T14:48:04.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-11T15:11:03.000Z (over 1 year ago)
- Last Synced: 2025-02-11T16:24:51.128Z (over 1 year ago)
- Topics: aws-ec2, ubuntu
- Homepage:
- Size: 33.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Secure Apache Web Server on AWS Free Tier
This is a writeup of a practical project that involves the following main concepts in order:
1. [AWS Account Setup and Launching an Ubuntu EC2 Instance](https://github.com/aaronamran/Secure-Apache-Web-Server-on-AWS/blob/main/README.md#aws-account-setup-and-launching-an-ubuntu-ec2-instance)
2. [Installing and Configuring Apache](https://github.com/aaronamran/Secure-Apache-Web-Server-on-AWS/blob/main/README.md#installing-and-configuring-apache)
3. [DNS Configuration with Cloudflare (or a Free DNS Provider)](https://github.com/aaronamran/Secure-Apache-Web-Server-on-AWS/blob/main/README.md#dns-configuration-with-cloudflare-or-a-free-dns-provider)
4. [SSL Setup with Certbot and Let’s Encrypt](https://github.com/aaronamran/Secure-Apache-Web-Server-on-AWS/blob/main/README.md#ssl-setup-with-certbot-and-lets-encrypt)
5. [Additional Security Best Practices](https://github.com/aaronamran/Secure-Apache-Web-Server-on-AWS/blob/main/README.md#additional-security-best-practices)
References: [Tutorial: Install a LAMP server on AL2](https://docs.aws.amazon.com/linux/al2/ug/ec2-lamp-amazon-linux-2.html)
## AWS Account Setup and Launching an Ubuntu EC2 Instance
- In AWS, create a free tier account and complete the identity verification and billing information
- To launch an Ubuntu EC2 Instance, login to the AWS Management Console

- Go to the EC2 Dashboard and click Launch Instance

- Choose an Amazon Machine Image (AMI) and select Ubuntu LTS image (Ubuntu Server 20.04 LTS)

- Choose an Instance Type. Pick the t2.micro as it is eligible under Free Tier

- Create a Key Pair for login usage by clicking `Create new key pair`. Choose a name such as `my-ec2-key`. Keep it secure as it will be used for SSH


- Configure the Security Group in Network settings. Create or select a security group that allows
- SSH (port 22) – for remote management
- HTTP (port 80) – for web traffic
- HTTPS (port 443) – for secure traffic

- For storage configuration, usually the default settings are sufficient

- To connect to the newly created instance, open a terminal on the local machine. In this case, we will be using WSL (Ubuntu 20.04.6 LTS) on Windows 11
- In WSL, the C drive in Windows can be found in `/mnt`. To check, enter the following
```
ls -l /mnt
```

- Since the key (`my-ec2-key.pem`) is in the Downloads folder in Windows, we need to navigate to the Windows Downloads folder to find the key.
```
cd /mnt/c/Users//Downloads
```

- Now that the key has been located, copy it to the WSL home directory:
```
cp my-ec2-key.pem ~/my-ec2-key.pem
```
Then return to WSL home directory and confirm the key is there

- Set permissions for your key (if needed):
```
chmod 400 ~/my-ec2-key.pem
```
- Connect via SSH:
```
ssh -i "my-ec2-key.pem" ec2-user@ec2-13-229-127-129.ap-southeast-1.compute.amazonaws.com
```
- The local machine should now be connected to the Ubuntu instance

## Installing and Configuring Apache
- Before updating the system, identify which Linux Distribution is in use. Run the command
```
cat /etc/os-release
```

Since Amazon Linux is in use, use `yum` instead of `apt` which is commonly used on Ubuntu or Debian distributions
- Update the system:
```
sudo yum update && sudo yum upgrade -y
```

- Install Apache:
```
sudo yum install httpd -y
```

- Verify Apache is running using each of the commands below, or simply visit `http:///` in your browser to see the default Apache page):
```
sudo systemctl status httpd
sudo systemctl enable httpd
sudo systemctl start httpd
sudo systemctl status httpd
```



- Note that in Amazon Linux, UFW firewall does not exist. It does not matter since Firewall rules were already configured earlier in Network settings' Security Group
```
sudo ufw allow 'Apache Full'
```

- Now let's prepare the website in the EC2 instance. First, navigate to the `/var/www/html` folder
```
cd /var/www/html
```
- Check if git is installed in the EC2 instance. If it is not installed, run the following command:
```
sudo yum install git -y
```
Then confirm it is installed by running
```
git --version
```
- Now let's clone a [sample PHP web app repository](https://github.com/aaronamran/sample-php-crud) into the current directory
```
sudo git clone https://github.com/aaronamran/sample-php-crud.git .
```

- Install MariaDB server for the website. Run the following command and look for `mariadb105-server`
```
sudo yum search mariadb
sudo yum install mariadb105-server
```

- Run each of the following commands after the installation is complete:
```
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo systemctl status mariadb
```

## DNS Configuration with Cloudflare (or a Free DNS Provider)
- For the sake of simplicity and free resource, No-IP will be used for a free hostname instead of Cloudflare. After signing up for a free account in No-IP, create a suitable hostname such as `todolist.zapto.org`. The public IP address of the hostname is the public IP address of the EC2 instance

- To verify if Apache (httpd) is listening on port 80 on the EC2 instance, run
```
sudo netstat -tulnp | grep :80
```

- Check the VirtualHost configuration
```
sudo httpd -S
```

In the screenshot above, Apache is not configured to serve a VirtualHost on port 80, which is required for Let's Encrypt to verify the domain ownership. To fix this, create a VirtualHost configuration for HTTP (Port 80)
```
sudo nano /etc/httpd/conf.d/todolist.conf
```
Add the following configuration:
```
ServerName todolist.zapto.org
DocumentRoot /var/www/html
AllowOverride All
Require all granted
ErrorLog /var/log/httpd/todolist-error.log
CustomLog /var/log/httpd/todolist-access.log combined
```
Then restart Apache to apply changes
```
sudo systemctl restart httpd
```
- Verify again that the VirtualHost is added
```
sudo httpd -S
```

## SSL Setup with Certbot and Let’s Encrypt
- Install Certbot and the Apache Plugin:
```
sudo yum install certbot python3-certbot-apache -y
```

- Run Certbot for Apache:
```
sudo certbot --apache -d todolist.zapto.org
```
Follow the interactive prompts:
- Provide your email address
- Agree to the Terms of Service
- Certbot will ask if you want to redirect HTTP to HTTPS—choose Yes to enforce HTTPS
- The command could be ran as the following
```
sudo certbot --apache
```

- Certbot sets up automatic renewal. You can test the renewal process with:
```
sudo certbot renew --dry-run
```
- Visit `https://todolist.zapto.org/` in the browser to confirm the SSL certificate is active and that the site redirects from HTTP to HTTPS

## Additional Security Best Practices
- Keep the system updated:
```
sudo yum update && sudo yum upgrade -y
```
- Regularly check `/var/log/apache2/` for any unusual activity
- To harden Apache, disable directory listings by ensuring Options -Indexes is set in your Apache configuration. Consider installing security modules like mod_security for added protection
- Change the default SSH port, and use key-based authentication and disable password login
- Ensure the SSL certificates are renewed by checking Certbot logs or setting up email notifications