I need to upgrade a Laravel package to not only add Let's Encrypt SSL certificates for main domain but also for the https://github.com/smart48/le-ssl-laravel-package/pull/30ub.com/smart48/le-ssl-laravel-package/pull/30
Does anyone know if I need to add two challenge directories if I want to get a certificate for both www and non www or is this setup as shown below okay ? We are using basic CHALLENGE_TYPE_HTTP as not to depend on needed DNS changes by the way. Two, should the ssl_ciphers be unique per block or domain ?
Here is the new src/Core/SslService.php:
<?php
namespace Imagewize\SslManager\Core;
use Exception;
use stonemax\acme2\Client;
use stonemax\acme2\constants\CommonConstant;
class SslService
{
/**
* @var string
*/
private $accountEmail;
/**
* @var string
*/
private $storagePath;
/**
* @var string
*/
private $challengeDirectory;
/**
* @var HttpService
*/
private $httpServer;
public function __construct(
$accountEmail,
$storagePath,
$challengeDirectory,
HttpService $httpService
) {
$this->accountEmail = $accountEmail;
$this->storagePath = $storagePath;
$this->challengeDirectory = $challengeDirectory;
$this->httpServer = $httpService;
}
public function updateCertificate($domain, $renew = true)
{
$wwwDomain = "www." . $domain;
echo "+ Starting ...\r\n";
// staging letsencrypt service
$staging = false;
$client = new Client([$this->accountEmail], $this->storagePath, $staging);
$renew = filter_var($renew, FILTER_VALIDATE_BOOLEAN);
$order = $client->getOrder(
[
CommonConstant::CHALLENGE_TYPE_HTTP => [$domain, $wwwDomain], // Including both www and non-www domains
],
CommonConstant::KEY_PAIR_TYPE_RSA,
$renew
);
echo "+ Order expires " . $order->expires . "\r\n";
$pendingChallenges = $order->getPendingChallengeList();
// Update for non-www domain
echo "+ Adding web server configuration for " . $domain . "\r\n";
$certificateInfo = null;
$this->httpServer->updateSite($domain, $certificateInfo);
$this->httpServer->reloadConfiguration();
// Update for www domain
echo "+ Adding web server configuration for " . $wwwDomain . "\r\n";
$this->httpServer->updateSite($wwwDomain, $certificateInfo);
$this->httpServer->reloadConfiguration();
echo "+ Starting challenges\r\n";
foreach ($pendingChallenges as $challenge) {
$challengeType = $challenge->getType();
$credential = $challenge->getCredential();
if ($challengeType == CommonConstant::CHALLENGE_TYPE_HTTP) {
$domainChallengeDirectory = "{$this->challengeDirectory}/{$domain}";
if (!file_exists($domainChallengeDirectory)) {
mkdir($domainChallengeDirectory, 0755, true);
}
echo "+ Saving challenge file for " . $domain . "\r\n";
file_put_contents(
"{$domainChallengeDirectory}/{$credential['fileName']}",
$credential['fileContent']
);
}
echo "+ Verifying challenge for " . $domain . "\r\n";
$challenge->verify();
}
echo "+ Getting certificate info (this can take a while)\r\n";
$certificateInfo = $order->getCertificateFile();
// Update for non-www domain
echo "+ Writing certificate to nginx config for " . $domain . "\r\n";
$this->httpServer->updateSite($domain, $certificateInfo);
// Update for www domain
echo "+ Writing certificate to nginx config for " . $wwwDomain . "\r\n";
$this->httpServer->updateSite($wwwDomain, $certificateInfo);
echo "+ Reloading web server configuration\r\n";
$this->httpServer->reloadConfiguration();
echo "Done!\r\n";
}
}
and site.blade.php:
server {
listen 80;
listen [::]:80;
server_name {{ $domain }} www.{{ $domain }}; // Include both www and non-www versions of the domain
location /.well-known/acme-challenge {
default_type "text/plain";
alias {{ $challengeDirectory }}/{{ $domain }};
}
@if ($certificateInfo)
# Redirect to HTTPS version
location / {
return 301 https://$host$request_uri;
}
@else
# Reset connection
location / {
return 444;
}
@endif
}
@if ($certificateInfo)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ $domain }}; // Non-www version of the domain
root {{ config("ssl-manager.root_site") }};
ssl_certificate {{ $certificateInfo['nonWwwCertificateFullChained'] }};
ssl_certificate_key {{ $certificateInfo['nonWwwPrivateKey'] }};
# Improve HTTPS performance with session resumption
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
# Enable server-side protection against BEAST attacks
ssl_prefer_server_ciphers on;
ssl_ciphers .....
# Disable SSLv3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Diffie-Hellman parameter for DHE ciphersuites
# $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Enable HSTS (https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
# Enable OCSP stapling (http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox)
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate {{ $certificateInfo['nonWwwCertificateFullChained'] }};
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/{{ $domain }}-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
include fastcgi_params;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.{{ $domain }}; // www version of the domain
root {{ config("ssl-manager.root_site") }};
ssl_certificate {{ $certificateInfo['wwwCertificateFullChained'] }};
ssl_certificate_key {{ $certificateInfo['wwwPrivateKey'] }};
# Improve HTTPS performance with session resumption
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
# Enable server-side protection against BEAST attacks
ssl_prefer_server_ciphers on;
ssl_ciphers ...
# Disable SSLv3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Diffie-Hellman parameter for DHE ciphersuites
# $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Enable HSTS (https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
# Enable OCSP stapling (http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox)
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate {{ $certificateInfo['wwwCertificateFullChained'] }};
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/www.{{ $domain }}-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
include fastcgi_params;
}
}
@endif