I’m running a PHP script on my cloud server to configure domains with Apache and SSL certificates. The script verifies the domain’s A record, creates the necessary webroot directory, generates an Apache virtual host configuration, and sets up SSL using Certbot.
VIEW MY PHP CODE
click here
<?php
$domain = $_POST['domain'] ?? '';
$public_ip = getServerPublicIP();
$webroot = '/var/www/html/' . $domain;
$hosting_id = uniqid(); // Generate a unique ID for each hosting instance
// Function to get the server's public IP address
function getServerPublicIP() {
$ip = file_get_contents('http://checkip.amazonaws.com/');
return trim($ip);
}
// Function to verify if the domain's A record points to the server's IP
function verifyDomain($domain, $public_ip) {
$dns_records = dns_get_record($domain, DNS_A);
if (!empty($dns_records)) {
foreach ($dns_records as $record) {
if ($record['ip'] == $public_ip) {
return true;
}
}
}
return false;
}
// Function to handle SSL certificate generation and renewal using Certbot
function setupSSL($domain) {
$output = shell_exec("sudo certbot --apache -d $domain 2>&1");
if (strpos($output, "Congratulations! Your certificate and chain have been saved") !== false) {
return true;
}
return false;
}
// Function to create Apache virtual host configuration
function createVirtualHostConfig($domain, $webroot, $hosting_id) {
$conf = "
<VirtualHost *:80>
ServerName $domain
Redirect permanent / https://$domain/
# Redirect IP address access to vinsanjay.me
RewriteEngine On
RewriteCond %{HTTP_HOST} ^" . getServerPublicIP() . "$
RewriteRule ^(.*)$ http://vinsanjay.me$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName $domain
DocumentRoot $webroot
<Directory $webroot>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/$domain_error.log
CustomLog ${APACHE_LOG_DIR}/$domain_access.log combined
SetEnv hosting_id $hosting_id
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/$domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/$domain/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
# Enforce HTTPS with HSTS
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Disable server signature
ServerSignature Off
ServerTokens Prod
# Prevent clickjacking
Header always append X-Frame-Options SAMEORIGIN
# Prevent MIME type sniffing
Header always set X-Content-Type-Options nosniff
# Prevent XSS attacks
Header always set X-XSS-Protection "1; mode=block"
# Disable directory listing
Options -Indexes
</VirtualHost>
";
// Save the configuration file using sudo
$conf_file = "/etc/apache2/sites-available/{$domain}.conf";
$command = "echo '$conf' | sudo tee $conf_file > /dev/null";
$output = shell_exec($command);
// Check if file creation was successful
if (!file_exists($conf_file)) {
error_log("Failed to save Apache configuration for $domain");
return false;
}
// Enable the site and reload Apache with sudo
$output = shell_exec("sudo -S a2ensite {$domain}.conf 2>&1");
if (strpos($output, "Enabling site $domain") !== false) {
exec("sudo -S systemctl reload apache2");
return true;
}
error_log("Failed to enable Apache site for $domain");
return false;
}
// Function to ensure secure permissions on webroot
function secureWebroot($webroot) {
// Set permissions to prevent directory listing and ensure security
chmod($webroot, 0755); // Set directory permissions to 0755
chmod($webroot . '/index.html', 0644); // Set file permissions to 0644
}
// Function to check if Apache configuration file exists
function apacheConfigExists($domain) {
$conf_file = "/etc/apache2/sites-available/{$domain}.conf";
return file_exists($conf_file);
}
// Function to handle errors and log them
function handleErrors($message) {
// Log errors to a file
error_log($message);
echo "Error occurred: $message";
}
if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($domain)) {
try {
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
throw new Exception("Invalid domain name format.");
}
// Verify domain A record points to the server's IP
if (!verifyDomain($domain, $public_ip)) {
throw new Exception("Domain verification failed. Ensure the A record points to $public_ip.");
}
if (!file_exists($webroot)) {
mkdir($webroot, 0775, true);
secureWebroot($webroot);
} else {
// Optionally handle existing directory scenario
// Log the event or notify the user
error_log("Web root directory $webroot already exists.");
}
if (apacheConfigExists($domain)) {
echo "Domain $domain is already configured.";
} else {
if (createVirtualHostConfig($domain, $webroot, $hosting_id)) {
echo "Domain $domain has been configured successfully!";
} else {
throw new Exception("Failed to configure domain $domain.");
}
// Setup SSL certificate
if (setupSSL($domain)) {
echo " SSL has been configured successfully!";
} else {
throw new Exception("SSL setup failed for domain $domain.");
}
// Check if index.html exists in the webroot to confirm successful hosting
if (file_exists($webroot . '/index.html')) {
echo " Your website hosted successfully at <a href='https://$domain' target='_blank'>https://$domain</a>";
} else {
throw new Exception("Website hosting failed.");
}
exec("sudo systemctl start apache2");
}
} catch (Exception $e) {
handleErrors($e->getMessage());
}
} else {
echo "Please enter a valid domain.";
}
?>
<!-- HTML form -->
<form method="POST">
<label for="domain">Enter Domain Name:</label>
<input type="text" id="domain" name="domain" required>
<button type="submit">Submit</button>
</form>
<p>POINT YOUR DOMAIN NAME TO THIS IP ADDRESS IN AN A RECORD: <?php echo $public_ip; ?></p>
Problem:
When I run this script, I encounter the following message:
Domain verification is successful but failed to create an Apache configuration.
I’ve ensured that:
The A record points to the server’s public IP.
The required permissions are set correctly.
Apache and Certbot are installed and configured properly.
Steps to Reproduce:
Set up a cloud server with Apache and Certbot installed.
Place the PHP script on the server.
Enter the domain name (e.g., ls.vinsanjay.me) in the form and submit.
What I’ve Tried:
Verified that the domain’s A record points to the server’s IP.
Checked the permissions for the directories and files involved.
Manually tested Certbot and Apache configuration commands, which worked fine outside the script.
Additional Information:
OS: Ubuntu 20.04
PHP Version: 7.4
Apache Version: 2.4.41
Question:
How can I resolve this issue? Any help or guidance would be greatly appreciated.
rubikproxy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.