1 ## To convert this file to apache.conf using the current Girocco::Config
2 ## values either do "make" or "make apache.conf" or ./make-apache-conf.sh
4 # This is an example configuration of a virtualhost running Girocco, as set up
5 # at repo.or.cz; unfortunately, somewhat independent from Girocco::Config.
6 # It is not essential for Girocco to use a special virtualhost, however.
8 <IfModule rewrite_module>
10 RewriteCond %{SERVER_NAME} !=@@httpdnsname@@
11 RewriteRule ^ http://@@httpdnsname@@%{REQUEST_URI} [L,NE,R=301]
12 <IfDefine @@TLSHost@@>
13 RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
14 RewriteCond %{SERVER_NAME} =@@httpdnsname@@
15 RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,NE,R=301]
19 Alias /.well-known/acme-challenge/ @@certsdir@@/acme/.well-known/acme-challenge/
20 <Directory "@@certsdir@@/acme/.well-known/acme-challenge/">
34 # ---- BEGIN LINES TO DUPLICATE ----
36 ServerName @@httpdnsname@@
37 ServerAlias www.@@httpdnsname@@
40 # This is the standard "combined" log format modified as follows:
41 # the REMOTE_USER (%u) has double-quotes around it
42 # the received time is shown as [YYYY-mm-dd_HH:MM:SS +hhmm] (almost RFC 3339 format)
43 # -- this is one character shorter than the default but sorts so much better
44 # when the logio_module is present (almost always) the %O value is prefixed with:
45 # %I-> -- <bytes-received-including-request-and-headers>
46 # the first line of the request ("%r") is prefixed with
47 # %X%k: -- <connection-status><keepalive-request-num>
48 # <keepalive-request-num> will be omitted if apache < 2.2.11
49 # these fields are added to the end:
50 # :%{local}p -- :<actual-server-port>
51 # %Dus -- <request-time-in-microseconds>
52 # "%o{Content-Range}" -- <outgoing Content-Range header>
54 LogFormat "%h %l \"%u\" %{[%F_%T %z]}t %X%k:\"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" :%{local}p %Dus \"%{Content-Range}o\"" girocco
56 <IfVersion !>= 2.2.11>
57 LogFormat "%h %l \"%u\" %{[%F_%T %z]}t %X:\"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" :%{local}p %Dus \"%{Content-Range}o\"" girocco
59 <IfModule logio_module>
60 # %I and %O are only available with the logio_module
62 LogFormat "%h %l \"%u\" %{[%F_%T %z]}t %X%k:\"%r\" %>s %I->%O \"%{Referer}i\" \"%{User-Agent}i\" :%{local}p %Dus \"%{Content-Range}o\"" girocco
64 <IfVersion !>= 2.2.11>
65 LogFormat "%h %l \"%u\" %{[%F_%T %z]}t %X:\"%r\" %>s %I->%O \"%{Referer}i\" \"%{User-Agent}i\" :%{local}p %Dus \"%{Content-Range}o\"" girocco
69 # If your distribution does not set APACHE_LOG_DIR before
70 # starting Apache you will need to edit the next two directives
71 ErrorLog "/var/log/apache2/repo-dev-error.log"
72 CustomLog "/var/log/apache2/repo-dev-access.log" girocco
74 <IfModule mime_magic_module>
75 # Avoid spurious Content-Type values when git-http-backend
76 # fails to provide a Content-Type header in its output
77 MimeMagicFile /dev/null
80 DocumentRoot @@webroot@@
81 <Directory @@webroot@@>
82 # Add MultiViews only if pages are truly
83 # offered in more than a single language
84 # FollowSymLinks or SymLinksIfOwnerMatch is required for .htaccess files
85 Options FollowSymLinks
86 # FileInfo (or All) must be enabled to activate .htaccess file mod_rewrite rules
99 # The non-mod_rewrite items are handled first where the magic /[bchrw]
100 # prefix always forces selection of the prefix-indicated cgi handler.
102 ScriptAlias /w @@cgiroot@@/gitweb.cgi
103 ScriptAlias /b @@cgiroot@@/bundles.cgi
104 AliasMatch ^/h/(.*\.html)$ @@cgiroot@@/html/$1
105 ScriptAliasMatch ^/(?!(?i)gitweb\.cgi|bundles\.cgi|html\.cgi(?:/|$))([^/]+\.cgi(?:/.*)?)$ @@cgiroot@@/$1
107 # Any requests without the magic /[bchrw] are treated as Git requests if they
108 # are one of the few possible Git URLs otherwise they go to bundles or gitweb
110 # Change the setting of $SmartHTTPOnly in Girocco::Config.pm to
111 # change whether or not non-smart HTTP fetch access will be allowed.
113 <IfDefine !@@SmartHTTPOnly@@>
114 # This accelerates non-smart HTTP access to loose objects, packs and info
116 "(?x)^/(?![bchw]/)(?:r/)? \
117 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?)(?:\.git)?/( \
119 objects/info/alternates | \
120 objects/info/http-alternates | \
121 objects/info/packs | \
122 objects/[0-9a-f]{2}/[0-9a-f]{38} | \
123 objects/pack/pack-[0-9a-f]{40}\.(?:pack|idx) )$" \
124 @@reporoot@@/$1.git/$2
127 # SetEnv GIT_HTTP_BACKEND_BIN to override Config.pm $git_http_backend_bin
128 ScriptAlias /r/ @@basedir@@/bin/git-http-backend-verify/
131 "(?x)^/(?![bchrw]/) \
132 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?)(?:\.git)?/( \
136 [a-zA-Z0-9][a-zA-Z0-9+._-]*\.bundle )$" \
137 @@basedir@@/bin/git-http-backend-verify/$1.git/$2
139 # Everything else off to bundles.cgi or gitweb.cgi
141 "(?x)^/(?![bchrw]/) \
142 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?\.git/bundles)$" \
143 @@cgiroot@@/bundles.cgi/$1
145 "(?x)^/(?![bchrw]/) \
146 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?\.git(?!/bundles)(?:/.*)?)$" \
147 @@cgiroot@@/gitweb.cgi/$1
149 # mod_rewrite is not strictly required for gitweb and fetch access, but
150 # if it's not available the trailing ".git" is never optional for
151 # gitweb, the leading /h is always required for *.html, snapshots are
152 # not throttled, some bogus Git http protocol requests will not be
153 # detected early and, if non-smart HTTP is allowed, access to the
154 # /info/refs file will not be accelerated in non-smart HTTP mode.
156 <IfModule rewrite_module>
159 # Snapshot/blob_plain requests are only allowed via the PATH_INFO mechanism
160 RewriteCond %{QUERY_STRING} (^|[&;])a=(?:snapshot|blob_plain)([&;]|$) [NC]
161 RewriteRule .? - [NS,F,L]
163 # Redirect snapshot requests to snapshot.cgi
165 "(?x)^/(?![bchr]/)(?:w/)? \
166 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?\.git/ \
167 snapshot(?:/.*)?)$" \
168 @@cgiroot@@/snapshot.cgi/$1 [NS,L,H=cgi-script]
170 # Detect blob_plain requests with is_blob_plain
172 "(?x)^/(?![bchr]/)(?:w/)? \
173 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?\.git)/ \
174 blob_plain(?:/.*)?$" \
175 - [E=is_blob_plain:$1]
177 # Reject blob_plain requests if .no_blob_plain file exists and is not zero bytes
178 RewriteCond "%{ENV:is_blob_plain}" !=""
179 RewriteCond "@@reporoot@@/%{ENV:is_blob_plain}/.no_blob_plain" -s
180 RewriteRule ^ - [NS,F]
182 # Reject blob_plain requests if .no_blob_plain file exists AND mismatched Referer
183 # We require the referer host and port and git project to match the current request
184 RewriteCond "%{ENV:is_blob_plain}" !=""
185 RewriteCond "@@reporoot@@/%{ENV:is_blob_plain}/.no_blob_plain" -f
186 RewriteRule ^ - [C,E=is_blob_ref:1]
187 RewriteRule ^ - [C,E=ref_host:]
188 RewriteRule ^ - [E=ref_path:]
189 RewriteCond "%{ENV:is_blob_ref}" =1
190 RewriteCond "%{HTTP_REFERER}" "^https?://(?:[^@/]*@)?([^@:/?#]+(?::[0-9]+)?)"
191 RewriteRule ^ - [E=ref_host:%1]
192 RewriteCond "%{ENV:is_blob_ref}" =1
193 RewriteCond "%{HTTP_REFERER}" "^https?://(?:[^@/]*@)?[^@:/?#]+(?::[0-9]*)?(?:/w)?(.*)$"
194 RewriteRule ^ - [E=ref_path:%1]
195 RewriteCond "%{ENV:is_blob_ref}" =1
196 RewriteCond "@%{HTTP_HOST}=%{ENV:ref_host}@" "!^@([^=]*)=\1@$" [NC,OR]
197 RewriteCond "@/%{ENV:is_blob_plain}=%{ENV:ref_path}" "!^@([^=]*)=\1(?:[/?#]|$)"
198 RewriteRule ^ - [NS,F]
200 # Make the leading /h optional for requests that name an existing .html template
201 RewriteCond @@webroot@@/$1 !-f
202 RewriteCond @@cgiroot@@/$1 !-f
203 RewriteCond @@cgiroot@@/html/$1 -s
205 ^/(?![bchrw]/)(.*\.html)$ \
208 # Redirect bare gitweb requests without .git that name an existing repo...
209 RewriteCond @@webroot@@/$2 !-f
210 RewriteCond @@cgiroot@@/$2 !-f
211 RewriteCond @@reporoot@@/$2.git/HEAD -s
213 "(?x)^/(?![bchr]/)((?:w/)?) \
214 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git))$" \
215 /$1$2.git [NS,L,R=301]
217 # Of the 11 possible Git protocol URLs (i.e. passed to git-http-backend-verify),
218 # 9 are only valid with GET/HEAD and the other two are only valid with POST
219 # Furthermore, 7 are only valid when non-smart is allowed and
220 # 1 is only valid when smart-only is enabled if it has the correct query string.
222 # These two always require POST
223 RewriteCond %{REQUEST_METHOD} !=POST
225 "(?x)^/(?![bchw]/)(?:r/)? \
226 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/(?: \
228 git-receive-pack )$" \
231 <IfDefine @@SmartHTTPOnly@@>
232 # These 7 are always forbidden when non-smart HTTP is disabled
234 "(?x)^/(?![bchw]/)(?:r/)? \
235 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/(?: \
237 objects/info/alternates | \
238 objects/info/http-alternates | \
239 objects/info/packs | \
240 objects/[0-9a-f]{2}/[0-9a-f]{38} | \
241 objects/pack/pack-[0-9a-f]{40}\.(?:pack|idx) )$" \
243 # This one is forbidden without the magic query string when non-smart is disabled
244 RewriteCond %{REQUEST_METHOD} !^(?:GET|HEAD)$ [OR]
245 RewriteCond %{QUERY_STRING} !(^|&)service=git-(?:upload|receive)-pack(&|$)
247 "(?x)^/(?![bchw]/)(?:r/)? \
248 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/ \
251 # This one requires GET (or HEAD)
252 RewriteCond %{REQUEST_METHOD} !^(?:GET|HEAD)$
254 "(?x)^/(?![bchw]/)(?:r/)? \
255 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/ \
256 [a-zA-Z0-9][a-zA-Z0-9+._-]*\.bundle $" \
260 <IfDefine !@@SmartHTTPOnly@@>
261 # These 9 require GET (or HEAD)
262 RewriteCond %{REQUEST_METHOD} !^(?:GET|HEAD)$
264 "(?x)^/(?![bchw]/)(?:r/)? \
265 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/(?: \
268 objects/info/alternates | \
269 objects/info/http-alternates | \
270 objects/info/packs | \
271 objects/[0-9a-f]{2}/[0-9a-f]{38} | \
272 objects/pack/pack-[0-9a-f]{40}\.(?:pack|idx) | \
273 [a-zA-Z0-9][a-zA-Z0-9+._-]*\.bundle )$" \
275 # This one can be accelerated when accessed with non-smart HTTP
276 RewriteCond %{REQUEST_METHOD} ^(?:GET|HEAD)$
277 RewriteCond %{QUERY_STRING} !(^|&)service=git-(?:upload|receive)-pack(&|$)
279 "(?x)^/(?![bchw]/)(?:r/)? \
280 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?)(?:\.git)?/ \
282 @@reporoot@@/$1.git/info/refs [NS,L]
286 <Directory @@reporoot@@>
287 Options FollowSymLinks
298 <IfModule rewrite_module>
299 # Everything fetched over the non-smart git http
300 # protocol should be an existing file. If the request
301 # is not for an existing file, just send back an error
302 # message without emitting anything into the error log.
305 RewriteCond @@reporoot@@/$1 !-f
306 RewriteRule ^(.*)$ - [NS,R=404,L]
310 <Directory @@cgiroot@@>
311 # FollowSymLinks or SymLinksIfOwnerMatch is required for .htaccess files
312 Options SymLinksIfOwnerMatch
313 # FileInfo must be enabled to activate .htaccess file mod_rewrite rules
314 AllowOverride FileInfo
333 <IfModule !mod_fastcgi.c>
334 <IfModule !mod_fcgid.c>
335 SetHandler cgi-script
339 # Note that in testing mod_fastcgi (in dynamic mode)
340 # was found to be slightly faster than mod_fcgid.
342 # However, we prefer mod_fcgid if both are available
343 # because we cannot control the server-global settings
344 # of mod_fastcgi's "FastCgiConfig" options.
346 # In order for gitweb.cgi to run reasonably well as a
347 # mod_fastcgi dynamic FastCGI application, the
348 # "FastCgiConfig" option "-idle-timeout" value needs to
349 # be increased from the default value of "30" to at
350 # least "120", preferably more like "300". But that
351 # will affect ALL dynamic mod_fastcgi applications on
352 # the ENTIRE server, not just gitweb.cgi. Additionally
353 # the "FastCgiConfig" "-restart" option probably ought
354 # to be set as well. Also, unfortunately, there is no
355 # mod_fastcgi option corresponding to mod_fcgid's
356 # MaxRequestsPerProcess option and gitweb.cgi running
357 # in FastCGI mode (without using FCGI::ProcManager) will
358 # always exit after serving 100 requests (a good thing).
360 # The alternative is to make gitweb.cgi a static
361 # mod_fastcgi application (the "FastCgiServer"
362 # directive), but then the number of running instances
363 # will be fixed at whatever value is chosen for the
364 # "-processes" option rather than being dynamically
365 # adjusted based on load and that's probably undesirable
366 # in most cases unless you run gitweb.cgi under a
367 # front-end that dynamically forks multiple copies of
368 # gitweb.cgi based on the current load. See the CPAN
369 # FCGI::ProcManager::Dynamic module for an example of
370 # how to do this in Perl:
372 # http://search.cpan.org/search?query=FCGI::ProcManager::Dynamic&mode=module
374 # So instead we prefer mod_fcgid because we can adjust
375 # the necessary options for good gitweb.cgi behavior
376 # while affecting only gitweb.cgi and having it remain
377 # a dynamic application whose total number of running
378 # instances is adjusted based on current server load.
380 <IfModule mod_fcgid.c>
381 SetHandler fcgid-script
383 <IfModule !mod_fcgid.c>
384 <IfModule mod_fastcgi.c>
385 SetHandler fastcgi-script
389 <FilesMatch ^(?!(?i)gitweb\.cgi$).*\.cgi$>
391 SetHandler cgi-script
402 <Directory @@cgiroot@@/html>
412 ForceType "text/html; charset=utf-8"
416 <IfModule mod_fcgid.c>
417 # mod_fcgid benefits from some additional config for gitweb.cgi
418 # gitweb.cgi has a hard-coded maximum of 100 requests
419 # and we do not want to give up too soon in case Git is lagging.
420 # Note that adding a 'MaxProcesses ...' option here may be valuable
421 # to limit the maximum number of gitweb.cgi processes that can be
422 # spawned (default is 100) -- perhaps to something much lower such
423 # as 1 or 2 times the number of CPU cores. Also note that in the
424 # unlikely event all the children finish their 100 requests at the
425 # same time, the server's FcgidSpawnScoreUpLimit (which defaults
426 # to 10 if not set) should be set to at least 3 times the
427 # MaxProcesses value chosen to allow them all to respawn
428 # immediately. FcgidSpawnScoreUpLimit MUST be at least twice the
429 # chosen MaxProcesses value (assuming FcgidTerminationScore is
430 # still set to the default 2) in order to allow any child at all to
431 # respawn immediately in this case without a delay.
432 FcgidCmdOptions @@cgiroot@@/gitweb.cgi \
433 MaxProcesses 8 MinProcesses 5 \
434 MaxRequestsPerProcess 100 IOTimeout 300
437 <Directory @@basedir@@/bin>
448 <Files git-http-backend-verify>
450 SetHandler cgi-script
462 # ---- END LINES TO DUPLICATE ----
467 # Change the setting of $TLSHost in Girocco::Config.pm to change
468 # whether or not the following https virtual host is enabled.
470 <IfDefine @@TLSHost@@>
472 # This is an example configuration of an https virtualhost running Girocco, as set
473 # up at repo.or.cz; unfortunately, completely independent from Girocco::Config.
474 # It is not essential for Girocco to use a special virtualhost, however.
475 # The Config.pm $httpspushurl variable needs to be defined to properly enable
479 # These certificate files will all be automatically generated, but the
480 # paths here may need to be corrected to match the paths
481 # (especially $certsdir) from Config.pm
483 SSLCertificateFile @@certsdir@@/acme/girocco_www_crt.pem
484 SSLCertificateKeyFile @@certsdir@@/acme/girocco_www_key.pem
485 SSLCertificateChainFile @@certsdir@@/acme/girocco_www_chain.pem
486 # When using a www server cert signed by a pre-trusted root, only
487 # the above three lines should be changed. Changing either of the
488 # below two lines will likely break https client authentication.
489 SSLCACertificateFile @@certsdir@@/girocco_root_crt.pem
490 SSLCADNRequestFile @@certsdir@@/girocco_client_crt.pem
493 SSLOptions +FakeBasicAuth +StrictRequire
496 # This configuration allows fetching over https without a certificate
497 # while always requiring a certificate for pushing over https
499 SSLVerifyClient optional
501 # these are left over git.or.cz links that may end up here by default
502 # as the old git.or.cz site does not have a TLS certificate.
503 # send them on to the same place that the old git.or.cz site would.
504 # anything without an exact match on the old site goes to git-scm.com.
505 RewriteCond %{SERVER_NAME} (^|\.)git.or.cz$ [NC]
506 RewriteRule ^/man/(.*) https://www.kernel.org/pub/software/scm/git/docs/$1.html [L,NE,R=301]
507 RewriteCond %{SERVER_NAME} (^|\.)git.or.cz$ [NC]
508 RewriteRule ^/gitwiki(/.*)? https://git.wiki.kernel.org/index.php$1 [L,NE,R=301]
509 RewriteCond %{SERVER_NAME} (^|\.)git.or.cz$ [NC]
510 RewriteRule ^ https://git-scm.com/ [L,NE,R=301]
512 RewriteCond %{REQUEST_METHOD} ^(GET|HEAD)$ [NC]
513 RewriteCond %{QUERY_STRING} (^|&)service=git-receive-pack(&|$) [NC]
514 RewriteRule /info/refs$ - [NC,NS,env=client_auth_required:1]
515 RewriteCond %{REQUEST_METHOD} =POST [NC]
516 RewriteRule /git-receive-pack$ - [NC,NS,env=client_auth_required:1]
517 RewriteCond %{ENV:client_auth_required} 1
518 RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
519 RewriteRule .? %{REQUEST_URI} [NS,R=401]
522 SSLOptions +FakeBasicAuth
523 AuthName "Git Client Authentication"
525 AuthBasicProvider anon
529 Deny from env=client_auth_required
537 Require not env client_auth_required
543 ErrorDocument 401 /authrequired.cgi
545 # ---- BEGIN DUPLICATE LINES ----
549 ## ALL the entire contents from the <VirtualHost *:80> section at the top of
550 ## this file must be copied here.
552 ## To avoid this duplication, the contents of the <VirtualHost *:80> section
553 ## above can be moved to a separate file and then included both here and in
554 ## the <VirtualHost *:80> section using an Include directive. Be careful not
555 ## to place the new include file in one of the directories the standard apache
556 ## configuration blindly includes all files from.
558 # ---- END DUPLICATE LINES ----