mirror of
https://github.com/certbot/certbot.git
synced 2026-06-03 22:08:07 -04:00
New enhancements proposal
This commit is contained in:
parent
83ea820525
commit
d40f9dc001
5 changed files with 196 additions and 3 deletions
|
|
@ -20,6 +20,7 @@ from certbot import util
|
|||
|
||||
from certbot.plugins import common
|
||||
from certbot.plugins.util import path_surgery
|
||||
from certbot.plugins.enhancements import AutoHSTSEnhancement
|
||||
|
||||
from certbot_apache import apache_util
|
||||
from certbot_apache import augeas_configurator
|
||||
|
|
@ -2156,3 +2157,24 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||
# to be modified.
|
||||
return common.install_version_controlled_file(options_ssl, options_ssl_digest,
|
||||
self.constant("MOD_SSL_CONF_SRC"), constants.ALL_SSL_OPTIONS_HASHES)
|
||||
|
||||
def update_autohsts(self, domain):
|
||||
"""
|
||||
The actual enhancement update method in installer plugin.
|
||||
"""
|
||||
logger.warning("NOOP from update")
|
||||
|
||||
def deploy_autohsts(self, lineage):
|
||||
"""
|
||||
The actual enhancement deploy method in installer plugin.
|
||||
"""
|
||||
logger.warning("NOOP from deploy")
|
||||
|
||||
def enable_autohsts(self, lineage):
|
||||
"""
|
||||
The actual enhancement enabling method in installer plugin.
|
||||
"""
|
||||
logger.warning("NOOP from enable")
|
||||
|
||||
|
||||
AutoHSTSEnhancement.register(ApacheConfigurator)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ from certbot import util
|
|||
|
||||
from certbot.display import util as display_util
|
||||
from certbot.plugins import disco as plugins_disco
|
||||
import certbot.plugins.enhancements as enhancements
|
||||
import certbot.plugins.selection as plugin_selection
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -1201,6 +1202,12 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis
|
|||
" is renewed. This setting does not apply to important TLS configuration"
|
||||
" updates.")
|
||||
|
||||
# Add the new style enhancements
|
||||
for enh in enhancements.INDEX:
|
||||
helpful.add(enh["cli_groups"], enh["cli_flag"], action=enh["cli_action"],
|
||||
dest=enh["cli_dest"], default=enh["cli_flag_default"],
|
||||
help=enh["cli_help"])
|
||||
|
||||
helpful.add_deprecated_argument("--agree-dev-preview", 0)
|
||||
helpful.add_deprecated_argument("--dialog", 0)
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ from certbot import updater
|
|||
from certbot import util
|
||||
|
||||
from certbot.display import util as display_util, ops as display_ops
|
||||
from certbot.plugins import enhancements
|
||||
from certbot.plugins import disco as plugins_disco
|
||||
from certbot.plugins import selection as plug_sel
|
||||
|
||||
|
|
@ -877,7 +878,8 @@ def enhance(config, plugins):
|
|||
"""
|
||||
supported_enhancements = ["hsts", "redirect", "uir", "staple"]
|
||||
# Check that at least one enhancement was requested on command line
|
||||
if not any([getattr(config, enh) for enh in supported_enhancements]):
|
||||
oldstyle_enh = any([getattr(config, enh) for enh in supported_enhancements])
|
||||
if not enhancements.is_supported(config) and not oldstyle_enh:
|
||||
msg = ("Please specify one or more enhancement types to configure. To list "
|
||||
"the available enhancement types, run:\n\n%s --help enhance\n")
|
||||
logger.warning(msg, sys.argv[0])
|
||||
|
|
@ -906,8 +908,11 @@ def enhance(config, plugins):
|
|||
if not config.chain_path:
|
||||
lineage = cert_manager.lineage_for_certname(config, config.certname)
|
||||
config.chain_path = lineage.chain_path
|
||||
le_client = _init_le_client(config, authenticator=None, installer=installer)
|
||||
le_client.enhance_config(domains, config.chain_path, ask_redirect=False)
|
||||
if oldstyle_enh:
|
||||
le_client = _init_le_client(config, authenticator=None, installer=installer)
|
||||
le_client.enhance_config(domains, config.chain_path, ask_redirect=False)
|
||||
if enhancements.is_supported(config):
|
||||
enhancements.enable(lineage, installer, config)
|
||||
|
||||
|
||||
def rollback(config, plugins):
|
||||
|
|
|
|||
109
certbot/plugins/enhancements.py
Normal file
109
certbot/plugins/enhancements.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
import abc
|
||||
import six
|
||||
|
||||
from certbot import errors
|
||||
|
||||
def is_supported(config):
|
||||
"""Checks if one or more of the requested enhancements are supported by
|
||||
the enhancement interfaces."""
|
||||
supported = []
|
||||
for enh in INDEX:
|
||||
if hasattr(config, enh["cli_dest"]):
|
||||
supported.append(getattr(config, enh["cli_dest"]))
|
||||
return bool(supported)
|
||||
|
||||
def enable(lineage, installer, config):
|
||||
"""
|
||||
Run enable method for each requested enhancement that is supported.
|
||||
|
||||
:param lineage: Certificate lineage object
|
||||
:type lineage: storage.RenewableCert
|
||||
|
||||
:param installer: Installer object
|
||||
:type installer: interfaces.IInstaller
|
||||
|
||||
:param config: Configuration.
|
||||
:type config: :class:`certbot.interfaces.IConfig`
|
||||
"""
|
||||
for enh in INDEX:
|
||||
if hasattr(config, enh["cli_dest"]) and getattr(config, enh["cli_dest"]):
|
||||
if not isinstance(installer, enh["class"]):
|
||||
msg = ("Requested enhancement {} not supported by selected "
|
||||
"installer").format(enh["name"])
|
||||
raise errors.NotSupportedError(msg)
|
||||
# Run the enable function
|
||||
getattr(installer, enh["enable_function"])(lineage)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class AutoHSTSEnhancement(object):
|
||||
"""Example enhancement interface class for AutoHSTS"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_autohsts(self, domain, *args, **kwargs):
|
||||
"""As updater function, takes the same parameters as
|
||||
interfaces.GenericUpdater.generic_updates
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def deploy_autohsts(self, lineage, *args, **kwargs):
|
||||
"""As renewer function, takes the same parameters as
|
||||
interfaces.RenewDeployer
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def enable_autohsts(self, lineage, *args, **kwargs):
|
||||
"""Installer function, uses lineage as a parameter.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class OCSPPrefetchEnhancement(object):
|
||||
"""Example enhancement interface class for OCSP prefetch"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_ocsp_prefetch(self, domain, *args, **kwargs):
|
||||
"""As updater function, takes the same parameters as
|
||||
interfaces.GenericUpdater.generic_updates
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def deploy_ocsp_prefetch(self, lineage, *args, **kwargs):
|
||||
"""As renewer function, takes the same parameters as
|
||||
interfaces.RenewDeployer
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def enable_ocsp_prefetch(self, lineage, *args, **kwargs):
|
||||
"""Installer function, uses lineage as a parameter."""
|
||||
|
||||
|
||||
INDEX = [
|
||||
{
|
||||
"name": "AutoHSTS",
|
||||
"cli_help": "Gradually increasing max-age value for HTTP Strict Transport "+
|
||||
"Security security header",
|
||||
"cli_flag": "--autohsts",
|
||||
"cli_flag_default": None,
|
||||
"cli_groups": ["security", "enhance"],
|
||||
"cli_dest": "auto_hsts",
|
||||
"cli_action": "store_true",
|
||||
"class": AutoHSTSEnhancement,
|
||||
"updater_function": "update_autohsts",
|
||||
"deployer_function": "deploy_autohsts",
|
||||
"enable_function": "enable_autohsts"
|
||||
},
|
||||
{
|
||||
"name": "OCSP Prefetch",
|
||||
"cli_help": "Prefetch OCSP responses within scheduled run with renew verb",
|
||||
"cli_flag": "--ocspprefetch",
|
||||
"cli_flag_default": None,
|
||||
"cli_groups": ["security", "enhance"],
|
||||
"cli_dest": "ocsp_prefetch",
|
||||
"cli_action": "store_true",
|
||||
"class": OCSPPrefetchEnhancement,
|
||||
"updater_function": "update_ocsp_prefetch",
|
||||
"deployer_function": None,
|
||||
"enable_function": "enable_ocsp_prefetch"
|
||||
}
|
||||
]
|
||||
|
|
@ -5,6 +5,7 @@ from certbot import errors
|
|||
from certbot import interfaces
|
||||
|
||||
from certbot.plugins import selection as plug_sel
|
||||
import certbot.plugins.enhancements as enhancements
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ def run_generic_updaters(config, plugins, lineage):
|
|||
logger.warning("Could not choose appropriate plugin for updaters: %s", e)
|
||||
return
|
||||
_run_updaters(lineage, installer, config)
|
||||
_run_enhancement_updaters(lineage, installer, config)
|
||||
|
||||
def run_renewal_deployer(lineage, installer, config):
|
||||
"""Helper function to run deployer interface method if supported by the used
|
||||
|
|
@ -47,6 +49,7 @@ def run_renewal_deployer(lineage, installer, config):
|
|||
if not config.disable_renew_updates and isinstance(installer,
|
||||
interfaces.RenewDeployer):
|
||||
installer.renew_deploy(lineage)
|
||||
_run_enhancement_deployers(lineage, installer, config)
|
||||
|
||||
def _run_updaters(lineage, installer, config):
|
||||
"""Helper function to run the updater interface methods if supported by the
|
||||
|
|
@ -65,3 +68,50 @@ def _run_updaters(lineage, installer, config):
|
|||
if not config.disable_renew_updates:
|
||||
if isinstance(installer, interfaces.GenericUpdater):
|
||||
installer.generic_updates(domain)
|
||||
|
||||
def _run_enhancement_updaters(lineage, installer, config):
|
||||
"""Iterates through known enhancement interfaces. If the installer implements
|
||||
an enhancement interface and the enhance interface has an updater method, the
|
||||
updater method gets run.
|
||||
|
||||
:param lineage: Certificate lineage object
|
||||
:type lineage: storage.RenewableCert
|
||||
|
||||
:param installer: Installer object
|
||||
:type installer: interfaces.IInstaller
|
||||
|
||||
:param config: Configuration object
|
||||
:type config: interfaces.IConfig
|
||||
"""
|
||||
|
||||
if config.disable_renew_updates:
|
||||
return
|
||||
for enh in enhancements.INDEX:
|
||||
if isinstance(installer, enh["class"]) and enh["updater_function"]:
|
||||
upd_func = getattr(installer, enh["updater_function"])
|
||||
for domain in lineage.names():
|
||||
upd_func(domain)
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
def _run_enhancement_deployers(lineage, installer, config):
|
||||
"""Iterates through known enhancement interfaces. If the installer implements
|
||||
an enhancement interface and the enhance interface has an deployer method, the
|
||||
deployer method gets run.
|
||||
|
||||
:param lineage: Certificate lineage object
|
||||
:type lineage: storage.RenewableCert
|
||||
|
||||
:param installer: Installer object
|
||||
:type installer: interfaces.IInstaller
|
||||
|
||||
:param config: Configuration object
|
||||
:type config: interfaces.IConfig
|
||||
"""
|
||||
|
||||
if config.disable_renew_updates:
|
||||
return
|
||||
for enh in enhancements.INDEX:
|
||||
if isinstance(installer, enh["class"]) and enh["deployer_function"]:
|
||||
getattr(installer, enh["deployer_function"])(lineage)
|
||||
|
|
|
|||
Loading…
Reference in a new issue