TailScale - VPN

versatile 64-bit multi-user Linux distribution


Moderators: kirk, jamesbond, p310don, JakeSFR, step, Forum moderators

Post Reply
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

TailScale - VPN

Post by stemsee »

https://tailscale.com/kb/1017/install
I manually installed on fatdog from a decompressed linux package. I had already setup on my android using my github login. Just copying the two binaries into path without systemd service confs still worked fine. Start the daemon first then tailscale login ... (thereafter tailscale up), accept on your android or other pc, and your virtual private network is up. To use internet in another country you would need a device there on your tailscale network set as an exit node. ... tailscale doesn't seem to provide remote web browsing internet access per se. Just sharing.

User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

There are addons (paid) for other services. I paid $5/month for Mullvad VPN, to use as an exit node with selection of 46 countries each which cities and servers to choose from. Mullvad add-on is in beta, works on my android and windows laptop, but not fully working on linux! On linux cli "tailscale up --exit-node="au-wg-syd-002.mullvad.ts.net" that is mullvad exit node city name (which I got from windows). I got a blisteringly fast connection.

There is also taildrop, which lets you send files to other devices on your network using cli, for Android right click file and select share > tailscale .... in alpha, and works: I selected my fatdog laptop as the target, the files first upload to tailscale servers then in linux cli "tailscale file get /root/Downloads" then all the uploaded files are retrieved. To send from linux cli "tailscale file cp /root/somefile 100.10.111.97 ... the ip would be the target device which will be listed in your admin console. On android files are auto received to Downloads.

I requested a feature which is shared clipboard.

Last edited by stemsee on Mon Sep 30, 2024 9:25 am, edited 1 time in total.
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

Tailscale vpn with addon was working today, after i set
nameserver fe80::1%wlan0
nameserver 192.168.1.1
tailscaled &
tailscale up

User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

tailscale vpn cli commands added to snapp. API is json based, i willneed to learn how to use it first before attempting to add it to snapp.

xscreenshot-20241005T103944.png
xscreenshot-20241005T103944.png (337.15 KiB) Viewed 1295 times
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

I have written a script for a tailscale chat app using taildrop file send and receive. Espeak function of cursor selected text. Persistent chat log. Translation of pre-sent text.... pre-alpha. Single click selects device, double click adds device for multiple send targets. Refresh devices re-initiates device list.

Updated 2024/10/09

Code: Select all

#!/bin/sh
# by stemsee 
# Copyright (C) 2024 Marcos M Contant
#
META="$RANDOM"
mkdir -p /tmp/ts-chat-$META
track=/tmp/ts-chat-"$META"
export track
touch "$track"/device
touch "$track"/devices
export camino="$HOME"/.config/ts_chat
for dir in "$camino"/{chats,icons}
do
	[[ ! -d "$dir" ]] && mkdir -p "$dir" 2>/dev/null
done
export iconpath="$camino/icons/"
export trans_cmnd='@bash -c "translatefn %1 %3"'
export send_cmnd='@bash -c "sendfn %2 %3"'
fkey=$(($RANDOM * $$))
export lpipe="$track/ts_chat.$RANDOM"
mkfifo "$lpipe"
export fpipe="$track/ts-chat.$RANDOM"
mkfifo "$fpipe"
exec 5<> ${lpipe}
exec 6<> ${fpipe}

# determine COPY/PASTE command
function x_clipfn {
if [ ! -z $(type -p xsel) ]; then
	export CLIP="xsel -o -b "
elif [ ! -z $(type -p xclip) ]; then
	export CLIP="xclip -o -p "
elif [ ! -z $(type -p clipit) ]; then
	export CLIP="clipit -p "
fi
export OUT_CLIP=$(echo $CLIP | cut -f1 -d' ')
}; export -f x_clipfn
x_clipfn

function hashtext {
	echo "$1"
}; export -f hashtext

