metznet-channel/system/base-system.scm

409 lines
17 KiB
Scheme

2022-09-17 19:54:28 -06:00
(define-module (system base-system)
2022-09-28 14:55:38 -06:00
#:use-module (metznet)
#:use-module (ice-9 exceptions)
#:use-module (nongnu system linux-initrd)
#:use-module (nongnu packages linux)
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module (guix download)
#:use-module (guix build-system gnu)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (gnu)
#:use-module (gnu system setuid)
#:use-module (gnu system nss)
#:use-module (gnu system pam)
#:use-module (gnu services pm)
2023-11-21 19:05:13 -07:00
#:use-module (gnu services authentication)
#:use-module (gnu services vpn)
#:use-module (gnu services networking)
#:use-module (gnu services ssh)
#:use-module (gnu services kerberos)
#:use-module (gnu services desktop)
#:use-module (gnu services xorg)
#:use-module (gnu services base)
#:use-module (gnu packages linux)
#:use-module (gnu packages compression)
#:use-module (gnu packages libedit)
#:use-module (gnu packages hurd)
#:use-module (gnu packages tls)
#:use-module (gnu packages xorg)
#:use-module (gnu packages pkg-config)
#:use-module (gnu packages groff)
#:use-module (gnu packages security-token)
#:use-module (gnu packages vim)
#:use-module (gnu packages certs)
#:use-module (gnu packages vpn)
#:use-module (gnu packages networking)
#:use-module (gnu packages dns)
#:use-module (gnu packages base)
#:use-module (gnu packages openldap)
#:use-module (gnu packages kerberos)
#:use-module (gnu packages admin)
#:use-module (gnu packages shells)
#:use-module (gnu packages gnome)
#:use-module (gnu packages wm)
#:use-module (gnu packages suckless)
#:use-module (gnu packages gnuzilla)
#:use-module (gnu packages terminals)
#:use-module (gnu packages virtualization)
#:use-module (gnu packages version-control)
2023-11-21 19:05:13 -07:00
#:export (%domain-realm)
#:export (%domain-name)
#:export (%domain-kadmin)
#:export (%domain-kdc)
#:export (%metznet-base-user-accounts)
#:export (%metznet-base-groups)
#:export (%metznet-base-packages)
#:export (%metznet-desktop-packages)
#:export (%metznet-server-packages)
#:export (%metznet-setuid-programs)
#:export (%default-keyboard-layout)
#:export (%kvm-udev-rule)
#:export (%usb-udev-rule)
#:export (%tun-udev-rule)
#:export (%metznet-desktop-services)
#:export (%metznet-server-services)
#:export (%metznet-base-server-system)
#:export (%metznet-base-desktop-system))
(define openssh-ldap
(package
(name "openssh")
(version "9.3p1")
(source (origin
(method url-fetch)
(uri (string-append "mirror://openbsd/OpenSSH/portable/"
"openssh-" version ".tar.gz"))
(patches (search-patches "openssh-hurd.patch"
"openssh-trust-guix-store-directory.patch"))
(sha256
(base32
"1a7qia3c255igny5kf00m5zxkp69lf1w6qjsv3rm2sm705vvmfp9"))))
(build-system gnu-build-system)
(native-inputs (list groff pkg-config))
(propagated-inputs (list nss-pam-ldapd))
(inputs `(("libedit" ,libedit)
("openssl" ,openssl)
,@(if (hurd-target?)
'()
`(("pam" ,linux-pam)
("libfido2" ,libfido2))) ;fails to build on GNU/Hurd
("mit-krb5" ,mit-krb5)
("zlib" ,zlib)
("xauth" ,xauth))) ; for 'ssh -X' and 'ssh -Y'
(arguments
`(#:test-target "tests"
;; Otherwise, the test scripts try to use a nonexistent directory and
;; fail.
#:make-flags '("REGRESSTMP=\"$${BUILDDIR}/regress\"")
#:configure-flags `("--sysconfdir=/etc/ssh"
;; Default value of 'PATH' used by sshd.
"--with-default-path=/run/current-system/profile/bin"
;; configure needs to find krb5-config.
,(string-append "--with-kerberos5="
(assoc-ref %build-inputs "mit-krb5")
"/bin")
;; libedit is needed for sftp completion.
"--with-libedit"
;; Enable PAM support in sshd.
,,@(if (hurd-target?)
'()
'("--with-pam"
;; Support creation and use of ecdsa-sk,
;; ed25519-sk keys.
"--with-security-key-builtin"))
;; "make install" runs "install -s" by default,
;; which doesn't work for cross-compiled binaries
;; because it invokes 'strip' instead of
;; 'TRIPLET-strip'. Work around this.
,,@(if (%current-target-system)
'("--disable-strip")
'()))
#:phases
(modify-phases %standard-phases
(add-after 'configure 'reset-/var/empty
(lambda* (#:key outputs #:allow-other-keys)
(let ((out (assoc-ref outputs "out")))
(substitute* "Makefile"
(("PRIVSEP_PATH=/var/empty")
(string-append "PRIVSEP_PATH=" out "/var/empty"))))))
(add-after 'configure 'set-store-location
(lambda* _
(substitute* "misc.c"
(("@STORE_DIRECTORY@")
(string-append "\"" (%store-directory) "\"")))))
(add-before 'check 'patch-tests
(lambda _
(substitute* "regress/test-exec.sh"
(("/bin/sh") (which "sh")))
;; Remove 't-exec' regress target which requires user 'sshd'.
(substitute* (list "Makefile"
"regress/Makefile")
(("^(tests:.*) t-exec(.*)" all pre post)
(string-append pre post)))))
(replace 'install
(lambda* (#:key outputs (make-flags '()) #:allow-other-keys)
(let ((out (assoc-ref outputs "out")))
;; Install without host keys and system configuration files.
;; This will install /var/empty to the store, which is needed
;; by the system openssh-service-type.
(apply invoke "make" "install-nosysconf" make-flags)
(with-directory-excursion "contrib"
(chmod "ssh-copy-id" #o555)
(install-file "ssh-copy-id"
(string-append out "/bin/"))
(install-file "ssh-copy-id.1"
(string-append out "/share/man/man1/")))))))))
(synopsis "Client and server for the secure shell (ssh) protocol")
(description
"The SSH2 protocol implemented in OpenSSH is standardised by the
IETF secsh working group and is specified in several RFCs and drafts.
It is composed of three layered components:
The transport layer provides algorithm negotiation and a key exchange.
The key exchange includes server authentication and results in a
cryptographically secured connection: it provides integrity, confidentiality
and optional compression.
The user authentication layer uses the established connection and relies on
the services provided by the transport layer. It provides several mechanisms
for user authentication. These include traditional password authentication
as well as public-key or host-based authentication mechanisms.
The connection layer multiplexes many different concurrent channels over the
authenticated connection and allows tunneling of login sessions and
TCP-forwarding. It provides a flow control service for these channels.
Additionally, various channel-specific options can be negotiated.")
(license (license:non-copyleft "file://LICENSE"
"See LICENSE in the distribution."))
(properties
'((release-monitoring-url . "https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/")))
(home-page "https://www.openssh.com/")))
2023-11-21 19:05:13 -07:00
(define %domain-realm "METZNET.CA")
(define %domain-name "metznet.ca")
(define %domain-kadmin (string-append "kerberos." %domain-name))
2023-11-21 20:57:51 -07:00
2023-11-21 19:05:13 -07:00
(define %domain-kdc (string-append "kerberos." %domain-name))
(define %metznet-base-user-accounts (append (list
(user-account
(name "root")
(group "root")
(uid 0)
(password (crypt "root" "$6$salt"))
(shell (file-append zsh "/bin/zsh"))))
%base-user-accounts))
2023-11-21 19:05:13 -07:00
(define %metznet-base-groups (append (list
(user-group
(system? #t)
(name "realtime"))
(user-group
(system? #t)
(name "usb")))
%base-groups))
(define %metznet-base-packages (append (list openssh-ldap nss-pam-ldapd glibc openldap git neovim zsh le-certs nss-certs mit-krb5 openvpn openresolv) %base-packages))
2023-11-21 19:05:13 -07:00
(define %metznet-desktop-packages (append (list i3-wm i3status dmenu kitty icecat) %metznet-base-packages))
2023-11-21 19:05:13 -07:00
(define %metznet-server-packages (append (list isc-dhcp) %metznet-base-packages))
2023-11-21 19:05:13 -07:00
(define %desktop-setuid-programs (append
(list (setuid-program
(program #~(string-append #$openvpn "/sbin/openvpn")))
(setuid-program
(program #~(string-append #$openresolv "/sbin/resolvconf"))))
%setuid-programs))
2023-11-21 20:57:51 -07:00
(define %metznet-krb5-config (krb5-configuration
2023-11-21 19:05:13 -07:00
(default-realm %domain-realm)
(allow-weak-crypto? #t)
(rdns? #f)
(realms (list (krb5-realm
2023-11-21 19:05:13 -07:00
(name %domain-realm)
2023-11-21 20:57:51 -07:00
(admin-server %domain-kadmin)
(kdc %domain-kdc))))))
2023-11-21 19:05:13 -07:00
(define %default-keyboard-layout (keyboard-layout "us"))
2023-11-21 19:05:13 -07:00
(define %kvm-udev-rule
(udev-rule
"65-kvm.rules"
"KERNEL==\"KVM\", GROUP=\"libvirt\", MODE=\"0660\""))
2023-11-21 19:05:13 -07:00
(define %usb-udev-rule
(udev-rule
"51-usb.rules"
(string-append "SUBSYSTEM==\"usb\", GROUP=\"usb\"\n"
"SUBSYSTEM==\"usbmisc\", GROUP=\"usb\"")))
(define %tun-udev-rule
(udev-rule
"90-tun.rules"
"KERNEL==\"tun\", GROUP=\"netdev\", MODE=\"0660\", OPTIONS+=\"static_node=net/tun\""))
(define %backlight-udev-rule
(udev-rule
"55-backlight.rules"
"RUN+=\"/bin/chgrp video /sys/class/backlight/intel_backlight/brightness\""))
2023-11-21 19:05:13 -07:00
(define %metznet-name-service-switch
(let ((services (list (name-service (name "ldap"))
(name-service (name "files")))))
2023-11-21 19:05:13 -07:00
(name-service-switch
(password services)
(shadow services)
(group services))))
; 1) need to create user directory on login
; 2) need to have /bin/zsh available to use as shell
(define pam-ldap-module (file-append nss-pam-ldapd "/lib/security/pam_ldap.so"))
(define (metznet-pam-service config)
(lambda (pam)
(if (member (pam-service-name pam) config)
(let ((sufficient
(pam-entry
(control "sufficient")
(module pam-ldap-module))))
(pam-service
(inherit pam)
(password (cons sufficient (pam-service-account pam)))))
pam)))
(define (metznet-pam-services config)
(list (metznet-pam-service config)))
(define metznet-service-type
(service-type
(name 'metznet-service)
(description "MetzNet Services")
(extensions
(list (service-extension pam-root-service-type metznet-pam-services)))
(default-value '())))
(define %metznet-nslcd-config (nslcd-configuration
(base "dc=metznet,dc=ca")
(log '("/var/log/nslcd" debug))
(pam-services (list "su" "login" "sshd" "passwd"))
(filters (list '(group "(objectClass=posixGroupAux)")))
(binddn (or (getenv "LDAP_BINDDN") ""))
(bindpw (or (getenv "LDAP_BINDPW") ""))
(uri (list "ldap://ldap.metznet.ca"))))
(define %metznet-services
(list
(simple-service 'metznet-ln-service activation-service-type #~(symlink "/run/current-system/profile/bin/zsh" "/bin/zsh"))
(service openssh-service-type (openssh-configuration
(openssh openssh-ldap)
(log-level 'debug3)
(extra-content "KerberosAuthentication yes")))
(service krb5-service-type %metznet-krb5-config)
(service pam-krb5-service-type (pam-krb5-configuration (pam-krb5 pam-krb5) (minimum-uid 1000)))
(service metznet-service-type (list "su" "login" "sshd" "passwd"))
(service nslcd-service-type %metznet-nslcd-config)))
2023-11-21 19:05:13 -07:00
(define %metznet-desktop-services
(append %metznet-services
(modify-services %desktop-services
(guix-service-type config => (guix-configuration
(inherit config)
(substitute-urls
(append (list "https://substitutes.nonguix.org")
%default-substitute-urls))
(authorized-keys
(append (list (plain-file "nonguix.pub"
"(public-key
(ecc
(curve Ed25519)
(q #C1FD53E5D4CE971933EC50C9F307AE2171A2D3B52C804642A7A35F84F3A4EA98#)))"))
%default-authorized-guix-keys))))
(elogind-service-type config =>
(elogind-configuration (inherit config)
(handle-lid-switch-external-power 'suspend)))
(udev-service-type config =>
(udev-configuration (inherit config)
(rules (append (list %tun-udev-rule
%backlight-udev-rule)
(udev-configuration-rules config)))))
(network-manager-service-type config =>
(network-manager-configuration (inherit config)
(vpn-plugins (list network-manager-openvpn)))))))
(define %metznet-server-services (append (append %metznet-services
(list
(service dhcp-client-service-type)
(openvpn-client-service
#:config (openvpn-client-configuration
(openvpn openvpn)
(pid-file "/var/run/openvpn/client.pid")
(persist-key? #f)
(tls-auth "/etc/openvpn/ta.key"))))
%base-services)))
2023-11-21 19:05:13 -07:00
(define %metznet-base-operating-system
(operating-system
;; Hostname and localization information
(host-name "base")
(timezone "America/Edmonton")
(locale "en_CA.utf8")
(keyboard-layout %default-keyboard-layout)
2023-11-21 19:05:13 -07:00
(name-service-switch %metznet-name-service-switch)
;; Kernel and firmware definitions
(kernel linux)
(kernel-arguments (append '("console=ttyS0") %default-kernel-arguments))
(firmware (list linux-firmware))
(initrd microcode-initrd)
;; Grub UEFI Bootloader installed to /boot/efi
(bootloader
(bootloader-configuration
(bootloader grub-efi-bootloader)
(targets '("/boot/efi"))
(keyboard-layout keyboard-layout)))
(file-systems (cons*
(file-system
(mount-point "/boot/efi")
(device "/dev/vda1")
(type "vfat")
(check? #f))
(file-system
(mount-point "/")
(device "/dev/vda3")
(type "xfs")
(check? #f))
%base-file-systems))
2023-11-21 19:05:13 -07:00
(users %metznet-base-user-accounts)
(groups %metznet-base-groups)
(packages %metznet-base-packages)
(services (append %metznet-services %base-services))))
2023-11-21 19:05:13 -07:00
(define %metznet-base-server-system
(operating-system
2023-11-21 19:05:13 -07:00
(inherit %metznet-base-operating-system)
(host-name "metznet-base-server")
(packages %metznet-server-packages)
(services %metznet-server-services)))
2023-11-21 19:05:13 -07:00
(define %metznet-base-desktop-system
(operating-system
2023-11-21 19:05:13 -07:00
(inherit %metznet-base-operating-system)
(host-name "metznet-base-desktop")
(setuid-programs %desktop-setuid-programs)
(packages %metznet-desktop-packages)
(services %metznet-desktop-services)))