mirror of
				https://github.com/optim-enterprises-bv/secureblue.git
				synced 2025-10-31 18:37:47 +00:00 
			
		
		
		
	chore: copy config from upstream and remove dep (#593)
This commit is contained in:
		
							
								
								
									
										14
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,7 +8,7 @@ on: | ||||
|   workflow_dispatch: # allow manually triggering  | ||||
| jobs: | ||||
|   run_tests: | ||||
|     runs-on: ubuntu-latest | ||||
|     runs-on: ubuntu-24.04 | ||||
|     name: Install Bats and run tests | ||||
|     steps: | ||||
|       - name: Checkout repo | ||||
| @@ -17,10 +17,20 @@ jobs: | ||||
|       - name: Setup Bats and bats libs | ||||
|         id: setup-bats | ||||
|         uses: bats-core/bats-action@2104b40bb7b6c2d5110b23a26b0bf265ab8027db #v3.0.0 | ||||
|         with: | ||||
|            support-path: "${{ github.workspace }}/.bats/bats-support" | ||||
|            assert-path: "${{ github.workspace }}/.bats/bats-assert" | ||||
|            detik-path: "${{ github.workspace }}/.bats/bats-detik" | ||||
|            file-path: "${{ github.workspace }}/.bats/bats-file" | ||||
|        | ||||
|       - name: Install just | ||||
|         run: |           | ||||
|           sudo apt-get install just | ||||
|  | ||||
|       - name: Run tests | ||||
|         shell: bash | ||||
|         env: | ||||
|           INSTALL_SCRIPT: install/install_secureblue.sh | ||||
|           BATS_LIB_PATH: "${{ github.workspace }}/.bats" | ||||
|         run: | | ||||
|           bats -p -t --verbose-run .github/workflows/tests | ||||
|           bats --timing --trace --verbose-run -r .github/workflows/tests | ||||
							
								
								
									
										31
									
								
								.github/workflows/tests/justfile_tests.bats
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								.github/workflows/tests/justfile_tests.bats
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| #!/usr/bin/env bats | ||||
|  | ||||
| setup() { | ||||
|     sudo mkdir -p /usr/share/ublue-os/just/ | ||||
|     sudo mkdir -p /usr/share/bluebuild/justfiles/ | ||||
|     sudo mkdir -p /usr/lib/ujust/ | ||||
|  | ||||
|  | ||||
|     sudo cp -fr files/system/usr/lib/ujust /usr/lib/ujust | ||||
|     sudo cp -f files/system/usr/bin/ujust /usr/bin/ujust | ||||
|     sudo cp -f files/system/usr/share/ublue-os/just/60-custom.just /usr/share/ublue-os/just/ | ||||
|     sudo cp -f files/system/usr/share/ublue-os/justfile /usr/share/ublue-os/ | ||||
|     sudo cp -f files/justfiles/*.just /usr/share/bluebuild/justfiles/ | ||||
|     for filepath in /usr/share/bluebuild/justfiles/*.just; do | ||||
|         sudo sh -c "echo \"import '$filepath'\" >> /usr/share/ublue-os/just/60-custom.just" | ||||
|     done | ||||
| } | ||||
|  | ||||
| @test "Ensure ujust is configured correctly for tests" { | ||||
|     run ujust logs-this-boot | ||||
|     [ "$status" -eq 0 ] | ||||
| } | ||||
|  | ||||
| @test "Ensure motd toggle functions properly" { | ||||
|     run ujust toggle-user-motd | ||||
|     [ "$status" -eq 0 ] | ||||
|     [ -f "${HOME}/.config/no-show-user-motd" ] | ||||
|     run ujust toggle-user-motd | ||||
|     [ "$status" -eq 0 ] | ||||
|     [ ! -f "${HOME}/.config/no-show-user-motd" ] | ||||
| } | ||||
| @@ -10,11 +10,7 @@ After rebasing to secureblue, follow the following steps in order. | ||||
| If you are using an nvidia image, run this after installation: | ||||
|  | ||||
| ``` | ||||
| rpm-ostree kargs \ | ||||
|     --append-if-missing=rd.driver.blacklist=nouveau \ | ||||
|     --append-if-missing=modprobe.blacklist=nouveau \ | ||||
|     --append-if-missing=nvidia-drm.modeset=1 \ | ||||
|     --append-if-missing=nvidia-drm.fbdev=1 | ||||
| ujust set-kargs-nvidia | ||||
| ``` | ||||
|  | ||||
| You may also need this (solves flickering and luks issues on some nvidia hardware): | ||||
|   | ||||
							
								
								
									
										379
									
								
								files/justfiles/audit.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								files/justfiles/audit.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,379 @@ | ||||
| # Audit secureblue | ||||
| audit-secureblue: | ||||
|     #!/bin/bash | ||||
|  | ||||
|     STATUS_SUCCESS="SUCCESS" | ||||
|     STATUS_WARNING="WARNING" | ||||
|     STATUS_FAILURE="FAILURE" | ||||
|     print_status() { | ||||
|         local check_name="$1" | ||||
|         local status="$2" | ||||
|  | ||||
|         local color_code | ||||
|         case "$status" in | ||||
|             $STATUS_SUCCESS) color_code=32 ;; # Green | ||||
|             $STATUS_WARNING) color_code=33 ;; # Yellow | ||||
|             $STATUS_FAILURE) color_code=31 ;;    # Red | ||||
|             *) color_code=0 ;; | ||||
|         esac | ||||
|  | ||||
|         local formatted_status | ||||
|         formatted_status=$(printf "%*s" $(( (7 + ${#status}) / 2 )) "$status") | ||||
|         formatted_status=$(printf "%-7s" "$formatted_status") | ||||
|  | ||||
|         printf "%-64s [ \033[%dm%s\033[0m ]\n" "$check_name"... "$color_code" "$formatted_status" | ||||
|     } | ||||
|  | ||||
|     hasPermission() { | ||||
|         local permissions=$1 | ||||
|         local prefix=$2 | ||||
|         local query=$3 | ||||
|         local line=$(grep "^${prefix}=" <<< "$permissions" | sed -e "s/^${prefix}=//" -e "s/#.*//") | ||||
|         IFS=';' read -r -a list <<< "$line" | ||||
|         for p in ${list[@]}; do | ||||
|             if [[ "$p" =~ ^$query$ ]]; then | ||||
|                 return | ||||
|             fi | ||||
|         done | ||||
|         return 1 | ||||
|     } | ||||
|  | ||||
|     KARGS=$(rpm-ostree kargs) | ||||
|     KARGS_LIST=( | ||||
|         "init_on_alloc=1" | ||||
|         "init_on_free=1" | ||||
|         "slab_nomerge" | ||||
|         "page_alloc.shuffle=1" | ||||
|         "randomize_kstack_offset=on" | ||||
|         "vsyscall=none" | ||||
|         "lockdown=confidentiality" | ||||
|         "random.trust_cpu=off" | ||||
|         "random.trust_bootloader=off" | ||||
|         "iommu=force" | ||||
|         "intel_iommu=on" | ||||
|         "amd_iommu=force_isolation" | ||||
|         "iommu.passthrough=0" | ||||
|         "iommu.strict=1" | ||||
|         "pti=on" | ||||
|         "module.sig_enforce=1" | ||||
|         "mitigations=auto,nosmt" | ||||
|         "spectre_v2=on" | ||||
|         "spec_store_bypass_disable=on" | ||||
|         "l1d_flush=on" | ||||
|         "gather_data_sampling=force" | ||||
|         "efi=disable_early_pci_dma" | ||||
|         "debugfs=off" | ||||
|         "ia32_emulation=0" | ||||
|     ) | ||||
|  | ||||
|     for karg in "${KARGS_LIST[@]}"; do | ||||
|         KARG_TEST_STRING="Checking for $karg karg" | ||||
|         if echo "$KARGS" | grep -q "$karg"; then | ||||
|             print_status "$KARG_TEST_STRING" "$STATUS_SUCCESS" | ||||
|         else | ||||
|             print_status "$KARG_TEST_STRING" "$STATUS_FAILURE" | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     SYSCTL_TEST_STRING="Ensuring no sysctl overrides" | ||||
|     readarray -t sysctl_hardening_conf < <(grep -v -E -e "^#" -e "^$" </usr/etc/sysctl.d/hardening.conf) | ||||
|     declare -A sysctl_hardening | ||||
|     for line in "${sysctl_hardening_conf[@]}"; do | ||||
|         parameter="$(sed -E -e "s/(.*) = .*/\1/"  <<<"$line")" | ||||
|         value="$(sed -E "s/.* = (.*)/\1/" <<<"$line")" | ||||
|         sysctl_hardening["$parameter"]+="$value" | ||||
|     done | ||||
|     sysctl_results="$(sysctl -a 2> >(grep -v "sysctl: permission denied on key "))" | ||||
|     sysctl_errors=() | ||||
|     for sysctl_parameter in "${!hardening[@]}"; do | ||||
|         hardened_parameter_value="${hardening["$sysctl_parameter"]}" | ||||
|         parameter_name="$(sed -E -e "s/\./\\\./g" -e "s/\*/\.\*/" <<<"$sysctl_parameter")" | ||||
|         readarray -t sysctl_parameter_values < <(grep -E "^$key = " <<<"$sysctl_results") | ||||
|         for parameter_value in "${sysctl_parameter_values[@]}"; do | ||||
|             parameter_value="$(sed -E  -e "s/.* = (.*)/\1/" -e "s/\t/ /g" <<<"$result" | tr -s " " )" | ||||
|             if [[ "$parameter_value" != "$hardened_parameter_value" && ("$hardened_parameter_value" != 0 && "$parameter_value" != disabled) ]]; then | ||||
|                 sysctl_errors+=("$sysctl_parameter should be $hardened_parameter_value, found $parameter_value") | ||||
|             fi | ||||
|         done | ||||
|     done | ||||
|     if [[ "${#sysctl_errors}" == 0 ]] && diff /usr/etc/sysctl.d/hardening.conf /etc/sysctl.d/hardening.conf > /dev/null; then | ||||
|         print_status "$SYSCTL_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$SYSCTL_TEST_STRING" "$STATUS_FAILURE" | ||||
|         for error in "${sysctl_errors[@]}"; do | ||||
|             echo "> $error" | ||||
|         done | ||||
|     fi | ||||
|  | ||||
|     SIGNED_IMAGE_TEST_STRING="Ensuring a signed image is in use" | ||||
|     if rpm-ostree status | grep -q "● ostree-image-signed"; then | ||||
|         print_status "$SIGNED_IMAGE_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$SIGNED_IMAGE_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     MODPROBE_TEST_STRING="Ensuring no modprobe overrides" | ||||
|     readarray -t unwanted_modules < <(comm -12 <(lsmod | cut -f 1 -d " " | sort) <(cat /usr/etc/modprobe.d/blacklist.conf | grep -E '^(blacklist)|(install)' | cut -f 2 -d " " | sort)) | ||||
|     if [[ "${#unwanted_modules[@]}" == 0 ]] && diff /usr/etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf > /dev/null; then | ||||
|         print_status "$MODPROBE_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$MODPROBE_TEST_STRING" "$STATUS_FAILURE" | ||||
|         for module in "${unwanted_modules[@]}"; do | ||||
|             echo "> $module is in blacklist.conf but it is loaded" | ||||
|             if [[ "$module" == "bluetooth" ]]; then | ||||
|                 bluetooth_loaded=true | ||||
|             fi | ||||
|         done | ||||
|     fi | ||||
|  | ||||
|     PTRACE_TEST_STRING="Ensuring ptrace is forbidden" | ||||
|     if [[ "$(cat /proc/sys/kernel/yama/ptrace_scope)" == 3 ]]; then | ||||
|         print_status "$PTRACE_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$PTRACE_TEST_STRING" "$STATUS_FAILURE" | ||||
|         ptrace_allowed=true | ||||
|     fi | ||||
|  | ||||
|     AUTHSELECT_TEST_STRING="Ensuring no authselect overrides" | ||||
|     if diff /usr/etc/authselect /etc/authselect --suppress-common-lines -r > /dev/null; then | ||||
|         print_status "$AUTHSELECT_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$AUTHSELECT_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     CONTAINER_POLICY_TEST_STRING="Ensuring no container policy overrides" | ||||
|     if diff /usr/etc/containers/policy.json /etc/containers/policy.json > /dev/null && [ ! -f $HOME/.config/containers/policy.json ]; then | ||||
|         print_status "$CONTAINER_POLICY_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$CONTAINER_POLICY_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     USBGUARD_TEST_STRING="Ensuring usbguard is active" | ||||
|     if systemctl is-active --quiet usbguard; then | ||||
|         print_status "$USBGUARD_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$USBGUARD_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     CHRONYD_TEST_STRING="Ensuring chronyd is active" | ||||
|     if systemctl is-active --quiet chronyd; then | ||||
|         print_status "$CHRONYD_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$CHRONYD_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     SECUREDNS_TEST_STRING="Ensuring system DNS resolution is secure" | ||||
|     if systemctl is-active --quiet systemd-resolved; then | ||||
|         DNSSEC_STATUS="$(cat /etc/systemd/resolved.conf.d/10-securedns.conf | grep "DNSSEC")" | ||||
|         DOT_STATUS="$(cat /etc/systemd/resolved.conf.d/10-securedns.conf | grep "DNSOverTLS")" | ||||
|         if [[ "$DNSSEC_STATUS" == "DNSSEC=true" && "$DOT_STATUS" == "DNSOverTLS=true" ]]; then | ||||
|             print_status "$SECUREDNS_TEST_STRING" "$STATUS_SUCCESS" | ||||
|         else | ||||
|             print_status "$SECUREDNS_TEST_STRING" "$STATUS_FAILURE" | ||||
|         fi | ||||
|     else | ||||
|         print_status "$SECUREDNS_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     BASH_TEST_STRING="Ensuring bash environment lockdown" | ||||
|     BASH_ENV_FILES=(~/.bashrc ~/.bash_profile) | ||||
|     all_locked=1 | ||||
|  | ||||
|     for file in "${BASH_ENV_FILES[@]}"; do | ||||
|         if [ -f "$file" ]; then | ||||
|             if lsattr "$file" 2>/dev/null | awk '{print $1}' | grep -q 'i'; then | ||||
|                 continue | ||||
|             else | ||||
|                 all_locked=0 | ||||
|                 break | ||||
|             fi | ||||
|         else | ||||
|             all_locked=0 | ||||
|             break | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     if [ "$all_locked" -eq 1 ]; then | ||||
|         print_status "$BASH_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$BASH_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     WHEEL_TEST_STRING="Ensuring user is not a member of wheel" | ||||
|     if groups | grep -q "\bwheel\b"; then | ||||
|         print_status "$WHEEL_TEST_STRING" "$STATUS_FAILURE" | ||||
|     else | ||||
|         print_status "$WHEEL_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     fi | ||||
|  | ||||
|     GNOME_XWAYLAND_TEST_STRING="Ensuring xwayland is disabled for GNOME" | ||||
|     if [ -f "/etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf" ]; then | ||||
|         print_status "$GNOME_XWAYLAND_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$GNOME_XWAYLAND_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     PLASMA_XWAYLAND_TEST_STRING="Ensuring xwayland is disabled for KDE Plasma" | ||||
|     if [ -f "/etc/systemd/user/plasma-kwin_wayland.service.d/override.conf" ]; then | ||||
|         print_status "$PLASMA_XWAYLAND_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$PLASMA_XWAYLAND_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     SWAY_XWAYLAND_TEST_STRING="Ensuring xwayland is disabled for Sway" | ||||
|     if [ -f "/etc/sway/config.d/99-noxwayland.conf" ]; then | ||||
|         print_status "$SWAY_XWAYLAND_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$SWAY_XWAYLAND_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     EXTENSIONS_TEST_STRING="Ensuring GNOME user extensions are disabled" | ||||
|     if command -v gnome-shell &> /dev/null; then | ||||
|         if [ "$(gsettings get org.gnome.shell allow-extension-installation)" = "false" ]; then | ||||
|             print_status "$EXTENSIONS_TEST_STRING" "$STATUS_SUCCESS" | ||||
|         else | ||||
|             print_status "$EXTENSIONS_TEST_STRING" "$STATUS_FAILURE" | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     SELINUX_TEST_STRING="Ensuring SELinux is in Enforcing mode" | ||||
|     if [ "$(getenforce)" = "Enforcing" ]; then | ||||
|         print_status "$SELINUX_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$SELINUX_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     ENVIRONMENT_TEST_STRING="Ensuring no environment file overrides" | ||||
|     if diff /usr/etc/environment /etc/environment > /dev/null; then | ||||
|         print_status "$ENVIRONMENT_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$ENVIRONMENT_TEST_STRING" "$STATUS_WARNING" | ||||
|     fi | ||||
|  | ||||
|     GHNS_TEST_STRING="Ensuring KDE GHNS is disabled" | ||||
|     KDE_GLOBALS_FILE="/etc/xdg/kdeglobals" | ||||
|     if test -e $KDE_GLOBALS_FILE; then | ||||
|         GHNS_STRING="$(grep 'ghns=false' $KDE_GLOBALS_FILE)" | ||||
|         if [[ $GHNS_STRING == "ghns=false" ]]; then | ||||
|             print_status "$GHNS_TEST_STRING" "$STATUS_SUCCESS" | ||||
|         else | ||||
|             print_status "$GHNS_TEST_STRING" "$STATUS_FAILURE" | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     HARDENED_MALLOC_TEST_STRING="Ensuring hardened_malloc is set in ld.so.preload" | ||||
|     if diff /usr/etc/ld.so.preload /etc/ld.so.preload > /dev/null; then | ||||
|         print_status "$HARDENED_MALLOC_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$HARDENED_MALLOC_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     SECUREBOOT_TEST_STRING="Ensuring secure boot is enabled" | ||||
|     if [ "$(mokutil --sb-state)" == "SecureBoot enabled" ]; then | ||||
|         print_status "$SECUREBOOT_TEST_STRING" "$STATUS_SUCCESS" | ||||
|     else | ||||
|         print_status "$SECUREBOOT_TEST_STRING" "$STATUS_FAILURE" | ||||
|     fi | ||||
|  | ||||
|     if command -v flatpak &> /dev/null; then | ||||
|         remotes="$(flatpak remotes -d)" | ||||
|         while read -r remote ; do | ||||
|             ref="$(cut -f 1 <<<"$remote")" | ||||
|             url="$(cut -f 3 <<< "$remote")" | ||||
|             subset="$(cut -f 5 <<< "$remote")" | ||||
|             remote_string="Auditing flatpak remote $ref" | ||||
|             if [[ "$url" != "https://dl.flathub.org/repo/" && "$url" != "https://dl.flathub.org/beta-repo/" ]]; then | ||||
|                 print_status "$remote_string" "$STATUS_FAILURE" | ||||
|                 echo "> $ref is configured with an unknown url!" | ||||
|             elif [ "$subset" != "verified" ]; then | ||||
|                 print_status "$remote_string" "$STATUS_FAILURE" | ||||
|                 echo "> $ref is not a verified repo!" | ||||
|             else | ||||
|                 print_status "$remote_string" "$STATUS_SUCCESS" | ||||
|             fi | ||||
|         done <<< "$remotes" | ||||
|  | ||||
|         declare -A flatpaks | ||||
|         while read -r ref version; do | ||||
|             flatpaks+=(["${ref}"]="${ref}//${version}") | ||||
|         done < <(flatpak list | sort -k 1 | cut --fields 2,4) | ||||
|  | ||||
|         for f in ${!flatpaks[@]}; do | ||||
|             warnings=() | ||||
|             status="$STATUS_SUCCESS" | ||||
|             fullref=${flatpaks["$f"]} | ||||
|             permissions=$(flatpak info --show-permissions "$fullref") | ||||
|  | ||||
|             if hasPermission "$permissions" "shared" "network"; then | ||||
|                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||
|                 warnings+=("> $f has network access!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --unshare=network $f'") | ||||
|             fi | ||||
|             if hasPermission "$permissions" "sockets" "x11" && ! hasPermission "$permissions" "sockets" "fallback-x11"; then | ||||
|                 status="$STATUS_FAILURE" | ||||
|                 warnings+=("> $f has x11 access!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --nosocket=x11 $f'") | ||||
|             fi | ||||
|             if hasPermission "$permissions" "sockets" "session-bus"; then | ||||
|                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||
|                 warnings+=("> $f has access to the D-Bus session bus!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --nosocket=session-bus $f'") | ||||
|             fi | ||||
|             if hasPermission "$permissions" "sockets" "system-bus"; then | ||||
|                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||
|                 warnings+=("> $f has access to the D-Bus system bus!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --nosocket=system-bus $f'") | ||||
|             fi | ||||
|             if ! hasPermission "$permissions" "LD_PRELOAD" .*"/libhardened_malloc.so"; then | ||||
|                 status="$STATUS_FAILURE" | ||||
|                 warnings+=("> $f is not requesting hardened_malloc!") | ||||
|                 warnings+=("> To enable it run:") | ||||
|                 warnings+=("> 'ujust harden-flatpak $f'") | ||||
|             fi | ||||
|             if ! hasPermission "$permissions" "filesystems" "host-os:ro"; then | ||||
|                 status="$STATUS_FAILURE" | ||||
|                 warnings+=("> $f is missing host-os:ro permission,") | ||||
|                 warnings+=("> which is needed to load hardened_malloc!") | ||||
|                 warnings+=("> To add it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --filesystem=host-os:ro $f'") | ||||
|             fi | ||||
|             if [[ "$bluetooth_loaded" == "true" ]] && hasPermission "$permissions" "features" "bluetooth"; then | ||||
|                 status="$STATUS_FAILURE" | ||||
|                 warnings+=("> $f has bluetooth access!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --disallow=bluetooth $f'") | ||||
|             fi | ||||
|             if [[ "$ptrace_allowed" == "true" ]] && hasPermission "$permissions" "features" "devel"; then | ||||
|                 status="$STATUS_FAILURE" | ||||
|                 warnings+=("> $f has ptrace access!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --disallow=devel $f'") | ||||
|             fi | ||||
|             if hasPermission "$permissions" "shared" "ipc"; then | ||||
|                 status="$STATUS_FAILURE" | ||||
|                 warnings+=("> $f has inter-process communications access!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --unshare=ipc $f'") | ||||
|             fi | ||||
|             if hasPermission "$permissions" "devices" "all"; then | ||||
|                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||
|                 warnings+=("> $f has device=all permission,") | ||||
|                 warnings+=("> granting access to GPU, input devices, raw USB, and virtualization,") | ||||
|                 warnings+=("> and introducing a vector for sandbox escapes!") | ||||
|                 warnings+=("> To remove it use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --nodevice=all $f'") | ||||
|                 warnings+=("> We recommend you enable device=dri to grant GPU access, if needed by the app") | ||||
|                 warnings+=("> To add GPU access use Flatseal or run:") | ||||
|                 warnings+=("> 'flatpak override -u --device=dri $f'") | ||||
|             fi | ||||
|             flatpak_test_string="Auditing $f" | ||||
|             print_status "$flatpak_test_string" "$status" | ||||
|             for warning in "${warnings[@]}"; do | ||||
|                 echo "$warning" | ||||
|             done | ||||
|         done | ||||
|     fi | ||||
| @@ -1,5 +1,17 @@ | ||||
| alias brew := install-brew | ||||
|  | ||||
| # Copyright 2024 Universal Blue | ||||
| # | ||||
| # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||
| # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and limitations under the License. | ||||
|  | ||||
| # Install Homebrew (Brew is now included by default. This command remains included for utility.) | ||||
| install-brew: | ||||
|     #!/usr/bin/env bash | ||||
|   | ||||
							
								
								
									
										320
									
								
								files/justfiles/dns.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								files/justfiles/dns.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,320 @@ | ||||
| # setup system DNS resolution | ||||
| dns-selector: | ||||
|     #! /bin/run0 /bin/bash | ||||
|     # constants | ||||
|     readonly resolved_conf="/etc/systemd/resolved.conf.d/10-securedns.conf" | ||||
|     readonly policy_file="/etc/chromium/policies/managed/10-securedns-browser.json" | ||||
|     mkdir -p /etc/systemd/resolved.conf.d/ | ||||
|     mkdir -p /etc/chromium/policies/managed/ | ||||
|     # variables | ||||
|     valid_input="0" | ||||
|     resolver_selection="" | ||||
|     resolver_subselection="" | ||||
|     resolver_has_second_ip="" | ||||
|     resolver_supports_ipv6="" | ||||
|     resolver_ipv4_address="" | ||||
|     resolver_ipv4_address_2="" | ||||
|     resolver_ipv6_address="" | ||||
|     resolver_ipv6_address_2="" | ||||
|     resolver_hostname="" | ||||
|     resolver_https_address="" | ||||
|     set_browser_policy="" | ||||
|  | ||||
|     echo "Below will be some options to set the DNS resolver for systemd-resolved." | ||||
|     echo "All resolvers support DNS-over-TLS (DoT) or DNS-over-QUIC (DoQ), DNS-over-HTTPS (DoH), and DNSSEC." | ||||
|     echo "Please select which DNS resolver you would like to set:" | ||||
|     echo "    0) Network Resolver - security may vary (system default state)" | ||||
|     echo "    1) Control D - has content filtering, anycast" | ||||
|     echo "    2) Mullvad - has content filtering, anycast" | ||||
|     echo "    3) Cloudflare - very fast with some data collection, anycast" | ||||
|     echo "    4) DNSForge - powerful filtering but can be very slow" | ||||
|     echo "    5) Custom Resolver - use a custom resolver (must support DoT/DoQ and DNSSEC, DoH support is also required to set a browser policy should that be desired)" | ||||
|     while [[ "$valid_input" == "0" ]]; do | ||||
|         read -p "Selection [0-5]: " resolver_selection | ||||
|         if [[ "$resolver_selection" == [012345]* ]]; then | ||||
|             valid_input="1" | ||||
|         else | ||||
|             echo "That is not a valid selection." | ||||
|         fi | ||||
|     done | ||||
|     valid_input="0" | ||||
|  | ||||
|     echo "" # blank space | ||||
|     case "$resolver_selection" in | ||||
|         0) | ||||
|             echo "Resetting resolved to default state." | ||||
|             if [[ -f "$policy_file" ]]; then | ||||
|                 rm $policy_file | ||||
|                 echo "Removed browser policy." | ||||
|             fi | ||||
|             cp /usr$resolved_conf $resolved_conf | ||||
|             systemctl restart systemd-resolved | ||||
|             echo "Configuration file for resolved reset and service restarted." | ||||
|             exit 0 | ||||
|             ;; | ||||
|         1) | ||||
|             resolver_has_second_ip="y" | ||||
|             resolver_supports_ipv6="y" | ||||
|             echo "Setting resolver Control D." | ||||
|             echo "What content would you like to filter:" | ||||
|             echo "    0) No filtering" | ||||
|             echo "    1) Malware: Malware filtering" | ||||
|             echo "    2) Standard: Malware + ad and tracker filtering" | ||||
|             echo "    3) Social: Standard + social media filtering" | ||||
|             echo "    4) Family: Social + adult content filtering (also enables safe search in major search engines)" | ||||
|             while [[ "$valid_input" == "0" ]]; do | ||||
|                 read -p "Selection [0-4]: " resolver_subselection | ||||
|                 if [[ "$resolver_subselection" == [01234]* ]]; then | ||||
|                     valid_input="1" | ||||
|                 else | ||||
|                     echo "That is not a valid selection." | ||||
|                 fi | ||||
|             done | ||||
|             valid_input="0" | ||||
|             case "$resolver_subselection" in | ||||
|                 0) | ||||
|                     resolver_ipv4_address="76.76.2.0" | ||||
|                     resolver_ipv4_address_2="76.76.10.0" | ||||
|                     resolver_ipv6_address="2606:1a40::" | ||||
|                     resolver_ipv6_address_2="2606:1a40:1::" | ||||
|                     resolver_hostname="p0.freedns.controld.com" | ||||
|                     resolver_https_address="https://freedns.controld.com/p0" | ||||
|                     ;; | ||||
|                 1) | ||||
|                     resolver_ipv4_address="76.76.2.1" | ||||
|                     resolver_ipv4_address_2="76.76.10.1" | ||||
|                     resolver_ipv6_address="2606:1a40::1" | ||||
|                     resolver_ipv6_address_2="2606:1a40:1::1" | ||||
|                     resolver_hostname="p1.freedns.controld.com" | ||||
|                     resolver_https_address="https://freedns.controld.com/p1" | ||||
|                     ;; | ||||
|                 2) | ||||
|                     resolver_ipv4_address="76.76.2.2" | ||||
|                     resolver_ipv4_address_2="76.76.10.2" | ||||
|                     resolver_ipv6_address="2606:1a40::2" | ||||
|                     resolver_ipv6_address_2="2606:1a40:1::2" | ||||
|                     resolver_hostname="p2.freedns.controld.com" | ||||
|                     resolver_https_address="https://freedns.controld.com/p2" | ||||
|                     ;; | ||||
|                 3) | ||||
|                     resolver_ipv4_address="76.76.2.3" | ||||
|                     resolver_ipv4_address_2="76.76.10.3" | ||||
|                     resolver_ipv6_address="2606:1a40::3" | ||||
|                     resolver_ipv6_address_2="2606:1a40:1::3" | ||||
|                     resolver_hostname="p3.freedns.controld.com" | ||||
|                     resolver_https_address="https://freedns.controld.com/p3" | ||||
|                     ;; | ||||
|                 4) | ||||
|                     resolver_ipv4_address="76.76.2.4" | ||||
|                     resolver_ipv4_address_2="76.76.10.4" | ||||
|                     resolver_ipv6_address="2606:1a40::4" | ||||
|                     resolver_ipv6_address_2="2606:1a40:1::4" | ||||
|                     resolver_hostname="family.freedns.controld.com" | ||||
|                     resolver_https_address="https://freedns.controld.com/family" | ||||
|                     ;; | ||||
|             esac | ||||
|             ;; | ||||
|         2) | ||||
|             resolver_has_second_ip="n" | ||||
|             resolver_supports_ipv6="y" | ||||
|             echo "Setting resolver Mullvad." | ||||
|             echo "What content would you like to filter:" | ||||
|             echo "    0) No filtering" | ||||
|             echo "    1) Standard: Ad and tracker filtering" | ||||
|             echo "    2) Base: Standard + malware filtering" | ||||
|             echo "    3) Extended: Base + social media filtering" | ||||
|             echo "    4) Family: Base + gambling and adult content filtering" | ||||
|             echo "    5) All: Family + social media filtering" | ||||
|             while [[ "$valid_input" == "0" ]]; do | ||||
|                 read -p "Selection [0-5]: " resolver_subselection | ||||
|                 if [[ "$resolver_subselection" == [012345]* ]]; then | ||||
|                     valid_input="1" | ||||
|                 else | ||||
|                     echo "That is not a valid selection." | ||||
|                 fi | ||||
|             done | ||||
|             valid_input="0" | ||||
|             case "$resolver_subselection" in | ||||
|                 0) | ||||
|                     resolver_ipv4_address="194.242.2.2" | ||||
|                     resolver_ipv6_address="2a07:e340::2" | ||||
|                     resolver_hostname="dns.mullvad.net" | ||||
|                     ;; | ||||
|                 1) | ||||
|                     resolver_ipv4_address="194.242.2.3" | ||||
|                     resolver_ipv6_address="2a07:e340::3" | ||||
|                     resolver_hostname="adblock.dns.mullvad.net" | ||||
|                     ;; | ||||
|                 2) | ||||
|                     resolver_ipv4_address="194.242.2.4" | ||||
|                     resolver_ipv6_address="2a07:e340::4" | ||||
|                     resolver_hostname="base.dns.mullvad.net" | ||||
|                     ;; | ||||
|                 3) | ||||
|                     resolver_ipv4_address="194.242.2.5" | ||||
|                     resolver_ipv6_address="2a07:e340::5" | ||||
|                     resolver_hostname="extended.dns.mullvad.net" | ||||
|                     ;; | ||||
|                 4) | ||||
|                     resolver_ipv4_address="194.242.2.6" | ||||
|                     resolver_ipv6_address="2a07:e340::6" | ||||
|                     resolver_hostname="family.dns.mullvad.net" | ||||
|                     ;; | ||||
|                 5) | ||||
|                     resolver_ipv4_address="194.242.2.9" | ||||
|                     resolver_ipv6_address="2a07:e340::9" | ||||
|                     resolver_hostname="all.dns.mullvad.net" | ||||
|                     ;; | ||||
|             esac | ||||
|             resolver_https_address="https://$resolver_hostname/dns-query" | ||||
|             ;; | ||||
|         3) | ||||
|             resolver_has_second_ip="y" | ||||
|             resolver_supports_ipv6="y" | ||||
|             echo "Setting resolver Cloudflare. (glory to the cloud)" | ||||
|             echo "What content would you like to filter:" | ||||
|             echo "    0) No filtering" | ||||
|             echo "    1) Security: Malware filtering" | ||||
|             echo "    2) Family: Security + adult content filtering" | ||||
|             while [[ "$valid_input" == "0" ]]; do | ||||
|                 read -p "Selection [0-2]: " resolver_subselection | ||||
|                 if [[ "$resolver_subselection" == [012]* ]]; then | ||||
|                     valid_input="1" | ||||
|                 else | ||||
|                     echo "That is not a valid selection." | ||||
|                 fi | ||||
|             done | ||||
|             valid_input="0" | ||||
|             case "$resolver_subselection" in | ||||
|                 0) | ||||
|                     resolver_ipv4_address="1.1.1.1" | ||||
|                     resolver_ipv4_address_2="1.0.0.1" | ||||
|                     resolver_ipv6_address="2606:4700:4700::1111" | ||||
|                     resolver_ipv6_address_2="2606:4700:4700::1001" | ||||
|                     resolver_hostname="cloudflare-dns.com" | ||||
|                     ;; | ||||
|                 1) | ||||
|                     resolver_ipv4_address="1.1.1.2" | ||||
|                     resolver_ipv4_address_2="1.0.0.2" | ||||
|                     resolver_ipv6_address="2606:4700:4700::1112" | ||||
|                     resolver_ipv6_address_2="2606:4700:4700::1002" | ||||
|                     resolver_hostname="security.cloudflare-dns.com" | ||||
|                     ;; | ||||
|                 2) | ||||
|                     resolver_ipv4_address="1.1.1.3" | ||||
|                     resolver_ipv4_address_2="1.0.0.3" | ||||
|                     resolver_ipv6_address="2606:4700:4700::1113" | ||||
|                     resolver_ipv6_address_2="2606:4700:4700::1003" | ||||
|                     resolver_hostname="family.cloudflare-dns.com" | ||||
|                     ;; | ||||
|             esac | ||||
|             resolver_https_address="https://$resolver_hostname/dns-query" | ||||
|             ;; | ||||
|         4) | ||||
|             resolver_has_second_ip="y" | ||||
|             resolver_supports_ipv6="y" | ||||
|             echo "Setting resolver DNSForge." | ||||
|             echo "What content would you like to filter:" | ||||
|             echo "    0) Standard: Ad, tracker, and malware filtering" | ||||
|             echo "    1) Clean: Standard + adult content filtering" | ||||
|             echo "    2) Hard: Clean + stricter ad, tracker, and malware filtering" | ||||
|             while [[ "$valid_input" == "0" ]]; do | ||||
|                 read -p "Selection [0-2]: " resolver_subselection | ||||
|                 if [[ "$resolver_subselection" == [012]* ]]; then | ||||
|                     valid_input="1" | ||||
|                 else | ||||
|                     echo "That is not a valid selection." | ||||
|                 fi | ||||
|             done | ||||
|             valid_input="0" | ||||
|             case "$resolver_subselection" in | ||||
|                 0) | ||||
|                     resolver_ipv4_address="176.9.93.198" | ||||
|                     resolver_ipv4_address_2="176.9.1.117" | ||||
|                     resolver_ipv6_address="2a01:4f8:151:34aa::198" | ||||
|                     resolver_ipv6_address_2="2a01:4f8:141:316d::117" | ||||
|                     resolver_hostname="dnsforge.de" | ||||
|                     ;; | ||||
|                 1) | ||||
|                     resolver_ipv4_address="49.12.223.2" | ||||
|                     resolver_ipv4_address_2="49.12.43.208" | ||||
|                     resolver_ipv6_address="2a01:4f8:c17:4fbc::2" | ||||
|                     resolver_ipv6_address_2="2a01:4f8:c012:ed89::208" | ||||
|                     resolver_hostname="clean.dnsforge.de" | ||||
|                     ;; | ||||
|                 2) | ||||
|                     resolver_ipv4_address="49.12.222.213" | ||||
|                     resolver_ipv4_address_2="88.198.122.154" | ||||
|                     resolver_ipv6_address="2a01:4f8:c17:2c61::213" | ||||
|                     resolver_ipv6_address_2="2a01:4f8:c013:5ec0::154" | ||||
|                     resolver_hostname="hard.dnsforge.de" | ||||
|                     ;; | ||||
|             esac | ||||
|             resolver_https_address="https://$resolver_hostname/dns-query" | ||||
|             ;; | ||||
|         5) | ||||
|             echo "Setting custom resolver." | ||||
|             echo "NOTE: If the resolver does not support DoT/DoQ or DNSSEC, this process will not work." | ||||
|             echo "" | ||||
|             echo "Please provide the technical information." | ||||
|             read -p "Please enter the resolver's IP address (e.g. '1.1.1.2'): " resolver_ipv4_address | ||||
|             read -p "Does the resolver provide two distinct IP addresses (e.g. '1.1.1.2' and '1.0.0.2')? [Y/n] " resolver_has_second_ip | ||||
|             resolver_has_second_ip=${resolver_has_second_ip:-y} | ||||
|             if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||
|                 read -p "Please enter the resolver's second IP address: " resolver_ipv4_address_2 | ||||
|             fi | ||||
|             read -p "Does the resolver support IPv6 (e.g. '2606:4700:4700::1112')? [Y/n] " resolver_supports_ipv6 | ||||
|             resolver_supports_ipv6=${resolver_supports_ipv6:-y} | ||||
|             if [[ "$resolver_supports_ipv6" == [Yy]* ]]; then | ||||
|                 read -p "Please enter the resolver's IPv6 address: " resolver_ipv6_address | ||||
|                 if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||
|                     read -p "Please enter the resolver's second IPv6 address: " resolver_ipv6_address_2 | ||||
|                 fi | ||||
|             fi | ||||
|             read -p "Please enter the second resolver's hostname (e.g. 'security.cloudflare-dns.com'): " resolver_hostname | ||||
|             ;; | ||||
|     esac | ||||
|  | ||||
|     read -p "Would you like the resolver to be set in the default browser (hardened-chromium) via management policy? [y/N] " set_browser_policy | ||||
|     if [[ "$set_browser_policy" == [Yy]* && "$resolver_selection" == 5 ]]; then | ||||
|         read -p "Please enter the second resolver's HTTPS address (e.g. 'https://security.cloudflare-dns.com/dns-query'): " resolver_https_address | ||||
|     fi | ||||
|  | ||||
|     resolved_conf_dns_string="DNS=" | ||||
|     resolved_conf_dns_string+=" $resolver_ipv4_address" | ||||
|     resolved_conf_dns_string+="#$resolver_hostname" | ||||
|     if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||
|         resolved_conf_dns_string+=" $resolver_ipv4_address_2" | ||||
|         resolved_conf_dns_string+="#$resolver_hostname" | ||||
|     fi | ||||
|     if [[ "$resolver_supports_ipv6" == [Yy]* ]]; then | ||||
|         resolved_conf_dns_string+=" $resolver_ipv6_address" | ||||
|         resolved_conf_dns_string+="#$resolver_hostname" | ||||
|         if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||
|             resolved_conf_dns_string+=" $resolver_ipv6_address_2" | ||||
|             resolved_conf_dns_string+="#$resolver_hostname" | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     cat << EOF > "$resolved_conf" | ||||
|     [Resolve] | ||||
|     DNSSEC=true | ||||
|     DNSOverTLS=true | ||||
|     $resolved_conf_dns_string | ||||
|     EOF | ||||
|  | ||||
|     systemctl restart systemd-resolved | ||||
|  | ||||
|     echo "Config file for resolved configured with selected resolver and service restarted." | ||||
|  | ||||
|     if [[ "$set_browser_policy" != [Yy]* ]]; then | ||||
|         exit 0 | ||||
|     fi | ||||
|     cat << EOF > "$policy_file" | ||||
|     { | ||||
|         "DnsOverHttpsMode": "secure", | ||||
|         "DnsOverHttpsTemplates": "$resolver_https_address" | ||||
|     } | ||||
|     EOF | ||||
|  | ||||
|     echo "Browser policy set with selected resolver." | ||||
							
								
								
									
										30
									
								
								files/justfiles/hardening.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								files/justfiles/hardening.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| # Harden flatpaks by preloading hardened_malloc (highest supported hwcap). When called with a flatpak application ID as an argument, applies the overrides to that application instead of globally. | ||||
