certbot/certbot-apache/certbot_apache/http_01.py

126 lines
4.2 KiB
Python
Raw Permalink Normal View History

"""A class that performs HTTP-01 challenges for Apache"""
import logging
import os
from certbot.plugins import common
logger = logging.getLogger(__name__)
class ApacheHttp01(common.TLSSNI01):
2018-01-16 19:04:11 -05:00
"""Class that performs HTTP-01 challenges within the Apache configurator."""
2018-01-16 19:04:11 -05:00
CONFIG_TEMPLATE22 = """\
2018-01-16 21:19:34 -05:00
RewriteEngine on
RewriteRule ^/\\.well-known/acme-challenge/([A-Za-z0-9-_=]+)$ {0}/$1 [L]
2018-01-16 19:04:11 -05:00
<Directory {0}>
2018-01-16 21:46:44 -05:00
Order Allow,Deny
2018-01-16 19:04:11 -05:00
Allow from all
</Directory>
"""
CONFIG_TEMPLATE24 = """\
2018-01-16 21:19:34 -05:00
RewriteEngine on
RewriteRule ^/\\.well-known/acme-challenge/([A-Za-z0-9-_=]+)$ {0}/$1 [END]
2018-01-16 19:04:11 -05:00
<Directory {0}>
Require all granted
</Directory>
"""
def __init__(self, *args, **kwargs):
super(ApacheHttp01, self).__init__(*args, **kwargs)
self.challenge_conf = os.path.join(
self.configurator.conf("challenge-location"),
"le_http_01_challenge.conf")
self.challenge_dir = os.path.join(
self.configurator.config.work_dir,
"http_challenges")
def perform(self):
"""Perform all HTTP-01 challenges."""
if not self.achalls:
return []
# Save any changes to the configuration as a precaution
# About to make temporary changes to the config
self.configurator.save("Changes before challenge setup", True)
self.configurator.ensure_listen(str(
self.configurator.config.http01_port))
self.prepare_http01_modules()
responses = self._set_up_challenges()
2018-01-16 19:04:11 -05:00
self._mod_config()
# Save reversible changes
self.configurator.save("HTTP Challenge", True)
return responses
def prepare_http01_modules(self):
"""Make sure that we have the needed modules available for http01"""
if self.configurator.conf("handle-modules"):
2018-01-16 21:18:16 -05:00
needed_modules = ["rewrite"]
if self.configurator.version < (2, 4):
needed_modules.append("authz_host")
else:
needed_modules.append("authz_core")
for mod in needed_modules:
if mod + "_module" not in self.configurator.parser.modules:
self.configurator.enable_mod(mod, temp=True)
def _mod_config(self):
2018-01-17 00:12:40 -05:00
moded_vhosts = set()
2018-01-16 19:04:11 -05:00
for chall in self.achalls:
2018-01-17 01:28:58 -05:00
vh = self.configurator.find_best_http_vhost(
chall.domain, filter_defaults=False,
port=str(self.configurator.config.http01_port))
2018-01-17 00:13:13 -05:00
if vh and vh not in moded_vhosts:
2018-01-16 19:04:11 -05:00
self._set_up_include_directive(vh)
2018-01-17 00:12:40 -05:00
moded_vhosts.add(vh)
2018-01-16 19:04:11 -05:00
self.configurator.reverter.register_file_creation(
True, self.challenge_conf)
2018-01-16 19:04:11 -05:00
if self.configurator.version < (2, 4):
2018-01-16 21:17:35 -05:00
config_template = self.CONFIG_TEMPLATE22
2018-01-16 19:04:11 -05:00
else:
2018-01-16 21:17:35 -05:00
config_template = self.CONFIG_TEMPLATE24
2018-01-16 19:04:11 -05:00
config_text = config_template.format(self.challenge_dir)
logger.debug("writing a config file with text:\n %s", config_text)
with open(self.challenge_conf, "w") as new_conf:
new_conf.write(config_text)
def _set_up_challenges(self):
if not os.path.isdir(self.challenge_dir):
os.makedirs(self.challenge_dir)
os.chmod(self.challenge_dir, 0o755)
responses = []
for achall in self.achalls:
responses.append(self._set_up_challenge(achall))
return responses
def _set_up_challenge(self, achall):
response, validation = achall.response_and_validation()
name = os.path.join(self.challenge_dir, achall.chall.encode("token"))
self.configurator.reverter.register_file_creation(True, name)
with open(name, 'wb') as f:
f.write(validation.encode())
os.chmod(name, 0o644)
return response
2018-01-16 19:04:11 -05:00
def _set_up_include_directive(self, vhost):
"""Includes override configuration to the beginning of VirtualHost.
Note that this include isn't added to Augeas search tree"""
self.configurator.parser.add_dir_beginning(vhost.path, "Include",
self.challenge_conf)