Compare commits
41 Commits
test-apach
...
also-mod-h
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afc0c20161 | ||
|
|
c2567863ef | ||
|
|
0ed5d565db | ||
|
|
14cd2ddf17 | ||
|
|
3a6607e897 | ||
|
|
01d8765395 | ||
|
|
c65d8635fb | ||
|
|
f555d19422 | ||
|
|
9bcec50185 | ||
|
|
22d52cd0df | ||
|
|
8ab1992789 | ||
|
|
d89aa9409f | ||
|
|
490bc3a865 | ||
|
|
a9c67cfbfc | ||
|
|
076d97da9f | ||
|
|
d96156f3fe | ||
|
|
53c4ae1169 | ||
|
|
8aa72dab4a | ||
|
|
a9587f7d3a | ||
|
|
26e4ce35cb | ||
|
|
459d6b7786 | ||
|
|
1c55846d20 | ||
|
|
cd3d9f49a7 | ||
|
|
95ba8364cd | ||
|
|
83261a7ce1 | ||
|
|
607fa341ab | ||
|
|
874a3c6a01 | ||
|
|
cf3212eb24 | ||
|
|
a56dfe68e9 | ||
|
|
280de3751a | ||
|
|
8ee2daf298 | ||
|
|
7f18c3de49 | ||
|
|
587e519ed4 | ||
|
|
6468c0bfe8 | ||
|
|
8deec9fa15 | ||
|
|
a53bdeb122 | ||
|
|
3977e4e7d2 | ||
|
|
0d6fee7a8d | ||
|
|
16542b2ff2 | ||
|
|
0834649654 | ||
|
|
efd87a872b |
@@ -6,6 +6,7 @@ Certbot adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
### Added
|
||||
|
||||
* Also create an https vhost when using http-01 authentication in Nginx.
|
||||
* `revoke` accepts `--cert-name`, and doesn't accept both `--cert-name` and `--cert-path`.
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -8,7 +8,6 @@ import tempfile
|
||||
import time
|
||||
|
||||
import OpenSSL
|
||||
import six
|
||||
import zope.interface
|
||||
|
||||
from acme import challenges
|
||||
@@ -32,6 +31,12 @@ from certbot_nginx import obj # pylint: disable=unused-import
|
||||
from acme.magic_typing import List, Dict, Set # pylint: disable=unused-import, no-name-in-module
|
||||
|
||||
|
||||
NAME_RANK = 0
|
||||
START_WILDCARD_RANK = 1
|
||||
END_WILDCARD_RANK = 2
|
||||
REGEX_RANK = 3
|
||||
NO_SSL_MODIFIER = 4
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -405,7 +410,8 @@ class NginxConfigurator(common.Installer):
|
||||
"""
|
||||
if not matches:
|
||||
return None
|
||||
elif matches[0]['rank'] in six.moves.range(2, 6):
|
||||
elif matches[0]['rank'] in [START_WILDCARD_RANK, END_WILDCARD_RANK,
|
||||
START_WILDCARD_RANK + NO_SSL_MODIFIER, END_WILDCARD_RANK + NO_SSL_MODIFIER]:
|
||||
# Wildcard match - need to find the longest one
|
||||
rank = matches[0]['rank']
|
||||
wildcards = [x for x in matches if x['rank'] == rank]
|
||||
@@ -414,10 +420,8 @@ class NginxConfigurator(common.Installer):
|
||||
# Exact or regex match
|
||||
return matches[0]['vhost']
|
||||
|
||||
|
||||
def _rank_matches_by_name_and_ssl(self, vhost_list, target_name):
|
||||
def _rank_matches_by_name(self, vhost_list, target_name):
|
||||
"""Returns a ranked list of vhosts from vhost_list that match target_name.
|
||||
The ranking gives preference to SSL vhosts.
|
||||
|
||||
:param list vhost_list: list of vhosts to filter and rank
|
||||
:param str target_name: The name to match
|
||||
@@ -437,21 +441,37 @@ class NginxConfigurator(common.Installer):
|
||||
if name_type == 'exact':
|
||||
matches.append({'vhost': vhost,
|
||||
'name': name,
|
||||
'rank': 0 if vhost.ssl else 1})
|
||||
'rank': NAME_RANK})
|
||||
elif name_type == 'wildcard_start':
|
||||
matches.append({'vhost': vhost,
|
||||
'name': name,
|
||||
'rank': 2 if vhost.ssl else 3})
|
||||
'rank': START_WILDCARD_RANK})
|
||||
elif name_type == 'wildcard_end':
|
||||
matches.append({'vhost': vhost,
|
||||
'name': name,
|
||||
'rank': 4 if vhost.ssl else 5})
|
||||
'rank': END_WILDCARD_RANK})
|
||||
elif name_type == 'regex':
|
||||
matches.append({'vhost': vhost,
|
||||
'name': name,
|
||||
'rank': 6 if vhost.ssl else 7})
|
||||
'rank': REGEX_RANK})
|
||||
return sorted(matches, key=lambda x: x['rank'])
|
||||
|
||||
def _rank_matches_by_name_and_ssl(self, vhost_list, target_name):
|
||||
"""Returns a ranked list of vhosts from vhost_list that match target_name.
|
||||
The ranking gives preference to SSLishness before name match level.
|
||||
|
||||
:param list vhost_list: list of vhosts to filter and rank
|
||||
:param str target_name: The name to match
|
||||
:returns: list of dicts containing the vhost, the matching name, and
|
||||
the numerical rank
|
||||
:rtype: list
|
||||
|
||||
"""
|
||||
matches = self._rank_matches_by_name(vhost_list, target_name)
|
||||
for match in matches:
|
||||
if not match['vhost'].ssl:
|
||||
match['rank'] += NO_SSL_MODIFIER
|
||||
return sorted(matches, key=lambda x: x['rank'])
|
||||
|
||||
def choose_redirect_vhosts(self, target_name, port, create_if_no_match=False):
|
||||
"""Chooses a single virtual host for redirect enhancement.
|
||||
@@ -486,6 +506,40 @@ class NginxConfigurator(common.Installer):
|
||||
vhosts = [self._vhost_from_duplicated_default(target_name, False, port)]
|
||||
return vhosts
|
||||
|
||||
def choose_http_and_https_vhosts(self, target_name, http_port):
|
||||
"""Chooses at least one http virtual host and at least one https virtual host.
|
||||
|
||||
Chooses the vhosts most closely matching target_name that are
|
||||
listening without using ssl on http_port and with ssl.
|
||||
|
||||
:param str target_name: domain name
|
||||
:param str http_port: http port number
|
||||
|
||||
:returns: (http_vhost, https_vhost) associated with target_name
|
||||
:rtype: tuple of :class:`~certbot_nginx.obj.VirtualHost`
|
||||
|
||||
"""
|
||||
# goal: return a set of vhosts that contains at least one http server and at least one
|
||||
# https server
|
||||
if util.is_wildcard_domain(target_name):
|
||||
raise errors.NotSupportedError("Wildcard issuance not supported by this method.")
|
||||
|
||||
try:
|
||||
https_vhosts = self.choose_vhosts(target_name, create_if_no_match=True)
|
||||
except errors.MisconfigurationError:
|
||||
# we couldn't choose a default and there was no match
|
||||
https_vhosts = []
|
||||
# https_vhosts will be definitely have an https block, maybe also http. in case there's
|
||||
# an ssl-only block, run choose_redirect vhosts to find a matching http block
|
||||
try:
|
||||
http_vhosts = self.choose_redirect_vhosts(target_name, http_port,
|
||||
create_if_no_match=True)
|
||||
except errors.MisconfigurationError:
|
||||
# we couldn't choose a default and there was no match
|
||||
http_vhosts = []
|
||||
|
||||
return (http_vhosts, https_vhosts)
|
||||
|
||||
def _port_matches(self, test_port, matching_port):
|
||||
# test_port is a number, matching is a number or "" or None
|
||||
if matching_port == "" or matching_port is None:
|
||||
@@ -531,9 +585,7 @@ class NginxConfigurator(common.Installer):
|
||||
|
||||
matching_vhosts = [vhost for vhost in all_vhosts if _vhost_matches(vhost, port)]
|
||||
|
||||
# We can use this ranking function because sslishness doesn't matter to us, and
|
||||
# there shouldn't be conflicting plaintextish servers listening on 80.
|
||||
return self._rank_matches_by_name_and_ssl(matching_vhosts, target_name)
|
||||
return self._rank_matches_by_name(matching_vhosts, target_name)
|
||||
|
||||
def get_all_names(self):
|
||||
"""Returns all names found in the Nginx Configuration.
|
||||
@@ -567,7 +619,8 @@ class NginxConfigurator(common.Installer):
|
||||
|
||||
return util.get_filtered_names(all_names)
|
||||
|
||||
def _get_snakeoil_paths(self):
|
||||
def get_snakeoil_paths(self):
|
||||
"""Generate invalid certs that let us create ssl directives for Nginx"""
|
||||
# TODO: generate only once
|
||||
tmp_dir = os.path.join(self.config.work_dir, "snakeoil")
|
||||
le_key = crypto_util.init_save_key(
|
||||
@@ -622,7 +675,7 @@ class NginxConfigurator(common.Installer):
|
||||
' ',
|
||||
'ssl']
|
||||
|
||||
snakeoil_cert, snakeoil_key = self._get_snakeoil_paths()
|
||||
snakeoil_cert, snakeoil_key = self.get_snakeoil_paths()
|
||||
|
||||
ssl_block = ([
|
||||
ipv6_block,
|
||||
|
||||
@@ -40,8 +40,6 @@ class NginxHttp01(common.ChallengePerformer):
|
||||
super(NginxHttp01, self).__init__(configurator)
|
||||
self.challenge_conf = os.path.join(
|
||||
configurator.config.config_dir, "le_http_01_cert_challenge.conf")
|
||||
self._ipv6 = None
|
||||
self._ipv6only = None
|
||||
|
||||
def perform(self):
|
||||
"""Perform a challenge on Nginx.
|
||||
@@ -102,6 +100,7 @@ class NginxHttp01(common.ChallengePerformer):
|
||||
config = [self._make_or_mod_server_block(achall) for achall in self.achalls]
|
||||
config = [x for x in config if x is not None]
|
||||
config = nginxparser.UnspacedList(config)
|
||||
logger.debug("Generated server block:\n%s", str(config))
|
||||
|
||||
self.configurator.reverter.register_file_creation(
|
||||
True, self.challenge_conf)
|
||||
@@ -115,29 +114,32 @@ class NginxHttp01(common.ChallengePerformer):
|
||||
:rtype: list
|
||||
"""
|
||||
addresses = [] # type: List[obj.Addr]
|
||||
default_addr = "%s" % self.configurator.config.http01_port
|
||||
ipv6_addr = "[::]:{0}".format(
|
||||
self.configurator.config.http01_port)
|
||||
|
||||
port = self.configurator.config.http01_port
|
||||
ssl_port = self.configurator.config.tls_sni_01_port
|
||||
|
||||
if self._ipv6 is None or self._ipv6only is None:
|
||||
self._ipv6, self._ipv6only = self.configurator.ipv6_info(port)
|
||||
ipv6, ipv6only = self._ipv6, self._ipv6only
|
||||
http_items = {}
|
||||
https_items = {}
|
||||
|
||||
if ipv6:
|
||||
# If IPv6 is active in Nginx configuration
|
||||
if not ipv6only:
|
||||
# If ipv6only=on is not already present in the config
|
||||
ipv6_addr = ipv6_addr + " ipv6only=on"
|
||||
addresses = [obj.Addr.fromstring(default_addr),
|
||||
obj.Addr.fromstring(ipv6_addr)]
|
||||
logger.info(("Using default addresses %s and %s for authentication."),
|
||||
default_addr,
|
||||
ipv6_addr)
|
||||
else:
|
||||
addresses = [obj.Addr.fromstring(default_addr)]
|
||||
logger.info("Using default address %s for authentication.",
|
||||
default_addr)
|
||||
http_items["ipv4_addr"] = "%s" % port
|
||||
http_items["ipv6_addr"] = "[::]:{0}".format(port)
|
||||
https_items["ipv4_addr"] = '{0} ssl'.format(ssl_port)
|
||||
https_items["ipv6_addr"] = '[::]:{0} ssl'.format(ssl_port)
|
||||
|
||||
http_items["ipv6"], http_items["ipv6only"] = self.configurator.ipv6_info(port)
|
||||
https_items["ipv6"], https_items["ipv6only"] = self.configurator.ipv6_info(ssl_port)
|
||||
|
||||
addresses = []
|
||||
for items in (http_items, https_items):
|
||||
addresses.append(obj.Addr.fromstring(items["ipv4_addr"]))
|
||||
if items["ipv6"]:
|
||||
# If IPv6 is active in Nginx configuration
|
||||
if not items["ipv6only"]:
|
||||
# If ipv6only=on is not already present in the config
|
||||
items["ipv6_addr"] = items["ipv6_addr"] + " ipv6only=on"
|
||||
addresses.append(obj.Addr.fromstring(items["ipv6_addr"]))
|
||||
|
||||
logger.info("Using default addresses for authentication.")
|
||||
return addresses
|
||||
|
||||
def _get_validation_path(self, achall):
|
||||
@@ -164,6 +166,17 @@ class NginxHttp01(common.ChallengePerformer):
|
||||
['root', ' ', document_root],
|
||||
self._location_directive_for_achall(achall)
|
||||
])
|
||||
|
||||
snakeoil_cert, snakeoil_key = self.configurator.get_snakeoil_paths()
|
||||
|
||||
ssl_block = ([
|
||||
['\n ', 'ssl_certificate', ' ', snakeoil_cert],
|
||||
['\n ', 'ssl_certificate_key', ' ', snakeoil_key],
|
||||
['\n ', 'include', ' ', self.configurator.mod_ssl_conf],
|
||||
['\n ', 'ssl_dhparam', ' ', self.configurator.ssl_dhparams],
|
||||
])
|
||||
block.extend(ssl_block)
|
||||
|
||||
# TODO: do we want to return something else if they otherwise access this block?
|
||||
return [['server'], block]
|
||||
|
||||
@@ -185,25 +198,25 @@ class NginxHttp01(common.ChallengePerformer):
|
||||
:class:`certbot.achallenges.KeyAuthorizationAnnotatedChallenge`
|
||||
|
||||
"""
|
||||
try:
|
||||
vhosts = self.configurator.choose_redirect_vhosts(achall.domain,
|
||||
'%i' % self.configurator.config.http01_port, create_if_no_match=True)
|
||||
except errors.MisconfigurationError:
|
||||
http_vhosts, https_vhosts = self.configurator.choose_http_and_https_vhosts(achall.domain,
|
||||
'%i' % self.configurator.config.http01_port)
|
||||
|
||||
vhosts = set(https_vhosts).union(http_vhosts)
|
||||
|
||||
for vhost in vhosts:
|
||||
# Modify existing server block
|
||||
location_directive = [self._location_directive_for_achall(achall)]
|
||||
|
||||
self.configurator.parser.add_server_directives(vhost,
|
||||
location_directive)
|
||||
|
||||
rewrite_directive = [['rewrite', ' ', '^(/.well-known/acme-challenge/.*)',
|
||||
' ', '$1', ' ', 'break']]
|
||||
self.configurator.parser.add_server_directives(vhost,
|
||||
rewrite_directive, insert_at_top=True)
|
||||
|
||||
# if vhosts doesn't contain at least one http and one https, make our own
|
||||
if not http_vhosts or not https_vhosts:
|
||||
# Couldn't find either a matching name+port server block
|
||||
# or a port+default_server block, so create a dummy block
|
||||
return self._make_server_block(achall)
|
||||
|
||||
# len is max 1 because Nginx doesn't authenticate wildcards
|
||||
# if len were or vhosts None, we would have errored
|
||||
vhost = vhosts[0]
|
||||
|
||||
# Modify existing server block
|
||||
location_directive = [self._location_directive_for_achall(achall)]
|
||||
|
||||
self.configurator.parser.add_server_directives(vhost,
|
||||
location_directive)
|
||||
|
||||
rewrite_directive = [['rewrite', ' ', '^(/.well-known/acme-challenge/.*)',
|
||||
' ', '$1', ' ', 'break']]
|
||||
self.configurator.parser.add_server_directives(vhost,
|
||||
rewrite_directive, insert_at_top=True)
|
||||
|
||||
@@ -36,7 +36,7 @@ class Addr(common.Addr):
|
||||
UNSPECIFIED_IPV4_ADDRESSES = ('', '*', '0.0.0.0')
|
||||
CANONICAL_UNSPECIFIED_ADDRESS = UNSPECIFIED_IPV4_ADDRESSES[0]
|
||||
|
||||
def __init__(self, host, port, ssl, default, ipv6, ipv6only):
|
||||
def __init__(self, host, port, ssl, default, ipv6, ipv6only, otherparts=None):
|
||||
# pylint: disable=too-many-arguments
|
||||
super(Addr, self).__init__((host, port))
|
||||
self.ssl = ssl
|
||||
@@ -44,6 +44,7 @@ class Addr(common.Addr):
|
||||
self.ipv6 = ipv6
|
||||
self.ipv6only = ipv6only
|
||||
self.unspecified_address = host in self.UNSPECIFIED_IPV4_ADDRESSES
|
||||
self.otherparts = otherparts
|
||||
|
||||
@classmethod
|
||||
def fromstring(cls, str_addr):
|
||||
@@ -84,6 +85,7 @@ class Addr(common.Addr):
|
||||
port = tup[2]
|
||||
|
||||
# The rest of the parts are options; we only care about ssl and default
|
||||
otherparts = set()
|
||||
while len(parts) > 0:
|
||||
nextpart = parts.pop()
|
||||
if nextpart == 'ssl':
|
||||
@@ -94,8 +96,10 @@ class Addr(common.Addr):
|
||||
default = True
|
||||
elif nextpart == "ipv6only=on":
|
||||
ipv6only = True
|
||||
else:
|
||||
otherparts.add(nextpart)
|
||||
|
||||
return cls(host, port, ssl, default, ipv6, ipv6only)
|
||||
return cls(host, port, ssl, default, ipv6, ipv6only, otherparts)
|
||||
|
||||
def to_string(self, include_default=True):
|
||||
"""Return string representation of Addr"""
|
||||
@@ -111,6 +115,12 @@ class Addr(common.Addr):
|
||||
parts += ' default_server'
|
||||
if self.ssl:
|
||||
parts += ' ssl'
|
||||
if self.ipv6only:
|
||||
parts += ' ipv6only=on'
|
||||
if self.otherparts:
|
||||
for word in self.otherparts:
|
||||
parts += ' '
|
||||
parts += word
|
||||
|
||||
return parts
|
||||
|
||||
|
||||
@@ -128,22 +128,39 @@ class NginxConfiguratorTest(util.NginxTest):
|
||||
['#', parser.COMMENT]]]],
|
||||
parsed[0])
|
||||
|
||||
def test_choose_vhosts(self):
|
||||
localhost_conf = set(['localhost', r'~^(www\.)?(example|bar)\.'])
|
||||
server_conf = set(['somename', 'another.alias', 'alias'])
|
||||
example_conf = set(['.example.com', 'example.*'])
|
||||
foo_conf = set(['*.www.foo.com', '*.www.example.com'])
|
||||
ipv6_conf = set(['ipv6.com'])
|
||||
def test_choose_vhosts_alias(self):
|
||||
self._test_choose_vhosts_common('alias', 'server_conf')
|
||||
|
||||
results = {'localhost': localhost_conf,
|
||||
'alias': server_conf,
|
||||
'example.com': example_conf,
|
||||
'example.com.uk.test': example_conf,
|
||||
'www.example.com': example_conf,
|
||||
'test.www.example.com': foo_conf,
|
||||
'abc.www.foo.com': foo_conf,
|
||||
'www.bar.co.uk': localhost_conf,
|
||||
'ipv6.com': ipv6_conf}
|
||||
def test_choose_vhosts_example_com(self):
|
||||
self._test_choose_vhosts_common('example.com', 'example_conf')
|
||||
|
||||
def test_choose_vhosts_localhost(self):
|
||||
self._test_choose_vhosts_common('localhost', 'localhost_conf')
|
||||
|
||||
def test_choose_vhosts_example_com_uk_test(self):
|
||||
self._test_choose_vhosts_common('example.com.uk.test', 'example_conf')
|
||||
|
||||
def test_choose_vhosts_www_example_com(self):
|
||||
self._test_choose_vhosts_common('www.example.com', 'example_conf')
|
||||
|
||||
def test_choose_vhosts_test_www_example_com(self):
|
||||
self._test_choose_vhosts_common('test.www.example.com', 'foo_conf')
|
||||
|
||||
def test_choose_vhosts_abc_www_foo_com(self):
|
||||
self._test_choose_vhosts_common('abc.www.foo.com', 'foo_conf')
|
||||
|
||||
def test_choose_vhosts_www_bar_co_uk(self):
|
||||
self._test_choose_vhosts_common('www.bar.co.uk', 'localhost_conf')
|
||||
|
||||
def test_choose_vhosts_ipv6_com(self):
|
||||
self._test_choose_vhosts_common('ipv6.com', 'ipv6_conf')
|
||||
|
||||
def _test_choose_vhosts_common(self, name, conf):
|
||||
conf_names = {'localhost_conf': set(['localhost', r'~^(www\.)?(example|bar)\.']),
|
||||
'server_conf': set(['somename', 'another.alias', 'alias']),
|
||||
'example_conf': set(['.example.com', 'example.*']),
|
||||
'foo_conf': set(['*.www.foo.com', '*.www.example.com']),
|
||||
'ipv6_conf': set(['ipv6.com'])}
|
||||
|
||||
conf_path = {'localhost': "etc_nginx/nginx.conf",
|
||||
'alias': "etc_nginx/nginx.conf",
|
||||
@@ -155,22 +172,22 @@ class NginxConfiguratorTest(util.NginxTest):
|
||||
'www.bar.co.uk': "etc_nginx/nginx.conf",
|
||||
'ipv6.com': "etc_nginx/sites-enabled/ipv6.com"}
|
||||
|
||||
vhost = self.config.choose_vhosts(name)[0]
|
||||
path = os.path.relpath(vhost.filep, self.temp_dir)
|
||||
|
||||
self.assertEqual(conf_names[conf], vhost.names)
|
||||
self.assertEqual(conf_path[name], path)
|
||||
# IPv6 specific checks
|
||||
if name == "ipv6.com":
|
||||
self.assertTrue(vhost.ipv6_enabled())
|
||||
# Make sure that we have SSL enabled also for IPv6 addr
|
||||
self.assertTrue(
|
||||
any([True for x in vhost.addrs if x.ssl and x.ipv6]))
|
||||
|
||||
def test_choose_vhosts_bad(self):
|
||||
bad_results = ['www.foo.com', 'example', 't.www.bar.co',
|
||||
'69.255.225.155']
|
||||
|
||||
for name in results:
|
||||
vhost = self.config.choose_vhosts(name)[0]
|
||||
path = os.path.relpath(vhost.filep, self.temp_dir)
|
||||
|
||||
self.assertEqual(results[name], vhost.names)
|
||||
self.assertEqual(conf_path[name], path)
|
||||
# IPv6 specific checks
|
||||
if name == "ipv6.com":
|
||||
self.assertTrue(vhost.ipv6_enabled())
|
||||
# Make sure that we have SSL enabled also for IPv6 addr
|
||||
self.assertTrue(
|
||||
any([True for x in vhost.addrs if x.ssl and x.ipv6]))
|
||||
|
||||
for name in bad_results:
|
||||
self.assertRaises(errors.MisconfigurationError,
|
||||
self.config.choose_vhosts, name)
|
||||
@@ -448,7 +465,7 @@ class NginxConfiguratorTest(util.NginxTest):
|
||||
|
||||
def test_get_snakeoil_paths(self):
|
||||
# pylint: disable=protected-access
|
||||
cert, key = self.config._get_snakeoil_paths()
|
||||
cert, key = self.config.get_snakeoil_paths()
|
||||
self.assertTrue(os.path.exists(cert))
|
||||
self.assertTrue(os.path.exists(key))
|
||||
with open(cert) as cert_file:
|
||||
@@ -974,5 +991,46 @@ class DetermineDefaultServerRootTest(certbot_test_util.ConfigTestCase):
|
||||
self.assertTrue(server_root == "/etc/nginx" or server_root == "/usr/local/etc/nginx")
|
||||
|
||||
|
||||
class ChooseHttpAndHttpsVhostsTest(util.NginxTest):
|
||||
"""Tests for certbot_nginx.configurator.choose_http_and_https_vhosts."""
|
||||
|
||||
def setUp(self):
|
||||
super(ChooseHttpAndHttpsVhostsTest, self).setUp()
|
||||
|
||||
self.config = util.get_nginx_configurator(
|
||||
self.config_path, self.config_dir, self.work_dir, self.logs_dir)
|
||||
|
||||
def _call(self, target_name, http_port):
|
||||
return self.config.choose_http_and_https_vhosts(target_name, http_port)
|
||||
|
||||
def test_wildcard(self):
|
||||
self.assertRaises(errors.NotSupportedError, self._call, "*.example.com", "80")
|
||||
|
||||
def test_http_only_initial(self):
|
||||
# only an http server initially
|
||||
# http server gets made https by choose_vhosts
|
||||
(http, https) = self._call("example.com", "80")
|
||||
self.assertTrue(http)
|
||||
self.assertEqual(http, https)
|
||||
|
||||
def test_only_https(self):
|
||||
# only an https server initially
|
||||
(http, https) = self._call("globalsslsetssl.com", "80")
|
||||
self.assertFalse(http)
|
||||
self.assertTrue(https)
|
||||
|
||||
def test_different_servers(self):
|
||||
# separate http and http servers
|
||||
(http, https) = self._call("migration.com", "80")
|
||||
self.assertTrue(http)
|
||||
self.assertTrue(https)
|
||||
self.assertNotEqual(http, https)
|
||||
|
||||
def test_no_match(self):
|
||||
(http, https) = self._call("uttergarbage.com", "80")
|
||||
self.assertFalse(http)
|
||||
self.assertFalse(https)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
||||
@@ -12,6 +12,7 @@ from certbot import achallenges
|
||||
from certbot.plugins import common_test
|
||||
from certbot.tests import acme_util
|
||||
|
||||
from certbot_nginx.obj import Addr
|
||||
from certbot_nginx.tests import util
|
||||
|
||||
|
||||
@@ -108,6 +109,45 @@ class HttpPerformTest(util.NginxTest):
|
||||
# self.assertEqual(vhost.addrs, set(v_addr2_print))
|
||||
# self.assertEqual(vhost.names, set([response.z_domain.decode('ascii')]))
|
||||
|
||||
@mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info")
|
||||
def test_default_listen_addresses_no_memoization(self, ipv6_info):
|
||||
# pylint: disable=protected-access
|
||||
ipv6_info.return_value = (True, True)
|
||||
self.http01._default_listen_addresses()
|
||||
ipv6_info.return_value = (False, False)
|
||||
self.http01._default_listen_addresses()
|
||||
self.assertEqual(ipv6_info.call_count, 4)
|
||||
|
||||
@mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info")
|
||||
def test_default_listen_addresses_t_t(self, ipv6_info):
|
||||
# pylint: disable=protected-access
|
||||
ipv6_info.return_value = (True, True)
|
||||
addrs = self.http01._default_listen_addresses()
|
||||
http_addr = Addr.fromstring("80")
|
||||
http_ipv6_addr = Addr.fromstring("[::]:80")
|
||||
ssl_addr = Addr.fromstring("5001 ssl")
|
||||
ssl_ipv6_addr = Addr.fromstring("[::]:5001 ssl")
|
||||
self.assertEqual(addrs, [http_addr, http_ipv6_addr, ssl_addr, ssl_ipv6_addr])
|
||||
|
||||
@mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info")
|
||||
def test_default_listen_addresses_t_f(self, ipv6_info):
|
||||
# pylint: disable=protected-access
|
||||
ipv6_info.return_value = (True, False)
|
||||
addrs = self.http01._default_listen_addresses()
|
||||
http_addr = Addr.fromstring("80")
|
||||
http_ipv6_addr = Addr.fromstring("[::]:80 ipv6only=on")
|
||||
ssl_addr = Addr.fromstring("5001 ssl")
|
||||
ssl_ipv6_addr = Addr.fromstring("[::]:5001 ssl ipv6only=on")
|
||||
self.assertEqual(addrs, [http_addr, http_ipv6_addr, ssl_addr, ssl_ipv6_addr])
|
||||
|
||||
@mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info")
|
||||
def test_default_listen_addresses_f_f(self, ipv6_info):
|
||||
# pylint: disable=protected-access
|
||||
ipv6_info.return_value = (False, False)
|
||||
addrs = self.http01._default_listen_addresses()
|
||||
http_addr = Addr.fromstring("80")
|
||||
ssl_addr = Addr.fromstring("5001 ssl")
|
||||
self.assertEqual(addrs, [http_addr, ssl_addr])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
||||
@@ -57,7 +57,7 @@ class AddrTest(unittest.TestCase):
|
||||
self.assertEqual(str(self.addr3), "192.168.1.1:80")
|
||||
self.assertEqual(str(self.addr4), "*:80 default_server ssl")
|
||||
self.assertEqual(str(self.addr5), "myhost")
|
||||
self.assertEqual(str(self.addr6), "80 default_server")
|
||||
self.assertEqual(str(self.addr6), "80 default_server spdy")
|
||||
self.assertEqual(str(self.addr8), "*:80 default_server ssl")
|
||||
|
||||
def test_to_string(self):
|
||||
@@ -67,8 +67,8 @@ class AddrTest(unittest.TestCase):
|
||||
self.assertEqual(self.addr4.to_string(), "*:80 default_server ssl")
|
||||
self.assertEqual(self.addr4.to_string(include_default=False), "*:80 ssl")
|
||||
self.assertEqual(self.addr5.to_string(), "myhost")
|
||||
self.assertEqual(self.addr6.to_string(), "80 default_server")
|
||||
self.assertEqual(self.addr6.to_string(include_default=False), "80")
|
||||
self.assertEqual(self.addr6.to_string(), "80 default_server spdy")
|
||||
self.assertEqual(self.addr6.to_string(include_default=False), "80 spdy")
|
||||
|
||||
def test_eq(self):
|
||||
from certbot_nginx.obj import Addr
|
||||
@@ -163,7 +163,7 @@ class VirtualHostTest(unittest.TestCase):
|
||||
from certbot_nginx.obj import VirtualHost
|
||||
vhost1b = VirtualHost(
|
||||
"filep",
|
||||
set([Addr.fromstring("localhost blah")]), False, False,
|
||||
set([Addr.fromstring("localhost")]), False, False,
|
||||
set(['localhost']), [], [])
|
||||
|
||||
self.assertEqual(vhost1b, self.vhost1)
|
||||
|
||||
@@ -2,7 +2,7 @@ server {
|
||||
server_name globalssl.com;
|
||||
listen 4.8.2.6:57;
|
||||
}
|
||||
|
||||
|
||||
server {
|
||||
server_name globalsslsetssl.com;
|
||||
listen 4.8.2.6:57 ssl;
|
||||
|
||||
@@ -51,9 +51,6 @@ class NginxTlsSni01(common.TLSSNI01):
|
||||
default_addr = "{0} ssl".format(
|
||||
self.configurator.config.tls_sni_01_port)
|
||||
|
||||
ipv6, ipv6only = self.configurator.ipv6_info(
|
||||
self.configurator.config.tls_sni_01_port)
|
||||
|
||||
for achall in self.achalls:
|
||||
vhosts = self.configurator.choose_vhosts(achall.domain, create_if_no_match=True)
|
||||
|
||||
@@ -61,6 +58,10 @@ class NginxTlsSni01(common.TLSSNI01):
|
||||
if vhosts and vhosts[0].addrs:
|
||||
addresses.append(list(vhosts[0].addrs))
|
||||
else:
|
||||
# choose_vhosts might have modified vhosts, so put this after
|
||||
ipv6, ipv6only = self.configurator.ipv6_info(
|
||||
self.configurator.config.tls_sni_01_port)
|
||||
|
||||
if ipv6:
|
||||
# If IPv6 is active in Nginx configuration
|
||||
ipv6_addr = "[::]:{0} ssl".format(
|
||||
@@ -141,6 +142,8 @@ class NginxTlsSni01(common.TLSSNI01):
|
||||
with open(self.challenge_conf, "w") as new_conf:
|
||||
nginxparser.dump(config, new_conf)
|
||||
|
||||
logger.debug("Generated challenge conf:\n%s", str(config))
|
||||
|
||||
def _make_server_block(self, achall, addrs):
|
||||
"""Creates a server block for a challenge.
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ test_deployment_and_rollback() {
|
||||
}
|
||||
|
||||
export default_server="default_server"
|
||||
nginx -v
|
||||
reload_nginx
|
||||
certbot_test_nginx --domains nginx.wtf run
|
||||
test_deployment_and_rollback nginx.wtf
|
||||
|
||||
Reference in New Issue
Block a user