diff options
43 files changed, 546 insertions, 13 deletions
diff --git a/files/etc/cron.d/zfs-autosnapshot.freebsd b/files/etc/cron.d/zfs-autosnapshot.freebsd new file mode 100644 index 0000000..0cc1e3b --- /dev/null +++ b/files/etc/cron.d/zfs-autosnapshot.freebsd @@ -0,0 +1,5 @@ +15,30,45 * * * * root /usr/local/sbin/zfs-auto-snapshot frequent 4 +0 * * * * root /usr/local/sbin/zfs-auto-snapshot hourly 24 +7 0 * * * root /usr/local/sbin/zfs-auto-snapshot daily 7 +14 0 * * 7 root /usr/local/sbin/zfs-auto-snapshot weekly 4 +28 0 1 * * root /usr/local/sbin/zfs-auto-snapshot monthly 12 diff --git a/files/etc/cron.d/zfs-trim.freebsd b/files/etc/cron.d/zfs.freebsd index 80e0cd5..477f1df 100644 --- a/files/etc/cron.d/zfs-trim.freebsd +++ b/files/etc/cron.d/zfs.freebsd @@ -1 +1,2 @@ @weekly root zpool list -Ho name | xargs -r -n1 zpool trim +@monthly root zpool list -Ho name | xargs -r zpool scrub diff --git a/files/etc/login.access.freebsd b/files/etc/login.access.freebsd new file mode 100644 index 0000000..e6667db --- /dev/null +++ b/files/etc/login.access.freebsd @@ -0,0 +1,13 @@ +# Always allow root logins. ++:root:ALL + +$(if [ -n "${login_access_groups:-}" ] || [ -n "${login_access_users:-}" ]; then + printf -- '-:ALL EXCEPT ' +if [ -n "${login_access_groups:-}" ]; then + printf '(%s) ' ${login_access_groups} +fi +if [ -n "${login_access_users:-}" ]; then + printf '%s ' ${login_access_users} +fi + printf ':ALL\n' +fi) diff --git a/files/etc/pam.d/kde.freebsd b/files/etc/pam.d/kde.freebsd index 8f87b98..cb89294 100644 --- a/files/etc/pam.d/kde.freebsd +++ b/files/etc/pam.d/kde.freebsd @@ -1,5 +1,5 @@ auth required /usr/local/lib/security/pam_krb5.so try_first_pass account required /usr/local/lib/security/pam_krb5.so -account required pam_login_access.so +account required pam_login_access.so nodefgroup account required pam_unix.so diff --git a/files/etc/pam.d/login.freebsd b/files/etc/pam.d/login.freebsd index 164fcb0..ae50bbe 100644 --- a/files/etc/pam.d/login.freebsd +++ b/files/etc/pam.d/login.freebsd @@ -5,12 +5,13 @@ auth required pam_unix.so no_warn try_first_pass nullok account requisite pam_securetty.so account required pam_nologin.so account required /usr/local/lib/security/pam_krb5.so -account required pam_login_access.so +account required pam_login_access.so nodefgroup account required pam_unix.so session required pam_lastlog.so no_fail session required pam_xdg.so session required /usr/local/lib/security/pam_krb5.so +session optional /usr/local/lib/pam_mkhomedir.so mode=0700 password sufficient /usr/local/lib/security/pam_krb5.so try_first_pass password required pam_unix.so no_warn try_first_pass diff --git a/files/etc/pam.d/other.freebsd b/files/etc/pam.d/other.freebsd new file mode 100644 index 0000000..38db8c5 --- /dev/null +++ b/files/etc/pam.d/other.freebsd @@ -0,0 +1,8 @@ +auth required pam_unix.so no_warn try_first_pass + +account required pam_nologin.so +account required pam_unix.so + +session required pam_permit.so + +password required pam_permit.so diff --git a/files/etc/pam.d/sddm.freebsd b/files/etc/pam.d/sddm.freebsd index 6a75823..c222750 100644 --- a/files/etc/pam.d/sddm.freebsd +++ b/files/etc/pam.d/sddm.freebsd @@ -10,12 +10,13 @@ auth optional pam_kwallet5.so account requisite pam_securetty.so account required pam_nologin.so account required /usr/local/lib/security/pam_krb5.so -account required pam_login_access.so +account required pam_login_access.so nodefgroup account required pam_unix.so session required pam_lastlog.so no_fail session required pam_xdg.so no_fail session required /usr/local/lib/security/pam_krb5.so +session optional /usr/local/lib/pam_mkhomedir.so mode=0700 session optional pam_kwallet5.so auto_start password required /usr/local/lib/security/pam_krb5.so try_first_pass diff --git a/files/etc/pam.d/sshd.freebsd b/files/etc/pam.d/sshd.freebsd index 559a980..1f81b48 100644 --- a/files/etc/pam.d/sshd.freebsd +++ b/files/etc/pam.d/sshd.freebsd @@ -3,11 +3,11 @@ auth required pam_unix.so no_warn try_first_pass account required pam_nologin.so account required /usr/local/lib/security/pam_krb5.so -account required pam_login_access.so +account required pam_login_access.so nodefgroup account required pam_unix.so session required /usr/local/lib/security/pam_krb5.so -session required pam_permit.so +session required /usr/local/lib/pam_mkhomedir.so mode=0700 password sufficient /usr/local/lib/security/pam_krb5.so try_first_pass password required pam_unix.so no_warn try_first_pass diff --git a/files/etc/pam.d/su.freebsd b/files/etc/pam.d/su.freebsd new file mode 100644 index 0000000..0bd3ea0 --- /dev/null +++ b/files/etc/pam.d/su.freebsd @@ -0,0 +1,10 @@ +auth sufficient pam_rootok.so no_warn +auth sufficient pam_self.so no_warn +auth requisite pam_group.so no_warn group=wheel root_only fail_safe ruser +auth sufficient /usr/local/lib/security/pam_krb5.so try_first_pass +auth required pam_unix.so no_warn try_first_pass nullok + +account required /usr/local/lib/security/pam_krb5.so +account required pam_unix.so + +session required pam_permit.so diff --git a/files/etc/pam.d/sudo.freebsd b/files/etc/pam.d/sudo.freebsd index 6a6b0a4..6c0a573 100644 --- a/files/etc/pam.d/sudo.freebsd +++ b/files/etc/pam.d/sudo.freebsd @@ -2,10 +2,9 @@ auth sufficient /usr/local/lib/security/pam_krb5.so try_first_pass auth required pam_unix.so no_warn try_first_pass account required /usr/local/lib/security/pam_krb5.so -account required pam_login_access.so account required pam_unix.so -account required pam_permit.so +session required pam_permit.so password sufficient /usr/local/lib/security/pam_krb5.so try_first_pass password required pam_unix.so no_warn try_first_pass diff --git a/files/etc/pam.d/system.freebsd b/files/etc/pam.d/system.freebsd new file mode 100644 index 0000000..b85310c --- /dev/null +++ b/files/etc/pam.d/system.freebsd @@ -0,0 +1,8 @@ +auth required pam_unix.so no_warn try_first_pass nullok + +account required pam_unix.so + +session required pam_lastlog.so no_fail +session required pam_xdg.so + +password required pam_unix.so no_warn try_first_pass diff --git a/files/etc/pf.conf.nfs_server b/files/etc/pf.conf.nfs_server new file mode 100644 index 0000000..628ed7c --- /dev/null +++ b/files/etc/pf.conf.nfs_server @@ -0,0 +1,52 @@ +$(if [ -n "${pf_egress_interfaces:-}" ]; then + printf 'egress = "{ %s }"\n' "$(join ', ' $pf_egress_interfaces)" + else + printf 'egress = "%s"\n' "$BOXCONF_DEFAULT_INTERFACE" + fi) +allowed_tcp_ports = "{ $(join ', ' ${allowed_tcp_ports:-}) }" +allowed_udp_ports = "{ $(join ', ' ${allowed_udp_ports:-}) }" + +$([ "${acme_standalone:-}" = true ] && cat <<EOF +acme_standalone_port = ${acme_standalone_port} +acme_standalone_user = $(id -u "$acme_user") +EOF +) +nfscbd_port = ${nfscbd_port} + +set block-policy return +set skip on lo +$([ -n "${pf_skip_interfaces:-}" ] && printf \ + 'set skip on %s\n' $pf_skip_interfaces) + +scrub in on \$egress all fragment reassemble no-df + +$([ "${acme_standalone:-}" = true ] && echo \ + 'rdr on $egress inet proto tcp to port http -> ($egress) port $acme_standalone_port' + +[ -n "${redirect_tcp_ports:-}" ] && printf \ + 'rdr on $egress inet proto tcp to port %s -> ($egress) port %s\n' $redirect_tcp_ports + +[ -n "${redirect_udp_ports:-}" ] && printf \ + 'rdr on $egress inet proto udp to port %s -> ($egress) port %s\n' $redirect_udp_ports) + +antispoof quick for \$egress + +block all +pass out quick on \$egress inet +pass in quick on \$egress inet proto icmp all icmp-type { echoreq, unreach } + +$([ "${acme_standalone:-}" = true ] && echo \ + 'pass in quick on $egress inet proto tcp to port $acme_standalone_port user $acme_standalone_user' + +[ -n "${allowed_tcp_ports:-}" ] && echo \ + 'pass in quick on $egress inet proto tcp to port $allowed_tcp_ports' + +[ -n "${allowed_udp_ports:-}" ] && echo \ + 'pass in quick on $egress inet proto udp to port $allowed_udp_ports' + +[ "$BOXCONF_VIRTUALIZATION_TYPE" == jail ] || echo \ + 'pass in quick on $egress inet proto { tcp, udp } to port $nfscbd_port' + +for user in ${syncthing_users:-}; do uid=$(id -u "$user"); eval "port=\$syncthing_${user}_port"; printf \ + 'pass in quick on $egress inet proto { tcp, udp } to port %s user %s\n' "$port" "$(id -u "$user")" +done) diff --git a/files/usr/local/etc/nginx/vhosts.conf.nfs_server b/files/usr/local/etc/nginx/vhosts.conf.nfs_server new file mode 100644 index 0000000..e6fa55b --- /dev/null +++ b/files/usr/local/etc/nginx/vhosts.conf.nfs_server @@ -0,0 +1,38 @@ +$(for user in ${syncthing_users:-}; do cat <<EOF +upstream syncthing_${user} { + server unix:///var/run/syncthing/${user}/syncthing.sock; +} + +EOF +done) + +server { + listen 443 ssl default_server; + listen [::]:443 ssl default_server; + http2 on; + + ssl_certificate ${syncthing_https_cert}; + ssl_certificate_key ${syncthing_https_key}; + + add_header Strict-Transport-Security "max-age=63072000" always; + + auth_gss_keytab ${nginx_keytab}; + auth_gss_allow_basic_fallback off; + +$(for user in ${syncthing_users:-}; do cat <<EOF + location /${user}/ { + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + proxy_read_timeout 600s; + proxy_send_timeout 600s; + proxy_pass http://syncthing_${user}/; + auth_gss on; + auth_gss_authorized_principal ${user}; + } +EOF +done) +} diff --git a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository index 883a88d..7d2a7ab 100644 --- a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository +++ b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository @@ -88,6 +88,7 @@ net/php${php_version}-ldap net/php${php_version}-sockets net/py-python-ldap net/rsync +net/syncthing net/turnserver net/wireguard-tools ports-mgmt/poudriere @@ -102,6 +103,7 @@ security/kstart security/openssh-portable security/pam_krb5@mit security/pam_mkhomedir +security/pam_mkhomedir security/php${php_version}-filter security/py-omemo-dr security/sshpass @@ -120,6 +122,7 @@ sysutils/pwgen sysutils/stow sysutils/tmux sysutils/tree +sysutils/zfstools textproc/hs-pandoc textproc/jq textproc/p5-YAML diff --git a/files/usr/local/etc/rc.d/syncthing_user.nfs_server b/files/usr/local/etc/rc.d/syncthing_user.nfs_server new file mode 100644 index 0000000..0229047 --- /dev/null +++ b/files/usr/local/etc/rc.d/syncthing_user.nfs_server @@ -0,0 +1,86 @@ +#!/bin/sh + +# PROVIDE: syncthing_user +# REQUIRE: DAEMON nslcd +# KEYWORD: shutdown +# +# syncthing_user_enable=YES +# syncthing_user_instances="bob joe" +# syncthing_user_bob_port="22000" +# syncthing_user_joe_port="22001" + +. /etc/rc.subr + +name=syncthing_user +rcvar=syncthing_user_enable + +load_rc_config $name + +: ${syncthing_user_enable:='NO'} +: ${syncthing_user_socket_group:='www'} + +syncthing_user_rundir=/var/run/syncthing +syncthing_user_confdir=/var/db/syncthing +syncthing_user_args='serve --no-browser --no-upgrade --no-default-folder --logflags=0 --logfile=-' +syncthing_config_template=/usr/local/etc/syncthing.template.xml + +procname="/usr/local/bin/syncthing" +command="/usr/sbin/daemon" +start_precmd=syncthing_user_startprecmd +required_files="${syncthing_config_template}" + +syncthing_user_startprecmd() +{ + [ -d "$syncthing_user_rundir" ] || install -d -m 0755 "$syncthing_user_rundir" + [ -d "$syncthing_user_irundir" ] || install -d -m 2750 -o "$syncthing_user_user" -g "$syncthing_user_socket_group" "$syncthing_user_irundir" + [ -d "$syncthing_user_iconfdir" ] || install -d -m 0750 -o "$syncthing_user_user" -g "$syncthing_user_user" "$syncthing_user_iconfdir" + + if [ ! -f "${syncthing_user_iconfdir}/config.xml" ]; then + su -m "$syncthing_user_user" -c "${procname} generate --home=${syncthing_user_iconfdir}" + + deviceid=$("$procname" serve --home="$syncthing_user_iconfdir" --device-id) + fqdn=$(hostname -f) + sed -E \ + -e "s|__DEVICEID__|${deviceid}|" \ + -e "s|__PORT__|${syncthing_user_port}|" \ + -e "s|__FQDN__|${fqdn}|" \ + -e "s|__SOCK__|${syncthing_user_irundir}/syncthing.sock|" \ + "$syncthing_config_template" > "${syncthing_user_iconfdir}/config.xml" + fi +} + +if [ -n "$syncthing_user_instances" ]; then + _1=$1 + if [ $# -gt 1 ]; then + shift + syncthing_user_instances=$* + fi + + rc=0 + for syncthing_user_user in $syncthing_user_instances; do + syncthing_user_group=$syncthing_user_user + syncthing_user_iconfdir="${syncthing_user_confdir}/${syncthing_user_user}" + syncthing_user_irundir="${syncthing_user_rundir}/${syncthing_user_user}" + unset syncthing_user_port + eval "syncthing_user_port=\$syncthing_user_${syncthing_user_user}_port" + + if [ -z "${syncthing_user_port:-}" ]; then + echo "syncthing_user_${syncthing_user_user}_port not defined in /etc/rc.conf - skipping" 1>&2 + continue + fi + + pidfile="${syncthing_user_rundir}/${syncthing_user_user}/syncthing.pid" + command_args="-cf -s info -l daemon -T syncthing-${syncthing_user_user} -p ${pidfile} -t syncthing-${syncthing_user_user} \ + ${procname} ${syncthing_user_args} --home=${syncthing_user_iconfdir} --gui-address=unix://${syncthing_user_irundir}/syncthing.sock" + + run_rc_command "$_1" + if [ $? -ne 0 ]; then rc=1; fi + + unset _pidcmd _rc_restart_done + done + + exit $rc +else + echo 'No users defined. Set syncthing_user_instances in /etc/rc.conf.' 1>&2 + exit 1 +fi diff --git a/files/usr/local/etc/syncthing.template.xml.nfs_server b/files/usr/local/etc/syncthing.template.xml.nfs_server new file mode 100644 index 0000000..3ee90a1 --- /dev/null +++ b/files/usr/local/etc/syncthing.template.xml.nfs_server @@ -0,0 +1,131 @@ +<configuration version="37"> + <device id="__DEVICEID__" name="__FQDN__" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy=""> + <address>tcp://__FQDN__:__PORT__</address> + <paused>false</paused> + <autoAcceptFolders>false</autoAcceptFolders> + <maxSendKbps>0</maxSendKbps> + <maxRecvKbps>0</maxRecvKbps> + <maxRequestKiB>0</maxRequestKiB> + <untrusted>false</untrusted> + <remoteGUIPort>0</remoteGUIPort> + <numConnections>0</numConnections> + </device> + <gui enabled="true" tls="false" debugging="false" sendBasicAuthPrompt="false"> + <address>unix://__SOCK__</address> + <unixSocketPermissions>770</unixSocketPermissions> + <theme>default</theme> + <insecureSkipHostcheck>true</insecureSkipHostcheck> + </gui> + <ldap></ldap> + <options> + <listenAddress>quic://0.0.0.0:__PORT__</listenAddress> + <listenAddress>tcp://0.0.0.0:__PORT__</listenAddress> + <globalAnnounceServer>default</globalAnnounceServer> + <globalAnnounceEnabled>false</globalAnnounceEnabled> + <localAnnounceEnabled>false</localAnnounceEnabled> + <localAnnouncePort>0</localAnnouncePort> + <localAnnounceMCAddr>[ff12::8384]:0</localAnnounceMCAddr> + <maxSendKbps>0</maxSendKbps> + <maxRecvKbps>0</maxRecvKbps> + <reconnectionIntervalS>60</reconnectionIntervalS> + <relaysEnabled>false</relaysEnabled> + <relayReconnectIntervalM>10</relayReconnectIntervalM> + <startBrowser>false</startBrowser> + <natEnabled>false</natEnabled> + <natLeaseMinutes>60</natLeaseMinutes> + <natRenewalMinutes>30</natRenewalMinutes> + <natTimeoutSeconds>10</natTimeoutSeconds> + <urAccepted>-1</urAccepted> + <urSeen>0</urSeen> + <urUniqueID></urUniqueID> + <urURL>https://data.syncthing.net/newdata</urURL> + <urPostInsecurely>false</urPostInsecurely> + <urInitialDelayS>1800</urInitialDelayS> + <autoUpgradeIntervalH>0</autoUpgradeIntervalH> + <upgradeToPreReleases>false</upgradeToPreReleases> + <keepTemporariesH>24</keepTemporariesH> + <cacheIgnoredFiles>false</cacheIgnoredFiles> + <progressUpdateIntervalS>5</progressUpdateIntervalS> + <limitBandwidthInLan>false</limitBandwidthInLan> + <minHomeDiskFree unit="%">1</minHomeDiskFree> + <releasesURL>https://upgrades.syncthing.net/meta.json</releasesURL> + <overwriteRemoteDeviceNamesOnConnect>false</overwriteRemoteDeviceNamesOnConnect> + <tempIndexMinBlocks>10</tempIndexMinBlocks> + <trafficClass>0</trafficClass> + <setLowPriority>false</setLowPriority> + <maxFolderConcurrency>0</maxFolderConcurrency> + <crashReportingURL>https://crash.syncthing.net/newcrash</crashReportingURL> + <crashReportingEnabled>false</crashReportingEnabled> + <stunKeepaliveStartS>0</stunKeepaliveStartS> + <stunKeepaliveMinS>0</stunKeepaliveMinS> + <stunServer>default</stunServer> + <databaseTuning>auto</databaseTuning> + <maxConcurrentIncomingRequestKiB>0</maxConcurrentIncomingRequestKiB> + <announceLANAddresses>true</announceLANAddresses> + <sendFullIndexOnUpgrade>false</sendFullIndexOnUpgrade> + <connectionLimitEnough>0</connectionLimitEnough> + <connectionLimitMax>0</connectionLimitMax> + <insecureAllowOldTLSVersions>false</insecureAllowOldTLSVersions> + <connectionPriorityTcpLan>10</connectionPriorityTcpLan> + <connectionPriorityQuicLan>20</connectionPriorityQuicLan> + <connectionPriorityTcpWan>30</connectionPriorityTcpWan> + <connectionPriorityQuicWan>40</connectionPriorityQuicWan> + <connectionPriorityRelay>50</connectionPriorityRelay> + <connectionPriorityUpgradeThreshold>0</connectionPriorityUpgradeThreshold> + </options> + <defaults> + <folder id="" label="" path="~" type="sendreceive" rescanIntervalS="3600" fsWatcherEnabled="true" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true"> + <filesystemType>basic</filesystemType> + <device id="__DEVICEID__" introducedBy=""> + <encryptionPassword></encryptionPassword> + </device> + <minDiskFree unit="%">1</minDiskFree> + <versioning> + <cleanupIntervalS>3600</cleanupIntervalS> + <fsPath></fsPath> + <fsType>basic</fsType> + </versioning> + <copiers>0</copiers> + <pullerMaxPendingKiB>0</pullerMaxPendingKiB> + <hashers>0</hashers> + <order>random</order> + <ignoreDelete>false</ignoreDelete> + <scanProgressIntervalS>0</scanProgressIntervalS> + <pullerPauseS>0</pullerPauseS> + <maxConflicts>10</maxConflicts> + <disableSparseFiles>false</disableSparseFiles> + <disableTempIndexes>false</disableTempIndexes> + <paused>false</paused> + <weakHashThresholdPct>25</weakHashThresholdPct> + <markerName>.stfolder</markerName> + <copyOwnershipFromParent>false</copyOwnershipFromParent> + <modTimeWindowS>0</modTimeWindowS> + <maxConcurrentWrites>2</maxConcurrentWrites> + <disableFsync>false</disableFsync> + <blockPullOrder>standard</blockPullOrder> + <copyRangeMethod>standard</copyRangeMethod> + <caseSensitiveFS>false</caseSensitiveFS> + <junctionsAsDirs>false</junctionsAsDirs> + <syncOwnership>false</syncOwnership> + <sendOwnership>false</sendOwnership> + <syncXattrs>false</syncXattrs> + <sendXattrs>false</sendXattrs> + <xattrFilter> + <maxSingleEntrySize>1024</maxSingleEntrySize> + <maxTotalSize>4096</maxTotalSize> + </xattrFilter> + </folder> + <device id="" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy=""> + <address>dynamic</address> + <paused>false</paused> + <autoAcceptFolders>false</autoAcceptFolders> + <maxSendKbps>0</maxSendKbps> + <maxRecvKbps>0</maxRecvKbps> + <maxRequestKiB>0</maxRequestKiB> + <untrusted>false</untrusted> + <remoteGUIPort>0</remoteGUIPort> + <numConnections>0</numConnections> + </device> + <ignores></ignores> + </defaults> +</configuration> diff --git a/files/usr/share/skel/dot.login.freebsd b/files/usr/share/skel/dot.login.freebsd new file mode 100644 index 0000000..6afb9f2 --- /dev/null +++ b/files/usr/share/skel/dot.login.freebsd @@ -0,0 +1,4 @@ +# .login - csh login script, read by login shell, after `.cshrc' at login. + +# Query terminal size; useful for serial lines. +if ( -x /usr/bin/resizewin ) /usr/bin/resizewin -z diff --git a/files/usr/share/skel/dot.profile.freebsd b/files/usr/share/skel/dot.profile.freebsd new file mode 100644 index 0000000..0197635 --- /dev/null +++ b/files/usr/share/skel/dot.profile.freebsd @@ -0,0 +1,6 @@ +export CLICOLOR=1 +export PAGER=less +export LESS='-iMRS -x2' +export EDITOR=vi +export LSCOLORS=DxfxgxgxcxxbxbaCacADAd +export ENV="${HOME}/.shrc" diff --git a/files/usr/share/skel/dot.shrc.freebsd b/files/usr/share/skel/dot.shrc.freebsd new file mode 100644 index 0000000..bc8e8da --- /dev/null +++ b/files/usr/share/skel/dot.shrc.freebsd @@ -0,0 +1,19 @@ +reset=$'\e[0m' +blue=$'\e[0;34m' +green=$'\e[0;32m' +PS1="\[${green}\]\u@\h\[${reset}\]:\[${blue}\]\W\[${green}\]\$\[${reset}\] " +unset reset blue green + +alias ls='ls -FHh' +alias ll='ls -l' +alias la='ls -la' +alias ..='cd ..' +alias ...='cd ../..' +alias mkdir='mkdir -p' +alias df='df -h' +alias du='du -ch' + +bind ^[[A ed-search-prev-history +bind ^[[B ed-search-next-history +bind "\\e[1;5C" em-next-word +bind "\\e[1;5D" ed-prev-word diff --git a/lib/10-core b/lib/10-core index bd4e80a..60d1101 100644 --- a/lib/10-core +++ b/lib/10-core @@ -351,7 +351,7 @@ _boxconf_run(){ "${BOXCONF_SITE_SCRIPT_DIR}/hostname/${BOXCONF_HOSTNAME}" # Reboot the target host if requested. - if [ "${BOXCONF_NEED_REBOOT:-}" = true ]; then + if [ "${BOXCONF_NEED_REBOOT:-}" = true ] && [ "${boxconf_reboot:-}" != false ]; then log '$BOXCONF_NEED_REBOOT was set. Rebooting host...' reboot fi diff --git a/scripts/hostclass/asterisk_server b/scripts/hostclass/asterisk_server index d519730..fe10f51 100644 --- a/scripts/hostclass/asterisk_server +++ b/scripts/hostclass/asterisk_server @@ -44,6 +44,10 @@ pkg install -y \ # Create ZFS dataset for Asterisk DB. create_dataset -o "mountpoint=${asterisk_db_dir}" "${state_dataset}/asterisk" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/asterisk" install_directory -o "$asterisk_user" -g "$asterisk_user" -m 0755 "$asterisk_db_dir" # Generate asterisk configuration. diff --git a/scripts/hostclass/cups_server b/scripts/hostclass/cups_server index d9b6e66..0fd624c 100644 --- a/scripts/hostclass/cups_server +++ b/scripts/hostclass/cups_server @@ -11,6 +11,7 @@ cups_tls_key="${cups_tls_dir}/${fqdn}.key" # Create dataset for persistent CUPS configuration. create_dataset -o "mountpoint=${cups_conf_dir}" "${state_dataset}/cups" +zfs set com.sun:auto-snapshot:daily=true "${state_dataset}/cups" # Install required packages. pkg install -y cups cups-filters diff --git a/scripts/hostclass/desktop b/scripts/hostclass/desktop index ed71393..ac8bdda 100644 --- a/scripts/hostclass/desktop +++ b/scripts/hostclass/desktop @@ -1,6 +1,5 @@ #!/bin/sh -: ${desktop_access_role:='desktop-access'} : ${desktop_access_gid:='40000'} : ${sddm_min_uid:='10000'} : ${sddm_max_uid:='19999'} @@ -38,6 +37,11 @@ install_file -m 0555 \ # Create ZFS dataset for local homedirs. create_dataset -o mountpoint=/usr/local/home "${state_dataset}/home" +zfs set \ + com.sun:auto-snapshot:hourly=true \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/home" # Enable sndio. sysrc -v sndiod_enable=YES diff --git a/scripts/hostclass/idm_server/10-slapd b/scripts/hostclass/idm_server/10-slapd index d01db70..12640a4 100644 --- a/scripts/hostclass/idm_server/10-slapd +++ b/scripts/hostclass/idm_server/10-slapd @@ -36,6 +36,11 @@ pkg install -y \ # Create ZFS dataset for OpenLDAP DB. create_dataset -o "mountpoint=${slapd_data_dir}" "${state_dataset}/openldap-data" +zfs set \ + com.sun:auto-snapshot:hourly=true \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/openldap-data" # To prevent a circular dependency in poudriere, we have to make a special "set" # of packages for the IDM hosts in which cyrus-sasl-gssapi is built with the diff --git a/scripts/hostclass/imap_server/10-solr b/scripts/hostclass/imap_server/10-solr index 252a8c3..a30d6fd 100644 --- a/scripts/hostclass/imap_server/10-solr +++ b/scripts/hostclass/imap_server/10-solr @@ -28,6 +28,10 @@ add_user \ # Create ZFS dataset for solr DB. create_dataset -o "mountpoint=${solr_data_dir}" "${state_dataset}/solr" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/solr" # Set ownership on solr DB dir. install_directory -m 0770 -o "$solr_user" -g "$solr_user" "$solr_data_dir" diff --git a/scripts/hostclass/imap_server/30-dovecot b/scripts/hostclass/imap_server/30-dovecot index ff41da5..66edd1d 100644 --- a/scripts/hostclass/imap_server/30-dovecot +++ b/scripts/hostclass/imap_server/30-dovecot @@ -35,6 +35,11 @@ add_user \ # Create ZFS dataset for virtual maildirs. create_dataset -o "mountpoint=${dovecot_vmail_dir}" "${state_dataset}/mailboxes" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + com.sun:auto-snapshot:monthly=true \ + "${state_dataset}/mailboxes" # Set ownership on vmail dir. install_directory -m 0770 -o "$dovecot_vmail_user" -g "$dovecot_vmail_user" "$dovecot_vmail_dir" diff --git a/scripts/hostclass/nfs_server b/scripts/hostclass/nfs_server/10-nfs index a775859..a775859 100644 --- a/scripts/hostclass/nfs_server +++ b/scripts/hostclass/nfs_server/10-nfs diff --git a/scripts/hostclass/nfs_server/20-syncthing b/scripts/hostclass/nfs_server/20-syncthing new file mode 100644 index 0000000..095b55c --- /dev/null +++ b/scripts/hostclass/nfs_server/20-syncthing @@ -0,0 +1,61 @@ +#!/bin/sh + +# syncthing_users='user1 user2' +# syncthing_user1_port=22000 +# syncthing_user2_port=22001 + +if [ -z "${syncthing_users:-}" ]; then + return 0 +fi + +syncthing_https_cert="${nginx_conf_dir}/syncthing.crt" +syncthing_https_key="${nginx_conf_dir}/syncthing.key" +syncthing_conf_dir=/var/db/syncthing +nginx_keytab="${keytab_dir}/nginx.keytab" + +pkg install -y \ + syncthing \ + nginx + +# Create ZFS dataset for syncthing configuration. +create_dataset -o "mountpoint=$syncthing_conf_dir" "${state_dataset}/syncthing" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/syncthing" +install_directory -m 0755 "$syncthing_conf_dir" + +# Copy syncthing_user rc script. +install_file -m 0644 /usr/local/etc/syncthing.template.xml +install_file -m 0555 /usr/local/etc/rc.d/syncthing_user + +# Generate nginx configuration. +install_template -m 0644 \ + /usr/local/etc/nginx/nginx.conf \ + /usr/local/etc/nginx/vhosts.conf + +# Create HTTP service principal and keytab. +add_principal -nokey -x "containerdn=${services_basedn}" "HTTP/${fqdn}" + +ktadd -k "$nginx_keytab" "HTTP/${fqdn}" +chgrp "$nginx_user" "$nginx_keytab" +chmod 640 "$nginx_keytab" + +# Copy TLS certificate for nginx. +install_certificate nginx "$syncthing_https_cert" +install_certificate_key nginx "$syncthing_https_key" + +# Enable and start daemons. +sysrc -v nginx_enable=YES +service nginx restart + +sysrc -v \ + syncthing_user_enable=YES \ + "syncthing_user_instances+=${syncthing_users}" + +for user in $syncthing_users; do + eval "port=\$syncthing_${user}_port" + sysrc -v "syncthing_user_${user}_port=${port}" +done + +service syncthing_user restart diff --git a/scripts/hostclass/pkg_repository b/scripts/hostclass/pkg_repository index 969dff7..7044f96 100644 --- a/scripts/hostclass/pkg_repository +++ b/scripts/hostclass/pkg_repository @@ -18,6 +18,9 @@ poudriere_patch_dir="${poudriere_conf_dir}/patches" # Create poudriere datasets. create_dataset -o "mountpoint=${poudriere_data_dir}" "${state_dataset}/poudriere" create_dataset -o "mountpoint=${poudriere_conf_dir}" "${state_dataset}/poudriere-config" +zfs set com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/poudriere" \ + "${state_dataset}/poudriere-config" # Since we're doing a ton of compilation, disable sync on the poudriere dataset. # Possibly snakeoil, but my hope is that most file I/O will end up in the ARC cache diff --git a/scripts/hostclass/postgresql_server b/scripts/hostclass/postgresql_server index 10bafc8..dbb84b4 100644 --- a/scripts/hostclass/postgresql_server +++ b/scripts/hostclass/postgresql_server @@ -28,6 +28,11 @@ create_dataset \ -o primarycache=metadata \ -o atime=off \ "${state_dataset}/postgres" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + com.sun:auto-snapshot:monthly=true \ + "${state_dataset}/postgres" install_directory -m 0755 -o "$postgres_user" -g "$postgres_user" "$postgres_home" # Initialize the database. diff --git a/scripts/hostclass/public_webserver b/scripts/hostclass/public_webserver index ccf5991..721cbfc 100644 --- a/scripts/hostclass/public_webserver +++ b/scripts/hostclass/public_webserver @@ -14,6 +14,10 @@ pkg install -y \ # Create ZFS dataset for webroots. create_dataset -o "mountpoint=${vhosts_dir}" "${state_dataset}/vhosts" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/vhosts" # Configure nginx. install_template -m 0644 /usr/local/etc/nginx/nginx.conf diff --git a/scripts/hostclass/smtp_server/10-rspamd b/scripts/hostclass/smtp_server/10-rspamd index 7b1aae9..215788b 100644 --- a/scripts/hostclass/smtp_server/10-rspamd +++ b/scripts/hostclass/smtp_server/10-rspamd @@ -33,6 +33,10 @@ pkg install -y \ # Create ZFS dataset for Redis DBs. create_dataset -o "mountpoint=${redis_data_dir}" "${state_dataset}/redis" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/redis" # Generate config files for redis instances. install_template -m 0644 \ diff --git a/scripts/hostclass/unifi_controller b/scripts/hostclass/unifi_controller index 32df063..9fd161e 100644 --- a/scripts/hostclass/unifi_controller +++ b/scripts/hostclass/unifi_controller @@ -11,6 +11,10 @@ pkg install -y unifi8 # Create ZFS dataset for unifi data. create_dataset -o "mountpoint=${unifi_home}/data" "${state_dataset}/unifi" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/unifi" # Set ownership on unifi data dir. install_directory -o "$unifi_user" -g "$unifi_user" -m 0700 "${unifi_home}/data" diff --git a/scripts/hostclass/znc_server b/scripts/hostclass/znc_server index 58f1d8a..e2c2fa6 100644 --- a/scripts/hostclass/znc_server +++ b/scripts/hostclass/znc_server @@ -18,6 +18,10 @@ pkg install -y \ # Create ZFS dataset for ZNC configs. create_dataset -o "mountpoint=${znc_home}" "${state_dataset}/znc" +zfs set \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${state_dataset}/znc" # Set ownership on ZNC dir. install_directory -o "$znc_user" -g "$znc_user" -m 0755 "$znc_home" diff --git a/scripts/hostname/nfs1/10-homedirs b/scripts/hostname/nfs1/10-homedirs index f2cd25c..3a6d923 100644 --- a/scripts/hostname/nfs1/10-homedirs +++ b/scripts/hostname/nfs1/10-homedirs @@ -14,6 +14,9 @@ for userquota in ${nfs_homedirs:-}; do zfs set "refquota=${privquota:-$default_priv_quota}" "${nfs_dataset}/user/${user}/priv" zfs set "refquota=${pubquota:-$default_pub_quota}" "${nfs_dataset}/user/${user}/pub" + zfs set 'com.sun:auto-snapshot=true' \ + "${nfs_dataset}/user/${user}/priv" \ + "${nfs_dataset}/user/${user}/pub" chown "${user}:${user}" \ "${nfs_root}/user/${user}/priv" \ @@ -34,6 +37,9 @@ for groupquota in ${nfs_groupdirs:-}; do zfs set "refquota=${privquota:-$default_priv_quota}" "${nfs_dataset}/group/${group}/priv" zfs set "refquota=${pubquota:-$default_pub_quota}" "${nfs_dataset}/group/${group}/pub" + zfs set 'com.sun:auto-snapshot=true' \ + "${nfs_dataset}/group/${group}/priv" \ + "${nfs_dataset}/group/${group}/pub" chown "root:${group}" \ "${nfs_root}/group/${group}/priv" \ diff --git a/scripts/hostname/nfs1/20-shares b/scripts/hostname/nfs1/20-shares index ef013cc..beb3b11 100644 --- a/scripts/hostname/nfs1/20-shares +++ b/scripts/hostname/nfs1/20-shares @@ -2,6 +2,11 @@ # media/music create_dataset -p "${nfs_dataset}/media/music" +zfs set \ + compression=off \ + com.sun:auto-snapshot:daily=true \ + com.sun:auto-snapshot:weekly=true \ + "${nfs_dataset}/media/music" chgrp media-admin "${nfs_root}/media/music" chmod 2770 "${nfs_root}/media/music" set_facl "${nfs_root}/media/music" \ diff --git a/scripts/os/80-zfs b/scripts/os/80-zfs new file mode 100644 index 0000000..1a24852 --- /dev/null +++ b/scripts/os/80-zfs @@ -0,0 +1 @@ +#!/bin/sh diff --git a/scripts/os/freebsd/20-zfs b/scripts/os/freebsd/20-zfs index 1cdc465..5d86df4 100644 --- a/scripts/os/freebsd/20-zfs +++ b/scripts/os/freebsd/20-zfs @@ -7,5 +7,5 @@ create_dataset -o mountpoint=none "$state_dataset" # If this is baremetal host or a VM, trim the zpools periodically. if [ "$BOXCONF_VIRTUALIZATION_TYPE" != jail ]; then - install_file -m 0644 /etc/cron.d/zfs-trim + install_file -m 0644 /etc/cron.d/zfs fi diff --git a/scripts/os/freebsd/50-idm b/scripts/os/freebsd/50-idm index ab7c2fd..1585c6f 100644 --- a/scripts/os/freebsd/50-idm +++ b/scripts/os/freebsd/50-idm @@ -15,14 +15,20 @@ pkg install -y \ pam_krb5 \ perl5 \ p5-perl-ldap \ - p5-Authen-SASL + p5-Authen-SASL \ + pam_mkhomedir # Configure PAM/NSS integration. install_file -m 0644 \ /etc/nsswitch.conf \ + /etc/pam.d/system \ /etc/pam.d/login \ /etc/pam.d/sshd \ - /etc/pam.d/sudo + /etc/pam.d/sudo \ + /etc/pam.d/su \ + /etc/pam.d/other + +install_template -m 0644 /etc/login.access install_template -m 0644 \ /etc/krb5.conf \ @@ -30,6 +36,13 @@ install_template -m 0644 \ /usr/local/etc/openldap/ldap.conf \ /usr/local/etc/nslcd.conf +# Ensure /home exists and configure skel files. +install_directory -m 0755 /home +install_file -m 0644 \ + /usr/share/skel/dot.login \ + /usr/share/skel/dot.profile \ + /usr/share/skel/dot.shrc + # Create ldap.conf symlink. ln -snfv /usr/local/etc/openldap/ldap.conf /usr/local/etc/ldap.conf diff --git a/scripts/os/freebsd/90-snapshots b/scripts/os/freebsd/90-snapshots new file mode 100644 index 0000000..fce9c34 --- /dev/null +++ b/scripts/os/freebsd/90-snapshots @@ -0,0 +1,10 @@ +#!/bin/sh + +# Don't run autosnapshot within jails. Otherwise we will create duplicate +# snapshots with the host system. +if [ "$BOXCONF_VIRTUALIZATION_TYPE" = jail ]; then + return 0 +fi + +pkg install -y zfstools +install_file -m 0644 /etc/cron.d/zfs-autosnapshot diff --git a/vars/hostclass/desktop b/vars/hostclass/desktop index 6c2e45f..4d97d4e 100644 --- a/vars/hostclass/desktop +++ b/vars/hostclass/desktop @@ -1,5 +1,8 @@ #!/bin/sh +desktop_access_role='desktop-access' +login_access_groups="${login_access_groups:-} ${desktop_access_role}" + # Let users run gdb/truss. allow_proc_debug=1 diff --git a/vars/hostclass/freebsd_hypervisor b/vars/hostclass/freebsd_hypervisor index f3d6ac1..818afc8 100644 --- a/vars/hostclass/freebsd_hypervisor +++ b/vars/hostclass/freebsd_hypervisor @@ -4,3 +4,4 @@ enable_pf=false enable_idm=false smtp_host=${smtp_host_ip} resolvers=$bootstrap_resolvers +boxconf_reboot=false diff --git a/vars/hostclass/nfs_server b/vars/hostclass/nfs_server index 2957aec..cd9963e 100644 --- a/vars/hostclass/nfs_server +++ b/vars/hostclass/nfs_server @@ -1,3 +1,4 @@ #!/bin/sh -allowed_tcp_ports='ssh nfsd' +allowed_tcp_ports='ssh nfsd http https' +nginx_gssapi=true |