| harden-flatpak FLATPAK="": | ||||
|     #!/usr/bin/bash | ||||
|     var1={{ FLATPAK }} | ||||
|     flatpak_id="${var1:-}" | ||||
|     flatpak override --user --filesystem=host-os:ro $flatpak_id | ||||
|     uarches="$(/usr/lib64/ld-linux-x86-64.so.2 --help | grep '(supported, searched)' | cut -d'v' -f2)" | ||||
|     bestuarch="${uarches:0:1}" | ||||
|     if [ -z "$bestuarch" ] ; then | ||||
|         echo "No microarchitecture support detected. Using default x86-64-v1 architecture${flatpak_id:+" for $flatpak_id's malloc"}." | ||||
|         flatpak override --user --env=LD_PRELOAD=/var/run/host/usr/lib64/libhardened_malloc.so $flatpak_id | ||||
|     else | ||||
|         echo "x86-64-v$bestuarch support detected. Using x86-64-v$bestuarch microarchitecture${flatpak_id:+" for $flatpak_id's malloc"}." | ||||
|         flatpak override --user --env=LD_PRELOAD=/var/run/host/usr/lib64/glibc-hwcaps/x86-64-v"$bestuarch"/libhardened_malloc.so $flatpak_id | ||||
|     fi | ||||
|  | ||||
| # Setup USBGuard | ||||
| setup-usbguard: | ||||
|     #!/usr/bin/bash | ||||
|     echo "Notice: This will generate a policy based on your existing connected USB devices." | ||||
|     ACTIVE_USERNAME=$(whoami) | ||||
|     pkexec sh -c ' | ||||
|         mkdir -p /var/log/usbguard | ||||
|         mkdir -p /etc/usbguard | ||||
|         chmod 755 /etc/usbguard | ||||
|         usbguard generate-policy > /etc/usbguard/rules.conf | ||||
|         systemctl enable --now usbguard.service | ||||
|         usbguard add-user $1 | ||||
|     ' -- $ACTIVE_USERNAME | ||||
|     systemctl enable --user --now usbguard-notifier.service | ||||
							
								
								
									
										89
									
								
								files/justfiles/kargs.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								files/justfiles/kargs.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| # Add additional boot parameters for hardening (requires reboot) | ||||
