Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1db665f
feat: starttls
JacobCoffee Mar 18, 2025
e655530
(broken) auto lets encrypt via acme state
JacobCoffee Apr 1, 2025
65dd645
(broken) correct commited result
JacobCoffee Apr 1, 2025
0dbf3ca
correct commited result again
JacobCoffee Apr 2, 2025
0aefff2
properly install PSF_CA certificate so certbot can use it
ewdurbin Apr 14, 2025
10a5006
uncomment working parts
JacobCoffee Apr 15, 2025
98dc839
stuff acme certs into appropriate pillar data
JacobCoffee Apr 21, 2025
ca751e4
feat: move acme stuff into pillar data
JacobCoffee Apr 23, 2025
50e70e7
fix: less suck, more good
JacobCoffee Apr 23, 2025
4d172e7
docs: explain a little
JacobCoffee Apr 24, 2025
536578a
fix: just one bugs section
JacobCoffee Apr 25, 2025
43ab883
fix: requires proper name to not break
JacobCoffee Apr 30, 2025
fa30753
feat: install certs alongside other certs.
JacobCoffee Apr 30, 2025
4d250dd
feat: read actual cert instead of config..
JacobCoffee Apr 30, 2025
bcb7bf6
chore: lint
JacobCoffee May 6, 2025
f2ab9c1
chore: lint again
JacobCoffee May 6, 2025
b740196
Merge branch 'main' into add-starttls
ewdurbin Oct 7, 2025
8d33d6c
fix: make acme_certs different from acme_certs 😵‍💫
JacobCoffee Oct 8, 2025
0da94f1
fix: use new, correct cert
JacobCoffee Oct 8, 2025
e2c1b7c
chore: cleanup star certs
JacobCoffee Oct 8, 2025
50af18e
feat: add services from lb
JacobCoffee Oct 8, 2025
ced030b
fix: dupe on planet
JacobCoffee Oct 8, 2025
33bb23a
cleanup things in fastly
JacobCoffee Oct 10, 2025
5eaa575
consolidate codespeed certs
ewdurbin Oct 10, 2025
2ec675e
literally just a nit
ewdurbin Oct 10, 2025
1ef51b5
consolidate legacy domains
ewdurbin Oct 10, 2025
daaee08
line breaks are free
ewdurbin Oct 10, 2025
a920973
alphabetize
ewdurbin Oct 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions pillar/base/tls.sls
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,80 @@ tls:
svn.psf.io:
roles:
- hg

acme_cert_configs:

bugs.python.org:
validation: http
name: bugs.python.org
roles:
- loadbalancer
- bugs
aliases:
- bugs.jython.org
- issues.roundup-tracker.org

buildbot.python.org:
validation: http
roles:
- loadbalancer

console.python.org:
validation: http
roles:
- loadbalancer

jobs.pyfound.org:
validation: http
roles:
- loadbalancer

jython.org:
validation: http
roles:
- loadbalancer
aliases:
- jython.net
- www.jython.net
- jython.com
- www.jython.com

legacy.python.org:
validation: http
roles:
- loadbalancer
aliases:
- hg.python.org
- svn.python.org

planetpython.org:
validation: http
roles:
- loadbalancer
aliases:
- www.planetpython.org
- planet.python.org

pypa.io:
validation: http
roles:
- loadbalancer

salt-public.psf.io:
validation: http
roles:
- loadbalancer

speed.python.org:
validation: http
roles:
- loadbalancer
aliases:
- speed.pypy.org

wiki.python.org:
validation: http
roles:
- loadbalancer
aliases:
- wiki.jython.org
1 change: 1 addition & 0 deletions pillar/dev/top.sls
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ base:
- tls
- users.*
- postgres.clusters
- pebble # needing to do this to have pebble rum in dev
# - secrets.sentry # Uncomment and update sentry secrets if you want to work in dev

'backup-server':
Expand Down
49 changes: 36 additions & 13 deletions salt/_extensions/pillar/ca.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,46 +295,69 @@ def get_ca_signed_cert(cacert_path, ca_name, CN):
return "\n".join([cert, key])


def _read_cert_file(path: str) -> str:
"""Helper to read certificate files, which might be symlinks"""
try:
with open(path, 'r') as f:
return f.read()
except (IOError, OSError):
return None


def ext_pillar(minion_id, pillar, base="/etc/ssl", name="PSFCA", cert_opts=None):
if cert_opts is None:
cert_opts = {}

# Ensure we have a CA created.
# Create CA certificate
opts = cert_opts.copy()
opts["CN"] = name
create_ca(base, name, **opts)

# Start our pillar with just the ca certificate.
data = {
"tls": {
"ca": {
name: get_ca_cert(base, name),
},
"certs": {},
"acme_certs": {},
},
}

# Create all of the certificates required by this minion
minion_roles = []
minion_roles.extend(
role_name
for role_name, role_config in pillar.get("roles", {}).items()
if role_config.get("pattern")
and compound(role_config["pattern"], minion_id)
)

