The HR department needs an app to register employees as we continue growing.
We will set up a CentOS VM and use Apache as the web server, it will be accessible via HTTP and HTTPs (we will bind an SSL certificate to the web app) on its private IP, and then we will be setting up a proper Fully qualified domain name (FQDN), finally we will use Cloudflare tunnel to securely publish our web app on the Internet.
Specs:
1 vCPU
1 Disk (40GB)
2 GB Ram
IP: 10.100.100.11/24
Setting up Hostname
Let’s change the hostname for our VM to BBM-WEB01:
sudo su
hostname BBM-WEB01
Setting up Apache
next, we can install Apache on our CentOS VM by running:
yum install httpd
Enter y:
After that, we will have the Apache server installed:
We can also verify by running:
rpm -qa | grep http
Let’s now to configure the index.html file:
cd /var/www/html/
ls -ltr
nano index.html
By default the Firewall (firewalld) will block incoming connections to port 80 and all ports, let’s disable it for now:
systemctl stop firewalld
After that, we can run the following command to make sure it’s disabled:
systemctl status firewalld
Then we can visit: http://10.100.100.11 and see the website opening
Configure SSL / HTTPS
As we noticed, we are accessing our web server via HTTP, which is an insecure protocol, let’s enable HTTPS, the secure version that uses SSL/TLS and create a self signed SSL certificate.
Let’s install the mod_ssl on our VM:
yum install mod_ssl
Now let’s create a folder to store (with full Read/Write permissions) the certificate and the private key:
mkdir /etc/ssl/private
chmod 700 /etc/ssl/private
Let’s create now our certificate with its private key:
openssl req: Initiates a certificate signing request
-x509: Specifies that you want to create a self-signed certificate instead of a certificate request
-nodes: Creates a key without a passphrase (No DES encryption)
-days 365: Certificate will be valid for 365 days
-newkey rsa:2048: Creates a new 2048-bit RSA key pair
-keyout /etc/ssl/private/ssl.key: Saves the private key to this location
-out /etc/ssl/private/ssl.crt: Saves the certificate to this location
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/ssl.key -out /etc/ssl/private/ssl.crt
After that, we will be prompted to fill out:
Country Name: US
Status or Province name (full name): Texas
Locality Name (City): Houston
Organization Name (Company): BeyondBareMetal
Organizational Unit Name: IT
Common Name: 10.100.100.11
Email Address: it@beyondbaremetal.com
Then we can verify the certificate and key have been generated and stored successfully:
cd /etc/ssl/private/
ls -ltr
Now for additional security let’s generate Diffie-Hellman parameters:
This file is commonly used in conjunction with SSL/TLS configurations (especially in Apache and Nginx) to provide additional security. The Diffie-Hellman parameters help ensure that even if a private key is compromised in the future, past communications remain secure.
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
openssl dhparam: Command to generate Diffie-Hellman parameters.
-out /etc/ssl/certs/dhparam.pem: Specifies where to save the generated parameters.
2048: Sets the key size to 2048 bits.
Let’s now append the DH parameters to our certificate:
cat /etc/ssl/certs/dhparam.pem: Reads the content of the DH parameters file
|: Pipes the output to the next command
tee -a /etc/ssl/certs/ssl.crt:
tee: reads from standard input and writes to both standard output and files
-a: means append (rather than overwrite)
Adds the DH parameters to the end of the SSL certificate file
cat /etc/ssl/certs/dhparam.pem | tee -a /etc/ssl/certs/ssl.crt
Let’s now configure the VirtualHost (to bind the certificate with our web app):
(I’ve previously created the file: beyondbaremetal.com.conf on that path)
nano /etc/httpd/conf.d/beyondbaremetal.com.conf
And set up as follows:
Finally, we can restart the Apache service:
systemctl restart httpd
We can open our web app at https://10.100.100.11:
We can verify it has the SSL certificate that we generated and bonded it to the web app:
Setting up DNS:
Now we have another challenge, the staff can’t remember which IP to use and they want to have a hostname instead: hr.beyondbaremetal.com, let’s configure that internally:
Let’s first log to the Domain Controller (DC) and create a new primary zone: beyondbaremetal.com
NOTE: When the website is live: beyondbaremetal.com we will need to come back here and add an A record for the website.
Open Server Manager > DNS
Right-click on Forward Lookup Zones > New Zone > Primary Zone
To all DNS servers running on domain controllers in this domain: beyondbaremetal.local
Zone name: beyondbaremetal.com
Allow only secure dynamic updates (recommended for Active Directory)
Review and finish:
Now go to the newly created zone: beyondbaremetal.com
Right-click on the main pane, select New host (A or AAAA) and set up as follows:
Go back to the main pane, right click and select now New Alias (CNAME), set up as follows:
Now we can check from a computer:
Notice we can open and verify is using the self-signed certificate:
SSL certificate with Active Directory Certificate Services
As you saw on the previous screens, whenever we access our web app it shows Not secure, even though we bonded an SSL certificate, that happens because that’s a self-signed certificate (not issued by any Certificate Authority), let’s now set up our Certificate Authority server and issue an SSL certificate.
Let’s login to BBM-DC01, Server manager > Manage > Add Roles and Features
Next
Select Role-based or featured-based installation, Next
Select Select a server from the server pool
Select and check Active Directory Certificate Services
Select Add Features
Check Certificate Authority
Finally we can hit Install:
We verify the install is complete:
Now let’s configure the Active Directory Certificate Services:
For role servers check Certificate Authority
Select Standalone CA
for CA type, select Root CA
Private key: Create a new private key
Cryptography:
Cryptographic provider: RSA#Microsoft Software Key Storage Provider
Key length: 2048
Hash algorithm: SHA256
CA Name: Leave a default
Validity Period: 5 Years
Certificate Database: leave as default
Review and hit Configure:
Now let’s go to Certificate Authority
We can check that we have the following:
Revoked Certificates
Issued Certificates
Pending Requests
Failed Requests
Let’s enable now Certificate Authority Web Enrollment:
Configure:
Configuration complete:
Now let’s go to our CentOS VM (Where Apache is running) and go to: 10.100.100.10/certsrv and select Request a certificate:
Advanced certificate request:
Now let’s create the Certificate Request (CSR):
openssl req -new -newkey rsa:2048 -nodes \
-keyout /etc/ssl/private/apache.key \
-out request.csr \
-subj "/C=US/ST=State/L=City/O=Organization/CN=hr.beyondbaremetal.com"
The result we copy and paste it on the request page:
After that we see that the Certificate is pending for approval:
Let’s go back to BBM-DC01 and open the Certification Authority tool > Pending Requests > Right click on the certificate and select All tasks > Issue
Next, we can see on the Issued Certificates, that the certificate has been issued correctly:
Let’s open it and export it:
Select Copy to File
Next:
Select the store for the cert in our case it will be: C:\SSL\hr.beyondbaremetal.com
Export complete:
After that let’s transfer it to our Web server BBM-WEB01:
Then let’s bind it our Virtual Host / Web app:
Then we can restart the Apache service (httpd)
Then let’s create a GPO to deploy the newly created Certificate to our domain-joined computers automatically:
Go to Computer Configuration > Policies > Windows Settings > Security Settings > Public Key > Trusted Root Certification Authorities right click and select Import
Next:
Select the Certificate:
Next:
Place all certificates in the following store: Trusted Root Certification Authorities and select Next
Finish
Import successful:
We can open it now on a domain joined computer and see the certificate is showing up correctly:
NOTE: It still shows Not Secure, which will be fixed later.
External Access
The previous was to make the Web app available for the internal network devices, but what about if we need it to be external facing in a secure way?
For that, we will use Cloudflare tunnels:
Let’s navigate to: https://one.dash.cloudflare.com/
Select Tunnels:
Set name and select the environment, for our case Red Hat:
We will be provided with a script to run on our Web server:
Then set up the public Hostname, (BBM-WEB01 private IP)
With that the Tunnel is all set:
After that, we can access the website externally and the SSL Certificate will be handled by CloudFlare:
Conclusion
We successfully set up a secure HR web application on a CentOS virtual machine using Apache in this implementation. We established multiple layers of security by implementing both a self-signed SSL certificate and later upgrading to an Active Directory Certificate Services-issued certificate. A domain controller enhanced The infrastructure with proper DNS configuration, allowing internal access via hr.beyondbaremetal.com. Finally, we enabled secure external access using Cloudflare tunnels, which provided an additional layer of security and SSL certificate management for public access. This setup ensures internal and external users can securely access the HR application while maintaining proper security protocols.
Thanks for reading!
Stay tuned for more content.
Link to the series 👉 beyondbaremetal.hashnode.dev/series/beyond-..