freedombone-app-scuttlebot 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. #!/bin/bash
  2. #
  3. # .---. . .
  4. # | | |
  5. # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
  6. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
  7. # ' ' --' --' -' - -' ' ' -' -' -' ' - --'
  8. #
  9. # Freedom in the Cloud
  10. #
  11. # scuttlebot pub application. Enables nat traversal for SSB.
  12. # https://scuttlebot.io
  13. #
  14. # License
  15. # =======
  16. #
  17. # Copyright (C) 2017-2018 Bob Mottram <bob@freedombone.net>
  18. #
  19. # This program is free software: you can redistribute it and/or modify
  20. # it under the terms of the GNU Affero General Public License as published by
  21. # the Free Software Foundation, either version 3 of the License, or
  22. # (at your option) any later version.
  23. #
  24. # This program is distributed in the hope that it will be useful,
  25. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. # GNU Affero General Public License for more details.
  28. #
  29. # You should have received a copy of the GNU Affero General Public License
  30. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  31. VARIANTS='full full-vim social'
  32. IN_DEFAULT_INSTALL=0
  33. SHOW_ON_ABOUT=0
  34. SHOW_ICANN_ADDRESS_ON_ABOUT=0
  35. SCUTTLEBOT_DOMAIN_NAME=
  36. SCUTTLEBOT_CODE=
  37. SCUTTLEBOT_VERSION='10.4.6'
  38. SCUTTLEBOT_PORT=8010
  39. SCUTTLEBOT_ONION_PORT=8623
  40. GIT_SSB_PORT=7718
  41. NGINX_GIT_SSB_PORT=7719
  42. scuttlebot_variables=(MY_USERNAME
  43. SCUTTLEBOT_DOMAIN_NAME
  44. SCUTTLEBOT_CODE
  45. DEFAULT_DOMAIN_NAME
  46. SYSTEM_TYPE)
  47. function logging_on_scuttlebot {
  48. echo -n ''
  49. }
  50. function logging_off_scuttlebot {
  51. echo -n ''
  52. }
  53. function scuttlebot_create_invite {
  54. invite_string=$(su -c "sbot invite.create 1" - scuttlebot | sed 's/"//g')
  55. clear
  56. echo -e "\\n\\nYour Scuttlebot invite code is:\\n\\n${invite_string}\\n\\n"
  57. # shellcheck disable=SC2034
  58. read -n1 -r -p $"Press any key to continue..." key
  59. }
  60. function configure_interactive_scuttlebot {
  61. W=(1 $"Create an invite")
  62. while true
  63. do
  64. # shellcheck disable=SC2068
  65. selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Scuttlebot" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
  66. if [ ! "$selection" ]; then
  67. break
  68. fi
  69. case $selection in
  70. 1) scuttlebot_create_invite;;
  71. esac
  72. done
  73. }
  74. function remove_user_scuttlebot {
  75. echo -n ''
  76. # remove_username="$1"
  77. }
  78. function add_user_scuttlebot {
  79. # new_username="$1"
  80. # new_user_password="$2"
  81. echo '0'
  82. }
  83. function install_interactive_scuttlebot {
  84. if [[ $ONION_ONLY != "no" ]]; then
  85. SCUTTLEBOT_DOMAIN_NAME='scuttlebot.local'
  86. write_config_param "SCUTTLEBOT_DOMAIN_NAME" "$SCUTTLEBOT_DOMAIN_NAME"
  87. else
  88. function_check interactive_site_details
  89. interactive_site_details scuttlebot
  90. fi
  91. APP_INSTALLED=1
  92. }
  93. function change_password_scuttlebot {
  94. # new_username="$1"
  95. # new_user_password="$2"
  96. echo '0'
  97. }
  98. function reconfigure_scuttlebot {
  99. if [ -d /etc/scuttlebot/.ssb ]; then
  100. systemctl stop scuttlebot
  101. rm -rf /etc/scuttlebot/.ssb
  102. systemctl start scuttlebot
  103. fi
  104. }
  105. function upgrade_scuttlebot {
  106. if ! grep -q 'scuttlebot version:' $"COMPLETION_FILE"; then
  107. return
  108. fi
  109. CURR_SCUTTLEBOT_VERSION=$(get_completion_param "scuttlebot version")
  110. echo "scuttlebot current version: ${CURR_SCUTTLEBOT_VERSION}"
  111. echo "scuttlebot app version: ${SCUTTLEBOT_VERSION}"
  112. if [[ "${CURR_SCUTTLEBOT_VERSION}" == "${SCUTTLEBOT_VERSION}" ]]; then
  113. return
  114. fi
  115. if ! npm upgrade -g scuttlebot@${SCUTTLEBOT_VERSION} --save; then
  116. return
  117. fi
  118. sed -i "s|scuttlebot version.*|scuttlebot version:${SCUTTLEBOT_VERSION}|g" "${COMPLETION_FILE}"
  119. }
  120. function backup_local_scuttlebot {
  121. if [ -d /etc/scuttlebot/.ssb ]; then
  122. systemctl stop scuttlebot
  123. function_check backup_directory_to_usb
  124. backup_directory_to_usb /etc/scuttlebot/.ssb scuttlebot
  125. systemctl start scuttlebot
  126. fi
  127. }
  128. function restore_local_scuttlebot {
  129. if [ -d /etc/scuttlebot ]; then
  130. systemctl stop scuttlebot
  131. temp_restore_dir=/root/tempscuttlebot
  132. function_check restore_directory_from_usb
  133. restore_directory_from_usb $temp_restore_dir scuttlebot
  134. if [ -d $temp_restore_dir/etc/scuttlebot/.ssb ]; then
  135. cp -r $temp_restore_dir/etc/scuttlebot/.ssb /etc/scuttlebot/
  136. else
  137. cp -r $temp_restore_dir/* /etc/scuttlebot/.ssb/*
  138. fi
  139. systemctl start scuttlebot
  140. rm -rf $temp_restore_dir
  141. fi
  142. }
  143. function backup_remote_scuttlebot {
  144. if [ -d /etc/scuttlebot/.ssb ]; then
  145. systemctl stop scuttlebot
  146. function_check backup_directory_to_friend
  147. backup_directory_to_friend /etc/scuttlebot/.ssb scuttlebot
  148. systemctl start scuttlebot
  149. fi
  150. }
  151. function restore_remote_scuttlebot {
  152. if [ -d /etc/scuttlebot ]; then
  153. systemctl stop scuttlebot
  154. temp_restore_dir=/root/tempscuttlebot
  155. function_check restore_directory_from_friend
  156. restore_directory_from_friend $temp_restore_dir scuttlebot
  157. if [ -d $temp_restore_dir/etc/scuttlebot/.ssb ]; then
  158. cp -r $temp_restore_dir/etc/scuttlebot/.ssb /etc/scuttlebot/
  159. else
  160. cp -r $temp_restore_dir/* /etc/scuttlebot/.ssb/*
  161. fi
  162. systemctl start scuttlebot
  163. rm -rf $temp_restore_dir
  164. fi
  165. }
  166. function remove_scuttlebot {
  167. firewall_remove ${SCUTTLEBOT_PORT}
  168. firewall_remove ${GIT_SSB_PORT}
  169. if [ $SCUTTLEBOT_DOMAIN_NAME ]; then
  170. nginx_dissite ${SCUTTLEBOT_DOMAIN_NAME}
  171. rm /etc/nginx/sites-available/${SCUTTLEBOT_DOMAIN_NAME}
  172. fi
  173. systemctl stop git_ssb
  174. systemctl stop scuttlebot
  175. systemctl disable git_ssb
  176. systemctl disable scuttlebot
  177. rm /etc/systemd/system/git_ssb.service
  178. rm /etc/systemd/system/scuttlebot.service
  179. systemctl daemon-reload
  180. userdel -r scuttlebot
  181. if [ -d /etc/scuttlebot ]; then
  182. rm -rf /etc/scuttlebot
  183. fi
  184. if [ -f /usr/bin/git-ssb-create ]; then
  185. rm /usr/bin/git-ssb-create
  186. fi
  187. remove_completion_param install_scuttlebot
  188. sed -i '/scuttlebot /d' "$COMPLETION_FILE"
  189. }
  190. function git_ssb_script {
  191. if [[ "$1" == "mesh" ]]; then
  192. # shellcheck disable=SC2154
  193. git_ssb_script_name=$rootdir/usr/bin/git-ssb-create
  194. git_ssb_daemon_filename=$rootdir/etc/systemd/system/git_ssb.service
  195. else
  196. git_ssb_script_name=/usr/bin/git-ssb-create
  197. git_ssb_daemon_filename=/etc/systemd/system/git_ssb.service
  198. fi
  199. { echo '#!/bin/bash';
  200. echo "reponame=\"\$1\"";
  201. echo '';
  202. echo "if [[ \"\$reponame\" != \"\" ]]; then";
  203. echo " mkdir \$reponame";
  204. echo " cd \$reponame";
  205. echo ' git init';
  206. echo " git ssb create ssb \$reponame";
  207. echo ' git push --tags ssb master';
  208. echo 'fi';
  209. echo 'exit 0'; } > $git_ssb_script_name
  210. chmod +x $git_ssb_script_name
  211. { echo '[Unit]';
  212. echo 'Description=Git SSB (SSB git web interface)';
  213. echo 'After=syslog.target';
  214. echo 'After=network.target';
  215. echo 'After=scuttlebot.target';
  216. echo '';
  217. echo '[Service]';
  218. echo 'Type=simple';
  219. echo 'User=scuttlebot';
  220. echo 'Group=scuttlebot';
  221. echo "WorkingDirectory=/etc/scuttlebot";
  222. echo "ExecStart=/usr/bin/git ssb web --public localhost:$GIT_SSB_PORT";
  223. echo 'Restart=always';
  224. echo 'Environment="USER=scuttlebot"';
  225. echo '';
  226. echo '[Install]';
  227. echo 'WantedBy=multi-user.target'; } > $git_ssb_daemon_filename
  228. }
  229. function scuttlebot_git_setup {
  230. if [[ "$1" == "mesh" ]]; then
  231. if [ ! -d "$rootdir/usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web/highlight" ]; then
  232. mkdir "$rootdir/usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web/highlight"
  233. fi
  234. if [ ! -f "$rootdir/usr/local/lib/node_modules/git-ssb/node_modules/highlight.js/styles/foundation.css" ]; then
  235. echo $'Could not find foundation.css'
  236. exit 347687245
  237. fi
  238. cp "$rootdir/usr/local/lib/node_modules/git-ssb/node_modules/highlight.js/styles/foundation.css" "$rootdir/usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web/highlight/foundation.css"
  239. git_ssb_nginx_site=$rootdir/etc/nginx/sites-available/git_ssb
  240. { echo 'server {';
  241. echo " listen $NGINX_GIT_SSB_PORT default_server;";
  242. echo " server_name P${PEER_ID}.local;";
  243. echo '';
  244. echo ' access_log /dev/null;';
  245. echo ' error_log /dev/null;';
  246. echo '';
  247. echo ' add_header X-XSS-Protection "1; mode=block";';
  248. echo ' add_header X-Content-Type-Options nosniff;';
  249. echo ' add_header X-Frame-Options SAMEORIGIN;'; } > "$git_ssb_nginx_site"
  250. else
  251. if [ ! $SCUTTLEBOT_DOMAIN_NAME ]; then
  252. exit 7357225
  253. fi
  254. if [ ! -d /usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web/highlight ]; then
  255. mkdir /usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web/highlight
  256. fi
  257. if [ ! -f /usr/local/lib/node_modules/git-ssb/node_modules/highlight.js/styles/foundation.css ]; then
  258. echo $'Could not find foundation.css'
  259. exit 347687245
  260. fi
  261. cp /usr/local/lib/node_modules/git-ssb/node_modules/highlight.js/styles/foundation.css /usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web/highlight/foundation.css
  262. git_ssb_nginx_site=/etc/nginx/sites-available/${SCUTTLEBOT_DOMAIN_NAME}
  263. function_check nginx_http_redirect
  264. nginx_http_redirect $SCUTTLEBOT_DOMAIN_NAME "index index.html"
  265. { echo 'server {';
  266. echo ' listen 443 ssl;';
  267. echo ' #listen [::]:443 ssl;';
  268. echo " server_name $SCUTTLEBOT_DOMAIN_NAME;";
  269. echo ''; } >> $git_ssb_nginx_site
  270. function_check nginx_compress
  271. nginx_compress $SCUTTLEBOT_DOMAIN_NAME
  272. echo '' >> "$git_ssb_nginx_site"
  273. echo ' # Security' >> "$git_ssb_nginx_site"
  274. function_check nginx_ssl
  275. nginx_ssl $SCUTTLEBOT_DOMAIN_NAME
  276. function_check nginx_security_options
  277. nginx_security_options $SCUTTLEBOT_DOMAIN_NAME
  278. fi
  279. { echo '';
  280. echo ' root /usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web;';
  281. echo '';
  282. echo ' location = / {';
  283. echo " proxy_pass http://localhost:${GIT_SSB_PORT};";
  284. echo " proxy_set_header X-Real-IP \$remote_addr;";
  285. echo " proxy_set_header Host \$host;";
  286. echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;";
  287. echo ' proxy_http_version 1.1;';
  288. echo " proxy_set_header Upgrade \$http_upgrade;";
  289. echo ' proxy_set_header Connection upgrade;';
  290. echo ' }';
  291. echo '}'; } >> $git_ssb_nginx_site
  292. if [ "$SCUTTLEBOT_ONION_HOSTNAME" ]; then
  293. { echo '';
  294. echo 'server {';
  295. echo " listen 127.0.0.1:${SCUTTLEBOT_ONION_PORT} default_server;";
  296. echo " server_name ${SCUTTLEBOT_ONION_HOSTNAME};";
  297. echo '';
  298. echo ' access_log /dev/null;';
  299. echo ' error_log /dev/null;';
  300. echo '';
  301. echo ' add_header X-XSS-Protection "1; mode=block";';
  302. echo ' add_header X-Content-Type-Options nosniff;';
  303. echo ' add_header X-Frame-Options SAMEORIGIN;';
  304. echo '';
  305. echo ' root /usr/local/lib/node_modules/git-ssb/node_modules/git-ssb-web;';
  306. echo '';
  307. echo ' location = / {';
  308. echo " proxy_pass http://localhost:${GIT_SSB_PORT};";
  309. echo " proxy_set_header X-Real-IP \$remote_addr;";
  310. echo " proxy_set_header Host \$host;";
  311. echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;";
  312. echo ' proxy_http_version 1.1;';
  313. echo " proxy_set_header Upgrade \$http_upgrade;";
  314. echo ' proxy_set_header Connection upgrade;';
  315. echo ' }';
  316. echo '}'; } >> $git_ssb_nginx_site
  317. fi
  318. if [[ "$1" != "mesh" ]]; then
  319. nginx_ensite git_ssb
  320. fi
  321. }
  322. function mesh_install_dat {
  323. get_npm_arch
  324. cat <<EOF > "$rootdir/usr/bin/install_dat"
  325. #!/bin/bash
  326. npm install --arch=$NPM_ARCH -g dat
  327. EOF
  328. chroot "$rootdir" /bin/chmod +x /usr/bin/install_dat
  329. chroot "$rootdir" /usr/bin/install_dat
  330. rm "$rootdir/usr/bin/install_dat"
  331. }
  332. function install_dat {
  333. npm install -g dat
  334. }
  335. function mesh_install_scuttlebot {
  336. SCUTTLEBOT_ONION_HOSTNAME=
  337. mesh_install_dat
  338. get_npm_arch
  339. cat <<EOF > "$rootdir/usr/bin/install_scuttlebot"
  340. #!/bin/bash
  341. npm install --arch=$NPM_ARCH -g scuttlebot@${SCUTTLEBOT_VERSION}
  342. npm install --arch=$NPM_ARCH -g git-ssb
  343. npm install --arch=$NPM_ARCH -g git-remote-ssb
  344. EOF
  345. chroot "$rootdir" /bin/chmod +x /usr/bin/install_scuttlebot
  346. chroot "$rootdir" /usr/bin/install_scuttlebot
  347. rm "$rootdir/usr/bin/install_scuttlebot"
  348. if [ ! -f "$rootdir/usr/local/bin/sbot" ]; then
  349. echo $'Scuttlebot was not installed'
  350. exit 528253
  351. fi
  352. if [ ! -d "$rootdir/etc/scuttlebot" ]; then
  353. mkdir -p "$rootdir/etc/scuttlebot"
  354. fi
  355. # an unprivileged user to run as
  356. chroot "$rootdir" useradd -d /etc/scuttlebot/ scuttlebot
  357. # daemon
  358. { echo '[Unit]';
  359. echo 'Description=Scuttlebot (messaging system)';
  360. echo 'After=syslog.target';
  361. echo 'After=network.target';
  362. echo '';
  363. echo '[Service]';
  364. echo 'Type=simple';
  365. echo 'User=scuttlebot';
  366. echo 'Group=scuttlebot';
  367. echo "WorkingDirectory=/etc/scuttlebot";
  368. echo 'ExecStart=/usr/local/bin/sbot server';
  369. echo 'Restart=always';
  370. echo 'Environment="USER=scuttlebot"';
  371. echo '';
  372. echo '[Install]';
  373. echo 'WantedBy=multi-user.target'; } > "$rootdir/etc/systemd/system/scuttlebot.service"
  374. scuttlebot_git_setup mesh
  375. git_ssb_script mesh
  376. }
  377. function install_scuttlebot {
  378. function_check install_nodejs
  379. install_nodejs scuttlebot
  380. npm install -g scuttlebot@${SCUTTLEBOT_VERSION}
  381. if [ ! -f /usr/local/bin/sbot ]; then
  382. exit 528253
  383. fi
  384. install_dat
  385. npm install -g git-ssb
  386. npm install -g git-remote-ssb
  387. if [ ! -d /etc/scuttlebot ]; then
  388. mkdir -p /etc/scuttlebot
  389. fi
  390. npm install -g dat
  391. # an unprivileged user to run as
  392. useradd -d /etc/scuttlebot/ scuttlebot
  393. # daemon
  394. { echo '[Unit]';
  395. echo 'Description=Scuttlebot (messaging system)';
  396. echo 'After=syslog.target';
  397. echo 'After=network.target';
  398. echo '';
  399. echo '[Service]';
  400. echo 'Type=simple';
  401. echo 'User=scuttlebot';
  402. echo 'Group=scuttlebot';
  403. echo "WorkingDirectory=/etc/scuttlebot";
  404. echo 'ExecStart=/usr/local/bin/sbot server';
  405. echo 'Restart=always';
  406. echo 'Environment="USER=scuttlebot"';
  407. echo '';
  408. echo '[Install]';
  409. echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/scuttlebot.service
  410. chown -R scuttlebot:scuttlebot /etc/scuttlebot
  411. # files gw_name myhostname mdns4_minimal [NOTFOUND=return] dns
  412. sed -i "s|hosts:.*|hosts: files mdns4_minimal dns mdns4 mdns|g" /etc/nsswitch.conf
  413. # start the daemon
  414. systemctl enable scuttlebot.service
  415. systemctl daemon-reload
  416. systemctl start scuttlebot.service
  417. sleep 3
  418. if [ ! -d /etc/scuttlebot/.ssb ]; then
  419. echo $'Scuttlebot config not generated'
  420. exit 73528
  421. fi
  422. SCUTTLEBOT_ONION_HOSTNAME=$(add_onion_service scuttlebot 80 ${SCUTTLEBOT_ONION_PORT})
  423. if [[ "$ONION_ONLY" == 'no' ]]; then
  424. { echo '{';
  425. echo " \"host\": \"${DEFAULT_DOMAIN_NAME}\",";
  426. echo ' "tor-only": false,'; } > /etc/scuttlebot/.ssb/config
  427. else
  428. { echo '{';
  429. echo " \"host\": \"${SCUTTLEBOT_ONION_HOSTNAME}\",";
  430. echo ' "tor-only": true,'; } > /etc/scuttlebot/.ssb/config
  431. fi
  432. { echo " \"port\": ${SCUTTLEBOT_PORT},";
  433. echo ' "timeout": 30000,';
  434. echo ' "pub": true,';
  435. echo ' "local": true,';
  436. echo ' "friends": {';
  437. echo ' "dunbar": 150,';
  438. echo ' "hops": 3';
  439. echo ' },';
  440. echo ' "gossip": {';
  441. echo ' "connections": 2';
  442. echo ' },';
  443. echo ' "master": [],';
  444. echo ' "logging": {';
  445. echo ' "level": "error"';
  446. echo ' }';
  447. echo '}'; } >> /etc/scuttlebot/.ssb/config
  448. chown scuttlebot:scuttlebot /etc/scuttlebot/.ssb/config
  449. systemctl restart scuttlebot.service
  450. firewall_add scuttlebot ${SCUTTLEBOT_PORT}
  451. firewall_add git_ssb ${GIT_SSB_PORT}
  452. scuttlebot_git_setup
  453. git_ssb_script
  454. systemctl enable git_ssb.service
  455. systemctl daemon-reload
  456. systemctl start git_ssb.service
  457. function_check create_site_certificate
  458. create_site_certificate ${SCUTTLEBOT_DOMAIN_NAME} 'yes'
  459. systemctl restart nginx
  460. if ! grep -q "scuttlebot version:" "${COMPLETION_FILE}"; then
  461. echo "scuttlebot version:${SCUTTLEBOT_VERSION}" >> "${COMPLETION_FILE}"
  462. else
  463. sed -i "s|scuttlebot version.*|scuttlebot version:${SCUTTLEBOT_VERSION}|g" "${COMPLETION_FILE}"
  464. fi
  465. APP_INSTALLED=1
  466. }
  467. # NOTE: deliberately no exit 0