Skip to content

Instantly share code, notes, and snippets.

@MilesTEG1
Last active May 15, 2023 18:08
Show Gist options
  • Save MilesTEG1/b69fad580a508a2c02db1b8213e50fdc to your computer and use it in GitHub Desktop.
Save MilesTEG1/b69fad580a508a2c02db1b8213e50fdc to your computer and use it in GitHub Desktop.
Loguer les IP publiques obtenues sur un MAC avec l'interface par défaut associée. Permet aussi de loguer les autres interfaces connectées.
#!/bin/zsh
#
# Version : 1.1.1
#
# Script pour loguer les différentes adresses IP obtenues sur le mac
# Prérequis :
# - ts via moreutils : brewi moreutils (ou : brew install moreutils )
# - ou ets : https://github.com/zmwangx/ets#installation
# - tee : man tee
# - logrotate : brewi logrotate (ou : brew install logrotate )
#
# -> Tout installer en une seule commande : brewi moreutils logrotate (ou : brew install moreutils logrotate )
#
# Voir à la fin du script la méthode pour lancer automatiquement ce script toutes les 5 minutes.
# Et aussi pour la partie logrotate.
# ====================================================================================== #
# ================================= Variables à définir ================================ #
# ====================================================================================== #
#
# Chemin absolu d'accès au fichier log dans lequel on veut conserver les IP détectées.
LOG_FILE="/Users/user_lambda/LOGs/ip_log/adresses_ip.log"
# Pour logrotate (à installer avant !), chemins absolus !
LOG_ROTATE_CONF_FILE="/Users/user_lambda/LOGs/logrotate/ip_log.zsh.conf"
LOG_ROTATE_LOG_FILE="/Users/user_lambda/LOGs/logrotate.log"
# Définition des chemins d'accès pour wget et ts et ip (à installer via homebrew)
wget_bin="/opt/homebrew/bin/wget"
ts_bin="/opt/homebrew/bin/ts"
ip_bin="/opt/homebrew/bin/ip"
logrotate_bin="/opt/homebrew/sbin/logrotate"
# --------------------------------------------------------------------------------------
# ====================================================================================== #
# ============================= Définitions des fonctions ============================== #
# ====================================================================================== #
# command to log | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
function check_log_file() {
# ╔══════════════════════════════════════════════════════════════════════════╗
# ║ Fonction pour tester si le fichier log existe ║
# ╚══════════════════════════════════════════════════════════════════════════╝
# Idée : https://github.com/Bleala/Vdirsyncer-DOCKERIZED/blob/main/files/scripts/start.sh
if [[ ! -e "${LOG_FILE}" ]]; then
# Create Log File
# curl --create-dirs --output "${LOG_FILE}" file:///dev/null >/dev/null 2>&1
touch "${LOG_FILE}"
# Save exit code
LOG_FILE_CREATED="${?}"
# Check if Log File has been created
if [[ "${LOG_FILE_CREATED}" -ne 0 ]]; then
# User info
{
printf "\nLogfile %s could not be created!" $LOG_FILE
printf "\nCheck the \"LOG_FILE\" environment variable."
} 2>&1 | $ts_bin '[%Y-%m-%d %H:%M:%S]'
# Exit script
exit 1
fi
else
# Lancement de logrotate
# Il faudra avoir préparé en amont le fichier de configuration. Exemple : (à copier coller et à décommenter)
# /path_to/adresses_ip.log {
# daily
# rotate 7
# minage 1
# minsize 171k
# nocompress
# nodateext
# missingok
# notifempty
# create 644 userAAA staff
# su userAAA staff
# }
$logrotate_bin "$LOG_ROTATE_CONF_FILE"
fi
}
function get_interface() {
# ╔══════════════════════════════════════════════════════════════════════════╗
# ║ Fonction pour récupérer la ou les interfaces réseau connectées. ║
# ║ Donne en premier celle utilisée par défaut. ║
# ╚══════════════════════════════════════════════════════════════════════════╝
interface_array=()
# interface_string=$($ip_bin route | grep default | sed -e "s/^.*dev.//" | tr '\n' ' ')
interface_array=($($ip_bin route | grep default | sed -e "s/^.*dev.//"))
# DEBUG
# echo "---- DEBUG"
# interface_array_lenght=$(( ${#interface_array[@]} ))
# printf "interface_string = %s.\n" "$interface_string"
# printf "interface_array = %s.\nlen : %d.\ninterface_array[1] = %s\n" "$interface_array" ${#interface_array[@]} "${interface_array[1]}"
# echo "---- DEBUG"
if ((${#interface_array[@]} != 0)); then
message="\t\tInterface principale utilisée par défaut : ${interface_array[1]}\t"
if [[ "${interface_array[1]}" =~ ^(ppp[[:digit:]]{1}|.*tun[[:digit:]]{1})$ ]]; then
# On est sur une connexion VPN là ! ppp0 ou ppp1 etc...
vpn_active_connection=""
vpn_active_connection=$(scutil --nc list | grep Connected)
if [[ -z "${vpn_active_connection}" ]]; then
printf "\tErreur : La connexion VPN ne semble pas active... Vérifier les connexions et le script ! -- DEBUG ! Fin du script.\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
exit 1
elif [[ $vpn_active_connection =~ "^.*(\".*\").*$" ]] ||[[ $vpn_active_connection =~ "^.*(\".*) \[VPN.*$" ]]; then # Regex : https://unix.stackexchange.com/questions/421460/bash-regex-and-https-regex101-com
if [[ "${match[1]: -1}" == "\"" ]]; then
message+="\t Connexion VPN -> $match[1]\t"
else
message+="\t Connexion VPN -> $match[1]...\"\t"
fi
fi
fi
if ((${#interface_array[@]} > 1)); then
message+="\n\t\t\t( Il y a au moins une autre interface réseaux connectée, mais non utilisée par défaut :"
for ((i = 2; i < ${#interface_array[@]} + 1; i++)); do
message+=" ${interface_array[i]}"
if ((i != ${#interface_array[@]})); then
message+=","
else
message+=" )"
fi
done
fi
printf "$message\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
else
printf "\t\tL'interface par défaut n'a pas pu être déterminée.\nSoit il n'y a aucune connexion réseau disponible, soit celle(s) en cours ne sont pas connectées.\nVérifier les connexions réseaux.\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
return 1
fi
}
function get_active_connection_and_MAC() {
# ╔══════════════════════════════════════════════════════════════════════════╗
# ║ Fonction pour récupérer les interfaces réseaux actives et le nom de ║
# ║ ces interfaces. ║
# ║ Peut aussi récupérer l'adresse MAC des interfaces, désactivé ici. ║
# ╚══════════════════════════════════════════════════════════════════════════╝
# Idée d'origine : https://gist.github.com/reorx/bec96e0d117855dbe36505c1eaec0ddf
services=$(networksetup -listnetworkserviceorder | grep 'Hardware Port')
while read line; do
sname=$(echo $line | awk -F "(, )|(: )|[)]" '{print $2}')
sdev=$(echo $line | awk -F "(, )|(: )|[)]" '{print $4}')
if [ -n "$sdev" ]; then
ifout="$(ifconfig $sdev 2>/dev/null)"
echo "$ifout" | grep 'status: active' >/dev/null 2>&1
rc="$?"
if [ "$rc" -eq 0 ]; then
currentservice="$sname"
currentdevice="$sdev"
# currentmac=$(echo "$ifout" | awk '/ether/{print $2}')
# current_values+="$currentservice|$currentdevice|$currentmac"
current_values+="$currentservice|$currentdevice"
fi
fi
done <<<"$(echo "$services")"
# DEBUG
# echo "\${#current_values[@]} = ${#current_values[@]}"
# echo "$current_values"
if [ ${#current_values[@]} -ne 0 ]; then
connection_name="$(echo "${current_values[1]}" | awk -F "\|" '{print $1}')"
connection_interface="$(echo "${current_values[1]}" | awk -F "\|" '{print $2}')"
message="\t\tConnexion principale active : « $connection_name » via interface $connection_interface"
if [[ "${connection_name}" == "Wi-Fi" ]]; then
message+=" ( SSID = $(networksetup -getairportnetwork $connection_interface | awk -F':' '{ print$2 }' | cut -c 2-) )"
fi
printf "${message}\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
# for value in "${current_values[@]}"; do
# # value1=$(echo "$value" | awk -F "\|" '{print $1}')
# printf "\nConnexion principale : « %s » via interface %s\n" "$(echo "$value" | awk -F "\|" '{print $1}')" "$(echo "$value" | awk -F "\|" '{print $2}')"
# # printf "Nom de l'interface : %s\t" "$(echo "$value" | awk -F "\|" '{print $2}')"
# # printf "Adresse MAC : %s\n" "$(echo "$value" | awk -F "\|" '{print $3}')"
# done
for ((i = 2; i < ${#current_values[@]} + 1; i++)); do
printf "\t\t\tConnexion secondaire : « %s » via interface %s\n" "$(echo "${current_values[i]}" | awk -F "\|" '{print $1}')" "$(echo "${current_values[i]}" | awk -F "\|" '{print $2}')" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
done
else
echo >&2 "Could not find current service"
return 1
fi
}
function get_ip() {
# ╔══════════════════════════════════════════════════════════════════════════╗
# ║ Fonction pour récupérer l'adresse IP publique. ║
# ╚══════════════════════════════════════════════════════════════════════════╝
arg1=""
# ~~~~~ Arguments passed to the function ~~~~ #
nb_param=$#
arg1=$1 # Si arg1="no-print" on n'affichera pas les messages.
# Sinon (arg1=""), on affiche les messages
# On conserve la valeur de l'adresse IP potentiellement déjà déterminée
ip_old=$ip
for ((j = 0; j < 5; j++)); do
# Là aussi, 5 essais max sur 10s, des fois que la connexion vienne juste de se faire...
ip=$($wget_bin -qO- ifconfig.me/ip)
if [[ -n "${ip}" ]]; then
if [[ "${arg1}" != "no-print" ]]; then
printf "\t\tAdresse IP publique détectée : %s\n" $ip | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
fi
break
elif [[ -z "${ip}" ]] && [[ j -eq 9 ]]; then
if [[ "${arg1}" != "no-print" ]]; then
printf "\t\tL'adresse IP publique ne peut pas être déterminée après 5 essais. Vérifier la connexion internet.\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
fi
return 1
else
if [[ "${arg1}" != "no-print" ]]; then
printf "\t\tL'adresse IP publique n'a pas pu être déterminée. Essai n°%d / 5.\n" $((j + 1)) | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
fi
fi
sleep 2
done
if [[ "${ip_old}" != "${ip}" ]] && [[ -n "${ip_old}" ]]; then
printf "\t\t** L'adresse IP ( %s ) a changé depuis sa détection au début du script...\n" "${ip_old}" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
printf "\t\t** Nouvelle adresse IP publique détectée : %s\n" $ip | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
return 2
fi
}
# ====================================================================================== #
# ============================= Partie principale du script ============================ #
# ====================================================================================== #
# ╔══════════════════════════════════════════════════════════════════════════╗
# ║ 0. On vérifie le fichier log et on fait tourner les .log ║
# ║ 1. On initialise certaines variables à zéro ║
# ║ 2. On récupère l'adresse IP, et si on l'obtient... ║
# ║ 3. On récupère les noms et interface de connexions actives ║
# ║ 4. On récupère l'interface par défaut utilisée. ║
# ╚══════════════════════════════════════════════════════════════════════════╝
check_log_file
ip=""
interface_string=""
interface_array=()
current_values=()
printf "\n--- Détection de la connexion active et de l'ip publique ---\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
get_ip
return_code_IP="$?"
if [ "$return_code_IP" -eq 0 ]; then
get_active_connection_and_MAC
return_code_AC="$?"
if [ "$return_code_AC" -eq 0 ]; then
sleep 5
get_interface
return_code_GI="$?"
if [ "$return_code_GI" -ne 0 ]; then
exit 1
fi
# On vérigie que l'adresse IP n'a pas changée
get_ip "no-print"
return_code_IP2="$?"
if [ "$return_code_IP2" -eq 2 ]; then
printf "\t\t** L'adresse IP ayant changée depuis la première détection, il se peut qu'une connexion VPN ait été activée ou désactivée.\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
printf "\t\t** On relance les tests.\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
get_active_connection_and_MAC
return_code_AC2="$?"
if [ "$return_code_AC2" -eq 0 ]; then
sleep 5
get_interface
return_code_GI2="$?"
if [ "$return_code_GI2" -ne 0 ]; then
exit 1
fi
get_ip
if [ "$return_code_GI" -ne 0 ]; then
exit 1
fi
fi
elif [ "$return_code_IP2" -ne 0 ]; then
exit 1
fi
fi
fi
printf "--- Fin du script ---\n" | $ts_bin '[%Y-%m-%d %H:%M:%S]' | tee -a "${LOG_FILE}"
# ====================================================================================== #
# ================= Méthode pour lancer le script toutes les 5 minutes ================= #
# ====================================================================================== #
#
# Il faut utiliser launchd.
#
# 1. Modification du fichier launched.ip_log.plist
# Dans ce fichier, il faut changer user_lambda par votre nom d'utilisateur à vous,
# si vous placez les fichiers dans votre dossier de profile.
# Il est aussi possible d'ajuster le timing d'exécution. Mon conseil, utiliser :
# - https://crontab-generator.org/ : pour générer le format crontab du Schedule du lien suivant ;
# - https://launched.zerowidth.com/ : pour générer le .plist.
#
# 2. Copier le fichier launched.ip_log.plist dans ~/Library/LaunchAgents/
# cp launched.ip_log.plist ~/Library/LaunchAgents/
# 3. Activer le .plist dans LaunchAgents : ( Voir aide : https://launched.zerowidth.com/help )
# launchctl load -w ~/Library/LaunchAgents/launched.ip_log.plist
# Il est aussi possible d'utiliser des outils comme lunchy (via homebrew), ou encore
# LaunchControl (payant) ou encore Lingon X (payant aussi).
#
# ====================================================================================== #
# ================= Pour la rotation du fichier log créé par le script ================= #
# ====================================================================================== #
#
# Il faudra avoir préparé en amont le fichier de configuration.
# Exemple : voir le fichier ip_log.zsh.conf
# Il contient ceci :
# /path_to/adresses_ip.log {
# daily
# rotate 7
# nocompress
# nodateext
# missingok
# notifempty
# create 644 userAAA staff
# su userAAA staff
# }
#
# ====================================================================================== #
/Users/user_lambda/LOGs/ip_log/adresses_ip.log {
daily
rotate 7
nocompress
nodateext
missingok
notifempty
create 644 user_lambda staff
su user_lambda staff
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>GroupName</key>
<string>everyone</string>
<key>Label</key>
<string>launched.ip_log</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>~/path_to/ip_log.zsh</string>
</array>
<key>StandardErrorPath</key>
<string>/Users/user_lambda/LOGs/ip_log/error.log</string>
<key>StandardOutPath</key>
<string>/Users/user_lambda/LOGs/ip_log/output.log</string>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Minute</key>
<integer>0</integer>
</dict>
<dict>
<key>Minute</key>
<integer>5</integer>
</dict>
<dict>
<key>Minute</key>
<integer>10</integer>
</dict>
<dict>
<key>Minute</key>
<integer>15</integer>
</dict>
<dict>
<key>Minute</key>
<integer>20</integer>
</dict>
<dict>
<key>Minute</key>
<integer>25</integer>
</dict>
<dict>
<key>Minute</key>
<integer>30</integer>
</dict>
<dict>
<key>Minute</key>
<integer>35</integer>
</dict>
<dict>
<key>Minute</key>
<integer>40</integer>
</dict>
<dict>
<key>Minute</key>
<integer>45</integer>
</dict>
<dict>
<key>Minute</key>
<integer>50</integer>
</dict>
<dict>
<key>Minute</key>
<integer>55</integer>
</dict>
</array>
<key>UserName</key>
<string>user_lambda</string>
<key>WorkingDirectory</key>
<string>/Users/user_lambda</string>
</dict>
</plist>
@MilesTEG1
Copy link
Author

Ajout du nom du SSID si la connexion est le Wi-Fi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment