Host Apache + Vhost + SSL — Monterey (OS 12)

Neto
3 min readJun 19, 2021

--

This is a quick guide to start an Apache2 server with 2 Vhost sites with a secure connection under OSX 12 Monterey.

This guide assumes that you:

  • Already have two domains (first.domain and second.domain) with the DNS A record pointing to your fixed IP.
  • You are familiar with Terminal.
  • Your two sites are already created in:

/Library/WebServer/Documents (for first.domain)

/Library/WebServer/Documents/Second (for second.domain)

APACHE CONFIG + VHOST

  1. Go to /etc and edit the hosts file (with your real domain names, obviously):

#Hosts file for local host and main site
127.0.0.1 first.domain
127.0.0.1 second.domain
127.0.0.1 localhost

2. Now go to /etc/apache2 and edit httpd.conf

3. Make sure around line 31 you set ServerRoot to:

ServerRoot “/usr”

4. Then the Listen to

<IfDefine SERVER_APP_HAS_DEFAULT_PORTS>
Listen 8080
</IfDefine>
<IfDefine !SERVER_APP_HAS_DEFAULT_PORTS>
Listen 80
</IfDefine>

5. In the LoadModule Section, you only need the following lines (remove the #):

LoadModule mpm_prefork_module libexec/apache2/mod_mpm_prefork.so
LoadModule authn_file_module libexec/apache2/mod_authn_file.so
LoadModule authn_core_module libexec/apache2/mod_authn_core.so
LoadModule authz_host_module libexec/apache2/mod_authz_host.so
LoadModule authz_groupfile_module libexec/apache2/mod_authz_groupfile.so
LoadModule authz_user_module libexec/apache2/mod_authz_user.so
LoadModule authz_core_module libexec/apache2/mod_authz_core.so
LoadModule access_compat_module libexec/apache2/mod_access_compat.so
LoadModule auth_basic_module libexec/apache2/mod_auth_basic.so
libexec/apache2/mod_allowmethods.so
libexec/apache2/mod_cache_socache.so
LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so
libexec/apache2/mod_socache_memcache.so
libexec/apache2/mod_socache_redis.so
LoadModule reqtimeout_module libexec/apache2/mod_reqtimeout.so
LoadModule filter_module libexec/apache2/mod_filter.so
LoadModule mime_module libexec/apache2/mod_mime.so
LoadModule log_config_module libexec/apache2/mod_log_config.so
LoadModule env_module libexec/apache2/mod_env.so
LoadModule headers_module libexec/apache2/mod_headers.so
LoadModule setenvif_module libexec/apache2/mod_setenvif.so
LoadModule version_module libexec/apache2/mod_version.so
libexec/apache2/mod_proxy_connect.so
LoadModule slotmem_shm_module libexec/apache2/mod_slotmem_shm.so
LoadModule ssl_module libexec/apache2/mod_ssl.so
libexec/apache2/mod_lbmethod_byrequests.so
LoadModule unixd_module libexec/apache2/mod_unixd.so
LoadModule status_module libexec/apache2/mod_status.so
LoadModule autoindex_module libexec/apache2/mod_autoindex.so
<IfModule !mpm_prefork_module>
</IfModule>
<IfModule mpm_prefork_module>
</IfModule>
LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
LoadModule negotiation_module libexec/apache2/mod_negotiation.so
LoadModule dir_module libexec/apache2/mod_dir.so
LoadModule alias_module libexec/apache2/mod_alias.so
LoadModule hfs_apple_module libexec/apache2/mod_hfs_apple.so

6. Now find the ServerAdmin line and add your email:

ServerAdmin your@email.com

7. And your ServerName:

ServerName first.domain:80

8. The DocumentRoot is where your first.domain is hosted in your Mac.

DocumentRoot “/Library/WebServer/Documents”
<Directory “/Library/WebServer/Documents”>

Almost there.

9. Near line 530 you will find the # Virtual hosts Section.

Add the configuration of your sites (change “first.domain” and “second.domain” for your domains, of course):

#FIRST DOMAIN

<VirtualHost first.domain:80>
ServerAdmin your@email.com
ServerName first.domain
DocumentRoot “/Library/WebServer/Documents”
ErrorLog “/private/var/log/apache2/first.local-error_log”
CustomLog “/private/var/log/apache2/first.local-access_log” common

<Directory “/Library/WebServer/Documents”>
AllowOverride All
Require all granted
</Directory>
Header add Access-Control-Allow-Origin “*”
</VirtualHost>

#SECOND DOMAIN

<VirtualHost second.domain:80>
DocumentRoot “/Library/WebServer/Documents/Second
ServerName second.domain
ErrorLog “/private/var/log/apache2/spin.local-error_log”
CustomLog “/private/var/log/apache2/spin.local-access_log” common

<Directory “/Library/WebServer/Documents/Second”>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

10. Finally, you should config the SSL section as bellow:

# Secure (SSL/TLS) connections
Include /private/etc/apache2/extra/httpd-ssl.conf
#
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
#
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>

Include /private/etc/apache2/other/*.conf

At this point, if you have any sites in the “/Library/WebServer/Documents/Second” and “/Library/WebServer/Documents/Second” folders, you should be good to go, although the Secure connection is not configured yet.

To test it, open Terminal start Apache:

sudo apachectl start

Go to your browser of choice and load the two sites. They should be running fine.

Now, let’s make them secure:

CERTBOT + SSL

  1. First, in Terminal, stop Apache:

sudo apachectl stop

2. Then edit the file /etc/apache2/extra/httpd-ssl.conf to look like this:

# the size may need to be increased. (AH01929 will be logged.)
#SSLStaplingCache “shmcb:/private/var/run/ssl_stapling(32768)”

# Seconds before valid OCSP responses are expired from the cache
#SSLStaplingStandardCacheTimeout 3600

# Seconds before invalid OCSP responses are expired from the cache
#SSLStaplingErrorCacheTimeout 600

##
## SSL Virtual Host Context
##

<VirtualHost first.domain:443>

# General setup for the virtual host
DocumentRoot “/Library/WebServer/Documents”
ServerName first.domain:443
ServerAdmin your@email.com
ErrorLog “/private/var/log/apache2/error_log”
TransferLog “/private/var/log/apache2/access_log”

SSLEngine on

SSLCertificateFile “/etc/letsencrypt/live/first.domain/fullchain.pem”
SSLCertificateKeyFile “/etc/letsencrypt/live/first.domain/privkey.pem”

<FilesMatch “\.(cgi|shtml|phtml|php)$”>
SSLOptions +StdEnvVars
</FilesMatch>
<Directory “/Library/WebServer/CGI-Executables”>
SSLOptions +StdEnvVars
</Directory>

BrowserMatch “MSIE [2–5]” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

CustomLog “/private/var/log/apache2/ssl_request_log” \
“%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \”%r\” %b”

</VirtualHost>

<VirtualHost second.domain:443>

# General setup for the virtual host
DocumentRoot “/Library/WebServer/Documents/Second”
ServerName first.domain:443
ServerAdmin your@email.com
ErrorLog “/private/var/log/apache2/error_log”
TransferLog “/private/var/log/apache2/access_log”

SSLEngine on

SSLCertificateFile “/etc/letsencrypt/live/second.domain/fullchain.pem”
SSLCertificateKeyFile “/etc/letsencrypt/live/second.domain/privkey.pem”

<FilesMatch “\.(cgi|shtml|phtml|php)$”>
SSLOptions +StdEnvVars
</FilesMatch>
<Directory “/Library/WebServer/CGI-Executables”>
SSLOptions +StdEnvVars
</Directory>

BrowserMatch “MSIE [2–5]” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

CustomLog “/private/var/log/apache2/ssl_request_log” \
“%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \”%r\” %b”

</VirtualHost>

Almost there.

3. Now you have to generate the certificates. Head to Terminal and run

sudo certbot certonly — standalone

Ignore error messages and add first.domain when asked.

Certbot will create two files at /etc/letsencrypt/live/first.domain note that this is the same path you entered in the /etc/apache2/extra/httpd-ssl.conf you edited above.

For the second domain, go to Terminal and, again:

sudo certbot certonly — standalone

Ignore error messages and add second.domain when asked.

Certbot will create two files at /etc/letsencrypt/live/second.domain note that this is also the same path you entered in the /etc/apache2/extra/httpd-ssl.conf you edited above.

Well… that’s it.

Start Apache in Terminal with:

sudo apachectl start

Now you should have two secure sites hosted.

Hope it helps!

--

--

Neto

“You learn who your friends are when the shit hits the fan.” ― Ozzy Osbourne