How to install Apache and configure virtualhosts with http and https on Ubuntu 18.04 LTS - jbilander/HowTos GitHub Wiki

How to install Apache and configure virtualhosts with http and https on Ubuntu 18.04 LTS

first become root:

jbilander@zeus:~$ sudo -s
[sudo] password for jbilander:
root@zeus:~#

install apache2:

root@zeus:~# apt update

root@zeus:~# apt install apache2
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.2-0 ssl-cert
Suggested packages:
  www-browser apache2-doc apache2-suexec-pristine | apache2-suexec-custom openssl-blacklist
The following NEW packages will be installed:
  apache2 apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.2-0 ssl-cert
0 upgraded, 10 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,730 kB of archives.
After this operation, 6,985 kB of additional disk space will be used.
Do you want to continue? [Y/n] y

Now apache2 is installed and running on your machine.

We can check how the default process has forked child processes:

root@zeus:~# pstree -p
systemd(1)─┬─accounts-daemon(4377)─┬─{accounts-daemon}(4472)
           β”‚                       └─{accounts-daemon}(4517)
           β”œβ”€agetty(4525)
           β”œβ”€apache2(5278)─┬─apache2(5279)─┬─{apache2}(5283)
           β”‚               β”‚               β”œβ”€{apache2}(5286)
           β”‚               β”‚               β”œβ”€{apache2}(5290)
           β”‚               β”‚               β”œβ”€{apache2}(5292)
           β”‚               β”‚               β”œβ”€{apache2}(5293)
           β”‚               β”‚               β”œβ”€{apache2}(5296)
           β”‚               β”‚               β”œβ”€{apache2}(5300)
           β”‚               β”‚               β”œβ”€{apache2}(5303)
           β”‚               β”‚               β”œβ”€{apache2}(5304)
           β”‚               β”‚               β”œβ”€{apache2}(5306)
           β”‚               β”‚               β”œβ”€{apache2}(5310)
           β”‚               β”‚               β”œβ”€{apache2}(5312)
           β”‚               β”‚               β”œβ”€{apache2}(5314)
           β”‚               β”‚               β”œβ”€{apache2}(5316)
           β”‚               β”‚               β”œβ”€{apache2}(5318)
           β”‚               β”‚               β”œβ”€{apache2}(5320)
           β”‚               β”‚               β”œβ”€{apache2}(5322)
           β”‚               β”‚               β”œβ”€{apache2}(5324)
           β”‚               β”‚               β”œβ”€{apache2}(5327)
           β”‚               β”‚               β”œβ”€{apache2}(5329)
           β”‚               β”‚               β”œβ”€{apache2}(5331)
           β”‚               β”‚               β”œβ”€{apache2}(5333)
           β”‚               β”‚               β”œβ”€{apache2}(5335)
           β”‚               β”‚               β”œβ”€{apache2}(5336)
           β”‚               β”‚               β”œβ”€{apache2}(5337)
           β”‚               β”‚               └─{apache2}(5338)
           β”‚               └─apache2(5280)─┬─{apache2}(5284)
           β”‚                               β”œβ”€{apache2}(5287)
           β”‚                               β”œβ”€{apache2}(5288)
           β”‚                               β”œβ”€{apache2}(5289)
           β”‚                               β”œβ”€{apache2}(5291)
           β”‚                               β”œβ”€{apache2}(5294)
           β”‚                               β”œβ”€{apache2}(5297)
           β”‚                               β”œβ”€{apache2}(5298)
           β”‚                               β”œβ”€{apache2}(5299)
           β”‚                               β”œβ”€{apache2}(5301)
           β”‚                               β”œβ”€{apache2}(5302)
           β”‚                               β”œβ”€{apache2}(5305)
           β”‚                               β”œβ”€{apache2}(5308)
           β”‚                               β”œβ”€{apache2}(5309)
           β”‚                               β”œβ”€{apache2}(5311)
           β”‚                               β”œβ”€{apache2}(5313)
           β”‚                               β”œβ”€{apache2}(5315)
           β”‚                               β”œβ”€{apache2}(5317)
           β”‚                               β”œβ”€{apache2}(5319)
           β”‚                               β”œβ”€{apache2}(5321)
           β”‚                               β”œβ”€{apache2}(5323)
           β”‚                               β”œβ”€{apache2}(5325)
           β”‚                               β”œβ”€{apache2}(5326)
           β”‚                               β”œβ”€{apache2}(5328)
           β”‚                               β”œβ”€{apache2}(5330)
           β”‚                               └─{apache2}(5332)
           β”œβ”€atd(4090)

