Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

Apache VirtualHost

{: .warning } You CANNOT test or use https until you have a certificate! You will also need to configure ssl! http is required first, so you can configure ssl

DNS

A Record

I point something.com to x.x.x.x IP

CNAME record

I point my CNAME of www.something.com to something.com

Apache VirtualHost

Assume your site is called “somesite.com”.

Install Apache

https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-22-04

sudo apt install apache2 

Disable the Default Site

sudo a2dissite 000-default

Copy Default Site Config

sudo mv /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/somesite.com.conf
sudo vim /etc/apache2/sites-available/somesite.com.conf

Allow Ports you want

I want to enable port 80, 443 and 4000. 80 and 4000 will be over http, not encrypted.

vim /etc/apache2/ports.conf
Listen 0.0.0.0:80
Listen 0.0.0.0:4000

<IfModule ssl_module>
        Listen 0.0.0.0:443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 0.0.0.0:443
</IfModule>

Create Directories and Logs

sudo mkdir /var/www/logs/
sudo mkdir /var/www/html/somesite.com/
sudo mkdir /var/www/html/grimoire.somesite.com/
sudo touch /var/www/logs/somesite.com.error.log
sudo touch /var/www/logs/somesite.com.access.log

Create port 80 Virtual Host

The *:port line says listen on any, and that port. I have specified ipv4 only in the ports.conf above.

#----------------------------------------
# somesite.com:80
#----------------------------------------
<VirtualHost *:80>
  ServerAdmin admin@somesite.com
  ServerName somesite.com
  ServerAlias www.somesite.com

  DirectoryIndex index.php index.html index.cgi
  DocumentRoot /var/www/html/somesite.com

  AddHandler cgi-script .cgi
  <Location /cgi-bin>
    Options +ExecCGI
  </Location>

  <Directory /var/www/html/somesite.com>
    Order allow,deny
    Allow from all
    Require all granted
  </Directory>

  RewriteEngine On
  RewriteCond %{HTTPS} off [OR]
  RewriteCond %{HTTP_HOST} ^www\. [NC]
  RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
  RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

  ErrorLog /var/www/logs/somesite.com.error.log
  CustomLog /var/www/logs/somesite.com.access.log combined
</VirtualHost>

Create port 443 Virtual Host

I do not need to rewrite 443 to 443, but I still want www.something.com redirected to something.com

I also want to serve files that end in .cgi and make them executable. This might be outdated, but still works. CGI is another topic on security, but you can use any backend script to respond as a web app. There are more modern ways now.

#----------------------------------------
# somesite.com:443
#----------------------------------------
<VirtualHost *:443>
  ServerAdmin admin@somesite.com
  ServerName somesite.com
  ServerAlias www.somesite.com

  DirectoryIndex index.php index.html index.cgi
  DocumentRoot /var/www/html/somesite.com

  ScriptAlias "/cgi-bin/" "/var/www/html/somesite.com/cgi-bin/"
  <Location /cgi-bin>
    AddHandler cgi-script .cgi
    Options +ExecCGI
  </Location>

  <Directory /var/www/html/somesite.com>
    Order allow,deny
    Allow from all
    Require all granted
  </Directory>

  RewriteEngine On
  RewriteCond %{HTTPS} off [OR]
  RewriteCond %{HTTP_HOST} ^www\. [NC]
  RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
  RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

  SSLEngine on
  SSLCertificateFile /etc/letsencrypt/live/somesite.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/somesite.com/privkey.pem

  ErrorLog /var/www/logs/somesite.com.error.log
  CustomLog /var/www/logs/somesite.com.access.log combined
</VirtualHost>

Create the Subdomain and Port

I have a private wiki that does not use SSL at http://subdomain.something.com:4000

#----------------------------------------
# grimoire.somesite.com:4000
#----------------------------------------

<VirtualHost *:4000>
  ServerAdmin admin@somesite.com
  ServerName grimoire.somesite.com
  #ServerAlias grimoire.somesite.com

  DirectoryIndex index.html
  DocumentRoot /var/www/html/grimoire.somesite.com

  <Directory /var/www/html/grimoire.somesite.com>
    Order allow,deny
    Allow from all
    Require all granted
  </Directory>

  ErrorLog /var/www/logs/grimoire.somesite.com.error.log
  CustomLog /var/www/logs/grimoire.somesite.com.access.log combined
</VirtualHost>

Enable the Modules

We are using auth_digest, headers and rewrite so…

sudo a2enmod auth_digest headers rewrite

Enable the New Config

sudo a2ensite somesite.com

Test the Configs, Restart

{: .warning } Again, you cannot configure/test/restart until you complete SSL.

sudo apache2ctl -t
sudo systemctl restart apache2
sudo apache2ctl -S

Review Headers

(1:2311)# curl -sIv http://grimoire.somesite.com
* Rebuilt URL to: http://grimoire.somesite.com/
*   Trying 162.243.46.68...
* TCP_NODELAY set
* Connected to grimoire.somesite.com (162.243.46.68) port 80 (#0)
> HEAD / HTTP/1.1
> Host: grimoire.somesite.com
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Mon, 14 Aug 2023 12:22:02 GMT
Date: Mon, 14 Aug 2023 12:22:02 GMT
< Server: Apache
Server: Apache
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< x-Frame-Options: SAMEORIGIN
x-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Content-Security-Policy: default-src 'self'; font-src *;img-src * data:; script-src *; style-src *;
Content-Security-Policy: default-src 'self'; font-src *;img-src * data:; script-src *; style-src *;
< Referrer-Policy: strict-origin
Referrer-Policy: strict-origin
< Last-Modified: Sat, 11 Jan 2020 23:45:23 GMT
Last-Modified: Sat, 11 Jan 2020 23:45:23 GMT
< ETag: "157-59be5d603f2dd"
ETag: "157-59be5d603f2dd"
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Content-Length: 343
Content-Length: 343
< Vary: Accept-Encoding
Vary: Accept-Encoding
< Content-Type: text/html
Content-Type: text/html

<
* Connection #0 to host grimoire.somesite.com left intact

Note, you CANNOT test or use https until you have a certificate!

(1:2312)# curl -sIv https://somesite.com
* Rebuilt URL to: https://somesite.com/
*   Trying 162.243.46.68...
* TCP_NODELAY set
* Connected to somesite.com (162.243.46.68) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
* TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=somesite.com
*  start date: Jul  2 20:48:16 2023 GMT
*  expire date: Sep 30 20:48:15 2023 GMT
*  subjectAltName: host "somesite.com" matched cert's "somesite.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
> HEAD / HTTP/1.1
> Host: somesite.com
> User-Agent: curl/7.58.0
> Accept: */*
>
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Mon, 14 Aug 2023 12:22:27 GMT
Date: Mon, 14 Aug 2023 12:22:27 GMT
< Server: Apache
Server: Apache
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< x-Frame-Options: SAMEORIGIN
x-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Content-Security-Policy: default-src 'self'; font-src *;img-src * data:; script-src *; style-src *;
Content-Security-Policy: default-src 'self'; font-src *;img-src * data:; script-src *; style-src *;
< Referrer-Policy: strict-origin
Referrer-Policy: strict-origin
< Strict-Transport-Security: max-age=31536000; includeSubDomains
Strict-Transport-Security: max-age=31536000; includeSubDomains
< Link: <https://somesite.com/wp-json/>; rel="https://api.w.org/"
Link: <https://somesite.com/wp-json/>; rel="https://api.w.org/"
< Link: <https://somesite.com/>; rel=shortlink
Link: <https://somesite.com/>; rel=shortlink
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8

<
* Connection #0 to host somesite.com left intact