diff options
Diffstat (limited to 'files/usr')
21 files changed, 282 insertions, 8 deletions
diff --git a/files/usr/local/etc/nslcd.conf.idm_server b/files/usr/local/etc/nslcd.conf.idm_server new file mode 100644 index 0000000..1f74779 --- /dev/null +++ b/files/usr/local/etc/nslcd.conf.idm_server @@ -0,0 +1,14 @@ +uid ${nslcd_user} +gid ${nslcd_user} + +uri ${slapd_ldapi_uri} + +base ${basedn} +base passwd ${accounts_basedn} +base group ${groups_basedn} + +sasl_mech EXTERNAL + +nss_min_uid ${nslcd_min_uid} +nss_initgroups_ignoreusers ALLLOCAL +nss_nested_groups yes diff --git a/files/usr/local/etc/openldap/ldap.conf.idm_server b/files/usr/local/etc/openldap/ldap.conf.idm_server index 3b285f7..a3e18f2 100644 --- a/files/usr/local/etc/openldap/ldap.conf.idm_server +++ b/files/usr/local/etc/openldap/ldap.conf.idm_server @@ -1,4 +1,4 @@ -URI ldapi:/// +URI ${slapd_ldapi_uri} BASE ${basedn} USE_SASL yes ROOTUSE_SASL yes diff --git a/files/usr/local/etc/openldap/slapd.ldif.idm_server b/files/usr/local/etc/openldap/slapd.ldif.idm_server index 784c63a..9dc0086 100644 --- a/files/usr/local/etc/openldap/slapd.ldif.idm_server +++ b/files/usr/local/etc/openldap/slapd.ldif.idm_server @@ -119,8 +119,8 @@ olcAccess: {1}to dn.base="cn=Subschema" by * read olcAccess: {3}to * by dn.exact=${slapd_replicator_dn} read - by dn.exact=uid=${idm_admin_username},${robots_basedn} manage - by group/groupOfMembers/member=cn=${idm_admin_groupname},${groups_basedn} manage + by dn.exact=krbPrincipalName=${boxconf_username},${robots_basedn} manage + by set="[cn=${slapd_admin_role},${roles_basedn}]/member* & user" manage by * break olcAccess: {4}to dn.subtree=${sudo_basedn} by dn.children=${hosts_basedn} read diff --git a/files/usr/local/etc/pdns/pdns.conf.idm_server b/files/usr/local/etc/pdns/pdns.conf.idm_server index fc63bd6..2d49dc3 100644 --- a/files/usr/local/etc/pdns/pdns.conf.idm_server +++ b/files/usr/local/etc/pdns/pdns.conf.idm_server @@ -4,7 +4,7 @@ # # You must set ldap-bindmethod=gssapi (?!) for this to work. This behavior doesn't # seem to be documented anywhere, but hey, it's nice! -ldap-host=ldapi:/// +ldap-host=${slapd_ldapi_uri} ldap-bindmethod=gssapi ldap-basedn=${dns_basedn} diff --git a/files/usr/local/etc/poudriere.d/idm-make.conf.pkg_repository b/files/usr/local/etc/poudriere.d/idm-make.conf.pkg_repository index 1d5ce20..ad5304f 100644 --- a/files/usr/local/etc/poudriere.d/idm-make.conf.pkg_repository +++ b/files/usr/local/etc/poudriere.d/idm-make.conf.pkg_repository @@ -4,8 +4,8 @@ DEFAULT_VERSIONS+=${poudriere_default_versions:-} MAKE_JOBS_NUMBER=${poudriere_make_jobs_number} # Global port options -OPTIONS_UNSET=TEST DEBUG GSSAPI_HEIMDAL GSSAPI_BASE GSSAPI_NONE HEIMDAL NLS DOCS AVAHI LIBWRAP MYSQL MSQLND ODBC READLINE PULSEAUDIO UPNP BASH ZSH INFO ALSA SAMBA WAYLAND PLATFORM_WAYLAND PIPEWIRE -OPTIONS_SET=GSSAPI GSSAPI_MIT NONFREE LIBEDIT +OPTIONS_UNSET=TEST DEBUG GSSAPI_HEIMDAL GSSAPI_BASE GSSAPI_NONE HEIMDAL HEIMDAL_BASE NLS DOCS AVAHI LIBWRAP MYSQL MSQLND ODBC READLINE PULSEAUDIO UPNP BASH ZSH INFO ALSA SAMBA WAYLAND PLATFORM_WAYLAND PIPEWIRE TCP_WRAPPERS +OPTIONS_SET=GSSAPI GSSAPI_MIT MIT NONFREE LIBEDIT # Per-port options dns_powerdns_SET=OPENLDAP diff --git a/files/usr/local/etc/poudriere.d/idm-pkglist.pkg_repository b/files/usr/local/etc/poudriere.d/idm-pkglist.pkg_repository index 86c102e..9504faa 100644 --- a/files/usr/local/etc/poudriere.d/idm-pkglist.pkg_repository +++ b/files/usr/local/etc/poudriere.d/idm-pkglist.pkg_repository @@ -12,6 +12,7 @@ net/py-python-ldap net/rsync security/cyrus-sasl2-saslauthd security/krb5 +security/openssh-portable security/pam_krb5@mit security/pam_mkhomedir security/sudo diff --git a/files/usr/local/etc/poudriere.d/make.conf.pkg_repository b/files/usr/local/etc/poudriere.d/make.conf.pkg_repository index 8348621..b0ae948 100644 --- a/files/usr/local/etc/poudriere.d/make.conf.pkg_repository +++ b/files/usr/local/etc/poudriere.d/make.conf.pkg_repository @@ -4,8 +4,8 @@ DEFAULT_VERSIONS+=${poudriere_default_versions:-} MAKE_JOBS_NUMBER=${poudriere_make_jobs_number} # Global port options -OPTIONS_UNSET=TEST DEBUG GSSAPI_HEIMDAL GSSAPI_BASE GSSAPI_NONE HEIMDAL NLS DOCS AVAHI LIBWRAP MYSQL MSQLND ODBC READLINE PULSEAUDIO UPNP BASH ZSH INFO ALSA SAMBA WAYLAND PLATFORM_WAYLAND PIPEWIRE -OPTIONS_SET=GSSAPI GSSAPI_MIT NONFREE LIBEDIT +OPTIONS_UNSET=TEST DEBUG GSSAPI_HEIMDAL GSSAPI_BASE GSSAPI_NONE HEIMDAL HEIMDAL_BASE NLS DOCS AVAHI LIBWRAP MYSQL MSQLND ODBC READLINE PULSEAUDIO UPNP BASH ZSH INFO ALSA SAMBA WAYLAND PLATFORM_WAYLAND PIPEWIRE TCP_WRAPPERS +OPTIONS_SET=GSSAPI GSSAPI_MIT MIT NONFREE LIBEDIT # Per-port options databases_akonadi_SET=MYSQL diff --git a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository index 80fc5e5..157ae8e 100644 --- a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository +++ b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository @@ -19,6 +19,7 @@ security/cyrus-sasl2-saslauthd security/kstart security/krb5@default security/krb5@ldap +security/openssh-portable security/pam_krb5@mit security/pam_mkhomedir security/sshpass diff --git a/files/usr/local/etc/ssh/ssh_config.freebsd b/files/usr/local/etc/ssh/ssh_config.freebsd new file mode 100644 index 0000000..9be624a --- /dev/null +++ b/files/usr/local/etc/ssh/ssh_config.freebsd @@ -0,0 +1,9 @@ +CanonicalizeHostname always +CanonicalizeMaxDots 0 +CanonicalDomains ${domain} +CanonicalizePermittedCNAMEs *.${domain}:*.${domain} +KnownHostsCommand /usr/local/libexec/idm-ssh-known-hosts %H + +Host *.${domain} + GSSAPIAuthentication yes + GSSAPIDelegateCredentials yes diff --git a/files/usr/local/etc/ssh/ssh_config.freebsd_hypervisor b/files/usr/local/etc/ssh/ssh_config.freebsd_hypervisor new file mode 120000 index 0000000..338cdba --- /dev/null +++ b/files/usr/local/etc/ssh/ssh_config.freebsd_hypervisor @@ -0,0 +1 @@ +ssh_config.no_idm
\ No newline at end of file diff --git a/files/usr/local/etc/ssh/ssh_config.no_idm b/files/usr/local/etc/ssh/ssh_config.no_idm new file mode 100644 index 0000000..97f3ba8 --- /dev/null +++ b/files/usr/local/etc/ssh/ssh_config.no_idm @@ -0,0 +1 @@ +# Intentionally empty. diff --git a/files/usr/local/etc/ssh/ssh_config.roadwarrior_laptop b/files/usr/local/etc/ssh/ssh_config.roadwarrior_laptop new file mode 120000 index 0000000..338cdba --- /dev/null +++ b/files/usr/local/etc/ssh/ssh_config.roadwarrior_laptop @@ -0,0 +1 @@ +ssh_config.no_idm
\ No newline at end of file diff --git a/files/usr/local/etc/ssh/sshd_config.freebsd b/files/usr/local/etc/ssh/sshd_config.freebsd new file mode 100644 index 0000000..df46af6 --- /dev/null +++ b/files/usr/local/etc/ssh/sshd_config.freebsd @@ -0,0 +1,16 @@ +Include /etc/ssh/sshd_config.d/*.conf + +PermitRootLogin prohibit-password +AuthorizedKeysFile .ssh/authorized_keys +AuthorizedKeysCommand /usr/local/libexec/idm-ssh-authorized-keys %u +AuthorizedKeysCommandUser ${ssh_authzkeys_user} + +KbdInteractiveAuthentication no +PasswordAuthentication yes + +GSSAPIAuthentication yes +GSSAPICleanupCredentials yes +UsePAM yes +UseDNS no + +Subsystem sftp /usr/local/libexec/sftp-server diff --git a/files/usr/local/etc/ssh/sshd_config.freebsd_hypervisor b/files/usr/local/etc/ssh/sshd_config.freebsd_hypervisor new file mode 120000 index 0000000..355377d --- /dev/null +++ b/files/usr/local/etc/ssh/sshd_config.freebsd_hypervisor @@ -0,0 +1 @@ +sshd_config.no_idm
\ No newline at end of file diff --git a/files/usr/local/etc/ssh/sshd_config.no_idm b/files/usr/local/etc/ssh/sshd_config.no_idm new file mode 100644 index 0000000..8a15559 --- /dev/null +++ b/files/usr/local/etc/ssh/sshd_config.no_idm @@ -0,0 +1,10 @@ +PermitRootLogin prohibit-password +AuthorizedKeysFile .ssh/authorized_keys + +KbdInteractiveAuthentication no +PasswordAuthentication yes + +UsePAM yes +UseDNS no + +Subsystem sftp /usr/local/libexec/sftp-server diff --git a/files/usr/local/etc/unbound/unbound.conf.idm_server b/files/usr/local/etc/unbound/unbound.conf.idm_server new file mode 100644 index 0000000..762fe09 --- /dev/null +++ b/files/usr/local/etc/unbound/unbound.conf.idm_server @@ -0,0 +1,68 @@ +server: + module-config: "respip validator iterator" + verbosity: 1 + num-threads: ${unbound_threads} + interface: 0.0.0.0 + interface: ::0 + do-ip6: no + prefer-ip6: no + prefetch: yes + prefetch-key: yes + so-rcvbuf: 425984 + do-not-query-localhost: no + access-control: 0.0.0.0/0 allow + access-control: ::0/0 allow + + cache-max-negative-ttl: ${unbound_cache_max_negative_ttl} + rrset-cache-size: ${unbound_rrset_cache_size} + msg-cache-size: ${unbound_msg_cache_size} + msg-cache-slabs: ${unbound_slabs} + rrset-cache-slabs: ${unbound_slabs} + infra-cache-slabs: ${unbound_slabs} + key-cache-slabs: ${unbound_slabs} + + private-address: 192.168.0.0/16 + private-address: 169.254.0.0/16 + private-address: 172.16.0.0/12 + private-address: 10.0.0.0/8 + + domain-insecure: "${domain}" +$([ -z "$unbound_insecure_domains" ] || printf ' domain-insecure: "%s"\n' $unbound_insecure_domains) + + local-zone: "10.in-addr.arpa" nodefault + local-zone: "16.172.in-addr.arpa" nodefault + local-zone: "17.172.in-addr.arpa" nodefault + local-zone: "18.172.in-addr.arpa" nodefault + local-zone: "19.172.in-addr.arpa" nodefault + local-zone: "20.172.in-addr.arpa" nodefault + local-zone: "21.172.in-addr.arpa" nodefault + local-zone: "22.172.in-addr.arpa" nodefault + local-zone: "23.172.in-addr.arpa" nodefault + local-zone: "24.172.in-addr.arpa" nodefault + local-zone: "25.172.in-addr.arpa" nodefault + local-zone: "26.172.in-addr.arpa" nodefault + local-zone: "27.172.in-addr.arpa" nodefault + local-zone: "28.172.in-addr.arpa" nodefault + local-zone: "29.172.in-addr.arpa" nodefault + local-zone: "30.172.in-addr.arpa" nodefault + local-zone: "31.172.in-addr.arpa" nodefault + local-zone: "168.192.in-addr.arpa" nodefault + +$([ -z "$unbound_local_zones" ] || printf ' local-zone: "%s" typetransparent\n' $unbound_local_zones) + + private-domain: "${domain}" +$([ -z "$unbound_local_zones" ] || printf ' private-domain: "%s"\n' $unbound_local_zones) + +$([ -z "$unbound_local_data" ] || printf ' local-data: "%s"\n' $unbound_local_data) + +$(echo "$unbound_blocklists" | while read -r name _url; do + [ -n "$name" ] && printf "rpz:\n name: %s\n zonefile: ${unbound_blocklist_dir}/%s.zone\n" "$name" "$name"; done) + +stub-zone: + name: "${domain}" + stub-addr: 127.0.0.1@${pdns_port} +$(printf "\ +stub-zone: + name: \"%s\" + stub-addr: 127.0.0.1@${pdns_port} +" $reverse_dns_zones) diff --git a/files/usr/local/libexec/idm-ssh-authorized-keys.common b/files/usr/local/libexec/idm-ssh-authorized-keys.common new file mode 100644 index 0000000..d18b199 --- /dev/null +++ b/files/usr/local/libexec/idm-ssh-authorized-keys.common @@ -0,0 +1,43 @@ +#!/usr/local/bin/perl + +use strict; +use warnings; + +use Net::LDAP; +use Net::LDAP::Util qw(escape_filter_value); +use Authen::SASL; + +open my $fh, '<', '/usr/local/etc/openldap/ldap.conf' or quit($!); +my %config; +while (<$fh>) { + chomp; + next if /^#/; + my @pair = split(' ', $_, 2); + next unless (@pair == 2); + $config{$pair[0]} = $pair[1]; +} +close($fh); + +my $mech = $config{SASL_MECH} // 'GSSAPI'; +my $uri = $config{URI} // quit('URI not specified'); +my $basedn = $config{BASE} // quit('BASE not specified'); + +@ARGV == 1 or die "usage: $0 USERNAME\n"; +my $username = $ARGV[0]; + +my $conn = Net::LDAP->new($uri, version => '3') or die "$0: $@"; +my $sasl = Authen::SASL->new($mech); +my $status = $conn->bind(sasl => $sasl); +$status->code and die "$0: ".$status->error; + +my $search = $conn->search( + scope => 'sub', + base => "ou=accounts,$basedn", + filter => '(&(objectClass=posixAccount)(sshPublicKey=*)(uid=' . escape_filter_value($username) . '))', + attrs => ['sshPublicKey']); +$search->code and die "$0: ".$search->error; + +exit 0 if $search->entries == 0; +die "$0: multiple LDAP entries returned for user: $username\n" if $search->entries > 1; + +print "$_\n" foreach (($search->entries)[0]->get_value('sshPublicKey')); diff --git a/files/usr/local/libexec/idm-ssh-known-hosts.common b/files/usr/local/libexec/idm-ssh-known-hosts.common new file mode 100644 index 0000000..78b48fc --- /dev/null +++ b/files/usr/local/libexec/idm-ssh-known-hosts.common @@ -0,0 +1,51 @@ +#!/usr/local/bin/perl + +use strict; +use warnings; + +use Net::LDAP; +use Net::LDAP::Util qw(escape_filter_value); +use Authen::SASL; + +sub quit { + # Prints an error message and exits with code 0. + # NB: If KnownHostsCommand returns nonzero, the entire SSH connection aborts, + # which isn't what we want. + print STDERR "$0: $_[0]" if @_ > 0; + exit 0 +} + +@ARGV == 1 or die "usage: $0 HOSTNAME\n"; +my $hostname = $ARGV[0]; + +open my $fh, '<', '/usr/local/etc/openldap/ldap.conf' or quit($!); +my %config; +while (<$fh>) { + chomp; + next if /^#/; + my @pair = split(' ', $_, 2); + next unless (@pair == 2); + $config{$pair[0]} = $pair[1]; +} +close($fh); + +my $mech = $config{SASL_MECH} // 'GSSAPI'; +my $uri = $config{URI} // quit('URI not specified'); +my $basedn = $config{BASE} // quit('BASE not specified'); + +my $conn = Net::LDAP->new($uri, version => '3') or quit($@); +my $sasl = Authen::SASL->new($mech); +my $status = $conn->bind(sasl => $sasl); +$status->code and quit($status->error); + +my $search = $conn->search( + scope => 'sub', + base => "ou=hosts,ou=accounts,$basedn", + filter => '(&(sshPublicKey=*)(associatedDomain=' . escape_filter_value($hostname) . '))', + attrs => ['sshPublicKey']); +$search->code and quit($search->error); + +quit if $search->entries == 0; +quit("multiple LDAP entries returned for host: $hostname\n") if $search->entries > 1; + +print "$hostname $_\n" foreach (($search->entries)[0]->get_value('sshPublicKey')); diff --git a/files/usr/local/libexec/idm-update-unbound-blocklists.idm_server b/files/usr/local/libexec/idm-update-unbound-blocklists.idm_server new file mode 100644 index 0000000..c33b909 --- /dev/null +++ b/files/usr/local/libexec/idm-update-unbound-blocklists.idm_server @@ -0,0 +1,32 @@ +#!/bin/sh + +set -eu -o pipefail + +prog=$(basename "$(readlink -f "$0")") +usage="${prog} BLOCKLIST_DIR + Blocklist URLs are read from stdin." + +die() { + printf '%s: %s\n' "$prog" "$*" 1>&2 + exit 1 +} + +usage(){ + printf 'usage: %s\n' "$usage" 1>&2 + exit 2 +} + +[ $# -eq 1 ] || usage +case $1 in + -h|--help) usage ;; +esac + +[ -d "$1" ] || die "not a directory: ${1}" + +cd "$1" + +find . -maxdepth 1 -type f -exec rm {} + + +while read -r name url; do + [ -n "$url" ] && curl -sSfL -o "${name}.zone" "$url" +done diff --git a/files/usr/local/var/krb5kdc/kadm5.acl.idm_server b/files/usr/local/var/krb5kdc/kadm5.acl.idm_server new file mode 100644 index 0000000..c2a454b --- /dev/null +++ b/files/usr/local/var/krb5kdc/kadm5.acl.idm_server @@ -0,0 +1,2 @@ +*/admin@${realm} * * -maxlife 1h -postdateable +${boxconf_username}@${realm} * * -maxlife 5m -postdateable diff --git a/files/usr/local/var/krb5kdc/kdc.conf.idm_server b/files/usr/local/var/krb5kdc/kdc.conf.idm_server new file mode 100644 index 0000000..ab16965 --- /dev/null +++ b/files/usr/local/var/krb5kdc/kdc.conf.idm_server @@ -0,0 +1,23 @@ +[realms] + ${realm} = { + database_module = openldap_ldapconf + key_stash_file = ${kdc_master_key_path} + max_life = ${kdc_max_life} + max_renewable_life = ${kdc_max_renewable_life} + default_principal_flags = +preauth + } + +[dbdefaults] + ldap_kerberos_container_dn = ${kdc_basedn} + ldap_kdc_sasl_mech = EXTERNAL + ldap_kadmind_sasl_mech = EXTERNAL + ldap_conns_per_server = 5 + +[dbmodules] + openldap_ldapconf = { + ldap_servers = ${slapd_ldapi_uri} + db_library = kldap + } + +[logging] + default = SYSLOG |