Hello,
This tutorial and script is useful only for people who have to use a spy phone for specific apps and are motivated enough to diminish the constant privacy violation
It can also be used to check what any device with wifi is doing behind your back
Here are some advices :
-
You should buy a “Silent pocket” Phone Faraday Sleeve (out of stock now …) / Phone Faraday Sleeve – Purism
I got one from purism, I tested only GPS and Wifi 2.4G, but both are blocked if you close correctly the pocket (open = not blocking)
And take the phone out of the pocket only when you really need it -
You should try to install LineageOS on the spy phone (if compatible), and use an alternative app store, it will be much better than the not up-to-date OS provided by default (lineageOS propose regular updates)
-
You should put your SIM card in the Librem5, use Wi-Fi tethering to provide Internet to your SIMless spy phone
In this post, I provide a script to ease the way to block all traffic and authorize only a whitelist of IP for your apps to work
How does it work ? it uses iptables, so you will need to use sudo to start or stop blocking
by default it will block all connection to all IP on all port coming from the tethering, so by default your spy phone cannot access anything on internet using your Librem5 wifi
So, to authorize an application YOU need to analyze which IP address the phone want to connect to when the app start or try to connect somewhere
To help you with this task, the script will configure iptable to log any attempt to any IP address on any port
So by default every attempt is logged and is visible with journalctl
I made 2 options :
./block_connections.sh live
./block_connections.sh logs
the option ‘live’ is printing any live attempt (ctrl+c to stop)
the option ‘logs’ deduplicate and print the IP addresses from the last 50 attempts, so maybe you can see only 13 IP addresses
Now you can see some IP, cool but what IP is related to your app ?
- you can use some web tools like abuseipdb.com or dnschecker.org/reverse-dns.php?query= to give you an hint, but sometimes it’s not giving any hint
- So, you can also use the command ‘host’ on your linux to check if the IP address correspond to the website of the app you use
example :
52.142.124.215 is not recognize with the web tools, but I know the app is using DuckDuckGo
when I do
host duckduckgo.com
I can see
duckduckgo.com has address 52.142.124.215 - If you didn’t find anything about the IP, you need to try many time you application and see, which IP appears again and again at every attempts, try to authorize it and see if it help or not
Ok now that we have validated 52.142.124.215 is related to duckduckgo.com
We can do 3 things :
- Add the IP 52.142.124.215 to the ‘IP_blacklist’ variable in the script if you want it to stay blocked and disappear from the log when an attempt to this IP is made
- Add the IP 52.142.124.215 to the ‘IP_whitelist’ variable in the script if you want it to be authorized always and disappear from the log when an attempt to this IP is made
- Add a new profile so you can authorize or block at will any IP for your duckduckgo app
There are examples in the script for those 3 possibilities
If you are still interested after this, then copy the following script in your Librem5
#!/bin/bash
if [ "$1" == "-h" ] || [ "$1" == "--help" ] ; then
echo -e "Usage : script <start|stop|switch|profil> [profil_option]
OPTIONS:
start Start blocking - Initialise and insert the iptable chain CLIENT_WHITELIST in first position in FORWARD
stop Stop blocking - Remove CLIENT_WHITELIST from FORWARD
switch Act like 'stop' or 'start' if CLIENT_WHITELIST is in or not in FORWARD
reset Update iptables with the changes you mabe in IP_whitelist and/or IP_blacklist
logs Show the last IP adresses in the last 50 connection attempt
live Show the current connection attempts, ctrl+c to stop
profil start <name> Authorize access to the IP addresses of the profil <name>
profil stop <name> Remove access to the IP addresses of the profil <name>
"
exit 0
fi
# -------------------- init --------------------------
iptables -L FORWARD | grep -q "CLIENT_WHITELIST"
flg_is_present=$?
# -------------------- lists --------------------------
# Whitelist
IP_whitelist="192.168.1.0/24
138.68.253.24
128.140.118.223
"
# profil LineageOS update
profils="LINEAGE 104.26.14.42 104.26.15.42 116.202.242.188 130.225.254.116 172.67.69.209 128.112.18.21 89.102.0.150 141.70.124.1"
# profil duckduckgo
profils="${profils}
DUCK 52.142.124.215"
# profil F-DROID store
profils="${profils}
FDROID 89.149.59.178"
# Blacklist Google
IP_blacklist="
35.227.200.0
35.244.172.51
34.54.163.57
34.89.151.119
34.102.162.219
34.102.213.67
34.117.147.68
142.251.39.195
142.251.142.3
142.251.152.119
142.251.153.119
142.251.154.119
142.251.155.119
142.251.156.119
142.251.157.119
172.217.20.35
172.217.22.35
216.239.32.223
216.239.34.223
216.239.36.223
216.239.38.223
"
# Blacklist Facebook
IP_blacklist="${IP_blacklist}
157.240.202.14"
# Blacklist useless IP I don't need for my profils to work
IP_blacklist="${IP_blacklist}
"
# ------------------ functions -----------------------
init_chain() {
# Test if chain exist and add if not
iptables -L CLIENT_WHITELIST > /dev/null
[ $? -ne 0 ] && iptables -N CLIENT_WHITELIST
# ACCEPT Whitelist
for IP in ${IP_whitelist} ; do
iptables -A CLIENT_WHITELIST -d ${IP} -j ACCEPT
done
# DROP Blacklist
#for IP in ${IP_blacklist} ; do
# iptables -A CLIENT_WHITELIST -d ${IP} -j DROP
# done
# Log everything else (non-whitelisted destinations)
#iptables -A CLIENT_WHITELIST -j LOG --log-prefix "CLIENT_BLOCKED: " --log-level 4
# Drop non-whitelisted traffic
iptables -A CLIENT_WHITELIST -j DROP
}
reset_chain() {
# Flush all the rules in the chain
iptables -F CLIENT_WHITELIST
init_chain
}
start_blocking() {
echo "- Start blocking"
# Test if chain exist and initialize it if not
iptables -L CLIENT_WHITELIST > /dev/null
[ $? -ne 0 ] && init_chain
# Insert custom chain in first position in FORWARD
iptables -I FORWARD 1 -i wlan0 -j CLIENT_WHITELIST
}
stop_blocking() {
echo "- Stop blocking"
# Determine the exact line to delete the right one, in case it's not in first position
local line=$(iptables -L FORWARD -n --line-numbers | grep "CLIENT_WHITELIST" | awk '{print $1}')
iptables -D FORWARD "${line}"
}
profil_start() {
local PROFIL=$1
[ "${PROFIL}" == "" ] && echo -e "\e[031mError\e[0m : Option 'profil start' must be followed by profil name" && exit 1
local list=$(echo "${profils}" | grep "^${PROFIL} ")
[ "${list}" == "" ] && echo -e "\e[031mError\e[0m : Profil inconnu : '${PROFIL}'" && exit 1
local verif=$(iptables -L --line-numbers | grep "${PROFIL}")
[ "${verif}" != "" ] && echo -e "\e[031mError\e[0m : Profil already set : '${PROFIL}'" && exit 1
for IP in ${list} ; do
[[ "${IP}" =~ ^[1-9] ]] && iptables -I CLIENT_WHITELIST 1 -d "${IP}" -j ACCEPT -m comment --comment "${PROFIL}"
done
}
profil_stop() {
local PROFIL=$1
[ "${PROFIL}" == "" ] && echo -e "\e[031mError\e[0m : Option 'profil stop' must be followed by profil name" && exit 1
echo "${profils}" | grep -q "^${PROFIL} "
[ $? -ne 0 ] && echo -e "\e[031mError\e[0m : Profil inconnu : '${PROFIL}'" && exit 1
local list=$(iptables -L --line-numbers | grep "ACCEPT" | grep "/\* ${PROFIL} \*/" | awk '{ print $1}' | sort -rn)
local rule_nb
for rule_nb in ${list} ; do
[[ "${rule_nb}" =~ ^[1-9] ]] && iptables -D CLIENT_WHITELIST "${rule_nb}"
done
}
# -------------------- main --------------------------
if [ "$1" == "start" ] ; then
[ ${flg_is_present} -eq 0 ] && echo -e "\e[031mError\e[0m : Rules already set" && exit 1
start_blocking
elif [ "$1" == "stop" ] ; then
[ ${flg_is_present} -ne 0 ] && echo -e "\e[031mError\e[0m : Rules not set" && exit 1
stop_blocking
elif [ "$1" == "switch" ] ; then
if [ ${flg_is_present} -eq 0 ] ; then
stop_blocking
else
start_blocking
fi
elif [ "$1" == "profil" ] ; then
if [ "$2" == "start" ] ; then
[ ${flg_is_present} -ne 0 ] && start_blocking
profil_start "$3"
elif [ "$2" == "stop" ] ; then
profil_stop "$3"
else
echo -e "\e[031mError\e[0m : Option profil must be followed by start or stop"
exit 1
fi
elif [ "$1" == "reset" ] ; then
reset_chain
elif [ "$1" == "logs" ] ; then
echo "- Last blocked IPs :"
journalctl -n 50 -g "CLIENT_BLOCKED: " | awk '{ print $11 }' | cut -d'=' -f2 | sort | uniq
elif [ "$1" == "live" ] ; then
journalctl -f -g "CLIENT_BLOCKED: "| awk '{ print $3 " " $11 }'
else
echo -e "\e[031mError\e[0m : Missing or unknown parameter"
exit 1
fi
#iptables -L
exit 0
make sure you a have the right to execute :
chmod u+x ./block_connections.sh
Now, hands-on work :
- Start your tethering
- Execute ‘sudo ./block_connections.sh start’
- Execute ‘sudo ./block_connections.sh live’
- Connect the spy phone to your Librem5 WiFi
- You will probably see a lots IP address appearing
- Stop the script with ctrl+c
- Try to determine if you want to block or authorize those IP, and add them to ‘IP_blacklist’, ‘IP_whitelist’, or in ‘profils’
- If you add something to ‘IP_blacklist’ or ‘IP_whitelist’, you need to do ‘sudo ./block_connections.sh reset’, it will apply your changes
- If you add a new profile (example DUCK), you just need to execute
sudo ./block_connections.sh profil start DUCKto authorize the IPs of the profil andsudo ./block_connections.sh profil stop DUCKto block those IPs again - Now execute
sudo ./block_connections.sh live, start the application you want to authorize and try to determine if you want to block or authorize those IP - If you want to stop blocking you just have to execute
sudo ./block_connections.sh stop, orsudo ./block_connections.sh switch
Once you have, configure everything you can disable the logs, by adding a # in front of the line :
iptables -A CLIENT_WHITELIST -j LOG --log-prefix "CLIENT_BLOCKED: " --log-level 4
you can also disable the 3 lines of the ‘for’ loop just before this line which handle IP_blacklist, which is useful only for reducing logs and knowing what you already disapprove
Some remarks :
- You can enable the
iptables -Lat the end of the script to see every changes made to iptables after every execution - I put 192.168.0.0/24 in the IP_whitelist just to show you can put your own LAN if you need it, remove this if useless…, same with 138.68.253.24 (puri.sm) and 128.140.118.223 (forums.puri.sm) only here for example
- For ease, you should SSH on your Librem5 from your computer
/!\ One last important thing : you need to execute sudo ./block_connections.sh start AFTER activating the tethering
every time AFTER you reactivate tethering : sudo ./block_connections.sh stop + sudo ./block_connections.sh start
because when you activate the tethering, it adds an iptable rule which authorize everything and is acting BEFORE the rule added by my script, so we need to put the rule of my script in first position
Feel free to criticize/copy/modify/redistribute the script