blob: ed02ad648707569558ea889bf6c78198b0b218d0 [file] [log] [blame]
Luigi Santivettied568d42020-05-18 00:53:17 +01001#!/bin/bash
2#
3# apache templates
4#
5# Copyright 2019 Luigi Santivetti <luigi.santivetti@gmail.com>
6
7# Permission is hereby granted, free of charge, to any person obtaining a
8# copy of this software and associated documentation files (the "Software"),
9# to deal in the Software without restriction, including without limitation
10# the rights to use, copy, modify, merge, publish, distribute, sublicense,
11# and/or sell copies of the Software, and to permit persons to whom the
12# Software is furnished to do so, subject to the following conditions:
13
14# The above copyright notice and this permission notice (including the next
15# paragraph) shall be included in all copies or substantial portions of the
16# Software.
17
18# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25declare -r vhost_http_t="\
26<VirtualHost *:${_APACHE_HTTP_PORT_}>
27
28 ServerName ${_APACHE_SERVER_NAME_}
29 ServerAlias ${_APACHE_SERVER_ALIAS_}
30
31 ErrorLog \"${_APACHE_VHOST_HTTP_LOG_F_}\"
32 RewriteEngine on
33
34 # NOTE: any POST or PUT send with http (:80) will be redirected
35 # with the side effect of dropping any data sent. We don't care
36 # nothing should transit over http anyway.
37
38 # Enforce https and www.
39 RewriteCond %{REQUEST_SCHEME} =http [NC]
40 RewriteCond %{SERVER_NAME} =${_APACHE_SERVER_NAME_} [NC]
41 RewriteRule ^ https://${_APACHE_SERVER_ALIAS_}%{REQUEST_URI} [NE,R=permanent,L]
42
43 # Enforce https
44 RewriteCond %{REQUEST_SCHEME} =http [NC]
45 RewriteCond %{SERVER_NAME} =${_APACHE_SERVER_ALIAS_} [NC]
46 RewriteRule ^ https://${_APACHE_SERVER_ALIAS_}%{REQUEST_URI} [NE,R=permanent,L]
47
48</VirtualHost>"
49
50declare -r vhost_https_t="\
51<IfModule mod_ssl.c>
52 <VirtualHost *:${_APACHE_HTTPS_PORT_}>
53
54 ServerName ${_APACHE_SERVER_NAME_}
55 ServerAlias ${_APACHE_SERVER_ALIAS_}
56
57 # DocumentRoot is the only publicly accessible data:
58 #
59 # - index.php, for dispatching requested URIs
60 # - theme/css, style
61 # - theme/js, style
62
63 DocumentRoot \"${_APACHE_DOCUMENT_ROOT_D_}\"
64 ErrorLog \"${_APACHE_SSL_LOG_F_}\"
65 LogLevel ${_APACHE_SSL_LOG_LEVEL_}
66
67 # Flags:
68 #
69 # NE, not escape, as keep chars such as & and ?
70 #
71 # R=status, redirect, if a valid URI is generated in the rewrite then
72 # issue a request to the browser. It always prepends the rewrite with
73 # [this protocol]://[thishost][:thisport]
74 #
75 # L, last, do not feed the rewrite result to the next rule
76 #
77 # NC, non case sensitive
78 #
79 # NOTE: This is to enforce 'www.' and *DO NOT* rediret! Skip POST and PUT
80 # because apache does an internal redirect 301 or 302 and drops the data
81 # attached to the request.
82
83 RewriteEngine on
84 RewriteCond %{REQUEST_METHOD} !^(POST|PUT) [NC]
85 RewriteCond %{SERVER_NAME} =${_APACHE_SERVER_NAME_} [NC]
86 RewriteRule ^ https://${_APACHE_SERVER_ALIAS_}%{REQUEST_URI} [NE]
87
88 # Proxy configuration
89 AllowEncodedSlashes on
90
91 # Route to vhost-gerrit.conf
92 #
93 # NOTE: 127.0.0.1 relative to container network
94
95 ProxyPassMatch /gerrit(/?)(.*) http://127.0.0.1:${_APACHE_GERRIT_PROXY_PORT_}/\$2 nocanon
96 ProxyPassReverse /gerrit(/?)(.*) http://127.0.0.1:${_APACHE_GERRIT_PROXY_PORT_}/\$2
97
98 # Within this context, it uses a file system path instead of URL path
99 #
100 # i.e.
101 # out %{REQUEST_URI} expands to https://servername.domain/whatever/
102 # in %{REQUEST_URI} expands to var/www/html/whatever/
103 #
104 # NOTE: %{REQUEST_URI} in directory context expands with a leading slash
105 # and a trailing slash
106
107 <Directory \"${_APACHE_DOCUMENT_ROOT_D_}\">
108
109 DirectorySlash Off
110 Require all granted
111
112 # This assumes to be calling a php handler, so:
113 #
114 # NOTE: Do not redirect or it will break the request.
115
116 RewriteCond %{REQUEST_FILENAME} !.*\.(css|js|mp4|jpg)$ [NC]
117 RewriteCond %{REQUEST_URI} !^/index.php [NC]
118 RewriteRule ^(.*)$ index.php/\$1 [NC,L]
119
120 </Directory>
121
122 # Lock out undesired auth requests
123
124 <Location \"/login/auth\">
125
126 Order Deny,Allow
127 Deny from all
128 Allow from ${_APACHE_MOD_AUTHNZ_LOCALHOST_}
129
130 </Location>
131
132 <LocationMatch \"^(/invite|/page/invite|/page/invite\\.html)$\">
133
134 AuthType Basic
135 AuthName \"Invite @ ${_APACHE_SERVER_NAME_}\"
136
137 # authnz_external
138 AuthBasicProvider external
139
140 # Call into php again
141 AuthExternal ${_APACHE_EXT_AUTH_KEYWORD_}
142
143 # mod_authz_core configuration
144 Require valid-user
145
146 </LocationMatch>
147
148 # NOTE: path relative to container rootfs
149 Include ${_APACHE_CON_SSL_CONF_F_}
150 SSLCertificateFile ${_APACHE_CON_SSL_CERT_F_}
151 SSLCertificateKeyFile ${_APACHE_CON_SSL_KEY_F_}
152
153 # Configure external authentication module
154 <IfModule mod_authnz_external.c>
155 DefineExternalAuth ${_APACHE_EXT_AUTH_KEYWORD_} pipe ${_APACHE_CON_EXT_AUTH_F_}
156 </IfModule>
157
158 # Configure set default environment
159 <IfModule mod_env.c>
160 SetEnv CI_ENV ${_APACHE_CODE_IGNITER_ENV_}
161 </IfModule>
162
163 </VirtualHost>
164</IfModule>"
165
166if [ "${_GERRIT_HAS_HTTPS_}" -eq 1 ]; then
167 declare -r vhost_gerrit_t_has_ssl="\
168 SSLProxyEngine on
169 SSLProxyCheckPeerCN off
170 SSLProxyCheckPeerName off"
171else
172 declare -r vhost_gerrit_t_has_ssl=""
173fi
174
175declare -r vhost_gerrit_t="\
176<VirtualHost 127.0.0.1:${_APACHE_GERRIT_PROXY_PORT_}>
177
178 # Restrict to only requests from 127.0.0.1
179
180 <LocationMatch \".*\">
181
182 Order Deny,Allow
183 Deny from all
184 Allow from 127.0.0.1
185
186 </LocationMatch>
187
188 ErrorLog \"${_APACHE_VHOST_GERRIT_LOG_F_}\"
189 LogLevel ${_APACHE_VHOST_GERRIT_LOG_LEVEL_}
190
191${vhost_gerrit_t_has_ssl}
192
193 ProxyVia off
194 ProxyRequests off
195 ProxyPreserveHost on
196 ProxyErrorOverride on
Luigi Santivettied568d42020-05-18 00:53:17 +0100197 AllowEncodedSlashes on
Luigi Santivetti348dc982020-11-03 22:42:50 +0000198
Luigi Santivettied568d42020-05-18 00:53:17 +0100199 # Proxy incoming requests towards Gerrit Code Review
Luigi Santivetti348dc982020-11-03 22:42:50 +0000200 ProxyPassMatch \\
201 ^/(.*)$ ${_GERRIT_PROXY_PROTOCOL_}://${_GERRIT_DKRC_FRONTEND_IP_}:${_GERRIT_PROXY_PORT_}/gerrit/\$1 nocanon
202 ProxyPassReverse \\
203 ^/(.*)$ ${_GERRIT_PROXY_PROTOCOL_}://${_GERRIT_DKRC_FRONTEND_IP_}:${_GERRIT_PROXY_PORT_}/gerrit/\$1
Luigi Santivettied568d42020-05-18 00:53:17 +0100204
205 <LocationMatch \"(/gerrit/login(/?)|/login(/?))\">
206
207 AuthType Basic
208 AuthName \"Gerrit @ ${_APACHE_SERVER_NAME_}\"
209
210 # authnz_external
211 AuthBasicProvider external
212
213 # Call into php again
214 AuthExternal ${_APACHE_EXT_AUTH_KEYWORD_}
215
216 # mod_authz_core configuration
217 Require valid-user
218
219 </LocationMatch>
220
221 # Configure external authentication module
222 <IfModule mod_authnz_external.c>
223 DefineExternalAuth ${_APACHE_EXT_AUTH_KEYWORD_} pipe ${_APACHE_CON_EXT_AUTH_F_}
224 </IfModule>
225
226</VirtualHost>"
227
228declare -r ports_t="\
229# If you just change the port or add more ports here, you will likely also
230# have to change the VirtualHost statement in
231# /etc/apache2/sites-enabled/000-default.conf
232
233#
234# Port mapped to the host (only one)
235#
236Listen ${_APACHE_HTTP_PORT_}
237
238#
239# Gerrit, vhost, proxied
240#
241Listen ${_APACHE_GERRIT_PROXY_PORT_}
242
243<IfModule ssl_module>
244 Listen ${_APACHE_HTTPS_PORT_}
245</IfModule>
246
247<IfModule mod_gnutls.c>
248 Listen ${_APACHE_HTTPS_PORT_}
249</IfModule>"
250
251declare -r apache2_t="\
252# This is the main Apache server configuration file. It contains the
253# configuration directives that give the server its instructions.
254# See http://httpd.apache.org/docs/2.4/ for detailed information about
255# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
256# hints.
257#
258#
259# Summary of how the Apache 2 configuration works in Debian:
260# The Apache 2 web server configuration in Debian is quite different to
261# upstream's suggested way to configure the web server. This is because Debian's
262# default Apache2 installation attempts to make adding and removing modules,
263# virtual hosts, and extra configuration directives as flexible as possible, in
264# order to make automating the changes and administering the server as easy as
265# possible.
266
267# It is split into several files forming the configuration hierarchy outlined
268# below, all located in the /etc/apache2/ directory:
269#
270# /etc/apache2/
271# |-- apache2.conf
272# | |-- ports.conf
273# |-- mods-enabled
274# | |-- *.load
275# | |-- *.conf
276# |-- conf-enabled
277# | |-- *.conf
278# +-- sites-enabled
279# |-- *.conf
280#
281#
282# * apache2.conf is the main configuration file (this file). It puts the pieces
283# together by including all remaining configuration files when starting up the
284# web server.
285#
286# * ports.conf is always included from the main configuration file. It is
287# supposed to determine listening ports for incoming connections which can be
288# customized anytime.
289#
290# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
291# directories contain particular configuration snippets which manage modules,
292# global configuration fragments, or virtual host configurations,
293# respectively.
294#
295# They are activated by symlinking available configuration files from their
296# respective *-available/ counterparts. These should be managed by using our
297# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
298# their respective man pages for detailed information.
299#
300# * The binary is called apache2. Due to the use of environment variables, in
301# the default configuration, apache2 needs to be started/stopped with
302# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
303# work with the default configuration.
304
305#
306# Global configuration
307#
308
309ServerName ${_APACHE_SERVER_NAME_}
310
311#
312# ServerRoot: The top of the directory tree under which the server's
313# configuration, error, and log files are kept.
314#
315# NOTE! If you intend to place this on an NFS (or otherwise network)
316# mounted filesystem then please read the Mutex documentation (available
317# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
318# you will save yourself a lot of trouble.
319#
320# Do NOT add a slash at the end of the directory path.
321#
322#ServerRoot \"/etc/apache2\"
323
324#
325# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
326#
327#Mutex file:\${APACHE_LOCK_DIR} default
328
329#
330# The directory where shm and other runtime files will be stored.
331#
332
333DefaultRuntimeDir \${APACHE_RUN_DIR}
334
335#
336# PidFile: The file in which the server should record its process
337# identification number when it starts.
338# This needs to be set in /etc/apache2/envvars
339#
340PidFile \${APACHE_PID_FILE}
341
342#
343# Timeout: The number of seconds before receives and sends time out.
344#
345Timeout 300
346
347#
348# KeepAlive: Whether or not to allow persistent connections (more than
349# one request per connection). Set to \"Off\" to deactivate.
350#
351KeepAlive On
352
353#
354# MaxKeepAliveRequests: The maximum number of requests to allow
355# during a persistent connection. Set to 0 to allow an unlimited amount.
356# We recommend you leave this number high, for maximum performance.
357#
358MaxKeepAliveRequests 100
359
360#
361# KeepAliveTimeout: Number of seconds to wait for the next request from the
362# same client on the same connection.
363#
364KeepAliveTimeout 5
365
366
367# These need to be set in /etc/apache2/envvars
368User \${APACHE_RUN_USER}
369Group \${APACHE_RUN_GROUP}
370
371#
372# HostnameLookups: Log the names of clients or just their IP addresses
373# e.g., www.apache.org (on) or 204.62.129.132 (off).
374# The default is off because it'd be overall better for the net if people
375# had to knowingly turn this feature on, since enabling it means that
376# each client request will result in AT LEAST one lookup request to the
377# nameserver.
378#
379HostnameLookups Off
380
381# ErrorLog: The location of the error log file.
382# If you do not specify an ErrorLog directive within a <VirtualHost>
383# container, error messages relating to that virtual host will be
384# logged here. If you *do* define an error logfile for a <VirtualHost>
385# container, that host's errors will be logged there and not here.
386#
387ErrorLog \${APACHE_LOG_DIR}/error.log
388
389#
390# LogLevel: Control the severity of messages logged to the error_log.
391# Available values: trace8, ..., trace1, debug, info, notice, warn,
392# error, crit, alert, emerg.
393# It is also possible to configure the log level for particular modules, e.g.
394# \"LogLevel info ssl:warn\"
395#
396LogLevel trace1
397
398# Include module configuration:
399IncludeOptional mods-enabled/*.load
400IncludeOptional mods-enabled/*.conf
401
402# Include list of ports to listen on
403Include ports.conf
404
405
406# Sets the default security model of the Apache2 HTTPD server. It does
407# not allow access to the root filesystem outside of /usr/share and /var/www.
408# The former is used by web applications packaged in Debian,
409# the latter may be used for local directories served by the web server. If
410# your system is serving content from a sub-directory in /srv you must allow
411# access here, or in any related virtual host.
412<Directory />
413 Options FollowSymLinks
414 AllowOverride None
415 Require all denied
416</Directory>
417
418<Directory /usr/share>
419 AllowOverride None
420 Require all granted
421</Directory>
422
423<Directory /var/www/>
424 Options Indexes FollowSymLinks
425 AllowOverride None
426 Require all granted
427</Directory>
428
429#<Directory /srv/>
430# Options Indexes FollowSymLinks
431# AllowOverride None
432# Require all granted
433#</Directory>
434
435# AccessFileName: The name of the file to look for in each directory
436# for additional configuration directives. See also the AllowOverride
437# directive.
438#
439AccessFileName .htaccess
440
441#
442# The following lines prevent .htaccess and .htpasswd files from being
443# viewed by Web clients.
444#
445<FilesMatch \"^\.ht\">
446 Require all denied
447</FilesMatch>
448
449#
450# The following directives define some format nicknames for use with
451# a CustomLog directive.
452#
453# These deviate from the Common Log Format definitions in that they use %O
454# (the actual bytes sent including headers) instead of %b (the size of the
455# requested file), because the latter makes it impossible to detect partial
456# requests.
457#
458# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
459# Use mod_remoteip instead.
460#
461LogFormat \"%v:%p %h %l %u %t \\\"%r\\\" %>s %O \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" vhost_combined
462LogFormat \"%h %l %u %t \\\"%r\\\" %>s %O \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined
463LogFormat \"%h %l %u %t \\\"%r\\\" %>s %O\" common
464LogFormat \"%{Referer}i -> %U\" referer
465LogFormat \"%{User-agent}i\" agent
466
467# Include of directories ignores editors' and dpkg's backup files,
468# see README.Debian for details.
469
470# Include generic snippets of statements
471IncludeOptional conf-enabled/*.conf
472
473# Include the virtual host configurations:
474IncludeOptional sites-enabled/*.conf
475
476# vim: syntax=apache ts=4 sw=4 sts=4 sr noet"
477
478if [ "${mod_mode}" = "${release}" ]; then
479 declare -rg dockerfile_debug_tools_t=""
480else
481 declare -rg dockerfile_debug_tools_t="\
482# debug only
483RUN apt-get -y install nmap
484RUN apt-get -y install net-tools"
485fi
486
487declare -rg dockerfile_t="\
488# Ref https://hub.docker.com/_/php/
489# php:7.3-apache-stretch
490# Apache/2.4.25 (Debian)
491# PHP 7.3 Cli
492ARG VERSION=7.3.9-apache-stretch
493FROM php:\$VERSION AS base
494
495RUN apt-get update
496RUN apt-get -y install sudo
497
498${dockerfile_debug_tools_t}
499
500# install apxs tools
501RUN apt-get -y install apache2-dev
502
503# mysqli driver
504RUN docker-php-ext-install mysqli
505
506# mysql dbd
507#RUN apt-get -y install libaprutil1-dbd-mysql
508
509# serivce and a2* need root access
510USER root
511
512# import mod_authnz_external source
513COPY ${_APACHE_MOD_AUTHNZ_EXTERNAL_D_} /${_APACHE_MOD_AUTHNZ_EXTERNAL_D_}
514
515# build and install mod_authnz_external
516WORKDIR /${_APACHE_MOD_AUTHNZ_EXTERNAL_D_}
517RUN apxs -c mod_authnz_external.c
518RUN sudo apxs -i -a mod_authnz_external.la
519
520# stop apache, it starts with docker-compose
521RUN [\"/bin/bash\", \"-c\", \"service apache2 stop\"]
522
523# disable default conf
524RUN [\"/bin/bash\", \"-c\", \"a2dissite 000-default\"]
525
526# enable proxy
527RUN [\"/bin/bash\", \"-c\", \"a2enmod proxy\"]
528RUN [\"/bin/bash\", \"-c\", \"a2enmod proxy_http\"]
529RUN [\"/bin/bash\", \"-c\", \"a2enmod proxy_ajp\"]
530RUN [\"/bin/bash\", \"-c\", \"a2enmod rewrite\"]
531RUN [\"/bin/bash\", \"-c\", \"a2enmod deflate\"]
532RUN [\"/bin/bash\", \"-c\", \"a2enmod headers\"]
533RUN [\"/bin/bash\", \"-c\", \"a2enmod proxy_balancer\"]
534RUN [\"/bin/bash\", \"-c\", \"a2enmod proxy_connect\"]
535RUN [\"/bin/bash\", \"-c\", \"a2enmod proxy_html\"]
536
537# enable mod_authnz_external
538RUN [\"/bin/bash\", \"-c\", \"a2enmod authnz_external\"]
539
540# enable dbd
541#RUN [\"/bin/bash\", \"-c\", \"a2enmod dbd\"]
542#RUN [\"/bin/bash\", \"-c\", \"a2enmod authn_dbd\"]
543#RUN [\"/bin/bash\", \"-c\", \"a2enmod authn_socache\"]
544
545# enable session
546#RUN [\"/bin/bash\", \"-c\", \"a2enmod session\"]
547#RUN [\"/bin/bash\", \"-c\", \"a2enmod session_dbd\"]
548
549# enable auth form
550#RUN [\"/bin/bash\", \"-c\", \"a2enmod request\"]
551#RUN [\"/bin/bash\", \"-c\", \"a2enmod auth_form\"]
552
553# enable SSL
554RUN [\"/bin/bash\", \"-c\", \"a2enmod ssl\"]"
555
556declare -r http_authentication_bang_t="\
557#!/bin/bash
558
559for key in username password; do
560 read -r value; eval \"declare -r \$key=\\\"\$value\\\"\"
561done
562
563declare -ir http_expected_status=\"${_APACHE_MOD_AUTHNZ_SUCCESS_CODE_}\"
564declare -r php_api=\"https://${_APACHE_MOD_AUTHNZ_LOCALHOST_}/login/auth\"
565
566declare curl_flags
567curl_flags+=\" -k -L --post301 --post302 --post303\"
568curl_flags+=\" -w %{http_code}\"
569curl_flags+=\" -o ${_APACHE_MOD_AUTHNZ_DEBUG_FLAG_}\"
570curl_flags+=\" -H \\\"${_APACHE_MOD_AUTHNZ_H_ACCEPT_}\\\"\"
571curl_flags+=\" -H \\\"${_APACHE_MOD_AUTHNZ_H_CONTENT_}\\\"\"
572curl_flags+=\" --data \\\"username=\$username&password=\$password\\\"\"
573
574declare -ir http_status=\"\$(eval \"curl \$curl_flags \$php_api\")\"
575[ \"\$http_status\" -eq \"\$http_expected_status\" ]
576declare -ir _CODE=\"\$?\"
577
578echo \"\$(date +'%d/%m/%Y - %H:%M:%S'): \${BASH_SOURCE[0]}: HTTP_STATUS: \$http_status\" >&2
579exit \$_CODE"