Curl-proxy / wget-proxy scripts in Templates so users can add GPG distro keys linked to added external repositories

Here comes the PoC.

Config changes

/etc/profile.d/download-wrapper-aliases.sh

alias curl="curl-wrapper"
alias wget="wget-wrapper"
# sudo will not use aliases unless https://linuxhandbook.com/run-alias-as-sudo/
alias sudo="sudo "

Append the following under /etc/bash.bashrc

#/etc/profile.d scripts are not loaded in interactive non-login shells (https://linuxhandbook.com/run-alias-as-sudo/)
if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

Scripts

/usr/bin/wget-wrapper

#!/bin/env bash
# wget-wrapper script around wget
#  Goal is to give a chance to the user of knowing what is going to happen next, educate and explain what is different in Templates
#
# This wrapper script detects if the wget command was ran in a TemplateVM (Which by default is prohibited)
#   In case the Template is trusted (No Network assigned), it warns the user to call wget-proxy instead and exits
#   In case the Template has network assigned, it warns the user the template should not be trusted anymore and proceeds in 3 seconds
#   In case we are not in a template, just add a warning and proceed with original wget call
# 
#Depends on : 
# this file being deployed in OS searchable path (eg: /usr/bin)
# alias being previously defined on the system prior of running wget. 
#   To test this:
#     alias wget="wget-wrapper"
#   To permanently define the alias for a user, add the alias in ~/.bashrc


if [ "$(qubesdb-read /type)" == "TemplateVM" ]; then 
	if ! $(qubesdb-read /qubes-gateway > /dev/null 2>&1); then 
		echo "You attempted to download a file with wget in a Template without direct internet access. (no network assigned)." >&2
		echo "" >&2
		echo "The attempted downloading command was: wget $@" >&2
		echo "" >&2
		echo "You either:" >&2 
		echo " 1- need to replace wget by wget-proxy in previous attempted shell command line (Recommended)." >&2
		echo " 2- assign a Networking qube to this Template which should consequently be less trusted. (Untrusted)." >&2
		exit 1
	else
		echo "You attempted to download a file with wget in a Template WITH DIRECT INTERNET ACCESS. (network assigned)." >&2
		echo "" >&2
		echo "The attempted downloading command was: wget $@" >&2
		echo "" >&2
		echo "Continuing in 3 seconds... Type CTRL+C to prevent the download now!" >&2
		sleep 3
		/usr/bin/wget "$@"
	fi
else
	echo "wget download attempt not in TemplateVM. Continuing..." >&2
	/usr/bin/wget "$@"
fi

/usr/bin/curl-wrapper

#!/bin/env bash
# curl-wrapper script around curl
#  Goal is to give a chance to the user of knowing what is going to happen next, educate and explain what is different in Templates
#
# This wrapper script detects if the curl command was ran in a TemplateVM (Which by default is prohibited)
#   In case the Template is trusted (No Network assigned), it warns the user to call curl-proxy instead and exits
#   In case the Template has network assigned, it warns the user the template should not be trusted anymore and proceeds in 3 seconds
#   In case we are not in a template, just add a warning and proceed with original curl call
# 
#Depends on : 
# this file being deployed in OS searchable path (eg: /usr/bin)
# alias being previously defined on the system prior of running curl. 
#   To test this:
#     alias curl="curl-wrapper"
#   To permanently define the alias for a user, add the alias in ~/.bashrc


if [ "$(qubesdb-read /type)" == "TemplateVM" ]; then 
	if ! $(qubesdb-read /qubes-gateway > /dev/null 2>&1); then 
		echo "You attempted to download a file with curl in a Template without direct internet access. (no network assigned)." >&2
		echo "" >&2
		echo "The attempted downloading command was: curl $@" >&2
		echo "" >&2
		echo "You either:" >&2 
		echo " 1- need to replace curl by curl-proxy in previous attempted shell command line (Recommended)." >&2
		echo " 2- assign a Networking qube to this Template which should consequently be less trusted. (Untrusted)." >&2
		exit 1
	else
		echo "You attempted to download a file with curl in a Template WITH DIRECT INTERNET ACCESS. (network assigned)." >&2
		echo "" >&2
		echo "The attempted downloading command was: curl $@" >&2
		echo "" >&2
		echo "Continuing in 3 seconds... Type CTRL+C to prevent the download now!" >&2
		sleep 3
		/usr/bin/curl "$@"
	fi
else
	echo "curl download attempt not in TemplateVM. Continuing..." >&2
	/usr/bin/curl "$@"
fi

/usr/bin/curl-proxy

#!/bin/env bash
curl --proxy http://127.0.0.1:8082/ --tlsv1.2 --proto =https --max-time 180 $@

/usr/bin/wget-proxy

#!/bin/env bash
https_proxy=http://127.0.0.1:8082/ http_proxy=http://127.0.0.1:8082/ wget --secure-protocol=TLSv1_2 --timeout=180 "$@"

Testing instructions

  1. Clone Template
  2. Deploy scripts
  3. Apply system wide changes above related to aliases (Should probably file a bug report @marmarek ?)
  4. Reproduce results
  5. Assign network to Template. Reproduce results
  6. Create qube based on previous cloned template. Reproduce results.

No network assigned to cloned Template use case:

user@debian-11:~$ alias
alias curl='curl-wrapper'
alias ls='ls --color=auto'
alias sudo='sudo '
alias wget='wget-wrapper'

Non-Networked Template: gpg key download of signal from user

