freedombone-utils-web 49KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272
  1. #!/bin/bash
  2. # _____ _ _
  3. # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
  4. # | __| _| -_| -_| . | . | | . | . | | -_|
  5. # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
  6. #
  7. # Freedom in the Cloud
  8. #
  9. # Web related functions
  10. #
  11. # License
  12. # =======
  13. #
  14. # Copyright (C) 2014-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. # default search engine for command line browser
  29. DEFAULT_SEARCH='https://searx.laquadrature.net'
  30. # onion port for the default domain
  31. DEFAULT_DOMAIN_ONION_PORT=8099
  32. # Whether Let's Encrypt is enabled for all sites
  33. LETSENCRYPT_ENABLED="yes"
  34. LETSENCRYPT_SERVER='https://acme-v01.api.letsencrypt.org/directory'
  35. # list of encryption protocols
  36. SSL_PROTOCOLS="TLSv1 TLSv1.1 TLSv1.2"
  37. # Mozilla recommended default ciphers. These work better on Android
  38. # See https://wiki.mozilla.org/Security/Server_Side_TLS
  39. SSL_CIPHERS="ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
  40. # some mobile apps (eg. NextCloud) have not very good cipher compatibility.
  41. # These ciphers can be used for those cases
  42. SSL_CIPHERS_MOBILE="ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA"
  43. NGINX_ENSITE_REPO="https://github.com/perusio/nginx_ensite"
  44. NGINX_ENSITE_COMMIT='fa4d72ce1c0a490442c8474e9c8dc21ed52c93d0'
  45. # memory limit for php in MB
  46. MAX_PHP_MEMORY=64
  47. # logging level for Nginx
  48. WEBSERVER_LOG_LEVEL='warn'
  49. # test a domain name to see if it's valid
  50. function validate_domain_name {
  51. # count the number of dots in the domain name
  52. dots=${TEST_DOMAIN_NAME//[^.]}
  53. no_of_dots=${#dots}
  54. if (( no_of_dots > 3 )); then
  55. TEST_DOMAIN_NAME=$"The domain $TEST_DOMAIN_NAME has too many subdomains. It should be of the type w.x.y.z, x.y.z or y.z"
  56. fi
  57. if (( no_of_dots == 0 )); then
  58. TEST_DOMAIN_NAME=$"The domain $TEST_DOMAIN_NAME has no top level domain. It should be of the type w.x.y.z, x.y.z or y.z"
  59. fi
  60. }
  61. function nginx_security_options {
  62. domain_name=$1
  63. filename=/etc/nginx/sites-available/$domain_name
  64. { echo ' add_header X-Frame-Options DENY;';
  65. echo ' add_header X-Content-Type-Options nosniff;';
  66. echo ' add_header X-XSS-Protection "1; mode=block";';
  67. echo ' add_header X-Robots-Tag none;';
  68. echo ' add_header X-Download-Options noopen;';
  69. echo ' add_header X-Permitted-Cross-Domain-Policies none;';
  70. echo ''; } >> "$filename"
  71. }
  72. function nginx_limits {
  73. domain_name=$1
  74. max_body='20m'
  75. if [ "$2" ]; then
  76. max_body=$2
  77. fi
  78. filename=/etc/nginx/sites-available/$domain_name
  79. { echo " client_max_body_size ${max_body};";
  80. echo ' client_body_buffer_size 128k;';
  81. echo '';
  82. echo ' limit_conn conn_limit_per_ip 10;';
  83. echo ' limit_req zone=req_limit_per_ip burst=10 nodelay;';
  84. echo ''; } >> "$filename"
  85. }
  86. function nginx_stapling {
  87. domain_name="$1"
  88. filename=/etc/nginx/sites-available/$domain_name
  89. { echo " ssl_stapling on;";
  90. echo ' ssl_stapling_verify on;';
  91. echo " ssl_trusted_certificate /etc/ssl/certs/${domain_name}.pem;";
  92. echo ''; } >> "$filename"
  93. }
  94. function nginx_http_redirect {
  95. # redirect port 80 to https
  96. domain_name=$1
  97. filename=/etc/nginx/sites-available/$domain_name
  98. { echo 'server {';
  99. echo ' listen 80;';
  100. echo ' listen [::]:80;';
  101. echo " server_name ${domain_name};";
  102. echo " root /var/www/${domain_name}/htdocs;";
  103. echo ' access_log /dev/null;';
  104. echo " error_log /dev/null;"; } > "$filename"
  105. function_check nginx_limits
  106. nginx_limits "$domain_name"
  107. if [ ${#2} -gt 0 ]; then
  108. echo " $2;" >> "$filename"
  109. fi
  110. { echo " rewrite ^ https://\$server_name\$request_uri? permanent;";
  111. echo '}';
  112. echo ''; } >> "$filename"
  113. }
  114. function nginx_compress {
  115. domain_name=$1
  116. filename=/etc/nginx/sites-available/$domain_name
  117. { echo ' gzip on;';
  118. echo ' gzip_min_length 1000;';
  119. echo ' gzip_proxied expired no-cache no-store private auth;';
  120. echo ' gzip_types text/plain application/xml;'; } >> "$filename"
  121. }
  122. function nginx_ssl {
  123. # creates the SSL/TLS section for a website
  124. domain_name=$1
  125. mobile_ciphers=$2
  126. filename=/etc/nginx/sites-available/$domain_name
  127. { echo ' ssl_stapling off;';
  128. echo ' ssl_stapling_verify off;';
  129. echo ' ssl on;';
  130. echo " ssl_certificate /etc/letsencrypt/live/${domain_name}/fullchain.pem;";
  131. echo " ssl_certificate_key /etc/letsencrypt/live/${domain_name}/privkey.pem;";
  132. echo " ssl_dhparam /etc/ssl/certs/${domain_name}.dhparam;";
  133. echo '';
  134. echo ' ssl_session_cache builtin:1000 shared:SSL:10m;';
  135. echo ' ssl_session_timeout 60m;';
  136. echo ' ssl_prefer_server_ciphers on;';
  137. echo " ssl_protocols $SSL_PROTOCOLS;"; } >> "$filename"
  138. if [ "$mobile_ciphers" ]; then
  139. echo " # Mobile compatible ciphers" >> "$filename"
  140. echo " ssl_ciphers '$SSL_CIPHERS_MOBILE';" >> "$filename"
  141. else
  142. echo " ssl_ciphers '$SSL_CIPHERS';" >> "$filename"
  143. fi
  144. echo " add_header Content-Security-Policy \"default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'\";" >> "$filename"
  145. #nginx_stapling $1
  146. }
  147. # check an individual domain name
  148. function test_domain_name {
  149. if [ "$1" ]; then
  150. TEST_DOMAIN_NAME=$1
  151. if [[ $TEST_DOMAIN_NAME != 'ttrss' ]]; then
  152. function_check validate_domain_name
  153. validate_domain_name
  154. if [[ "$TEST_DOMAIN_NAME" != "$1" ]]; then
  155. echo $"Invalid domain name $TEST_DOMAIN_NAME"
  156. exit 8528
  157. fi
  158. fi
  159. fi
  160. }
  161. # Checks whether certificates were generated for the given hostname
  162. function check_certificates {
  163. if [ ! "$1" ]; then
  164. echo $'No certificate name provided'
  165. exit 3568736585683
  166. fi
  167. USE_LETSENCRYPT='no'
  168. if [ "$2" ]; then
  169. USE_LETSENCRYPT="$2"
  170. fi
  171. if [[ $USE_LETSENCRYPT == 'no' || "$ONION_ONLY" != 'no' ]]; then
  172. if [ ! -f "/etc/ssl/private/${1}.key" ]; then
  173. echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
  174. exit 63959
  175. fi
  176. if [ ! -f "/etc/ssl/certs/${1}.crt" ]; then
  177. echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
  178. exit 7679
  179. fi
  180. if grep -q "${1}.pem" "/etc/nginx/sites-available/${1}"; then
  181. sed -i "s|${1}.pem|${1}.crt|g" "/etc/nginx/sites-available/${1}"
  182. fi
  183. else
  184. if [ ! -f "/etc/letsencrypt/live/${1}/privkey.pem" ]; then
  185. echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
  186. exit 6282
  187. fi
  188. if [ ! -f "/etc/letsencrypt/live/${1}/fullchain.pem" ]; then
  189. echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
  190. exit 5328
  191. fi
  192. if grep -q "${1}.crt" "/etc/nginx/sites-available/${1}"; then
  193. sed -i "s|${1}.crt|${1}.pem|g" "/etc/nginx/sites-available/${1}"
  194. fi
  195. fi
  196. if [ ! -f "/etc/ssl/certs/${1}.dhparam" ]; then
  197. echo $"DiffieHellman parameters for ${CHECK_HOSTNAME} were not created"
  198. exit 5989
  199. fi
  200. }
  201. function cert_exists {
  202. cert_type='dhparam'
  203. if [ "$2" ]; then
  204. cert_type="$2"
  205. fi
  206. if [ -f "/etc/ssl/certs/${1}.${cert_type}" ]; then
  207. echo "1"
  208. else
  209. if [ -f "/etc/letsencrypt/live/${1}/fullchain.${cert_type}" ]; then
  210. echo "1"
  211. else
  212. echo "0"
  213. fi
  214. fi
  215. }
  216. function create_self_signed_cert {
  217. if [ ! "${SITE_DOMAIN_NAME}" ]; then
  218. echo $'No site domain specified for self signed cert'
  219. exit 4638565385
  220. fi
  221. "${PROJECT_NAME}-addcert" -h "${SITE_DOMAIN_NAME}" --dhkey "${DH_KEYLENGTH}"
  222. function_check check_certificates
  223. check_certificates "${SITE_DOMAIN_NAME}"
  224. }
  225. function create_letsencrypt_cert {
  226. if [ ! "${SITE_DOMAIN_NAME}" ]; then
  227. echo $'No site domain specified for letsencrypt cert'
  228. exit 246824624
  229. fi
  230. if ! "${PROJECT_NAME}-addcert" -e "${SITE_DOMAIN_NAME}" -s "${LETSENCRYPT_SERVER}" --dhkey "${DH_KEYLENGTH}" --email "${MY_EMAIL_ADDRESS}"; then
  231. if [[ ${NO_SELF_SIGNED} == 'no' ]]; then
  232. echo $"Lets Encrypt failed for ${SITE_DOMAIN_NAME}, so try making a self-signed cert"
  233. "${PROJECT_NAME}-addcert" -h "${SITE_DOMAIN_NAME}" --dhkey "${DH_KEYLENGTH}"
  234. function_check check_certificates
  235. CHECK_HOSTNAME="${SITE_DOMAIN_NAME}"
  236. check_certificates "${SITE_DOMAIN_NAME}"
  237. else
  238. echo $"Lets Encrypt failed for $SITE_DOMAIN_NAME"
  239. if [ -f "/etc/nginx/sites-available/$SITE_DOMAIN_NAME" ]; then
  240. nginx_dissite "$SITE_DOMAIN_NAME"
  241. fuser -k 80/tcp
  242. fuser -k 443/tcp
  243. systemctl restart nginx
  244. fi
  245. exit 682529
  246. fi
  247. return
  248. fi
  249. function_check check_certificates
  250. CHECK_HOSTNAME="${SITE_DOMAIN_NAME}"
  251. check_certificates "${SITE_DOMAIN_NAME}" 'yes'
  252. }
  253. function create_site_certificate {
  254. SITE_DOMAIN_NAME="$1"
  255. # if yes then only "valid" certs are allowed, not self-signed
  256. NO_SELF_SIGNED='no'
  257. if [ "$2" ]; then
  258. NO_SELF_SIGNED="$2"
  259. fi
  260. if [[ $ONION_ONLY == "no" ]]; then
  261. if [[ "$(cert_exists "${SITE_DOMAIN_NAME}")" == "0" ]]; then
  262. if [[ $LETSENCRYPT_ENABLED != "yes" ]]; then
  263. create_self_signed_cert
  264. else
  265. create_letsencrypt_cert
  266. fi
  267. else
  268. if [[ $LETSENCRYPT_ENABLED == "yes" ]]; then
  269. if [[ "$(cert_exists "${SITE_DOMAIN_NAME}" pem)" == "0" ]]; then
  270. create_letsencrypt_cert
  271. fi
  272. fi
  273. fi
  274. fi
  275. }
  276. # script to automatically renew any Let's Encrypt certificates
  277. function letsencrypt_renewals {
  278. if [[ $ONION_ONLY != "no" ]]; then
  279. return
  280. fi
  281. renewals_script=/tmp/renewals_letsencrypt
  282. renewals_retry_script=/tmp/renewals_retry_letsencrypt
  283. renewal_failure_msg=$'The certificate for $LETSENCRYPT_DOMAIN could not be renewed'
  284. renewal_email_title=$'${PROJECT_NAME} Lets Encrypt certificate renewal'
  285. # the main script tries to renew once per month
  286. { echo '#!/bin/bash';
  287. echo '';
  288. echo 'if [ -f ~/temp_renewletsencrypt.txt ]; then';
  289. echo ' rm ~/temp_renewletsencrypt.txt';
  290. echo 'fi';
  291. echo '';
  292. echo 'if [ -f /tmp/.upgrading ]; then';
  293. echo ' if [ ! -f ~/letsencrypt_failed ]; then';
  294. echo ' touch ~/letsencrypt_failed';
  295. echo ' fi';
  296. echo ' exit 0';
  297. echo 'fi';
  298. echo '';
  299. echo "PROJECT_NAME='${PROJECT_NAME}'";
  300. echo "COMPLETION_FILE=\$HOME/\${PROJECT_NAME}-completed.txt";
  301. echo '';
  302. echo 'if [ -d /etc/letsencrypt ]; then';
  303. echo ' if [ -f ~/letsencrypt_failed ]; then';
  304. echo ' rm ~/letsencrypt_failed';
  305. echo ' fi';
  306. echo -n " ADMIN_USERNAME=\$(cat \$COMPLETION_FILE | grep \"Admin user\" | ";
  307. echo -n "awk -F ':' '{print ";
  308. echo -n "\$2";
  309. echo "}')";
  310. echo " ADMIN_EMAIL_ADDRESS=\$ADMIN_USERNAME@\$HOSTNAME";
  311. echo ' for d in /etc/letsencrypt/live/*/ ; do';
  312. echo '';
  313. echo ' if [ -f /tmp/.upgrading ]; then';
  314. echo ' if [ ! -f ~/letsencrypt_failed ]; then';
  315. echo ' touch ~/letsencrypt_failed';
  316. echo ' fi';
  317. echo ' exit 0';
  318. echo ' fi';
  319. echo '';
  320. echo -n " LETSENCRYPT_DOMAIN=\$(echo \"\$d\" | ";
  321. echo -n "awk -F '/' '{print ";
  322. echo -n "\$5";
  323. echo "}')";
  324. echo " if [ -f /etc/nginx/sites-available/\$LETSENCRYPT_DOMAIN ]; then";
  325. echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt";
  326. echo ' if [ ! "$?" = "0" ]; then';
  327. echo " echo \"${renewal_failure_msg}\" > ~/temp_renewletsencrypt.txt";
  328. echo ' echo "" >> ~/temp_renewletsencrypt.txt';
  329. echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt 2>> ~/temp_renewletsencrypt.txt";
  330. echo -n " cat ~/temp_renewletsencrypt.txt | mail -s \"${renewal_email_title}\" ";
  331. echo "\$ADMIN_EMAIL_ADDRESS";
  332. echo ' rm ~/temp_renewletsencrypt.txt';
  333. echo ' if [ ! -f ~/letsencrypt_failed ]; then';
  334. echo ' touch ~/letsencrypt_failed';
  335. echo ' fi';
  336. echo ' fi';
  337. echo ' fi';
  338. echo ' done';
  339. echo 'fi'; } > "$renewals_script"
  340. chmod +x "$renewals_script"
  341. if [ ! -f /etc/cron.monthly/letsencrypt ]; then
  342. cp $renewals_script /etc/cron.monthly/letsencrypt
  343. else
  344. HASH1=$(sha256sum $renewals_script | awk -F ' ' '{print $1}')
  345. HASH2=$(sha256sum /etc/cron.monthly/letsencrypt | awk -F ' ' '{print $1}')
  346. if [[ "$HASH1" != "$HASH2" ]]; then
  347. cp $renewals_script /etc/cron.monthly/letsencrypt
  348. fi
  349. fi
  350. rm $renewals_script
  351. # a secondary script keeps trying to renew after a failure
  352. { echo '#!/bin/bash';
  353. echo '';
  354. echo 'if [ -f ~/temp_renewletsencrypt.txt ]; then';
  355. echo ' rm ~/temp_renewletsencrypt.txt';
  356. echo 'fi';
  357. echo '';
  358. echo 'if [ -f /tmp/.upgrading ]; then';
  359. echo ' if [ ! -f ~/letsencrypt_failed ]; then';
  360. echo ' touch ~/letsencrypt_failed';
  361. echo ' fi';
  362. echo ' exit 0';
  363. echo 'fi';
  364. echo '';
  365. echo "PROJECT_NAME='${PROJECT_NAME}'";
  366. echo "COMPLETION_FILE=\$HOME/\${PROJECT_NAME}-completed.txt";
  367. echo '';
  368. echo 'if [ -d /etc/letsencrypt ]; then';
  369. echo ' if [ -f ~/letsencrypt_failed ]; then';
  370. echo ' rm ~/letsencrypt_failed';
  371. echo -n " ADMIN_USERNAME=\$(cat \$COMPLETION_FILE | grep \"Admin user\" | ";
  372. echo -n "awk -F ':' '{print ";
  373. echo -n "\$2";
  374. echo "}')";
  375. echo " ADMIN_EMAIL_ADDRESS=\$ADMIN_USERNAME@\$HOSTNAME";
  376. echo ' for d in /etc/letsencrypt/live/*/ ; do';
  377. echo '';
  378. echo ' if [ -f /tmp/.upgrading ]; then';
  379. echo ' if [ ! -f ~/letsencrypt_failed ]; then';
  380. echo ' touch ~/letsencrypt_failed';
  381. echo ' fi';
  382. echo ' exit 0';
  383. echo ' fi';
  384. echo '';
  385. echo -n " LETSENCRYPT_DOMAIN=\$(echo \"\$d\" | ";
  386. echo -n "awk -F '/' '{print ";
  387. echo -n "\$5";
  388. echo "}')";
  389. echo " if [ -f /etc/nginx/sites-available/\$LETSENCRYPT_DOMAIN ]; then";
  390. echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt";
  391. echo ' if [ ! "$?" = "0" ]; then';
  392. echo " echo \"${renewal_failure_msg}\" > ~/temp_renewletsencrypt.txt";
  393. echo ' echo "" >> ~/temp_renewletsencrypt.txt';
  394. echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt 2>> ~/temp_renewletsencrypt.txt";
  395. echo -n " cat ~/temp_renewletsencrypt.txt | mail -s \"${renewal_email_title}\" ";
  396. echo "\$ADMIN_EMAIL_ADDRESS";
  397. echo ' rm ~/temp_renewletsencrypt.txt';
  398. echo ' if [ ! -f ~/letsencrypt_failed ]; then';
  399. echo ' touch ~/letsencrypt_failed';
  400. echo ' fi';
  401. echo ' fi';
  402. echo ' fi';
  403. echo ' done';
  404. echo ' fi';
  405. echo 'fi'; } > "$renewals_retry_script"
  406. chmod +x "$renewals_retry_script"
  407. if [ ! -f /etc/cron.daily/letsencrypt ]; then
  408. cp $renewals_retry_script /etc/cron.daily/letsencrypt
  409. else
  410. HASH1=$(sha256sum $renewals_retry_script | awk -F ' ' '{print $1}')
  411. HASH2=$(sha256sum /etc/cron.daily/letsencrypt | awk -F ' ' '{print $1}')
  412. if [[ "$HASH1" != "$HASH2" ]]; then
  413. cp $renewals_retry_script /etc/cron.daily/letsencrypt
  414. fi
  415. fi
  416. rm $renewals_retry_script
  417. }
  418. function configure_php {
  419. sed -i "s/memory_limit =.*/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php/7.0/fpm/php.ini
  420. sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php/7.0/fpm/php.ini
  421. sed -i "s/memory_limit =.*/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php/7.0/cli/php.ini
  422. sed -i "s/upload_max_filesize =.*/upload_max_filesize = 50M/g" /etc/php/7.0/fpm/php.ini
  423. sed -i "s/upload_max_filesize =.*/upload_max_filesize = 50M/g" /etc/php/7.0/cli/php.ini
  424. sed -i "s/post_max_size =.*/post_max_size = 50M/g" /etc/php/7.0/fpm/php.ini
  425. }
  426. function install_web_server_access_control {
  427. if [ ! -f /etc/pam.d/nginx ]; then
  428. { echo '#%PAM-1.0';
  429. echo '@include common-auth';
  430. echo '@include common-account';
  431. echo '@include common-session'; } > /etc/pam.d/nginx
  432. fi
  433. }
  434. function upgrade_inadyn_config {
  435. if [ ! -f "${INADYN_CONFIG_FILE}" ]; then
  436. return
  437. fi
  438. if [ ! -f /usr/sbin/inadyn ]; then
  439. return
  440. fi
  441. if grep -q "{" "${INADYN_CONFIG_FILE}"; then
  442. return
  443. fi
  444. read_config_param DDNS_PROVIDER
  445. read_config_param DDNS_USERNAME
  446. read_config_param DDNS_PASSWORD
  447. read_config_param DEFAULT_DOMAIN_NAME
  448. grep "alias " "${INADYN_CONFIG_FILE}" | sed 's| alias ||g' > ~/.inadyn_existing_sites
  449. if [[ "$DDNS_PROVIDER" == "default@freedns.afraid.org" ]]; then
  450. DDNS_PROVIDER='freedns'
  451. write_config_param DDNS_PROVIDER "$DDNS_PROVIDER"
  452. fi
  453. { echo 'period = 300';
  454. echo '';
  455. echo "provider $DDNS_PROVIDER {";
  456. echo " ssl = true";
  457. echo " username = $DDNS_USERNAME";
  458. echo " password = $DDNS_PASSWORD";
  459. echo ' wildcard = true';
  460. echo " hostname = $DEFAULT_DOMAIN_NAME";
  461. echo '}'; } > "${INADYN_CONFIG_FILE}"
  462. }
  463. function install_dynamicdns {
  464. if [[ $SYSTEM_TYPE == "mesh"* ]]; then
  465. return
  466. fi
  467. if [[ $ONION_ONLY != "no" ]]; then
  468. return
  469. fi
  470. if grep -q "INADYN_REPO" "$CONFIGURATION_FILE"; then
  471. sed -i '/INADYN_REPO/d' "$CONFIGURATION_FILE"
  472. fi
  473. if grep -q "INADYN_COMMIT" "$CONFIGURATION_FILE"; then
  474. sed -i '/INADYN_COMMIT/d' "$CONFIGURATION_FILE"
  475. fi
  476. if [ -f /usr/local/sbin/inadyn ]; then
  477. if grep -q "inadyn commit" "$COMPLETION_FILE"; then
  478. sed -i '/inadyn commit/d' "$COMPLETION_FILE"
  479. fi
  480. else
  481. CURR_INADYN_COMMIT=$(get_completion_param "inadyn commit")
  482. if [[ "${CURR_INADYN_COMMIT}" == "${INADYN_COMMIT}" ]]; then
  483. return
  484. fi
  485. fi
  486. if [ -f /usr/local/sbin/inadyn ]; then
  487. if [ -d "$INSTALL_DIR/inadyn" ]; then
  488. rm -rf "$INSTALL_DIR/inadyn"
  489. fi
  490. if [ -d /repos/inadyn ]; then
  491. rm -rf /repos/inadyn
  492. fi
  493. else
  494. # update to the next commit
  495. function_check set_repo_commit
  496. set_repo_commit "$INSTALL_DIR/inadyn" "inadyn commit" "$INADYN_COMMIT" "$INADYN_REPO"
  497. fi
  498. # Here we compile from source because the current package
  499. # doesn't support https, which could result in passwords
  500. # being leaked
  501. # Debian version 1.99.4-1
  502. # https version 1.99.8
  503. apt-get -yq install build-essential curl libgnutls28-dev automake1.11
  504. apt-get -yq install gnutls-dev libconfuse-dev pkg-config libtool
  505. if [ ! -d "$INSTALL_DIR/inadyn" ]; then
  506. if [ -d /repos/inadyn ]; then
  507. mkdir "$INSTALL_DIR/inadyn"
  508. cp -r -p /repos/inadyn/. "$INSTALL_DIR/inadyn"
  509. cd "$INSTALL_DIR/inadyn" || exit 2462874684
  510. git pull
  511. else
  512. git_clone "$INADYN_REPO" "$INSTALL_DIR/inadyn"
  513. fi
  514. fi
  515. if [ ! -d "$INSTALL_DIR/inadyn" ]; then
  516. echo 'inadyn repo not cloned'
  517. echo -n | openssl s_client -showcerts -connect github.com:443 -CApath /etc/ssl/certs
  518. exit 6785
  519. fi
  520. cd "$INSTALL_DIR/inadyn" || exit 246824684
  521. git checkout "$INADYN_COMMIT" -b "$INADYN_COMMIT"
  522. set_completion_param "inadyn commit" "$INADYN_COMMIT"
  523. ./autogen.sh
  524. if ! ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var; then
  525. exit 74890
  526. fi
  527. if ! make -j5; then
  528. exit 74858
  529. fi
  530. if ! make install-strip; then
  531. exit 3785
  532. fi
  533. # create a configuration file
  534. if [ ! -f "${INADYN_CONFIG_FILE}" ]; then
  535. { echo 'period = 300';
  536. echo ''; } > "${INADYN_CONFIG_FILE}"
  537. fi
  538. chmod 600 "${INADYN_CONFIG_FILE}"
  539. { echo '[Unit]';
  540. echo 'Description=Internet Dynamic DNS Client';
  541. echo 'Documentation=man:inadyn';
  542. echo 'Documentation=man:inadyn.conf';
  543. echo 'Documentation=https://github.com/troglobit/inadyn';
  544. echo 'ConditionPathExists=/etc/inadyn.conf';
  545. echo 'After=network-online.target';
  546. echo 'Requires=network-online.target';
  547. echo '';
  548. echo '[Service]';
  549. echo 'Type=simple';
  550. echo "ExecStart=/usr/sbin/inadyn -C -n -s --loglevel=err --config ${INADYN_CONFIG_FILE}";
  551. echo 'Restart=on-failure';
  552. echo 'RestartSec=10';
  553. echo '';
  554. echo '[Install]';
  555. echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/inadyn.service
  556. systemctl daemon-reload
  557. systemctl enable inadyn
  558. systemctl start inadyn
  559. # Remove old version of inadyn
  560. if [ -f /usr/local/sbin/inadyn ]; then
  561. rm /usr/local/sbin/inadyn
  562. upgrade_inadyn_config
  563. fi
  564. }
  565. function update_default_search_engine {
  566. for d in /home/*/ ; do
  567. USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
  568. if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
  569. if ! grep -q "WWW_HOME" "/home/$USERNAME/.bashrc"; then
  570. if ! grep -q 'controluser' "/home/$USERNAME/.bashrc"; then
  571. if ! grep -q 'export WWW_HOME=' "/home/$USERNAME/.bashrc"; then
  572. echo "export WWW_HOME=$DEFAULT_SEARCH" >> "/home/$USERNAME/.bashrc"
  573. else
  574. sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
  575. fi
  576. else
  577. if ! grep -q 'export WWW_HOME=' "/home/$USERNAME/.bashrc"; then
  578. sed -i "/controluser/i export WWW_HOME=$DEFAULT_SEARCH" "/home/$USERNAME/.bashrc"
  579. else
  580. sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
  581. fi
  582. fi
  583. fi
  584. fi
  585. done
  586. }
  587. function install_command_line_browser {
  588. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  589. return
  590. fi
  591. apt-get -yq install elinks
  592. update_default_search_engine
  593. mark_completed "${FUNCNAME[0]}"
  594. }
  595. function mesh_web_server {
  596. if [ -d /etc/apache2 ]; then
  597. # shellcheck disable=SC2154
  598. chroot "$rootdir" apt-get -yq remove --purge apache2
  599. chroot "$rootdir" rm -rf /etc/apache2
  600. fi
  601. chroot "$rootdir" apt-get -yq install nginx
  602. if [ ! -d "$rootdir/etc/nginx" ]; then
  603. echo $'Unable to install web server'
  604. exit 346825
  605. fi
  606. }
  607. function install_web_server {
  608. if [ "$INSTALLING_MESH" ]; then
  609. mesh_web_server
  610. return
  611. fi
  612. # update to the next commit
  613. function_check set_repo_commit
  614. set_repo_commit "$INSTALL_DIR/nginx_ensite" "nginx-ensite commit" "$NGINX_ENSITE_COMMIT" $NGINX_ENSITE_REPO
  615. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  616. return
  617. fi
  618. # remove apache
  619. apt-get -yq remove --purge apache2
  620. if [ -d /etc/apache2 ]; then
  621. rm -rf /etc/apache2
  622. fi
  623. # install nginx
  624. apt-get -yq install nginx
  625. apt-get -yq install php-fpm git
  626. # Turn off logs by default
  627. sed -i 's|access_log.*|access_log = /dev/null;|g' /etc/nginx/nginx.conf
  628. sed -i 's|error_log.*|error_log = /dev/null;|g' /etc/nginx/nginx.conf
  629. # limit the number of php processes
  630. sed -i 's/; process.max =.*/process.max = 32/g' /etc/php/7.0/fpm/php-fpm.conf
  631. #sed -i 's/;process_control_timeout =.*/process_control_timeout = 300/g' /etc/php/7.0/fpm/php-fpm.conf
  632. sed -i 's|;systemd_interval.*|systemd_interval = 10|g' /etc/php/7.0/fpm/php-fpm.conf
  633. sed -i 's|;emergency_restart_threshold.*|emergency_restart_threshold = 2|g' /etc/php/7.0/fpm/php-fpm.conf
  634. sed -i 's|emergency_restart_threshold.*|emergency_restart_threshold = 2|g' /etc/php/7.0/fpm/php-fpm.conf
  635. sed -i 's|;emergency_restart_interval.*|emergency_restart_interval = 1m|g' /etc/php/7.0/fpm/php-fpm.conf
  636. sed -i 's|emergency_restart_interval.*|emergency_restart_interval = 1m|g' /etc/php/7.0/fpm/php-fpm.conf
  637. sed -i 's|;process_control_timeout.*|process_control_timeout = 10s|g' /etc/php/7.0/fpm/php-fpm.conf
  638. sed -i 's|process_control_timeout.*|process_control_timeout = 10s|g' /etc/php/7.0/fpm/php-fpm.conf
  639. if ! grep -q "pm.max_children" /etc/php/7.0/fpm/php-fpm.conf; then
  640. { echo 'pm = static';
  641. echo 'pm.max_children = 10';
  642. echo 'pm.start_servers = 2';
  643. echo 'pm.min_spare_servers = 2';
  644. echo 'pm.max_spare_servers = 5';
  645. echo 'pm.max_requests = 10'; } >> /etc/php/7.0/fpm/php-fpm.conf
  646. fi
  647. if ! grep -q "request_terminate_timeout" /etc/php/7.0/fpm/php-fpm.conf; then
  648. echo 'request_terminate_timeout = 30' >> /etc/php/7.0/fpm/php-fpm.conf
  649. else
  650. sed -i 's|request_terminate_timeout =.*|request_terminate_timeout = 30|g' >> /etc/php/7.0/fpm/php-fpm.conf
  651. fi
  652. sed -i 's|max_execution_time =.*|max_execution_time = 30|g' /etc/php/7.0/fpm/php.ini
  653. if [ ! -d /etc/nginx ]; then
  654. echo $"ERROR: nginx does not appear to have installed. $CHECK_MESSAGE"
  655. exit 51
  656. fi
  657. # Nginx settings
  658. { echo 'user www-data;';
  659. #echo "worker_processes; $CPU_CORES";
  660. echo 'pid /run/nginx.pid;';
  661. echo '';
  662. echo 'events {';
  663. echo ' worker_connections 50;';
  664. echo ' # multi_accept on;';
  665. echo '}';
  666. echo '';
  667. echo 'http {';
  668. echo ' # limit the number of connections per single IP';
  669. echo " limit_conn_zone \$binary_remote_addr zone=conn_limit_per_ip:10m;";
  670. echo '';
  671. echo ' # limit the number of requests for a given session';
  672. echo " limit_req_zone \$binary_remote_addr zone=req_limit_per_ip:10m rate=140r/s;";
  673. echo '';
  674. echo ' # if the request body size is more than the buffer size, then the entire (or partial) request body is written into a temporary file';
  675. echo ' client_body_buffer_size 128k;';
  676. echo '';
  677. echo ' # headerbuffer size for the request header from client, its set for testing purpose';
  678. echo ' client_header_buffer_size 3m;';
  679. echo '';
  680. echo ' # maximum number and size of buffers for large headers to read from client request';
  681. echo ' large_client_header_buffers 4 256k;';
  682. echo '';
  683. echo ' # read timeout for the request body from client, its set for testing purpose';
  684. echo ' client_body_timeout 3m;';
  685. echo '';
  686. echo ' # how long to wait for the client to send a request header, its set for testing purpose';
  687. echo ' client_header_timeout 3m;';
  688. echo '';
  689. echo ' ##';
  690. echo ' # Basic Settings';
  691. echo ' ##';
  692. echo '';
  693. echo ' sendfile on;';
  694. echo ' tcp_nopush on;';
  695. echo ' tcp_nodelay on;';
  696. echo ' keepalive_timeout 65;';
  697. echo ' types_hash_max_size 2048;';
  698. echo ' server_tokens off;';
  699. echo '';
  700. echo ' # server_names_hash_bucket_size 64;';
  701. echo ' # server_name_in_redirect off;';
  702. echo '';
  703. echo ' include /etc/nginx/mime.types;';
  704. echo ' default_type application/octet-stream;';
  705. echo '';
  706. echo ' ##';
  707. echo ' # Logging Settings';
  708. echo ' ##';
  709. echo '';
  710. echo ' access_log /dev/null;';
  711. echo ' error_log /dev/null;';
  712. echo '';
  713. echo ' ###';
  714. echo ' # Gzip Settings';
  715. echo ' ##';
  716. echo ' gzip on;';
  717. echo ' gzip_disable "msie6";';
  718. echo '';
  719. echo ' # gzip_vary on;';
  720. echo ' # gzip_proxied any;';
  721. echo ' # gzip_comp_level 6;';
  722. echo ' # gzip_buffers 16 8k;';
  723. echo ' # gzip_http_version 1.1;';
  724. echo ' # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;';
  725. echo '';
  726. echo ' ##';
  727. echo ' # Virtual Host Configs';
  728. echo ' ##';
  729. echo '';
  730. echo ' include /etc/nginx/conf.d/*.conf;';
  731. echo ' include /etc/nginx/sites-enabled/*;';
  732. echo '}'; } > /etc/nginx/nginx.conf
  733. # install a script to easily enable and disable nginx virtual hosts
  734. if [ ! -d "$INSTALL_DIR" ]; then
  735. mkdir "$INSTALL_DIR"
  736. fi
  737. cd "$INSTALL_DIR" || exit 2798462846827
  738. function_check git_clone
  739. git_clone "$NGINX_ENSITE_REPO" "$INSTALL_DIR/nginx_ensite"
  740. cd "$INSTALL_DIR/nginx_ensite" || exit 2468748223
  741. git checkout "$NGINX_ENSITE_COMMIT" -b "$NGINX_ENSITE_COMMIT"
  742. set_completion_param "nginx-ensite commit" "$NGINX_ENSITE_COMMIT"
  743. make install
  744. nginx_dissite default
  745. function_check configure_firewall_for_web_access
  746. configure_firewall_for_web_access
  747. mark_completed "${FUNCNAME[0]}"
  748. }
  749. function remove_certs {
  750. domain_name=$1
  751. if [ ! "$domain_name" ]; then
  752. return
  753. fi
  754. if [ -f "/etc/ssl/certs/${domain_name}.dhparam" ]; then
  755. rm "/etc/ssl/certs/${domain_name}.dhparam"
  756. fi
  757. if [ -f "/etc/ssl/certs/${domain_name}.pem" ]; then
  758. rm "/etc/ssl/certs/${domain_name}.pem"
  759. fi
  760. if [ -f "/etc/ssl/certs/${domain_name}.crt" ]; then
  761. rm "/etc/ssl/certs/${domain_name}.crt"
  762. fi
  763. if [ -f "/etc/ssl/private/${domain_name}.key" ]; then
  764. rm "/etc/ssl/private/${domain_name}.key"
  765. fi
  766. }
  767. function configure_firewall_for_web_access {
  768. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  769. return
  770. fi
  771. if [[ $INSTALLED_WITHIN_DOCKER == "yes" ]]; then
  772. # docker does its own firewalling
  773. return
  774. fi
  775. if [[ $ONION_ONLY != "no" ]]; then
  776. return
  777. fi
  778. firewall_add HTTP 80 tcp
  779. firewall_add HTTPS 443 tcp
  780. mark_completed "${FUNCNAME[0]}"
  781. }
  782. function update_default_domain {
  783. echo $'Updating default domain'
  784. if [[ $ONION_ONLY == 'no' ]]; then
  785. if [ -f /etc/mumble-server.ini ]; then
  786. if [ ! -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
  787. if ! grep -q "mumble.pem" /etc/mumble-server.ini; then
  788. sed -i 's|sslCert=.*|sslCert=/var/lib/mumble-server/mumble.pem|g' /etc/mumble-server.ini
  789. sed -i 's|sslKey=.*|sslKey=/var/lib/mumble-server/mumble.key|g' /etc/mumble-server.ini
  790. systemctl restart mumble
  791. fi
  792. else
  793. if ! grep -q "${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/mumble-server.ini; then
  794. usermod -a -G ssl-cert mumble-server
  795. sed -i "s|sslCert=.*|sslCert=/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/mumble-server.ini
  796. sed -i "s|sslKey=.*|sslKey=/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/mumble-server.ini
  797. systemctl restart mumble
  798. fi
  799. fi
  800. fi
  801. if [ -d /etc/prosody ]; then
  802. if [ ! -d /etc/prosody/certs ]; then
  803. mkdir /etc/prosody/certs
  804. fi
  805. cp /etc/ssl/private/xmpp* /etc/prosody/certs
  806. cp /etc/ssl/certs/xmpp* /etc/prosody/certs
  807. if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
  808. usermod -a -G ssl-cert prosody
  809. if grep -q "/etc/prosody/certs/xmpp.key" /etc/prosody/conf.avail/xmpp.cfg.lua; then
  810. sed -i "s|/etc/prosody/certs/xmpp.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
  811. fi
  812. if grep -q "/etc/prosody/certs/xmpp.crt" /etc/prosody/conf.avail/xmpp.cfg.lua; then
  813. sed -i "s|/etc/prosody/certs/xmpp.crt|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
  814. fi
  815. if grep -q "/etc/prosody/certs/xmpp.key" /etc/prosody/prosody.cfg.lua; then
  816. sed -i "s|/etc/prosody/certs/xmpp.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/prosody.cfg.lua
  817. fi
  818. if grep -q "/etc/prosody/certs/xmpp.crt" /etc/prosody/prosody.cfg.lua; then
  819. sed -i "s|/etc/prosody/certs/xmpp.crt|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/prosody.cfg.lua
  820. fi
  821. if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key" /etc/prosody/conf.avail/xmpp.cfg.lua; then
  822. sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
  823. fi
  824. if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem" /etc/prosody/conf.avail/xmpp.cfg.lua; then
  825. sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
  826. fi
  827. if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key" /etc/prosody/prosody.cfg.lua; then
  828. sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/prosody.cfg.lua
  829. fi
  830. if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem" /etc/prosody/prosody.cfg.lua; then
  831. sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/prosody.cfg.lua
  832. fi
  833. fi
  834. chown -R prosody:default /etc/prosody
  835. chmod -R 700 /etc/prosody/certs/*
  836. chmod 600 /etc/prosody/prosody.cfg.lua
  837. if [ -d "$INSTALL_DIR/prosody-modules" ]; then
  838. cp -r "$INSTALL_DIR/prosody-modules/"* /var/lib/prosody/prosody-modules/
  839. cp -r "$INSTALL_DIR/prosody-modules/"* /usr/lib/prosody/modules/
  840. fi
  841. chown -R prosody:prosody /var/lib/prosody/prosody-modules
  842. chown -R prosody:prosody /usr/lib/prosody/modules
  843. systemctl reload prosody
  844. fi
  845. if [ -d /home/znc/.znc ]; then
  846. echo $'znc found'
  847. if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
  848. pkill znc
  849. cat "/etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem" "/etc/ssl/private/${DEFAULT_DOMAIN_NAME}.key" > /home/znc/.znc/znc.pem
  850. chown znc:znc /home/znc/.znc/znc.pem
  851. chmod 700 /home/znc/.znc/znc.pem
  852. sed -i "s|CertFile =.*|CertFile = /etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/ngircd/ngircd.conf
  853. sed -i "s|DHFile =.*|DHFile = /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.dhparam" /etc/ngircd/ngircd.conf
  854. sed -i "s|KeyFile =.*|KeyFile = /etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem" /etc/ngircd/ngircd.conf
  855. echo $'irc certificates updated'
  856. systemctl restart ngircd
  857. su -c 'znc' - znc
  858. fi
  859. fi
  860. if [ ${#DEFAULT_DOMAIN_NAME} -gt 0 ]; then
  861. if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
  862. if [ -d /etc/dovecot ]; then
  863. if ! grep -q "ssl_cert = </etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/dovecot/conf.d/10-ssl.conf; then
  864. sed -i "s|#ssl_cert =.*|ssl_cert = </etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/dovecot/conf.d/10-ssl.conf
  865. sed -i "s|ssl_cert =.*|ssl_cert = </etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/dovecot/conf.d/10-ssl.conf
  866. systemctl restart dovecot
  867. fi
  868. fi
  869. if [ -d /etc/exim4 ]; then
  870. # Unfortunately there doesn't appear to be any other way than copying certs here
  871. cp "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/{fullchain,privkey}.pem" /etc/exim4/
  872. chown root:Debian-exim /etc/exim4/*.pem
  873. chmod 640 /etc/exim4/*.pem
  874. sed -i "s|MAIN_TLS_CERTIFICATE =.*|MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem|g" /etc/exim4/conf.d/main/03_exim4-config_tlsoptions
  875. sed -i "s|MAIN_TLS_CERTIFICATE =.*|MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem|g" /etc/exim4/exim4.conf.template
  876. sed -i "s|MAIN_TLS_PRIVATEKEY =.*|MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem|g" /etc/exim4/conf.d/main/03_exim4-config_tlsoptions
  877. sed -i "s|MAIN_TLS_PRIVATEKEY =.*|MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem|g" /etc/exim4/exim4.conf.template
  878. systemctl restart exim4
  879. fi
  880. fi
  881. fi
  882. fi
  883. }
  884. function create_default_web_site {
  885. if [ ! -f "/etc/nginx/sites-available/${DEFAULT_DOMAIN_NAME}" ]; then
  886. # create a web site for the default domain
  887. if [ ! -d "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs" ]; then
  888. mkdir -p "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs"
  889. if [ -d "/root/${PROJECT_NAME}" ]; then
  890. cd "/root/${PROJECT_NAME}/website" || exit 24687246468
  891. ./deploy.sh EN "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs"
  892. else
  893. if [ -d "/home/${MY_USERNAME}/${PROJECT_NAME}" ]; then
  894. cd "/home/${MY_USERNAME}/${PROJECT_NAME}" || exit 2462874624
  895. ./deploy.sh EN "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs"
  896. fi
  897. fi
  898. fi
  899. # add a config for the default domain
  900. nginx_site=/etc/nginx/sites-available/$DEFAULT_DOMAIN_NAME
  901. if [[ $ONION_ONLY == "no" ]]; then
  902. function_check nginx_http_redirect
  903. nginx_http_redirect "$DEFAULT_DOMAIN_NAME"
  904. { echo 'server {';
  905. echo ' listen 443 ssl;';
  906. echo ' #listen [::]:443 ssl;';
  907. echo " server_name $DEFAULT_DOMAIN_NAME;";
  908. echo '';
  909. echo ' # Security'; } >> "$nginx_site"
  910. function_check nginx_ssl
  911. nginx_ssl "$DEFAULT_DOMAIN_NAME" mobile
  912. function_check nginx_security_options
  913. nginx_security_options "$DEFAULT_DOMAIN_NAME"
  914. { echo ' add_header Strict-Transport-Security max-age=15768000;';
  915. echo '';
  916. echo ' # Logs';
  917. echo ' access_log /dev/null;';
  918. echo ' error_log /dev/null;';
  919. echo '';
  920. echo ' # Root';
  921. echo " root /var/www/$DEFAULT_DOMAIN_NAME/htdocs;";
  922. echo '';
  923. echo ' # Index';
  924. echo ' index index.html;';
  925. echo '';
  926. echo ' # Location';
  927. echo ' location / {'; } >> "$nginx_site"
  928. function_check nginx_limits
  929. nginx_limits "$DEFAULT_DOMAIN_NAME" '15m'
  930. { echo ' }';
  931. echo '';
  932. echo ' # Restrict access that is unnecessary anyway';
  933. echo ' location ~ /\.(ht|git) {';
  934. echo ' deny all;';
  935. echo ' }';
  936. echo '}'; } >> "$nginx_site"
  937. else
  938. echo -n '' > "$nginx_site"
  939. fi
  940. { echo 'server {';
  941. echo " listen 127.0.0.1:$DEFAULT_DOMAIN_ONION_PORT default_server;";
  942. echo " server_name $DEFAULT_DOMAIN_NAME;";
  943. echo ''; } >> "$nginx_site"
  944. function_check nginx_security_options
  945. nginx_security_options "$DEFAULT_DOMAIN_NAME"
  946. { echo '';
  947. echo ' # Logs';
  948. echo ' access_log /dev/null;';
  949. echo ' error_log /dev/null;';
  950. echo '';
  951. echo ' # Root';
  952. echo " root /var/www/$DEFAULT_DOMAIN_NAME/htdocs;";
  953. echo '';
  954. echo ' # Location';
  955. echo ' location / {'; } >> "$nginx_site"
  956. function_check nginx_limits
  957. nginx_limits "$DEFAULT_DOMAIN_NAME" '15m'
  958. { echo ' }';
  959. echo '';
  960. echo ' # Restrict access that is unnecessary anyway';
  961. echo ' location ~ /\.(ht|git) {';
  962. echo ' deny all;';
  963. echo ' }';
  964. echo '}'; } >> "$nginx_site"
  965. if [ ! -f "/etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem" ]; then
  966. function_check create_site_certificate
  967. create_site_certificate "$DEFAULT_DOMAIN_NAME" 'yes'
  968. fi
  969. nginx_ensite "$DEFAULT_DOMAIN_NAME"
  970. fi
  971. }
  972. function install_composer {
  973. composer_options="$1"
  974. # curl -sS https://getcomposer.org/installer | php
  975. if [ -f "${HOME}/${PROJECT_NAME}/image_build/composer_install" ]; then
  976. php < "${HOME}/${PROJECT_NAME}/image_build/composer_install"
  977. else
  978. if [ -f "/home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install" ]; then
  979. php < "/home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install"
  980. fi
  981. fi
  982. if [ -f composer.phar ]; then
  983. cp composer.phar composer
  984. fi
  985. if ! php composer.phar install "$composer_options"; then
  986. echo $'Unable to run composer install'
  987. exit 7252198
  988. fi
  989. }
  990. function email_disable_chunking {
  991. if [ -f /etc/exim4/conf.d/main/04_exim4-config_chunking ]; then
  992. return
  993. fi
  994. echo "chunking_advertise_hosts =" > /etc/exim4/conf.d/main/04_exim4-config_chunking
  995. update-exim4.conf
  996. dpkg-reconfigure --frontend noninteractive exim4-config
  997. systemctl restart exim4
  998. }
  999. function email_update_onion_domain {
  1000. email_hostname='/var/lib/tor/hidden_service_email/hostname'
  1001. cp $email_hostname /etc/skel/.email_onion_domain
  1002. for d in /home/*/ ; do
  1003. USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
  1004. if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
  1005. cp $email_hostname "/home/$USERNAME/.email_onion_domain"
  1006. chown "$USERNAME":"$USERNAME" "/home/$USERNAME/.email_onion_domain"
  1007. fi
  1008. done
  1009. }
  1010. function email_install_tls {
  1011. tls_config_file=/etc/exim4/conf.d/main/03_exim4-config_tlsoptions
  1012. tls_auth_config_file=/etc/exim4/conf.d/auth/30_exim4-config_examples
  1013. email_config_changed=
  1014. if [ ! -f $tls_config_file ]; then
  1015. tls_config_file=/etc/exim4/exim4.conf.template
  1016. tls_auth_config_file=$tls_config_file
  1017. fi
  1018. if [ ! -f /etc/ssl/certs/exim.dhparam ]; then
  1019. "${PROJECT_NAME}-addcert" -h exim --dhkey "$DH_KEYLENGTH"
  1020. CHECK_HOSTNAME=exim
  1021. check_certificates exim
  1022. cp /etc/ssl/certs/exim.dhparam /etc/exim4
  1023. chown root:Debian-exim /etc/exim4/exim.dhparam
  1024. chmod 640 /etc/exim4/exim.key /etc/exim4/exim.crt /etc/exim4/exim.dhparam
  1025. email_config_changed=1
  1026. fi
  1027. if ! grep -q 'MAIN_TLS_ENABLE = true' $tls_config_file; then
  1028. sed -i "/.ifdef MAIN_HARDCODE_PRIMARY_HOSTNAME/i\\MAIN_HARDCODE_PRIMARY_HOSTNAME =\\nMAIN_TLS_ENABLE = true" "$tls_config_file"
  1029. email_config_changed=1
  1030. fi
  1031. if ! grep -q "tls_on_connect_ports=465" $tls_config_file; then
  1032. sed -i '/SSL configuration for exim/i\tls_on_connect_ports=465' $tls_config_file
  1033. email_config_changed=1
  1034. fi
  1035. if grep -q '# login_saslauthd_server' $tls_auth_config_file; then
  1036. sed -i '/login_saslauthd_server/,/.endif/ s/# *//' $tls_auth_config_file
  1037. email_config_changed=1
  1038. fi
  1039. if [ -f "/etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem" ]; then
  1040. cp "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/exim4/
  1041. chown root:Debian-exim /etc/exim4/*.pem
  1042. chmod 640 /etc/exim4/*.pem
  1043. if ! grep -q "MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem" $tls_config_file; then
  1044. sed -i "/.ifdef MAIN_TLS_CERTKEY/i\\MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem" $tls_config_file
  1045. email_config_changed=1
  1046. fi
  1047. fi
  1048. if [ -f "/etc/ssl/private/${DEFAULT_DOMAIN_NAME}.key" ]; then
  1049. cp "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem" /etc/exim4/
  1050. chown root:Debian-exim /etc/exim4/*.pem
  1051. chmod 640 /etc/exim4/*.pem
  1052. if ! grep -q "MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem" $tls_config_file; then
  1053. sed -i "/.ifndef MAIN_TLS_PRIVATEKEY/i\\MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem" $tls_config_file
  1054. email_config_changed=1
  1055. fi
  1056. fi
  1057. if ! grep -q "SMTPLISTENEROPTIONS='-oX 465:25:587" /etc/default/exim4; then
  1058. sed -i "s|SMTPLISTENEROPTIONS=.*|SMTPLISTENEROPTIONS='-oX 465:25:587 -oP /var/run/exim4/exim.pid'|g" /etc/default/exim4
  1059. email_config_changed=1
  1060. fi
  1061. if [ $email_config_changed ]; then
  1062. systemctl restart saslauthd
  1063. systemctl restart exim4
  1064. fi
  1065. }
  1066. function install_web_local_user_interface {
  1067. # TODO
  1068. # This is intended as a placeholder for a potential local web user interface
  1069. # similar to Plinth or the yunohost admin interface
  1070. local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
  1071. if [ ! -d "/var/www/${local_hostname}/htdocs" ]; then
  1072. mkdir -p "/var/www/${local_hostname}/htdocs"
  1073. fi
  1074. { echo '<html>';
  1075. echo ' <body>';
  1076. echo " This is a test on ${local_hostname}";
  1077. echo ' </body>';
  1078. echo '</html>'; } > "/var/www/${local_hostname}/htdocs/index.html"
  1079. nginx_file=/etc/nginx/sites-available/$local_hostname
  1080. { echo 'server {';
  1081. echo ' listen 80 default_server;';
  1082. echo ' #listen [::]:80;';
  1083. echo " server_name ${local_hostname};";
  1084. echo " root /var/www/${local_hostname}/htdocs;";
  1085. echo ' index index.html;';
  1086. echo '';
  1087. echo ' access_log /dev/null;';
  1088. echo ' error_log /dev/null;';
  1089. echo '';
  1090. echo ' location /icons {';
  1091. echo ' autoindex on;';
  1092. echo ' break;';
  1093. echo ' }';
  1094. echo '';
  1095. echo ' rewrite ^/plinth/(.*)$ /api.json last;';
  1096. echo '';
  1097. echo ' location / {';
  1098. echo " root /var/www/${local_hostname}/htdocs/plinth;";
  1099. echo ' index api.json /api.json;';
  1100. echo " error_page 405 = \$uri;";
  1101. echo ' }';
  1102. echo '}';
  1103. echo '';
  1104. echo 'server {';
  1105. echo ' listen 443 default_server ssl;';
  1106. echo ' #listen [::]:443 ssl;';
  1107. echo " server_name ${local_hostname};";
  1108. echo " root /var/www/${local_hostname}/htdocs;";
  1109. echo ' index index.html;';
  1110. echo '';
  1111. echo ' access_log /dev/null;';
  1112. echo ' error_log /dev/null;';
  1113. echo ''; } > "$nginx_file"
  1114. nginx_ssl "${local_hostname}"
  1115. nginx_security_options "${local_hostname}"
  1116. { echo ' add_header Strict-Transport-Security max-age=0;';
  1117. echo '';
  1118. echo ' location /icons {';
  1119. echo ' autoindex on;';
  1120. echo ' break;';
  1121. echo ' }';
  1122. echo '';
  1123. echo ' rewrite ^/plinth/(.*)$ /api.json last;';
  1124. echo '';
  1125. echo ' location / {';
  1126. echo " root /var/www/${local_hostname}/htdocs/plinth;";
  1127. echo ' index api.json /api.json;';
  1128. echo " error_page 405 = \$uri;";
  1129. echo ' }';
  1130. echo '}'; } >> "$nginx_file"
  1131. if [ ! -f "/etc/ssl/certs/${local_hostname}.crt" ]; then
  1132. "${PROJECT_NAME}-addcert" -h "${local_hostname}" --dhkey "${DH_KEYLENGTH}"
  1133. fi
  1134. sed -i "s|ssl_certificate .*|ssl_certificate /etc/ssl/certs/${local_hostname}.crt;|g" "$nginx_file"
  1135. sed -i "s|ssl_certificate_key .*|ssl_certificate_key /etc/ssl/private/${local_hostname}.key;|g" "$nginx_file"
  1136. nginx_ensite "${local_hostname}"
  1137. # Compatibility with FreedomBox android app
  1138. # The installed apps get published to a json file called api.json
  1139. # in this directory
  1140. if [ ! -d "/var/www/${local_hostname}/htdocs/plinth" ]; then
  1141. mkdir -p "/var/www/${local_hostname}/htdocs/plinth"
  1142. fi
  1143. chown -R www-data:www-data "/var/www/${local_hostname}/htdocs"
  1144. }
  1145. # NOTE: deliberately no exit 0