TorBox icon indicating copy to clipboard operation
TorBox copied to clipboard

improve bridge's listing

Open nyxnor opened this issue 4 years ago • 7 comments

This can be useful to activate, deactivate or delete bridges. For now, the code below just displays them:

#!/usr/bin/env bash

torrc="/etc/tor/torrc"

all_bridges="$(sudo grep "Bridge obfs4" "${torrc}")"
#activated_bridges="$(grep "^Bridge obfs4" <<< "${all_bridges}")"

while IFS= read -r line || [ -n "$line" ]; do
  bridge_ip=$(awk '{print $3}' <<< "${line}" )
  bridge_fingerprint=$(awk '{print $4}' <<< "${line}" )
  bridge_list="$(printf "%s\n%s\n%s\n" "${bridge_list}" "${bridge_ip}" "${bridge_fingerprint}")"
done <<< "${all_bridges}"

# shellcheck disable=SC2086
whiptail --menu "Bridges" 20 80 10 ${bridge_list} 3>&1 1>&2 2>&3

image

nyxnor avatar Nov 24 '21 00:11 nyxnor

I think checklist can be simple also, if the bridge is activated, it will be marked with an x by defaylt, if not, it will be unchecked as in deactivated.

nyxnor avatar Nov 24 '21 00:11 nyxnor

this script prints to stdout the bridge ip which should be activated or at least continue to be, the rest must be deactivated. An way to deal with this is deactivate all bridges and them just activate them by their ip, or fingerprint if selected.

#!/usr/bin/env bash

torrc="/etc/tor/torrc"

all_bridges="$(sudo grep "Bridge obfs4" "${torrc}")"
#activated_bridges="$(grep "^Bridge obfs4" <<< "${all_bridges}")"

while IFS= read -r line || [ -n "$line" ]; do
  bridge_status=0
  grep -q "^Bridge obfs4" <<< "$line" && bridge_status=1
  bridge_ip=$(awk '{print $3}' <<< "${line}" )
  bridge_fingerprint=$(awk '{print $4}' <<< "${line}" )
  bridge_checklist="$(printf "%s\n%s\n%s\n%s\n" "${bridge_checklist}" "${bridge_ip}" "${bridge_fingerprint}" "${bridge_status}")"
  bridge_menu="$(printf "%s\n%s\n%s\n" "${bridge_menu}" "${bridge_ip}" "${bridge_fingerprint}")"
done <<< "${all_bridges}"

dialog_type=checklist
case $dialog_type in
  menu)
    # shellcheck disable=SC2086
    menu_result="$(whiptail--menu "Bridges" 20 80 10 ${bridge_menu} 3>&1 1>&2 2>&3)"
  ;;
  checklist)
    # shellcheck disable=SC2086
    menu_result="$(whiptail --separate-output --checklist "Bridges" 20 80 10 ${bridge_checklist} 3>&1 1>&2 2>&3)"
  ;;
esac

echo "$menu_result"

image

$ ./test.sh
37.218.245.14:38224
212.101.26.106:443
34.255.123.165:52176

nyxnor avatar Nov 24 '21 00:11 nyxnor

It is also possible to display their current status acquired from onionoo, but because of column space, I would prefer to drop the fingerprint from the menu and organize it like this:

$ip    $status_from_onionoo    $status_act_or_inact_on_torrc

But I guess as the fingerprint is sent to onionoo, them replace $ip for $fingerprint

nyxnor avatar Nov 24 '21 00:11 nyxnor

Thanks for testing! I will look into it, and in one way or another, it will be implemented. In my view, using checklists is the way how we should deal with it.

radio24 avatar Nov 24 '21 05:11 radio24

The box is checked if the bridge is activated on the torrc. The other field is the fingerprint (ip and fingerprint does not fit, too big). The third field was acquired status of the fingeprint with the onionoo database.

image image

#!/usr/bin/env bash

torrc="/etc/tor/torrc"