export LANGUAGES="$TL!$(hashtext 'Afrikaans') - af!$(hashtext 'Albanian') - sq!$(hashtext 'Amharic') - am!$(hashtext 'Arabic') - ar!$(hashtext 'Armenian') - hy!$(hashtext 'Azerbaijani') - az!$(hashtext 'Basque') - eu!$(hashtext 'Belarusian') - be!$(hashtext 'Bengali') - bn!$(hashtext 'Bosnian') - bs!$(hashtext 'Bulgarian') - bg!$(hashtext 'Cantonese') - yue!$(hashtext 'Catalan') - ca!$(hashtext 'Cebuano') - ceb!$(hashtext 'Chichewa') - ny!$(hashtext 'Chinese(Simple)') - zh-CN!$(hashtext 'Chinese(Trad)') - zh-TW!$(hashtext 'Corsican') - co!$(hashtext 'Croatian') - hr!$(hashtext 'Czech') - cs!$(hashtext 'Danish') - da!$(hashtext 'Dutch') - nl!$(hashtext 'English') - en!$(hashtext 'Esperanto') - eo!$(hashtext 'Estonian') - et!$(hashtext 'Fijian') - fj!$(hashtext 'Filipino') - tl!$(hashtext 'Finnish') - fi!$(hashtext 'French') - fr!$(hashtext 'Frisian') - fy!$(hashtext 'Galician') - gl!$(hashtext 'Georgian') - ka!$(hashtext 'German') - de!$(hashtext 'Greek') - el!$(hashtext 'Gujarati') - gu!$(hashtext 'Haitian-Creole') - ht!$(hashtext 'Hausa') - ha!$(hashtext 'Hawaiian') - haw!$(hashtext 'Hebrew') - he!$(hashtext 'Hindi') - hi!$(hashtext 'Hmong') - hmn!$(hashtext 'Hmong-Daw') - mww!$(hashtext 'Hungarian') - hu!$(hashtext 'Icelandic') - is!$(hashtext 'Igbo') - ig!$(hashtext 'Indonesian') - id!$(hashtext 'Irish') - ga!$(hashtext 'Italian') - it!$(hashtext 'Japanese') - ja!$(hashtext 'Javanese') - jv!$(hashtext 'Kannada') - kn!$(hashtext 'Kazakh') - kk!$(hashtext 'Khmer') - km!$(hashtext 'Klingon') - tlh!$(hashtext 'Korean') - ko!$(hashtext 'Kurdish') - ku!$(hashtext 'Kyrgyz') - ky!$(hashtext 'Lao') - lo!$(hashtext 'Latin') - la!$(hashtext 'Latvian') - lv!$(hashtext 'Lithuanian') - lt!$(hashtext 'Luxembourgish') - lb!$(hashtext 'Macedonian') - mk!$(hashtext 'Malagasy') - mg!$(hashtext 'Malay') - ms!$(hashtext 'Malayalam') - ml!$(hashtext 'Maltese') - mt!$(hashtext 'Maori') - mi!$(hashtext 'Marathi') - mr!$(hashtext 'Mongolian') - mn!$(hashtext 'Myanmar') - my!$(hashtext 'Nepali') - ne!$(hashtext 'Norwegian') - no!$(hashtext 'Pashto') - ps!$(hashtext 'Persian') - fa!$(hashtext 'Polish') - pl!$(hashtext 'Portuguese') - pt!$(hashtext 'Punjabi') - pa!$(hashtext 'Queretaro-Otomi') - otq!$(hashtext 'Roman') - rm!$(hashtext 'Romanian') - ro!$(hashtext 'Russian') - ru!$(hashtext 'Samoan') - sm!$(hashtext 'Scots-Gaelic') - gd!$(hashtext 'Serbian(Cyr)') - sr-Cyrl!$(hashtext 'Serbian(Latin)') - sr-Latn!$(hashtext 'Sesotho') - st!$(hashtext 'Shona') - sn!$(hashtext 'Sindhi') - sd!$(hashtext 'Sinhala') - si!$(hashtext 'Slovak') - sk!$(hashtext 'Slovenian') - sl!$(hashtext 'Somali') - so!$(hashtext 'Spanish') - es!$(hashtext 'Sundanese') - su!$(hashtext 'Swahili') - sw!$(hashtext 'Swedish') - sv!$(hashtext 'Tahitian') - ty!$(hashtext 'Tajik') - tg!$(hashtext 'Tamil') - ta!$(hashtext 'Tatar') - tt!$(hashtext 'Telugu') - te!$(hashtext 'Thai') - th!$(hashtext 'Tongan') - to!$(hashtext 'Turkish') - tr!$(hashtext 'Udmurt') - udm!$(hashtext 'Ukrainian') - uk!$(hashtext 'Urdu') - ur!$(hashtext 'Uzbek') - uz!$(hashtext 'Vietnamese') - vi!$(hashtext 'Welsh') - cy!$(hashtext 'Xhosa') - xh!$(hashtext 'Yiddish') - yi!$(hashtext 'Yoruba') - yo!$(hashtext 'Yucatec-Maya') - yua!$(hashtext 'Zulu') - zu"

export ESPKLANG="$ETL!af!am!an!ar!as!az!ba!be!bg!bn!bpy!bs!ca!chr-US-Qaaa-x-west!cmn!cmn-latn-pinyin!cs!cv!cy!da!de!el!en-029!en-gb!en-gb-scotland!en-gb-x-gbclan!en-gb-x-gbcwmd!en-gb-x-rp!en-us!en-us-nyc!eo!es!es-419!et!eu!fa!fa-latn!fi!fr-be!fr-ch!fr-fr!ga!gd!gn!grc!gu!hak!haw!he!hi!hr!ht!hu!hy!hyw!ia!id!io!is!it!ja!jbo!ka!kk!kl!kn!ko!kok!ku!ky!la!lb!lfn!lt!ltg!lv!mi!mk!ml!mr!ms!mt!mto!my!nb!nci!ne!nl!nog!om!or!pa!pap!piqd!pl!pt!pt-br!py!qdb!qu!quc!qya!ro!ru!ru-cl!ru-lv!sd!shn!si!sjn!sk!sl!smj!sq!sr!sv!sw!ta!te!th!tk!tn!tr!tt!ug!uk!ur!uz!vi!vi-vn-x-central!vi-vn-x-south!yue!yue!Language!af!am!an!ar!as!az!ba!be!bg!bn!bpy!bs!ca!chr-US-Qaaa-x-west!cmn!cmn-latn-pinyin!cs!cv!cy!da!de!el!en-029!en-gb!en-gb-scotland!en-gb-x-gbclan!en-gb-x-gbcwmd!en-gb-x-rp!en-us!en-us-nyc!eo!es!es-419!et!eu!fa!fa-latn!fi!fr-be!fr-ch!fr-fr!ga!gd!gn!grc!gu!hak!haw!he!hi!hr!ht!hu!hy!hyw!ia!id!io!is!it!ja!jbo!ka!kk!kl!kn!ko!kok!ku!ky!la!lb!lfn!lt!ltg!lv!mi!mk!ml!mr!ms!mt!mto!my!nb!nci!ne!nl!nog!om!or!pa!pap!piqd!pl!pt!pt-br!py!qdb!qu!quc!qya!ro!ru!ru-cl!ru-lv!sd!shn!si!sjn!sk!sl!smj!sq!sr!sv!sw!ta!te!th!tk!tn!tr!tt!ug!uk!ur!uz!vi!vi-vn-x-central!vi-vn-x-south!yue!yue!Language!af!am!an!ar!as!az!ba!be!bg!bn!bpy!bs!ca!chr-US-Qaaa-x-west!cmn!cmn-latn-pinyin!cs!cv!cy!da!de!el!en-029!en-gb!en-gb-scotland!en-gb-x-gbclan!en-gb-x-gbcwmd!en-gb-x-rp!en-us!en-us-nyc!eo!es!es-419!et!eu!fa!fa-latn!fi!fr-be!fr-ch!fr-fr!ga!gd!gn!grc!gu!hak!haw!he!hi!hr!ht!hu!hy!hyw!ia!id!io!is!it!ja!jbo!ka!kk!kl!kn!ko!kok!ku!ky!la!lb!lfn!lt!ltg!lv!mi!mk!ml!mr!ms!mt!mto!my!nb!nci!ne!nl!nog!om!or!pa!pap!piqd!pl!pt!pt-br!py!qdb!qu!quc!qya!ro!ru!ru-cl!ru-lv!sd!shn!si!sjn!sk!sl!smj!sq!sr!sv!sw!ta!te!th!tk!tn!tr!tt!ug!uk!ur!uz!vi!vi-vn-x-central!vi-vn-x-south!yue!yue!"