| set-kargs-hardening: | ||||
|     #!/usr/bin/bash | ||||
|     read -p "Do you need support for 32-bit processes/syscalls? (This is mostly used by legacy software, with some exceptions, such as Steam) [y/N]: " YES | ||||
|     if [[ "$YES" == [Yy]* ]]; then | ||||
|         echo "Keeping 32-bit support." | ||||
|     else | ||||
|         IAEMU_NO="--append-if-missing=ia32_emulation=0" | ||||
|         echo "Disabling 32-bit support, for the next boot." | ||||
|     fi | ||||
|     read -p "Do you want to force disable Simultaneous Multithreading (SMT) / Hyperthreading? (This can cause a reduction in the performance of certain tasks in favor of security) (Note that in most hardware SMT will be disabled anyways to mitigate a known vulnerability, this turns it off on all hardware regardless) [y/N]: " YES | ||||
|     if [[ "$YES" == [Yy]* ]]; then | ||||
|         NOSMT_YES="--append-if-missing=nosmt=force" | ||||
|         echo "Force disabling SMT/Hyperthreading." | ||||
|     else | ||||
|         echo "Not force disabling SMT/Hyperthreading." | ||||
|     fi | ||||
|     read -p "Would you like to set additional (unstable) hardening kargs? (Warning: Setting these kargs may lead to boot issues on some hardware.) [y/N]: " YES | ||||
|     if [[ "$YES" == [Yy]* ]]; then | ||||
|     UNSTABLE_YES="--append-if-missing=efi=disable_early_pci_dma \ | ||||
|         --append-if-missing=debugfs=off" | ||||
|         echo "Setting unstable hardening kargs." | ||||
|     else | ||||
|         echo "Not setting unstable hardening kargs." | ||||
|     fi | ||||
|     echo "Applying boot parameters..." | ||||
|     rpm-ostree kargs \ | ||||
|       ${UNSTABLE_YES:+$UNSTABLE_YES} ${IAEMU_NO:+$IAEMU_NO} ${NOSMT_YES:+$NOSMT_YES} \ | ||||
|       --append-if-missing=init_on_alloc=1 \ | ||||
|       --append-if-missing=init_on_free=1 \ | ||||
|       --append-if-missing=slab_nomerge \ | ||||
|       --append-if-missing=page_alloc.shuffle=1 \ | ||||
|       --append-if-missing=randomize_kstack_offset=on \ | ||||
|       --append-if-missing=vsyscall=none \ | ||||
|       --append-if-missing=lockdown=confidentiality \ | ||||
|       --append-if-missing=random.trust_cpu=off \ | ||||
|       --append-if-missing=random.trust_bootloader=off \ | ||||
|       --append-if-missing=iommu=force \ | ||||
|       --append-if-missing=intel_iommu=on \ | ||||
|       --append-if-missing=amd_iommu=force_isolation \ | ||||
|       --append-if-missing=iommu.passthrough=0 \ | ||||
|       --append-if-missing=iommu.strict=1 \ | ||||
|       --append-if-missing=pti=on \ | ||||
|       --append-if-missing=module.sig_enforce=1 \ | ||||
|       --append-if-missing=mitigations=auto,nosmt \ | ||||
|       --append-if-missing=spectre_v2=on \ | ||||
|       --append-if-missing=spec_store_bypass_disable=on \ | ||||
|       --append-if-missing=l1d_flush=on \ | ||||
|       --append-if-missing=gather_data_sampling=force  | ||||
|     echo "Hardening kargs applied." | ||||
|  | ||||
| # Remove all hardening boot parameters (requires reboot) | ||||
| remove-kargs-hardening: | ||||
|     #!/usr/bin/bash | ||||
|     rpm-ostree kargs \ | ||||
|       --delete-if-present="init_on_alloc=1" \ | ||||
|       --delete-if-present="init_on_free=1" \ | ||||
|       --delete-if-present="slab_nomerge" \ | ||||
|       --delete-if-present="page_alloc.shuffle=1" \ | ||||
|       --delete-if-present="randomize_kstack_offset=on" \ | ||||
|       --delete-if-present="vsyscall=none" \ | ||||
|       --delete-if-present="lockdown=confidentiality" \ | ||||
|       --delete-if-present="random.trust_cpu=off" \ | ||||
|       --delete-if-present="random.trust_bootloader=off" \ | ||||
|       --delete-if-present="iommu=force" \ | ||||
|       --delete-if-present="intel_iommu=on" \ | ||||
|       --delete-if-present="amd_iommu=force_isolation" \ | ||||
|       --delete-if-present="iommu.passthrough=0" \ | ||||
|       --delete-if-present="iommu.strict=1" \ | ||||
|       --delete-if-present="pti=on" \ | ||||
|       --delete-if-present="module.sig_enforce=1" \ | ||||
|       --delete-if-present="mitigations=auto,nosmt" \ | ||||
|       --delete-if-present="efi=disable_early_pci_dma" \ | ||||
|       --delete-if-present="debugfs=off" \ | ||||
|       --delete-if-present="spectre_v2=on" \ | ||||
|       --delete-if-present="spec_store_bypass_disable=on" \ | ||||
|       --delete-if-present="l1d_flush=on" \ | ||||
|       --delete-if-present="gather_data_sampling=force" \ | ||||
|       --delete-if-present="ia32_emulation=0" | ||||
|     echo "Hardening kargs removed." | ||||
|  | ||||
| # Set nvidia kargs | ||||
| set-kargs-nvidia: | ||||
|     #!/usr/bin/bash | ||||
|     rpm-ostree kargs \ | ||||
|       --append-if-missing=rd.driver.blacklist=nouveau \ | ||||
|       --append-if-missing=modprobe.blacklist=nouveau \ | ||||
|       --append-if-missing=nvidia-drm.modeset=1 \ | ||||
|       --append-if-missing=nvidia-drm.fbdev=1 | ||||
							
								
								
									
										22
									
								
								files/justfiles/luks.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								files/justfiles/luks.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| # vim: set ft=make : | ||||
| # Copyright 2024 Universal Blue | ||||
| # | ||||
| # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||
| # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and limitations under the License. | ||||
|  | ||||
| # Enable automatic LUKS unlock via TPM | ||||
| setup-luks-tpm-unlock: | ||||
|     #!/usr/bin/bash | ||||
|     run0 /usr/libexec/luks-enable-tpm2-autounlock | ||||
|  | ||||
| # Disable automatic LUKS unlock via TPM | ||||
| remove-luks-tpm-unlock: | ||||
|     #!/usr/bin/bash | ||||
|     run0 /usr/libexec/luks-disable-tpm2-autounlock | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										223
									
								
								files/justfiles/toggles.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								files/justfiles/toggles.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | ||||
