Merge ~pjdc/ubuntu-mirror-charm/+git/ubuntu-mirror-charm:tls into ubuntu-mirror-charm:master

Proposed by Paul Collins
Status: Merged
Approved by: Paul Collins
Approved revision: 64c5add84d95adda45fcfffeb64eb8030fd21c91
Merged at revision: 2e6f364321c6f3e58e109b60d18c03905dc351cf
Proposed branch: ~pjdc/ubuntu-mirror-charm/+git/ubuntu-mirror-charm:tls
Merge into: ubuntu-mirror-charm:master
Prerequisite: ~pjdc/ubuntu-mirror-charm/+git/ubuntu-mirror-charm:remove-apache-2.2-support
Diff against target: 340 lines (+142/-10)
9 files modified
config.yaml (+29/-1)
hooks/hooks.py (+26/-3)
templates/apache-cdimage.tmpl (+12/-1)
templates/apache-cloud-images.tmpl (+12/-1)
templates/apache-listen-ports.conf.tmpl (+15/-0)
templates/apache-ports.tmpl (+12/-1)
templates/apache-releases.tmpl (+12/-1)
templates/apache-simple-streams.tmpl (+12/-1)
templates/apache-ubuntu.tmpl (+12/-1)
Reviewer Review Type Date Requested Status
Joel Sing (community) +1 Approve
Canonical IS Reviewers Pending
Review via email: mp+380758@code.launchpad.net

Commit message

support TLS and listening on specific addresses

This is so that we can avoid opening port 443 on archive.ubuntu.com.

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Joel Sing (jsing) wrote :

LGTM, but see comments/questions inline.

review: Approve (+1)
Revision history for this message
Paul Collins (pjdc) wrote :

Most comments addressed in upcoming push. Replies inline re ports.conf template.

Revision history for this message
Paul Collins (pjdc) wrote :

Pushed new commit to generate ports.conf a little more straightforwardly.

Revision history for this message
Joel Sing (jsing) :
Revision history for this message
Joel Sing (jsing) wrote :

LGTM

