Created
October 7, 2024 05:39
-
-
Save guihkx/ba87152d6d15bf8cfb4d97bb268703c4 to your computer and use it in GitHub Desktop.
Sets up Warsaw (internet banking crap) and Firefox using systemd-nspawn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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