If you have UFW running on your machine make sure you have enabled http port (80) and https port (443) https://github.com/jbilander/HowTos/wiki/How-to-set-up-Uncomplicated-Firewall-(UFW)-on-Ubuntu-18.04-LTS

Now, point your browser to the IP address of the machine and you will see this page:

Let's check what modules were loaded when apache2 started:

root@zeus:~# apachectl -M
Loaded Modules:
 core_module (static)
 so_module (static)
 watchdog_module (static)
 http_module (static)
 log_config_module (static)
 logio_module (static)
 version_module (static)
 unixd_module (static)
 access_compat_module (shared)
 alias_module (shared)
 auth_basic_module (shared)
 authn_core_module (shared)
 authn_file_module (shared)
 authz_core_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 filter_module (shared)
 mime_module (shared)
 mpm_event_module (shared)
 negotiation_module (shared)
 reqtimeout_module (shared)
 setenvif_module (shared)
 status_module (shared)

OK, we can take a look at the available modules with ls:

root@zeus:~# ls -al /etc/apache2/mods-available/*.load
-rw-r--r-- 1 root root 100 Oct 10 20:59 /etc/apache2/mods-available/access_compat.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/actions.load
-rw-r--r-- 1 root root  62 Oct 10 20:59 /etc/apache2/mods-available/alias.load
-rw-r--r-- 1 root root  76 Oct 10 20:59 /etc/apache2/mods-available/allowmethods.load
-rw-r--r-- 1 root root  76 Oct 10 20:59 /etc/apache2/mods-available/asis.load
-rw-r--r-- 1 root root  94 Oct 10 20:59 /etc/apache2/mods-available/auth_basic.load
-rw-r--r-- 1 root root  96 Oct 10 20:59 /etc/apache2/mods-available/auth_digest.load
-rw-r--r-- 1 root root 100 Oct 10 20:59 /etc/apache2/mods-available/auth_form.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/authn_anon.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/authn_core.load
-rw-r--r-- 1 root root  85 Oct 10 20:59 /etc/apache2/mods-available/authn_dbd.load
-rw-r--r-- 1 root root  70 Oct 10 20:59 /etc/apache2/mods-available/authn_dbm.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/authn_file.load
-rw-r--r-- 1 root root  78 Oct 10 20:59 /etc/apache2/mods-available/authn_socache.load
-rw-r--r-- 1 root root  74 Oct 10 20:59 /etc/apache2/mods-available/authnz_fcgi.load
-rw-r--r-- 1 root root  90 Oct 10 20:59 /etc/apache2/mods-available/authnz_ldap.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/authz_core.load
-rw-r--r-- 1 root root  96 Oct 10 20:59 /etc/apache2/mods-available/authz_dbd.load
-rw-r--r-- 1 root root  92 Oct 10 20:59 /etc/apache2/mods-available/authz_dbm.load
-rw-r--r-- 1 root root 104 Oct 10 20:59 /etc/apache2/mods-available/authz_groupfile.load
-rw-r--r-- 1 root root  94 Oct 10 20:59 /etc/apache2/mods-available/authz_host.load
-rw-r--r-- 1 root root  74 Oct 10 20:59 /etc/apache2/mods-available/authz_owner.load
-rw-r--r-- 1 root root  94 Oct 10 20:59 /etc/apache2/mods-available/authz_user.load
-rw-r--r-- 1 root root  70 Oct 10 20:59 /etc/apache2/mods-available/autoindex.load
-rw-r--r-- 1 root root  64 Oct 10 20:59 /etc/apache2/mods-available/buffer.load
-rw-r--r-- 1 root root  89 Oct 10 20:59 /etc/apache2/mods-available/cache_disk.load
-rw-r--r-- 1 root root  62 Oct 10 20:59 /etc/apache2/mods-available/cache.load
-rw-r--r-- 1 root root  95 Oct 10 20:59 /etc/apache2/mods-available/cache_socache.load
-rw-r--r-- 1 root root  70 Oct 10 20:59 /etc/apache2/mods-available/cern_meta.load
-rw-r--r-- 1 root root  60 Oct 10 20:59 /etc/apache2/mods-available/cgid.load
-rw-r--r-- 1 root root  58 Oct 10 20:59 /etc/apache2/mods-available/cgi.load
-rw-r--r-- 1 root root  76 Oct 10 20:59 /etc/apache2/mods-available/charset_lite.load
-rw-r--r-- 1 root root  60 Oct 10 20:59 /etc/apache2/mods-available/data.load
-rw-r--r-- 1 root root  79 Oct 10 20:59 /etc/apache2/mods-available/dav_fs.load
-rw-r--r-- 1 root root  58 Oct 10 20:59 /etc/apache2/mods-available/dav.load
-rw-r--r-- 1 root root  68 Oct 10 20:59 /etc/apache2/mods-available/dav_lock.load
-rw-r--r-- 1 root root  58 Oct 10 20:59 /etc/apache2/mods-available/dbd.load
-rw-r--r-- 1 root root  84 Oct 10 20:59 /etc/apache2/mods-available/deflate.load
-rw-r--r-- 1 root root  64 Oct 10 20:59 /etc/apache2/mods-available/dialup.load
-rw-r--r-- 1 root root  58 Oct 10 20:59 /etc/apache2/mods-available/dir.load
-rw-r--r-- 1 root root  64 Oct 10 20:59 /etc/apache2/mods-available/dump_io.load
-rw-r--r-- 1 root root  60 Oct 10 20:59 /etc/apache2/mods-available/echo.load
-rw-r--r-- 1 root root  58 Oct 10 20:59 /etc/apache2/mods-available/env.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/expires.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/ext_filter.load
-rw-r--r-- 1 root root  89 Oct 10 20:59 /etc/apache2/mods-available/file_cache.load
-rw-r--r-- 1 root root  64 Oct 10 20:59 /etc/apache2/mods-available/filter.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/headers.load
-rw-r--r-- 1 root root 176 Oct 10 20:59 /etc/apache2/mods-available/heartbeat.load
-rw-r--r-- 1 root root 182 Oct 10 20:59 /etc/apache2/mods-available/heartmonitor.load
-rw-r--r-- 1 root root  62 Oct 10 20:59 /etc/apache2/mods-available/http2.load
-rw-r--r-- 1 root root  62 Oct 10 20:59 /etc/apache2/mods-available/ident.load
-rw-r--r-- 1 root root  68 Oct 10 20:59 /etc/apache2/mods-available/imagemap.load
-rw-r--r-- 1 root root  82 Oct 10 20:59 /etc/apache2/mods-available/include.load
-rw-r--r-- 1 root root  60 Oct 10 20:59 /etc/apache2/mods-available/info.load
-rw-r--r-- 1 root root 116 Oct 10 20:59 /etc/apache2/mods-available/lbmethod_bybusyness.load
-rw-r--r-- 1 root root 116 Oct 10 20:59 /etc/apache2/mods-available/lbmethod_byrequests.load
-rw-r--r-- 1 root root 114 Oct 10 20:59 /etc/apache2/mods-available/lbmethod_bytraffic.load
-rw-r--r-- 1 root root 114 Oct 10 20:59 /etc/apache2/mods-available/lbmethod_heartbeat.load
-rw-r--r-- 1 root root  60 Oct 10 20:59 /etc/apache2/mods-available/ldap.load
-rw-r--r-- 1 root root  70 Oct 10 20:59 /etc/apache2/mods-available/log_debug.load
-rw-r--r-- 1 root root  76 Oct 10 20:59 /etc/apache2/mods-available/log_forensic.load
-rw-r--r-- 1 root root  58 Oct 10 20:59 /etc/apache2/mods-available/lua.load
-rw-r--r-- 1 root root  62 Oct 10 20:59 /etc/apache2/mods-available/macro.load
-rw-r--r-- 1 root root  60 Oct 10 20:59 /etc/apache2/mods-available/mime.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/mime_magic.load
-rw-r--r-- 1 root root 106 Oct 10 20:59 /etc/apache2/mods-available/mpm_event.load
-rw-r--r-- 1 root root 108 Oct 10 20:59 /etc/apache2/mods-available/mpm_prefork.load
-rw-r--r-- 1 root root 107 Oct 10 20:59 /etc/apache2/mods-available/mpm_worker.load
-rw-r--r-- 1 root root  74 Oct 10 20:59 /etc/apache2/mods-available/negotiation.load
-rw-r--r-- 1 root root  87 Oct 10 20:59 /etc/apache2/mods-available/proxy_ajp.load
-rw-r--r-- 1 root root 115 Oct 10 20:59 /etc/apache2/mods-available/proxy_balancer.load
-rw-r--r-- 1 root root  95 Oct 10 20:59 /etc/apache2/mods-available/proxy_connect.load
-rw-r--r-- 1 root root  95 Oct 10 20:59 /etc/apache2/mods-available/proxy_express.load
-rw-r--r-- 1 root root  89 Oct 10 20:59 /etc/apache2/mods-available/proxy_fcgi.load
-rw-r--r-- 1 root root  93 Oct 10 20:59 /etc/apache2/mods-available/proxy_fdpass.load
-rw-r--r-- 1 root root  87 Oct 10 20:59 /etc/apache2/mods-available/proxy_ftp.load
-rw-r--r-- 1 root root  93 Oct 10 20:59 /etc/apache2/mods-available/proxy_hcheck.load
-rw-r--r-- 1 root root  97 Oct 10 20:59 /etc/apache2/mods-available/proxy_html.load
-rw-r--r-- 1 root root  97 Oct 10 20:59 /etc/apache2/mods-available/proxy_http2.load
-rw-r--r-- 1 root root  89 Oct 10 20:59 /etc/apache2/mods-available/proxy_http.load
-rw-r--r-- 1 root root  62 Oct 10 20:59 /etc/apache2/mods-available/proxy.load
-rw-r--r-- 1 root root  89 Oct 10 20:59 /etc/apache2/mods-available/proxy_scgi.load
-rw-r--r-- 1 root root  97 Oct 10 20:59 /etc/apache2/mods-available/proxy_wstunnel.load
-rw-r--r-- 1 root root  85 Oct 10 20:59 /etc/apache2/mods-available/ratelimit.load
-rw-r--r-- 1 root root  70 Oct 10 20:59 /etc/apache2/mods-available/reflector.load
-rw-r--r-- 1 root root  68 Oct 10 20:59 /etc/apache2/mods-available/remoteip.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/reqtimeout.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/request.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/rewrite.load
-rw-r--r-- 1 root root  58 Oct 10 20:59 /etc/apache2/mods-available/sed.load
-rw-r--r-- 1 root root  99 Oct 10 20:59 /etc/apache2/mods-available/session_cookie.load
-rw-r--r-- 1 root root  99 Oct 10 20:59 /etc/apache2/mods-available/session_crypto.load
-rw-r--r-- 1 root root  93 Oct 10 20:59 /etc/apache2/mods-available/session_dbd.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/session.load
-rw-r--r-- 1 root root  68 Oct 10 20:59 /etc/apache2/mods-available/setenvif.load
-rw-r--r-- 1 root root  78 Oct 10 20:59 /etc/apache2/mods-available/slotmem_plain.load
-rw-r--r-- 1 root root  74 Oct 10 20:59 /etc/apache2/mods-available/slotmem_shm.load
-rw-r--r-- 1 root root  74 Oct 10 20:59 /etc/apache2/mods-available/socache_dbm.load
-rw-r--r-- 1 root root  84 Oct 10 20:59 /etc/apache2/mods-available/socache_memcache.load
-rw-r--r-- 1 root root  78 Oct 10 20:59 /etc/apache2/mods-available/socache_shmcb.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/speling.load
-rw-r--r-- 1 root root  97 Oct 10 20:59 /etc/apache2/mods-available/ssl.load
-rw-r--r-- 1 root root  64 Oct 10 20:59 /etc/apache2/mods-available/status.load
-rw-r--r-- 1 root root  72 Oct 10 20:59 /etc/apache2/mods-available/substitute.load
-rw-r--r-- 1 root root  64 Oct 10 20:59 /etc/apache2/mods-available/suexec.load
-rw-r--r-- 1 root root  70 Oct 10 20:59 /etc/apache2/mods-available/unique_id.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/userdir.load
-rw-r--r-- 1 root root  70 Oct 10 20:59 /etc/apache2/mods-available/usertrack.load
-rw-r--r-- 1 root root  74 Oct 10 20:59 /etc/apache2/mods-available/vhost_alias.load
-rw-r--r-- 1 root root  66 Oct 10 20:59 /etc/apache2/mods-available/xml2enc.load
root@zeus:~#

For this apache2-server I want to enable the rewrite_module and the ssl_module:

root@zeus:~# a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
  systemctl restart apache2

root@zeus:~# a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
  systemctl restart apache2

root@zeus:~#

Nice, rewrite and ssl modules enabled, now I will configure and use virtual hosts, we start by looking what we got currently in the sites-available and sites-enabled folders:

root@zeus:~# ls -al /etc/apache2/sites-available/
total 22
drwxr-xr-x 2 root root    4 Jan 16 10:34 .
drwxr-xr-x 8 root root   12 Jan 16 10:34 ..
-rw-r--r-- 1 root root 1332 Oct 10 20:59 000-default.conf
-rw-r--r-- 1 root root 6338 Oct 10 20:59 default-ssl.conf  

root@zeus:~# ls -al  /etc/apache2/sites-enabled/
total 10
drwxr-xr-x 2 root root  3 Jan 16 10:34 .
drwxr-xr-x 8 root root 12 Jan 16 10:34 ..
lrwxrwxrwx 1 root root 35 Jan 16 10:34 000-default.conf -> ../sites-available/000-default.conf

Ok, let's turn off the default config and make a copy of that file and call it vhosts-default.conf:

root@zeus:~# a2dissite 000-default
Site 000-default disabled.
To activate the new configuration, you need to run:
  systemctl reload apache2

