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
- 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
- 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!