XF 2.2 Sign your localhost dev server to make it https-capable.

ShikiSuen

Well-known member
This demonstrative article utilizes PHP 7.3 and Apache (I forgot its version). Both of them are built-in builds in macOS Big Sur 11.2.1 update.
(However, Apple claims that the built-in PHP will be removed in a future macOS release... sigh...)

Also, I use "NE" as my favorite terminal text editor. // (Who the bl**dy h*ll designed vi & vim?!)
It's installation is easy: download the source code (and then run make build install): vigna/ne: ne, the nice editor (github.com)
  1. sudo su # elevate your terminal to root access. All following commands are supposed to be run with root privileges.
  2. Run ne /etc/apache2/httpd.conf and uncomment these three lines (by remving their initial # signs):
    Code:
    #LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so
    #LoadModule ssl_module libexec/apache2/mod_ssl.so
    #Include /private/etc/apache2/extra/httpd-ssl.conf
    After that, double-tap the ESC twice to call the menu, save the file and quit.
  3. Run ne /etc/apache2/extra/httpd-ssl.conf and search the string <VirtualHost_default_:443> to locate its block. It should look like this by default:
    Code:
    ##
    ## SSL Virtual Host Context
    ##
    
    <VirtualHost _default_:443>
    
    #   General setup for the virtual host
    DocumentRoot "/Library/WebServer/Documents"
    ServerName www.example.com:443
    ServerAdmin you@example.com
    ErrorLog "/private/var/log/apache2/error_log"
    TransferLog "/private/var/log/apache2/access_log"
    You edit this block as the following one:
    (Please change the inetpub/wwwroot string to your site files folder. It appears in two places in total.)
    (Also the LOWERCASE server name shown in your macOS system share preferences.)

    Code:
    ##
    ## SSL Virtual Host Context
    ##
    
    <VirtualHost _default_:443>
    
    <Directory "/usr/local/inetpub/wwwroot">
      Options All
      MultiviewsMatch Any
      AllowOverride All
      Require all granted
    </Directory>
    
    #   General setup for the virtual host
    DocumentRoot "/usr/local/inetpub/wwwroot"
    ServerName mycomputer-owner.local:443
    ServerAdmin whateveremailyouwant@domain.com
    ErrorLog "/private/var/log/apache2/error_log"
    TransferLog "/private/var/log/apache2/access_log"
    After that, double-tap the ESC twice to call the menu, save the file and quit.
  4. Run ne /etc/ssl/openssl.cnf and make sure the following block exists at the end of this file.
    If this block doesn't exist, you insert.
    Please pay attention to the lower-case server name here as it should be the same as the one we used in the previous step:
    Code:
    [ san ]
    subjectAltName                  = mycomputer-owner.local
    After that, double-tap the ESC twice to call the menu, save the file and quit.
  5. Run ne /private/etc/apache2/sslgen.sh to create a blank bash script file. Paste the following content into it:
    (Don't forget to make sure the domain name is the same one you used in Step 3 and Step 4.)
    Bash:
    ######################
    # Become a Certificate Authority
    ######################
    
    # Generate private key
    openssl genrsa -des3 -out myCA.key 2048
    # Generate root certificate
    openssl req -x509 -new -nodes -key myCA.key -sha256 -days 825 -out myCA.pem
    
    ######################
    # Create CA-signed certs
    ######################
    
    NAME=mycomputer-owner.local # Use your own domain name
    # Generate a private key
    openssl genrsa -out server.key 2048
    # Create a certificate-signing request
    openssl req -new -key server.key -out server.csr
    # Create a config file for the extensions
    >server.ext cat <<-EOF
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    extendedKeyUsage=serverAuth,clientAuth
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = $NAME
    DNS.2 = localhost
    IP.1 = 127.0.0.1
    EOF
    # Create the signed certificate
    openssl x509 -req -in server.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial \
    -out server.crt -days 825 -sha256 -extfile server.ext
    After that, double-tap the ESC twice to call the menu, save the file and quit.
  6. Open macOS KeyChain to whitelist the cert you just created, setting it as always-trusted.
  7. apachectl -k start // or restart.

You are good to go.

P.S.: Why lower-casing the domain name? It is to make sure the cert generation process won't get fried. "XXXXX.local" are abnormal domain names and are only used in BSD-like distros (FreeBSD HelloSystem, macOS, etc.), bringing my concern here.


References:
// Set up localhost on macOS High Sierra (Apache, MySQL, and PHP 7) with SSL/HTTPS (websitebeaver.com)
// ssl - Getting Chrome to accept self-signed localhost certificate - Stack Overflow

---- Might be useful even if unrelated to this topic if someone wants to use homebrew PHP module with macOS built-in Apache ----
How to future proof your apache modules in macOS by signing them with your own certificate authority (phusion.nl)
Also, Kier mentioned that PHP-fpm can also be used in Apache to bypass the codesigning process. Feel free to try.
 
Last edited:

ShikiSuen

Well-known member
Regarding the script in the 5th step, an additional line is helpful to automatically trust the newly generated cert:
Code:
security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /private/etc/apache2/server.crt
 
Top