Skip to content

Commit d135e61

Browse files
authored
apache: handle statically linked mod_ssl (certbot#8007)
In certbot#7771, the Apache configurator gained the ability to identify what version of OpenSSL Apache's ssl_module is linked against. However, the detection was only functional if the module was built as a DSO (which is almost always the case). This commit covers the case where the ssl_module is statically linked within the Apache binary. It requires the user to specify the path to the binary (with --apache-bin) and emits a warning if static linking is detected but no path has been provided.
1 parent 010b38f commit d135e61

File tree

10 files changed

+45
-9
lines changed

10 files changed

+45
-9
lines changed

certbot-apache/certbot_apache/_internal/configurator.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class ApacheConfigurator(common.Installer):
115115
handle_modules=False,
116116
handle_sites=False,
117117
challenge_location="/etc/apache2",
118+
bin=None
118119
)
119120

120121
def option(self, key):
@@ -145,7 +146,7 @@ def _prepare_options(self):
145146
"""
146147
opts = ["enmod", "dismod", "le_vhost_ext", "server_root", "vhost_root",
147148
"logs_root", "challenge_location", "handle_modules", "handle_sites",
148-
"ctl"]
149+
"ctl", "bin"]
149150
for o in opts:
150151
# Config options use dashes instead of underscores
151152
if self.conf(o.replace("_", "-")) is not None:
@@ -194,6 +195,8 @@ def add_parser_arguments(cls, add):
194195
"(Only Ubuntu/Debian currently)")
195196
add("ctl", default=DEFAULTS["ctl"],
196197
help="Full path to Apache control script")
198+
add("bin", default=DEFAULTS["bin"],
199+
help="Full path to apache2/httpd binary")
197200

198201
def __init__(self, *args, **kwargs):
199202
"""Initialize an Apache Configurator.
@@ -269,18 +272,25 @@ def openssl_version(self, warn_on_no_mod_ssl=True):
269272
"""
270273
if self._openssl_version:
271274
return self._openssl_version
272-
# Step 1. Check for LoadModule directive
275+
# Step 1. Determine the location of ssl_module
273276
try:
274277
ssl_module_location = self.parser.modules['ssl_module']
275278
except KeyError:
276279
if warn_on_no_mod_ssl:
277280
logger.warning("Could not find ssl_module; not disabling session tickets.")
278281
return None
279-
if not ssl_module_location:
280-
logger.warning("Could not find ssl_module; not disabling session tickets.")
281-
return None
282-
ssl_module_location = self.parser.standard_path_from_server_root(ssl_module_location)
283-
# Step 2. Grep in the .so for openssl version
282+
if ssl_module_location:
283+
# Possibility A: ssl_module is a DSO
284+
ssl_module_location = self.parser.standard_path_from_server_root(ssl_module_location)
285+
else:
286+
# Possibility B: ssl_module is statically linked into Apache
287+
if self.option("bin"):
288+
ssl_module_location = self.option("bin")
289+
else:
290+
logger.warning("ssl_module is statically linked but --apache-bin is "
291+
"missing; not disabling session tickets.")
292+
return None
293+
# Step 2. Grep in the binary for openssl version
284294
contents = self._open_module_file(ssl_module_location)
285295
if not contents:
286296
logger.warning("Unable to read ssl_module file; not disabling session tickets.")

certbot-apache/certbot_apache/_internal/override_arch.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ class ArchConfigurator(configurator.ApacheConfigurator):
2424
handle_modules=False,
2525
handle_sites=False,
2626
challenge_location="/etc/httpd/conf",
27+
bin=None,
2728
)

certbot-apache/certbot_apache/_internal/override_centos.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
3535
handle_modules=False,
3636
handle_sites=False,
3737
challenge_location="/etc/httpd/conf.d",
38+
bin=None,
3839
)
3940

4041
def config_test(self):

certbot-apache/certbot_apache/_internal/override_darwin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ class DarwinConfigurator(configurator.ApacheConfigurator):
2424
handle_modules=False,
2525
handle_sites=False,
2626
challenge_location="/etc/apache2/other",
27+
bin=None,
2728
)

certbot-apache/certbot_apache/_internal/override_debian.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class DebianConfigurator(configurator.ApacheConfigurator):
3333
handle_modules=True,
3434
handle_sites=True,
3535
challenge_location="/etc/apache2",
36+
bin=None,
3637
)
3738

3839
def enable_site(self, vhost):

certbot-apache/certbot_apache/_internal/override_fedora.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class FedoraConfigurator(configurator.ApacheConfigurator):
2929
handle_modules=False,
3030
handle_sites=False,
3131
challenge_location="/etc/httpd/conf.d",
32+
bin=None,
3233
)
3334

3435
def config_test(self):

certbot-apache/certbot_apache/_internal/override_gentoo.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class GentooConfigurator(configurator.ApacheConfigurator):
2727
handle_modules=False,
2828
handle_sites=False,
2929
challenge_location="/etc/apache2/vhosts.d",
30+
bin=None,
3031
)
3132

3233
def _prepare_options(self):

certbot-apache/certbot_apache/_internal/override_suse.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ class OpenSUSEConfigurator(configurator.ApacheConfigurator):
2424
handle_modules=False,
2525
handle_sites=False,
2626
challenge_location="/etc/apache2/vhosts.d",
27+
bin=None,
2728
)

certbot-apache/tests/configurator_test.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1772,12 +1772,22 @@ def test_openssl_version(self):
17721772
AH02556: "SSLOpenSSLConfCmd %s %s" applied to %s
17731773
OpenSSL 1.0.2g 1 Mar 2016
17741774
"""
1775+
# ssl_module as a DSO
17751776
self.config.parser.modules['ssl_module'] = '/fake/path'
17761777
with mock.patch("certbot_apache._internal.configurator."
17771778
"ApacheConfigurator._open_module_file") as mock_omf:
17781779
mock_omf.return_value = some_string_contents
17791780
self.assertEqual(self.config.openssl_version(), "1.0.2g")
17801781