root@zeus:~# cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/vhosts-default.conf

Now, edit the vhosts-default.conf file with your favorite editor, I use vim here and will use the domain name example.com here for demoing purposes:

root@zeus:~# vi /etc/apache2/sites-enabled/vhosts-default.conf

<VirtualHost *:80>
        ServerName example.com
        ServerAlias example.se
        ServerAlias www.example.se
        Redirect permanent / http://www.example.com
</VirtualHost>
<VirtualHost *:80>
        ServerName www.example.com
        DocumentRoot /var/www/example
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        <Directory /var/www/example>
                Options Indexes FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>
</VirtualHost>

Save the file and exit.

Now, what does this config say? If you browse to this site with the naked domain (example.com) or one of the .se aliases you will be redirected to www.example.com and served by the index file at location /var/www.example. Let's create that directory:

root@zeus:~# mkdir /var/www/example

and create a simple html index file in this folder:

root@zeus:~# vi /var/www/example/index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Hello World</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

save and exit.

Now enable the site:

root@zeus:~# a2ensite vhosts-default
Enabling site vhosts-default.
To activate the new configuration, you need to run:
  systemctl reload apache2

Check that the syntax in the configuration file is OK:

root@zeus:~# apachectl -t
Syntax OK

Restart apache2:

root@zeus:~# systemctl restart apache2