| # Toggle the cups service on/off | ||||
| toggle-cups: | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     if systemctl is-enabled --quiet cups; then | ||||
|       firewall-cmd --permanent --remove-port=631/tcp | ||||
|       firewall-cmd --permanent --remove-port=631/udp  | ||||
|       firewall-cmd --reload  | ||||
|       systemctl mask cups | ||||
|       systemctl disable cups | ||||
|       systemctl stop cups | ||||
|       systemctl daemon-reload | ||||
|       echo "Cups disabled." | ||||
|     else | ||||
|       firewall-cmd --permanent --add-port=631/tcp | ||||
|       firewall-cmd --permanent --add-port=631/udp  | ||||
|       firewall-cmd --reload  | ||||
|       systemctl unmask cups | ||||
|       systemctl enable cups | ||||
|       systemctl start cups | ||||
|       systemctl daemon-reload | ||||
|       echo "Cups enabled." | ||||
|     fi | ||||
|  | ||||
| # Toggle bluetooth kernel modules on/off (requires reboot) | ||||
| toggle-bluetooth-modules: | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     BLUE_MOD_FILE="/etc/modprobe.d/99-bluetooth.conf" | ||||
|     if test -e $BLUE_MOD_FILE; then | ||||
|       sudo rm -f $BLUE_MOD_FILE | ||||
|       echo "Bluetooth kernel modules disabled. Reboot to take effect." | ||||
|     else | ||||
|       sudo sh -c 'echo "install bluetooth /sbin/modprobe --ignore-install bluetooth" >> "$1"' _ "$BLUE_MOD_FILE" | ||||
|       sudo sh -c 'echo "install btusb /sbin/modprobe --ignore-install btusb" >> "$1"' _ "$BLUE_MOD_FILE" | ||||
|       sudo chmod 644 $BLUE_MOD_FILE | ||||
|       echo "Bluetooth kernel modules enabled. Reboot to take effect." | ||||
|     fi | ||||
|  | ||||
| # Toggle GHNS (KDE Get New Stuff) | ||||
| toggle-ghns: | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     KDE_GLOBALS_FILE="/etc/xdg/kdeglobals" | ||||
|     if test -e $KDE_GLOBALS_FILE; then | ||||
|       if grep -q "ghns=false" "$KDE_GLOBALS_FILE"; then | ||||
|         sed -i "s/ghns=false/ghns=true/" "$KDE_GLOBALS_FILE" | ||||
|         echo "GHNS enabled." | ||||
|       elif grep -q "ghns=true" "$KDE_GLOBALS_FILE"; then | ||||
|         sed -i "s/ghns=true/ghns=false/" "$KDE_GLOBALS_FILE" | ||||
|         echo "GHNS disabled." | ||||
|       else  | ||||
|         echo "The kdeglobals file is missing the ghns toggle." | ||||
|       fi | ||||
|     else | ||||
|       echo "No kdeglobals file found. Are you on kinoite?" | ||||
|     fi | ||||
|  | ||||
| # enable a kernel module that is disabled by modprobe.d (requires restart) | ||||
| override-enable-module mod_name: | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     MOD_NAME="{{ mod_name }}" | ||||
|     MOD_FILE="/etc/modprobe.d/99-$MOD_NAME.conf" | ||||
|     if test -e $MOD_FILE; then | ||||
|       echo "$MOD_NAME module is already enabled." | ||||
|     else | ||||
|       sudo sh -c 'echo "install $1 /sbin/modprobe --ignore-install $1" >> "$2"' _ "$MOD_NAME" "$MOD_FILE"  | ||||
|       sudo chmod 644 $MOD_FILE | ||||
|       echo "Override created to enable $MOD_NAME module. Reboot to take effect." | ||||
|     fi | ||||
|  | ||||
| # reset the override by `just override-enable-module`, i.e. disable the module again (requires restart) | ||||
| override-reset-module mod_name: | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     MOD_NAME="{{ mod_name }}" | ||||
|     MOD_FILE="/etc/modprobe.d/99-$MOD_NAME.conf" | ||||
|     if test -e $MOD_FILE; then | ||||
|       sudo rm -f $MOD_FILE | ||||
|       echo "The override for $MOD_NAME module has been reset. Reboot to take effect." | ||||
|     else | ||||
|       echo "No override found for $MOD_NAME module." | ||||
|     fi | ||||
|  | ||||
| # Toggle anticheat support by changing ptrace scope (requires restart) | ||||
| toggle-anticheat-support: | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     SYSCTL_HARDENING_FILE="/etc/sysctl.d/hardening.conf" | ||||
|     if grep -q "kernel.yama.ptrace_scope = 3" "$SYSCTL_HARDENING_FILE"; then | ||||
|         sed -i "s/kernel.yama.ptrace_scope = 3/kernel.yama.ptrace_scope = 1/" "$SYSCTL_HARDENING_FILE" | ||||
|         echo "Anticheat support enabled. ptrace_scope set to 1." | ||||
|     elif grep -q "kernel.yama.ptrace_scope = 1" "$SYSCTL_HARDENING_FILE"; then | ||||
|         sed -i "s/kernel.yama.ptrace_scope = 1/kernel.yama.ptrace_scope = 3/" "$SYSCTL_HARDENING_FILE" | ||||
|         echo "Anticheat support disabled. ptrace_scope set back to 3." | ||||
|     else  | ||||
|         echo "The sysctl hardening file is missing the ptrace_scope setting." | ||||
|     fi | ||||
|  | ||||
| # Toggle Gnome JIT JavaScript for GJS and WebkitGTK (requires session restart) | ||||
| toggle-gnome-jit-js: | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     ENV_FILE="/etc/profile.d/gnome-disable-jit.sh" | ||||
|     if test -e $ENV_FILE; then | ||||
|         sudo rm -f $ENV_FILE | ||||
|         echo "JIT JavaScript for Gnome and WebkitGTK has been enabled." | ||||
|     else | ||||
|         sudo cp /usr$ENV_FILE $ENV_FILE | ||||
|         sudo chmod 644 $ENV_FILE | ||||
|         echo "JIT JavaScript for Gnome and WebkitGTK has been disabled." | ||||
|     fi | ||||
|  | ||||
| # Toggle support for using GNOME user extensions | ||||
| toggle-gnome-extensions: | ||||
|     #!/usr/bin/bash | ||||
|     GSETTING="$(gsettings get org.gnome.shell allow-extension-installation)" | ||||
|     if [[ "${GSETTING}" == "false" ]]; then | ||||
|       gsettings set org.gnome.shell allow-extension-installation true | ||||
|       echo "Support for GNOME user extensions have been enabled" | ||||
|     else | ||||
|       gsettings reset org.gnome.shell allow-extension-installation | ||||
|       echo "Support for GNOME user extensions have been disabled" | ||||
|     fi | ||||
|  | ||||
| # Toggle Xwayland support | ||||
| toggle-xwayland ACTION="prompt": | ||||
|     #!/usr/bin/pkexec /usr/bin/bash | ||||
|     source /usr/lib/ujust/ujust.sh | ||||
|     OPTION={{ ACTION }} | ||||
|     if [ "$OPTION" == "prompt" ]; then | ||||
|       echo "${bold}Toggling Xwayland (requires logout)${normal}" | ||||
|       echo 'For which DE/WM do you want to toggle Xwayland?' | ||||
|       OPTION=$(ugum choose "GNOME" "KDE Plasma" "Sway") | ||||
|     elif [ "$OPTION" == "help" ]; then | ||||
|       echo "Usage: ujust toggle-xwayland <option>" | ||||
|       echo "  <option>: Specify the quick option - 'gnome', 'plasma', or 'sway'" | ||||
|       echo "  Use 'gnome' to Toggle Xwayland for GNOME." | ||||
|       echo "  Use 'plasma' to Toggle Xwayland for KDE Plasma." | ||||
|       echo "  Use 'sway' to Toggle Xwayland for Sway." | ||||
|       exit 0 | ||||
|     fi | ||||
|     if [ "$OPTION" == "GNOME" ] || [ "${OPTION,,}" == "gnome" ]; then | ||||
|       GNOME_XWAYLAND_FILE="/etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf" | ||||
|       if test -e $GNOME_XWAYLAND_FILE; then | ||||
|         sudo rm -f $GNOME_XWAYLAND_FILE | ||||
|         echo "Xwayland for GNOME has been enabled." | ||||
|       else | ||||
|         sudo cp /usr$GNOME_XWAYLAND_FILE $GNOME_XWAYLAND_FILE | ||||
|         sudo chmod 644 $GNOME_XWAYLAND_FILE | ||||
|         echo "Xwayland for GNOME has been disabled." | ||||
|       fi | ||||
|     elif [ "$OPTION" == "KDE Plasma" ] || [ "${OPTION,,}" == "plasma" ]; then | ||||
|       PLASMA_XWAYLAND_FILE="/etc/systemd/user/plasma-kwin_wayland.service.d/override.conf" | ||||
|       if test -e $PLASMA_XWAYLAND_FILE; then | ||||
|         sudo rm -f $PLASMA_XWAYLAND_FILE | ||||
|         echo "Xwayland for KDE Plasma has been enabled." | ||||
|       else | ||||
|         sudo cp /usr$PLASMA_XWAYLAND_FILE $PLASMA_XWAYLAND_FILE | ||||
|         sudo chmod 644 $PLASMA_XWAYLAND_FILE | ||||
|         echo "Xwayland for KDE Plasma has been disabled." | ||||
|       fi | ||||
|     elif [ "$OPTION" == "Sway" ] || [ "${OPTION,,}" == "sway" ]; then | ||||
|       SWAY_XWAYLAND_FILE="/etc/sway/config.d/99-noxwayland.conf" | ||||
|       if test -e $SWAY_XWAYLAND_FILE; then | ||||
|         sudo rm -f $SWAY_XWAYLAND_FILE | ||||
|         echo "Xwayland for Sway has been enabled." | ||||
|       else | ||||
|         sudo cp /usr$SWAY_XWAYLAND_FILE $SWAY_XWAYLAND_FILE | ||||
|         sudo chmod 644 $SWAY_XWAYLAND_FILE | ||||
|         echo "Xwayland for Sway has been disabled." | ||||
|       fi | ||||
|     fi | ||||
|  | ||||
| # Toggle bash environment lockdown (mitigates LD_PRELOAD attacks) | ||||
| toggle-bash-environment-lockdown: | ||||
|     #!/usr/bin/bash | ||||
|     BASH_ENV_FILES=("$HOME/.bashrc" "$HOME/.bash_profile") | ||||
|     echo "${b}WARNING${n} This will overwrite your .bashrc and .bash_profile." | ||||
|     echo "This is needed to ensure the mitigation is effective." | ||||
|     echo "Do you understand?" | ||||
|     echo "Please type in \"YES I UNDERSTAND\" and press enter" | ||||
|     read ACCEPT | ||||
|     if [ "$ACCEPT" == "YES I UNDERSTAND" ]; then | ||||
|       if lsattr "${BASH_ENV_FILES[0]}" 2>/dev/null | awk '{print $1}' | grep -q 'i'; then | ||||
|         echo "Bash environment '(${BASH_ENV_FILES[@]})' is locked down. Unlocking it." | ||||
|         for file in "${BASH_ENV_FILES[@]}"; do | ||||
|             pkexec chattr -i "$file" | ||||
|         done | ||||
|       else | ||||
|         echo "Bash environment '(${BASH_ENV_FILES[@]})' is unlocked. Locking it." | ||||
|         echo " | ||||
|     # .bashrc | ||||
|  | ||||
|     # Source global definitions | ||||
|     if [ -f /etc/bashrc ]; then | ||||
|         . /etc/bashrc | ||||
|     fi | ||||
|  | ||||
|     # User specific environment | ||||
|     if ! [[ "\$PATH" =~ "\$HOME/.local/bin:\$HOME/bin:" ]]; then | ||||
|         PATH="\$HOME/.local/bin:\$HOME/bin:\$PATH" | ||||
|     fi | ||||
|     export PATH | ||||
|  | ||||
|     # Uncomment the following line if you don't like systemctl's auto-paging feature: | ||||
|     # export SYSTEMD_PAGER= | ||||
|  | ||||
|     unset rc | ||||
|           " > ~/.bashrc | ||||
|  | ||||
|         echo " | ||||
|     # .bash_profile | ||||
|  | ||||
|     # Get the aliases and functions | ||||
|     if [ -f ~/.bashrc ]; then | ||||
|         . ~/.bashrc | ||||
|     fi | ||||
|  | ||||
|     # User specific environment and startup programs | ||||
|         " > ~/.bash_profile | ||||
|  | ||||
|         for file in "${BASH_ENV_FILES[@]}"; do | ||||
|             pkexec chattr +i "$file" | ||||
|         done | ||||
|       fi | ||||
|     else | ||||
|       echo "Capitalization matters when you type \"YES I UNDERSTAND\"" | ||||
|     fi | ||||
							
								
								
									
										178
									
								
								files/justfiles/utilities.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								files/justfiles/utilities.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | ||||