user@debian-11:~$ wget -O- https://updates.signal.org/desktop/apt/keys.asc 
You attempted to download a file with wget in a Template without direct internet access. (no network assigned).

The attempted downloading command was: wget -O- https://updates.signal.org/desktop/apt/keys.asc

You either:
 1- need to replace wget by wget-proxy in previous attempted shell command line (Recommended).
 2- assign a Networking qube to this Template which should consequently be less trusted. (Untrusted).

user@debian-11:~$ wget-proxy -O- https://updates.signal.org/desktop/apt/keys.asc | gpg --dearmor > signal-desktop-keyring.gpg
--2022-04-21 10:52:38--  https://updates.signal.org/desktop/apt/keys.asc
Connecting to 127.0.0.1:8082... connected.
Proxy request sent, awaiting response... 200 OK
Length: 3090 (3.0K) [application/pgp-signature]
Saving to: ‘STDOUT’

-                                     100%[=======================================================================>]   3.02K  18.1KB/s    in 0.2s    

2022-04-21 10:52:41 (18.1 KB/s) - written to stdout [3090/3090]

Non-Networked Template: gpg key download of session (sudo curl call per instructions) use case:

user@debian-11:~$ alias
alias curl='curl-wrapper'
alias ls='ls --color=auto'
alias sudo='sudo '
alias wget='wget-wrapper'

user@debian-11:~$ sudo curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg
You attempted to download a file with curl in a Template without direct internet access. (no network assigned).

The attempted downloading command was: curl /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg

You either:
 1- need to replace curl by curl-proxy in previous attempted shell command line (Recommended).
 2- assign a Networking qube to this Template which should consequently be less trusted. (Untrusted).

user@debian-11:~$ sudo curl-proxy -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg

user@debian-11:~$ ls -al /etc/apt/trusted.gpg.d/oxen.gpg
-rw-r--r-- 1 root root 2213 Apr 21 11:58 /etc/apt/trusted.gpg.d/oxen.gpg

Assigned network to Template use case:

Networked Template: Signal wget use case (normal user)

user@debian-11-networked:~$ wget -O- https://updates.signal.org/desktop/apt/keys.asc | gpg --dearmor > signal-desktop-keyring.gpg
You attempted to download a file with wget in a Template WITH DIRECT INTERNET ACCESS. (network assigned).

The attempted downloading command was: wget -O- https://updates.signal.org/desktop/apt/keys.asc

Continuing in 3 seconds... Type CTRL+C to prevent the download now!
--2022-04-21 12:01:23--  https://updates.signal.org/desktop/apt/keys.asc
Resolving updates.signal.org (updates.signal.org)... 172.64.155.131, 104.18.32.125, 2606:4700:4400::6812:207d, ...
Connecting to updates.signal.org (updates.signal.org)|172.64.155.131|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3090 (3.0K) [application/pgp-signature]
Saving to: ‘STDOUT’

-                   100%[===================>]   3.02K  --.-KB/s    in 0s      

2022-04-21 12:01:23 (13.0 MB/s) - written to stdout [3090/3090]

Networked Template: Session sudo curl use case (runs as root)

user@debian-11-networked:~$ sudo curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg
You attempted to download a file with curl in a Template WITH DIRECT INTERNET ACCESS. (network assigned).

The attempted downloading command was: curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg

Continuing in 3 seconds... Type CTRL+C to prevent the download now!

user@debian-11-networked:~$ ls -al /etc/apt/trusted.gpg.d/oxen.gpg
-rw-r--r-- 1 root root 2213 Apr 21 12:02 /etc/apt/trusted.gpg.d/oxen.gpg

curl and wget direct calls in Networked Templates

user@debian-11-networked:~$ wget
You attempted to download a file with wget in a Template WITH DIRECT INTERNET ACCESS. (network assigned).

The attempted downloading command was: wget 

Continuing in 3 seconds... Type CTRL+C to prevent the download now!
wget: missing URL
Usage: wget [OPTION]... [URL]...

Try `wget --help' for more options.

user@debian-11-networked:~$ curl
You attempted to download a file with curl in a Template WITH DIRECT INTERNET ACCESS. (network assigned).

The attempted downloading command was: curl 

Continuing in 3 seconds... Type CTRL+C to prevent the download now!
curl: try 'curl --help' or 'curl --manual' for more information

Normal Qube depending on that cloned template use case

user@wrapper-test:~$ wget
wget download attempt not in TemplateVM. Continuing...
wget: missing URL
Usage: wget [OPTION]... [URL]...

Try `wget --help' for more options.

user@wrapper-test:~$ curl
curl download attempt not in TemplateVM. Continuing...
curl: try 'curl --help' or 'curl --manual' for more information

Notes

@marmarek @adw @Sven @fsflover @Demi @deeplow : Am I making my point?
@Demi @marmarek: Fell upon two interesting bugs

  1. sudo cannot invoque aliases unless alias sudo="sudo " per How to Run an Alias With Sudo in Linux
  2. /etc/profile.d/* are ignored when using graphical shells (interactive, non-login shells: Why are scripts in /etc/profile.d/ being ignored (system-wide bash aliases)? )

This is why /etc/bash.bashrc was modified to also source /etc/profile.d/*.sh.
@marmarek @demi @fepitre : Qubes Bug/Feature?

Edit: Sorry for all the edits. I’m done now.
Edit2. I’m done for real, sorry. This is why writing documentation is so hard.

2 Likes