Last active
May 15, 2023 18:08
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
# } | |
# | |
# ====================================================================================== # |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ajout du nom du SSID si la connexion est le Wi-Fi.