all_bridges="$(sudo grep "Bridge obfs4" "${torrc}")"
#activated_bridges="$(grep "^Bridge obfs4" <<< "${all_bridges}")"
count_bridges=$(grep -c "Bridge obfs4" <<< "${all_bridges}")

i=0
while IFS= read -r line || [ -n "$line" ]; do
  i=$((i+1))
  printf %s"(${i}/${count_bridges})"
  bridge_action=0
  grep -q "^Bridge obfs4" <<< "$line" && bridge_action=1
  bridge_ip=$(awk '{print $3}' <<< "${line}" )
  bridge_fingerprint=$(awk '{print $4}' <<< "${line}" )
  printf %s" Gathering status for bridge: ${bridge_ip} ${bridge_fingerprint}"
  bridge_status=$(./bridges_check.py --network=tor -f "${bridge_fingerprint}")
  case ${bridge_status} in
    2) bridge_status="nonexistent";;
    1) bridge_status="online";;
    0) bridge_status="offline";;
    *) bridge_status=" ";;
  esac
  printf %s" - ${bridge_status}\n"
  bridge_checklist="$(printf "%s\n%s\n%s\n%s\n" "${bridge_checklist}" "${bridge_ip}" "${bridge_status}" "${bridge_action}")"
done <<< "${all_bridges}"

# shellcheck disable=SC2086
menu_result="$(whiptail --separate-output --checklist "Bridges" 20 80 10 ${bridge_checklist} 3>&1 1>&2 2>&3)"
if [ -n "${menu_result}" ]; then
  sudo sed -i "s/^Bridge obfs4/#Bridge obfs4/" ${torrc}
  ## comment brackets for IPV6
  menu_result=${menu_result//\[/\\\[}
  menu_result=${menu_result//\]/\\\]}
  for ip in ${menu_result}; do
    bridge_address="#Bridge obfs4 ${ip}"
    uncomment_bridge_address="${bridge_address//#/}"
    sudo sed -i "s/${bridge_address}/${uncomment_bridge_address}/g" ${torrc}
  done
fi

If you notice, instead of

ORIGINAL_STR="Bridge $bridge_address"
ORIGINAL_STR="$(<<< "$ORIGINAL_STR" sed -e 's`[][\\/.*^$]`\\&`g')"
ORIGINAL_STR="^$ORIGINAL_STR"
REPLACEMENT_STR="#Bridge $bridge_address"
REPLACEMENT_STR="$(<<< "$REPLACEMENT_STR" sed -e 's`[][\\/.*^$]`\\&`g')"

I am using

menu_result=${menu_result//\[/\\\[}
menu_result=${menu_result//\]/\\\]}

which result in less sed and more parameter expansion, it just fix the brackets and less lines. Also it is done one time, not on a loop.

nyxnor avatar Nov 25 '21 14:11 nyxnor

I can take care of it, or do you want to submit a pull request?

radio24 avatar Nov 25 '21 18:11 radio24

I am just thinking of how doing so.

  • bridge_activate_old

    • " 3" "Activate only selected OBFS4 bridges" \
    • " 4" "List all $number_configured_bridges_total OBFS4 bridges" \
  • bridge_deactivate_old

    • "3" "Deactivate only selected OBFS4 bridges" \
    • " 4" "List all $number_configured_bridges_total OBFS4 bridges" \

These options basically become the same with this new menu, except we can pass a flag to check if the bridge is online or not check at all, in the case you already now what bridge to activate/deactivate.

Option 4 on both script are the same. Option 3 is almost the same, changing between commenting and uncommenting. Because of this I would exclude them and convert those two script into only one with the following options:

  • " 1" "List all configured OBFS4 bridges and manually activate/deactivate them" \
  • " 2" "Activate ALL configured OBFS4 bridges" \
  • " 3" "Activate only OBFS4 bridges, which are ONLINE" \
  • " 4" "Deactivate ALL configured OBFS4 bridges and directly connect tor" \
  • " 5" "Deactivate only OBFS4 bridges, which are not longer ONLINE" \

If you don't agree, take care of it.

nyxnor avatar Nov 25 '21 19:11 nyxnor