Skip to content

Instantly share code, notes, and snippets.

@guihkx
Created October 7, 2024 05:39
Show Gist options
  • Save guihkx/ba87152d6d15bf8cfb4d97bb268703c4 to your computer and use it in GitHub Desktop.
Save guihkx/ba87152d6d15bf8cfb4d97bb268703c4 to your computer and use it in GitHub Desktop.
Sets up Warsaw (internet banking crap) and Firefox using systemd-nspawn
#!/usr/bin/env bash
# Script options that can be overriden via environment variables.
SUDO=${SUDO:-'sudo'}
CONTAINER_NAME=${CONTAINER_NAME:-'debian-warsaw'}
TARGET_DIR=${TARGET_DIR:-"/tmp/${CONTAINER_NAME}"}
NORMAL_USER=${NORMAL_USER:-'user'}
BANK_TEST_PAGE=${BANK_TEST_PAGE:-'https://seg.bb.com.br/home.html'}
##### Do not touch anything below this #####
set -euo pipefail
SCRIPT_NAME=$(basename "${0}")
function msg() {
echo -e "\033[1m[${SCRIPT_NAME}] ${*} \033[0m" >&2
}
function create_dir() {
if [ -w "$(dirname "${1}")" ]; then
mkdir -p "${1}"
else
"${SUDO}" mkdir -p "${1}"
fi
}
function container_running() {
[[ "$(machinectl -q show -P State "${CONTAINER_NAME}" 2>/dev/null)" == 'running' ]] && printf yes || printf no
}
function run_debootstrap() {
# Set up the base system (Debian stable)
# https://wiki.archlinux.org/title/Systemd-nspawn#Create_a_Debian_or_Ubuntu_environment
if [ ! -d "${TARGET_DIR}/usr" ]; then
msg "Setting up Debian stable on directory '${TARGET_DIR}'..."
create_dir "${TARGET_DIR}"
"${SUDO}" debootstrap --include=systemd-container,dbus stable "${TARGET_DIR}" https://cdn-fastly.deb.debian.org/debian
else
msg "Container ${CONTAINER_NAME} seems to be already set up in '${TARGET_DIR}', continuing..."
fi
}
function run_in_container() {
"${SUDO}" systemd-nspawn -q -M "${CONTAINER_NAME}" --hostname "${CONTAINER_NAME}" -D "${TARGET_DIR}" "${@}"
}
apt_lists_populated() {
run_in_container bash -c "[[ -n \"\$(find /var/lib/apt/lists -name \"*_Packages\")\" ]] && printf yes || printf no"
}
function apt_refresh_repos() {
if [[ "$(apt_lists_populated)" == 'no' ]]; then
msg 'Directory "/var/lib/apt/lists" is not populated in container, running "apt update"...'
run_in_container apt update
fi
}
function installed_in_container() {
if [[ "$(container_running)" == 'yes' ]]; then
run_in_booted_up_container_as_root /bin/bash -c "[[ \"\$(dpkg-query --show --showformat='\${db:Status-Status}' -- ${1} 2>/dev/null)\" == 'installed' ]] && printf yes || printf no"
else
run_in_container bash -c "[[ \"\$(dpkg-query --show --showformat='\${db:Status-Status}' -- ${1} 2>/dev/null)\" == 'installed' ]] && printf yes || printf no"
fi
}
function install_if_needed() {
local program_name="${1}"
shift
local to_install=()
for pkg in "${@}"; do
if [[ "$(installed_in_container "${pkg}")" != 'yes' ]]; then
to_install+=("${pkg}")
fi
done
if [ "${#to_install[@]}" -gt 0 ]; then
msg "Installing needed package(s) for ${program_name}: ${to_install[*]}"
if [[ "$(container_running)" == 'yes' ]]; then
run_in_booted_up_container_as_root /usr/bin/apt install -y --no-install-recommends "${to_install[@]}"
else
run_in_container apt install -y --no-install-recommends "${to_install[@]}"
fi
fi
}
function install_fluxbox_wm() {
local pkgs=('fluxbox' 'xterm')
install_if_needed 'Fluxbox' "${pkgs[@]}"
}
function install_firefox() {
local pkgs=('firefox-esr' 'libegl1' 'libgl1' 'libpci3' 'webext-ublock-origin-firefox')
install_if_needed 'Firefox' "${pkgs[@]}"
}
function user_exists() {
run_in_container bash -c "[[ \"\$(getent shadow '${1}' 2>/dev/null)\" =~ ^${1}:! ]] && printf yes || printf no"
}
function add_normal_user() {
if [[ "$(user_exists "${NORMAL_USER}")" == 'no' ]]; then
msg "Adding unprivileged account ('${NORMAL_USER}')..."
run_in_container useradd -m "${NORMAL_USER}" -s /bin/bash
fi
}
function first_boot() {
# We need systemd to be running to be able to install the deb package correctly.
msg 'Booting up the container...'
"${SUDO}" systemd-nspawn -q -b -M "${CONTAINER_NAME}" --hostname "${CONTAINER_NAME}" -D "${TARGET_DIR}" &>/dev/null &
disown
}
function run_in_booted_up_container() {
local user
local env
user="${1}"
shift
if [[ "${1}" =~ ^/ ]]; then
# second argument is an absolute path to a binary
"${SUDO}" machinectl -q shell "${user}@${CONTAINER_NAME}" "${@}"
else
# second argument is an environment variable
env="${1}"
shift
"${SUDO}" machinectl -q -E "${env}" shell "${user}@${CONTAINER_NAME}" "${@}"
fi
}
function run_in_booted_up_container_as_root() {
run_in_booted_up_container root "${@}"
}
function run_in_booted_up_container_as_user() {
run_in_booted_up_container "${NORMAL_USER}" "${@}"
}
function install_warsaw() {
# warsaw uses the certutil tool from the libnss3-tools package
local pkgs=('curl' 'libnss3-tools' 'python3' 'zenity')
local deb_url='https://cloud.gastecnologia.com.br/bb/downloads/ws/warsaw_setup64.deb'
install_if_needed 'Warsaw' "${pkgs[@]}"
if [[ "$(installed_in_container 'warsaw')" == 'no' ]]; then
msg 'Downloading Warsaw...'
run_in_booted_up_container_as_root /usr/bin/curl "${deb_url}" -o /tmp/warsaw.deb
msg 'Installing Warsaw...'
run_in_booted_up_container_as_root /usr/bin/dpkg -i /tmp/warsaw.deb
run_in_booted_up_container_as_root /usr/bin/rm /tmp/warsaw.deb
fi
}
function stop_warsaw_service() {
msg 'Stopping Warsaw service...'
run_in_booted_up_container_as_root /usr/bin/systemctl stop warsaw
}
function apt_clean_cache() {
if [[ "$(run_in_booted_up_container_as_root /usr/bin/du -sB1 /var/cache/apt | cut -f1)" -ne 0 ]]; then
msg 'Running "apt clean"...'
run_in_booted_up_container_as_root /usr/bin/apt clean
fi
}
function run_xephyr() {
if ! pidof -q -- Xephyr; then
msg 'Starting nested X11 server (Xephyr)...'
Xephyr -br -ac -noreset -screen 1400x900 :1 &
disown
fi
}
function is_process_running_in_container() {
run_in_booted_up_container_as_user /usr/bin/bash -c "pidof -q -- ${1} && printf yes || printf no"
}
function run_fluxbox_wm() {
if [[ "$(is_process_running_in_container 'fluxbox')" == 'no' ]]; then
msg 'Starting fluxbox window manager...'
run_in_booted_up_container_as_user 'DISPLAY=:1' /usr/bin/fluxbox &>/dev/null &
disown
fi
}
function start_warsaw_service() {
msg 'Starting Warsaw service...'
run_in_booted_up_container_as_root /usr/bin/systemctl start warsaw
}
function run_firefox() {
if [[ "$(is_process_running_in_container 'firefox-esr')" == 'no' ]]; then
msg 'Starting Firefox... (press Ctrl+C to stop)'
run_in_booted_up_container_as_user 'DISPLAY=:1' /usr/bin/firefox "${BANK_TEST_PAGE}"
fi
}
if [[ "$(container_running)" == 'yes' ]]; then
msg "Warning: Container '${CONTAINER_NAME}' has already booted up."
msg "If you want to run the setup script again, you have to run 'machinectl poweroff ${CONTAINER_NAME}' first."
else
run_debootstrap
apt_refresh_repos
install_fluxbox_wm
install_firefox
add_normal_user
first_boot
while [[ "$(container_running)" == 'no' ]]; do
msg 'Waiting for container to fully boot up...'
sleep 1
done
fi
install_warsaw
apt_clean_cache
stop_warsaw_service
run_xephyr
run_fluxbox_wm
start_warsaw_service
run_firefox
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment