chore: copy config from upstream and remove dep (#593)

This commit is contained in:
RoyalOughtness
2024-11-21 17:23:06 -08:00
committed by GitHub
parent 5172baa133
commit 261936654f
59 changed files with 2753 additions and 1161 deletions

View File

@@ -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

View 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" ]
}

View File

@@ -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
View 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

View File

@@ -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
View 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."

View 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

View 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
View 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

View 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

View 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

View File

@@ -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"

View 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

View File

@@ -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}
<

View File

@@ -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

View 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"
}
]
}
}
}

View File

@@ -0,0 +1,3 @@
docker:
quay.io/toolbx-images:
use-sigstore-attachments: true

View File

@@ -0,0 +1,3 @@
docker:
ghcr.io/ublue-os:
use-sigstore-attachments: true

View 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

View File

@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQr63Nsc66mA3oGMArrQPm8/AkuTO
K+ZrK3WCWzx00LW5K1qu+BS3U4eyMmXaFKIsX69PEFZWzXKy9psum8wj9Q==
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHLRpBfPRYiMl9wb7s6fx47PzzNWu
3zyJgXhWEvxoOgwv9CpwjbvUwR9qHxNMWkJhuGE6cjDA2hpy1I6NbA+24Q==
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
[[ -d /home/linuxbrew/.linuxbrew && $- == *i* ]] && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

View 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

View File

@@ -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) ]]'

View File

@@ -0,0 +1,4 @@
[Timer]
RandomizedDelaySec=10m
OnCalendar=*-*-* 4:00:00
Persistent=true

View 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

View 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"

View 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"

View File

@@ -0,0 +1 @@
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1|096e", ATTRS{idProduct}=="5026|0858|085b", TAG+="uaccess"

View 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"

View 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"

View 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"

View 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"

View File

@@ -0,0 +1 @@
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0666", TAG+="uaccess", TAG+="udev-acl"

View File

@@ -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
View 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
View 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 "${@}"

View File

@@ -0,0 +1 @@
add_dracutmodules+=" fido2 tpm2-tss pkcs11 pcsc "

View File

@@ -0,0 +1 @@
enable flatpak-system-update.service

View File

@@ -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

View 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

View File

@@ -0,0 +1 @@
enable flatpak-user-update.service

View File

@@ -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

View 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

View 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.

View 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/'
}

View 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
}

View 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}"
}

View 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 $?
}

View 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
}

View 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

View 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..."

View 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

View File

@@ -0,0 +1,2 @@
# vim: set ft=make :
# This file can be modified downstream to add custom just commands

View 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"

View File

@@ -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:

View File

@@ -7,5 +7,4 @@ scripts:
- createmissingdirectories.sh
- removesuid.sh
- disablegeoclue.sh
- hardencontainerpolicy.sh
- enablesecurebluefirstrun.sh

View File

@@ -7,5 +7,4 @@ scripts:
- disablealsastate.sh
- disablemodemmanager.sh
- disablenfsdaemons.sh
- disablesssd.sh
- justfilehardening.sh
- disablesssd.sh