| # vim: set ft=make : | ||||
| # Copyright 2024 secureblue | ||||
| # | ||||
| # This file includes code from Universal Blue which is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" | ||||
| # BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language | ||||
| # governing permissions and limitations under the License. | ||||
|  | ||||
| uid := `id -u` | ||||
| shell := `grep :$(id -u): /etc/passwd | cut -d: -f7` | ||||
|  | ||||
| # Boot into this device's BIOS/UEFI screen | ||||
| bios: | ||||
|     #!/usr/bin/bash | ||||
|     if [ -d /sys/firmware/efi ]; then | ||||
|       systemctl reboot --firmware-setup | ||||
|     else | ||||
|       echo "Rebooting to legacy BIOS from OS is not supported." | ||||
|     fi | ||||
|  | ||||
| # Show all messages from this boot | ||||
| logs-this-boot: | ||||
|     sudo journalctl -b 0 | ||||
|  | ||||
| # Show all messages from last boot | ||||
| logs-last-boot: | ||||
|     sudo journalctl -b -1 | ||||
|  | ||||
| # Regenerate GRUB config, useful in dual-boot scenarios where a second operating system isn't listed | ||||
| regenerate-grub: | ||||
|     #!/usr/bin/bash | ||||
|     if [ -d /sys/firmware/efi ]; then | ||||
|       sudo grub2-mkconfig -o /etc/grub2-efi.cfg | ||||
|     else | ||||
|       sudo grub2-mkconfig -o /etc/grub2.cfg | ||||
|     fi | ||||
|  | ||||
| # Enroll Nvidia driver & KMOD signing key for secure boot - Enter password "universalblue" if prompted | ||||
| enroll-secure-boot-key: | ||||
|     sudo mokutil --timeout -1 | ||||
|     echo 'The next line will prompt for a MOK password. Then, input "universalblue"' | ||||
|     sudo mokutil --import /etc/pki/akmods/certs/akmods-ublue.der | ||||
|     echo 'At next reboot, the mokutil UEFI menu UI will be displayed (*QWERTY* keyboard input and navigation).\nThen, select "Enroll MOK", and input "universalblue" as the password' | ||||
|  | ||||
| # Toggle display of the user-motd in terminal | ||||
| toggle-user-motd: | ||||
|     #!/usr/bin/bash | ||||
|     if test -e "${HOME}/.config/no-show-user-motd"; then | ||||
|       rm -f "${HOME}/.config/no-show-user-motd" | ||||
|     else | ||||
|       if test ! -d "${HOME}/.config"; then | ||||
|         mkdir "${HOME}/.config" | ||||
|       fi | ||||
|       touch "${HOME}/.config/no-show-user-motd" | ||||
|     fi | ||||
|  | ||||
| # Update device firmware | ||||
| [no-exit-message] | ||||
| update-firmware: | ||||
|     fwupdmgr refresh --force | ||||
|     fwupdmgr get-updates | ||||
|     fwupdmgr update | ||||
|  | ||||
| # Clean up old up unused podman images, volumes, flatpak packages and rpm-ostree content | ||||
| clean-system: | ||||
|     #!/usr/bin/bash | ||||
|     podman image prune -af | ||||
|     podman volume prune -f | ||||
|     flatpak uninstall --unused | ||||
|     rpm-ostree cleanup -bm | ||||
|  | ||||
| # Check for local overrides | ||||
| check-local-overrides: | ||||
|     #!/usr/bin/bash | ||||
|     diff -r \ | ||||
|       --suppress-common-lines \ | ||||
|       --color="always" \ | ||||
|       --exclude "passwd*" \ | ||||
|       --exclude "group*" \ | ||||
|       --exclude="subgid*" \ | ||||
|       --exclude="subuid*" \ | ||||
|       --exclude="machine-id" \ | ||||
|       --exclude="adjtime" \ | ||||
|       --exclude="fstab" \ | ||||
|       --exclude="system-connections" \ | ||||
|       --exclude="shadow*" \ | ||||
|       --exclude="gshadow*" \ | ||||
|       --exclude="ssh_host*" \ | ||||
|       --exclude="cmdline" \ | ||||
|       --exclude="crypttab" \ | ||||
|       --exclude="hostname" \ | ||||
|       --exclude="localtime" \ | ||||
|       --exclude="locale*" \ | ||||
|       --exclude="*lock" \ | ||||
|       --exclude=".updated" \ | ||||
|       --exclude="*LOCK" \ | ||||
|       --exclude="vconsole*" \ | ||||
|       --exclude="00-keyboard.conf" \ | ||||
|       --exclude="grub" \ | ||||
|       --exclude="system.control*" \ | ||||
|       --exclude="cdi" \ | ||||
|       --exclude="default.target" \ | ||||
|       /usr/etc /etc 2>/dev/null | sed '/Binary\ files\ /d' | ||||
|  | ||||
| # Debug dump pastebin for issue reporting | ||||
| debug-info: | ||||
|     #!/usr/bin/bash | ||||
|     rpm_ostree_status=$(echo -e "=== Rpm-Ostree Status ===\n"; rpm-ostree status --verbose) | ||||
|     sysinfo=$(echo -e "\n"; fpaste --sysinfo --printonly) | ||||
|     flatpaks=$(echo "=== Flatpaks Installed ==="; flatpak list --columns=application,version,options) | ||||
|     audit_results=$(echo -e "\n=== Audit Results ===\n"; ujust audit-secureblue) | ||||
|     local_overrides=$(echo -e "\n=== Listing Local Overrides ===\n"; ujust check-local-overrides) | ||||
|     recent_events=$(echo -e "\n=== Recent System Events ===\n"; journalctl -b -p err..alert --since "1 hour ago") | ||||
|     failed_services=$(echo -e "\n=== Failed Services ===\n"; systemctl list-units --state=failed) | ||||
|     content="$rpm_ostree_status$sysinfo$flatpaks$audit_results$local_overrides$recent_events$failed_services" | ||||
|     echo "$content" | fpaste --confirm --private=1 | ||||
|  | ||||
| # Rerun Yafti | ||||
| rerun-yafti: | ||||
|     yafti -f /usr/share/ublue-os/firstboot/yafti.yml | ||||
|  | ||||
| alias assemble := distrobox-assemble | ||||
|  | ||||
| # Create distroboxes from a defined manifest | ||||
| distrobox-assemble CONTAINER="prompt" ACTION="create" FILE="/etc/distrobox/distrobox.ini": | ||||
|     #!/usr/bin/bash | ||||
|     # Distroboxes are gathered from distrobox.ini, please add them there | ||||
|     source /usr/lib/ujust/ujust.sh | ||||
|     AssembleList {{ FILE }} {{ ACTION }} {{ CONTAINER }} | ||||
|  | ||||
| # Create toolbox containers from a defined manifest (this spec will not be expanded) | ||||
| toolbox-assemble CONTAINER="prompt" ACTION="create" FILE="/etc/toolbox/toolbox.ini": | ||||
|     #!/usr/bin/bash | ||||
|     # Toolboxes are gathered from toolbox.ini, please add them there | ||||
|     source /usr/lib/ujust/ujust.sh | ||||
|     ToolboxAssembleList {{ FILE }} {{ ACTION }} {{ CONTAINER }} | ||||
|  | ||||
|     alias nvidia := configure-nvidia | ||||
|  | ||||
| # Configure the Nvidia driver | ||||
| configure-nvidia ACTION="prompt": | ||||
|     #!/usr/bin/bash | ||||
|     source /usr/lib/ujust/ujust.sh | ||||
|     OPTION={{ ACTION }} | ||||
|     if [ "$OPTION" == "prompt" ]; then | ||||
|       echo "${bold}Configuring Nvidia drivers${normal}" | ||||
|       echo 'What would you like to do?' | ||||
|       OPTION=$(ugum choose "Set needed kernel arguments" "Test CUDA support") | ||||
|     elif [ "$OPTION" == "help" ]; then | ||||
|       echo "Usage: ujust configure-nvidia <option>" | ||||
|       echo "  <option>: Specify the quick option - 'kargs' or 'test-cuda'" | ||||
|       echo "  Use 'kargs' to Set needed kernel arguments" | ||||
|       echo "  Use 'test-cuda' to Test CUDA support" | ||||
|       exit 0 | ||||
|     fi | ||||
|     if [ "$OPTION" == "Set needed kernel arguments" ] || [ "${OPTION,,}" == "kargs" ]; then | ||||
|       if command -v nvidia-smi; then | ||||
|       else | ||||
|         echo 'You do not appear to be on a Nvidia image, please refer to the README for your uBlue-OS image.' | ||||
|       fi | ||||
|     elif [ "$OPTION" == "Test CUDA support" ] || [ "${OPTION,,}" == "test-cuda" ]; then | ||||
|       if lsmod | grep -wq "nvidia"; then | ||||
|         podman run \ | ||||
|           --user 1000:1000 \ | ||||
|           --security-opt=no-new-privileges \ | ||||
|           --cap-drop=ALL \ | ||||
|           --security-opt label=type:nvidia_container_t  \ | ||||
|           --device=nvidia.com/gpu=all \ | ||||
|           docker.io/nvidia/samples:vectoradd-cuda11.2.1 | ||||
|       else | ||||
|         echo 'The Nvidia kernel module is not loaded. You may be using secure boot without the needed signing key, lacking the needed kargs, or may not be on a Nvidia image. See "just enroll-secure-boot-key" and "just nvidia-set-kargs".' | ||||
|       fi | ||||
|     fi | ||||
| @@ -1,53 +0,0 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # Tell build process to exit if there are any errors. | ||||
| set -oue pipefail | ||||
|  | ||||
| POLICY_FILE="/usr/etc/containers/policy.json" | ||||
|  | ||||
| if [[ ! -f "$POLICY_FILE" ]]; then | ||||
|     echo "Error: $POLICY_FILE does not exist." | ||||
|     exit 1 | ||||
| fi | ||||
|  | ||||
| sed -i 's/insecureAcceptAnything/reject/' "$POLICY_FILE" | ||||
|  | ||||
|  | ||||
| yq -i -o=j '.transports.docker |= | ||||
|     {"ghcr.io/jasonn3": [ | ||||
|         { | ||||
|           "type": "sigstoreSigned", | ||||
|           "keyPath": "/usr/etc/pki/containers/build-container-installer.pub", | ||||
|           "signedIdentity": { | ||||
|             "type": "matchRepository" | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
| + .' "$POLICY_FILE" | ||||
|  | ||||
| yq -i -o=j '.transports.docker |= | ||||
|     {"ghcr.io/zelikos": [ | ||||
|         { | ||||
|           "type": "sigstoreSigned", | ||||
|           "keyPath": "/usr/etc/pki/containers/davincibox.pub", | ||||
|           "signedIdentity": { | ||||
|             "type": "matchRepository" | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
| + .' "$POLICY_FILE" | ||||
|  | ||||
| yq -i -o=j '.transports.docker |= | ||||
|     {"ghcr.io/wayblueorg": [ | ||||
|         { | ||||
|           "type": "sigstoreSigned", | ||||
|           "keyPath": "/usr/etc/pki/containers/wayblue.pub", | ||||
|           "signedIdentity": { | ||||
|             "type": "matchRepository" | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
| + .' "$POLICY_FILE" | ||||
| @@ -1,7 +0,0 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # Tell build process to exit if there are any errors. | ||||
| set -oue pipefail | ||||
|  | ||||
| patch /usr/share/ublue-os/just/15-luks.just < use-pkexec-in-luks-just.patch | ||||
| patch /usr/share/ublue-os/just/40-nvidia.just < remove-unusable-just-command.patch | ||||
| @@ -1,15 +0,0 @@ | ||||
| 61,74d60 | ||||
| < # Switch between Nvidia image and NVK | ||||
| < toggle-nvk: | ||||
| <     #!/usr/bin/bash | ||||
| <     CURRENT_IMAGE=$(rpm-ostree status -b --json | jq -r '.deployments[0]."container-image-reference"' | sed -E 's/^.+\/(.+:.+)$/\1/') | ||||
| <     CURRENT_URI=$(rpm-ostree status -b --json | jq -r '.deployments[0]."container-image-reference"' | sed -E 's/^(.+\/).+:.+$/\1/') | ||||
| <     NEW_IMAGE=$CURRENT_IMAGE | ||||
| <     if [[ "$CURRENT_IMAGE" =~ "nvidia" ]]; then | ||||
| <       NEW_IMAGE=${CURRENT_IMAGE/-nvidia/} | ||||
| <     else | ||||
| <       NEW_IMAGE=${CURRENT_IMAGE/:/-nvidia:} | ||||
| <     fi | ||||
| <     echo "Rebasing to ${NEW_IMAGE}" | ||||
| <     rpm-ostree rebase ${CURRENT_URI}${NEW_IMAGE} | ||||
| <  | ||||
| @@ -1,8 +0,0 @@ | ||||
| 6c6 | ||||
| <     sudo /usr/libexec/luks-enable-tpm2-autounlock | ||||
| --- | ||||
| >     pkexec /usr/libexec/luks-enable-tpm2-autounlock | ||||
| 11c11 | ||||
| <     sudo /usr/libexec/luks-disable-tpm2-autounlock | ||||
| --- | ||||
| >     pkexec /usr/libexec/luks-disable-tpm2-autounlock | ||||
							
								
								
									
										131
									
								
								files/system/etc/containers/policy.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								files/system/etc/containers/policy.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| { | ||||
|   "default": [ | ||||
|       { | ||||
|           "type": "reject" | ||||
|       } | ||||
|   ], | ||||
|   "transports": { | ||||
|       "docker": { | ||||
|         "ghcr.io/wayblueorg": [ | ||||
|           { | ||||
|             "type": "sigstoreSigned", | ||||
|             "keyPath": "/usr/etc/pki/containers/wayblue.pub", | ||||
|             "signedIdentity": { | ||||
|               "type": "matchRepository" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "ghcr.io/zelikos": [ | ||||
|           { | ||||
|             "type": "sigstoreSigned", | ||||
|             "keyPath": "/usr/etc/pki/containers/davincibox.pub", | ||||
|             "signedIdentity": { | ||||
|               "type": "matchRepository" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "ghcr.io/jasonn3": [ | ||||
|           { | ||||
|             "type": "sigstoreSigned", | ||||
|             "keyPath": "/usr/etc/pki/containers/build-container-installer.pub", | ||||
|             "signedIdentity": { | ||||
|               "type": "matchRepository" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "registry.access.redhat.com": [ | ||||
|             { | ||||
|                 "type": "signedBy", | ||||
|                 "keyType": "GPGKeys", | ||||
|                 "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" | ||||
|             } | ||||
|         ], | ||||
|         "registry.redhat.io": [ | ||||
|             { | ||||
|                 "type": "signedBy", | ||||
|                 "keyType": "GPGKeys", | ||||
|                 "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" | ||||
|             } | ||||
|         ], | ||||
|         "quay.io/toolbx-images": [ | ||||
|             { | ||||
|                 "type": "sigstoreSigned", | ||||
|                 "keyPath": "/etc/pki/containers/quay.io-toolbx-images.pub", | ||||
|                 "signedIdentity": { | ||||
|                     "type": "matchRepository" | ||||
|                 } | ||||
|             } | ||||
|         ], | ||||
|         "ghcr.io/ublue-os": [ | ||||
|             { | ||||
|                 "type": "sigstoreSigned", | ||||
|                 "keyPath": "/etc/pki/containers/ublue-os.pub", | ||||
|                 "signedIdentity": { | ||||
|                     "type": "matchRepository" | ||||
|                 } | ||||
|             } | ||||
|         ], | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "docker-daemon": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "atomic": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "containers-storage": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "dir": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "oci": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "oci-archive": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "docker-archive": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     "tarball": { | ||||
|         "": [ | ||||
|             { | ||||
|                 "type": "reject" | ||||
|             } | ||||
|         ] | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,3 @@ | ||||
| docker: | ||||
|   quay.io/toolbx-images: | ||||
|     use-sigstore-attachments: true | ||||
							
								
								
									
										3
									
								
								files/system/etc/containers/registries.d/ublue-os.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								files/system/etc/containers/registries.d/ublue-os.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| docker: | ||||
|   ghcr.io/ublue-os: | ||||
|     use-sigstore-attachments: true | ||||
							
								
								
									
										59
									
								
								files/system/etc/distrobox/distrobox.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								files/system/etc/distrobox/distrobox.ini
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| # Add more distros and then use: | ||||
| # distrobox assemble create --replace --file /etc/distrobox/distrobox.ini --name containername | ||||
| # This will replace your distroboxes in place | ||||
| # Tip: Use additional_packages as declarative config! | ||||
| # See https://distrobox.privatedns.org/usage/distrobox-assemble/ | ||||
| [arch] | ||||
| image=ghcr.io/ublue-os/arch-distrobox:latest | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [arch-amdgpupro] | ||||
| image=ghcr.io/ublue-os/arch-distrobox-amdgpupro:latest | ||||
| nvidia=false | ||||
| pull=true | ||||
|  | ||||
| [bluefin-cli] | ||||
| image=ghcr.io/ublue-os/bluefin-cli | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [debian] | ||||
| image=quay.io/toolbx-images/debian-toolbox:unstable | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [fedora] | ||||
| image=ghcr.io/ublue-os/fedora-distrobox:latest | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [opensuse] | ||||
| image=quay.io/toolbx-images/opensuse-toolbox:tumbleweed | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [ubuntu] | ||||
| image=ghcr.io/ublue-os/ubuntu-toolbox:latest | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [alma] | ||||
| image=quay.io/toolbx-images/almalinux-toolbox:latest | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [centos] | ||||
| image=quay.io/toolbx-images/centos-toolbox:latest | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [wolfi] | ||||
| image=ghcr.io/ublue-os/wolfi-toolbox | ||||
| nvidia=true | ||||
| pull=true | ||||
|  | ||||
| [wolfi-dx] | ||||
| image=ghcr.io/ublue-os/wolfi-dx-toolbox | ||||
| nvidia=true | ||||
| pull=true | ||||
| @@ -0,0 +1,4 @@ | ||||
| -----BEGIN PUBLIC KEY----- | ||||
| MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQr63Nsc66mA3oGMArrQPm8/AkuTO | ||||
| K+ZrK3WCWzx00LW5K1qu+BS3U4eyMmXaFKIsX69PEFZWzXKy9psum8wj9Q== | ||||
| -----END PUBLIC KEY----- | ||||
							
								
								
									
										4
									
								
								files/system/etc/pki/containers/ublue-os.pub
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								files/system/etc/pki/containers/ublue-os.pub
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| -----BEGIN PUBLIC KEY----- | ||||
| MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHLRpBfPRYiMl9wb7s6fx47PzzNWu | ||||
| 3zyJgXhWEvxoOgwv9CpwjbvUwR9qHxNMWkJhuGE6cjDA2hpy1I6NbA+24Q== | ||||
| -----END PUBLIC KEY----- | ||||
							
								
								
									
										2
									
								
								files/system/etc/profile.d/brew.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								files/system/etc/profile.d/brew.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| #!/usr/bin/env bash | ||||
| [[ -d /home/linuxbrew/.linuxbrew && $- == *i* ]] && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" | ||||
							
								
								
									
										13
									
								
								files/system/etc/profile.d/user-motd.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								files/system/etc/profile.d/user-motd.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # Prevent doublesourcing | ||||
| if [ -z "$USERMOTDSOURCED" ]; then | ||||
|   USERMOTDSOURCED="Y" | ||||
|   if test -d "$HOME"; then | ||||
|     if test ! -e "$HOME"/.config/no-show-user-motd; then | ||||
|       if test -x "/usr/libexec/ublue-motd"; then | ||||
|         /usr/libexec/ublue-motd | ||||
|       fi | ||||
|     fi | ||||
|   fi | ||||
| fi | ||||
| @@ -0,0 +1,6 @@ | ||||
| [Unit] | ||||
| Wants=network-online.target | ||||
| After=network-online.target | ||||
|  | ||||
| [Service] | ||||
| ExecCondition=/bin/bash -c '[[ "$(busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered | cut -c 3-)" == @(2|4) ]]' | ||||
| @@ -0,0 +1,4 @@ | ||||
| [Timer] | ||||
| RandomizedDelaySec=10m | ||||
| OnCalendar=*-*-* 4:00:00 | ||||
| Persistent=true | ||||
							
								
								
									
										11
									
								
								files/system/etc/toolbox/toolbox.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								files/system/etc/toolbox/toolbox.ini
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| # Add more distros and then use: | ||||
| # ujust toolbox-assemble prompt create | ||||
| # This will replace your toolboxes in place | ||||
| [rhel-toolbox-8] | ||||
| image=registry.access.redhat.com/ubi8/toolbox:latest | ||||
|  | ||||
| [rhel-toolbox-9] | ||||
| image=registry.access.redhat.com/ubi9/toolbox:latest | ||||
|  | ||||
| [fedora-toolbox-39] | ||||
| image=fedora:39 | ||||
							
								
								
									
										13
									
								
								files/system/etc/udev/rules.d/50-framework16.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								files/system/etc/udev/rules.d/50-framework16.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| # Audio Expansion Card | ||||
| ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0010", ATTR{power/autosuspend}="10", ATTR{power/control}="auto", GOTO="rules_end" | ||||
|  | ||||
| # Framework Laptop 16 Keyboard Module - ANSI | ||||
| ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0012", ATTR{power/autosuspend}="-1", ATTR{power/control}="on", ATTR{power/wakeup}="disabled", GOTO="rules_end" | ||||
|  | ||||
| # Framework Laptop 16 Numpad Module | ||||
| ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0014", ATTR{power/autosuspend}="-1", ATTR{power/control}="on", ATTR{power/wakeup}="disabled", GOTO="rules_end" | ||||
|  | ||||
| # Framework Laptop 16 Keyboard Module | ||||
| ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0018", ATTR{power/autosuspend}="-1", ATTR{power/control}="on", ATTR{power/wakeup}="disabled", GOTO="rules_end" | ||||
|  | ||||
| LABEL="rules_end" | ||||
							
								
								
									
										46
									
								
								files/system/etc/udev/rules.d/50-usb-realtek-net.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								files/system/etc/udev/rules.d/50-usb-realtek-net.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| # This is used to change the default configuration of Realtek USB ethernet adapters | ||||
|  | ||||
| ACTION!="add", GOTO="usb_realtek_net_end" | ||||
| SUBSYSTEM!="usb", GOTO="usb_realtek_net_end" | ||||
| ENV{DEVTYPE}!="usb_device", GOTO="usb_realtek_net_end" | ||||
|  | ||||
| # Modify this to change the default value | ||||
| ENV{REALTEK_MODE1}="1" | ||||
| ENV{REALTEK_MODE2}="3" | ||||
|  | ||||
| # Realtek | ||||
| ATTR{idVendor}=="0bda", ATTR{idProduct}=="815[2,3,5,6]", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="0bda", ATTR{idProduct}=="8053", ATTR{bcdDevice}=="e???", ATTR{bConfigurationValue}!="$env{REALTEK_MODE2}", ATTR{bConfigurationValue}="$env{REALTEK_MODE2}" | ||||
|  | ||||
| # Samsung | ||||
| ATTR{idVendor}=="04e8", ATTR{idProduct}=="a101", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
|  | ||||
| # Lenovo | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="304f", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="3052", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="3054", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="3057", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="3062", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="3069", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="3082", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="3098", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="7205", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="720a", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="720b", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="720c", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="7214", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="721e", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="8153", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="a359", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
| ATTR{idVendor}=="17ef", ATTR{idProduct}=="a387", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
|  | ||||
| # TP-LINK | ||||
| ATTR{idVendor}=="2357", ATTR{idProduct}=="0601", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
|  | ||||
| # Nvidia | ||||
| ATTR{idVendor}=="0955", ATTR{idProduct}=="09ff", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
|  | ||||
| # LINKSYS | ||||
| ATTR{idVendor}=="13b1", ATTR{idProduct}=="0041", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||
|  | ||||
| LABEL="usb_realtek_net_end" | ||||
							
								
								
									
										1
									
								
								files/system/etc/udev/rules.d/70-titan-key.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								files/system/etc/udev/rules.d/70-titan-key.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1|096e", ATTRS{idProduct}=="5026|0858|085b", TAG+="uaccess" | ||||
							
								
								
									
										89
									
								
								files/system/etc/udev/rules.d/70-u2f.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								files/system/etc/udev/rules.d/70-u2f.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| # Copyright (C) 2013-2015 Yubico AB | ||||
| # | ||||
| # This program is free software; you can redistribute it and/or modify it | ||||
| # under the terms of the GNU Lesser General Public License as published by | ||||
| # the Free Software Foundation; either version 2.1, or (at your option) | ||||
| # any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, but | ||||
| # WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser | ||||
| # General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General Public License | ||||
| # along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| # this udev file should be used with udev 188 and newer | ||||
| ACTION!="add|change", GOTO="u2f_end" | ||||
|  | ||||
| # Yubico YubiKey | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0113|0114|0115|0116|0120|0121|0200|0402|0403|0406|0407|0410", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Happlink (formerly Plug-Up) Security KEY | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="f1d0", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Neowave Keydo and Keydo AES | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1e0d", ATTRS{idProduct}=="f1d0|f1ae", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # HyperSecu HyperFIDO | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e|2ccf", ATTRS{idProduct}=="0880", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Feitian ePass FIDO, BioPass FIDO2 | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0850|0852|0853|0854|0856|0858|085a|085b|085d|0866|0867", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # JaCarta U2F | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="24dc", ATTRS{idProduct}=="0101|0501", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # U2F Zero | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # VASCO SecureClick | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1a44", ATTRS{idProduct}=="00bb", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Bluink Key | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2abe", ATTRS{idProduct}=="1002", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Thetis Key | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1ea8", ATTRS{idProduct}=="f025", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Nitrokey FIDO U2F, Nitrokey FIDO2, Safetech SafeKey | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="4287|42b1|42b3", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Google Titan U2F | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="5026", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Tomu board + chopstx U2F + SoloKeys | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="cdab|a2ca", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # SoloKeys | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="5070|50b0", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Trezor | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Infineon FIDO | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="058b", ATTRS{idProduct}=="022d", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Ledger Blue, Nano S and Nano X | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0000|0001|0004|0005|0015|1005|1015|4005|4015", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Kensington VeriMark | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="06cb", ATTRS{idProduct}=="0088", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # Longmai mFIDO | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="4c4d", ATTRS{idProduct}=="f703", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # eWBM FIDO2 - Goldengate 310, 320, 500, 450 | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="4a1a|4c2a|5c2f|f47c", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # OnlyKey (FIDO2 / U2F) | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # GoTrust Idem Key | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="f143", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| # ellipticSecure MIRKey | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ac", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||
|  | ||||
| LABEL="u2f_end" | ||||
							
								
								
									
										96
									
								
								files/system/etc/udev/rules.d/70-wooting.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								files/system/etc/udev/rules.d/70-wooting.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| # Wooting One Legacy | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff01", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff01", MODE="0660", TAG+="uaccess" | ||||
| # Wooting One update mode  | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2402", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Two Legacy | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff02", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff02", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Two update mode   | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2403", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting One | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1100", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1100", MODE="0660", TAG+="uaccess" | ||||
| # Wooting One Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1101", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1101", MODE="0660", TAG+="uaccess" | ||||
| # Wooting One 2nd Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1102", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1102", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Two | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1200", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1200", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Two Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1201", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1201", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Two 2nd Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1202", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1202", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Lekker | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1210", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1210", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Lekker Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1211", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1211", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Lekker 2nd Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1212", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1212", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Lekker update mode   | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="121f", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Two HE | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1220", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1220", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Two HE Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1221", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1221", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Two HE 2nd Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1222", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1222", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Two HE update mode   | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="122f", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Two HE (ARM) | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1230", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1230", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Two HE Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1231", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1231", MODE="0660", TAG+="uaccess" | ||||
| # Wooting Two HE 2nd Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1232", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1232", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting Two HE (ARM) update mode   | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="123f", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting 60HE | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1300", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1300", MODE="0660", TAG+="uaccess" | ||||
| # Wooting 60HE Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1301", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1301", MODE="0660", TAG+="uaccess" | ||||
| # Wooting 60HE 2nd Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1302", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1302", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting 60HE update mode   | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="130f", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting 60HE (ARM) | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1310", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1310", MODE="0660", TAG+="uaccess" | ||||
| # Wooting 60HE (ARM) Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1311", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1311", MODE="0660", TAG+="uaccess" | ||||
| # Wooting 60HE (ARM) 2nd Alt-gamepad mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1312", MODE="0660", TAG+="uaccess" | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1312", MODE="0660", TAG+="uaccess" | ||||
|  | ||||
| # Wooting 60HE (ARM) update mode | ||||
| SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="131f", MODE="0660", TAG+="uaccess" | ||||
							
								
								
									
										4
									
								
								files/system/etc/udev/rules.d/88-neutron_hifi_dac.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								files/system/etc/udev/rules.d/88-neutron_hifi_dac.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| # udev rule for Neutron HiFi DAC V1 | ||||
| # https://neutronhifi.com/devices/dac/v1 | ||||
|  | ||||
| SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="82f9", MODE="0666" | ||||
							
								
								
									
										5
									
								
								files/system/etc/udev/rules.d/90-apple-superdrive.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								files/system/etc/udev/rules.d/90-apple-superdrive.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| # Apple SuperDrive udev rule | ||||
| # Credits: @yookoala from GitHub | ||||
| # See: https://gist.github.com/yookoala/818c1ff057e3d965980b7fd3bf8f77a6 | ||||
|  | ||||
| ACTION=="add", ATTRS{idProduct}=="1500", ATTRS{idVendor}=="05ac", DRIVERS=="usb", RUN+="/usr/bin/sg_raw %r/sr%n EA 00 00 00 00 00 01" | ||||
							
								
								
									
										1
									
								
								files/system/etc/udev/rules.d/92-viia.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								files/system/etc/udev/rules.d/92-viia.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0666", TAG+="uaccess", TAG+="udev-acl" | ||||
| @@ -0,0 +1,7 @@ | ||||
| # Change the permissions of the battery threshold attributes so that they can be modified by ordinary users | ||||
| # See https://gitlab.com/marcosdalvarez/thinkpad-battery-threshold-extension | ||||
|  | ||||
| ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_start_threshold" | ||||
| ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_end_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_end_threshold" | ||||
| ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_start_threshold" | ||||
| ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_stop_threshold", RUN+="/bin/chmod 666 /sys%p/charge_stop_threshold" | ||||
							
								
								
									
										204
									
								
								files/system/usr/bin/ugum
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										204
									
								
								files/system/usr/bin/ugum
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,204 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # Copyright 2024 Universal Blue | ||||
| # | ||||
| # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||
| # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and limitations under the License. | ||||
|  | ||||
|  | ||||
| ################################################################## | ||||
| # This is a helper script to provide a basic fallback replacement  | ||||
| # for just commands and bash scripts that want to use gum in uBlue | ||||
| ################################################################## | ||||
|  | ||||
| # Supported menu handlers | ||||
| SUPPORTED_HANDLERS=( | ||||
|     "fzf" | ||||
| ) | ||||
|  | ||||
| # Check if gum is present | ||||
| GUM=$(which gum 2>/dev/null) | ||||
|  | ||||
| # Check if fzf is installed and set it as the handler | ||||
| FALLBACK_HANDLER=$(which fzf 2>/dev/null) | ||||
| HANDLER="" | ||||
| if [[ -n $FALLBACK_HANDLER ]]; then | ||||
|     HANDLER="fzf" | ||||
| fi | ||||
|  | ||||
| # If $MENU is set | ||||
| if [[ -n $MENU ]]; then | ||||
|     for BIN in "${SUPPORTED_HANDLERS[@]}" | ||||
|     do | ||||
|         if [[ "$BIN" == "$MENU" ]]; then | ||||
|             HANDLER=$BIN | ||||
|         fi | ||||
|     done | ||||
| fi | ||||
|  | ||||
| # Logic for what to do if gum is not installed | ||||
| function noGum () { | ||||
|     if [[ -z "$1" ]]; then | ||||
|         # If no arguments are provided then error with  | ||||
|         echo "ugum supports only choose or confirm as the first argument!" | ||||
|         echo "Usage:" | ||||
|         echo '    ugum choose option1 option2 \"option 3\"' | ||||
|         echo '        Returns: selected string' | ||||
|         echo '    ugum confirm "this is an optional question' | ||||
|         echo '        Returns: exit code in $? will be 0 for YES and 1 for NO' | ||||
|         exit 5 | ||||
|     elif [[ "$1" == "choose" ]]; then | ||||
|         # If choose is the verb then run the choose function and pass all remaining args to an appropriate handler | ||||
|         if [[ "$HANDLER" == "fzf" ]]; then | ||||
|             # Use fzf for choice selector | ||||
|             choose_Fzf "${@:2}" | ||||
|         else | ||||
|             # Use generic bash selector | ||||
|             choose_Generic "${@:2}" | ||||
|         fi | ||||
|     elif [[ "$1" == "confirm" ]]; then | ||||
|         # If confirm is the verb then run the confirm function and pass all remaining args to an appropriate handler | ||||
|         if [[ "$HANDLER" == "fzf" ]]; then | ||||
|             # Use fzf as a confirm dialog | ||||
|             confirm_Fzf "${@:2}" | ||||
|         else | ||||
|             # Use a generic bash dialog | ||||
|             confirm_Generic "${@:2}" | ||||
|         fi | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # Implements a generic bash choice dialog | ||||
| function choose_Generic () { | ||||
|     # Change PS3 to our select prompt | ||||
|     PS3='Please enter your choice: ' | ||||
|  | ||||
|     # Make an array to contain all options in | ||||
|     OPTIONS=() | ||||
|  | ||||
|     # Parse the arguments for the ones we support and care about | ||||
|     for arg in "$@" | ||||
|     do | ||||
|         # If the argument does not start with - | ||||
|         if [[ ! $arg =~ ^- ]]; then | ||||
|             OPTIONS+=("$arg") | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     # Make a select prompt in bash | ||||
|     select opt in "${OPTIONS[@]}" | ||||
|     do | ||||
|         case $opt in | ||||
|             "") | ||||
|                 # Invalid options print to STDERR and then loops back for the user to select again | ||||
|                 echo "Invalid option $REPLY" >&2 | ||||
|                 ;; | ||||
|             "$opt") | ||||
|                 echo "$opt" | ||||
|                 break | ||||
|                 ;; | ||||
|         esac | ||||
|     done  | ||||
| } | ||||
|  | ||||
| # Implements a choice dialog using fzf | ||||
| function choose_Fzf () { | ||||
|     # Change our select prompt | ||||
|     PROMPT='Please select your choice: ' | ||||
|  | ||||
|     # Make an array to contain all options in | ||||
|     local OPTIONS | ||||
|  | ||||
|     # Parse the arguments for the ones we support and care about | ||||
|     for arg in "$@" | ||||
|     do | ||||
|         # If the argument does not start with - | ||||
|         if [[ ! $arg =~ ^- ]]; then | ||||
|             if [[ "$OPTIONS" == "" ]]; then | ||||
|                 OPTIONS="${arg}" | ||||
|                 continue | ||||
|             fi | ||||
|             OPTIONS="${OPTIONS}\n${arg}" | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     # Make a select prompt using fzf | ||||
|     echo -e "$OPTIONS" | fzf --layout=reverse --height="~20%" --prompt="$PROMPT" | ||||
| } | ||||
|  | ||||
| # Implements a generic bash confirm dialog | ||||
| function confirm_Generic () { | ||||
|     # Set default prompt | ||||
|     PROMPT="Are you sure?" | ||||
|  | ||||
|     # Parse the arguments for the ones we support and care about  | ||||
|     for arg in "$@" | ||||
|     do | ||||
|         if [[ ! $arg =~ ^- ]]; then | ||||
|             PROMPT="$arg" | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     # Print the prompt and read input | ||||
|     read -r -p "$PROMPT [Y/n]: " YESNO | ||||
|     confirm_Parse "$YESNO" | ||||
| } | ||||
|  | ||||
| # Implements a confirm dialog in fzf | ||||
| function confirm_Fzf () { | ||||
|     PROMPT=$(confirm_getPrompt "$@") | ||||
|  | ||||
|     # Make the confirm prompt using fzf and read response | ||||
|     YESNO=$(echo -e "Yes\nNo" | fzf --layout=reverse --height="~20%" --prompt="$PROMPT ") | ||||
|     confirm_Parse "$YESNO" | ||||
| } | ||||
|  | ||||
| # Gets the prompt for the confirm dialog, with a fallback to "Are you sure?" | ||||
| function confirm_getPrompt () { | ||||
|     # Set default prompt | ||||
|     PROMPT="Are you sure?" | ||||
|  | ||||
|     # Parse the arguments for the ones we support and care about  | ||||
|     for arg in "$@" | ||||
|     do | ||||
|         if [[ ! $arg =~ ^- ]]; then | ||||
|             PROMPT="$arg" | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     # Return the prompt | ||||
|     echo "$PROMPT" | ||||
| } | ||||
|  | ||||
| # Parse the confirm response and translate it the same exit codes gum uses | ||||
| function confirm_Parse () { | ||||
|     case "$@" in | ||||
|         [Yy]*) | ||||
|             # Use exit code 0 for yes, just like gum | ||||
|             exit 0 | ||||
|             ;; | ||||
|         [Nn]*) | ||||
|             # Use exit code 1 for no, just like gum | ||||
|             exit 1 | ||||
|             ;; | ||||
|         *) | ||||
|             # Default exit code is 0 | ||||
|             exit 0 | ||||
|             ;; | ||||
|     esac | ||||
| } | ||||
|  | ||||
| # If gum is not present | ||||
| if [[ -z "$GUM" ]]; then | ||||
|     noGum "$@" | ||||
| else | ||||
|     # If gum is present just pass args to gum | ||||
|     $GUM "$@" | ||||
| fi | ||||
							
								
								
									
										15
									
								
								files/system/usr/bin/ujust
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								files/system/usr/bin/ujust
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # Copyright 2024 Universal Blue | ||||
| # | ||||
| # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||
| # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and limitations under the License. | ||||
|  | ||||
| /usr/bin/just --justfile /usr/share/ublue-os/justfile "${@}" | ||||
| @@ -0,0 +1 @@ | ||||
| add_dracutmodules+=" fido2 tpm2-tss pkcs11 pcsc " | ||||
| @@ -0,0 +1 @@ | ||||
| enable flatpak-system-update.service | ||||
| @@ -0,0 +1,10 @@ | ||||
| [Unit] | ||||
| Description=Flatpak Automatic Update | ||||
| Documentation=man:flatpak(1) | ||||
| Wants=network-online.target | ||||
| After=network-online.target | ||||
|  | ||||
| [Service] | ||||
| Type=oneshot | ||||
| ExecCondition=/bin/bash -c '[[ "$(busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered | cut -c 3-)" == @(2|4) ]]' | ||||
| ExecStart=/usr/bin/flatpak --system uninstall --unused -y --noninteractive ; /usr/bin/flatpak --system update -y --noninteractive ; /usr/bin/flatpak --system repair | ||||
| @@ -0,0 +1,12 @@ | ||||
| [Unit] | ||||
| Description=Flatpak Automatic Update Trigger | ||||
| Documentation=man:flatpak(1) | ||||
|  | ||||
| [Timer] | ||||
| RandomizedDelaySec=10m | ||||
| OnBootSec=2m | ||||
| OnCalendar=*-*-* 4:00:00 | ||||
| Persistent=true | ||||
|  | ||||
| [Install] | ||||
| WantedBy=timers.target | ||||
| @@ -0,0 +1 @@ | ||||
| enable flatpak-user-update.service | ||||
| @@ -0,0 +1,10 @@ | ||||
| [Unit] | ||||
| Description=Flatpak Automatic Update | ||||
| Documentation=man:flatpak(1) | ||||
| Wants=network-online.target | ||||
| After=network-online.target | ||||
|  | ||||
| [Service] | ||||
| Type=oneshot | ||||
| ExecCondition=/bin/bash -c '[[ "$(busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered | cut -c 3-)" == @(2|4) ]]' | ||||
| ExecStart=/usr/bin/flatpak --user uninstall --unused -y --noninteractive ; /usr/bin/flatpak --user update -y --noninteractive ; /usr/bin/flatpak --user repair | ||||
							
								
								
									
										12
									
								
								files/system/usr/lib/systemd/user/flatpak-user-update.timer
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								files/system/usr/lib/systemd/user/flatpak-user-update.timer
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| [Unit] | ||||
| Description=Flatpak Automatic Update Trigger | ||||
| Documentation=man:flatpak(1) | ||||
|  | ||||
| [Timer] | ||||
| RandomizedDelaySec=10m | ||||
| OnBootSec=2m | ||||
| OnCalendar=*-*-* 4:00:00 | ||||
| Persistent=true | ||||
|  | ||||
| [Install] | ||||
| WantedBy=timers.target | ||||
							
								
								
									
										11
									
								
								files/system/usr/lib/ujust/COPYRIGHT.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								files/system/usr/lib/ujust/COPYRIGHT.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Copyright 2024 Universal Blue | ||||
|  | ||||
| The files in this directory contain code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use these files except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||
| distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and limitations under the License. | ||||
							
								
								
									
										50
									
								
								files/system/usr/lib/ujust/libcolors.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								files/system/usr/lib/ujust/libcolors.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| #!/usr/bin/bash | ||||
| # Disable shellchecks for things that do not matter for | ||||
| # a sourceable file | ||||
| # shellcheck disable=SC2034,SC2155 | ||||
| ######## | ||||
| ### Basic Colors | ||||
| ### the bg function allows flipping these to background colors | ||||
| ### using the 90-97 colors is not supported by the bg function | ||||
| ### add them as extended colors instead which uses | ||||
| ### option 38 (foreground) which can be flipped to 48 (background) | ||||
| ######## | ||||
| declare -r black=$'\033[30m' | ||||
| declare -r red=$'\033[31m' | ||||
| declare -r green=$'\033[32m' | ||||
| declare -r yellow=$'\033[33m' | ||||
| declare -r blue=$'\033[34m' | ||||
| declare -r magenta=$'\033[35m' | ||||
| declare -r purple="$magenta" | ||||
| declare -r cyan=$'\033[36m' | ||||
| declare -r lightgrey=$'\033[37m' | ||||
| declare -r lightgray="$lightgrey" | ||||
|  | ||||
| ######## | ||||
| ### Extended Colors | ||||
| ### You can use cpick from https://github.com/ethanbaker/cpick to get the colors | ||||
| ### cpick bash varname | sed -E 's/readonly/declare/' | ||||
| ######## | ||||
| declare -r darkgrey=$'\033[38;2;168;168;168m' | ||||
| declare -r darkgray="$darkgrey" | ||||
| declare -r lightred=$'\033[38;2;255;114;118m' | ||||
| declare -r lightgreen=$'\033[38;2;146;240;146m' | ||||
| declare -r lightyellow=$'\033[38;2;255;255;224m' | ||||
| declare -r lightblue=$'\033[38;2;172;215;230m' | ||||
| declare -r pink=$'\033[38;2;255;20;146m' | ||||
| declare -r lightmagenta="$pink" | ||||
| declare -r lightcyan=$'\033[38;2;224;255;255m' | ||||
| declare -r white=$'\033[38;2;250;235;215m' | ||||
| declare -r lightpink=$'\033[38;2;255;181;192m' | ||||
| declare -r darkorange=$'\033[38;2;255;129;3m' | ||||
|  | ||||
| ## Function to generate background color from foreground color | ||||
| ## NOTE: doublequote the color or future calls to bg will error out! | ||||
| # bgblue=$(Bg "$blue") | ||||
| # echo "${bgblue}text now has blue background${normal} this text has no background color" | ||||
| function Bg (){ | ||||
|     COLOR="$1" | ||||
|      | ||||
|     # Flip foreground to background | ||||
|     echo "$COLOR" | sed -E 's/\[3([0-8]{1,1})/\[4\1/' | ||||
| } | ||||
							
								
								
									
										138
									
								
								files/system/usr/lib/ujust/libdistrobox.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								files/system/usr/lib/ujust/libdistrobox.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| #!/usr/bin/bash | ||||
| # shellcheck disable=SC2154 | ||||
| ######## | ||||
| ## Function to create a distrobox with standardized args | ||||
| ######## | ||||
| ## Create a distrobox using default fedora:latest, name the box "my-fedora-box" and give it a custom homedir | ||||
| # Distrobox "fedora:latest" "my-fedora-box" "$HOME/.var/containers/fedora-box" | ||||
| ## Create a debian toolbox distrobox named debian-unstable | ||||
| # Distrobox "quay.io/toolbx-images/debian-toolbox:unstable" "debian-unstable" | ||||
| ## Create an ubuntu distrobox named someubuntubox with no custom homedir and unshare network namespace | ||||
| ## ($3 is required if supplying extra args, using "" makes the function skip it) | ||||
| # Distrobox "ubuntu:latest" "someubuntubox" "" --unshare-ns | ||||
| function Distrobox (){ | ||||
|     IMAGE="$1" | ||||
|     NAME="$2" | ||||
|     HOMEDIR="" | ||||
|     # If custom home directory is supplied | ||||
|     if [ -n "$3" ]; then | ||||
|         HOMEDIR="$3" | ||||
|     fi | ||||
|  | ||||
|     # If a custom home directory is not specified | ||||
|     if [ -z "$HOMEDIR" ]; then | ||||
|         distrobox create --nvidia -Y --image "$IMAGE" -n "$NAME" "${@:3}" | ||||
|     else | ||||
|         # Make the custom homedir path if it does not exist | ||||
|         if [ ! -d "$HOMEDIR" ]; then | ||||
|             mkdir -p "$HOMEDIR" | ||||
|         fi | ||||
|         # Create distrobox with custom home path | ||||
|         distrobox create --nvidia -Y --image "$IMAGE" -n "$NAME" -H "$HOMEDIR" "${@:4}" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| ######## | ||||
| ## Function to assemble pre-defined distrobox containers from manifest files | ||||
| ######## | ||||
| ## Assemble all containers defined in an ini file without confirmation | ||||
| # Assemble noconfirmcreate "/etc/distrobox/distrobox.ini" | ||||
| # Assemble noconfirmcreate "" ALL | ||||
| ## Assemble ubuntu from default ini manifest, with confirmation | ||||
| # Assemble confirm "" ubuntu | ||||
| ## Remove a container defined in the default ini manifest | ||||
| # Assemble rm "" ubuntu | ||||
| function Assemble(){ | ||||
|     # Set defaults | ||||
|     ACTION="create" | ||||
|     FILE="/etc/distrobox/distrobox.ini" | ||||
|     NAME="" | ||||
|  | ||||
|     # If an action is provided | ||||
|     if [ -n "$1" ]; then | ||||
|         # Set ACTION to the action specified | ||||
|         # and remove "noconfirm" from $1 when assigning it to ACTION | ||||
|         ACTION="${1/noconfirm/}" | ||||
|     fi | ||||
|  | ||||
|     # If a filename is provided | ||||
|     if [ -n "$2" ]; then | ||||
|         # Set FILE to the provided filename | ||||
|         FILE="$2" | ||||
|     fi | ||||
|  | ||||
|     # If container name is ALL | ||||
|     if [ "$3" == "ALL" ] || [ -z "$3" ]; then | ||||
|         if [[ ! "$1" =~ ^noconfirm ]]; then | ||||
|             # Ask user if they REALLY want to assemble all the containers | ||||
|             echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n}\nALL containers defined in ${b}$FILE${n}." | ||||
|             CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||
|             if [ "$CONFIRM" == "1" ]; then | ||||
|                 echo "Aborting..." | ||||
|                 return 1 | ||||
|             fi | ||||
|         fi | ||||
|         # Run the distrobox assemble command | ||||
|         distrobox assemble "$ACTION" --file "$FILE" --replace | ||||
|         return $? | ||||
|     else | ||||
|         # Set distrobox name to provided name | ||||
|         NAME="$3" | ||||
|     fi | ||||
|      | ||||
|     # If we do not want confirmations | ||||
|     if [[ ! "$1" =~ ^noconfirm ]]; then | ||||
|         # Ask the user if they really want to replace $NAME container | ||||
|         echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n} the container ${b}$NAME${n}\nwith the one defined in ${b}$FILE${n}." | ||||
|         CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||
|         if [ "$CONFIRM" == "1" ]; then | ||||
|             echo "Aborting..." | ||||
|             return 1 | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     # Run the distrobox assemble command | ||||
|     distrobox assemble "$ACTION" --file "$FILE" --name "$NAME" --replace | ||||
| } | ||||
|  | ||||
| ######## | ||||
| ## Function to parse a distrobox.ini file and make a selectable list from it | ||||
| ######## | ||||
| ## Parse a distrobox.ini manifest and let user select which container to setup | ||||
| # AssembleList "$HOME/distrobox.ini" create | ||||
| ## Parse a distrobox.ini manifest and create ubuntu container without confirmation | ||||
| # AssembleList "$HOME/distrobox.ini" noconfirmcreate ubuntu | ||||
| function AssembleList (){ | ||||
|     # Set defaults | ||||
|     FILE="$1" | ||||
|     ACTION="create" | ||||
|     CHOICE="prompt" | ||||
|  | ||||
|     # If an ACTION is supplied | ||||
|     if [ -n "$2" ]; then | ||||
|         # Replace default action | ||||
|         ACTION="$2" | ||||
|     fi | ||||
|      | ||||
|     # If a CHOICE is predefined | ||||
|     if [ -n "$3" ]; then | ||||
|         # Replace default choice | ||||
|         CHOICE="$3" | ||||
|     fi | ||||
|  | ||||
|     # If the choice is "prompt" then ask user what container they want | ||||
|     if [ "$CHOICE" == "prompt" ]; then | ||||
|         CONTAINERS=$(grep -P "\[.+\]" "$FILE" | sed -E 's/\[(.+)\]/\1/') | ||||
|         echo "${b}Pre-defined Containers${n}" | ||||
|         echo "Please select a container to create" | ||||
|         # Disable an irrelevant shellscheck for next line as we want word splitting | ||||
|         # shellcheck disable=SC2086 | ||||
|         CHOICE=$(Choose ALL $CONTAINERS) | ||||
|     fi | ||||
|  | ||||
|     # If choice is not empty by now (will be empty if escaped from Choice function) | ||||
|     if [ -n "$CHOICE" ]; then | ||||
|         # Assemble the selected container | ||||
|         Assemble "$ACTION" "$FILE" "$CHOICE" | ||||
|     fi | ||||
| } | ||||
							
								
								
									
										42
									
								
								files/system/usr/lib/ujust/libformatting.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								files/system/usr/lib/ujust/libformatting.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| #!/usr/bin/bash | ||||
| # Disable shellchecks for things that do not matter for | ||||
| # a sourceable file | ||||
| # shellcheck disable=SC2034,SC2155 | ||||
| ######## | ||||
| ### Text Formating | ||||
| ######## | ||||
| declare -r bold=$'\033[1m' | ||||
| declare -r b="$bold" | ||||
| declare -r dim=$'\033[2m' | ||||
| declare -r underline=$'\033[4m' | ||||
| declare -r u="$underline" | ||||
| declare -r blink=$'\033[5m' | ||||
| declare -r invert=$'\033[7m' | ||||
| declare -r highlight="$invert" | ||||
| declare -r hidden=$'\033[8m' | ||||
|  | ||||
| ######## | ||||
| ### Remove Text Formating | ||||
| ######## | ||||
| declare -r normal=$'\033[0m' | ||||
| declare -r n="$normal" | ||||
| declare -r unbold=$'\033[21m' | ||||
| declare -r undim=$'\033[22m' | ||||
| declare -r nounderline=$'\033[24m' | ||||
| declare -r unblink=$'\033[25m' | ||||
| declare -r uninvert=$'\033[27m' | ||||
| declare -r unhide=$'\033[28m' | ||||
|  | ||||
| ######## | ||||
| ### Special text formating | ||||
| ######## | ||||
| ## Function to generate a clickable link, you can call this using | ||||
| # url=$(Urllink "https://ublue.it" "Visit the ublue website") | ||||
| # echo "${url}" | ||||
| function Urllink (){ | ||||
|     URL=$1 | ||||
|     TEXT=$2 | ||||
|  | ||||
|     # Generate a clickable hyperlink | ||||
|     printf "\e]8;;%s\e\\%s\e]8;;\e\\" "$URL" "$TEXT${n}" | ||||
| } | ||||
							
								
								
									
										31
									
								
								files/system/usr/lib/ujust/libfunctions.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								files/system/usr/lib/ujust/libfunctions.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| #!/usr/bin/bash | ||||
| # shellcheck disable=SC2154 | ||||
| ######## | ||||
| ## Useful functions we use a lot, if you want to use them, source libjust.sh | ||||
| ## As it depends on libformatting.sh and libcolors.sh | ||||
| ## They are not imported here to avoid attempting to redeclare readonly vars. | ||||
| ######## | ||||
|  | ||||
| ######## | ||||
| ## Function to generate a choice selection and return the selected choice | ||||
| ######## | ||||
| # CHOICE=$(Choice option1 option2 "option 3") | ||||
| # *user selects "option 3"* | ||||
| # echo "$CHOICE" will return "option 3" | ||||
| function Choose (){ | ||||
|     CHOICE=$(ugum choose "$@") | ||||
|     echo "$CHOICE" | ||||
| } | ||||
|  | ||||
| ######## | ||||
| ## Function to generate a confirm dialog and return the selected choice | ||||
| ######## | ||||
| # CHOICE=$(Confirm "Are you sure you want to do this?") | ||||
| # *user selects "No"* | ||||
| # echo "$CHOICE" will return "1" | ||||
| # 0 = Yes | ||||
| # 1 = No | ||||
| function Confirm (){ | ||||
|     ugum confirm "$@" | ||||
|     echo $? | ||||
| } | ||||
							
								
								
									
										171
									
								
								files/system/usr/lib/ujust/libtoolbox.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								files/system/usr/lib/ujust/libtoolbox.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | ||||
| #!/usr/bin/bash | ||||
| # shellcheck disable=SC2154 | ||||
| ######## | ||||
| ## Function to create a toolbox with standardized args | ||||
| ######## | ||||
| ## Create a debian toolbox toolbox named debian-unstable | ||||
| # Toolbox create "quay.io/toolbx-images/debian-toolbox:unstable" "debian-unstable" | ||||
| ## Create an ubuntu toolbox and provide an authfile to authenticate with the registry | ||||
| # Toolbox create "ubuntu:22.04" --authfile "/path/to/file" | ||||
| function Toolbox (){ | ||||
|     # Get the action we want to do | ||||
|     local ACTION="$1" | ||||
|     # Get the "image" argument, we use this as an abstraction layer | ||||
|     # To decide if it is an image registry or a distro+release image argument | ||||
|     local IMAGE="$2" | ||||
|  | ||||
|     # Define local variables | ||||
|     local DISTRORELEASE | ||||
|  | ||||
|     # If the ACTION is "replace" | ||||
|     if [ "$1" == "replace" ]; then | ||||
|         # Set ACTION to create | ||||
|         ACTION="create" | ||||
|  | ||||
|         # Remove old image before continuing | ||||
|         toolbox rm --force "${@:3}"  | ||||
|     fi | ||||
|  | ||||
|     # Check if $IMAGE is an image registry url | ||||
|     if [[ "$IMAGE" =~ / ]]; then | ||||
|         # Create toolbox based on image from registry | ||||
|         toolbox "$ACTION" --image "$IMAGE" "${@:3}" | ||||
|     else | ||||
|         # Split IMAGE string into an array | ||||
|         # shellcheck disable=SC2206 | ||||
|         DISTRORELEASE=(${IMAGE//:/ }) | ||||
|         # Create toolbox with distro and release args | ||||
|         toolbox "$ACTION" --distro "${DISTRORELEASE[0]}" --release "${DISTRORELEASE[1]}" "${@:3}"  | ||||
|     fi | ||||
| } | ||||
|  | ||||
| ######## | ||||
| ## Function to assemble pre-defined toolbox containers from manifest files | ||||
| ######## | ||||
| ## Assemble all containers defined in an ini file without confirmation | ||||
| # ToolboxAssemble noconfirmcreate "/etc/toolbox/toolbox.ini" | ||||
| # ToolboxAssemble noconfirmcreate "/etc/toolbox/toolbox.ini" ALL | ||||
| ## Assemble ubuntu from default ini manifest, with confirmation | ||||
| # ToolboxAssemble confirm "/etc/toolbox/toolbox.ini" ubuntu-toolbox-22.04 | ||||
| ## Remove a container defined in the default ini manifest | ||||
| # ToolboxAssemble rm "/etc/toolbox/toolbox.ini" ubuntu-toolbox-22.04 | ||||
| function ToolboxAssemble (){ | ||||
|     # Set defaults | ||||
|     local ACTION="create" | ||||
|     local FILE="/etc/toolbox/toolbox.ini" | ||||
|     local NAME="" | ||||
|  | ||||
|     # Define local variables | ||||
|     local CONTAINERS | ||||
|     local IMAGE | ||||
|     local CONFIRM | ||||
|  | ||||
|     # If an action is provided | ||||
|     if [ -n "$1" ]; then | ||||
|         # Set ACTION to the action specified | ||||
|         # and remove "noconfirm" from $1 when assigning it to ACTION | ||||
|         ACTION="${1/noconfirm/}" | ||||
|     fi | ||||
|  | ||||
|     # If a filename is provided | ||||
|     if [ -n "$2" ]; then | ||||
|         # Set FILE to the provided filename | ||||
|         FILE="$2" | ||||
|     fi | ||||
|  | ||||
|     # If container name is ALL | ||||
|     if [ "$3" == "ALL" ] || [ -z "$3" ]; then | ||||
|         if [[ ! "$1" =~ ^noconfirm ]]; then | ||||
|             # Ask user if they REALLY want to assemble all the containers | ||||
|             echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n}\nALL containers defined in ${b}$FILE${n}." | ||||
|             CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||
|             if [ "$CONFIRM" == "1" ]; then | ||||
|                 echo "Aborting..." | ||||
|                 return 1 | ||||
|             fi | ||||
|         fi | ||||
|         # Get all the containers | ||||
|         CONTAINERS=$(grep -P "\[.+\]" "$FILE" | sed -E 's/\[(.+)\]/\1/') | ||||
|          | ||||
|         # Run the toolbox assemble command | ||||
|         #toolbox assemble "$ACTION" --file "$FILE" --replace | ||||
|         for CONTAINER in $CONTAINERS | ||||
|         do | ||||
|             # Get the image for the container | ||||
|             IMAGE=$(grep -A1 -P "\[$CONTAINER\]" "$FILE" | grep "image" | sed 's/image=//') | ||||
|  | ||||
|             # Replace the container | ||||
|             Toolbox replace "$IMAGE" "$CONTAINER" | ||||
|         done | ||||
|         return $? | ||||
|     else | ||||
|         # Set toolbox name to provided name | ||||
|         NAME="$3" | ||||
|     fi | ||||
|      | ||||
|     # If we do not want confirmations | ||||
|     if [[ ! "$1" =~ ^noconfirm ]]; then | ||||
|         # Ask the user if they really want to replace $NAME container | ||||
|         echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n} the container ${b}$NAME${n}\nwith the one defined in ${b}$FILE${n}." | ||||
|         CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||
|         if [ "$CONFIRM" == "1" ]; then | ||||
|             echo "Aborting..." | ||||
|             return 1 | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     # Get the image for the container | ||||
|     IMAGE=$(grep -A1 -P "\[$NAME\]" "$FILE" | grep "image" | sed 's/image=//') | ||||
|  | ||||
|     # Replace the toolbox container | ||||
|     Toolbox replace "$IMAGE" "$NAME" | ||||
| } | ||||
|  | ||||
| ######## | ||||
| ## Function to parse a toolbox.ini file and make a selectable list from it | ||||
| ######## | ||||
| ## Parse a toolbox.ini manifest and let user select which container to setup | ||||
| # ToolboxAssembleList "$HOME/toolbox.ini" create | ||||
| ## Parse a toolbox.ini manifest and create ubuntu container without confirmation | ||||
| # ToolboxAssembleList "$HOME/toolbox.ini" noconfirmcreate ubuntu-toolbox-22.04 | ||||
| function ToolboxAssembleList (){ | ||||
|     # Set defaults | ||||
|     local FILE="$1" | ||||
|     local ACTION="create" | ||||
|     local CHOICE="prompt" | ||||
|  | ||||
|     # Define local variables | ||||
|     local CONTAINERS | ||||
|  | ||||
|     # If an ACTION is supplied | ||||
|     if [ -n "$2" ]; then | ||||
|         # Replace default action | ||||
|         ACTION="$2" | ||||
|     fi | ||||
|      | ||||
|     # If a CHOICE is predefined | ||||
|     if [ -n "$3" ]; then | ||||
|         # Replace default choice | ||||
|         CHOICE="$3" | ||||
|     fi | ||||
|  | ||||
|     # If the choice is "prompt" then ask user what container they want | ||||
|     if [ "$CHOICE" == "prompt" ]; then | ||||
|         CONTAINERS=$(grep -P "\[.+\]" "$FILE" | sed -E 's/\[(.+)\]/\1/') | ||||
|         echo "${b}Pre-defined Containers${n}" | ||||
|         echo "Please select a container to create" | ||||
|         # Disable an irrelevant shellscheck for next line as we want word splitting | ||||
|         # shellcheck disable=SC2086 | ||||
|         CHOICE=$(Choose ALL $CONTAINERS) | ||||
|     fi | ||||
|  | ||||
|     # If choice is not empty by now (will be empty if escaped from Choice function) | ||||
|     if [ -n "$CHOICE" ]; then | ||||
|         # If ACTION is create | ||||
|         if [ "$ACTION" == "create" ]; then | ||||
|             ACTION="replace" | ||||
|         fi | ||||
|         # Assemble the selected container | ||||
|         ToolboxAssemble "$ACTION" "$FILE" "$CHOICE" | ||||
|     fi | ||||
| } | ||||
							
								
								
									
										12
									
								
								files/system/usr/lib/ujust/ujust.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								files/system/usr/lib/ujust/ujust.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #!/usr/bin/bash | ||||
| # shellcheck source=/dev/null | ||||
| # Import color formatting | ||||
| source /usr/lib/ujust/libcolors.sh | ||||
| # Import text formatting | ||||
| source /usr/lib/ujust/libformatting.sh | ||||
| # Import functionality for just | ||||
| source /usr/lib/ujust/libfunctions.sh | ||||
| # Import functionality related to distrobox | ||||
| source /usr/lib/ujust/libdistrobox.sh | ||||
| # Import functionality related to toolbox | ||||
| source /usr/lib/ujust/libtoolbox.sh | ||||
							
								
								
									
										95
									
								
								files/system/usr/libexec/luks-disable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										95
									
								
								files/system/usr/libexec/luks-disable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Copyright 2024 Universal Blue | ||||
| # | ||||
| # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||
| # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and limitations under the License. | ||||
|  | ||||
|  | ||||
| ## disable auto-unlock LUKS2 encrypted root on Fedora/Silverblue/maybe others | ||||
| set -euo pipefail | ||||
|  | ||||
| [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;} | ||||
|  | ||||
| echo "This script utilizes systemd-cryptenroll for removing tpm2 auto-unlock." | ||||
| echo "You can review systemd-cryptenroll's manpage for more information." | ||||
| echo "This will modify your system and disable TPM2 auto-unlock of your LUKS partition!" | ||||
| read -p "Are you sure are good with this and want to disable TPM2 auto-unlock? (y/N): " -n 1 -r | ||||
| echo | ||||
| if [[ ! $REPLY =~ ^[Yy]$ ]]; then | ||||
|   [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell | ||||
| fi | ||||
|  | ||||
| ## Inspect Kernel Cmdline for rd.luks.uuid | ||||
| RD_LUKS_UUID="$(xargs -n1 -a /proc/cmdline | grep rd.luks.uuid | cut -d = -f 2)" | ||||
|  | ||||
| # Check to make sure cmdline rd.luks.uuid exists | ||||
| if [[ -z ${RD_LUKS_UUID:-} ]]; then | ||||
|   printf "LUKS device not defined on Kernel Commandline.\n" | ||||
|   printf "This is not supported by this script.\n" | ||||
|   printf "Exiting...\n" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Check to make sure that the specified cmdline uuid exists. | ||||
| if ! grep -q "${RD_LUKS_UUID}" <<< "$(lsblk)" ; then | ||||
|   printf "LUKS device not listed in block devices.\n" | ||||
|   printf "Exiting...\n" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Cut off the luks- | ||||
| LUKS_PREFIX="luks-" | ||||
| if grep -q ^${LUKS_PREFIX} <<< "${RD_LUKS_UUID}"; then | ||||
|   DISK_UUID=${RD_LUKS_UUID#"$LUKS_PREFIX"} | ||||
| else | ||||
|   echo "LUKS UUID format mismatch." | ||||
|   echo "Exiting..." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Specify Crypt Disk by-uuid | ||||
| CRYPT_DISK="/dev/disk/by-uuid/$DISK_UUID" | ||||
|  | ||||
| # Check to make sure crypt disk exists | ||||
| if [[ ! -L "$CRYPT_DISK" ]]; then | ||||
|   printf "LUKS device not listed in block devices.\n" | ||||
|   printf "Exiting...\n" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| ## Restore the crypttab | ||||
| cp -a /etc/crypttab /etc/crypttab.working-before-disable-tpm2 | ||||
| if [ -f /etc/crypttab.known-good ]; then | ||||
|   echo "Restoring /etc/crypttab.known-good to original /etc/crypttab" | ||||
|   mv /etc/crypttab.known-good /etc/crypttab | ||||
| fi | ||||
|  | ||||
| ## Wipe luks slot | ||||
| if cryptsetup luksDump "$CRYPT_DISK" | grep systemd-tpm2 > /dev/null; then | ||||
|   echo "Wiping systemd-tpm2 from LUKS on $CRYPT_DISK" | ||||
|   systemd-cryptenroll --wipe-slot=tpm2 "$CRYPT_DISK" | ||||
| else | ||||
|   echo "No systemd-tpm2 found in LUKS to wipe" | ||||
| fi | ||||
|  | ||||
| ## Disable initramfs | ||||
| if rpm-ostree initramfs | grep tpm2 > /dev/null; then | ||||
|   echo "WARNING: if you configured initramfs for anything other than TPM2, this wipes that too..." | ||||
|   echo "here's a printout:" | ||||
|   rpm-ostree initramfs | ||||
|   echo | ||||
|   echo "Disabling rpm-ostree initramfs..." | ||||
|   rpm-ostree initramfs --disable | ||||
| else | ||||
|   echo "TPM2 is not configured in 'rpm-ostree initramfs'..." | ||||
| fi | ||||
|  | ||||
| echo "TPM2 auto-unlock disabled..." | ||||
							
								
								
									
										123
									
								
								files/system/usr/libexec/luks-enable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										123
									
								
								files/system/usr/libexec/luks-enable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,123 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Copyright 2024 Universal Blue | ||||
| # | ||||
| # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||
| # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and limitations under the License. | ||||
|  | ||||
|  | ||||
| ## setup auto-unlock LUKS2 encrypted root on Fedora/Silverblue/maybe others | ||||
| set -eou pipefail | ||||
|  | ||||
|  | ||||
| [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;} | ||||
|  | ||||
| echo "WARNING: Do NOT use this if your CPU is vulnerable to faulTPM!" | ||||
| echo "All AMD Zen2 and Zen3 Processors are known to be affected!" | ||||
| echo "All AMD Zen1 processors are also likely affected, with Zen4 unknown!" | ||||
| echo "If you have an AMD CPU, you likely shouldn't use this!" | ||||
| echo "----------------------------------------------------------------------------" | ||||
| echo "This script uses systemd-cryptenroll to enable TPM2 auto-unlock." | ||||
| echo "You can review systemd-cryptenroll's manpage for more information." | ||||
| echo "This script will modify your system." | ||||
| echo "It will enable TPM2 auto-unlock of your LUKS partition for your root device!" | ||||
| echo "It will bind to PCR 7 and 14 which is tied to your secureboot and moklist state." | ||||
| read -p "Are you sure are good with this and want to enable TPM2 auto-unlock? (y/N): " -n 1 -r | ||||
| echo | ||||
| if [[ ! $REPLY =~ ^[Yy]$ ]]; then | ||||
|   [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell | ||||
| fi | ||||
|  | ||||
| ## Inspect Kernel Cmdline for rd.luks.uuid | ||||
| RD_LUKS_UUID="$(xargs -n1 -a /proc/cmdline | grep rd.luks.uuid | cut -d = -f 2)" | ||||
|  | ||||
| # Check to make sure cmdline rd.luks.uuid exists | ||||
| if [[ -z ${RD_LUKS_UUID:-} ]]; then | ||||
|   printf "LUKS device not defined on Kernel Commandline.\n" | ||||
|   printf "This is not supported by this script.\n" | ||||
|   printf "Exiting...\n" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Check to make sure that the specified cmdline uuid exists. | ||||
| if ! grep -q "${RD_LUKS_UUID}" <<< "$(lsblk)" ; then | ||||
|   printf "LUKS device not listed in block devices.\n" | ||||
|   printf "Exiting...\n" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Cut off the luks- | ||||
| LUKS_PREFIX="luks-" | ||||
| if grep -q ^${LUKS_PREFIX} <<< "${RD_LUKS_UUID}"; then | ||||
|   DISK_UUID=${RD_LUKS_UUID#"$LUKS_PREFIX"} | ||||
| else | ||||
|   echo "LUKS UUID format mismatch." | ||||
|   echo "Exiting..." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| SET_PIN_ARG="" | ||||
| read -p "Would you like to set a PIN? (y/N): " -n 1 -r | ||||
| echo | ||||
| if [[ $REPLY =~ ^[Yy]$ ]]; then | ||||
|   SET_PIN_ARG=" --tpm2-with-pin=yes " | ||||
| fi | ||||
|  | ||||
| # Specify Crypt Disk by-uuid | ||||
| CRYPT_DISK="/dev/disk/by-uuid/$DISK_UUID" | ||||
|  | ||||
| # Check to make sure crypt disk exists | ||||
| if [[ ! -L "$CRYPT_DISK" ]]; then | ||||
|   printf "LUKS device not listed in block devices.\n" | ||||
|   printf "Exiting...\n" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| if cryptsetup luksDump "$CRYPT_DISK" | grep systemd-tpm2 > /dev/null; then | ||||
|   KEYSLOT=$(cryptsetup luksDump "$CRYPT_DISK"|grep -A29 systemd-tpm2|grep Keyslot|awk '{print $2}') | ||||
|   echo "TPM2 already present in LUKS keyslot $KEYSLOT of $CRYPT_DISK." | ||||
|   read -p "Wipe it and re-enroll? (y/N): " -n 1 -r | ||||
|   echo | ||||
|   if [[ $REPLY =~ ^[Yy]$ ]]; then | ||||
|     systemd-cryptenroll --wipe-slot=tpm2 "$CRYPT_DISK" | ||||
|   else | ||||
|     echo | ||||
|     echo "Either clear the existing TPM2 keyslot before retrying, else choose 'y' next time." | ||||
|     echo "Exiting..." | ||||
|     [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| ## Run crypt enroll | ||||
| echo "Enrolling TPM2 unlock requires your existing LUKS2 unlock password" | ||||
| systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7+14 $SET_PIN_ARG "$CRYPT_DISK" | ||||
|  | ||||
|  | ||||
| if lsinitrd 2>&1 | grep -q tpm2-tss > /dev/null; then | ||||
|   ## add tpm2-tss to initramfs | ||||
|   if rpm-ostree initramfs | grep tpm2 > /dev/null; then | ||||
|     echo "TPM2 already present in rpm-ostree initramfs config." | ||||
|     rpm-ostree initramfs | ||||
|     echo "Re-running initramfs to pickup changes above." | ||||
|   fi | ||||
|   rpm-ostree initramfs --enable --arg=--force-add --arg=tpm2-tss | ||||
| else | ||||
|   ## initramfs already containts tpm2-tss | ||||
|   echo "TPM2 already present in initramfs." | ||||
| fi | ||||
|  | ||||
| ## Now reboot | ||||
| echo | ||||
| echo "TPM2 LUKS auto-unlock configured. Reboot now." | ||||
|  | ||||
|  | ||||
| # References: | ||||
| #  https://www.reddit.com/r/Fedora/comments/uo4ufq/any_way_to_get_systemdcryptenroll_working_on/ | ||||
| #  https://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html | ||||
							
								
								
									
										2
									
								
								files/system/usr/share/ublue-os/just/60-custom.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								files/system/usr/share/ublue-os/just/60-custom.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| # vim: set ft=make : | ||||
| # This file can be modified downstream to add custom just commands | ||||
							
								
								
									
										10
									
								
								files/system/usr/share/ublue-os/justfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								files/system/usr/share/ublue-os/justfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| set allow-duplicate-recipes := true | ||||
| set ignore-comments := true | ||||
|  | ||||
| _default: | ||||
|     #!/usr/bin/bash | ||||
|     source /usr/lib/ujust/libformatting.sh | ||||
|     /usr/bin/ujust --list --list-heading $'Available commands:\n' --list-prefix $' - ' | ||||
|  | ||||
| # Imports | ||||
| import "/usr/share/ublue-os/just/60-custom.just" | ||||
| @@ -2,31 +2,18 @@ modules: | ||||
|     - type: script | ||||
|       scripts: | ||||
|         - createautostartdir.sh | ||||
|     - type: containerfile | ||||
|       snippets: | ||||
|         - RUN rpm-ostree install just powerstat | ||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-udev-rules.noarch.rpm / | ||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-update-services.noarch.rpm / | ||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-signing.noarch.rpm / | ||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-luks.noarch.rpm / | ||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-just.noarch.rpm / | ||||
|         - RUN rpm -q ublue-os-udev-rules || rpm -ivh /ublue-os-udev-rules.noarch.rpm | ||||
|         - RUN rpm -q ublue-os-update-services || rpm -ivh /ublue-os-update-services.noarch.rpm | ||||
|         - RUN rpm -q ublue-os-signing || rpm -ivh /ublue-os-signing.noarch.rpm | ||||
|         - RUN rpm -q ublue-os-luks || rpm -ivh /ublue-os-luks.noarch.rpm | ||||
|         - RUN rpm -q ublue-os-just || rpm -ivh /ublue-os-just.noarch.rpm | ||||
|     - type: script | ||||
|       scripts: | ||||
|         - installrpmfusion.sh | ||||
|     - from-file: common/common-packages.yml | ||||
|     - type: justfiles | ||||
|       validate: true | ||||
|     - type: files | ||||
|       files: | ||||
|         - source: system/usr | ||||
|           destination: /usr | ||||
|         - source: system/etc | ||||
|           destination: /etc | ||||
|     - type: justfiles | ||||
|       validate: true | ||||
|     - from-file: common/common-scripts.yml | ||||
|     - type: script | ||||
|       scripts: | ||||
|   | ||||
| @@ -7,5 +7,4 @@ scripts: | ||||
|   - createmissingdirectories.sh | ||||
|   - removesuid.sh | ||||
|   - disablegeoclue.sh | ||||
|   - hardencontainerpolicy.sh | ||||
|   - enablesecurebluefirstrun.sh | ||||
|   | ||||
| @@ -8,4 +8,3 @@ scripts: | ||||
|   - disablemodemmanager.sh | ||||
|   - disablenfsdaemons.sh | ||||
|   - disablesssd.sh | ||||
|   - justfilehardening.sh | ||||
		Reference in New Issue
	
	Block a user
	 RoyalOughtness
					RoyalOughtness