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