1782+
# ssl_module statically linked
1783+
self.config._openssl_version = None
1784+
self.config.parser.modules['ssl_module'] = None
1785+
self.config.options['bin'] = '/fake/path/to/httpd'
1786+
with mock.patch("certbot_apache._internal.configurator."
1787+
"ApacheConfigurator._open_module_file") as mock_omf:
1788+
mock_omf.return_value = some_string_contents
1789+
self.assertEqual(self.config.openssl_version(), "1.0.2g")
1790+
17811791
def test_current_version(self):
17821792
self.config.version = (2, 4, 10)
17831793
self.config._openssl_version = '1.0.2m'
@@ -1799,12 +1809,21 @@ def test_openssl_version_warns(self):
17991809
self.assertEqual(self.config.openssl_version(), None)
18001810
self.assertTrue("Could not find ssl_module" in mock_log.call_args[0][0])
18011811

1812+
# When no ssl_module is present at all
18021813
self.config._openssl_version = None
1803-
self.config.parser.modules['ssl_module'] = None
1814+
self.assertTrue("ssl_module" not in self.config.parser.modules)
18041815
with mock.patch("certbot_apache._internal.configurator.logger.warning") as mock_log:
18051816
self.assertEqual(self.config.openssl_version(), None)
18061817
self.assertTrue("Could not find ssl_module" in mock_log.call_args[0][0])
18071818

1819+
# When ssl_module is statically linked but --apache-bin not provided
1820+
self.config._openssl_version = None
1821+
self.config.options['bin'] = None
1822+
self.config.parser.modules['ssl_module'] = None
1823+
with mock.patch("certbot_apache._internal.configurator.logger.warning") as mock_log:
1824+
self.assertEqual(self.config.openssl_version(), None)
1825+
self.assertTrue("ssl_module is statically linked but" in mock_log.call_args[0][0])
1826+
18081827
self.config.parser.modules['ssl_module'] = "/fake/path"
18091828
with mock.patch("certbot_apache._internal.configurator.logger.warning") as mock_log:
18101829
# Check that correct logger.warning was printed

certbot/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
1010

1111
### Changed
1212

13-
*
13+
* Allow session tickets to be disabled in Apache when mod_ssl is statically linked.
1414

1515
### Fixed
1616

0 commit comments

Comments
 (0)