Compare commits
3 commits
8a9434a384
...
8532f914c3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8532f914c3 | ||
![]() |
33062c3ec6 | ||
![]() |
be6903d3a6 |
4 changed files with 104 additions and 84 deletions
|
@ -1,5 +1,4 @@
|
||||||
Host *
|
Host *
|
||||||
#UserKnownHostsFile ~/.ssh/known_hosts ~/.ssh/known_hosts.d/%k
|
|
||||||
SendEnv LANG LC_*
|
SendEnv LANG LC_*
|
||||||
HashKnownHosts yes
|
HashKnownHosts yes
|
||||||
GSSAPIAuthentication yes
|
GSSAPIAuthentication yes
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
if not node.metadata.get('FIXME_dont_touch_sshd', False):
|
|
||||||
# on debian bullseye raspberry images, starting the systemd ssh
|
# on debian bullseye raspberry images, starting the systemd ssh
|
||||||
# daemon seems to collide with an existing sysv daemon
|
# daemon seems to collide with an existing sysv daemon
|
||||||
|
dont_touch_sshd = node.metadata.get('FIXME_dont_touch_sshd', False),
|
||||||
|
|
||||||
directories = {
|
directories = {
|
||||||
'/etc/ssh': {
|
'/etc/ssh': {
|
||||||
'purge': True,
|
'purge': True,
|
||||||
'mode': '0755',
|
'mode': '0755',
|
||||||
|
'skip': dont_touch_sshd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
files = {
|
files = {
|
||||||
'/etc/ssh/moduli': {
|
'/etc/ssh/moduli': {
|
||||||
'content_type': 'any',
|
'content_type': 'any',
|
||||||
|
'skip': dont_touch_sshd,
|
||||||
},
|
},
|
||||||
'/etc/ssh/ssh_config': {
|
'/etc/ssh/ssh_config': {
|
||||||
'triggers': [
|
'triggers': [
|
||||||
'svc_systemd:ssh:restart'
|
'svc_systemd:ssh:restart'
|
||||||
],
|
],
|
||||||
|
'skip': dont_touch_sshd,
|
||||||
},
|
},
|
||||||
'/etc/ssh/ssh_config': {
|
'/etc/ssh/ssh_config': {
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
|
@ -24,6 +28,7 @@ if not node.metadata.get('FIXME_dont_touch_sshd', False):
|
||||||
'triggers': [
|
'triggers': [
|
||||||
'svc_systemd:ssh:restart'
|
'svc_systemd:ssh:restart'
|
||||||
],
|
],
|
||||||
|
'skip': dont_touch_sshd,
|
||||||
},
|
},
|
||||||
'/etc/ssh/sshd_config': {
|
'/etc/ssh/sshd_config': {
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
|
@ -33,6 +38,7 @@ if not node.metadata.get('FIXME_dont_touch_sshd', False):
|
||||||
'triggers': [
|
'triggers': [
|
||||||
'svc_systemd:ssh:restart'
|
'svc_systemd:ssh:restart'
|
||||||
],
|
],
|
||||||
|
'skip': dont_touch_sshd,
|
||||||
},
|
},
|
||||||
'/etc/ssh/ssh_host_ed25519_key': {
|
'/etc/ssh/ssh_host_ed25519_key': {
|
||||||
'content': node.metadata.get('ssh/host_key/private') + '\n',
|
'content': node.metadata.get('ssh/host_key/private') + '\n',
|
||||||
|
@ -62,4 +68,5 @@ if not node.metadata.get('FIXME_dont_touch_sshd', False):
|
||||||
'needs': [
|
'needs': [
|
||||||
'tag:ssh_users',
|
'tag:ssh_users',
|
||||||
],
|
],
|
||||||
|
'skip': dont_touch_sshd,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from ipaddress import ip_interface
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,3 +33,34 @@ def host_key(metadata):
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'ssh/hostnames',
|
||||||
|
)
|
||||||
|
def hostnames(metadata):
|
||||||
|
ips = set()
|
||||||
|
|
||||||
|
for network in node.metadata.get('network').values():
|
||||||
|
if network.get('ipv4', None):
|
||||||
|
ips.add(str(ip_interface(network['ipv4']).ip))
|
||||||
|
if network.get('ipv6', None):
|
||||||
|
ips.add(str(ip_interface(network['ipv6']).ip))
|
||||||
|
|
||||||
|
domains = {
|
||||||
|
domain
|
||||||
|
for domain, records in node.metadata.get('dns').items()
|
||||||
|
for type, values in records.items()
|
||||||
|
if type in {'A', 'AAAA'}
|
||||||
|
and set(values) & ips
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'ssh': {
|
||||||
|
'hostnames': {
|
||||||
|
node.hostname,
|
||||||
|
*ips,
|
||||||
|
*domains,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
22
libs/ssh.py
22
libs/ssh.py
|
@ -2,7 +2,6 @@ from base64 import b64decode, b64encode
|
||||||
from hashlib import sha3_224, sha1
|
from hashlib import sha3_224, sha1
|
||||||
from functools import cache
|
from functools import cache
|
||||||
import hmac
|
import hmac
|
||||||
from ipaddress import ip_interface
|
|
||||||
|
|
||||||
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
|
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
|
||||||
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, PublicFormat, NoEncryption
|
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, PublicFormat, NoEncryption
|
||||||
|
@ -57,30 +56,13 @@ def generate_ed25519_key_pair(secret):
|
||||||
# - `bw debug -c 'repo.libs.ssh.known_hosts_entry_for(repo.get_node(<node with hostname 10.0.0.5>), <salt from ssh-keygen>)'`
|
# - `bw debug -c 'repo.libs.ssh.known_hosts_entry_for(repo.get_node(<node with hostname 10.0.0.5>), <salt from ssh-keygen>)'`
|
||||||
@cache
|
@cache
|
||||||
def known_hosts_entry_for(node, test_salt=None):
|
def known_hosts_entry_for(node, test_salt=None):
|
||||||
ips = set()
|
|
||||||
|
|
||||||
for network in node.metadata.get('network').values():
|
|
||||||
if network.get('ipv4', None):
|
|
||||||
ips.add(str(ip_interface(network['ipv4']).ip))
|
|
||||||
if network.get('ipv6', None):
|
|
||||||
ips.add(str(ip_interface(network['ipv6']).ip))
|
|
||||||
|
|
||||||
domains = {
|
|
||||||
domain
|
|
||||||
for domain, records in node.metadata.get('dns').items()
|
|
||||||
for type, values in records.items()
|
|
||||||
if type in {'A', 'AAAA'}
|
|
||||||
and set(values) & ips
|
|
||||||
}
|
|
||||||
|
|
||||||
lines = set()
|
lines = set()
|
||||||
|
|
||||||
for hostname in {node.hostname, *ips, *domains}:
|
for hostname in sorted(node.metadata.get('ssh/hostnames')):
|
||||||
|
|
||||||
if test_salt:
|
if test_salt:
|
||||||
salt = b64decode(test_salt)
|
salt = b64decode(test_salt)
|
||||||
else:
|
else:
|
||||||
salt = sha1(node.metadata.get('id').encode()).digest()
|
salt = sha1((node.metadata.get('id') + hostname).encode()).digest()
|
||||||
|
|
||||||
hash = hmac.new(salt, hostname.encode(), sha1).digest()
|
hash = hmac.new(salt, hostname.encode(), sha1).digest()
|
||||||
pubkey = node.metadata.get('ssh/host_key/public')
|
pubkey = node.metadata.get('ssh/host_key/public')
|
||||||
|
|
Loading…
Reference in a new issue