diff options
context:
space:
mode:
Diffstat (limited to 'custom/servers/apache.conf')
-rw-r--r--custom/servers/apache.conf212
1 file changed, 157 insertions, 55 deletions
diff --git a/custom/servers/apache.conf b/custom/servers/apache.conf
index d042dd9..7ff3bab 100644
--- a/custom/servers/apache.conf
+++ b/custom/servers/apache.conf
@@ -1,9 +1,15 @@
# Apache httpd 2.4 configuration for cgit.
#
+# This is a complete httpd.conf rather than a vhost snippet, so nothing here
+# is included from elsewhere and no distro base config is assumed. Check it
+# and run it with
+# httpd -t -f /path/to/apache.conf # check the syntax
+# httpd -f /path/to/apache.conf # run it
+# To use it as an ordinary vhost file instead, drop everything above the
+# virtual hosts and let your distro's httpd.conf supply it.
+#
# Apache runs the cgit.cgi binary directly through mod_cgid, so no FastCGI
-# bridge is needed. Drop this file in your vhost directory, for example
-# /etc/apache2/sites-available/cgit.conf on Debian and Ubuntu or
-# /etc/httpd/conf.d/cgit.conf on RHEL and Fedora, then enable it and reload.
+# bridge is needed.
#
# Paths assumed below, edit them to match your install.
# cgit CGI binary /usr/lib/cgit/cgit.cgi
@@ -21,26 +27,134 @@
# routes from shadowing each other.
-# --- Required modules -------------------------------------------------------
+# ServerRoot is what every relative path below resolves against, including the
+# module paths. It is /etc/httpd on RHEL and Fedora and /etc/apache2 on Debian
+# and Ubuntu, where the modules live in /usr/lib/apache2/modules and the
+# LoadModule lines need that absolute path instead of the relative one.
+ServerRoot /etc/httpd
+PidFile /var/run/httpd.pid
+
+# Where Apache puts its runtime scratch, the mutexes and the SSL session
+# cache. It is /var/run/httpd on RHEL and Fedora and /var/run/apache2 on
+# Debian and Ubuntu. The directory has to exist and be writable before Apache
+# starts, which is normally the packaging's job.
+DefaultRuntimeDir /var/run/httpd
+
+Listen 80
+Listen 443
+
+# Set globally so Apache does not have to guess a name at startup, which it
+# warns about. Each vhost overrides it with its own.
+ServerName git.example.org
+
+# Drop the version number from the Server header and from error pages.
+ServerTokens Prod
+ServerSignature Off
+
+
# mod_cgid suits the threaded MPMs that ship by default. Use mod_cgi instead
-# only on the old prefork MPM. mod_alias provides Alias and ScriptAlias and
-# mod_env provides SetEnv. On Debian and Ubuntu run a2enmod cgid alias env
+# only on the old prefork MPM. mod_alias provides Alias and ScriptAlias,
+# mod_env provides SetEnv, and the rest are the core pieces a standalone
+# config cannot do without. On Debian and Ubuntu run
+# a2enmod cgid alias env headers expires ssl
# rather than editing these lines. The guards make double-loading harmless.
-<IfModule !mod_cgid.c>
- LoadModule cgid_module modules/mod_cgid.so
+<IfModule !mpm_event_module>
+ LoadModule mpm_event_module modules/mod_mpm_event.so
+</IfModule>
+<IfModule !unixd_module>
+ LoadModule unixd_module modules/mod_unixd.so
+</IfModule>
+<IfModule !authz_core_module>
+ LoadModule authz_core_module modules/mod_authz_core.so
</IfModule>
-<IfModule !mod_alias.c>
- LoadModule alias_module modules/mod_alias.so
+<IfModule !log_config_module>
+ LoadModule log_config_module modules/mod_log_config.so
</IfModule>
-<IfModule !mod_env.c>
- LoadModule env_module modules/mod_env.so
+<IfModule !mime_module>
+ LoadModule mime_module modules/mod_mime.so
</IfModule>
-<IfModule !mod_headers.c>
- LoadModule headers_module modules/mod_headers.so
+<IfModule !alias_module>
+ LoadModule alias_module modules/mod_alias.so
</IfModule>
+<IfModule !cgid_module>
+ LoadModule cgid_module modules/mod_cgid.so
+</IfModule>
+<IfModule !env_module>
+ LoadModule env_module modules/mod_env.so
+</IfModule>
+<IfModule !headers_module>
+ LoadModule headers_module modules/mod_headers.so
+</IfModule>
+<IfModule !expires_module>
+ LoadModule expires_module modules/mod_expires.so
+</IfModule>
+# TLS. Delete these two along with the HTTPS vhost to run plain HTTP only.
+# mod_socache_shmcb backs the SSL session cache and mod_ssl expects it.
+<IfModule !socache_shmcb_module>
+ LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
+</IfModule>
+<IfModule !ssl_module>
+ LoadModule ssl_module modules/mod_ssl.so
+</IfModule>
+
+
+# The user Apache drops to after binding the ports. It is apache on RHEL and
+# Fedora, www-data on Debian and Ubuntu, and http on Arch.
+User apache
+Group apache
+
+
+# The combined format comes from the distro config rather than from Apache
+# itself, so a standalone config has to define it before any CustomLog uses it.
+LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+ErrorLog /var/log/apache2/error.log
+LogLevel warn
+
+
+# The usual "TypesConfig conf/mime.types" would pull in a second file. Exactly
+# five static files are served off disk, so their types are declared here
+# instead. Everything else Apache returns comes from cgit, which sets its own
+# Content-Type.
+AddType text/css .css
+AddType text/javascript .js
+AddType image/png .png
+AddType image/vnd.microsoft.icon .ico
+AddType text/plain .txt
+
+
+# Deny the whole filesystem, then open only the two directories cgit needs.
+# Without this a misplaced Alias could expose anything readable on the host.
+<Directory />
+ AllowOverride None
+ Require all denied
+</Directory>
+
+# The static asset directory, read only.
+<Directory "/usr/share/cgit">
+ Options None
+ AllowOverride None
+ Require all granted
+
+ # These assets rarely change, so let browsers cache them.
+ <IfModule mod_expires.c>
+ ExpiresActive On
+ ExpiresDefault "access plus 30 days"
+ </IfModule>
+</Directory>
+
+# The cgit binary.
+<Directory "/usr/lib/cgit">
+ # Allow CGI execution here. ScriptAlias implies it, stating it makes the
+ # intent clear.
+ Options +ExecCGI
+ # Run cgit.cgi as a CGI even if it is ever reached through a plain Alias
+ # rather than ScriptAlias.
+ SetHandler cgi-script
+ AllowOverride None
+ Require all granted
+</Directory>
-# --- Plain HTTP virtual host ------------------------------------------------
# This vhost only bounces plain HTTP up to HTTPS. It serves no cgit itself,
# every cgit directive lives in the HTTPS vhost below. To run without TLS for
# now, convert the HTTPS vhost to port 80 and delete this whole block rather
@@ -56,39 +170,44 @@
</VirtualHost>
-# --- HTTPS virtual host, this one serves cgit -------------------------------
-# To run without TLS for now, change this opening line to <VirtualHost *:80>,
-# delete the three SSL lines, and delete the port 80 vhost above so there is
-# only one vhost. Everything else stays the same.
+# The vhost that serves cgit. To run without TLS for now, change this opening
+# line to port 80, delete the SSL lines, and delete the vhost above so there
+# is only one. Everything else stays as it is.
<VirtualHost *:443>
ServerName git.example.org
ErrorLog /var/log/apache2/cgit_ssl_error.log
CustomLog /var/log/apache2/cgit_ssl_access.log combined
- # TLS needs mod_ssl (a2enmod ssl). Point these at your certificate.
+ # Point these at your certificate.
SSLEngine on
SSLCertificateFile /etc/ssl/certs/git.example.org.crt
SSLCertificateKeyFile /etc/ssl/private/git.example.org.key
+ # Subtractive rather than naming the versions to keep, since a mod_ssl
+ # built before TLS 1.3 rejects the +TLSv1.3 token outright and refuses to
+ # start. This form enables 1.3 wherever it exists.
+ SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
# Which config cgit reads. It falls back to the compiled-in /etc/cgitrc,
# the same path used here, but setting it makes the location explicit and
# lets you point at a per-vhost file later.
SetEnv CGIT_CONFIG /etc/cgitrc
- # --- Security headers (needs mod_headers, a2enmod headers) --------------
- # Set here, not in cgit, so they also cover the static assets Apache
- # serves. script-src stays self because cgit loads only its own cgit.js,
- # and style-src allows inline for the diffstat bars. If you enable the
- # gravatar or libravatar avatar filter, add its host to img-src, for
- # example https://www.gravatar.com.
+ # The only request body cgit ever reads is the auth-filter login form, and
+ # it stops after 4096 bytes. Nothing else here accepts an upload.
+ LimitRequestBody 65536
+
+ # Security headers are set here, not in cgit, so they also cover the static
+ # assets Apache serves. script-src stays self because cgit loads only its
+ # own cgit.js, and style-src allows inline for the diffstat bars. If you
+ # enable the gravatar or libravatar avatar filter, add its host to img-src,
+ # for example https://www.gravatar.com.
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'; base-uri 'none'; frame-ancestors 'self'"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "no-referrer"
# Enable only once you serve HTTPS exclusively, since it is hard to undo.
#Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
- # --- Static assets, served directly by Apache ---------------------------
# These five files are the only things served off disk. Each Alias maps
# one URL to one file. Because they come before the ScriptAlias below, a
# request for /cgit.css is answered from disk and never reaches cgit.
@@ -101,22 +220,6 @@
Alias /favicon.ico /usr/share/cgit/favicon.ico
Alias /robots.txt /usr/share/cgit/robots.txt
- # Apache 2.4 denies filesystem access by default, so open the asset
- # directory for reading.
- <Directory "/usr/share/cgit">
- Options None
- AllowOverride None
- Require all granted
-
- # Optional. These assets rarely change, so let browsers cache them.
- # Needs mod_expires (a2enmod expires). Safe to delete this block.
- <IfModule mod_expires.c>
- ExpiresActive On
- ExpiresDefault "access plus 30 days"
- </IfModule>
- </Directory>
-
- # --- cgit, the catch-all ------------------------------------------------
# ScriptAlias maps a URL prefix to a path, marks it executable, and
# forwards the rest of the URL as PATH_INFO. Mapping / makes cgit the
# handler for every URL the static Aliases above did not already claim.
@@ -128,21 +231,20 @@
# h=next. cgit derives its link base from SCRIPT_NAME, which at the domain
# root is / and needs no tuning. For a sub-path install see the note below.
ScriptAlias / /usr/lib/cgit/cgit.cgi/
-
- <Directory "/usr/lib/cgit">
- # Allow CGI execution here. ScriptAlias implies it, stating it makes
- # the intent clear.
- Options +ExecCGI
- # Run cgit.cgi as a CGI even if it is ever reached through a plain
- # Alias rather than ScriptAlias.
- SetHandler cgi-script
- AllowOverride None
- Require all granted
- </Directory>
</VirtualHost>
-# --- Sub-path install, only if cgit is not at the domain root ---------------
+# The SSL session cache is a global mod_ssl setting, so it sits outside the
+# vhosts. Resumption keeps a browser paging through a repository from redoing
+# a full handshake on every connection. Delete along with the HTTPS vhost if
+# you serve plain HTTP.
+<IfModule mod_ssl.c>
+ # Relative, so it lands in DefaultRuntimeDir and follows it across distros.
+ SSLSessionCache "shmcb:ssl_scache(512000)"
+ SSLSessionCacheTimeout 300
+</IfModule>
+
+
# To serve cgit at https://git.example.org/cgit/ instead of the root, change
# the ScriptAlias to
# ScriptAlias /cgit/ /usr/lib/cgit/cgit.cgi/