commit f48c6569971ee3d718ed6b8a7e2ad75105d08c6e Author: Daniel Pätzold Date: Fri Jan 2 11:24:52 2026 +0100 First Commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..11a76d1 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +Fedora OEMDRV +an automated massinstallation scripting collection for Anakonda diff --git a/ks.cfg b/ks.cfg new file mode 100644 index 0000000..fb3faa6 --- /dev/null +++ b/ks.cfg @@ -0,0 +1 @@ +%include ks_pc_prof/pc-9cdb93ef7c20.cfg diff --git a/ks_base_profiles/basic_pre_script.inc b/ks_base_profiles/basic_pre_script.inc new file mode 100644 index 0000000..359ecc8 --- /dev/null +++ b/ks_base_profiles/basic_pre_script.inc @@ -0,0 +1,93 @@ +# Fedora Install Pre- Script +# +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# This script is meant to be executed from Fedora install ks.cfg in the pre-section +# It should reside on the Partition named OEMDRV formated as BTRFS or EXT4 +# The Location inside the OEMDRV- Partition should be /ks_base_profiles/basic_pre_script.inc +# When running from ks.cfg pre-section, the OEMDRV should be mountet by Anaconda to /mnt/tmp +# It will be run as root and will use sh to execute, the pre-section should look somewhat like this: +# %pre +# /bin/sh /mnt/tmp/ks_base_profiles/basic_pre_script.inc +# %end + +# The Script will search for the drive with the Partition OEMDRV on it and +# REMOVE ANY OTHER PARTITIONS ON THAT DRIVE +# As Anacondas scripts are non interactive, it will do so without asking or stopping. + +# We need to be root +if [ "$EUID" -ne 0 ] + then echo "* Error: Please run as root" + exit 1 +fi + +# Usually, the pre section is run in the sh- shell, the OEMDRV will be mountet at /mnt/tmp +# So we need to check if this is the case +FQFILENAME="/mnt/tmp/ks_base_profiles/basic_pre_script.inc" +if [ ! -f ${FQFILENAME} ]; then + echo "* Error finding the expeted Directory/File structure: Missing File" + echo "${FQFILENAME}" + echo "* Please check to run from Kickstart- Installation, or mount the OEMDRV with this File in /mnt/tmp before." + exit 1 +fi + +# Check if there is a Partition OEMDRV and on which Drive +source /mnt/tmp/system_setup/setup_system.conf +OEMDRVINFO=$(blkid | grep 'LABEL="OEMDRV"') +if [ "${OEMDRVINFO}." == "." ] ; then + echo "* Error: Required partition with label 'OEMDRV' is not found." + echo "It seems like this PC has never been setup to this Domain before." + echo "Please Check your Documentation at" + echo "${INSTALLDOCS}" + echo "on how to create a new setup on this PC" + exit 1 +fi +OEMDRVPART=$(echo "${OEMDRVINFO}" | cut -d ':' -f 1) +echo "Found Label OEMDRV on ${OEMDRVPART}" + +#Checking which is the Drive that the Partition is on +SYSDRIVE=$(lsblk -l | grep ":0" | while IFS= read -r SYSDRIVETMP; do + SYSDRIVE='/dev/'$(echo "${SYSDRIVETMP}" | cut -d ' ' -f 1) +# echo "Check ${SYSDRIVE}" + if echo "${OEMDRVPART}" | grep -q "${SYSDRIVE}"; then + echo ${SYSDRIVE} + break; + fi +done) +echo "Found Disk for Installation: ${SYSDRIVE} with Partition ${OEMDRVPART}" + +#Check if the Drive has a GPT +if [ "$(fdisk -l ${SYSDRIVE} | grep 'type: gpt')." == "." ]; then + echo "* Error: The Drive ${SYSDRIVE} does not look like it has a GPT. Installation cannot proceed." + exit 1 +else + echo "The Drive ${SYSDRIVE} contains a GPT." +fi + +OEMDRVPARTSHORT=${OEMDRVPART:5} +ALLPARTS=$(lsblk -n -l -o NAME "${SYSDRIVE}" -Q 'TYPE=="part"') +REMPARTS=$(echo "$ALLPARTS" | grep -v "${OEMDRVPARTSHORT}") +if [ "${REMPARTS}." != "." ]; then + echo + echo "The Following Partitions were found and are now going to be deleted:" + # echo "${REMPARTS}" + echo "${REMPARTS}" | while IFS= read -r REMPART; do + # Find the Last Number + PARTNR="" + for (( i=0; i<${#REMPART}; i++ )); do + CHAR="${REMPART:$i:1}" + if [[ "${CHAR}" =~ [0-9] ]]; then + PARTNR+="${CHAR}" # Append if it's a digit + else + PARTNR="" # Reset if a non-digit is encountered + fi + done + echo "${SYSDRIVE}: Part ${PARTNR}" + blkid /dev/${REMPART} + if [ $? -eq 0 ]; then + parted ${SYSDRIVE} rm ${PARTNR} + fi + done +fi +sync diff --git a/ks_base_profiles/kde_fullsetup.cfg b/ks_base_profiles/kde_fullsetup.cfg new file mode 100644 index 0000000..07791bb --- /dev/null +++ b/ks_base_profiles/kde_fullsetup.cfg @@ -0,0 +1,63 @@ +# Generated by Anaconda 43.44 + +%pre +/bin/sh /mnt/tmp/ks_base_profiles/basic_pre_script.inc +%end + +# Keyboard layouts +keyboard --vckeymap=de-nodeadkeys --xlayouts='de (nodeadkeys)' +# System language +lang de_DE.UTF-8 + +%packages +@^kde-desktop-environment +@admin-tools +@development-tools +@domain-client +@editors +@firefox +@kde-apps +@kde-desktop +@kde-media +@kde-spin-initial-setup +@libreoffice +@office +@sound-and-video +@system-tools +@vlc + +%end + +# System authorization information +authselect enable-feature with-fingerprint + +# Run the Setup Agent on first boot +firstboot --enable + +# Generated using Blivet version 3.12.1 +ignoredisk --only-use=nvme0n1 +# Partition clearing information +clearpart --none --initlabel +# Disk partitioning information +part /boot/efi --fstype="efi" --ondisk=nvme0n1 --size=600 --fsoptions="umask=0077,shortname=winnt" +#part /sys_config --fstype="ext4" --noformat --onpart=UUID=3f9837da-5a46-4da1-a98b-62a8899e63cb --label=OEMDRV +part /sys_config --fstype="ext4" --noformat --label=OEMDRV +part /boot --fstype="ext4" --ondisk=nvme0n1 --size=2048 +#part btrfs.115 --fstype="btrfs" --ondisk=nvme0n1 --size=485249 +# Make the Install have 100GB at the beginning +part btrfs.115 --fstype="btrfs" --ondisk=nvme0n1 --size=100000 +btrfs none --label=fedora_fedora btrfs.115 +btrfs / --subvol --name=root LABEL=fedora_fedora +btrfs /home --subvol --name=home LABEL=fedora_fedora + +timesource --ntp-server=_gateway +# System timezone +timezone Europe/Berlin --utc + +# Root password +# This Password is completely unknown to anyone. After installation, the PC should be Member of Domain and the users may use sudo to become superuser. +rootpw --iscrypted $y$j9T$jpKVkxaFqL6GH6GAgB0Yb/$oc.rfZgnHNlTAIj/boJeI.ZFf1QHvMF7fymZww9bzE3 + +%post +/bin/sh /mnt/tmp/system_setup/setup_system_full.sh install +%end diff --git a/ks_base_profiles/minimal_setup.cfg b/ks_base_profiles/minimal_setup.cfg new file mode 100644 index 0000000..ab8e1e3 --- /dev/null +++ b/ks_base_profiles/minimal_setup.cfg @@ -0,0 +1,50 @@ +# Generated by Anaconda 43.44 +# Keyboard layouts +keyboard --vckeymap=de-nodeadkeys --xlayouts='de (nodeadkeys)' +# System language +lang de_DE.UTF-8 + +%packages +@^kde-desktop-environment +@admin-tools +@development-tools +@domain-client +@editors +@firefox +@kde-apps +@kde-desktop +@kde-media +@kde-spin-initial-setup +@libreoffice +@office +@sound-and-video +@system-tools +@vlc + +%end + +# System authorization information +authselect enable-feature with-fingerprint + +# Run the Setup Agent on first boot +firstboot --enable + +# Generated using Blivet version 3.12.1 +ignoredisk --only-use=nvme0n1 +# Partition clearing information +clearpart --none --initlabel +# Disk partitioning information +part /boot/efi --fstype="efi" --ondisk=nvme0n1 --size=600 --fsoptions="umask=0077,shortname=winnt" +part /sys_config --fstype="ext4" --noformat --onpart=UUID=3f9837da-5a46-4da1-a98b-62a8899e63cb --label=OEMDRV +part /boot --fstype="ext4" --ondisk=nvme0n1 --size=2048 +part btrfs.115 --fstype="btrfs" --ondisk=nvme0n1 --size=485249 +btrfs none --label=fedora_fedora btrfs.115 +btrfs / --subvol --name=root LABEL=fedora_fedora +btrfs /home --subvol --name=home LABEL=fedora_fedora + +timesource --ntp-server=_gateway +# System timezone +timezone Europe/Berlin --utc + +# Root password +rootpw --iscrypted $y$j9T$SYQgSGCnU.FUaT7BKMEI9TKz$nLPf1uHlzpoBCmEndvVRK2FnY67wUY2TyxiMUIufH7A \ No newline at end of file diff --git a/ks_pc_prof/pc-9cdb93ef7c20.cfg b/ks_pc_prof/pc-9cdb93ef7c20.cfg new file mode 100644 index 0000000..9f0cc95 --- /dev/null +++ b/ks_pc_prof/pc-9cdb93ef7c20.cfg @@ -0,0 +1 @@ +%include ../ks_base_profiles/kde_fullsetup.cfg diff --git a/system_setup/create_nc_package_from_sys_config.sh b/system_setup/create_nc_package_from_sys_config.sh new file mode 100755 index 0000000..f62ab63 --- /dev/null +++ b/system_setup/create_nc_package_from_sys_config.sh @@ -0,0 +1,13 @@ +#!/bin/sh +source ./setup_system.conf +mkdir -p ${HOME}/temp +cd ${SYSCONFIGPATH} +tar --exclude='.*' -I 'zstd -9' -cf ${HOME}/temp/sys_config.tar.zst ${SYSCONFIGPATH} +if [ $? -eq 0 ]; then + echo "Archive of ${SYSCONFIGPATH} has been written to ~/temp/sys_config.tar.zst" +else + echo "Some Errors occured, quit" +fi +# TODO +# - up file to NC - is only possible, when setup already has the webdav-token created +# diff --git a/system_setup/logon_script.sh b/system_setup/logon_script.sh new file mode 100755 index 0000000..bc23310 --- /dev/null +++ b/system_setup/logon_script.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +source ./setup_system.conf +source ./setup_system.inc + +echo "User Logon Script" +echo "==================" +echo "" + +#Check and copy Autostart-Entry +#TODO: Check if Desktop is KDE/Plasma and support other Displays +if [ ! -f "${HOME}/.config/autostart/Logon_Script.desktop" ]; then + cp "${SCRIPTPATH}/Logon_Script.desktop" "${HOME}/.config/autostart" +fi + +# Mount the private Directory +if [ ${IPAVAULTUSE} == "true" ]; then + ./mount_ecrypt_home.sh +else + ./mount_nocrypt_home.sh +fi +if [ $? -ne 0 ]; then + echo "Some Error when mounting private Directory, cannot continue. Your Data will not be available." + echo "If you want to redo this script here, execute ${SCRIPTPATH}/${SCRIPTNAME}" + read -n 1 -s -r -p "Press any key to continue" + exit 1 +fi + +#Get WEBDAV TOKEN from Nextcloud +get_nc_token +echo "Successfully obtained Token for User "${DAVTOKEN_USER} + +#SYNC Firefox + Thunderbird Profile +./mozilla_starter.sh firefox sync && ./mozilla_starter.sh thunderbird sync + +#Install additional Software +./sync_client_software.sh +if [ -f "${CLIENT_SOFTWARE_DST}/install.sh" ]; then + /bin/sh "${CLIENT_SOFTWARE_DST}/install.sh" +fi + +#Last, remove unused Flatpak- Runtimes and unused Data +echo "Removing unused Flatpak- Data." +flatpak uninstall --unused -y +flatpak uninstall --delete-data -y +echo "Sucessfully run logon script (Wait 5 seconds)" +sleep 5 + +#read -n 1 -s -r -p "Press any key to continue" +#echo "" +exit 0 diff --git a/system_setup/mount_ecrypt_home.sh b/system_setup/mount_ecrypt_home.sh new file mode 100755 index 0000000..7d05ec7 --- /dev/null +++ b/system_setup/mount_ecrypt_home.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# Will Get IPA- Vault- Entry for local File Encryption and mout the data- Directory in your Home + +# If no IPA-Server is available (e.g. if no internet is available) it will Prompt the User to Enter the Key manually. ATTENTION: The Key MUST NOT BE STORED plaintext on this PC, this would be very insecure! + +# If no encryption has been setup so far, it will create a new wallet and Store the Encryption to the IPA Vault. +source ./setup_system.conf +EXECDIR=$(pwd) + +#Check if Directory is alread mounted +grep ${DECRYPTEDDATADIR} /etc/mtab >/dev/null +if [ $? -eq 0 ]; then + #Directory is already mounted + echo "It looks like the directory is already mounted. Not mounting again." + echo "If you want to unmount it, use: fusermount -u ${DECRYPTEDDATADIR}" + exit 0 +fi + +#Test for connectivity +curl -I https://${SERVERFQDN_IPA}/ipa/session/json >/dev/null 2>&1 +if [ $? -ne 0 ]; then + # Server is offline + if [ -d "${ENCRYPTEDDATADIR}" ]; then + echo "The encrypted Directory ${ENCRYPTEDDATADIR} exists." + read -p "To mount it with your Key, that you noticed when installing that PC, enter the Key now or press CTRL+C to abort: " ENCKEY + echo ${ENCKEY} > /var/tmp/IPAVAULTKEY.txt + else + echo "The Server ${SERVERFQDN_IPA} is offline and no Directory ${ENCRYPTEDDATADIR} exists. Cannot continue." + echo "Please check your Connection/Server and retry." + exit 1 + fi +else + # Server is online + #Get the Token from IPA + echo Getting the Vault ${IPAVAULTNAME} + ipa vault-retrieve ${IPAVAULTNAME} --out /var/tmp/IPAVAULTKEY.txt >/dev/null #TODO: Instead of /var/tmp use tmpfs for more security + if [ $? -ne 0 ]; then + echo "No Key found." + fi + if [ $? -ne 0 ]; then + echo "No Key found. Will try to Setup a new one." + ENCKEY=$( openssl rand -base64 24 ) + echo ${ENCKEY} > /var/tmp/IPAVAULTKEY.txt + ipa vault-add "${IPAVAULTNAME}" --desc "Key for Fileencrytption of ${HOSTNM}" --type=standard + if [ $? -eq 0 ]; then + ipa vault-archive "${IPAVAULTNAME}" --in /var/tmp/IPAVAULTKEY.txt + fi + if [ $? -eq 0 ]; then + echo + echo "Your Key has been sucessfully stored to the Vault ${IPAVAULTNAME}" + echo + echo "The Value is: ${ENCKEY}" + echo + echo "PLEASE NOTE THAT KEY IN A SECRET PLACE NOW !!!" + echo + echo "Without that Key and in case, that the IPA- Vault is not accassible any more, all private Data will be lost!" + echo + read -n 1 -s -r -p "Press any key AFTER YOU WROTE YOUR KEY DOWN to continue" + echo + else + echo "Failed to create the Vault. Please check the Errors and try again." + fi + else + ENCKEY=$( cat /var/tmp/IPAVAULTKEY.txt ) +# echo "The Key is: ${ENCKEY}" + fi +fi +if [ "${ENCKEY}." == "." ]; then + echo "Some Error while fetching your Credentials. This should not happen. Quit." + rm /var/tmp/IPAVAULTKEY.txt + exit 2 +fi + +#Setup and use encrypted filesystem +if [ ! -d "${DECRYPTEDDATADIR}" ]; then + #Key has been obtained, but no Directory was created till know + echo "First Setup of encryption: Creating new Directories now" + mkdir -p ${ENCRYPTEDDATADIR} ${DECRYPTEDDATADIR} ${HOME}/.config/gocryptfs + gocryptfs -init -passfile /var/tmp/IPAVAULTKEY.txt -config ${HOME}/.config/gocryptfs/gocryptfs.conf ${ENCRYPTEDDATADIR} >/dev/null +fi +gocryptfs -noprealloc -passfile /var/tmp/IPAVAULTKEY.txt -config ${HOME}/.config/gocryptfs/gocryptfs.conf ${ENCRYPTEDDATADIR} ${DECRYPTEDDATADIR} >/dev/null +RETVAL=$? +rm /var/tmp/IPAVAULTKEY.txt +cd ${EXECDIR} +if [ ${RETVAL} -eq 0 ]; then + echo "Sucessfully mounted encrypted private Directory ${DECRYPTEDDATADIR}" + exit 0 +else + echo "Errorcode ${RETAVAL}" + exit 1 +fi diff --git a/system_setup/mount_nocrypt_home.sh b/system_setup/mount_nocrypt_home.sh new file mode 100755 index 0000000..906ee73 --- /dev/null +++ b/system_setup/mount_nocrypt_home.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# 30.12.2025 - Currently, the basic Encryption- System of FreeIPA is NOT WORKING due to failing KRA- Install at FreeIPA +# I created an Issue for that: https://github.com/dogtagpki/pki/issues/5242 +# So we will skip encryption completely! + +source ./setup_system.conf +EXECDIR=$(pwd) + +#Check if Directory is alread mounted +grep ${DECRYPTEDDATADIR} /etc/mtab >/dev/null +if [ $? -eq 0 ]; then + #Directory is already mounted + echo "It looks like the directory is already mounted. Not mounting again." + exit 0 +fi + +#Setup and use encrypted filesystem +if [ ! -d "${DECRYPTEDDATADIR}" ]; then + #Key has been obtained, but no Directory was created till know + echo "First Setup of encryption: Creating new Directories now" + mkdir -p ${DECRYPTEDDATADIR} + if [ $? -eq 0 ]; then + echo "Sucessfully mounted encrypted private Directory ${DECRYPTEDDATADIR}" + exit 0 + else + echo "Errorcode ${RETAVAL}" + exit 1 + fi +fi diff --git a/system_setup/mozilla_starter.sh b/system_setup/mozilla_starter.sh new file mode 100755 index 0000000..dfaba67 --- /dev/null +++ b/system_setup/mozilla_starter.sh @@ -0,0 +1,102 @@ +#!/bin/sh +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +source ./setup_system.conf +source ./setup_system.inc + +#Lokal Vars +LOGFILE="${TEMPDIR}/${SCRIPTNAME}.log" + +#Check or get Token +if [ "${DAVTOKEN_USER}." == "." ]; then + get_nc_token +fi + +#Parametercheck: +if [ "${1}." == "." ]; then + echo "ERROR: Parameter 1 missing." + BREAK_ERROR=1 +elif [ ${1} == 'firefox' ]; then + REMOTE_PATH=${PROFILE_FIREFOX_SRC} + PROFILE_PATH=${PROFILE_FIREFOX_DST} + if [ "${2}." == 'run.' ]; then + RUNCMD="/usr/bin/firefox --profile ${PROFILE_FIREFOX_DST}" + elif [ "${2}." == 'sync.' ]; then + RUNCMD="" + else + RUNCMD="" + echo "ERROR: Parameter 2 wrong" + BREAK_ERROR=1 + fi +elif [ ${1} == 'thunderbird' ]; then + REMOTE_PATH=${PROFILE_TB_SRC} + PROFILE_PATH=${PROFILE_TB_DST} + if [ "${2}." == 'run.' ]; then + RUNCMD="/usr/bin/thunderbird -profile ${PROFILE_TB_DST}" + elif [ "${2}." == 'sync.' ]; then + RUNCMD="" + else + RUNCMD="" + echo "ERROR: Parameter 2 wrong" + BREAK_ERROR=1 + fi +else + echo "Error: First Parameter wrong" + BREAK_ERROR=1 +fi +if [[ ${BREAK_ERROR} == 1 ]]; then + echo "Call: ${SCRIPTNAME} [firefox | thunderbird] [run | sync]" + exit 1 +fi + +echo "Synchronise profile" +# optional: -s = silentmodus +SYNCCMD="/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=nextcloudcmd com.nextcloud.desktopclient.nextcloud -h -u ${DAVTOKEN_USER} -p ${DAVTOKEN_PASS} --path ${REMOTE_PATH} ${PROFILE_PATH} https://${SERVERFQDN_NC}" +SYNCCMD_HIDDENPW=$( echo "${SYNCCMD/${DAVTOKEN_PASS}/***HIDDEN***}" ) +echo "Exec: ${SYNCCMD_HIDDENPW}" +mkdir -p ${TEMPDIR} +echo "Mozilla Starter" > ${LOGFILE} +echo "===============" >> ${LOGFILE} +date >> ${LOGFILE} +echo "Parameters: $@" >> ${LOGFILE} +echo ${SYNCCMD_HIDDENPW} >> ${LOGFILE} +echo "" >> ${LOGFILE} +mkdir -p ${PROFILE_PATH} +${SYNCCMD} >> ${LOGFILE} 2>&1 +if [[ $? -ne 0 ]]; then + echo "Error in sync:" + echo "****" + cat ${LOGFILE} + echo "****" + echo "" + echo "Please check if your Token is setup right and for the Output" + read -n 1 -s -r -p "Press any key to continue" + echo "" + exit 1 +fi + +#Execute +if [ "${RUNCMD}." != "." ]; then + echo "OK. Starting ${1}..." + ${RUNCMD} && echo "${1} ended successfully. Please wait for the Profile to sync." + if [[ $? -ne 0 ]]; then + echo "****" + echo "" + echo "Error running ${1}, not syncing Profile!" + read -n 1 -s -r -p "Press any key to continue" + echo "" + exit 2 + fi + sleep 5 + ${SYNCCMD} >> ${LOGFILE} 2>&1 + if [[ $? -ne 0 ]]; then + echo "****" + echo "" + echo "Error syncing ${SYNCCMD_HIDDENPW} - check Logfile ${LOGFILE}!" + read -n 1 -s -r -p "Press any key to continue" + echo "" + exit 3 + fi +fi +echo "Sucessfully synced. Quit." diff --git a/system_setup/pack_skel.sh b/system_setup/pack_skel.sh new file mode 100755 index 0000000..314c0aa --- /dev/null +++ b/system_setup/pack_skel.sh @@ -0,0 +1,22 @@ +#!/bin/bash +source ./setup_system.conf +mv skel.tar.zst backup_skel.tar.zst +if [ $? -eq 0 ]; then + echo "Old Archive renamed to backup_skel.tar.zst" +else + echo "Some Errors occured, cannot continue." + exit 1 +fi +tar -I 'zstd -9' -cf skel.tar.zst skel +if [ $? -eq 0 ]; then + echo "Archive skel.tar.zst has been created" + echo "You should now remove skel- Folder here" +else + echo "Some Errors occured, quit" + exit 1 +fi +rm backup_skel.tar.zst +echo "Old Archive deleted" +# TODO +# - up file to NC - is only possible, when setup already has the webdav-token created +# diff --git a/system_setup/setup_skel.sh b/system_setup/setup_skel.sh new file mode 100755 index 0000000..62c82f0 --- /dev/null +++ b/system_setup/setup_skel.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Replaces /etc/skel with the contents of skel.tar.zst +source ./setup_system.conf +EXECDIR=$(pwd) +SRCFILE="${SYSCONFIGPATH}/system_setup/skel.tar.zst" + +cd /etc +sudo rm -f -r /etc/skel +sudo tar -xf ${SRCFILE} +if [ $? -eq 0 ]; then + echo "Sucessfully wrote skel new" + sudo chown -R root:root /etc/skel + sudo setfacl -R -m u::rwX,g::rX,o::rX /etc/skel +else + echo "Something went wrong, please check Output" +fi +cd ${EXECDIR} + diff --git a/system_setup/setup_system.conf b/system_setup/setup_system.conf new file mode 100644 index 0000000..f1cc4cc --- /dev/null +++ b/system_setup/setup_system.conf @@ -0,0 +1,61 @@ +# Include for System Settings +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +TLDOMAIN=obel1x.de +DOMAIN=clients.${TLDOMAIN} +SERVERFQDN_IPA=ipa.${TLDOMAIN} # Needs to be the IPA- Server +SERVERFQDN_NC=nextcloud.${TLDOMAIN} +SYSCONFIGPATH="/sys_config" +INSTALLDOCS="https://dokuwiki.obel1x.de/content:serverbasics" + +# Method to determine Unique Hostname / FQDN of the Client. May be replaced by your needs +if [ "$EUID" -eq 0 ]; then + HOSTNM="pc-$( dmidecode -t system | grep -i 'UUID' | sed 's/UUID: //' | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z]*//g' | xargs|tail -c 13)" +else + HOSTNM=$( hostname -s ) +fi +FQDN=${HOSTNM}.${DOMAIN} + +#Secure File Encryption +#Needs a running KRA- Service on FreeIPA +# Set to "true" to use Encryption via IPAVAULT - OTHERWISE YOUR FILES WILL NOT BE ENCRYPTED +IPAVAULTUSE="false" +# Vaultname - can be any Name +IPAVAULTNAME="CLIENT_FILEENCRYPTION_"${HOSTNM} + +#This if the Path, that will be encryptet at system logon +DECRYPTEDDATADIR="${HOME}/data" # Decrypted Dir to work for the User +ENCRYPTEDDATADIR="${HOME}/.data" # Contains the encrypted Data + +#Important Files +DAVTOKENFILENAME="${DECRYPTEDDATADIR}/WEBDAVTOKEN" + +#Additional Client-Software- Repository-Folder (Shared Folder / Systemwide) +CLIENT_SOFTWARE_DST="/opt/client_software" # Optional. If you don't have a Folder that should always be synced, leave this empty +CLIENT_SOFTWARE_SRC="/Shared/sw_geteilt/client_software" + +#Firefox Profiles +PROFILE_FIREFOX_SRC="mozilla_profiles/firefox" +PROFILE_FIREFOX_DST="${DECRYPTEDDATADIR}/firefox" + +#Thunderbird Profiles +PROFILE_TB_SRC="mozilla_profiles/thunderbird" +PROFILE_TB_DST="${DECRYPTEDDATADIR}/thunderbird" + +#First run Service Name +FIRSTRUN_SERVICENAME="setup-system.service" +FIRSTRUN_SCRIPTPATH="/usr/lib/systemd/system" + +#Basic commons not needing change +CDATEC8=$(date '+%Y%m%d') # Date 8 Characters long: YYYYMMDD +CTIMEC6=$(date '+%H%M%S') # Time 6 Chars: HHMMSS + +#Basic runtime-Vars +EXECDIR=$(pwd) +SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +if [ ${SCRIPTPATH::2} == "//" ]; then + SCRIPTPATH=${SCRIPTPATH:1} +fi +SCRIPTNAME=$(basename "$0") +TEMPDIR="${HOME}/temp/system_setup" diff --git a/system_setup/setup_system.inc b/system_setup/setup_system.inc new file mode 100644 index 0000000..97df29d --- /dev/null +++ b/system_setup/setup_system.inc @@ -0,0 +1,111 @@ +# Includes for System Setup +# +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# + +#Check if we are root +check_root() +{ + if [ "$EUID" -ne 0 ] + then echo "Please run as root" + return 1 + fi + return 0 +} + +#Check if the Data- Directory is encrypted +check_data_isecrypted() { + CHECKRES=$( cat /etc/mtab | grep "${DECRYPTEDDATADIR}" | grep "fuse.gocryptfs" ) + if [ "${CHECKRES}." == "." ]; then + return 1 # Error: Directory is not mounted + else + return 0 # Directory is mounted + fi +} + +# Will set variable DAVTOKEN_USER and DAVTOKEN_PASS to the stored value or get a new one +get_nc_token() { + DAVTOKEN_USER="" + DAVTOKEN_PASS="" + + if [ ${IPAVAULTUSE} == "true" ]; then + check_data_isecrypted + if [ $? -ne 0 ]; then + echo "Data Directory is not encrypted. Please mount it first." + return 1 + fi + fi + + if [ ! -f ${DAVTOKENFILENAME} ]; then + # Directory is ok, but no Tokenfile was found, need to generate a new one + REQJSON=$( curl -s -A "WEBDAV:${HOSTNM}" -X POST "https://${SERVERFQDN_NC}/index.php/login/v2" ) + # echo "JSON is:" + # echo "${REQJSON}" + + REQTOKEN=$( echo "${REQJSON}" | grep -oP '(?<="token":")[^"]+(?=")' ) + REQURL=$( echo "${REQJSON}" | grep -oP '(?<="login":")[^"]+(?=")' ) + /usr/bin/firefox "${REQURL}" & + + for i in {1..200} + do + echo "Waiting 6 seconds" + sleep 6 + echo -n "Poll Number ${i}..." + POLLJSON=$( curl -s -X POST "https://${SERVERFQDN_NC}/login/v2/poll" -d "token=${REQTOKEN}" ) + if [[ "${POLLJSON}" == *"appPassword"* ]]; then + echo "${POLLJSON}" > ${DAVTOKENFILENAME} + echo "found token. Token has been written to ${DAVTOKENFILENAME}" + break + else + echo "failed" + fi + done + else + # Tokenfile found, reading it + POLLJSON=$( cat ${DAVTOKENFILENAME} ) + fi + DAVTOKEN_USER=$( echo "${POLLJSON}" | grep -oP '(?<="loginName":")[^"]+(?=")' ) + DAVTOKEN_PASS=$( echo "${POLLJSON}" | grep -oP '(?<="appPassword":")[^"]+(?=")' ) +} + +# Custom `select` implementation that allows *empty* input. +# Pass the choices as individual arguments. +# Output is the chosen item, or "", if the user just pressed ENTER. +# Example: +# choice=$(selectWithDefault 'one' 'two' 'three') +selectWithDefault() { + + local item i=0 numItems=$# + + # Print numbered menu items, based on the arguments passed. + for item; do # Short for: for item in "$@"; do + printf '%s\n' "$((++i))) $item" + done >&2 # Print to stderr, as `select` does. + + # Prompt the user for the index of the desired item. + while :; do + printf %s "${PS3-#? }" >&2 # Print the prompt string to stderr, as `select` does. + read -r index + # Make sure that the input is either empty or that a valid index was entered. + [[ -z $index ]] && break # empty input + (( index >= 1 && index <= numItems )) 2>/dev/null || { echo "Invalid selection. Please try again." >&2; continue; } + break + done + + # Output the selected item, if any. + [[ -n $index ]] && printf %s "${@: index:1}" + +} +selectExample() { +# Print the prompt message and call the custom select function. +echo "Include audits (default is 'Nope')?" +optionsAudits=('Yep' 'Nope') +opt=$(selectWithDefault "${optionsAudits[@]}") + +# Process the selected item. +case $opt in +'Yep') includeAudits=true; ;; +''|'Nope') includeAudits=false; ;; # $opt is '' if the user just pressed ENTER +esac +} diff --git a/system_setup/setup_system_full.sh b/system_setup/setup_system_full.sh new file mode 100755 index 0000000..a5ebc93 --- /dev/null +++ b/system_setup/setup_system_full.sh @@ -0,0 +1,229 @@ +#!/bin/sh +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# This Script has some functions: +# +# A. First setup of PC +# Shall run after install of some new Fedora- installation -> in %post Section of Kickstart +# Attention: Kickstart-Installations ARE NON INTERACTIVE ! +# When this script is executed without knowledge, it can destroy your Installation ! + +# Basic concepts: +# First, you need some other tool, to make a new PC include the OEM- Partition on your drive (refer to the Docs) +# The you can run a Installation of Fedora using the Everything Netinstaller or Server DVD- ISO written to USB +# The Kickstart will setup your PC, while clearing unused Partitions will be handled by pre- Section of Kickstart +# In the post-section this script will be called, to setup your PC and to have the pc getting you in the Domain on first boot +# At the first logon, the script is called by your Window- Manager again to fully setup your profile + +# TODO +# - Make it ask for all needed Parameters and store them to the System if needed +# - Make it check for what to do each time so that it can be called every startup +# - Make it callable from anakondas kickstart post- script to setup system at first run +# (kickstart post-script must be non-interactive, while first start with systemd can have a service bounf to tty for getting user-input too) +# - Detect System Environement and make User-Logon- Setup Start after first Logon +# Supported: Cinnamon, KDE +# - Not needed: Import Firefox-Cert from IPA automatically at first run to system -> Somehow this is not needed any more, firefox will work from scratch! + +# TODO Additionally +# Build a bootstick with kickstarter-configuration +# Needs the SHARE_ID where to get the installarchive from Nextcloud +# when creating the Stick + +# TODO write a doc! + +#Load Sytem Settings +source $(dirname "$0")/setup_system.conf +source $(dirname "$0")/setup_system.inc +# TODO +# Install System settings to installed system +# read system settings from that file + +##Step 1 - Install at System boot +firstrun_prepare() +{ +#Checking Service +FIRSTRUN_SERVICESTATUS=$( systemctl is-enabled ${FIRSTRUN_SERVICENAME} ) +echo "Current Service Status of ${FIRSTRUN_SERVICENAME} is ${FIRSTRUN_SERVICESTATUS}" +if [ ${FIRSTRUN_SERVICESTATUS} != "enabled" ]; then + echo "Installing Service at ${FIRSTRUN_SCRIPTPATH}/${FIRSTRUN_SERVICENAME}" +( cat </dev/null + sudo chmod go+r ${FIRSTRUN_SCRIPTPATH}/${FIRSTRUN_SERVICENAME} + echo "Activating Service" + sudo systemctl daemon-reload + sudo systemctl enable ${FIRSTRUN_SERVICENAME} +fi +} + +firstrun_remove() +{ + sudo systemctl disable ${FIRSTRUN_SERVICENAME} && sudo rm ${FIRSTRUN_SCRIPTPATH}/${FIRSTRUN_SERVICENAME} +} + +#Do updates +upgrade_interactive() +{ +check_root +dnf upgrade --refresh +#Check if restart is needed +dnf needs-restarting +if [ $? -eq 0 ]; then + echo "No Restart required." +else + echo "Restart is required, please do so now and rerun this script after reboot." + read -n 1 -s -r -p "If you do not want to restart, please hit CTRL+C now. Any other key to continue." + echo +# echo "If you do not want to restart, please hit CTRL+C in the next 10 seconds" +# for i in {10..01} +# do +# echo -ne "\r$i" +# sleep 1 +# done + shutdown -r now +fi +} + +#Software needed and additional stuff +install_sw() +{ +check_root +yum install -y mc htop ipa-client thunderbird pip npm pykickstart gocryptfs mediawriter +flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo +flatpak install -y --reinstall flathub com.nextcloud.desktopclient.nextcloud + +#Set default Umask 0077 +sudo cp -f /etc/login.defs /etc/login.defs_backup_${CDATEC8}_${CTIMEC6} +( sed 's/^UMASK.*022$/UMASK\t077/' /etc/login.defs | sudo tee /etc/login.defs ) >/dev/null +} + +ipa_register_host() +{ +#Integrate this PC into Domain +chvt 8 +#Check if IPA is already Configured +echo "Checking for existing IPA- Setup." +if ( grep -q "${FQDN}" /etc/ipa/default.conf ); then + echo "IPA is already installed, skipping setup." + return 0 +fi +echo "IPA not jet installed, doing Setup." +check_root +#Serialnr of this device +echo "This PC is called ${FQDN} and will join Domain ${DOMAIN}" +#Always set determined hostname - see setup_system.conf +hostnamectl set-hostname ${HOSTNM} +#Check, if hostname is resolvable to this host - if not, add entry to /etc/hosts +if ! grep -q ${FQDN} "/etc/hosts"; then + echo "Adding Host ${FQDN} to /etc/hosts" + echo "">>"/etc/hosts" + echo "127.0.0.1 ${FQDN} ${HOSTNM}">>"/etc/hosts" +fi +echo +echo -n "Please Enter your Domain- Userid: " +read IPAUSERID +echo -n "Please Enter your Domain- Password: " +read -s IPAPASSWD +INSTCMD="ipa-client-install -U --mkhomedir --force-join --no-ntp --principal=${IPAUSERID} --domain=${DOMAIN} --server=${SERVERFQDN_IPA} --hostname=${FQDN} -w ${IPAPASSWD}" +echo ${INSTCMD} +${INSTCMD} +if [ $? -ne 0 ]; then + echo "Some Error. Please check what went wrong and redo." + return 1 +fi +echo "The PC was integrated into the Domain. You should now be able to Logon with tha User. If not, restart SSSD- Service and check the Logs." +echo "" +echo "ADVISE: for the First Logon, you may use Console (Using e.g. CONTROL+ALT+F3) - as maybe you will be prompted for Changing your Password there" +echo "which may not work on graphical logon. After that works, use CONTROL+ALT+F2 (or F7) to get back to the graphical logon." +echo "" +read -n 1 -s -r -p "Press any key to continue." +echo "" +} + +test_tty() +{ + #Use TTY3 and show it + chvt 8 + whoami + read -r -p "This is a Test. Please enter some String: " SOMESTRING + echo "The String was ${SOMESTRING}" + read -n 1 -s -r -p "Press any key to continue" + echo "" + echo "========== END ========" +} + +prepare_skel() +{ +check_root +#Copy and extrakt Skel-Archive +#Include: Autostart for Getting WEB-DAV-Token if not there +#+An empty Firefox Profile - already integrated into domain with one single Startup-Page: Get Token +# https://nextcloud.obel1x.de/settings/user/security +# +#File was created with from Draft-Folder and then transferred to NC +#tar -I 'zstd -9' -cf system_setup.tar.zst ~/system_setup +# +./setup_skel.sh +} + +### MAIN +case $1 in + 'install') + echo "Mode: Install" + install_sw + prepare_skel +# firstrun_prepare + ;; + 'firstrun_prepare') + firstrun_prepare + ;; + 'firstrun_remove') + firstrun_remove + ;; + 'firstrun_run') +# test_tty + ipa_register_host + echo "========== END FIRSTRUN-SERVICE ========" + ;; + 'logon') + upgrade + ;; +# ''|'something) botherpossible=true; ;; + *) + echo "Wrong first Parameter. Choose from: install,logon,firstrun_prepare,firstrun_remove,firstrun_run" + echo "PLEASE DON'T USE THIS SCRIPT WITHOUT YOU KNOW WHAT YOU ARE DOING!" + echo + echo "ATTENTION: THIS SCRIPT MAY RENDER YOUR PC USELESS WITHOUT ASKING IF USED WRONG !!!" + exit 1 + ;; +esac + +#End +exit 0 + +#temp +read -n 1 -s -r -p "Press any key to continue" diff --git a/system_setup/skel.tar.zst b/system_setup/skel.tar.zst new file mode 100644 index 0000000..66c873b Binary files /dev/null and b/system_setup/skel.tar.zst differ diff --git a/system_setup/sync_client_software.sh b/system_setup/sync_client_software.sh new file mode 100755 index 0000000..454d7c2 --- /dev/null +++ b/system_setup/sync_client_software.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# SPDX-FileCopyrightText: Daniel Pätzold +# SPDX-License-Identifier: AGPL-3.0-or-later +# +source ./setup_system.conf +source ./setup_system.inc + +#Lokal Vars +LOGFILE="${TEMPDIR}/${SCRIPTNAME}.log" + +#Check if Repository is defined +if [ "${CLIENT_SOFTWARE_DST}." == "." ]; then + echo "No central softwarerepository defined (CLIENT_SOFTWARE_DST). Skipping sync." + exit 0 +fi + +echo "Syncing central softwarerepository." + +#Check or get Token +if [ "${DAVTOKEN_USER}." == "." ]; then + get_nc_token +fi + +# Create Directory if not existent +if [ ! -d ${CLIENT_SOFTWARE_DST} ]; then + sudo mkdir ${CLIENT_SOFTWARE_DST} + sudo chmod o=rwx ${CLIENT_SOFTWARE_DST} +fi +#Sync Files +SYNCCMD="/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=nextcloudcmd com.nextcloud.desktopclient.nextcloud -h -u ${DAVTOKEN_USER} -p ${DAVTOKEN_PASS} --path ${CLIENT_SOFTWARE_SRC} ${CLIENT_SOFTWARE_DST} https://${SERVERFQDN_NC}" +SYNCCMD_HIDDENPW=$( echo "${SYNCCMD/${DAVTOKEN_PASS}/***HIDDEN***}" ) +echo "Exec: ${SYNCCMD_HIDDENPW}" +mkdir -p ${TEMPDIR} +echo "Sync Client Software" > ${LOGFILE} +echo "====================" >> ${LOGFILE} +date >> ${LOGFILE} +echo ${SYNCCMD_HIDDENPW} >> ${LOGFILE} +echo "" >> ${LOGFILE} +${SYNCCMD} >> ${LOGFILE} 2>&1 +if [[ $? -ne 0 ]]; then + echo "Error in sync:" + echo "****" + cat ${LOGFILE} + echo "****" + echo "" + echo "Please check if your Token is setup right and for the above Output" + read -n 1 -s -r -p "Press any key to continue" + echo "" + exit 1 +fi +if [ -f "${CLIENT_SOFTWARE_DST}/install.sh" ]; then + chmod ugo+x "${CLIENT_SOFTWARE_DST}/install.sh" +fi +echo "Sucessfully synced. Quit."