function translatefn { # sends text for translation
export TL=$(echo "$1" | awk '{print $NF}')
ENGINE="bing"
[[ ! -z "$2" ]] && export TTEXT="$2" || exit
T_TEXT=$(echo -e "$TTEXT" | trans -e "$ENGINE" -b -tl "$TL" --show-languages --no-ansi -brief)
T_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< "$T_TEXT")
[[ -f "$track"/espk ]] && espeak -a 50 -s 160 -p 50 -v "$TL" "$T_TEXT" &
[[ ! -z "$T_TEXT" ]] && printf "%s\n%s\n%s\n%s\n%s\n" "" "" "$T_TEXT" "" "" > "$fpipe"
}; export -f translatefn

function espeakfn {
	if [[ ! -z $(type -p espeak) ]]; then
		killall espeak 2>/dev/null
		espeak -a 50 -s 160 -p 50 -v en-us "$($OUT_CLIP)" &
		xsel<<<' '
	fi
};export -f espeakfn

function devlstfn {
export DEVLST="$(tailscale status | grep -v -e mullvad -e '#')"
echo -e "$DEVLST" > "$track"/devices
echo -e '\f' > $lpipe
cat "$track"/devices | while read line
do
	IP=$(echo "$line" | awk '{print $1}')
	NICKNAME=$(echo "$line" | awk '{print $2}')
	USER=$(echo "$line" | awk '{print $3}')
	OS=$(echo "$line" | awk '{print $4}')
	STATUS=$(echo "$line" | awk '{print $5}')
	printf "%s\n%s\n%s\n%s\n%s\n%s" "$IP" "$NICKNAME" "$USER" "$OS" "$STATUS" >$lpipe
done
}; export -f devlstfn
devlstfn
export SELF="$(echo $DEVLST | head -n1 | cut -f1 -d' ')"