Now since I'm not the owner of example.com (and this is just for demoing purposes) I will have to put temporary entries in my client computer's hosts file to be able to access the site. I will use Windows here as a client and will put entries in the C:\Windows\System32\drivers\etc\hosts file. Make sure you edit the file as Administrator to later be able to save the file, put in your servers IP address, mine was 192.168.1.16, change to your IP, you can find out the current ip with the command ifconfig in Ubuntu.

Edit C:\Windows\System32\drivers\etc\hosts with your apache server's current IP:

192.168.1.16            example.se
192.168.1.16            www.example.se
192.168.1.16            example.com
192.168.1.16            www.example.com

Point your browser to any of the domain names above with normal http and voila! we got served with the index page:

Now let's configure https as well, edit and add the following to our vhosts-default.conf file:

root@zeus:~# vi /etc/apache2/sites-enabled/vhosts-default.conf

<IfModule mod_ssl.c>
        <VirtualHost *:443>
                ServerName example.com
                ServerAlias example.se
                ServerAlias www.example.se
                Redirect permanent / https://www.example.com
                SSLEngine on
                SSLCertificateFile /etc/apache2/ssl-stuff/Example.crt
                SSLCertificateKeyFile /etc/apache2/ssl-stuff/Example.key
        </VirtualHost>
        <VirtualHost *:443>
                ServerName www.example.com
                DocumentRoot /var/www/example
                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined
                SSLEngine on
                SSLCertificateFile /etc/apache2/ssl-stuff/Example.crt
                SSLCertificateKeyFile /etc/apache2/ssl-stuff/Example.key
                <Directory /var/www/example>
                        Options Indexes FollowSymLinks
                        AllowOverride All
                        Require all granted
                </Directory>
        </VirtualHost>
</IfModule>

Create the directory ssl-stuff:

root@zeus:~# mkdir /etc/apache2/ssl-stuff

