Useful CLI tools (bash) for Arch Linux administration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
6.2 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. #!/usr/bin/env bash
  2. #
  3. # genmac - Generate a random MAC address for a Systemd-configured network interface
  4. #
  5. # Copyright (C) 2021 Pekka Helenius <pekka.helenius@fjordtek.com>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #####################################
  20. trap ctrl_c INT
  21. function ctrl_c() {
  22. echo -e "\nAborting.\n"
  23. return
  24. }
  25. random_mac() {
  26. MAC=$(printf '%02x' $((0x$(od /dev/urandom -N1 -t x1 -An | cut -c 2-) & 0xFE | 0x02)); od /dev/urandom -N5 -t x1 -An | sed 's/ /:/g')
  27. }
  28. insert_mac() {
  29. echo -e "\nChanging MAC address information (root permission required).\n"
  30. sudo sed -i "/\[Link\]/!b;n;cMACAddress=$MAC" /etc/systemd/network/00-default.link
  31. echo -e "MAC address changed from '$MAC_OLD' to '$MAC' for interface '$MAC_DEVICE'.\n\nPlease restart this interface to apply the changes.\n\nTo restore original MAC address, either delete configuration file '/etc/systemd/network/$linkname' or set real MAC address manually into it.\n"
  32. return 0
  33. }
  34. geninsert_mac() {
  35. gennew_mac() {
  36. while true; do
  37. unset response
  38. read -r -p "Generate a new MAC address? [Y/n] " response
  39. if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  40. random_mac
  41. newname_mac
  42. else
  43. echo -e "\nKeeping old MAC address configuration.\n"
  44. return
  45. fi
  46. done
  47. }
  48. newname_mac() {
  49. unset response
  50. read -r -p "New MAC address for '$MAC_DEVICE' will be '$MAC'. Accept? [Y/n] " response
  51. if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  52. insert_mac
  53. else
  54. gennew_mac
  55. fi
  56. }
  57. newname_mac
  58. }
  59. gen_mac() {
  60. real_mac() {
  61. AVAILABLE_MACS=$(ip -br link show | sed '/LOOPBACK/d' | awk '{print NR"\t"$1"\t"$3"\t"$2}')
  62. IFS=$'\n'
  63. echo -e "\nAvailable network interfaces with their MAC addresses are:\n\n${AVAILABLE_MACS[*]}"
  64. echo -e "\nPlease select the interface which MAC address you want to spoof of\n"
  65. read -r -p "Selection [number]: " number
  66. if [[ ! $number =~ ^[0-9]+$ ]]; then
  67. echo -e "\nInvalid input value. Aborting.\n"
  68. return 1
  69. fi
  70. for INTERFACE in $(echo -e "${AVAILABLE_MACS[*]}"); do
  71. intf_num=$(echo $INTERFACE | awk '{print $1}')
  72. if [[ $number -eq $intf_num ]]; then
  73. MAC_REAL=$(echo $INTERFACE | awk '{print $3}')
  74. MAC_DEVICE=$(echo $INTERFACE | awk '{print $2}')
  75. break
  76. fi
  77. done
  78. unset IFS
  79. if [[ $MAC_REAL == "" ]]; then
  80. echo -e "\nNot a valid MAC address found for interface number $number. Aborting.\n"
  81. return 1
  82. fi
  83. }
  84. real_mac
  85. PREV_CONF=$(grep -Ril "$MAC_REAL" /etc/systemd/network/)
  86. if [[ ! $(echo $PREV_CONF | wc -w) -eq 0 ]]; then
  87. echo -e "\nUsing existing configuration file for interface '$MAC_DEVICE':\n$PREV_CONF\n"
  88. linkname=$(basename $PREV_CONF)
  89. MAC_OLD=$(awk -F= '/\[Link\]/{getline; print $2}' $PREV_CONF)
  90. else
  91. MAC_OLD=$MAC_REAL
  92. echo -e "\nPrevious configuration file not found. Creating it (root permission required).\n"
  93. read -r -p "Configuration file name? (must follow syntax: 00-default.link, 41-default.link, 98-default.link etc.): " linkname
  94. if [[ $linkname =~ ^[0-9][0-9]-default.link ]]; then
  95. if [[ ! $(sudo -n true) ]]; then
  96. sudo echo ""
  97. fi
  98. echo -e "[Match]\nMACAddress=$MAC_REAL\n\n[Link]\nMACAddress=$MAC_REAL\nNamePolicy=kernel database onboard slot path" \
  99. | sudo tee /etc/systemd/network/$linkname > /dev/null
  100. echo -e "Created new configuration file: /etc/systemd/network/$linkname\n"
  101. else
  102. echo -e "\nInvalid file name given. Aborting.\n"
  103. return 1
  104. fi
  105. fi
  106. unset response
  107. echo -e "Either randomly generated or manually specified MAC address can be used.\n"
  108. read -r -p "Do you want to use randomly generated MAC address? [Y/n] " response
  109. if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  110. random_mac
  111. geninsert_mac
  112. else
  113. if [[ $(echo $response | sed 's/ //g') =~ ^([nN][oO]|[nN])$ ]]; then
  114. read -r -p "Please type a new MAC address (Syntax is e.g. aa:bb:33:zz:f0:4a): " MAC
  115. maxtries=5
  116. while [[ $maxtries -gt 0 ]]; do
  117. case "$MAC" in
  118. [[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]])
  119. insert_mac
  120. ;;
  121. esac
  122. unset MAC
  123. read -r -p "Invalid MAC address given. Please type again ($maxtries tries left): " MAC
  124. let maxtries--
  125. done
  126. else
  127. echo -e "\nInvalid answer. Aborting.\n"
  128. fi
  129. fi
  130. }
  131. echo -e "\nWARNING: Changing MAC address WILL DISRUPT connections to any network device using MAC-based authentication methods. These devices may include configured routers, WiFi hotspots etc. Remember to write down the new MAC address, and make sure you are authorized to configure the MAC address to all affected network devices if needed.\n"
  132. read -r -p "You are going to spoof a MAC address of a network interface of this computer. Are you sure? [Y/n] " response
  133. if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  134. gen_mac
  135. else
  136. echo -e "\nKeeping old MAC address configuration.\n"
  137. fi