Introduction
I am a PHP developer. I use Linux, Apache, MySQL, and PHP to further that goal.
This video/article will show how to create a self signed SSL on a test virtual machine running on a private IP with a non-routable domain name with the Top Level Domain (TLD) of .internal.
I only use self signed SSL’s for my test servers that I have created. For production I use Let’s Encrypt.
The steps below will show how to create a self signed SSL certificate for a virtual host. Using these instruction each virtual server will have it’s own certificate.
I include the instructions for configuring the secured Apache configuration including PHP-FPM. If you are not using PHP-FPM you can remove that code from the Apache secured configuration as provided.
——->>>> Add YT Video <<<<<<<———
Prerequisites
-
- Access to a web server via SSH.
- A user capable of becomming sudo.
Overview
You’ll:
1. Create a self-signed certificate for one <-domain.tld-> , in my case that will be ‘lamp.internal’. The Top Level Domain (TLD) of .internal is not publicly routable.
2. Configure one virtual host for one domain using the cert.
3. Enable the virtual host in Apache.
Step 1. Create Self-Signed Certificates
For each domain, <-domain.tld-> (use the domain name and TLD that you desire), run:
-
- sudo mkdir -p /etc/ssl/internal/<-domain.tld->
- sudo openssl req -x509 -nodes -days 825 -newkey rsa:2048 \
-keyout /etc/ssl/internal/<-domain.tld->/<-domain.tld->.key \
-out /etc/ssl/internal/<-domain.tld->/<-domain.tld->.crt \
-subj “/C=<-YourCountryCode->/ST=<-YourState->/L=<-YourCity->/O=<-YourCompany->/OU=<-YourDepartment->/CN=<-domain.tld->”
Replace
-
- <-domain.tld-> with your domain.
- <-YourCountryCode-> with your company code.
- <-YourState-> with your state.
- <-YourCity-> with your city.
- <-YourCompany-> with your company.
- <-YourDepartment-> with your department.
Step 2. Create Apache Virtual Host Config
Create a file like /etc/apache2/sites-available/<-domain.tld-ssl->.conf with the following contents.
-
- sudo vi /etc/apache2/sites-available/<-domain.tld-ssl->.conf
<VirtualHost *:443>
ServerName <-domain.tld->
ServerAlias www.<-domain.tld-> # if you are configuring your virtual host to redirect to <-www.domain.tld-> you will need this directive.
DocumentRoot /var/www/<-domain.tld->/public_html
SSLEngine on
SSLCertificateFile /etc/ssl/internal/<-domain.tld->/<-domain.tld->.crt
SSLCertificateKeyFile /etc/ssl/internal/<-domain.tld->/<-domain.tld->.key
# mod_rewrite
# .htaccess has the other needed mod_rewrite code
<Directory /var/www/<-domain.tld->/public_html/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Start PHP-FPM
# This is the PHP-FPM code. If you are not running PHP-FPM you can comment out or remove.
# Adjust PHP socket version if needed.
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.3-fpm.<-php-fpm-user->.sock|fcgi://localhost/"
</FilesMatch>
# End PHP-FPM
ErrorLog ${APACHE_LOG_DIR}/<-domain.tld->.error.log
CustomLog ${APACHE_LOG_DIR}/<-domain.tld->.access.log combined
</VirtualHost>
Step 3 Enable SSL and Site
-
- sudo a2enmod ssl
- sudo a2ensite <-domain.tld-ssl->.conf.
- sudo systemctl reload apache2
Step 4. Add Domain to /etc/hosts file
-
- sudo vi /etc/hosts
- hit the i key to put vi in insert mode
- add a line return
- Enter the IP of the server, then a tab, then <-domain.tld->
- Enter the IP of the server, then a tab, then www.<-domain.tld->
- Press the escape key to exit insert mode
- Press the colon key
- Press the q key followed by the w key, followed by the enter key
- These steps will configure the local virtual server.
- In my case the Virtual host resides on VirtualBox that is installed on a Windows 10 laptop so the Windows host file needs to be updated as well.
- To update the Windows host file:
- Launch as notepad as administrator by right mouse clicking on notepad and selecting “Run as administrator”.
- From the top menu click on Open.
- Travers to Windows->System32->drivers->etc.
- In the lower right of the dialog box set the file exnstention to “All Files (*.*).
- Click on the file hosts.
- Scroll to the bottom and press return to obtain a new line.
- Press the tabb key, enter the domain followed by another tab then enter the domain name.
- From the main file click on File, Select save and exit the diaolg pager.
- If you are on a Linux Desktop then you will need to update that Linux box’s /etc/host file:
- At the command line enter “sudo vi /etc/hosts
- hit the i key to put vi in insert mode
- add a line return
- Enter the IP of the server, then a tab, then <-domain.tld->
- Enter the IP of the server, then a tab, then www.<-domain.tld->
- Press the escape key to exit insert mode
- Press the colon key
- Press the q key followed by the w key, followed by the enter key
Step 5. Verify the Apache Configuration
-
- sudo apache2ctl configtest
- Should Return : Syntax OK
Step 6. Verify SSL Certificate:
Use openssl to test:
echo -e "GET / HTTP/1.1\r\nHost: <-domain.tld->\r\nConnection: close\r\n\r\n" | openssl s_client -connect <-domain.tld->:443 -servername <-domain.tld-> -quiet
Look for:
-
- Verify return code: 0 (ok)
- verify error:num=18:self-signed certificate : this is normal.
- Run : sudo apache2ctl configtest – which will return “Syntax OK”
Step 7. Check with a Browser:
-
- Visit https://<-domain.tld-> to verify. (ensure it is https)
- Since this is self signed, there will be an SSL warning.
Since I am doing this for PHP development and for testing, all my websites are on a local web server that is on a private domain. To resolve my non-routable domain names, I use the Windows and Linux hosts files as a simple domain name system (DNS). If I am using the private IP range of 192.168.1.001 to 192.168.1.253 and I configure my server to use the IP 192.168.1.55 I would add “192.168.1.55<tab><-domain.tld->” to the Windows and Linux hosts files.
When accessing this private server that is configured with a self-signed cert, your browser will show a warning — you can proceed manually.
To create more self-signed certificates for other virtual hosting accounts just repeat these instruction.
Conclusion
That’s it. With this setup, I can easily create self-signed SSL certificates for any of my test environments running on private, non-routable Top Level Domain (TLD). Each virtual host gets its own certificate, and the Apache configuration can be reused and tweaked as needed — especially if you’re using PHP-FPM. This is how I like to keep my development environments secure and consistent without relying on external certificate authorities. For production, I always use Let’s Encrypt — but for local testing, this works just fine.