blob: d042dd9bb74be7e1d97b85b7b574f9e6de7f5adc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# Apache httpd 2.4 configuration for cgit.
#
# 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.
#
# Paths assumed below, edit them to match your install.
#   cgit CGI binary   /usr/lib/cgit/cgit.cgi
#   static assets     /usr/share/cgit  (cgit.css cgit.js cgit.png favicon.ico robots.txt)
#   cgit config       /etc/cgitrc
#   public URL        https://git.example.org/  (cgit at the domain root)
#
# cgit is one CGI executable. It learns the repository and the page from
# PATH_INFO and reads page options such as h= and id= from QUERY_STRING.
# ScriptAlias runs the binary and forwards the trailing path as PATH_INFO, so
# no extra path tuning is needed. cgit builds its own link base from
# SCRIPT_NAME. The five static assets are served straight off disk. mod_alias
# resolves Alias and ScriptAlias in order and the first match wins, so the
# static Alias lines come before the catch-all ScriptAlias to stop the two
# routes from shadowing each other.


# --- Required modules -------------------------------------------------------
# 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
# rather than editing these lines. The guards make double-loading harmless.
<IfModule !mod_cgid.c>
    LoadModule cgid_module  modules/mod_cgid.so
</IfModule>
<IfModule !mod_alias.c>
    LoadModule alias_module modules/mod_alias.so
</IfModule>
<IfModule !mod_env.c>
    LoadModule env_module   modules/mod_env.so
</IfModule>
<IfModule !mod_headers.c>
    LoadModule headers_module modules/mod_headers.so
</IfModule>


# --- 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
# than editing it, since deleting only the Redirect line would leave a vhost
# that serves nothing.
<VirtualHost *:80>
    ServerName git.example.org

    ErrorLog  /var/log/apache2/cgit_error.log
    CustomLog /var/log/apache2/cgit_access.log combined

    Redirect permanent / https://git.example.org/
</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.
<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.
    SSLEngine on
    SSLCertificateFile    /etc/ssl/certs/git.example.org.crt
    SSLCertificateKeyFile /etc/ssl/private/git.example.org.key

    # 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.
    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.
    # cgit.css and cgit.js are the paths cgit's HTML points at by default, so
    # if you relocate the assets update both these Alias targets and the css,
    # js, logo and favicon settings in cgitrc to agree.
    Alias /cgit.css    /usr/share/cgit/cgit.css
    Alias /cgit.js     /usr/share/cgit/cgit.js
    Alias /cgit.png    /usr/share/cgit/cgit.png
    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.
    #
    # The trailing slash on cgit.cgi/ is load bearing. It tells Apache that
    # cgit.cgi is the program and the rest of the URL is PATH_INFO. So a
    # request for /torvalds/linux/tree/kernel?h=next runs the binary with
    # PATH_INFO set to /torvalds/linux/tree/kernel and QUERY_STRING set to
    # 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 ---------------
# To serve cgit at https://git.example.org/cgit/ instead of the root, change
# the ScriptAlias to
#     ScriptAlias /cgit/ /usr/lib/cgit/cgit.cgi/
# and move the static assets under the same prefix, for example
#     Alias /cgit/cgit.css /usr/share/cgit/cgit.css
# SCRIPT_NAME then becomes /cgit and cgit auto-detects it. If links come out
# wrong, pin the base in cgitrc with virtual-root=/cgit.