Closed dholth closed 5 years ago
fixes #25
Merging #26 into master will decrease coverage by
0.79%
. The diff coverage is80%
.
@@ Coverage Diff @@
## master #26 +/- ##
========================================
- Coverage 95% 94.2% -0.8%
========================================
Files 6 6
Lines 400 414 +14
Branches 28 30 +2
========================================
+ Hits 380 390 +10
- Misses 12 15 +3
- Partials 8 9 +1
Impacted Files | Coverage Δ | |
---|---|---|
txsni/parser.py | 100% <100%> (ø) |
:arrow_up: |
txsni/snimap.py | 86.6% <76.47%> (-2.4%) |
:arrow_down: |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update 5014c14...c9650a7. Read the comment docs.
It's unfortunate that we have to choose a certificate for our hostname before we can immediately switch to the acme one
How dehydrated stores its certificates. letsencrypt doesn't agree with us yet, saying "detail": "remote error: tls: no application protocol"
import pem.twisted
class DehydratedMap(object):
"""
Dehydrated's certs, in per-hostname subdirectories
"""
def __init__(self, directoryPath):
self.directoryPath = directoryPath
def __getitem__(self, hostname):
if hostname is None:
hostname = b"DEFAULT"
hostPath = self.directoryPath.child(hostname)
keyPath = hostPath.child('privkey.pem')
fullchainPath = hostPath.child('fullchain.pem')
print('regular', hostname, keyPath, fullchainPath)
if keyPath.isfile() and fullchainPath.isfile():
print('regular', hostname, 'found')
return pem.twisted.certificateOptionsFromFiles(keyPath.path, fullchainPath.path)
else:
raise KeyError("no pem file for " + hostname.decode('latin1'))
class DehydratedAcmeMap(object):
"""
Dehydrated's ALPN certs, in files
"""
def __init__(self, directoryPath):
self.directoryPath = directoryPath
def __getitem__(self, hostname):
print('acme', hostname)
certPath = self.directoryPath.child(hostname).siblingExtension(".crt.pem")
keyPath = self.directoryPath.child(hostname).siblingExtension(".key.pem")
if certPath.isfile() and keyPath.isfile():
print('acme', hostname, 'found')
return pem.twisted.certificateOptionsFromFiles(keyPath.path, certPath.path)
else:
raise KeyError("no alpn cert for " + hostname.decode('latin1'))
It at least works if the alpn certificate is the only one. SNIMap(acme_mapping)
I've cracked it. We already use bio so Python sees all the bytes, and we already proxy Connection. Trap the first call to bio to search for alpn in the first packet, if True load certificates from a different directory during SNI. Cheesy!
will replace
@dholth What replaced this?
https://github.com/glyph/txsni/pull/28
On Sat, Aug 3, 2019, at 6:24 PM, Glyph wrote:
@dholth https://github.com/dholth What replaced this?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/glyph/txsni/pull/26?email_source=notifications&email_token=AABSZEUUI5QEXQU6AYZEWJDQCYAQFA5CNFSM4HASGI52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3PWXOA#issuecomment-517958584, or mute the thread https://github.com/notifications/unsubscribe-auth/AABSZEWWCSQVVW5Q4OY5ELTQCYAQFANCNFSM4HASGI5Q.
Thanks.
As you probably know letsencrypt requires alpn negotiation instead of just SNI these days.
This change intercepts alpn negotiation so that acme-tls/1 is always used if the client supports it. Then txsni chooses certificates from a second mapping, currently just an alpn/ directory underneath the default mapping, to use for that connection. When letsencrypt sees that special cert it knows you control the domain.
So if you have already generated the special certificate and placed it in acme/hostname.pem, txsni will be able to make letsencrypt happy. Then your ACME client can finish issuing you a new cert.
I expect to use this with dehydrated, the shell script acme client, and possibly with a new mapping object that can do dehydrated's separate key / cert layout. There's not enough here for txsni's "even the first request succeeds after waiting for the new certificate" but it should be really handy for development.