Learn about Centmin Mod LEMP Stack today
Register Now

Letsencrypt What is the proper way to force www and still have Let's Encrypt work?

Discussion in 'Install & Upgrades or Pre-Install Questions' started by ElChorizo, Aug 11, 2023.

  1. ElChorizo

    ElChorizo Member

    60
    8
    8
    Apr 29, 2021
    Ratings:
    +13
    Local Time:
    10:16 PM
    1.19.10
    10.3.28
    I've got a few sites going and have Let's Encrypt set up and working and automatically renewing certs. However, if I modify the nginx config so that it forces all traffic to go through www and https, the Let's Encrypt renewal fails. It fails because it can't access the root domain, or something to that effect.


    What is the proper way to set up the site to force traffic to www and still allow it to renew both certs? (ie, domain and www.domain).
     
  2. eva2000

    eva2000 Administrator Staff Member

    55,801
    12,271
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,857
    Local Time:
    1:16 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+
    Do you use Cloudflare? Outline the exact steps and nginx rules you modify in Nginx vhost to do the redirects.

    If you use Cloudflare, then don't need Nginx redirects and can do redirect from Cloudflare Page rules or Always HTTPS.

    But if done via Nginx read centminmod.com/nginx_domain_dns_setup.html#httpsredirect is the correct way to set it up - pay attention to different way if you want redirect target being www version instead of non-www and vice versa and that the target version www or non-www is the only version listed in server_name for the 2nd/main server {} context.

    If you prefer www domain i.e. https://wwww.newdomain.com to be the intended redirect target, you will have add a 3rd server{} context to your Nginx HTTPS SSL vhost config file as outlined here.

    Code (Text):
    # Centmin Mod Getting Started Guide
    # must read http://centminmod.com/getstarted.html
    # For HTTP/2 SSL Setup
    # read http://centminmod.com/nginx_configure_https_ssl_spdy.html
    
    # redirect from www to non-www  forced SSL
    # uncomment, save file and restart Nginx to enable
    # if unsure use return 302 before using return 301
     server {
       server_name newdomain.com www.newdomain.com;
       return 302 https://www.newdomain.com$request_uri;
     }
    
    server {
      listen 443 ssl http2;
      server_name newdomain.com;
      return 302 https://www.newdomain.com$request_uri;
    
      ssl_dhparam /usr/local/nginx/conf/ssl/newdomain.com/dhparam.pem;
      ssl_certificate      /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.crt;
      ssl_certificate_key  /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.key;
      include /usr/local/nginx/conf/ssl_include.conf;
    }
    
    server {
      listen 443 ssl http2;
      server_name www.newdomain.com;
    
      ssl_dhparam /usr/local/nginx/conf/ssl/newdomain.com/dhparam.pem;
      ssl_certificate      /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.crt;
      ssl_certificate_key  /usr/local/nginx/conf/ssl/newdomain.com/newdomain.com.key;
      include /usr/local/nginx/conf/ssl_include.conf;
    
    < snipped the rest of the nginx settings >

    Notice the middle server{} context tells Nginx to redirect non-www domain HTTPS requests to www domain HTTPS requests for www domain on third server{} context. While first server{} context tells Nginx to redirect both non-HTTPS non-www and www domain requests to HTTPS requests for www domain on third server{} context.

    key to testing is using 302 temp redirect first in a private incognito browser session otherwise the problems you can experience may end up being due to browser caching or 301 permanent redirects unless you clear browser cache and reboot local computer(s) and even then some web browsers don't let go of 301 permanent redirect browser cache that willingly :)

    You can test in SSH via curl to check headers for location field (where the redirect goes) using the following commands:
    Code (Text):
    curl -I http://domain.com
    

    Code (Text):
    curl -I http://www.domain.com
    
     
  3. ElChorizo

    ElChorizo Member

    60
    8
    8
    Apr 29, 2021
    Ratings:
    +13
    Local Time:
    10:16 PM
    1.19.10
    10.3.28
    Those work but it doesn't allow Let's Encrypt to work behind Cloudflare, it gives an error.
     
  4. eva2000

    eva2000 Administrator Staff Member

    55,801
    12,271
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,857
    Local Time:
    1:16 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+
    what do these 4 curl commands output show, wrap each output in BBCODE CODE tags
    non-HTTPS
    Code (Text):
    curl -I http://domain.com
    

    Code (Text):
    curl -I http://www.domain.com
    

    HTTPS
    Code (Text):
    curl -I https://domain.com
    

    Code (Text):
    curl -I https://www.domain.com
    

    But if you're using Cloudflare, you can use Cloudflare DNS API to validate domains for letsencrypt instead of web root domain validation as per Letsencrypt Free SSL Certificates

     
  5. ElChorizo

    ElChorizo Member

    60
    8
    8
    Apr 29, 2021
    Ratings:
    +13
    Local Time:
    10:16 PM
    1.19.10
    10.3.28
    So the recommended way then would be to use a self signed cert and then set up Cloudflare?

    Or, what is the method to use acmetool with the DNS API?
     
    Last edited: Aug 22, 2023
  6. eva2000

    eva2000 Administrator Staff Member

    55,801
    12,271
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,857
    Local Time:
    1:16 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+
    As per quoted link to Letsencrypt Free SSL Certificates, if you use Cloudflare in front of Centmin Mod Nginx, you can switch to using Letsencrypt SSL trusted certificates via Cloudlfare DNS API. So in persistent config file /etc/centminmod/custom_config.inc (create the file if it does not already exist), add
    Code (Text):
    LETSENCRYPT_DETECT='y'
    CF_DNSAPI_GLOBAL='y'
    CF_Token="YOUR_CF_TOKEN"
    CF_Account_ID="YOUR_CF_ACCOUNT_ID"
    

    1st is to enable Centmin Mod Letsencrypt SSL support which by default uses web root authentication and validation of domains. Then last 3, switches default web root authentication to Cloudflare DNS API method of validating domains for Letsencrypt SSL issuance.

    Cloudflare API Tokens, requires you to create your Cloudflare Token API with permissions for read access to Zone.Zone, and edit/write access to Zone.DNS, across all Zones at https://dash.cloudflare.com/profile/api-tokens and to grab your Cloudflare Account ID from any of your Cloudflare domain's main dashboard's right side column listing.

    Only one Cloudflare Account is supported, so intended domains need to be within same Cloudflare Account unless you have Cloudflare Account with invited administrator access to other Cloudflare Accounts and you can generate the CF API Token to include access to the other Cloudflare Accounts.

    So when these 4 variables are set, using Centmin Mod centmin.sh menu option 2, 22 or nv commands and you answer yes to Letsencrypt live SSL certificate, the underlying acme.sh client tool will use your Cloudflare DNS API token credentials to automatically create a DNS TXT record that Letsencrypt will read to confirm and validate your domain and then issue a web browser trusted SSL certificate and install it on Centmin Mod Nginx side and then you can use Cloudflare Full SSL on edge side to talk to Centmin Mod Nginx HTTPS side with the Letsncrypt SSL cert.

    You can see an older example on my blog post at Wordpress Cache Enabler Advanced Full Page Caching Guide - Centmin Mod Blog
     
  7. ElChorizo

    ElChorizo Member

    60
    8
    8
    Apr 29, 2021
    Ratings:
    +13
    Local Time:
    10:16 PM
    1.19.10
    10.3.28
    Awesome. Perfect explanation. Thank you very much.