review: Approve (+1)
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 2e6f364321c6f3e58e109b60d18c03905dc351cf

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/config.yaml b/config.yaml
2index 915332b..bd8370e 100644
3--- a/config.yaml
4+++ b/config.yaml
5@@ -14,7 +14,35 @@ options:
6 role_map:
7 default: ''
8 type: string
9- description: 'JSON-formatted list of which type of mirror is enabled on which unit. Format is: {"hostname1":["cdimage","ubuntu"],"hostname2":["releases"]}'
10+ description: >-
11+ JSON document describing which mirror is enabled on which machine.
12+
13+ There are two formats. The first format is simple:
14+
15+ {"hostname1": ["cdimage", "ubuntu"], "hostname2": ["releases"]}
16+
17+ In the second more complex format each hostname's value is a
18+ dictionary rather than a list of roles. For example:
19+
20+ {
21+ "hostname1": {
22+ "releases": {
23+ "addresses": ["1.2.3.4"],
24+ "https": true
25+ },
26+ "ubuntu": null
27+ },
28+ "hostname2": [
29+ "releases",
30+ "ubuntu"
31+ ]
32+ }
33+
34+ Here, hostname1's ubuntu role will result in an HTTP VirtualHost
35+ that listens on *:80 and serves the Ubuntu archive.
36+
37+ The releases role will result in HTTP and HTTPS VirtualHosts
38+ that listen on 1.2.3.4:80 and 1.2.3.4:443 respectively.
39 mirror_ubuntu_name:
40 default: "archive.ubuntu.com"
41 type: string
42diff --git a/hooks/hooks.py b/hooks/hooks.py
43index 8b47b2c..bc7a9d2 100755
44--- a/hooks/hooks.py
45+++ b/hooks/hooks.py
46@@ -8,13 +8,14 @@ import base64
47 import json
48 import os
49 import os.path
50+import platform
51 import pwd
52 import shutil
53 import socket
54 import subprocess
55 import sys
56+import types
57 import yaml
58-import platform
59
60 from charmhelpers.core.host import (
61 adduser,
62@@ -313,6 +314,8 @@ def configure_apache():
63
64 wanted_vhosts = []
65
66+ all_addresses = set()
67+ all_ports = set()
68 # Create vhost configs for all active roles
69 for role in roles[hostname]:
70 try:
71@@ -320,11 +323,19 @@ def configure_apache():
72 except ValueError:
73 log("CHARM: Missing details - skipping {}".format(role))
74 else:
75+ if isinstance(roles[hostname], types.DictType) and roles[hostname][role]:
76+ role_config = roles[hostname][role]
77+ else:
78+ role_config = {}
79 wanted_vhosts.append(role)
80 sites_available = os.path.join(available_dir, role + ".conf")
81 sites_enabled = os.path.join(enabled_dir, role + ".conf")
82 tmpl_data = mirror
83 tmpl_data["logdir"] = apache_logdir
84+ tmpl_data["addresses"] = role_config.get('addresses', ['*'])
85+ all_addresses.update(tmpl_data["addresses"])
86+ tmpl_data["ports"] = [80, 443] if role_config.get('https') else [80]
87+ all_ports.update(tmpl_data["ports"])
88 tmpl_file = str("apache-{}.tmpl".format(role))
89 file_from_template(tmpl_file, sites_available, tmpl_data)
90 symlink(sites_available, sites_enabled)
91@@ -345,6 +356,18 @@ def configure_apache():
92 os.chown(mirror["path"], mirror_userinfo.pw_uid, mirror_userinfo.pw_gid)
93 symlink(mirror["path"], linkdest)
94
95+ # Update ports file
96+ all_addresses.discard('*') # archive.ubuntu.com must not open port 443.
97+ file_from_template('apache-listen-ports.conf.tmpl', '/etc/apache2/ports.conf',
98+ {'addresses': sorted(all_addresses), 'ports': sorted(all_ports)})
99+
100+ # Enable ssl module, if not already enabled
101+ restart_for_ssl = False
102+ if 443 in all_ports:
103+ if check_call(['/usr/sbin/a2query', '-m', 'ssl']) != 0:
104+ check_call(['/usr/sbin/a2enmod', 'ssl'])
105+ restart_for_ssl = True
106+
107 # Remove all other vhosts
108 unwanted_vhosts = set(conf.role_list()) - set(wanted_vhosts)
109 for vhost in unwanted_vhosts:
110@@ -356,7 +379,7 @@ def configure_apache():
111 log("CHARM: Unable to delete vhost {}".format(vhost))
112
113 # Set up server limits
114- restart_needed = configure_apache_mpm()
115+ restart_for_mpm = configure_apache_mpm()
116
117 # Configure status module
118 tmpl_data = {}
119@@ -385,7 +408,7 @@ def configure_apache():
120 override_file = '{}/override.conf'.format(systemd_apachedir)
121 file_from_template("systemd-apache-override.tmpl", override_file, tmpl_data)
122
123- if restart_needed:
124+ if restart_for_mpm or restart_for_ssl:
125 log("CHARM: Restarting apache")
126 service_restart("apache2")
127 else:
128diff --git a/templates/apache-cdimage.tmpl b/templates/apache-cdimage.tmpl
129index d36cf64..ea841dc 100644
130--- a/templates/apache-cdimage.tmpl
131+++ b/templates/apache-cdimage.tmpl
132@@ -1,4 +1,6 @@
133-<VirtualHost *:80>
134+#for $port in $ports
135+#set $sockets = ' '.join(sorted(['{}:{}'.format(address, port) for address in $addresses]))
136+<VirtualHost ${sockets}>
137 ${apache_early_extra}
138 ServerName ${name}
139 #for $alias in $aliases
140@@ -8,6 +10,13 @@ ${apache_early_extra}
141 CustomLog ${logdir}/${name}-access.log combined
142 ErrorLog ${logdir}/${name}-error.log
143
144+#if $port == 443
145+ SSLEngine On
146+ SSLCertificateFile /etc/apache2/ssl/${name}.crt
147+ SSLCertificateKeyFile /etc/apache2/ssl/${name}.key
148+ SSLCertificateChainFile /etc/apache2/ssl/${name}_chain.crt
149+
150+#end if
151 DocumentRoot /srv/${name}/www
152 Alias /cdimage "/srv/${name}/www/"
153
154@@ -21,3 +30,5 @@ ${apache_early_extra}
155 </Directory>
156 ${apache_late_extra}
157 </VirtualHost>
158+
159+#end for
160diff --git a/templates/apache-cloud-images.tmpl b/templates/apache-cloud-images.tmpl
161index 9c59a8b..04f11cc 100644
162--- a/templates/apache-cloud-images.tmpl
163+++ b/templates/apache-cloud-images.tmpl
164@@ -1,4 +1,6 @@
165-<VirtualHost *:80>
166+#for $port in $ports
167+#set $sockets = ' '.join(sorted(['{}:{}'.format(address, port) for address in $addresses]))
168+<VirtualHost ${sockets}>
169 ${apache_early_extra}
170 ServerName ${name}
171 #for $alias in $aliases
172@@ -9,6 +11,13 @@ ${apache_early_extra}
173 ErrorLog ${logdir}/${name}-error.log
174 LogFormat "%h %D %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined-ext
175
176+#if $port == 443
177+ SSLEngine On
178+ SSLCertificateFile /etc/apache2/ssl/${name}.crt
179+ SSLCertificateKeyFile /etc/apache2/ssl/${name}.key
180+ SSLCertificateChainFile /etc/apache2/ssl/${name}_chain.crt
181+
182+#end if
183 DocumentRoot /srv/${name}/www
184 Alias /cloud-images "/srv/${name}/www/"
185
186@@ -22,3 +31,5 @@ ${apache_early_extra}
187 </Directory>
188 ${apache_late_extra}
189 </VirtualHost>
190+
191+#end for
192diff --git a/templates/apache-listen-ports.conf.tmpl b/templates/apache-listen-ports.conf.tmpl
193new file mode 100644
194index 0000000..7a633b9
195--- /dev/null
196+++ b/templates/apache-listen-ports.conf.tmpl
197@@ -0,0 +1,15 @@
198+#if 80 in $ports
199+Listen 80
200+
201+#end if
202+#if len($addresses) > 0 and len($ports) > 1
203+# We only want to listen for non-HTTP on specific addresses
204+# so that we don't accidentally expose port 443 for archive.
205+#for $port in $ports
206+#if $port != 80
207+#for $address in $addresses
208+Listen ${address}:${port}
209+#end for
210+#end if
211+#end for
212+#end if
213diff --git a/templates/apache-ports.tmpl b/templates/apache-ports.tmpl
214index 4ce54db..f24823e 100644
215--- a/templates/apache-ports.tmpl
216+++ b/templates/apache-ports.tmpl
217@@ -1,4 +1,6 @@
218-<VirtualHost *:80>
219+#for $port in $ports
220+#set $sockets = ' '.join(sorted(['{}:{}'.format(address, port) for address in $addresses]))
221+<VirtualHost ${sockets}>
222 ${apache_early_extra}
223 ServerName ${name}
224 #for $alias in $aliases
225@@ -8,6 +10,13 @@ ${apache_early_extra}
226 CustomLog ${logdir}/${name}-access.log combined
227 ErrorLog ${logdir}/${name}-error.log
228
229+#if $port == 443
230+ SSLEngine On
231+ SSLCertificateFile /etc/apache2/ssl/${name}.crt
232+ SSLCertificateKeyFile /etc/apache2/ssl/${name}.key
233+ SSLCertificateChainFile /etc/apache2/ssl/${name}_chain.crt
234+
235+#end if
236 DocumentRoot /srv/${name}/www
237 Alias /cdimage "/srv/${name}/www/"
238
239@@ -20,3 +29,5 @@ ${apache_early_extra}
240 </Directory>
241 ${apache_late_extra}
242 </VirtualHost>
243+
244+#end for
245diff --git a/templates/apache-releases.tmpl b/templates/apache-releases.tmpl
246index 730d30c..aeae97c 100644
247--- a/templates/apache-releases.tmpl
248+++ b/templates/apache-releases.tmpl
249@@ -1,4 +1,6 @@
250-<VirtualHost *:80>
251+#for $port in $ports
252+#set $sockets = ' '.join(sorted(['{}:{}'.format(address, port) for address in $addresses]))
253+<VirtualHost ${sockets}>
254 ${apache_early_extra}
255 ServerName ${name}
256 #for $alias in $aliases
257@@ -9,6 +11,13 @@ ${apache_early_extra}
258 ErrorLog ${logdir}/${name}-error.log
259 LogFormat "%h %D %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined-ext
260
261+#if $port == 443
262+ SSLEngine On
263+ SSLCertificateFile /etc/apache2/ssl/${name}.crt
264+ SSLCertificateKeyFile /etc/apache2/ssl/${name}.key
265+ SSLCertificateChainFile /etc/apache2/ssl/${name}_chain.crt
266+
267+#end if
268 DocumentRoot /srv/${name}/www
269 Alias /releases "/srv/${name}/www/"
270
271@@ -22,3 +31,5 @@ ${apache_early_extra}
272 </Directory>
273 ${apache_late_extra}
274 </VirtualHost>
275+
276+#end for
277diff --git a/templates/apache-simple-streams.tmpl b/templates/apache-simple-streams.tmpl
278index ea4a16d..8e4b613 100644
279--- a/templates/apache-simple-streams.tmpl
280+++ b/templates/apache-simple-streams.tmpl
281@@ -1,4 +1,6 @@
282-<VirtualHost *:80>
283+#for $port in $ports
284+#set $sockets = ' '.join(sorted(['{}:{}'.format(address, port) for address in $addresses]))
285+<VirtualHost ${sockets}>
286 ${apache_early_extra}
287 ServerName ${name}
288 #for $alias in $aliases
289@@ -9,6 +11,13 @@ ${apache_early_extra}
290 ErrorLog ${logdir}/${name}-error.log
291 LogFormat "%h %D %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined-ext
292
293+#if $port == 443
294+ SSLEngine On
295+ SSLCertificateFile /etc/apache2/ssl/${name}.crt
296+ SSLCertificateKeyFile /etc/apache2/ssl/${name}.key
297+ SSLCertificateChainFile /etc/apache2/ssl/${name}_chain.crt
298+
299+#end if
300 DocumentRoot /srv/${name}/www
301 Alias /simple-streams "/srv/${name}/www/"
302
303@@ -22,3 +31,5 @@ ${apache_early_extra}
304 </Directory>
305 ${apache_late_extra}
306 </VirtualHost>
307+
308+#end for
309diff --git a/templates/apache-ubuntu.tmpl b/templates/apache-ubuntu.tmpl
310index bfe69e6..0887271 100644
311--- a/templates/apache-ubuntu.tmpl
312+++ b/templates/apache-ubuntu.tmpl
313@@ -1,4 +1,6 @@
314-<VirtualHost *:80>
315+#for $port in $ports
316+#set $sockets = ' '.join(sorted(['{}:{}'.format(address, port) for address in $addresses]))
317+<VirtualHost ${sockets}>
318 ${apache_early_extra}
319 ServerName ${name}
320 #for $alias in $aliases
321@@ -8,6 +10,13 @@ ${apache_early_extra}
322 CustomLog ${logdir}/${name}-access.log combined
323 ErrorLog ${logdir}/${name}-error.log
324
325+#if $port == 443
326+ SSLEngine On
327+ SSLCertificateFile /etc/apache2/ssl/${name}.crt
328+ SSLCertificateKeyFile /etc/apache2/ssl/${name}.key
329+ SSLCertificateChainFile /etc/apache2/ssl/${name}_chain.crt
330+
331+#end if
332 DocumentRoot /srv/${name}/www
333 # Munge the Cache-Control/Expires response headers to try make
334 # transparent proxy servers DTRT.
335@@ -39,3 +48,5 @@ ${apache_early_extra}
336 </Directory>
337 ${apache_late_extra}
338 </VirtualHost>
339+
340+#end for

Subscribers

People subscribed via source and target branches