function receivefn {
	tailscale file get /root/Downloads/tailscale
	for i in $(ls /root/Downloads/tailscale/*_ts-chat.txt)
	do
	[[ -f "$i" ]] && cat "$i" >> "$camino"/chats/tschat.txt
	A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//" | tail -n40))
	printf "%s\n%s\n%s\n%s\n%s\n" "" "$A_TEXT" "" "" "" > "$fpipe"
	rm -f "$i" 2>/dev/null
	done
}; export -f receivefn

function sendfn {
	device="$(cat $track/device | cut -f1 -d' ')"
	NM=$(grep "$device" "$track"/devices | awk '{print $2}')
	echo -e "$SELF to $device $NM:\n$2" > "$camino"/chats/ts-chat.txt
	echo -e "$SELF to $device $NM:\n$2" >> "$camino"/chats/tschat.txt
	CHAT="$(cat $camino/chats/tschat.txt | tail -n40)"
	A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))
	printf "%s\n%s\n%s\n%s\n%s\n" "$TL\n$LANGUAGES" "$A_TEXT" "" "$send_cmnd" "$trans_cmnd" > "$fpipe"
	sleep 2 && xdotool key --repeat 22 Page_Down
	while read line
	do
		dev="$(echo $line | cut -f1 -d' ')"
		[ "$dev" != "$SELF" ] && tailscale file cp "$camino"/chats/"$SELF"_ts-chat.txt "$device":
	done <"$track"/device
	sleep 2
	rm -f "$camino"/chats/"$SELF"_ts-chat.txt
}; export -f sendfn

function devicefn {
	device=$(grep $1 "$track"/devices)
	[[ $(echo "$1" | cut -f1 -d' ') != "$SELF" ]] && [[ -z $(grep "$1" "$track"/device)  ]] && echo -e "$device" >> "$track"/device
};export -f devicefn

function doubleclickfn {
[[ $(echo "$1" | cut -f1 -d' ' | cut -f1 -d']') != "$SELF" ]] && [[ -z $(grep "$1" "$track"/device)  ]] && echo -e "$1" >> "$track"/device
};export -f doubleclickfn

function load_chat {
	[[ -f "$camino"/chats/tschat.txt ]] && CHAT="$(cat $camino/chats/tschat.txt)"
	A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))
	printf "%s\n%s\n%s\n%s\n%s\n" "$TL\n$LANGUAGES" "$A_TEXT" "type here" "$send_cmnd" "${trans_cmnd}" > "$fpipe"
};export -f load_chat

echo -e '\f' >&5
echo -e '\f' >&6

[ -f "$camino"/chats/tschat.txt ] && CHAT="$(cat $camino/chats/tschat.txt | tail -n40)"

 A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))

 printf "%s\n%s\n%s\n%s\n%s\n" "$TL\n$LANGUAGES" "$A_TEXT" "type here" "$send_cmnd" "${trans_cmnd}" > "$fpipe"

 yad --plug="$fkey" --title="list" --select-action="bash -c \"devicefn "%s" \" " --search-column=1 --print-column=1 --columns=5 --tabnum=1 --listen --fontname="$FONTNAME" --list --column="$SELF":TXT --column=Nickname:TXT --column=User:TXT --column=OS:TXT --column=Status:TXT --dclick-action="bash -c \"doubleclickfn "%s" \" " <&5 &

 yad --plug="$fkey" --title="form" --tail --tabnum=2 --listen --fontname="$FONTNAME" --focus-field=2 --enable-spell --homogenous --form --cycle-read --field="TL":CBE --field="<b>Chat Log:</b>  $(hashtext 'Input / Paste')":TXT --field="<b>Input:</b> $(hashtext 'Input')":TXT --field="$(hashtext 'Send')!gtk-refresh!$(hashtext 'send to chat')":fbtn --field="$(hashtext 'Translate')!gtk-save!$(hashtext 'translate Chat')":fbtn <&6 &

 yadu --key="$fkey" --title="$(hashtext 'tailscale chat')" --splitter=670 --window-icon="$iconpath/transtray.png" --image-on-top --geometry=1046x528+780+661 --image="$iconpath/tailscale.png" --width=1000 --height=400 --paned --tab=AB --tab=BA --orient=hori --buttons-layout=center --button="$(hashtext 'Receive Chats')!gtk-refresh!$(hashtext 'update chats'):bash -c 'receivefn'" --button="$(hashtext 'Load Entire Chat Log')!gtk-refresh!$(hashtext 'Load full Chat'):bash -c 'load_chat'" --button="$(hashtext 'Refresh Devices'):bash -c 'devlstfn'"  --button="eSpeak Selected:bash -c 'espeakfn $CLIP'" --button="Exit:bash -c 'eval exec /tmp/close_$META'" &
 
devlstfn

echo -e "#!/bin/sh
	sleep 0.3
	echo 'quit' > $fpipe
	echo 'quit' > $lpipe
	rm -rf $track &
	kill $loopid
	rm -f /tmp/close_$META &
" > /tmp/close_"$META"
chmod 755 /tmp/close_"$META"
Attachments
xscreenshot-20241007T165255.png
xscreenshot-20241007T165255.png (154.92 KiB) Viewed 1248 times
Last edited by stemsee on Wed Feb 12, 2025 4:11 am, edited 2 times in total.
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

I am using Reader Era app on Android to read the text and then it has the function to make a note and share the note to tailscale. ... which acts as a reply.
Improved the script and added the facility to send a file just by dragging it to the input field (directories not supported), and sending as path and file.

Last edited by stemsee on Wed Feb 12, 2025 4:14 am, edited 1 time in total.
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

There are a large number of apps on android suitable for viewing text messages ... I am now using Simple Text Editor, because I can save as, and rename files.

Between two linux machines the chats will be hopefully potentially less disjointed.

taildrop seems to have a minimum file size for transport, so i changed the script to send 20 or 40 lines of chat. Also added the reply header '$other to $self:' for ease of editing. $other and $self are now nicknames instead of ip addresses, just easier to remember.

Added save button for when editing the viewable chat. This backsup chat then recreates a chat with the edits in chat viewer.

Translate now works for input text or selected text.
Simple Text Editor defaults to saving text as newfile.txt - so script will look for that file name when receiving chats.

script update

Code: Select all

#!/bin/sh
# by stemsee 
# Copyright (C) 2024 Marcos M Contant
#
version=0.3
META="$RANDOM"
mkdir -p /tmp/ts-chat-$META
track=/tmp/ts-chat-"$META"
export track
touch "$track"/device
touch "$track"/devices
export camino="$HOME"/.config/ts_chat
for dir in "$camino"/{chats,icons}
do
	[[ ! -d "$dir" ]] && mkdir -p "$dir" 2>/dev/null
done
export iconpath="$camino/icons/"
export trans_cmnd='@bash -c "translatefn %1 %3"'
export send_cmnd='@bash -c "sendfn %2 %3"'
export save_cmnd='@bash -c "savefn %2"'
fkey=$(($RANDOM * $$))
export lpipe="$track/ts_chat.$RANDOM"
mkfifo "$lpipe"
export fpipe="$track/ts-chat.$RANDOM"
mkfifo "$fpipe"
exec 5<> ${lpipe}
exec 6<> ${fpipe}

# determine COPY/PASTE command
function x_clipfn {
if [ ! -z $(type -p xsel) ]; then
	export CLIP="xsel -o -b "
elif [ ! -z $(type -p xclip) ]; then
	export CLIP="xclip -o -p "
elif [ ! -z $(type -p clipit) ]; then
	export CLIP="clipit -p "
fi
export OUT_CLIP=$(echo $CLIP | cut -f1 -d' ')
}; export -f x_clipfn
x_clipfn

function hashtext {
	echo "$1"
}; export -f hashtext

export LANGUAGES="$TL!$(hashtext 'Afrikaans') - af!$(hashtext 'Albanian') - sq!$(hashtext 'Amharic') - am!$(hashtext 'Arabic') - ar!$(hashtext 'Armenian') - hy!$(hashtext 'Azerbaijani') - az!$(hashtext 'Basque') - eu!$(hashtext 'Belarusian') - be!$(hashtext 'Bengali') - bn!$(hashtext 'Bosnian') - bs!$(hashtext 'Bulgarian') - bg!$(hashtext 'Cantonese') - yue!$(hashtext 'Catalan') - ca!$(hashtext 'Cebuano') - ceb!$(hashtext 'Chichewa') - ny!$(hashtext 'Chinese(Simple)') - zh-CN!$(hashtext 'Chinese(Trad)') - zh-TW!$(hashtext 'Corsican') - co!$(hashtext 'Croatian') - hr!$(hashtext 'Czech') - cs!$(hashtext 'Danish') - da!$(hashtext 'Dutch') - nl!$(hashtext 'English') - en!$(hashtext 'Esperanto') - eo!$(hashtext 'Estonian') - et!$(hashtext 'Fijian') - fj!$(hashtext 'Filipino') - tl!$(hashtext 'Finnish') - fi!$(hashtext 'French') - fr!$(hashtext 'Frisian') - fy!$(hashtext 'Galician') - gl!$(hashtext 'Georgian') - ka!$(hashtext 'German') - de!$(hashtext 'Greek') - el!$(hashtext 'Gujarati') - gu!$(hashtext 'Haitian-Creole') - ht!$(hashtext 'Hausa') - ha!$(hashtext 'Hawaiian') - haw!$(hashtext 'Hebrew') - he!$(hashtext 'Hindi') - hi!$(hashtext 'Hmong') - hmn!$(hashtext 'Hmong-Daw') - mww!$(hashtext 'Hungarian') - hu!$(hashtext 'Icelandic') - is!$(hashtext 'Igbo') - ig!$(hashtext 'Indonesian') - id!$(hashtext 'Irish') - ga!$(hashtext 'Italian') - it!$(hashtext 'Japanese') - ja!$(hashtext 'Javanese') - jv!$(hashtext 'Kannada') - kn!$(hashtext 'Kazakh') - kk!$(hashtext 'Khmer') - km!$(hashtext 'Klingon') - tlh!$(hashtext 'Korean') - ko!$(hashtext 'Kurdish') - ku!$(hashtext 'Kyrgyz') - ky!$(hashtext 'Lao') - lo!$(hashtext 'Latin') - la!$(hashtext 'Latvian') - lv!$(hashtext 'Lithuanian') - lt!$(hashtext 'Luxembourgish') - lb!$(hashtext 'Macedonian') - mk!$(hashtext 'Malagasy') - mg!$(hashtext 'Malay') - ms!$(hashtext 'Malayalam') - ml!$(hashtext 'Maltese') - mt!$(hashtext 'Maori') - mi!$(hashtext 'Marathi') - mr!$(hashtext 'Mongolian') - mn!$(hashtext 'Myanmar') - my!$(hashtext 'Nepali') - ne!$(hashtext 'Norwegian') - no!$(hashtext 'Pashto') - ps!$(hashtext 'Persian') - fa!$(hashtext 'Polish') - pl!$(hashtext 'Portuguese') - pt!$(hashtext 'Punjabi') - pa!$(hashtext 'Queretaro-Otomi') - otq!$(hashtext 'Roman') - rm!$(hashtext 'Romanian') - ro!$(hashtext 'Russian') - ru!$(hashtext 'Samoan') - sm!$(hashtext 'Scots-Gaelic') - gd!$(hashtext 'Serbian(Cyr)') - sr-Cyrl!$(hashtext 'Serbian(Latin)') - sr-Latn!$(hashtext 'Sesotho') - st!$(hashtext 'Shona') - sn!$(hashtext 'Sindhi') - sd!$(hashtext 'Sinhala') - si!$(hashtext 'Slovak') - sk!$(hashtext 'Slovenian') - sl!$(hashtext 'Somali') - so!$(hashtext 'Spanish') - es!$(hashtext 'Sundanese') - su!$(hashtext 'Swahili') - sw!$(hashtext 'Swedish') - sv!$(hashtext 'Tahitian') - ty!$(hashtext 'Tajik') - tg!$(hashtext 'Tamil') - ta!$(hashtext 'Tatar') - tt!$(hashtext 'Telugu') - te!$(hashtext 'Thai') - th!$(hashtext 'Tongan') - to!$(hashtext 'Turkish') - tr!$(hashtext 'Udmurt') - udm!$(hashtext 'Ukrainian') - uk!$(hashtext 'Urdu') - ur!$(hashtext 'Uzbek') - uz!$(hashtext 'Vietnamese') - vi!$(hashtext 'Welsh') - cy!$(hashtext 'Xhosa') - xh!$(hashtext 'Yiddish') - yi!$(hashtext 'Yoruba') - yo!$(hashtext 'Yucatec-Maya') - yua!$(hashtext 'Zulu') - zu"

export ESPKLANG="$ETL!af!am!an!ar!as!az!ba!be!bg!bn!bpy!bs!ca!chr-US-Qaaa-x-west!cmn!cmn-latn-pinyin!cs!cv!cy!da!de!el!en-029!en-gb!en-gb-scotland!en-gb-x-gbclan!en-gb-x-gbcwmd!en-gb-x-rp!en-us!en-us-nyc!eo!es!es-419!et!eu!fa!fa-latn!fi!fr-be!fr-ch!fr-fr!ga!gd!gn!grc!gu!hak!haw!he!hi!hr!ht!hu!hy!hyw!ia!id!io!is!it!ja!jbo!ka!kk!kl!kn!ko!kok!ku!ky!la!lb!lfn!lt!ltg!lv!mi!mk!ml!mr!ms!mt!mto!my!nb!nci!ne!nl!nog!om!or!pa!pap!piqd!pl!pt!pt-br!py!qdb!qu!quc!qya!ro!ru!ru-cl!ru-lv!sd!shn!si!sjn!sk!sl!smj!sq!sr!sv!sw!ta!te!th!tk!tn!tr!tt!ug!uk!ur!uz!vi!vi-vn-x-central!vi-vn-x-south!yue!yue!Language!af!am!an!ar!as!az!ba!be!bg!bn!bpy!bs!ca!chr-US-Qaaa-x-west!cmn!cmn-latn-pinyin!cs!cv!cy!da!de!el!en-029!en-gb!en-gb-scotland!en-gb-x-gbclan!en-gb-x-gbcwmd!en-gb-x-rp!en-us!en-us-nyc!eo!es!es-419!et!eu!fa!fa-latn!fi!fr-be!fr-ch!fr-fr!ga!gd!gn!grc!gu!hak!haw!he!hi!hr!ht!hu!hy!hyw!ia!id!io!is!it!ja!jbo!ka!kk!kl!kn!ko!kok!ku!ky!la!lb!lfn!lt!ltg!lv!mi!mk!ml!mr!ms!mt!mto!my!nb!nci!ne!nl!nog!om!or!pa!pap!piqd!pl!pt!pt-br!py!qdb!qu!quc!qya!ro!ru!ru-cl!ru-lv!sd!shn!si!sjn!sk!sl!smj!sq!sr!sv!sw!ta!te!th!tk!tn!tr!tt!ug!uk!ur!uz!vi!vi-vn-x-central!vi-vn-x-south!yue!yue!Language!af!am!an!ar!as!az!ba!be!bg!bn!bpy!bs!ca!chr-US-Qaaa-x-west!cmn!cmn-latn-pinyin!cs!cv!cy!da!de!el!en-029!en-gb!en-gb-scotland!en-gb-x-gbclan!en-gb-x-gbcwmd!en-gb-x-rp!en-us!en-us-nyc!eo!es!es-419!et!eu!fa!fa-latn!fi!fr-be!fr-ch!fr-fr!ga!gd!gn!grc!gu!hak!haw!he!hi!hr!ht!hu!hy!hyw!ia!id!io!is!it!ja!jbo!ka!kk!kl!kn!ko!kok!ku!ky!la!lb!lfn!lt!ltg!lv!mi!mk!ml!mr!ms!mt!mto!my!nb!nci!ne!nl!nog!om!or!pa!pap!piqd!pl!pt!pt-br!py!qdb!qu!quc!qya!ro!ru!ru-cl!ru-lv!sd!shn!si!sjn!sk!sl!smj!sq!sr!sv!sw!ta!te!th!tk!tn!tr!tt!ug!uk!ur!uz!vi!vi-vn-x-central!vi-vn-x-south!yue!yue!"

function savefn {
 [[ -f "$camino"/chats/"$(cat $track/device)"/tschat.txt ]] && mv -f "$camino"/chats/"$(cat $track/device)"/tschat.txt "$camino"/chats/"$(cat $track/device)"/tschat.txt-$(date +%Y%m%d%H%M%S)
 echo -e "$1" > "$camino"/chats/"$(cat $track/device)"/tschat.txt
 [[ -f "$camino"/chats/"$(cat $track/device)"/tschat.txt ]] && CHAT="$(cat $camino/chats/$(cat $track/device)/tschat.txt | tail -n40)"
 A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))
 printf "%s\n%s\n%s\n%s\n%s\n%s\n" "$TL\n$LANGUAGES" "$A_TEXT" "type here" "$send_cmnd" "${trans_cmnd}" "${save_cmnd}" > "$fpipe"
  sleep 4 && xdotool key --repeat 22 Page_Down
};export -f savefn

function translatefn { # sends text for translation
export TL=$(echo "$1" | awk '{print $NF}')
ENGINE="bing"
[[ ! -z "$2" ]] && export TTEXT="$2" || export TTEXT="$($OUT_CLIP)"
[[ -z "$TTEXT" ]] && exit
T_TEXT=$(echo -e "$TTEXT" | trans -e "$ENGINE" -b -tl "$TL")
T_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< "$2\n$T_TEXT")
[[ ! -z "$T_TEXT" ]] && printf "%s\n%s\n%s\n%s\n%s\n%s\n" "" "" "$T_TEXT" "" "" "" > "$fpipe" || exit
}; export -f translatefn

function espeakfn {
	if [[ ! -z $(type -p espeak) ]]; then
		killall espeak 2>/dev/null
		espeak -a 50 -s 160 -p 50 -v en-us "$($OUT_CLIP)" &
		xsel<<<' '
	fi
};export -f espeakfn

function devlstfn {
export DEVLST="$(tailscale status | grep -v -e mullvad -e '#')"
echo -e "$DEVLST" > "$track"/devices
echo -e '\f' > $lpipe
cat "$track"/devices | while read line
do
	IP=$(echo "$line" | awk '{print $1}')
	NICKNAME=$(echo "$line" | awk '{print $2}')
	USER=$(echo "$line" | awk '{print $3}')
	OS=$(echo "$line" | awk '{print $4}')
	STATUS=$(echo "$line" | awk '{print $5}')
	printf "%s\n%s\n%s\n%s\n%s\n%s" "$IP" "$NICKNAME" "$USER" "$OS" "$STATUS" >$lpipe
	[[ ! -d "$camino"/chats/"$NICKNAME" ]] && mkdir -p "$camino"/chats/"$NICKNAME"
done
}; export -f devlstfn
devlstfn

export SELF="$(echo $DEVLST | head -n1 | cut -f2 -d' ')"

function receivefn {
	tailscale file get /root/Downloads/tailscale &
	sleep 7

		dev="$(cat "$track"/device | cut -f2 -d' ')"
		[[ -f /root/Downloads/tailscale/aaa_tschat_"$dev".txt ]] && cat /root/Downloads/tailscale/aaa_tschat_"$dev".txt >> "$camino"/chats/"$dev"/tschat.txt
		[[ -f /root/Downloads/tailscale/newfile.txt ]] && cat /root/Downloads/tailscale/newfile.txt >> "$camino"/chats/$dev/tschat.txt

		if [[ -f "$camino"/chats/"$dev"/tschat.txt ]]; then
			CHAT=$(cat "$camino"/chats/"$dev"/tschat.txt | tail -n 40)
			A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//" | tail -n40))
			printf "%s\n%s\n%s\n%s\n%s\n%s\n" "" "$A_TEXT" "" "" "" "" > "$fpipe"
			sleep 2 && xdotool key --repeat 22 Page_Down
			rm -f "/root/Downloads/tailscale/aaa_tschat_$dev.txt" 2>/dev/null
			rm -f "/root/Downloads/tailscale/newfile.txt" 2>/dev/null
		fi
}; export -f receivefn

function sendfn {
	while read line
	do
	device="$(echo "$line" | cut -f2 -d' ')"
	if [[ "$device" != "$SELF" ]]; then
	echo -e "$SELF to $device:\n$2" >> "$camino"/chats/"$device"/tschat.txt
	CHAT="$(cat $camino/chats/$device/tschat.txt | tail -n40)"
	echo -e "${CHAT}\n$device to $SELF:\n" > "$camino"/chats/"$device"/aaa_tschat_"$SELF".txt
	A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))
	printf "%s\n%s\n%s\n%s\n%s\n%s\n" "$TL!$LANGUAGES" "$A_TEXT" "" "$send_cmnd" "$trans_cmnd" "${save_cmnd}" > "$fpipe"
	sleep 2 && xdotool key --repeat 22 Page_Down
	[[ "$device" != "$SELF" ]] && tailscale file cp "$camino"/chats/"$device"/aaa_tschat_"$SELF".txt "$device":
	sleep 2
	rm -f "$camino"/chats/"$device"/aaa__tschat_"$SELF".txt
	fi
	done <"$track"/device
}; export -f sendfn

function devicefn {
	device=$(grep $1 "$track"/devices | awk '{print $2}')
	[[ "$device" != "$SELF" ]] && echo -e "$device" > "$track"/device
	[[ ! -d "$camino"/chats/"$device" ]] && mkdir -p "$camino"/chats/"$device"
	[[ -f "$camino"/chats/"$(cat $track/device)"/tschat.txt ]] && CHAT="$(cat $camino/chats/$(cat $track/device)/tschat.txt | tail -n40)"
 A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))
 printf "%s\n%s\n%s\n%s\n%s\n%s\n" "$TL\n$LANGUAGES" "$A_TEXT" "" "$send_cmnd" "${trans_cmnd}" "${save_cmnd}" > "$fpipe"
 sleep 4 && xdotool key --repeat 22 Page_Down
};export -f devicefn

function doubleclickfn {
[[ $(echo "$1" | cut -f2 -d' ' | cut -f1 -d']') != "$SELF" ]] && [[ -z $(grep "$1" "$track"/device)  ]] && echo -e "$1" >> "$track"/device
};export -f doubleclickfn

function load_chat {
	[[ -f "$camino"/chats/"$(cat $track/device)"/tschat.txt ]] && CHAT="$(cat $camino/chats/$(cat $track/device)/tschat.txt)"
	A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))
	printf "%s\n%s\n%s\n%s\n%s\n%s\n" "$TL\n$LANGUAGES" "$A_TEXT" "type here" "$send_cmnd" "${trans_cmnd}" "${save_cmnd}" > "$fpipe"
	 sleep 4 && xdotool key --repeat 22 Page_Down
};export -f load_chat

echo -e '\f' >&5
echo -e '\f' >&6

 yad --plug="$fkey" --title="list" --select-action="bash -c \"devicefn "%s" \" " --search-column=1 --print-column=1 --columns=5 --tabnum=1 --listen --fontname="$FONTNAME" --list --column="$SELF":TXT --column=Nickname:TXT --column=User:TXT --column=OS:TXT --column=Status:TXT --dclick-action="bash -c \"doubleclickfn "%s" \" " <&5 &

 yad --plug="$fkey" --title="form" --tabnum=2 --listen --fontname="$FONTNAME" --focus-field=2 --enable-spell --homogenous --form --cycle-read --field="TL":CBE --tail --field="<b>Chat Log:</b>  $(hashtext 'Editable')":TXT --tail --field="<b>Input:</b> $(hashtext 'Input')":TXT --field="$(hashtext 'Send')!gtk-refresh!$(hashtext 'send to chat')":fbtn --field="$(hashtext 'Translate')!gtk-refresh!$(hashtext 'translate input text or cursor selected text')":fbtn --field="$(hashtext 'SAVE CHAT')!gtk-save!$(hashtext 'Edit Chat and Save with backup')":fbtn <&6 &

 yad --key="$fkey" --title="$(hashtext 'tailscale chat')" --splitter=670 --window-icon="$iconpath/transtray.png" --image-on-top --geometry=1046x528+780+661 --image="$iconpath/tailscale.png" --width=1000 --height=400 --paned --tab=AB --tab=BA --orient=hori --buttons-layout=center --button="$(hashtext 'Receive Chats')!gtk-refresh!$(hashtext 'update chats'):bash -c 'receivefn'" --button="$(hashtext 'Load Entire Chat Log')!gtk-refresh!$(hashtext 'Load full Chat'):bash -c 'load_chat'" --button="$(hashtext 'Refresh Devices'):bash -c 'devlstfn'"  --button="eSpeak Selected:bash -c 'espeakfn $CLIP'" --button="Exit:bash -c 'eval exec /tmp/close_$META'" &
 
devlstfn

echo -e "#!/bin/sh
	sleep 0.3
	echo 'quit' > $fpipe
	echo 'quit' > $lpipe
	rm -rf $track &
	kill $loopid
	rm -f /tmp/close_$META &
" > /tmp/close_"$META"
chmod 755 /tmp/close_"$META"
while [[ -z "$(cat $track/device)" ]];
do
sleep 1
done
[ -f "$camino"/chats/"$(cat $track/device)"/tschat.txt ] && CHAT="$(cat $camino/chats/$(cat $track/device)/tschat.txt | tail -n40)"

 A_TEXT=$(while read -r line; do printf "%s" "$line\n"; done <<< $(printf "%q" "${CHAT}" | sed -e "s/'$//" -e "s/^$'//"))

 printf "%s\n%s\n%s\n%s\n%s\n%s\n" "$TL\n$LANGUAGES" "$A_TEXT" "type here" "$send_cmnd" "${trans_cmnd}" "${save_cmnd}" > "$fpipe"
 sleep 4 && xdotool key --repeat 22 Page_Down
Last edited by stemsee on Wed Feb 12, 2025 4:14 am, edited 1 time in total.
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

VKl Text Editor, is the most compatible txt editor for ts-chat on android, that i have so far found.
1) save as overwrite
2) save as new file
3) save note
4) insert date time
5) share as message to chat apps
6) search and replace
7) choose line feed, encoding etc

xscreenshot-20241012T180525.png
xscreenshot-20241012T180525.png (352.11 KiB) Viewed 1141 times
xscreenshot-20241012T180635.png
xscreenshot-20241012T180635.png (312.63 KiB) Viewed 1141 times
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

I hacked together this initd service starrt, stop, restart script /etc/initd/55-tailscaled

EDIT: note the start stanza needs to restart tailscaled. The first start doesn't succeed because the service tries to start before tun is ready. The restart succeeds because tun is ready from the first start attempt.

Code: Select all

#!/bin/dash
# tailscaled VPN service

Restart=on-failure
PORT="41641"
FLAGS="-tun tailscale0"
RuntimeDirectory=/var/run/tailscale
RuntimeDirectoryMode=0755
StateDirectory=/var/lib/tailscale
StateDirectoryMode=0700
CacheDirectory=/var/cache/tailscale
CacheDirectoryMode=0750
Type=notify

start_tailscaled() {
	/usr/sbin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=${PORT} $FLAGS &
}

stop_tailscaled() {
	/usr/sbin/tailscaled --cleanup
	while pidof tailscaled > /dev/null; do killall tailscaled 2>/dev/null; done
}

is_up_tailscaled() {
	pidof tailscaled > /dev/null
}

case "$1" in
	start)
		start_tailscaled
		sleep 1
		stop_tailscaled
		sleep 1 
		start_tailscaled
		;;

	stop)
		stop_tailscaled
		;;
	
	restart)
		stop_tailscaled
		sleep 1
		start_tailscaled
		;;
		
	status)
		is_up_tailscaled && echo "tailscaled is running." || echo "tailscaled is stopped."
		;;		

esac
Last edited by stemsee on Sat Nov 02, 2024 10:48 am, edited 1 time in total.
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

green and red icons for online / offline

reverted the script to just sending latest lines.

see if i can get this to use socks5 instead.
EDIT: if a device is using mullvad exit node it may appear to be offline. I will need to query with the developers on github to get a codable understanding.

xscreenshot-20241014T153909.png
xscreenshot-20241014T153909.png (119.3 KiB) Viewed 1081 times
Last edited by stemsee on Sat Nov 02, 2024 10:40 am, edited 2 times in total.
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

I am sharing a tailscale.sfs package, among others, from my laptop, directly on tailscale using

Code: Select all

tailscale funnel /tmp/dir

. This package contains tailscaled and tailscale binaries version 1.8 beta.

https://ccp-5-5.taild4ecf9.ts.net/

Last edited by stemsee on Wed Feb 12, 2025 4:04 am, edited 3 times in total.
User avatar
stemsee
Posts: 835
Joined: Sun Jul 26, 2020 8:11 am
Location: lattitude 8
Has thanked: 195 times
Been thanked: 144 times
Contact:

Re: TailScale - VPN

Post by stemsee »

A free tailscale account gives a upto three individual tailnets - a tailnet is a vpn account each allowing three users, and 100 devices.

On one of my tailnets I pay a monthly $5 fee for the mullvad vpn which provides 49 exit-nodes around the globe. The mullvad vpn deal is for 5 devices, extra devices cost an extra $0.50 cents per device per month. When i first configured the mullvad addon I had to add individual devices by their ip address to each of the five slots available. Now, however, because you have an Access Policy (ACL) you can write a rule which allows any device belonging to user@email.com to access one of the five mullvad slots. So devices accessing internet through a mullvad exit node take a free slot if available. In effect 100 devices share five slots depending on availability. So no need to add devices in settings to the mullvad configurator, just use the Access Policy file to take care of it for you. If needed you can write a rule to 'deny' a device by ip if required.

my relevant acl sections look like this, in HuJSON (Human) format

Code: Select all

	// Define the tags which can be applied to devices and by which users.
	"tagOwners": {
		"tag:mullvad": ["cru444@github"],
	},
		{
	"nodeAttrs": [
		{
			// Funnel policy, which lets tailnet members control Funnel
			// for their own devices.
			// Learn more at https://tailscale.com/kb/1223/tailscale-funnel/
			"target": ["autogroup:member"],
			"attr":   ["funnel"],
		},
		{
			"target": ["autogroup:member",],
			"attr": ["mullvad"],
		},
	],

}

the funnel attribute allows serving a folder or file directly to the public internet.
EDIT: of course the above nodeAttrs stanza can be simplified to

Code: Select all

	"nodeAttrs": [
		{
			// Funnel policy, which lets tailnet members control Funnel
			// for their own devices.
			// Learn more at https://tailscale.com/kb/1223/tailscale-funnel/
			"target": ["autogroup:member"],
			"attr":   ["funnel","mullvad"],
		},
	],

}
Post Reply

Return to “FatDog64”