freedombone-mesh-batman 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. #!/bin/bash
  2. # _____ _ _
  3. # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
  4. # | __| _| -_| -_| . | . | | . | . | | -_|
  5. # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
  6. #
  7. # Freedom in the Cloud
  8. #
  9. # Used to enable or disable batman mesh protocol on a given interface
  10. #
  11. # License
  12. # =======
  13. #
  14. # Copyright (C) 2015-2018 Bob Mottram <bob@freedombone.net>
  15. #
  16. # This program is free software: you can redistribute it and/or modify
  17. # it under the terms of the GNU Affero General Public License as published by
  18. # the Free Software Foundation, either version 3 of the License, or
  19. # (at your option) any later version.
  20. #
  21. # This program is distributed in the hope that it will be useful,
  22. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. # GNU Affero General Public License for more details.
  25. #
  26. # You should have received a copy of the GNU Affero General Public License
  27. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  28. PROJECT_NAME='freedombone'
  29. COMPLETION_FILE="/root/${PROJECT_NAME}-completed.txt"
  30. # hotspot passphrase must be 5 characters or longer
  31. HOTSPOT_PASSPHRASE="${PROJECT_NAME}"
  32. # The type of interface which the mesh will run on
  33. MESH_INTERFACE_TYPE='wlan'
  34. source /usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-wifi
  35. source /usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-mesh
  36. function status {
  37. batctl o
  38. if grep -q "bmx6" "$MESH_CURRENT_PROTOCOL"; then
  39. bmx6 -c show=originators
  40. fi
  41. if grep -q "bmx7" "$MESH_CURRENT_PROTOCOL"; then
  42. bmx7 -c show=originators
  43. fi
  44. }
  45. function stop {
  46. if [ ! -f "$MESH_CURRENT_PROTOCOL" ]; then
  47. return
  48. fi
  49. if [ -z "$IFACE" ]; then
  50. echo 'error: unable to find wifi interface, not enabling batman-adv mesh'
  51. return
  52. fi
  53. systemctl stop bmx6
  54. if [ -d /etc/bmx7 ]; then
  55. systemctl stop bmx7
  56. fi
  57. systemctl stop olsr2
  58. systemctl stop babel
  59. systemctl disable bmx6
  60. systemctl disable bmx7
  61. systemctl disable olsr2
  62. systemctl disable babel
  63. systemctl stop dnsmasq
  64. systemctl disable dnsmasq
  65. # shellcheck disable=SC2153
  66. if [ "$EIFACE" ]; then
  67. if [[ "$EIFACE" != "$IFACE" ]] ; then
  68. brctl delif "$BRIDGE" bat0
  69. ifconfig "$BRIDGE" down || true
  70. ethernet_connected=$(cat "/sys/class/net/$EIFACE/carrier")
  71. if [[ "$ethernet_connected" != "0" ]]; then
  72. systemctl stop hostapd
  73. brctl delif "$BRIDGE" "$EIFACE"
  74. ifconfig "$EIFACE" down -promisc
  75. fi
  76. brctl delbr "$BRIDGE"
  77. fi
  78. fi
  79. ifconfig bat0 down -promisc
  80. batctl if del "$IFACE"
  81. ifconfig "$IFACE" mtu 1500
  82. ifconfig "$IFACE" down
  83. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  84. iwconfig "$IFACE" mode managed
  85. fi
  86. if [ "$IFACE_SECONDARY" ]; then
  87. systemctl stop hostapd
  88. systemctl disable hostapd
  89. batctl if del "$IFACE_SECONDARY"
  90. ifconfig "$IFACE_SECONDARY" mtu 1500
  91. ifconfig "$IFACE_SECONDARY" down
  92. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  93. iwconfig "$IFACE_SECONDARY" mode managed
  94. fi
  95. fi
  96. rmmod batman-adv
  97. disable_mesh_firewall
  98. systemctl restart network-manager
  99. if [ -f "$MESH_CURRENT_PROTOCOL" ]; then
  100. rm "$MESH_CURRENT_PROTOCOL"
  101. fi
  102. }
  103. function verify {
  104. tempfile="$(mktemp)"
  105. batctl o > "$tempfile"
  106. if grep -q "disabled" "$tempfile"; then
  107. echo $'B.A.T.M.A.N. not enabled'
  108. rm "$tempfile"
  109. stop
  110. exit 726835
  111. fi
  112. echo $'B.A.T.M.A.N. is running'
  113. rm "$tempfile"
  114. }
  115. function add_wifi_interface {
  116. ifname=$1
  117. ifssid=$WIFI_SSID
  118. if [ "$2" ]; then
  119. ifssid=$2
  120. fi
  121. ifmode=ad-hoc
  122. if [ "$3" ]; then
  123. ifmode=$3
  124. fi
  125. ifchannel=$CHANNEL
  126. if [ "$4" ]; then
  127. ifchannel=$4
  128. fi
  129. ifconfig "$ifname" down
  130. ifconfig "$ifname" mtu 1532
  131. peermac=$(assign_peer_address)
  132. if [ ! "$peermac" ]; then
  133. echo $"Unable to obtain MAC address for $peermac on $ifname"
  134. return
  135. fi
  136. ifconfig "$ifname" hw ether "$peermac"
  137. echo $"$ifname assigned MAC address $peermac"
  138. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  139. iwconfig "$ifname" enc off
  140. iwconfig "$ifname" mode "$ifmode" essid "$ifssid" channel "$ifchannel"
  141. fi
  142. batctl if add "$ifname"
  143. ifconfig "$ifname" up
  144. }
  145. # shellcheck disable=SC2120
  146. function start {
  147. update_wifi_adaptors "${MESH_INTERFACE_TYPE}"
  148. if [ -z "$IFACE" ] ; then
  149. echo 'error: unable to find wifi interface, not enabling batman-adv mesh'
  150. exit 723657
  151. fi
  152. echo "info: enabling batman-adv mesh network $WIFI_SSID on $IFACE"
  153. stop
  154. systemctl stop network-manager
  155. sleep 5
  156. systemctl stop dnsmasq
  157. systemctl disable dnsmasq
  158. # remove an avahi service which isn't used
  159. if [ -f /etc/avahi/services/udisks.service ]; then
  160. sudo rm /etc/avahi/services/udisks.service
  161. fi
  162. global_rate_limit
  163. # Might have to re-enable wifi
  164. rfkill unblock "$(rfkill list|awk -F: "/phy/ {print $1}")" || true
  165. secondary_wifi_available=
  166. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  167. if [ "$IFACE_SECONDARY" ]; then
  168. if [[ "$IFACE" != "$IFACE_SECONDARY" ]]; then
  169. if [ -d /etc/hostapd ]; then
  170. if [ ${#HOTSPOT_PASSPHRASE} -gt 4 ]; then
  171. secondary_wifi_available=1
  172. else
  173. echo $'Hotspot passphrase is too short'
  174. fi
  175. fi
  176. fi
  177. fi
  178. fi
  179. modprobe batman-adv
  180. # avahi on ipv6
  181. sed -i 's|use-ipv4=.*|use-ipv4=no|g' /etc/avahi/avahi-daemon.conf
  182. sed -i 's|use-ipv6=.*|use-ipv6=yes|g' /etc/avahi/avahi-daemon.conf
  183. # set the wifi interface for layer 3 routing
  184. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx6 dev=${IFACE}|g" /etc/systemd/system/bmx6.service
  185. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx7 dev=${IFACE}|g" /etc/systemd/system/bmx7.service
  186. sed -i "s|ExecStart=.*|ExecStart=/usr/local/sbin/olsrd2_static ${IFACE}|g" /etc/systemd/system/olsr2.service
  187. sed -i "s|ExecStart=.*|ExecStart=/usr/local/bin/babeld ${IFACE}|g" /etc/systemd/system/babel.service
  188. systemctl daemon-reload
  189. add_wifi_interface "$IFACE" "$WIFI_SSID" ad-hoc "$CHANNEL"
  190. # NOTE: Don't connect the secondary wifi device. hostapd will handle that by itself
  191. ifconfig bat0 up promisc
  192. brctl addbr "$BRIDGE"
  193. brctl addif "$BRIDGE" bat0
  194. ifconfig bat0 0.0.0.0
  195. ethernet_connected='0'
  196. if [ "$EIFACE" ] ; then
  197. if [[ "$EIFACE" != "$IFACE" ]] ; then
  198. ethernet_connected=$(cat "/sys/class/net/$EIFACE/carrier")
  199. if [[ "$ethernet_connected" != "0" ]]; then
  200. echo $'Trying ethernet bridge to the internet'
  201. brctl addif "$BRIDGE" "$EIFACE"
  202. ifconfig "$EIFACE" 0.0.0.0
  203. ifconfig "$EIFACE" up promisc
  204. echo $'End of internet bridge'
  205. # set the wifi interfaces for layer 3 routing
  206. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx6 dev=${IFACE} dev=${EIFACE}|g" /etc/systemd/system/bmx6.service
  207. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx7 dev=${IFACE} dev=${EIFACE}|g" /etc/systemd/system/bmx7.service
  208. sed -i "s|ExecStart=.*|ExecStart=/usr/local/sbin/olsrd2_static ${IFACE} ${EIFACE}|g" /etc/systemd/system/olsr2.service
  209. sed -i "s|ExecStart=.*|ExecStart=/usr/local/bin/babeld ${IFACE} ${EIFACE}|g" /etc/systemd/system/babel.service
  210. systemctl daemon-reload
  211. else
  212. echo $"$EIFACE is not connected"
  213. fi
  214. fi
  215. fi
  216. ifconfig "$BRIDGE" up
  217. dhclient "$BRIDGE"
  218. enable_mesh_seconary_wifi
  219. enable_mesh_firewall
  220. enable_mesh_scuttlebot
  221. enable_mesh_tor
  222. sed -i "s|server_name .*|server_name ${HOSTNAME}.local;|g" /etc/nginx/sites-available/git_ssb
  223. systemctl restart nginx
  224. if [ ! -f "$MESH_DEFAULT_PROTOCOL" ]; then
  225. echo 'bmx6' > "$MESH_DEFAULT_PROTOCOL"
  226. fi
  227. if grep -q "bmx6" "$MESH_DEFAULT_PROTOCOL"; then
  228. systemctl enable bmx6
  229. systemctl restart bmx6
  230. sed -i 's|<type>.*|<type>_bmx6._tcp</type>|g' /etc/avahi/services/routing.service
  231. fi
  232. if grep -q "bmx7" "$MESH_DEFAULT_PROTOCOL"; then
  233. systemctl enable bmx7
  234. systemctl restart bmx7
  235. sed -i 's|<type>.*|<type>_bmx7._tcp</type>|g' /etc/avahi/services/routing.service
  236. fi
  237. if grep -q "olsr" "$MESH_DEFAULT_PROTOCOL"; then
  238. IFACE=$(grep ExecStart "/etc/systemd/system/olsr2.service" | awk -F ' ' '{print $2}')
  239. mesh_generate_ipv6_address "$IFACE"
  240. systemctl enable olsr2
  241. systemctl restart olsr2
  242. sed -i 's|<type>.*|<type>_olsr2._tcp</type>|g' /etc/avahi/services/routing.service
  243. fi
  244. if grep -q "babel" "$MESH_DEFAULT_PROTOCOL"; then
  245. IFACE=$(grep ExecStart /etc/systemd/system/babel.service | awk -F ' ' '{print $2}')
  246. mesh_generate_ipv6_address "$IFACE"
  247. systemctl enable babel
  248. systemctl restart babel
  249. sed -i 's|<type>.*|<type>_babel._tcp</type>|g' /etc/avahi/services/routing.service
  250. fi
  251. systemctl restart avahi-daemon
  252. verify
  253. cat "$MESH_DEFAULT_PROTOCOL" > "$MESH_CURRENT_PROTOCOL"
  254. }
  255. function monitor {
  256. if [[ "$MESH_INTERFACE_TYPE" != 'wlan'* ]]; then
  257. return
  258. fi
  259. if [ -z "$IFACE" ] ; then
  260. echo 'error: unable to find wifi interface, not enabling batman-adv mesh'
  261. exit 723657
  262. fi
  263. clear
  264. echo ''
  265. echo $'*** Stopping network ***'
  266. echo ''
  267. stop
  268. echo "info: monitoring mesh network $WIFI_SSID on $IFACE"
  269. systemctl stop network-manager
  270. sleep 5
  271. clear
  272. echo ''
  273. echo $'*** Setting firewall rate limit ***'
  274. echo ''
  275. global_rate_limit
  276. clear
  277. echo ''
  278. echo $'*** Enabling wifi adaptor in monitor mode ***'
  279. echo ''
  280. # Might have to re-enable wifi
  281. rfkill unblock "$(rfkill list|awk -F: "/phy/ {print $1}")" || true
  282. ifconfig "$IFACE" down
  283. ifconfig "$IFACE" mtu 1532
  284. ifconfig "$IFACE" hw ether "$(assign_peer_address)"
  285. iwconfig "$IFACE" enc off
  286. iwconfig "$IFACE" mode monitor channel "$CHANNEL"
  287. sleep 1
  288. iwconfig "$IFACE" ap "$CELLID"
  289. modprobe batman-adv
  290. batctl if add "$IFACE"
  291. ifconfig "$IFACE" up
  292. horst -i "$IFACE"
  293. clear
  294. echo ''
  295. echo $'*** Restarting the network daemon. This may take a while. ***'
  296. echo ''
  297. # shellcheck disable=SC2119
  298. start
  299. }
  300. # optionally a file can contain the mesh interface type
  301. mesh_interface_type_file=/root/.mesh_interface_type
  302. if [ -f "$mesh_interface_type_file" ]; then
  303. MESH_INTERFACE_TYPE=$(head -n 1 < "$mesh_interface_type_file")
  304. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  305. MESH_INTERFACE_TYPE='wlan'
  306. fi
  307. if [[ "$MESH_INTERFACE_TYPE" == 'eth'* ]]; then
  308. MESH_INTERFACE_TYPE='eth'
  309. fi
  310. fi
  311. mesh_protocol_init
  312. if [[ "$MESH_INTERFACE_TYPE" == 'eth'* ]]; then
  313. MESH_INTERFACE_TYPE='eth'
  314. fi
  315. update_wifi_adaptors "${MESH_INTERFACE_TYPE}"
  316. if [ ! "$IFACE" ]; then
  317. echo $'No wlan adaptor'
  318. exit 0
  319. fi
  320. if [ -e /etc/default/batctl ]; then
  321. # shellcheck disable=SC1091
  322. . /etc/default/batctl
  323. fi
  324. if ! grep -q "$IFACE" /proc/net/dev; then
  325. echo "Interface \$IFACE was not found"
  326. stop
  327. exit 1
  328. fi
  329. case "$1" in
  330. start|stop|status|monitor)
  331. $1
  332. ;;
  333. restart)
  334. clear
  335. echo ''
  336. echo $'*** Stopping mesh network connection ***'
  337. echo ''
  338. stop
  339. sleep 10
  340. clear
  341. echo ''
  342. echo $'*** Starting mesh network connection ***'
  343. echo ''
  344. # shellcheck disable=SC2119
  345. start
  346. ;;
  347. ping)
  348. batctl ping "$2"
  349. ;;
  350. data)
  351. watch -n1 "batctl s | grep mgmt | grep bytes"
  352. ;;
  353. ls|list)
  354. avahi-browse -atl
  355. ;;
  356. *)
  357. echo "error: invalid parameter $1"
  358. echo "usage: \$0 {start|stop|restart|status|ping|ls|list}"
  359. exit 2
  360. ;;
  361. esac
  362. exit 0