# Process CA-signed certificates (gen_certs)
gen_certs = pillar.get("tls", {}).get("gen_certs", {})
for certificate, config in gen_certs.items():
role_patterns = [
role.get("pattern")
for role in [
pillar.get("roles", {}).get(r) for r in config.get("roles", "")
]
if role and role.get("pattern") is not None
]
if any([compound(pat, minion_id) for pat in role_patterns]):
cert_roles = config.get("roles", [])
# Check if any of the minion's roles are in the certificate's required roles
if any(role in minion_roles for role in cert_roles):
# Create the options
opts = cert_opts.copy()
opts["CN"] = certificate
opts["days"] = config.get("days", 1)

# Create the signed certificates
create_ca_signed_cert(base, name, **opts)

# Add the signed certificates to the pillar data
cert_data = get_ca_signed_cert(base, name, certificate)
data["tls"]["certs"][certificate] = cert_data

return data
# Collect ACME certs (acme.cert) for this minion based on its roles
acme_cert_configs = pillar.get("tls", {}).get("acme_cert_configs", {})
for domain, domain_config in acme_cert_configs.items():
cert_roles = domain_config.get("roles", [])
if any(role in minion_roles for role in cert_roles):
cert_name = domain_config.get('name', domain)
full_cert_chain = _read_cert_file(f"/etc/letsencrypt/live/{cert_name}/fullchain.pem")
privkey = _read_cert_file(f"/etc/letsencrypt/live/{cert_name}/privkey.pem")

if full_cert_chain and privkey:
data["tls"]["acme_certs"][domain] = full_cert_chain + "\n" + privkey

return data
4 changes: 2 additions & 2 deletions salt/bugs/config/postfix/main.cf
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ compatibility_level = 3.6


# TLS parameters
smtpd_tls_cert_file=ssl_certificate /etc/ssl/private/bugs.psf.io.pem;
smtpd_tls_key_file=etc/ssl/private/bugs.psf.io.pem;
smtpd_tls_cert_file=/etc/ssl/private/acme-bugs.python.org.pem
smtpd_tls_key_file=/etc/ssl/private/acme-bugs.python.org.pem
smtpd_tls_security_level=may

smtp_tls_CApath=/etc/ssl/certs
Expand Down
60 changes: 60 additions & 0 deletions salt/tls/init.sls
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
include:
- .pebble
- .lego

ssl-cert:
pkg.installed

certbot:
pkg.installed

{% for name in salt["pillar.get"]("tls:ca", {}) %} # " Syntax Hack
/etc/ssl/certs/{{ name }}.pem:
Expand All @@ -11,8 +17,21 @@ ssl-cert:
- mode: "0644"
- require:
- pkg: ssl-cert

/usr/local/share/ca-certificates/{{ name }}.crt:
file.managed:
- contents_pillar: tls:ca:{{ name }}
- user: root
- group: ssl-cert
- mode: "0644"
- require:
- pkg: ssl-cert
{% endfor %}

/usr/sbin/update-ca-certificates:
cmd.run:
- onchanges:
- file: /usr/local/share/ca-certificates/*.crt

{% for name in salt["pillar.get"]("tls:certs", {}) %} # " Syntax Hack
/etc/ssl/private/{{ name }}.pem:
Expand All @@ -25,3 +44,44 @@ ssl-cert:
- require:
- pkg: ssl-cert
{% endfor %}

# Install acme.cert certs prepended with acme-* to avoic conflicts
{% for name in salt["pillar.get"]("tls:acme_certs", {}) %}
/etc/ssl/private/acme-{{ name }}.pem:
file.managed:
- contents_pillar: tls:acme_certs:{{ name }}
- user: root
- group: ssl-cert
- mode: "0640"
- show_diff: False
- require:
- pkg: ssl-cert
{% endfor %}

{% if salt["match.compound"](pillar["roles"]["salt-master"]["pattern"]) %}
# Process ACME certificates
{% for domain, domain_config in salt["pillar.get"]("tls:acme_cert_configs", {}).items() %}
{{ domain }}:
acme.cert:
- email: [email protected]
- webroot: /etc/lego
- renew: 14
{% if domain_config.get('aliases') %}
- aliases:
{% for alias in domain_config.get('aliases', []) %}
- {{ alias }}
{% endfor %}
{% endif %}
{% if pillar["dc"] == "vagrant" %}
- server: https://salt-master.vagrant.psf.io:14000/dir
{% endif %}
{% if domain_config.get('validation') == "dns" %}
- dns_plugin: {{ domain_config.get('dns_plugin') }}
- dns_plugin_credentials: {{ domain_config.get('dns_plugin_credentials') }}
{% else %}
- require:
- sls: tls.lego
- pkg: certbot
{% endif %}
{% endfor %}
{% endif %}
2 changes: 2 additions & 0 deletions salt/tls/pebble.sls
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% if salt["match.compound"](pillar["roles"]["salt-master"]["pattern"]) %}
{% if pillar.get('pebble', {'enabled': False}).enabled %}
pebble-build-deps:
pkg.installed:
Expand Down Expand Up @@ -60,3 +61,4 @@ pebble-service:
- file: /etc/ssl/certs/PSF_CA.pem
- file: /etc/ssl/private/salt-master.vagrant.psf.io.pem
{% endif %}
{% endif %}