1 ## To convert this file to lighttpd.conf using the current Girocco::Config
2 ## values either do "make" or "make lighttpd.conf" or ./make-lighttpd-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 # Minimum lighttpd version 1.4.53 or later required for this config file
10 # Minimum lighttpd version 1.4.53 recommended
12 # Minimum lighttpd version 1.4.53 required for server.systemd-socket-activation
14 # Minimum lighttpd version 1.4.48 required for girocco https push support
16 # Versions prior to 1.4.50 have security issues with incoming requests
17 # having unnormalized URLs in them which can bypass access checks
19 # Versions prior to 1.4.52 accept invalid incoming requests that do
20 # not start the path with a '/'
22 # Prior to version 1.4.53, the private key for the server's
23 # certificate will have to be appended to the `server.pemfile`
24 # since `server.privkey` is not supported until version 1.4.53.
26 # Required lighttpd modules:
28 # mod_openssl - for https and client push certs
29 # mod_setenv - passing environment
30 # mod_indexfile - (should be automatic)
31 # mod_access - access checks
32 # mod_alias - aliases (no regexp)
33 # mod_redirect - regexp access etc.
34 # mod_rewrite - regexp rewrites/aliases/etc.
35 # mod_status - optional (local server status)
36 # mod_cgi - standard cgi
37 # mod_fastcgi - accelerated cgi
38 # mod_dirlisting - (should be automatic but unused)
39 # mod_staticfile - (should be automatic)
40 # mod_accesslog - for logging requests
44 ## IPv4/IPv6 addresses
46 ## These are needed in multiple places and collected here in
47 ## convenience variables to avoid duplication.
49 var.httpport = 80 # for http: connections
50 var.httpsport = 443 # for https: connections
51 @@if(!lighttpd_loopback_only)@@
52 # externally accessible web server
53 var.ipv4addr = "0.0.0.0" # IPv4 INADDR_ANY
54 var.ipv6addr = "::" # IPv6 IN6ADDR_ANY
56 @@if(lighttpd_loopback_only)@@
57 # web server only accessible from localhost
58 var.ipv4addr = "127.0.0.1"
62 # Suitable default PATH for CGI use
63 var.syspath = "@@var_getconfpath@@"
67 ## Standalone configuration
69 ## If this file is being included to provide a virtual
70 ## host service, then this configuration should have already
71 ## been done once somewhere else
74 @@if(lighttpd_standalone)@@
89 # This does not attempt to be a comprehensive list, but
90 # should be sufficient for Girocco on a standalone server
92 ".html" => "text/html",
93 ".htm" => "text/html",
94 ".txt" => "text/plain",
95 ".pem" => "text/plain",
96 ".ico" => "image/x-icon",
98 ".js" => "application/javascript",
99 ".png" => "image/png",
100 ".gif" => "image/gif",
101 ".bmp" => "image/bmp",
102 ".svg" => "image/svg+xml",
103 ".svgz" => "image/svg+xml",
104 ".jpg" => "image/jpeg",
105 ".jpeg" => "image/jpeg",
106 ".mp3" => "audio/mpeg",
107 "" => "application/octet-stream"
110 # This acts as a no-op if not activated via systemd, but without
111 # setting this it's not possible to pass sockets from systemd.
112 # Therefore just always set it in standalone mode
113 server.systemd-socket-activation = "enable"
115 # lighttpd has a problem passing sockets from systemd in that
116 # if systemd passes in an IPv6 socket, lighttpd will fail to bind
117 # a global `server.bind` value to an IPv4 socket. Oops.
118 # That's why `server.bind` here uses the IPv6 address.
119 server.bind = "["+var.ipv6addr+"]"
120 server.port = var.httpport
122 # these are required and in standalone mode won't be set anywhere else
123 @@if(!lighttpd_unprivileged)@@
124 # run privileged at first and after initializing, drop privileges
125 # normally no need to set the groupname as it's inited from the username
126 server.username = "@@cgi_user@@"
127 server.pid-file = "/var/run/lighttpd.pid"
128 var.logbase = "/var/log/lighttpd/"
129 var.fcgisockbase = "/var/run/lighttpd/"
130 @@endif(!lighttpd_unprivileged)@@
131 @@if(lighttpd_unprivileged)@@
132 # put the log files in /tmp using tmpsuffix
133 server.pid-file = "/tmp/lighttpd-@@tmpsuffix@@.pid"
134 var.logbase = "/tmp/lighttpd-@@tmpsuffix@@_"
135 var.fcgisockbase = "/tmp/lighttpd-fcgi-"
136 @@endif(lighttpd_unprivileged)@@
137 server.errorlog = var.logbase+"error.log"
138 # Send CGI stderr to error log
139 server.breakagelog = server.errorlog
141 # Special checks a standalone server might be expected to do
142 $HTTP["url"] =~ "(?i)\.htaccess$" { url.access-deny = ( "" ) }
144 @@endif(lighttpd_standalone)@@
146 @@if(!lighttpd_standalone)@@
147 var.logbase = "/var/log/lighttpd/"
148 var.fcgisockbase = "/var/run/lighttpd/"
151 # Lighttpd ignores exactly matching duplicate socket definitions
152 # therefore just go ahead and mention them to make sure they're active.
153 # Only the http sockets are here.
154 # See the bottom of this file for the https sockets.
156 $SERVER["socket"] == var.ipv4addr+":"+var.httpport {}
157 $SERVER["socket"] == "["+var.ipv6addr+"]:"+var.httpport {}
159 var.rdrbase = "${url.scheme}://${url.authority}" # helpful for redirects
160 var.botpat = "(?i)Slurp|Bot|Spider|Riddler|ltx71|Crawl"
162 @@if(!lighttpd_standalone)@@
163 # The configuration inside this virtual host conditional
164 # ends up only depending on the value of the 'Host:' header sent
165 # by the remote client since it contains no TLS-specific settings
166 $HTTP["host"] == "@@httpdnsname@@" { # "virtual" host @@httpdnsname@@
169 # These help to prevent a bot from monopolizing a connection
170 server.max-keep-alive-requests = 7 # default is 100
171 server.max-keep-alive-idle = 2 # default is 5
173 # Without these little bits here to set server.name,
174 # if an HTTP/1.0 request comes in on a non-standard port
175 # and it lacks a Host: header, redirects might give the
176 # wrong answer without these.
177 $HTTP["scheme"] == "http" {
178 server.name = "@@httpdnsname@@:"+var.httpport
180 else $HTTP["scheme"] == "https" {
181 server.name = "@@httpdnsname@@:"+var.httpsport
184 # This is the standard "combined" log format modified as follows:
185 # the REMOTE_USER (%u) has double-quotes around it
186 # the received time is shown as [YYYY-mm-dd_HH:MM:SS +hhmm] (almost RFC 3339 format)
187 # -- this is one character shorter than the default but sorts so much better
188 # the %O value is prefixed with:
189 # %I-> -- <bytes-received-including-request-and-headers>
190 # the first line of the request ("%r") is prefixed with
191 # %X%k: -- <connection-status><keepalive-request-num>
192 # these fields are added to the end:
193 # :%{local}p -- :<actual-server-port>
194 # %Dus -- <request-time-in-microseconds>
195 # "%o{Content-Range}" -- <outgoing Content-Range header>
196 accesslog.format = "%h %l \"%u\" %{[%F_%T %z]}t %X%k:\"%r\" %>s %I->%O \"%{Referer}i\" \"%{User-Agent}i\" :%{local}p %Dus \"%{Content-Range}o\""
198 # lighttpd does not permit a separate error log per host
200 # This may need to be adjusted as needed
201 accesslog.filename = var.logbase+"@@nickname@@-access.log"
203 # Send CGI stderr to error log (done above for standalone mode)
204 #global { server.breakagelog = server.errorlog }
206 # Avoid breaking gitweb
207 server.force-lowercase-filenames = "disable"
209 # lighttpd "normalization" suffers from many defects;
210 # no available configuration is standards compliant.
211 # Failing to enable any "normalization" (the default
212 # through version 1.4.53) allows URL-encoded items
213 # to bypass access and other checks. Enabling even
214 # the bare minimum (this configuration here), causes
215 # anomalies that reject standards-complying URLs and
216 # potentially corrupt regular expressions in the config
217 # file. The problems with the code are rampant.
218 # This is the only possible acceptable configuration.
219 # Worse yet, it can't even be set on a per-connection basis!
221 # yes, just always stomp on any misguided
222 # global config for these items
223 server.http-parseopts := (
224 "url-path-2f-decode" => "disable",
225 "url-normalize-unreserved" => "enable",
226 "url-path-dotseg-remove" => "enable")
229 server.document-root = "@@webroot@@"
230 static-file.disable-pathinfo = "enable" # should be default
231 cgi.execute-x-only = "enable" # why is this not the default???
232 cgi.local-redir = "enable" # match Apache -- required by RFC 3875
234 # The standard Apache Girocco configuration follows
235 # symlinks as a prerequisite to make ".htaccess" files work.
236 # That's not a consideration here, but to be compatible
237 # with any symlinks that might be in use, it's enabled.
238 server.follow-symlink = "enable"
240 # Send bare "/" directly to gitweb
241 url.rewrite-repeat = ( "^/(?:\?|$)" => "/w${qsa}" )
243 # The magic /[bchrw] prefix always forces selection of the
244 # prefix-indicated cgi handler.
246 $HTTP["url"] =~ "^/w(?:/|$)" {
247 $REQUEST_HEADER["user-agent"] =~ var.botpat {
248 $HTTP["query-string"] =~ "(?x)
264 url.access-deny = ( "" )
266 else $HTTP["url"] =~ "(?x)/(?:
279 url.access-deny = ( "" )
281 else $HTTP["query-string"] =~ "(.*h=.*;)hb=[^;]*(.*)" {
282 url.redirect-code = 303
283 url.redirect = ( "^([^?#]*)" => var.rdrbase + "$1%1%2" )
286 #alias.url = ( "/w" => "@@cgiroot@@/gitweb.cgi" ) # would munge DOCUMENT_ROOT
287 fastcgi.server = ( "/w" => ( "gitweb" => (
288 "socket" => var.fcgisockbase+"gitweb-@@tmpsuffix@@",
289 "check-local" => "disable",
290 # lighttpd cannot handle gitweb exiting gracefully after each 100 requests;
291 # to kludge around lighttpd's limitations, use gitweb-gc.sh instead.
292 #"bin-path" => "@@cgiroot@@/gitweb.cgi",
293 "bin-path" => "@@basedir@@/bin/gitweb-gc.sh",
294 "min-procs" => 1, # default is min(4, max-procs)
295 "max-procs" => @@var_online_cpus@@, # default is 4
296 "idle-timeout" => 180, # seconds (default is 60)
297 # Unlike mod_cgi, mod_fastcgi by default passes through
298 # the server's environment (the exact opposite of Apache)
299 # In order to be consistent we use bin-copy-environment (which
300 # would be better named bin-clean-environment) plus bin-environment
301 # to get an environment that matches the one sent to mod_cgi executables
302 "bin-copy-environment" => ( "" ), # cleans env like mod_cgi does
303 "bin-environment" => ( "PATH" => var.syspath ), # adds consistent PATH
306 else $HTTP["url"] =~ "^/b(?:/|$)" {
307 $REQUEST_HEADER["user-agent"] =~ var.botpat { url.access-deny = ( "" ) }
308 alias.url = ( "/b" => "@@cgiroot@@/bundles.cgi" )
309 cgi.assign = ( "" => "" )
310 # CGI scripts will likely behave poorly without this
311 setenv.set-environment += ( "PATH" => var.syspath )
312 # Send Apache-identical DOCUMENT_ROOT not lighttpd crazy one
313 setenv.set-environment += ( "DOCUMENT_ROOT" => server.document-root )
315 # setenv.set-environment GIT_HTTP_BACKEND_BIN to override Config.pm $git_http_backend_bin
316 else $HTTP["url"] =~ "^/r(?:/|$)" {
317 $REQUEST_HEADER["user-agent"] =~ var.botpat { url.access-deny = ( "" ) }
318 setenv.set-environment += ( "REQUIRE_SSL_CLIENT_VERIFY_SUCCESS" => "1" )
319 alias.url = ( "/r" => "@@basedir@@/bin/git-http-backend-verify" )
320 cgi.assign = ( "" => "" )
321 # CGI scripts will likely behave poorly without this
322 setenv.set-environment += ( "PATH" => var.syspath )
323 # Send Apache-identical DOCUMENT_ROOT not lighttpd crazy one
324 setenv.set-environment += ( "DOCUMENT_ROOT" => server.document-root )
326 # /h/ => html pages pre-generated via the html.cgi template script
327 else $HTTP["url"] =~ "^/h/.+\.html$" {
328 mimetype.assign = ( "" => "text/html; charset=utf-8" )
329 alias.url = ( "/h/" => "@@cgiroot@@/html/" )
332 # A top-level .cgi suffix selects that cgi if it's not gitweb, bundles or html
333 else $HTTP["url"] =~ "^/(?!(?i)gitweb\.cgi|bundles\.cgi|html\.cgi(?:/|$))([^/]+\.cgi(?:/.*)?)$" {
334 alias.url = ( "/" => "@@cgiroot@@/" )
335 cgi.assign = ( "" => "" )
336 # CGI scripts will likely behave poorly without this
337 setenv.set-environment += ( "PATH" => var.syspath )
338 # Send Apache-identical DOCUMENT_ROOT not lighttpd crazy one
339 setenv.set-environment += ( "DOCUMENT_ROOT" => server.document-root )
342 # Any requests without the magic /[bchrw] are treated as Git requests if they
343 # are one of the few possible Git URLs otherwise they go to bundles or gitweb
345 # Change the setting of $SmartHTTPOnly in Girocco::Config.pm to
346 # change whether or not non-smart HTTP fetch access will be allowed.
348 @@if(!SmartHTTPOnly)@@
349 # This accelerates non-smart HTTP access to loose objects, packs and info
350 $HTTP["url"] =~ "(?x)
352 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?)(?:\.git)?/(
354 objects/info/alternates |
355 objects/info/http-alternates |
357 objects/[0-9a-f]{2}/[0-9a-f]{38} |
358 objects/pack/pack-[0-9a-f]{40}\.(?:pack|idx) )$" {
359 $REQUEST_HEADER["user-agent"] =~ var.botpat { url.access-deny = ( "" ) }
361 "^[^?]*\.git/" => "", # skip rewrite if not needed
365 "/r/" => "@@reporoot@@/",
366 "/" => "@@reporoot@@/"
371 @@if(SmartHTTPOnly)@@
372 # This can never match but allows an "else" to always be used next
373 $HTTP["url"] =~ "^(?=0)1" {}
376 else $HTTP["url"] =~ "(?x)
378 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?)(?:\.git)?/(
382 [a-zA-Z0-9][a-zA-Z0-9+._-]*\.bundle )$" {
384 "^[^?]*\.git/" => "", # skip rewrite if not needed
385 "" => "/r/%1.git/%2${qsa}"
387 $REQUEST_HEADER["user-agent"] =~ var.botpat { url.access-deny = ( "" ) }
388 setenv.set-environment += ( "REQUIRE_SSL_CLIENT_VERIFY_SUCCESS" => "1" )
389 alias.url = ( "/" => "@@basedir@@/bin/git-http-backend-verify/" )
390 cgi.assign = ( "" => "" )
391 # CGI scripts will likely behave poorly without this
392 setenv.set-environment += ( "PATH" => var.syspath )
393 # Send Apache-identical DOCUMENT_ROOT not lighttpd crazy one
394 setenv.set-environment += ( "DOCUMENT_ROOT" => server.document-root )
397 # Everything else off to bundles.cgi or gitweb.cgi
398 else $HTTP["url"] =~ "(?x)
400 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?\.git/bundles)$" {
401 $REQUEST_HEADER["user-agent"] =~ var.botpat { url.access-deny = ( "" ) }
402 alias.url = ( "/" => "@@cgiroot@@/bundles.cgi/" )
403 cgi.assign = ( "" => "" )
404 # CGI scripts will likely behave poorly without this
405 setenv.set-environment += ( "PATH" => var.syspath )
406 # Send Apache-identical DOCUMENT_ROOT not lighttpd crazy one
407 setenv.set-environment += ( "DOCUMENT_ROOT" => server.document-root )
409 else $HTTP["url"] =~ "(?x)
411 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?\.git(?!/bundles)(?:/.*)?)$" {
412 url.rewrite-once = ( "" => "/w/%1${qsa}" )
415 # mod_rewrite is always required for this lighttpd configuration
416 # which means the trailing ".git" is optional in some cases,
417 # the leading /h is optional for *.html, snapshots are
418 # always throttled, some bogus Git http protocol requests will be
419 # detected early and, if non-smart HTTP is allowed, access to the
420 # /info/refs file will be accelerated in non-smart HTTP mode.
422 # Make the leading /h optional for requests that name a first or second level .html template
423 # Without having file tests available, this is not as flexible.
424 else $HTTP["url"] =~ "^/(?![bchrw]/)(([a-zA-Z]+/)?[^/]+\.html)$" {
425 mimetype.assign = ( "" => "text/html; charset=utf-8" )
426 alias.url = ( "/" => "@@cgiroot@@/html/" )
429 # Redirect bare gitweb /w requests without .git
430 else $HTTP["url"] =~ "(?x)^/w/
431 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git))$" {
432 url.redirect = ( "" => var.rdrbase + "/w/%1.git${qsa}" )
435 # Redirect bare gitweb non-/w requests without .git
436 # Without having file tests available, this is problematic.
437 # It's necessary to avoid redirecting requests for static files
438 # that are part of the website itself, but we can do a reasonable approximation
439 # since we know that no users or project names will be allowed to be created
440 # with any of the case-insensitive extensions in %Girocco::Config::reserved_suffixes
441 else $HTTP["url"] =~ "(?x)
443 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git))$" {
444 # This is a big gnarly mess!
445 # We need to exclude any query string when checking for prohibited extensions.
446 # And $HTTP["url"] conveniently lets us do that.
447 # Attempting to do it in the `url.redirect` pattern itself means it would have to
448 # be anchored to the beginning part up to and excluding any first `?` character.
449 # Unfortunately, that causes a rather bad exponential explosion in `pcre_exec`
450 # likely because the negative assertion patterns are anchored to the end.
451 # Therefore we do the check in two stages, first against $HTTP["url"] only
452 # anchored at the end and then let the redirect pattern match take care of
453 # figuring out where the non-querystring part of the url ends to insert `.git`.
454 $HTTP["url"] =~ "(?ix)
455 @@reserved()@@ # replaced with reserved extension negative assertions
457 url.redirect = ( "^/([^?]*)(.*)$" => var.rdrbase + "/$1.git$2" )
461 # Snapshot/blob_plain requests are only allowed via the PATH_INFO mechanism
462 $HTTP["query-string"] =~ "(?i)(^|[&;])a=(?:snapshot|blob_plain)([&;]|$)" {
463 url.access-deny = ( "" )
466 # Redirect snapshot requests to snapshot.cgi
467 else $HTTP["url"] =~ "(?x)
469 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?\.git/
470 snapshot(?:/.*)?)$" {
472 "/w/" => "@@cgiroot@@/snapshot.cgi/",
473 "/" => "@@cgiroot@@/snapshot.cgi/"
476 cgi.assign = ( "" => "" )
477 # CGI scripts will likely behave poorly without this
478 setenv.set-environment += ( "PATH" => var.syspath )
479 # Send Apache-identical DOCUMENT_ROOT not lighttpd crazy one
480 setenv.set-environment += ( "DOCUMENT_ROOT" => server.document-root )
483 # The fancy .no_blob_plain processing is not handled with lighttpd...yet!
485 # Of the 11 possible Git protocol URLs (i.e. passed to git-http-backend-verify),
486 # 9 are only valid with GET/HEAD and the other two are only valid with POST
487 # Furthermore, 7 are only valid when non-smart is allowed and
488 # 1 is only valid when smart-only is enabled if it has the correct query string.
490 # These two always require POST
491 $HTTP["request-method"] != "POST" {
492 $HTTP["url"] =~ "(?x)^/(?![bchw]/)(?:r/)?
493 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/(?:
495 git-receive-pack )$" {
496 url.access-deny = ( "" )
500 @@if(SmartHTTPOnly)@@
501 # These 7 are always forbidden when non-smart HTTP is disabled
502 $HTTP["url"] =~ "(?x)^/(?![bchw]/)(?:r/)?
503 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/(?:
505 objects/info/alternates |
506 objects/info/http-alternates |
508 objects/[0-9a-f]{2}/[0-9a-f]{38} |
509 objects/pack/pack-[0-9a-f]{40}\.(?:pack|idx) )$" {
510 url.access-deny = ( "" )
512 # This one is forbidden without the magic query string when non-smart is disabled
513 $HTTP["url"] =~ "(?x)^/(?![bchw]/)(?:r/)?
514 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/
516 $HTTP["request-method"] !~ "^(?:GET|HEAD)$" {
517 url.access-deny = ( "" )
519 else $HTTP["query-string"] !~ "(^|&)service=git-(?:upload|receive)-pack(&|$)" {
520 url.access-deny = ( "" )
523 # This one requires GET (or HEAD)
524 $HTTP["request-method"] !~ "^(?:GET|HEAD)$" {
525 $HTTP["url"] =~ "(?x)^/r/
526 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/
527 [a-zA-Z0-9][a-zA-Z0-9+._-]*\.bundle $" {
528 url.access-deny = ( "" )
533 @@if(!SmartHTTPOnly)@@
534 # These 9 require GET (or HEAD)
535 $HTTP["request-method"] !~ "^(?:GET|HEAD)$" {
536 $HTTP["url"] =~ "(?x)^/(?![bchw]/)(?:r/)?
537 (?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?(?:\.git)?/(?:
540 objects/info/alternates |
541 objects/info/http-alternates |
543 objects/[0-9a-f]{2}/[0-9a-f]{38} |
544 objects/pack/pack-[0-9a-f]{40}\.(?:pack|idx) |
545 [a-zA-Z0-9][a-zA-Z0-9+._-]*\.bundle )$" {
546 url.access-deny = ( "" )
549 # This one can be accelerated when accessed with non-smart HTTP
550 $HTTP["request-method"] =~ "^(?:GET|HEAD)$" {
551 $HTTP["query-string"] !~ "(^|&)service=git-(?:upload|receive)-pack(&|$)" {
552 $HTTP["url"] =~ "(?x)^/(?![bchw]/)(?:r/)?
553 ((?:[a-zA-Z0-9][a-zA-Z0-9+._-]*(?<!\.git)/)*[a-zA-Z0-9][a-zA-Z0-9+._-]*?)(?:\.git)?/
555 $REQUEST_HEADER["user-agent"] =~ var.botpat { url.access-deny = ( "" ) }
557 "^[^?]*\.git/" => "", # skip rewrite if not needed
558 "" => "/r/%1.git/info/refs"
561 "/r/" => "@@reporoot@@/",
562 "/" => "@@reporoot@@/"
570 @@if(!lighttpd_standalone)@@
571 } # "virtual" host @@httpdnsname@@
574 # Change the setting of $TLSHost in Girocco::Config.pm to change
575 # whether or not the following TLS configuration is enabled.
581 ## Lighttpd TLS Virtual Host Info
583 ## Yes, lighttpd can do TLS virtual hosting.
584 ## By default, if $Girocco::Config::lighttpd_standalone is false
585 ## and $Girocco::Config::TLSHost is true then this config file
586 ## will be set up for TLS virtual hosting.
588 ## But there's a catch.
590 ## For Lighttpd TLS virtual hosting, the correct server certificate
591 ## will be set inside a $HTTP["host"] conditional which will trigger
592 ## based on the incoming SNI (server name indication).
594 ## The gotcha is that Lighttpd requires a valid server certificate and
595 ## private key to always be set at the same level where TLS is enabled (either
596 ## the $SERVER["socket"] section or the global configuration).
598 ## This configuration will not do that (if $lighttp_standalone is false)
599 ## on the assumption that this configuration file has been included by
600 ## a global configuration that has already configured TLS to listen on the
601 ## intended address+port and has already provided a valid TLS server
602 ## certificate and private key for that TLS address+port. In which case
603 ## when the incoming SNI matches our Girocco host, it will be overridden
604 ## with the Girocco server certificate and key configured in this file.
606 ## If that is not the case (when $lighttpd_standalone is false), then
607 ## lighttpd will complain at startup about a missing "ssl.pemfile" due
608 ## to the "ssl.enable" below.
610 ## If $Girocco::Config::lighttpd_tls_virtualhost is false, then the TLS
611 ## virtual host config part will be omitted (it's always omitted when
612 ## $lighttpd_standalone is true) even when not $lighttpd_standalone.
614 ## Recall that a correctly operating web browser (or other client such as git)
615 ## will NEVER SEND an SNI value when a literal IPv4 or IPv6 address has been
616 ## specified (i.e. https://127.0.0.1/ and https://[::1]/) which means that
617 ## when TLS virtual host mode is enabled an actual host name must be used
618 ## to get the correct certificate (i.e. https://localhost/).
621 $SERVER["socket"] == var.ipv4addr+":"+var.httpsport { # IPv4 TLS
623 # ---- BEGIN LINES TO DUPLICATE ----
627 ssl.engine = "enable"
628 @@if(lighttpd_standalone)@@
629 # cipher-list must be set or the default wide-open list will be used
630 ssl.cipher-list = "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!eNULL:!LOW:!MEDIUM:!RC4:!SSLv2:!CAMELLIA:!CHACHA20:!aGOST:!DSS:!ECDSA:@STRENGTH"
631 #ssl.read-ahead = "disable" # disable read-ahead on resource constrained systems
632 @@endif(lighttpd_standalone)@@
634 @@if(!lighttpd_standalone)@@
635 @@if(lighttpd_tls_virtualhost)@@
636 $HTTP["host"] == "@@httpdnsname@@" { # "virtual" host @@httpdnsname@@
637 @@endif(lighttpd_tls_virtualhost)@@
638 @@endif(!lighttpd_standalone)@@
640 # These certificate files will all be automatically generated, but the
641 # paths here may need to be corrected to match the paths
642 # (especially $certsdir) from Config.pm
644 ssl.pemfile = "@@certsdir@@/girocco_www_fullchain.pem"
645 ssl.privkey = "@@certsdir@@/girocco_www_key.pem"
646 # When using a www server cert signed by a pre-trusted root, only
647 # the above two lines should be changed. Changing either of the
648 # below two lines will likely break https client authentication.
649 ssl.ca-file = "@@certsdir@@/girocco_root_crt.pem"
650 ssl.ca-dn-file = "@@certsdir@@/girocco_client_crt.pem"
652 ssl.verifyclient.activate = "enable"
653 ssl.verifyclient.enforce = "disable"
654 ssl.verifyclient.depth = 3
655 ssl.verifyclient.username = "SSL_CLIENT_S_DN"
657 @@if(!lighttpd_standalone)@@
658 @@if(lighttpd_tls_virtualhost)@@
659 } # "virtual" host @@httpdnsname@@
660 @@endif(lighttpd_tls_virtualhost)@@
661 @@endif(!lighttpd_standalone)@@
663 # ---- END LINES TO DUPLICATE ----
667 $SERVER["socket"] == "["+var.ipv6addr+"]:"+var.httpsport { # IPv6 TLS
669 # ---- BEGIN DUPLICATE LINES ----
673 ## ALL the entire contents from the '$SERVER["socket"] ==' section above
674 ## must be copied here.
676 ## To avoid this duplication, the contents of the '$SERVER["socket"] =='
677 ## section above can be moved to a separate file and then included both
678 ## here and above using an include directive. Be careful not to place
679 ## the new include file in one of the directories the standard
680 ## configuration blindly includes all files from.
682 # ---- END DUPLICATE LINES ----