Now, I will copy the key and cert from another server into this folder, rename it to Example.crt and Example.key. This will of course give validation error in the browser since the cert is for another domain, but it will work for demoing purposes:

root@zeus:~# scp [email protected]:/home/jbilander/Example.crt /etc/apache2/ssl-stuff/
root@zeus:~# scp [email protected]:/home/jbilander/Example.key /etc/apache2/ssl-stuff/
root@zeus:~# scp [email protected]:/home/jbilander/Comodo_CA_bundle.crt /etc/apache2/ssl-stuff/

root@zeus:~# cd /etc/apache2/ssl-stuff/

root@zeus:/etc/apache2/ssl-stuff# ls -al
total 31
drwxr-xr-x 2 root root    5 Jan 16 14:15 .
drwxr-xr-x 9 root root   13 Jan 16 14:03 ..
-rw-r--r-- 1 root root 4104 Jan 16 14:15 Comodo_CA_bundle.crt
-rw-r--r-- 1 root root 6062 Jan 16 14:12 Example.crt
-rw-r--r-- 1 root root 1700 Jan 16 14:13 Example.key

Make sure the key is secured only to read access for root:

root@zeus:/etc/apache2/ssl-stuff# chmod 400 Example.key
root@zeus:/etc/apache2/ssl-stuff# ls -al
total 31
drwxr-xr-x 2 root root    5 Jan 16 14:15 .
drwxr-xr-x 9 root root   13 Jan 16 14:03 ..
-rw-r--r-- 1 root root 4104 Jan 16 14:15 Comodo_CA_bundle.crt
-rw-r--r-- 1 root root 6062 Jan 16 14:12 Example.crt
-r-------- 1 root root 1700 Jan 16 14:13 Example.key

Since SSLCertificateChainFile is deprecated for Apache 2.4.8 and later, I appended the CA_bundle.crt to my signed crt to get a complete chain.

root@zeus:/etc/apache2/ssl-stuff# cat Comodo_CA_bundle.crt >> Example.crt

root@zeus:/etc/apache2/ssl-stuff# cd
root@zeus:~#

Verify that the new config file is OK:

root@zeus:~# apachectl -t
Syntax OK

Restart apache2:

root@zeus:~# systemctl restart apache2

Now try to browse to https://example.com

Of course we get a warning here since the certificate is for another domain but by clicking Advanced -> Proceed to example.com (unsafe) we can verify the index page is served through https from the server, and that we get redirected to https://www.example.com

Now it just a matter of getting a signed certificate for your domain, I use this service:

https://www.ssls.com/ (PositiveSSL Multi-Domain)

and when ordering I add the subdomain git as well.

To check what domains the certificate is signed for:

root@zeus:/etc/apache2/ssl-stuff# openssl x509 -in Example.crt -text -noout

...
X509v3 Subject Alternative Name:
    DNS:www.creang.com, DNS:creang.com, DNS:git.creang.com

and then put in an A-record in DNS to point your domain to your servers public static IP.

All done!!! Now time to grab some coffee :)


Complete vhosts-default.conf file:

<VirtualHost *:80>
        ServerName example.com
        ServerAlias example.se
        ServerAlias www.example.se
        Redirect permanent / http://www.example.com
</VirtualHost>
<VirtualHost *:80>
        ServerName www.example.com
        DocumentRoot /var/www/example
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        <Directory /var/www/example>
                Options Indexes FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>
</VirtualHost>
<IfModule mod_ssl.c>
        <VirtualHost *:443>
                ServerName example.com
                ServerAlias example.se
                ServerAlias www.example.se
                Redirect permanent / https://www.example.com
                SSLEngine on
                SSLCertificateFile /etc/apache2/ssl-stuff/Example.crt
                SSLCertificateKeyFile /etc/apache2/ssl-stuff/Example.key
        </VirtualHost>
        <VirtualHost *:443>
                ServerName www.example.com
                DocumentRoot /var/www/example
                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined
                SSLEngine on
                SSLCertificateFile /etc/apache2/ssl-stuff/Example.crt
                SSLCertificateKeyFile /etc/apache2/ssl-stuff/Example.key
                <Directory /var/www/example>
                        Options Indexes FollowSymLinks
                        AllowOverride All
                        Require all granted
                </Directory>
        </VirtualHost>
</IfModule>
⚠️ **GitHub.com Fallback** ⚠️