This commit is contained in:
Bob Mottram 2018-04-04 15:46:40 +01:00
commit 8ee6075366
48 changed files with 2236 additions and 1867 deletions

34
doc/EN/app_bludit.org Normal file
View File

@ -0,0 +1,34 @@
#+TITLE:
#+AUTHOR: Bob Mottram
#+EMAIL: bob@freedombone.net
#+KEYWORDS: freedombone, bludit, blog
#+DESCRIPTION: How to use Bludit
#+OPTIONS: ^:nil toc:nil
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
#+BEGIN_CENTER
[[file:images/logo.png]]
#+END_CENTER
#+BEGIN_EXPORT html
<center>
<h1>Bludit</h1>
</center>
#+END_EXPORT
This is a databaseless blogging system which uses markdown files. It's not very complex and so there is not much to go wrong, and it should run well on any server hardware.
* Installation
Log into your system with:
#+begin_src bash
ssh myusername@mydomain -p 2222
#+end_src
Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
Select *Add/Remove Apps* then *bluit*. Enter the subdomain that you which to use, such as *blog.mydomain.net*, and optionally a FreeDNS code.
Now in a browser navigate to your subdomain. You will need to enter some details for the database. You'll be asked to provide an initial administrator password.
From there on it's all pretty straightforward. If you need to publish a draft the post status can be changed on a drop down list on the right hand side.

View File

@ -1,45 +0,0 @@
#+TITLE:
#+AUTHOR: Bob Mottram
#+EMAIL: bob@freedombone.net
#+KEYWORDS: freedombone, ghost
#+DESCRIPTION: How to use Ghost
#+OPTIONS: ^:nil toc:nil
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
#+BEGIN_CENTER
[[file:images/logo.png]]
#+END_CENTER
#+BEGIN_EXPORT html
<center>
<h1>Ghost</h1>
</center>
#+END_EXPORT
Ghost is a blogging system which uses markdown formatted posts. It's quite simple to use, and also looks nice even on small mobile screens.
* Installation
Log into your system with:
#+begin_src bash
ssh myusername@mydomain -p 2222
#+end_src
Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
Select *Add/Remove Apps* then *ghost*. You will then be asked for a domain name and if you are using FreeDNS also the code for the domain which can be found under *Dynamic DNS* on the FreeDNS site (the random string from "/quick cron example/" which appears after /update.php?/ and before />>/). For more details on obtaining a domain and making it accessible via dynamic DNS see the [[./faq.html][FAQ]]. Typically the domain name you use will be a subdomain, such as /blog.mydomainname.net/. It will need to be a domain which you have bought somewhere and own and not one of the FreeDNS subdomains, otherwise you won't be able to get a SSL/TLS certificate for it.
After the install has completed go to *Security settings* and select *Create a new Let's Encrypt certificate* and enter the domain name that you are using for Ghost. If you're using the "onion only" version of the system then you don't need to do this. If the certificate is obtained successfully then you will see a congratulations message.
* Initial setup
If you have just obtained a Lets Encrypt certificate as above then go to *About* on the administrator control panel and you should see your Ghost blog domain listed there along with an onion address. You can then navigate to your site in a browser.
To see the login password for your site go to *Passwords* on the *Administrator control panel* and select the appropriate username and app. The passwords will be different for each user and may not be the same as the password which you used to originally ssh into the system.
Navigate to https://yourghostblogdomain/ghost and click on *create your account*
Enter your email address, password and blog title.
When prompted to invite users click on *I'll do this later*
Under *Settings* on the *General* option you can set a description, background image and so on.

49
doc/EN/app_peertube.org Normal file
View File

@ -0,0 +1,49 @@
#+TITLE:
#+AUTHOR: Bob Mottram
#+EMAIL: bob@freedombone.net
#+KEYWORDS: freedombone, peertube
#+DESCRIPTION: How to use PeerTube
#+OPTIONS: ^:nil toc:nil
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
#+BEGIN_CENTER
[[file:images/logo.png]]
#+END_CENTER
#+BEGIN_CENTER
[[file:images/peertube.jpg]]
#+END_CENTER
This is a video hosting system similar to Mediagoblin but using webtorrent to help distribute the files to or between clients. This should be more practical for situations where a video becomes popular because the load is then spread across the network, with performance increasing with the number of nodes. However, the torrenting aspect of it only works with WebRTC enabled browsers and so this means it's unlikely to fully work with a Tor browser. Without WebRTC then from a user point of view it's effectively the same thing as Mediagoblin.
* Installation
Log into your system with:
#+begin_src bash
ssh myusername@mydomain -p 2222
#+end_src
Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
Select *Add/Remove Apps* then *peertube*. You will then be asked for a domain name and if you are using FreeDNS also the code for the domain which can be found under *Dynamic DNS* on the FreeDNS site (the random string from "/quick cron example/" which appears after /update.php?/ and before />>/). For more details on obtaining a domain and making it accessible via dynamic DNS see the [[./faq.html][FAQ]]. Typically the domain name you use will be a subdomain, such as /video.mydomainname.net/. It will need to be a domain which you have bought somewhere and own and not one of the FreeDNS subdomains, otherwise you won't be able to get a SSL/TLS certificate for it.
* Initial setup
Navigate to your site and select *Signup* to create a new account. By default the maximum number of accounts on your system is limited to a small number so that millions of random internet users can't then begin uploading dubious content. After that it's pretty straightforward.
If you wish it's possible to turn off further signups via the *Administrator control panel* under *App settings* for *peertube*.
* Importing videos from YouTube/Vimeo/Dailymotion
It's possible to import videos from the main proprietary video hosting sites. /Only do this if they're videos which you made, or if the license is Creative Commons/. Hosting arbitrary videos under nonfree licenses is likely to get you into trouble, and we know how that works out from the P2P wars of the 2000s (i.e. badly).
Go to the *Administrator control panel*, select *App settings* then *peertube* then *Import videos from YouTube/Vimeo/Dailymotion*. Enter your PeerTube login details and then you may specify either the individual video URL or the channel URL if you want to import a whole channel.
* Importing videos from your desktop
The most convenient way to add new videos to PeerTube is if you have the *syncthing* app installed. Set up [[./app_syncthing.html][syncthing]] with a folder called ~/Sync in your home directory. Create a subdirectory called *~/Sync/peertube_upload*. Within that directory make a text file called *login.txt*. This will contain your PeerTube login details.
The first line of login.txt should be your username, the second line should be the password and optionally the third line can contain the words *public* and/or *nsfw*, if you want to make imported videos immediately public or mark them as not suitable for work.
Prepare your videos in *ogv*, *mp4* or *webm* format. To minimize bandwidth usage try to keep your videos as small as possible. Giant videos with incredibly high resolution tend to result in a bad user experience. Often just converting your videos to *webm* using *ffmpeg* will keep the size down.
Now copy or drag and drop your videos into the *~/Sync/peertube_upload* directory. Syncthing will sync to the server and automatically add the videos to PeerTube. Depending on how large the videos are this may take some time.
Imported videos can be seen by logging into PeerTube, selecting *My account* then the *My videos* tab. You can then view them, add a description and select to make them public if you wish.

View File

@ -29,6 +29,10 @@ A web based accounts system for small businesses or freelancers.
It's like ordinary email, but with [[https://en.wikipedia.org/wiki/I2P][i2p]] as the transport mechanism.
[[./app_bdsmail.html][How to use it]]
* Bludit
This is a simple databaseless blogging system which uses markdown files. It should run well on any hardware.
[[./app_bludit.html][How to use it]]
* CryptPad
Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
@ -63,10 +67,6 @@ A new approach to creating wiki content.
Federated social network system.
[[./app_friendica.html][How to use it]]
* Ghost
Modern looking blogging system.
[[./app_ghost.html][How to use it]]
* GNU Social
Federated social network based on the OStatus protocol. You can "/remote follow/" other users within the GNU Social federation.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -54,7 +54,7 @@ function akaunting_remove_bad_links {
# copy jquery locally
jquery_version='1.12.4'
if [ ! -f jquery-${jquery_version}.js ]; then
cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 3276324
cd "/var/www/$AKAUNTING_DOMAIN_NAME/htdocs" || exit 3276324
wget https://code.jquery.com/jquery-${jquery_version}.js
jquery_hash=$(sha256sum jquery-${jquery_version}.js | awk -F ' ' '{print $1}')
if [[ "$jquery_hash" != '430f36f9b5f21aae8cc9dca6a81c4d3d84da5175eaedcf2fdc2c226302cb3575' ]]; then

338
src/freedombone-app-bludit Executable file
View File

@ -0,0 +1,338 @@
#!/bin/bash
#
# .---. . .
# | | |
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
#
# Freedom in the Cloud
#
# License
# =======
#
# Copyright (C) 2018 Bob Mottram <bob@freedombone.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
VARIANTS='full full-vim'
IN_DEFAULT_INSTALL=0
SHOW_ON_ABOUT=1
BLUDIT_DOMAIN_NAME=
BLUDIT_CODE=
BLUDIT_ONION_PORT=9844
BLUDIT_REPO="https://github.com/bludit/bludit"
BLUDIT_COMMIT='0e27e31a84421b3e6bd000a77bc89c2dff3c446a'
bludit_variables=(ONION_ONLY
BLUDIT_DOMAIN_NAME
BLUDIT_CODE
DDNS_PROVIDER
MY_USERNAME)
function logging_on_bludit {
echo -n ''
}
function logging_off_bludit {
echo -n ''
}
function remove_user_bludit {
remove_username="$1"
"${PROJECT_NAME}-pass" -u "$remove_username" --rmapp bludit
}
function add_user_bludit {
new_username="$1"
new_user_password="$2"
"${PROJECT_NAME}-pass" -u "$new_username" -a bludit -p "$new_user_password"
echo '0'
}
function install_interactive_bludit {
if [ ! "$ONION_ONLY" ]; then
ONION_ONLY='no'
fi
if [[ "$ONION_ONLY" != "no" ]]; then
BLUDIT_DOMAIN_NAME='bludit.local'
write_config_param "BLUDIT_DOMAIN_NAME" "$BLUDIT_DOMAIN_NAME"
else
interactive_site_details "bludit" "BLUDIT_DOMAIN_NAME" "BLUDIT_CODE"
fi
APP_INSTALLED=1
}
function change_password_bludit {
curr_username="$1"
new_user_password="$2"
read_config_param 'BLUDIT_DOMAIN_NAME'
"${PROJECT_NAME}-pass" -u "$curr_username" -a bludit -p "$new_user_password"
}
function reconfigure_bludit {
# This is used if you need to switch identity. Dump old keys and generate new ones
echo -n ''
}
function upgrade_bludit {
CURR_BLUDIT_COMMIT=$(get_completion_param "bludit commit")
if [[ "$CURR_BLUDIT_COMMIT" == "$BLUDIT_COMMIT" ]]; then
return
fi
if grep -q "bludit domain" "$COMPLETION_FILE"; then
BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
fi
# update to the next commit
set_repo_commit "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" "bludit commit" "$BLUDIT_COMMIT" $BLUDIT_REPO
chown -R www-data:www-data "/var/www/${BLUDIT_DOMAIN_NAME}/htdocs"
}
function backup_local_bludit {
BLUDIT_DOMAIN_NAME='bludit'
if grep -q "bludit domain" "$COMPLETION_FILE"; then
BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
fi
source_directory=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
suspend_site "${BLUDIT_DOMAIN_NAME}"
dest_directory=bludit
backup_directory_to_usb "$source_directory" $dest_directory
restart_site
}
function restore_local_bludit {
if ! grep -q "bludit domain" "$COMPLETION_FILE"; then
return
fi
BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
if [ "$BLUDIT_DOMAIN_NAME" ]; then
temp_restore_dir=/root/tempbludit
bludit_dir=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
restore_directory_from_usb $temp_restore_dir bludit
if [ -d $temp_restore_dir ]; then
if [ -d "$temp_restore_dir$bludit_dir" ]; then
cp -rp "$temp_restore_dir$bludit_dir"/* "$bludit_dir"/
else
if [ ! -d "$bludit_dir" ]; then
mkdir "$bludit_dir"
fi
cp -rp "$temp_restore_dir"/* "$bludit_dir"/
fi
chown -R www-data:www-data "$bludit_dir"
rm -rf $temp_restore_dir
fi
fi
}
function backup_remote_bludit {
BLUDIT_DOMAIN_NAME='bludit'
if grep -q "bludit domain" "$COMPLETION_FILE"; then
BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
fi
source_directory=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
suspend_site "${BLUDIT_DOMAIN_NAME}"
dest_directory=bludit
backup_directory_to_friend "$source_directory" $dest_directory
restart_site
}
function restore_remote_bludit {
if ! grep -q "bludit domain" "$COMPLETION_FILE"; then
return
fi
BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
if [ "$BLUDIT_DOMAIN_NAME" ]; then
temp_restore_dir=/root/tempbludit
bludit_dir=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
restore_directory_from_friend $temp_restore_dir bludit
if [ -d $temp_restore_dir ]; then
if [ -d "$temp_restore_dir$bludit_dir" ]; then
cp -rp "$temp_restore_dir$bludit_dir"/* "$bludit_dir"/
else
if [ ! -d "$bludit_dir" ]; then
mkdir "$bludit_dir"
fi
cp -rp $temp_restore_dir/* "$bludit_dir"/
fi
chown -R www-data:www-data "$bludit_dir"
rm -rf $temp_restore_dir
fi
fi
}
function remove_bludit {
nginx_dissite "$BLUDIT_DOMAIN_NAME"
remove_certs "$BLUDIT_DOMAIN_NAME"
if [ -d "/var/www/$BLUDIT_DOMAIN_NAME" ]; then
rm -rf "/var/www/$BLUDIT_DOMAIN_NAME"
fi
if [ -f "/etc/nginx/sites-available/$BLUDIT_DOMAIN_NAME" ]; then
rm "/etc/nginx/sites-available/$BLUDIT_DOMAIN_NAME"
fi
remove_onion_service bludit ${BLUDIT_ONION_PORT}
if grep -q "bludit" /etc/crontab; then
sed -i "/bludit/d" /etc/crontab
fi
remove_app bludit
remove_completion_param install_bludit
sed -i '/bludit/d' "$COMPLETION_FILE"
remove_ddns_domain "$BLUDIT_DOMAIN_NAME"
}
function install_bludit {
apt-get -yq install php-gettext php-curl php-gd php-mysql git curl
apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl
if [ ! "$BLUDIT_DOMAIN_NAME" ]; then
echo $'No domain name was given'
exit 3568356
fi
if [ -d "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" ]; then
rm -rf "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
fi
if [ -d /repos/bludit ]; then
mkdir "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
cp -r -p /repos/bludit/. "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
cd "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" || exit 324687356
git pull
else
git_clone $BLUDIT_REPO "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
fi
if [ ! -d "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" ]; then
echo $'Unable to clone bludit repo'
exit 87525
fi
cd "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" || exit 36587356
git checkout $BLUDIT_COMMIT -b $BLUDIT_COMMIT
set_completion_param "bludit commit" "$BLUDIT_COMMIT"
chmod g+w "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
chown -R www-data:www-data "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
add_ddns_domain "$BLUDIT_DOMAIN_NAME"
BLUDIT_ONION_HOSTNAME=$(add_onion_service bludit 80 ${BLUDIT_ONION_PORT})
bludit_nginx_site=/etc/nginx/sites-available/$BLUDIT_DOMAIN_NAME
if [[ "$ONION_ONLY" == "no" ]]; then
nginx_http_redirect "$BLUDIT_DOMAIN_NAME" "index index.php"
{ echo 'server {';
echo ' listen 443 ssl;';
echo ' #listen [::]:443 ssl;';
echo " server_name $BLUDIT_DOMAIN_NAME;";
echo ''; } >> "$bludit_nginx_site"
nginx_compress "$BLUDIT_DOMAIN_NAME"
echo '' >> "$bludit_nginx_site"
echo ' # Security' >> "$bludit_nginx_site"
nginx_ssl "$BLUDIT_DOMAIN_NAME"
nginx_security_options "$BLUDIT_DOMAIN_NAME"
{ echo ' add_header Strict-Transport-Security max-age=15768000;';
echo '';
echo ' # Logs';
echo ' access_log /dev/null;';
echo ' error_log /dev/null;';
echo '';
echo ' # Root';
echo " root /var/www/$BLUDIT_DOMAIN_NAME/htdocs;";
echo '';
echo ' index index.php;';
echo ' location ~ \.php {';
echo ' include snippets/fastcgi-php.conf;';
echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';
echo ' fastcgi_read_timeout 30;';
echo ' }';
echo '';
echo ' # Location';
echo ' location / {'; } >> "$bludit_nginx_site"
nginx_limits "$BLUDIT_DOMAIN_NAME" '15m'
{ echo " try_files \$uri \$uri/ /index.php?\$args;";
echo ' }';
echo '}'; } >> "$bludit_nginx_site"
else
echo -n '' > "$bludit_nginx_site"
fi
{ echo 'server {';
echo " listen 127.0.0.1:$BLUDIT_ONION_PORT default_server;";
echo " server_name $BLUDIT_ONION_HOSTNAME;";
echo ''; } >> "$bludit_nginx_site"
nginx_compress "$BLUDIT_DOMAIN_NAME"
echo '' >> "$bludit_nginx_site"
nginx_security_options "$BLUDIT_DOMAIN_NAME"
{ echo '';
echo ' # Logs';
echo ' access_log /dev/null;';
echo ' error_log /dev/null;';
echo '';
echo ' # Root';
echo " root /var/www/$BLUDIT_DOMAIN_NAME/htdocs;";
echo '';
echo ' index index.php;';
echo ' location ~ \.php {';
echo ' include snippets/fastcgi-php.conf;';
echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';
echo ' fastcgi_read_timeout 30;';
echo ' }';
echo '';
echo ' # Location';
echo ' location / {'; } >> "$bludit_nginx_site"
nginx_limits "$BLUDIT_DOMAIN_NAME" '15m'
{ echo " try_files \$uri \$uri/ index.php?\$args;";
echo ' }';
echo '}'; } >> "$bludit_nginx_site"
configure_php
create_site_certificate "$BLUDIT_DOMAIN_NAME" 'yes'
nginx_ensite "$BLUDIT_DOMAIN_NAME"
systemctl restart php7.0-fpm
systemctl restart nginx
"${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a bludit -p "$BLUDIT_ADMIN_PASSWORD"
set_completion_param "bludit domain" "$BLUDIT_DOMAIN_NAME"
APP_INSTALLED=1
}
# NOTE: deliberately there is no "exit 0"

View File

@ -368,7 +368,7 @@ function mesh_install_cryptpad {
cryptpad_nginx_site=$rootdir/etc/nginx/sites-available/cryptpad
{ echo 'server {';
echo " listen 80 default_server;";
echo ' listen [::]:80 default_server;';
echo " server_name P${PEER_ID}.local;";
echo '';
echo ' # Logs';
@ -389,7 +389,7 @@ function mesh_install_cryptpad {
echo ' }';
echo '';
echo ' location = /cryptpad_websocket {';
echo " proxy_pass http://localhost:$CRYPTPAD_PORT;";
echo " proxy_pass http://[::]:$CRYPTPAD_PORT;";
echo " proxy_set_header X-Real-IP \$remote_addr;";
echo " proxy_set_header Host \$host;";
echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;";

View File

@ -47,29 +47,22 @@ function logging_off_dlna {
}
function configure_interactive_dlna {
W=(1 $"Attach a drive containing playable media"
2 $"Remove a drive containing playable media")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Media Menu" \
--radiolist $"Choose an operation:" 13 70 3 \
1 $"Attach a drive containing playable media" off \
2 $"Remove a drive containing playable media" off \
3 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
break;;
255) rm -f "$data"
break;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Media Menu" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) attach-music;;
2) remove-music;;
3) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -131,29 +131,22 @@ function edith_browse {
}
function configure_interactive_edith {
W=(1 $"Enable login"
2 $"Browse notes")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Edith" \
--radiolist $"Choose an operation:" 10 50 3 \
1 $"Enable login" off \
2 $"Browse notes" off \
3 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
break;;
255) rm -f "$data"
break;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Edith" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) edith_enable_login;;
2) edith_browse;;
3) rm -f "$data"
break;;
esac
rm -f "$data"
done
}
@ -460,7 +453,7 @@ function install_interactive_edith {
fi
if [[ "$ONION_ONLY" != "no" ]]; then
GHOST_DOMAIN_NAME='edith.local'
EDITH_DOMAIN_NAME='edith.local'
write_config_param "EDITH_DOMAIN_NAME" "$EDITH_DOMAIN_NAME"
else
function_check interactive_site_details

View File

@ -269,29 +269,22 @@ function etherpad_set_welcome_message {
}
function configure_interactive_etherpad {
W=(1 $"Set Title"
2 $"Set a welcome message")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Etherpad Settings" \
--radiolist $"Choose an operation:" 12 70 3 \
1 $"Set Title" off \
2 $"Set a welcome message" off \
3 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Etherpad" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) etherpad_set_title;;
2) etherpad_set_welcome_message;;
3) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -55,50 +55,50 @@ fedwiki_variables=(FEDWIKI_DOMAIN_NAME
function fedwiki_remove_bad_links {
if [[ $ONION_ONLY == 'no' ]]; then
sed -i "s|link[href='https://maxcdn.bootstrapcdn.com.*|link[href='https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
sed -i "s|link\\[href='https://maxcdn.bootstrapcdn.com.*|link\\[href='https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
else
FEDWIKI_ONION_HOSTNAME=$(cat /var/lib/tor/hidden_service_fedwiki/hostname)
sed -i "s|link[href='https://maxcdn.bootstrapcdn.com.*|link[href='http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
sed -i "s|link\\[href='https://maxcdn.bootstrapcdn.com.*|link\\[href='http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
fi
if [ -f /usr/local/lib/node_modules/wiki/node_modules/localforage/docs/theme/style.css ]; then
sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/localforage/docs/theme/style.css
if [ -f /var/lib/wiki/node_modules/localforage/docs/theme/style.css ]; then
sed -i '/googleapi/d' /var/lib/wiki/node_modules/localforage/docs/theme/style.css
fi
if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html ]; then
sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html
if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html ]; then
sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html
fi
if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/done.html ]; then
sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/done.html
if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/done.html ]; then
sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/done.html
fi
if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html ]; then
sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html
if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html ]; then
sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html
fi
if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html ]; then
sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html
if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html ]; then
sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html
fi
if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-google-oauth20 ]; then
rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-google-oauth20
if [ -d /var/lib/wiki/node_modules/passport-google-oauth20 ]; then
rm -rf /var/lib/wiki/node_modules/passport-google-oauth20
fi
if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-oauth2 ]; then
rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-oauth2
if [ -d /var/lib/wiki/node_modules/passport-oauth2 ]; then
rm -rf /var/lib/wiki/node_modules/passport-oauth2
fi
if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-twitter ]; then
rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-twitter
if [ -d /var/lib/wiki/node_modules/passport-twitter ]; then
rm -rf /var/lib/wiki/node_modules/passport-twitter
fi
if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-github ]; then
rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-github
if [ -d /var/lib/wiki/node_modules/passport-github ]; then
rm -rf /var/lib/wiki/node_modules/passport-github
fi
}
@ -168,7 +168,13 @@ function upgrade_fedwiki {
systemctl stop fedwiki
npm upgrade -g wiki@$FEDWIKI_VERSION
cp -r /root/.npm-global/lib/node_modules/wiki/* /var/lib/wiki/
cp /root/.npm-global/bin/wiki /var/lib/wiki/wiki
chown -R fedwiki:fedwiki /var/lib/wiki
fedwiki_remove_bad_links
chown -R fedwiki:fedwiki $FEDWIKI_DATA
systemctl start fedwiki
@ -302,6 +308,9 @@ function remove_fedwiki {
if [ -d "/var/www/$FEDWIKI_DOMAIN_NAME" ]; then
rm -rf "/var/www/$FEDWIKI_DOMAIN_NAME"
fi
if [ -d /var/lib/wiki ]; then
rm -rf /var/lib/wiki
fi
remove_config_param FEDWIKI_DOMAIN_NAME
remove_config_param FEDWIKI_CODE
function_check remove_onion_service
@ -437,13 +446,13 @@ function install_fedwiki {
exit 783533
fi
if [ ! -f /usr/local/bin/wiki ]; then
if [ ! -f /root/.npm-global/bin/wiki ]; then
echo $'wiki was not installed'
exit 5293524
fi
if [ ! -d /usr/local/lib/node_modules/wiki ]; then
echo $'wiki directory not found /usr/local/lib/node_modules/wiki'
if [ ! -d /root/.npm-global/lib/node_modules/wiki ]; then
echo $'wiki directory not found /root/.npm-global/lib/node_modules/wiki'
exit 6285324
fi
@ -453,6 +462,10 @@ function install_fedwiki {
FEDWIKI_COOKIE="$(create_password 20)"
fi
cp -r /root/.npm-global/lib/node_modules/wiki /var/lib
cp /root/.npm-global/bin/wiki /var/lib/wiki
chown -R fedwiki:fedwiki /var/lib/wiki
{ echo '[Unit]';
echo 'Description=Fedwiki federated wiki';
echo 'After=syslog.target';
@ -461,8 +474,8 @@ function install_fedwiki {
echo '[Service]';
echo 'User=fedwiki';
echo 'Group=fedwiki';
echo "WorkingDirectory=/usr/local/lib/node_modules/wiki";
echo "ExecStart=/usr/local/bin/wiki --security_type friends --session_duration 7 --data $FEDWIKI_DATA -p $FEDWIKI_PORT --cookieSecret '${FEDWIKI_COOKIE}'";
echo "WorkingDirectory=/var/lib/wiki";
echo "ExecStart=/var/lib/wiki/wiki --security_type friends --session_duration 7 --data $FEDWIKI_DATA -p $FEDWIKI_PORT --cookieSecret '${FEDWIKI_COOKIE}'";
echo 'StandardOutput=syslog';
echo 'StandardError=syslog';
echo 'SyslogIdentifier=fedwiki';

View File

@ -152,31 +152,26 @@ function friendica_allow_registrations {
}
function configure_interactive_friendica {
W=(1 $"Set channel directory server"
2 $"Renew SSL certificate"
3 $"Close new account registrations"
4 $"Allow new account registrations")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Friendica" \
--radiolist $"Choose an operation:" 15 70 6 \
1 $"Set channel directory server" off \
2 $"Renew SSL certificate" off \
3 $"Close new account registrations" off \
4 $"Allow new account registrations" off \
5 $"Back to main menu" on 2> "$data"
sel=$?
case $sel in
1) break;;
255) break;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Friendica" --menu $"Choose an operation, or ESC to exit:" 14 60 4 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) friendica_channel_directory_server;;
2) friendica_renew_cert;;
3) friendica_close_registrations;;
4) friendica_allow_registrations;;
5) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -1,603 +0,0 @@
#!/bin/bash
#
# .---. . .
# | | |
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
#
# Freedom in the Cloud
#
# Ghost blog
#
# License
# =======
#
# Copyright (C) 2016-2018 Bob Mottram <bob@freedombone.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
VARIANTS="full full-vim writer"
IN_DEFAULT_INSTALL=0
SHOW_ON_ABOUT=1
GHOST_VERSION=1.19.0
GHOST_DOMAIN_NAME=
GHOST_CODE=
GHOST_ONION_PORT=8104
GHOST_PORT=2368
ghost_variables=(GHOST_DOMAIN_NAME
GHOST_CODE
GHOST_ADMIN_PASSWORD
ONION_ONLY
DDNS_PROVIDER
MY_USERNAME)
function ghost_bust {
# kill the started ghost process
kill_pid=$(pgrep "ghost run" | head -n 1)
kill -9 "$kill_pid"
kill_pid=$(pgrep "ghost" | head -n 1)
kill -9 "$kill_pid"
kill_pid=$(pgrep "ghost" | head -n 1)
kill -9 "$kill_pid"
}
function logging_on_ghost {
echo -n ''
}
function logging_off_ghost {
echo -n ''
}
function ghost_replace_jquery {
curr_domain="https://$GHOST_DOMAIN_NAME"
if [[ "$ONION_ONLY" != 'no' ]]; then
curr_domain="http://$GHOST_ONION_HOSTNAME"
fi
sed -i "s|src=\"https://code.jquery.com/jquery-.*|src=\"$curr_domain/jquery-${jquery_version}.js\"|g" current/content/themes/casper/default.hbs
sed -i "s|src=\"https://code.jquery.com/jquery-.*|src=\"$curr_domain/jquery-${jquery_version}.js\"></script>|g" current/node_modules/gscan/app/tpl/layouts/default.hbs
sed -i "s|http://code.jquery.com/jquery.js|$curr_domain/jquery-${jquery_version}.js|g" current/node_modules/jsdom/README.md
sed -i "s|https://code.jquery.com/jquery.js|$curr_domain/jquery-${jquery_version}.js|g" current/node_modules/jsdom/README.md
cd "/var/www/${GHOST_DOMAIN_NAME}/htdocs/current" || exit 3468368
find ./ -type f -exec sed -i -e "s|https://code.jquery.com|$curr_domain|g" {} \;
find ./ -type f -exec sed -i -e "s|http://code.jquery.com|$curr_domain|g" {} \;
}
function ghost_rss_button {
# remove feedly -aaargh!
sed -i 's|http://cloud.feedly.com/#subscription/feed/{{@blog.url}}/rss/|{{@blog.url}}/rss/|g' /var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/content/themes/casper/partials/site-nav.hbs
sed -i 's|http://cloud.feedly.com/#subscription/feed/{{url absolute="true"}}/rss/|{{url absolute="true"}}rss/|g' /var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/content/themes/casper/author.hbs
}
function ghost_remove_offsite_links {
curr_domain="$GHOST_DOMAIN_NAME"
if [[ "$ONION_ONLY" != 'no' ]]; then
curr_domain="$GHOST_ONION_HOSTNAME"
fi
ghost_rss_button
# remove google font links
cd "/var/www/$GHOST_DOMAIN_NAME/htdocs/current" || exit 246872424
find ./ -type f -exec sed -i -e "s/fonts.googleapis.com/$curr_domain/g" {} \;
# copy jquery locally
previous_jquery_version='1.12.0'
jquery_version='1.12.4'
if [ ! -f /var/www/$GHOST_DOMAIN_NAME/htdocs/jquery-${jquery_version}.js ]; then
cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 3468746824
wget https://code.jquery.com/jquery-${jquery_version}.js
jquery_hash=$(sha256sum jquery-${jquery_version}.js | awk -F ' ' '{print $1}')
if [[ "$jquery_hash" != '430f36f9b5f21aae8cc9dca6a81c4d3d84da5175eaedcf2fdc2c226302cb3575' ]]; then
echo $'Unexpected jquery hash value'
exit 258442
fi
fi
ghost_replace_jquery
previous_jquery_version='1.11.3'
ghost_replace_jquery
}
function ghost_replace_proprietary_services {
replace_file="$1"
sed -i 's|Twitter Profile|GNU Social Profile|g' "$replace_file"
sed -i 's|Twitter profile|GNU Social Profile|g' "$replace_file"
sed -i 's|Twitter Username|GNU Social Username|g' "$replace_file"
sed -i 's|twitter.com|quitter.se|g' "$replace_file"
sed -i 's|Facebook Page|Hubzilla Channel|g' "$replace_file"
sed -i 's|Facebook Profile|Hubzilla Channel|g' "$replace_file"
sed -i 's|Facebook profile|Hubzilla Channel|g' "$replace_file"
sed -i 's|www.facebook.com/username|hubzilladomain/username|g' "$replace_file"
sed -i 's|www.facebook.com/ghost|hubzilladomain/username|g' "$replace_file"
sed -i 's|www.facebook.com/testuser|hubzilladomain/username|g' "$replace_file"
sed -i 's|www.facebook.com/testing|hubzilladomain/username|g' "$replace_file"
sed -i 's|www.facebook.com/test|hubzilladomain/username|g' "$replace_file"
sed -i 's|www.facebook.com/yourUsername|hubzilladomain/username|g' "$replace_file"
sed -i 's|www.facebook.com/yourPage|hubzilladomain/username|g' "$replace_file"
sed -i 's|Facebook Username|Hubzilla Channel|g' "$replace_file"
sed -i 's|www.facebook.com|hubzilladomain|g' "$replace_file"
sed -i 's|facebook value|hubzilla value|g' "$replace_file"
sed -i '/<section class="share">/,/<\/section>/d' "$replace_file"
}
function ghost_replace_services {
ghost_replace_proprietary_services /var/www/${GHOST_DOMAIN_NAME}/htdocs/content/themes/casper/post.hbs
}
function remove_user_ghost {
remove_username="$1"
}
function add_user_ghost {
if [[ $(app_is_installed ghost) == "0" ]]; then
echo '0'
return
fi
new_username="$1"
new_user_password="$2"
echo '0'
}
function install_interactive_ghost {
if [ ! "$ONION_ONLY" ]; then
ONION_ONLY='no'
fi
if [[ $ONION_ONLY != "no" ]]; then
GHOST_DOMAIN_NAME='ghost.local'
write_config_param "GHOST_DOMAIN_NAME" "$GHOST_DOMAIN_NAME"
else
function_check interactive_site_details
interactive_site_details "ghost" "GHOST_DOMAIN_NAME" "GHOST_CODE"
fi
APP_INSTALLED=1
}
function change_password_ghost {
#GHOST_USERNAME="$1"
GHOST_PASSWORD="$2"
if [ ${#GHOST_PASSWORD} -lt 8 ]; then
echo $'Ghost password is too short'
return
fi
#"${PROJECT_NAME}-pass" -u "$GHOST_USERNAME" -a ghost -p "$GHOST_PASSWORD"
}
function reconfigure_ghost {
echo -n ''
}
function upgrade_ghost {
CURR_GHOST_VERSION=$(get_completion_param "ghost version")
if [[ "${CURR_GHOST_VERSION}" == "${GHOST_VERSION}" ]]; then
return
fi
read_config_param GHOST_DOMAIN_NAME
if [ ! -d /var/www/$GHOST_DOMAIN_NAME/htdocs ]; then
return
fi
systemctl stop ghost
ghost_bust
cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 3468463
npm i -g ghost-cli
/usr/local/bin/ghost update &
sleep 200
ghost_bust
ghost_replace_services
ghost_remove_offsite_links
chown root:root /usr/local/bin/ghost
chown -R root:root /usr/local/lib
chown -R ghost: /var/www/${GHOST_DOMAIN_NAME}/htdocs
systemctl restart ghost
sed -i "s|ghost version.*|ghost version:${GHOST_VERSION}|g" "${COMPLETION_FILE}"
}
function backup_local_ghost {
GHOST_DOMAIN_NAME='ghost.local'
if grep -q "ghost domain" "$COMPLETION_FILE"; then
GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
fi
suspend_site "${GHOST_DOMAIN_NAME}"
systemctl stop ghost
ghost_path=/var/www/${GHOST_DOMAIN_NAME}/htdocs/content
if [ -d "$ghost_path" ]; then
backup_directory_to_usb "$ghost_path" ghostcontent
fi
ghost_path=/var/www/${GHOST_DOMAIN_NAME}/htdocs/current/content
if [ -d "$ghost_path" ]; then
backup_directory_to_usb "$ghost_path" ghostcurrent
fi
systemctl start ghost
restart_site
}
function restore_local_ghost {
GHOST_DOMAIN_NAME='ghost.local'
if grep -q "ghost domain" "$COMPLETION_FILE"; then
GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
fi
if [ "$GHOST_DOMAIN_NAME" ]; then
suspend_site "${GHOST_DOMAIN_NAME}"
systemctl stop ghost
temp_restore_dir=/root/tempghostcontent
function_check restore_directory_from_usb
restore_directory_from_usb $temp_restore_dir ghostcontent
if [ -d $temp_restore_dir ]; then
if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
else
if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
mkdir "/var/www/$GHOST_DOMAIN_NAME/htdocs/content"
fi
cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
fi
chown -R ghost:ghost "/var/www/$GHOST_DOMAIN_NAME/htdocs/content"
rm -rf $temp_restore_dir
fi
temp_restore_dir=/root/tempghostcurrent
function_check restore_directory_from_usb
restore_directory_from_usb $temp_restore_dir ghostcurrent
if [ -d $temp_restore_dir ]; then
if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
else
if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
mkdir -p "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content"
fi
cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
fi
chown -R ghost:ghost "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content"
rm -rf $temp_restore_dir
fi
systemctl start ghost
restart_site
fi
}
function backup_remote_ghost {
GHOST_DOMAIN_NAME='ghost.local'
if grep -q "ghost domain" "$COMPLETION_FILE"; then
GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
fi
suspend_site "${GHOST_DOMAIN_NAME}"
temp_backup_dir=/var/www/${GHOST_DOMAIN_NAME}/htdocs/content
if [ -d "$temp_backup_dir" ]; then
backup_directory_to_friend "$temp_backup_dir" ghostcontent
else
restart_site
echo $"Ghost domain specified but not found in /var/www/${GHOST_DOMAIN_NAME}"
exit 2578
fi
temp_backup_dir=/var/www/${GHOST_DOMAIN_NAME}/htdocs/current/content
if [ -d "$temp_backup_dir" ]; then
backup_directory_to_friend "$temp_backup_dir" ghostcurrent
else
restart_site
echo $"Ghost domain specified but not found in $temp_backup_dir"
exit 78353
fi
restart_site
}
function restore_remote_ghost {
GHOST_DOMAIN_NAME='ghost.local'
if grep -q "ghost domain" "$COMPLETION_FILE"; then
GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
fi
suspend_site "${GHOST_DOMAIN_NAME}"
systemctl stop ghost
temp_restore_dir=/root/tempghostcontent
function_check restore_directory_from_friend
restore_directory_from_friend $temp_restore_dir ghostcontent
if [ -d $temp_restore_dir ]; then
if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
else
if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
mkdir "/var/www/$GHOST_DOMAIN_NAME/htdocs/content"
fi
cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
fi
chown -R ghost: "/var/www/$GHOST_DOMAIN_NAME/htdocs"
rm -rf $temp_restore_dir
fi
temp_restore_dir=/root/tempghostcurrent
function_check restore_directory_from_friend
restore_directory_from_friend $temp_restore_dir ghostcurrent
if [ -d $temp_restore_dir ]; then
if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
else
if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
mkdir -p "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content"
fi
cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
fi
chown -R ghost: "/var/www/$GHOST_DOMAIN_NAME/htdocs"
rm -rf $temp_restore_dir
fi
systemctl start ghost
restart_site
}
function remove_ghost {
if [ ${#GHOST_DOMAIN_NAME} -eq 0 ]; then
return
fi
systemctl stop ghost
systemctl disable ghost
rm /etc/systemd/system/ghost.service
systemctl daemon-reload
npm uninstall -g ghost-cli
function_check remove_nodejs
remove_nodejs ghost
read_config_param "GHOST_DOMAIN_NAME"
nginx_dissite "$GHOST_DOMAIN_NAME"
remove_certs "${GHOST_DOMAIN_NAME}"
if [ -f "/etc/nginx/sites-available/$GHOST_DOMAIN_NAME" ]; then
rm -f "/etc/nginx/sites-available/$GHOST_DOMAIN_NAME"
fi
if [ -d "/var/www/$GHOST_DOMAIN_NAME" ]; then
rm -rf "/var/www/$GHOST_DOMAIN_NAME"
fi
remove_config_param GHOST_DOMAIN_NAME
remove_config_param GHOST_CODE
function_check remove_onion_service
remove_onion_service ghost ${GHOST_ONION_PORT}
remove_completion_param "install_ghost"
sed -i '/Ghost/d' "$COMPLETION_FILE"
sed -i '/ghost/d' "$COMPLETION_FILE"
groupdel -f ghost
userdel -r ghost
function_check remove_ddns_domain
remove_ddns_domain "$GHOST_DOMAIN_NAME"
}
function install_ghost {
check_ram_availability 900
if [ ! $ONION_ONLY ]; then
ONION_ONLY='no'
fi
if [ ! "$GHOST_DOMAIN_NAME" ]; then
echo $'The ghost domain name was not specified'
exit 5062
fi
# for the avatar changing command
apt-get -yq install unzip wget
if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs" ]; then
mkdir -p "/var/www/$GHOST_DOMAIN_NAME/htdocs"
fi
cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 26422842
function_check install_nodejs
install_nodejs ghost
# now install ghost itself
npm install -g ghost-cli@latest
if [ ! -f /usr/local/bin/ghost ]; then
echo $'ghost was not installed'
exit 738539
fi
GHOST_ONION_HOSTNAME=$(add_onion_service ghost 80 ${GHOST_ONION_PORT})
npm install -g yarn
yarn install --no-emoji --no-progress
yarn cache clean
adduser --system --home="/var/www/${GHOST_DOMAIN_NAME}/htdocs/" --group ghost
rm -rf "/var/www/$GHOST_DOMAIN_NAME/htdocs/"*
printf 'y' | ghost install ${GHOST_VERSION} --user ghost --db=sqlite3 --port ${GHOST_PORT} --verbose
if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/versions" ]; then
echo $'versions directory was not found'
exit 782523462
fi
if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
echo $'content directory was not found'
exit 68352682
fi
npm install -g knex-migrator
if [ ! -f "/var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/MigratorConfig.js" ]; then
echo $'MigratorConfig.js was not found'
exit 62783538
fi
cp "/var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/MigratorConfig.js" "/var/www/$GHOST_DOMAIN_NAME/htdocs"
chown -R ghost: "/var/www/$GHOST_DOMAIN_NAME/htdocs"
cd "/var/www/$GHOST_DOMAIN_NAME/htdocs/current" || exit 783452464
knex-migrator init
ghost_bust
echo '{' > "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
if [[ "$ONION_ONLY" == 'no' ]]; then
# NOTE: url must be http, not https
echo " \"url\": \"http://${GHOST_DOMAIN_NAME}\"," >> "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
else
echo " \"url\": \"http://${GHOST_ONION_HOSTNAME}\"," >> "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
fi
{ echo ' "paths": {';
echo " \"contentPath\": \"/var/www/${GHOST_DOMAIN_NAME}/htdocs/content\"";
echo ' }';
echo '}'; } >> "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
{ echo '[Unit]';
echo 'Description=Ghost Blog';
echo 'After=syslog.target';
echo 'After=network.target';
echo '';
echo '[Service]';
echo 'Type=simple';
echo 'User=ghost';
echo 'Group=ghost';
echo "WorkingDirectory=/var/www/${GHOST_DOMAIN_NAME}/htdocs";
echo "ExecStart=/usr/local/bin/ghost run -D";
echo "ExecStop=/usr/local/bin/ghost stop";
echo "ExecRestart=/usr/local/bin/ghost restart";
echo 'Restart=always';
echo 'RestartSec=60';
echo "Environment=NODE_ENV=development PORT=${GHOST_PORT}";
echo '';
echo '[Install]';
echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/ghost.service
ghost_remove_offsite_links
chown -R ghost: "/var/www/${GHOST_DOMAIN_NAME}/htdocs"
systemctl enable ghost
systemctl daemon-reload
systemctl start ghost
if [[ ${ONION_ONLY} == "no" ]]; then
function_check nginx_http_redirect
nginx_http_redirect "${GHOST_DOMAIN_NAME}"
{ echo 'server {';
echo ' listen 443 ssl;';
echo ' #listen [::]:443 ssl;';
echo " root /var/www/${GHOST_DOMAIN_NAME}/htdocs;";
echo " server_name ${GHOST_DOMAIN_NAME};";
echo ' access_log /dev/null;';
echo " error_log /dev/null;";
echo ''; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
function_check nginx_ssl
nginx_ssl "${GHOST_DOMAIN_NAME}"
function_check nginx_security_options
nginx_security_options "${GHOST_DOMAIN_NAME}"
{ echo ' add_header Strict-Transport-Security max-age=0;';
echo '';
echo ' location / {'; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
function_check nginx_limits
nginx_limits "${GHOST_DOMAIN_NAME}" '10G'
{ echo " proxy_pass http://localhost:${GHOST_PORT};";
echo ' }';
echo '';
echo ' fastcgi_buffers 64 4K;';
echo '';
echo ' error_page 403 /core/templates/403.php;';
echo ' error_page 404 /core/templates/404.php;';
echo '';
echo ' location = /robots.txt {';
echo ' allow all;';
echo ' log_not_found off;';
echo ' access_log /dev/null;';
echo ' }';
echo '}';
echo ''; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
else
echo -n '' > "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
fi
{ echo 'server {';
echo " listen 127.0.0.1:${GHOST_ONION_PORT} default_server;";
echo " root /var/www/$GHOST_DOMAIN_NAME/htdocs;";
echo " server_name $GHOST_ONION_HOSTNAME;";
echo ' access_log /dev/null;';
echo " error_log /dev/null;";
echo ''; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
function_check nginx_security_options
nginx_security_options "${GHOST_DOMAIN_NAME}"
{ echo ' add_header Strict-Transport-Security max-age=0;';
echo '';
echo ' location / {'; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
function_check nginx_limits
nginx_limits "${GHOST_DOMAIN_NAME}" '10G'
{ echo " proxy_pass http://localhost:${GHOST_PORT};";
echo ' }';
echo '';
echo ' fastcgi_buffers 64 4K;';
echo '';
echo ' error_page 403 /core/templates/403.php;';
echo ' error_page 404 /core/templates/404.php;';
echo '';
echo ' location = /robots.txt {';
echo ' allow all;';
echo ' log_not_found off;';
echo ' access_log /dev/null;';
echo ' }';
echo '}'; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
function_check create_site_certificate
create_site_certificate "$GHOST_DOMAIN_NAME" 'yes'
ghost_replace_services
function_check nginx_ensite
nginx_ensite "$GHOST_DOMAIN_NAME"
systemctl restart nginx
"${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a ghost -p "$GHOST_ADMIN_PASSWORD"
function_check add_ddns_domain
add_ddns_domain "$GHOST_DOMAIN_NAME"
chown root:root /usr/local/bin/ghost
chown -R root:root /usr/local/lib
chown -R ghost: "/var/www/${GHOST_DOMAIN_NAME}/htdocs"
set_completion_param "ghost domain" "$GHOST_DOMAIN_NAME"
if ! grep -q "ghost version:" "${COMPLETION_FILE}"; then
echo "ghost version:${GHOST_VERSION}" >> "${COMPLETION_FILE}"
else
sed -i "s|ghost version.*|ghost version:${GHOST_VERSION}|g" "${COMPLETION_FILE}"
fi
APP_INSTALLED=1
}
# NOTE: deliberately no exit 0

View File

@ -306,34 +306,28 @@ function configure_interactive_gnusocial {
read_config_param GNUSOCIAL_EXPIRE_MONTHS
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"GNU Social" \
--radiolist $"Choose an operation:" 16 70 7 \
1 $"Set a background image" off \
2 $"Set the title" off \
3 $"Set post expiry period (currently $GNUSOCIAL_EXPIRE_MONTHS months)" off \
4 $"Select Qvitter user interface" off \
5 $"Select Pleroma user interface" off \
6 $"Select Classic user interface" off \
7 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
W=(1 $"Set a background image"
2 $"Set the title"
3 $"Set post expiry period (currently $GNUSOCIAL_EXPIRE_MONTHS months)"
4 $"Select Qvitter user interface"
5 $"Select Pleroma user interface"
6 $"Select Classic user interface")
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"GNU Social" --menu $"Choose an operation, or ESC to exit:" 15 60 6 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) gnusocial_set_background_image;;
2) gnusocial_set_title;;
3) gnusocial_set_expire_months;;
4) gnusocial_use_qvitter gnusocial;;
5) gnusocial_use_pleroma gnusocial;;
6) gnusocial_use_classic gnusocial;;
7) break;;
esac
rm -f "$data"
done
}

View File

@ -138,27 +138,22 @@ function hubzilla_channel_directory_server {
}
function configure_interactive_hubzilla {
W=(1 $"Set channel directory server"
2 $"Renew SSL certificate")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Hubzilla" \
--radiolist $"Choose an operation:" 13 70 4 \
1 $"Set channel directory server" off \
2 $"Renew SSL certificate" off \
3 $"Back to main menu" on 2> "$data"
sel=$?
case $sel in
1) break;;
255) break;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Hubzilla" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) hubzilla_channel_directory_server;;
2) hubzilla_renew_cert;;
3) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -401,32 +401,28 @@ function icecast_set_maximum_streams {
}
function configure_interactive_icecast {
W=(1 $"Import stream files from directory"
2 $"Import stream files from USB drive"
3 $"Format a USB drive for stream file storage"
4 $"Export stream files to USB drive"
5 $"Manually edit playlist"
6 $"Enable login for stream visitors"
7 $"Change password for stream visitors"
8 $"Re-scan playlist"
9 $"Restart stream"
10 $"Set Stream Name/Description/Genre"
11 $"Set maximum number of clients/streams")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Icecast" \
--radiolist $"Choose an operation:" 19 70 12 \
1 $"Import stream files from directory" off \
2 $"Import stream files from USB drive" off \
3 $"Format a USB drive for stream file storage" off \
4 $"Export stream files to USB drive" off \
5 $"Manually edit playlist" off \
6 $"Enable login for stream visitors" off \
7 $"Change password for stream visitors" off \
8 $"Re-scan playlist" off \
9 $"Restart stream" off \
10 $"Set Stream Name/Description/Genre" off \
11 $"Set maximum number of clients/streams" off \
12 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
break;;
255) rm -f "$data"
break;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Icecast" --menu $"Choose an operation, or ESC to exit:" 20 60 11 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) icecast_import_from_directory;;
2) icecast_import_from_usb;;
3) icecast_format_drive;;
@ -443,10 +439,7 @@ function configure_interactive_icecast {
start_icecast;;
10) icecast_set_stream_name;;
11) icecast_set_maximum_streams;;
12) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -398,28 +398,22 @@ function configure_interactive_irc {
return
fi
W=(1 $"Set a password for all IRC users"
2 $"Show current IRC login password")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"IRC Menu" \
--radiolist $"Choose an operation:" 14 70 4 \
1 $"Set a password for all IRC users" off \
2 $"Show current IRC login password" off \
3 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
break;;
255) rm -f "$data"
break;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"IRC" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) irc_set_global_password;;
2) irc_show_password;;
3) break;;
esac
rm -f "$data"
done
}

View File

@ -531,31 +531,24 @@ function keyserver_remove_key {
}
function configure_interactive_keyserver {
W=(1 $"Remove a key"
2 $"Sync with other keyserver"
3 $"Edit sync keyservers")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"SKS Keyserver" \
--radiolist $"Choose an operation:" 12 70 4 \
1 $"Remove a key" off \
2 $"Sync with other keyserver" off \
3 $"Edit sync keyservers" off \
4 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"SKS Keyserver" --menu $"Choose an operation, or ESC to exit:" 11 60 3 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) keyserver_remove_key;;
2) keyserver_sync;;
3) keyserver_edit;;
4) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -272,33 +272,26 @@ function format_music_drive {
function configure_interactive_koel {
W=(1 $"Import music from directory"
2 $"Import music from USB drive"
3 $"Export music to USB drive"
4 $"Format a USB drive for music storage")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Koel" \
--radiolist $"Choose an operation:" 12 70 5 \
1 $"Import music from directory" off \
2 $"Import music from USB drive" off \
3 $"Export music to USB drive" off \
4 $"Format a USB drive for music storage" off \
5 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
break;;
255) rm -f "$data"
break;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Koel" --menu $"Choose an operation, or ESC to exit:" 12 60 4 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) koel_import_from_directory;;
2) koel_import_from_usb;;
3) koel_export_to_usb;;
4) format_music_drive;;
5) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -227,7 +227,7 @@ function install_mailpile {
echo 'User=mailpile';
echo 'Group=mailpile';
echo "WorkingDirectory=/var/www/$MAILPILE_DOMAIN_NAME/mail";
echo "ExecStart=/var/www/$MAILPILE_DOMAIN_NAME/mail/mp --www=0.0.0.0:${MAILPILE_PORT} --wait";
echo "ExecStart=/var/www/$MAILPILE_DOMAIN_NAME/mail/mp --www=127.0.0.1:${MAILPILE_PORT} --wait";
echo 'Restart=always';
echo 'RestartSec=10';
echo '';

View File

@ -125,7 +125,7 @@ function matrix_nginx {
matrix_nginx_site=/etc/nginx/sites-available/$MATRIX_DOMAIN_NAME
if [[ $ONION_ONLY == "no" ]]; then
{ echo 'server {';
echo " listen 0.0.0.0:443;";
echo " listen 443;";
echo " server_name ${MATRIX_DOMAIN_NAME};";
echo '';
echo ' # Security'; } > $matrix_nginx_site
@ -154,7 +154,7 @@ function matrix_nginx {
echo '}';
echo '';
echo 'server {';
echo " listen 0.0.0.0:${MATRIX_HTTP_PORT};";
echo " listen ${MATRIX_HTTP_PORT};";
echo " server_name ${MATRIX_DOMAIN_NAME};";
echo '';
echo ' # Security'; } >> $matrix_nginx_site

View File

@ -39,7 +39,7 @@ SHOW_ON_ABOUT=1
PEERTUBE_DOMAIN_NAME=
PEERTUBE_CODE=
PEERTUBE_REPO="https://github.com/Chocobozzz/PeerTube"
PEERTUBE_COMMIT='fef2c7164e025b12a64185dbab058ef4129733c6'
PEERTUBE_COMMIT='f209b32afaffbb8b93c265525ebde182ab66c37a'
PEERTUBE_ONION_PORT=8136
PEERTUBE_PORT=9004
MESH_PEERTUBE_PORT=8500
@ -54,6 +54,93 @@ peertube_variables=(PEERTUBE_DOMAIN_NAME
ARCHITECTURE
MY_EMAIL_ADDRESS)
function peertube_import_from_syncthing {
peertubedomain="https://$PEERTUBE_DOMAIN_NAME"
nodecmd='node'
if [[ "$ONION_ONLY" != 'no' ]]; then
peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)"
nodecmd='torsocks node'
fi
{ echo '#!/bin/bash';
echo '';
echo 'LOCKFILE=/tmp/.peertube.lock';
echo '';
echo 'if [ -f /root/.peertube.lock ]; then';
echo " lockctr=\$(cat \$LOCKFILE)";
echo " lockctr=\$((lockctr+1))";
echo " echo \"\$lockctr\" > \$LOCKFILE";
echo " if [ \$lockctr -ge 30 ]; then";
echo " rm \$LOCKFILE";
echo ' else';
echo ' exit 0';
echo ' fi';
echo 'fi';
echo '';
echo "MY_USERNAME=\$(cat /root/${PROJECT_NAME}.cfg | grep MY_USERNAME | awk -F '=' '{print \$2}')";
echo "if [ ! \"\$MY_USERNAME\" ]; then";
echo ' exit 0';
echo 'fi';
echo '';
echo "search_dir=/home/\$MY_USERNAME/Sync/peertube_upload";
echo "if [ ! -f \$search_dir/login.txt ]; then";
echo ' exit 0';
echo 'fi';
echo "import_script=${PEERTUBE_DIR}/dist/server/tools/upload.js";
echo "if [ ! -f \$import_script ]; then";
echo ' exit 0';
echo 'fi';
echo '';
echo "peertubedomain=\"$peertubedomain\"";
echo "peertubeuser=\$(sed -n 1p < \"\$search_dir/login.txt\")";
echo "peertubepassword=\$(sed -n 2p < \"\$search_dir/login.txt\")";
echo 'peertubensfw=';
echo "if grep -q 'nsfw' \"\$search_dir/login.txt\"; then";
echo " peertubensfw='--nsfw'";
echo 'fi';
echo "if grep -q 'NSFW' \"\$search_dir/login.txt\"; then";
echo " peertubensfw='--nsfw'";
echo 'fi';
echo '';
echo "peertubeprivate='-P 3'";
echo "if grep -q 'public' \"\$search_dir/login.txt\"; then";
echo " peertubeprivate='-P 1'";
echo 'fi';
echo "if grep -q 'Public' \"\$search_dir/login.txt\"; then";
echo " peertubeprivate='-P 1'";
echo 'fi';
echo '';
echo 'failed_uploads=0';
echo '';
echo "cd ${PEERTUBE_DIR} || exit 32468356";
echo "echo \"0\" > \$LOCKFILE";
echo '';
echo "for video_file in \$search_dir/*; do";
echo " if [[ \"\$video_file\" == *'.ogv' || \"\$video_file\" == *'.mp4' || \"\$video_file\" == *'.webm' ]]; then";
echo " if ! grep -q \"\$video_file\" /root/.peertube_uploaded; then";
echo " peertubetitle=\$(basename \"\$video_file\" | awk -F '.' '{print \$1}' | sed 's|_| |g' | sed 's|-| |g')";
echo " if $nodecmd \$import_script -n \"\$peertubetitle\" \$peertubensfw \$peertubeprivate -u \"\$peertubedomain\" -U \"\$peertubeuser\" --password \"\$peertubepassword\" -f \"\$video_file\"; then";
echo " echo \"\$video_file\" >> /root/.peertube_uploaded";
echo " rm \$LOCKFILE";
echo " exit 0";
echo ' else';
echo " failed_uploads=\$((failed_uploads+1))";
echo " if [ \$failed_uploads -gt 1 ]; then";
echo " rm \$LOCKFILE";
echo ' exit 0';
echo ' fi';
echo ' fi';
echo ' fi';
echo ' fi';
echo 'done';
echo '';
echo "rm \$LOCKFILE"; } > /usr/bin/peertubesync
chmod +x /usr/bin/peertubesync
cron_add_mins 1 /usr/bin/peertubesync
}
function peertube_create_database {
if [ -f "$IMAGE_PASSWORD_FILE" ]; then
PEERTUBE_ADMIN_PASSWORD="$(printf "%s" "$(cat "$IMAGE_PASSWORD_FILE")")"
@ -149,28 +236,172 @@ function peertube_disable_signups {
systemctl restart peertube
}
function configure_interactive_peertube {
while true
do
data=$(mktemp 2>/dev/null)
function peertube_import_from_file {
read_config_param MY_USERNAME
read_config_param PEERTUBE_DOMAIN_NAME
read_config_param ONION_ONLY
data2=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"PeerTube" \
--radiolist $"Choose an operation:" 10 70 4 \
1 $"Set administrator email address" off \
2 $"Disable or enable signups" off \
3 $"Exit" on 2> "$data"
--title $"Import Video from file" \
--form $"Enter your PeerTube login details and video title" 10 65 4 \
$"Username:" 1 1 "$MY_USERNAME" 1 18 16 15 \
$"Password:" 2 1 "" 2 18 40 10000 \
$"Video Title:" 3 1 "" 3 18 40 1000 \
$"NSFW:" 4 1 $"no" 4 18 4 4 \
2> "$data2"
sel=$?
case $sel in
1) break;;
255) break;;
1) rm -f "$data2"
return;;
255) rm -f "$data2"
return;;
esac
case $(cat "$data") in
peertubeuser=$(sed -n 1p < "$data2")
peertubepassword=$(sed -n 2p < "$data2")
peertubetitle=$(sed -n 3p < "$data2")
peertubensfw=$(sed -n 4p < "$data2")
rm -f "$data2"
peertubedomain="https://$PEERTUBE_DOMAIN_NAME"
nodecmd='node'
if [[ "$ONION_ONLY" != 'no' ]]; then
peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)"
nodecmd='torsocks node'
fi
data2=$(mktemp 2>/dev/null)
dialog --title "Choose the video file (select with spacebar)" --fselect "/home/$MY_USERNAME/" 30 60 2> "$data2"
selected_file=$(cat "$data2")
rm -f "$data2"
if [ ! "$selected_file" ]; then
return
fi
if [[ "$selected_file" != *'.ogv' && "$selected_file" != *'.mp4' && "$selected_file" != *'.webm' ]]; then
dialog --title $"Import video from file" \
--msgbox $"The video should be in ogv, mp4 or webm format" 6 75
return
fi
cd $PEERTUBE_DIR || exit 32468356
import_script=$PEERTUBE_DIR/dist/server/tools/upload.js
if [ ! -f $import_script ]; then
dialog --title $"Import videos" \
--msgbox $"upload script was not found" 6 75
return
fi
nsfwstr=
if [[ "$peertubensfw" == *'y'* || "$peertubensfw" == *'Y'* ]]; then
nsfwstr='--nsfw'
fi
titlestr=$(basename "$selected_file" | awk -F '.' '{print $1}' | sed 's|_| |g' | sed 's|-| |g')
if [ "$peertubetitle" ]; then
titlestr="-n \"$peertubetitle\""
fi
clear
$nodecmd $import_script $nsfwstr "$titlestr" -u "$peertubedomain" -U "$peertubeuser" --password "$peertubepassword" -f "$selected_file"
dialog --title $"Import video from file" \
--msgbox $"Video imported from $selected_file" 6 75
}
function peertube_import_videos {
read_config_param MY_USERNAME
read_config_param PEERTUBE_DOMAIN_NAME
read_config_param ONION_ONLY
data2=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Import Videos from legacy sites" \
--form $"Enter a channel of video URL for YouTube/Vimeo/Dailymotion" 10 75 4 \
$"Username:" 1 1 "$MY_USERNAME" 1 22 16 15 \
$"Password:" 2 1 "" 2 22 50 10000 \
$"Video/Channel URL:" 3 1 "" 3 22 50 10000 \
2> "$data2"
sel=$?
case $sel in
1) rm -f "$data2"
return;;
255) rm -f "$data2"
return;;
esac
peertubeuser=$(sed -n 1p < "$data2")
peertubepassword=$(sed -n 2p < "$data2")
video_url=$(sed -n 3p < "$data2")
rm -f "$data2"
peertubedomain="https://$PEERTUBE_DOMAIN_NAME"
nodecmd='node'
if [[ "$ONION_ONLY" != 'no' ]]; then
peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)"
nodecmd='torsocks node'
fi
if [ ${#peertubeuser} -lt 3 ]; then
dialog --title $"Import videos from legacy sites" \
--msgbox $"Username was not valid" 6 75
return
fi
if [ ${#peertubepassword} -lt 3 ]; then
dialog --title $"Import videos from legacy sites" \
--msgbox $"Password was not valid" 6 75
return
fi
if [[ "$video_url" == *' '* || "$video_url" == *','* || "$video_url" == *'@'* ]]; then
dialog --title $"Import videos from legacy sites" \
--msgbox $"Video/channel URL was not valid" 6 75
return
fi
if [ ${#video_url} -lt 8 ]; then
dialog --title $"Import videos from legacy sites" \
--msgbox $"Video/channel URL was not valid" 6 75
return
fi
cd $PEERTUBE_DIR || exit 32468356
import_script=$PEERTUBE_DIR/dist/server/tools/import-videos.js
if [ ! -f $import_script ]; then
dialog --title $"Import videos from legacy sites" \
--msgbox $"import-videos script was not found" 6 75
return
fi
clear
$nodecmd $import_script -u "$peertubedomain" -U "$peertubeuser" --password "$peertubepassword" -t "$video_url"
dialog --title $"Import videos from legacy sites" \
--msgbox $"Video/s imported from $video_url" 6 75
}
function configure_interactive_peertube {
W=(1 $"Set administrator email address"
2 $"Disable or enable signups"
3 $"Import videos from YouTube/Vimeo/Dailymotion"
4 $"Import video from file")
while true
do
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"PeerTube" --menu $"Choose an operation, or ESC to exit:" 12 60 4 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) peertube_set_admin_email;;
2) peertube_disable_signups;;
3) rm -f "$data"
break;;
3) peertube_import_videos;;
4) peertube_import_from_file;;
esac
rm -f "$data"
done
}
@ -189,6 +420,8 @@ function reconfigure_peertube {
}
function upgrade_peertube {
peertube_import_from_syncthing
CURR_PEERTUBE_COMMIT=$(get_completion_param "peertube commit")
if [[ "$CURR_PEERTUBE_COMMIT" == "$PEERTUBE_COMMIT" ]]; then
return
@ -342,6 +575,14 @@ function remove_peertube {
remove_onion_service peertube ${PEERTUBE_ONION_PORT}
remove_completion_param "install_peertube"
sed -i '/peertube/d' "$COMPLETION_FILE"
sed -i '/peertubesync/d' /etc/crontab
if [ -f /usr/bin/peertubesync ]; then
rm /usr/bin/peertubesync
fi
if [ -f /root/peertube_uploaded ]; then
rm /root/peertube_uploaded
fi
function_check drop_database_postgresql
drop_database_postgresql peertube peertube
@ -622,11 +863,11 @@ function mesh_install_peertube {
if [[ "$VARIANT" != "meshclient" && "$VARIANT" != "meshusb" ]]; then
return
fi
if [[ "$ARCHITECTURE" != 'x86_64' && "$ARCHITECTURE" != 'amd64' ]]; then
if [[ "$ARCHITECTURE" != 'x86_64' && "$ARCHITECTURE" != 'amd64' && "$ARCHITECTURE" != 'i386' ]]; then
return
fi
chroot "$rootdir" apt-get -yq install ffmpeg curl
chroot "$rootdir" apt-get -yq install ffmpeg curl redis-tools redis-server
function_check install_postgresql
install_postgresql
@ -653,35 +894,40 @@ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/source
apt-get -y update
apt-get -yq install yarn
#npm install --arch=$NPM_ARCH -g yarn
#if [ ! "\$?" = "0" ]; then
#if ! npm install --arch=$NPM_ARCH -g yarn@1.5.1; then
# echo $'PeerTube Failed to install yarn'
# exit 79353234
#fi
#npm install --arch=$NPM_ARCH webpack@3.10.0 --no-optional
#if [ ! "\$?" = "0" ]; then
#if ! npm install --arch=$NPM_ARCH webpack@3.10.0 --no-optional; then
# echo $'PeerTube failed to install webpack'
# exit 68386353
#fi
yarn install
yarn run build:prod
yarn add -D webpack
if [ ! "\$?" = "0" ]; then
if ! yarn add -D webpack; then
echo $'PeerTube failed to add webpack'
exit 67342823
fi
yarn install --ignore-optional
if [ ! "\$?" = "0" ]; then
if ! yarn install --ignore-optional; then
echo $'PeerTube failed to run yarn install'
exit 63754235
fi
npm install --arch=$NPM_ARCH
if [ ! "\$?" = "0" ]; then
if ! npm install --arch=$NPM_ARCH -g npm@4; then
# https://github.com/KraigM/homebridge-harmonyhub/issues/119
echo $'Failed to downgrade npm'
exit 3476835
fi
cp /root/.npm-global/bin/npm /usr/local/bin/npm
if ! npm install --arch=$NPM_ARCH; then
echo $'PeerTube failed to install peertube'
exit 7835243
fi
npm run build --arch=$NPM_ARCH
if [ ! "\$?" = "0" ]; then
if ! npm install --arch=$NPM_ARCH -g "npm@${NPM_VERSION}"; then
echo $'Failed to restore npm after downgrade'
exit 5737583
fi
cp /root/.npm-global/bin/npm /usr/local/bin/npm
if ! npm run build --arch=$NPM_ARCH; then
echo $'PeerTube failed to build peertube'
exit 5293593
fi
@ -737,7 +983,7 @@ function install_peertube {
exit 783523
fi
apt-get -yq install ffmpeg
apt-get -yq install ffmpeg redis-tools redis-server
function_check install_postgresql
install_postgresql
@ -772,7 +1018,7 @@ function install_peertube {
git checkout $PEERTUBE_COMMIT -b $PEERTUBE_COMMIT
set_completion_param "peertube commit" "$PEERTUBE_COMMIT"
if ! npm install -g yarn; then
if ! npm install -g yarn@1.5.1; then
echo $'Failed to install yarn'
exit 79353234
fi
@ -781,10 +1027,21 @@ function install_peertube {
echo $'Failed to run yarn install'
exit 63754235
fi
if ! npm install -g npm@4; then
# https://github.com/KraigM/homebridge-harmonyhub/issues/119
echo $'Failed to downgrade npm'
exit 3476835
fi
cp /root/.npm-global/bin/npm /usr/local/bin/npm
if ! npm install; then
echo $'Failed to install peertube'
exit 7835243
fi
if ! npm install -g "npm@${NPM_VERSION}"; then
echo $'Failed to restore npm after downgrade'
exit 5737583
fi
cp /root/.npm-global/bin/npm /usr/local/bin/npm
if ! npm run build; then
echo $'Failed to build peertube'
exit 5293593
@ -834,6 +1091,8 @@ function install_peertube {
# update the admin email address after creation of the database
sed -i "s|email: .*|email: '$MY_EMAIL_ADDRESS'|g" $PEERTUBE_DIR/config/production.yaml
peertube_import_from_syncthing
set_completion_param "peertube domain" "$PEERTUBE_DOMAIN_NAME"
APP_INSTALLED=1
}

View File

@ -37,8 +37,8 @@ IN_DEFAULT_INSTALL=0
SHOW_ON_ABOUT=0
PIHOLE_IFACE=eth0
PIHOLE_DNS1='85.214.73.63'
PIHOLE_DNS2='213.73.91.35'
PIHOLE_DNS1='91.239.100.100'
PIHOLE_DNS2='89.233.43.71'
piholeBasename=pihole
piholeDir=/etc/$piholeBasename
@ -134,26 +134,27 @@ function pihole_update {
function pihole_change_upstream_dns {
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Ad Blocker Upstream DNS" \
--radiolist $"Pick a domain name service (DNS):" 28 50 19 \
1 $"Digital Courage" on \
2 $"German Privacy Foundation 1" off \
3 $"German Privacy Foundation 2" off \
4 $"Chaos Computer Club" off \
5 $"ClaraNet" off \
6 $"OpenNIC 1" off \
7 $"OpenNIC 2" off \
8 $"OpenNIC 3" off \
9 $"OpenNIC 4" off \
10 $"OpenNIC 5" off \
11 $"OpenNIC 6" off \
12 $"OpenNIC 7" off \
13 $"PowerNS" off \
14 $"ValiDOM" off \
15 $"Freie Unzensierte" off \
16 $"DNS.Watch" off \
17 $"uncensoreddns.org" off \
18 $"Lorraine Data Network" off \
19 $"Google" off 2> "$data"
--radiolist $"Pick a domain name service (DNS):" 29 50 20 \
1 $"UncensoredDNS" on \
2 $"Digital Courage" off \
3 $"German Privacy Foundation 1" off \
4 $"German Privacy Foundation 2" off \
5 $"Chaos Computer Club" off \
6 $"ClaraNet" off \
7 $"OpenNIC 1" off \
8 $"OpenNIC 2" off \
9 $"OpenNIC 3" off \
10 $"OpenNIC 4" off \
11 $"OpenNIC 5" off \
12 $"OpenNIC 6" off \
13 $"OpenNIC 7" off \
14 $"PowerNS" off \
15 $"ValiDOM" off \
16 $"Freie Unzensierte" off \
17 $"DNS.Watch" off \
18 $"uncensoreddns.org" off \
19 $"Lorraine Data Network" off \
20 $"Google" off 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
@ -162,61 +163,64 @@ function pihole_change_upstream_dns {
exit 1;;
esac
case $(cat "$data") in
1) PIHOLE_DNS1='85.214.73.63'
PIHOLE_DNS2='213.73.91.35'
;;
2) PIHOLE_DNS1='87.118.100.175'
PIHOLE_DNS2='94.75.228.29'
;;
3) PIHOLE_DNS1='85.25.251.254'
PIHOLE_DNS2='2.141.58.13'
;;
4) PIHOLE_DNS1='213.73.91.35'
PIHOLE_DNS2='85.214.73.63'
;;
5) PIHOLE_DNS1='212.82.225.7'
PIHOLE_DNS2='212.82.226.212'
;;
6) PIHOLE_DNS1='58.6.115.42'
PIHOLE_DNS2='58.6.115.43'
;;
7) PIHOLE_DNS1='119.31.230.42'
PIHOLE_DNS2='200.252.98.162'
;;
8) PIHOLE_DNS1='217.79.186.148'
PIHOLE_DNS2='81.89.98.6'
;;
9) PIHOLE_DNS1='78.159.101.37'
PIHOLE_DNS2='203.167.220.153'
;;
10) PIHOLE_DNS1='82.229.244.191'
PIHOLE_DNS2='82.229.244.191'
;;
11) PIHOLE_DNS1='216.87.84.211'
PIHOLE_DNS2='66.244.95.20'
;;
12) PIHOLE_DNS1='207.192.69.155'
PIHOLE_DNS2='72.14.189.120'
;;
13) PIHOLE_DNS1='194.145.226.26'
PIHOLE_DNS2='77.220.232.44'
;;
14) PIHOLE_DNS1='78.46.89.147'
PIHOLE_DNS2='88.198.75.145'
;;
15) PIHOLE_DNS1='85.25.149.144'
PIHOLE_DNS2='87.106.37.196'
;;
16) PIHOLE_DNS1='84.200.69.80'
PIHOLE_DNS2='84.200.70.40'
;;
17) PIHOLE_DNS1='91.239.100.100'
1) PIHOLE_DNS1='91.239.100.100'
PIHOLE_DNS2='89.233.43.71'
;;
18) PIHOLE_DNS1='80.67.188.188'
2) PIHOLE_DNS1='85.214.73.63'
PIHOLE_DNS2='213.73.91.35'
;;
3) PIHOLE_DNS1='87.118.100.175'
PIHOLE_DNS2='94.75.228.29'
;;
4) PIHOLE_DNS1='85.25.251.254'
PIHOLE_DNS2='2.141.58.13'
;;
5) PIHOLE_DNS1='213.73.91.35'
PIHOLE_DNS2='85.214.73.63'
;;
6) PIHOLE_DNS1='212.82.225.7'
PIHOLE_DNS2='212.82.226.212'
;;
7) PIHOLE_DNS1='58.6.115.42'
PIHOLE_DNS2='58.6.115.43'
;;
8) PIHOLE_DNS1='119.31.230.42'
PIHOLE_DNS2='200.252.98.162'
;;
9) PIHOLE_DNS1='217.79.186.148'
PIHOLE_DNS2='81.89.98.6'
;;
10) PIHOLE_DNS1='78.159.101.37'
PIHOLE_DNS2='203.167.220.153'
;;
11) PIHOLE_DNS1='82.229.244.191'
PIHOLE_DNS2='82.229.244.191'
;;
12) PIHOLE_DNS1='216.87.84.211'
PIHOLE_DNS2='66.244.95.20'
;;
13) PIHOLE_DNS1='207.192.69.155'
PIHOLE_DNS2='72.14.189.120'
;;
14) PIHOLE_DNS1='194.145.226.26'
PIHOLE_DNS2='77.220.232.44'
;;
15) PIHOLE_DNS1='78.46.89.147'
PIHOLE_DNS2='88.198.75.145'
;;
16) PIHOLE_DNS1='85.25.149.144'
PIHOLE_DNS2='87.106.37.196'
;;
17) PIHOLE_DNS1='84.200.69.80'
PIHOLE_DNS2='84.200.70.40'
;;
18) PIHOLE_DNS1='91.239.100.100'
PIHOLE_DNS2='89.233.43.71'
;;
19) PIHOLE_DNS1='80.67.188.188'
PIHOLE_DNS2='89.234.141.66'
;;
19) PIHOLE_DNS1='8.8.8.8'
20) PIHOLE_DNS1='8.8.8.8'
PIHOLE_DNS2='4.4.4.4'
dialog --title $"WARNING" \
--msgbox $"\\nGoogle's main purpose for providing DNS resolvers is to spy upon people and know which sites they are visiting.\\n\\nThis is something to consider, and you should only really be using Google DNS as a last resort if other resolvers are unavailable." 12 60

View File

@ -38,7 +38,7 @@ PLEROMA_CODE=
PLEROMA_PORT=4000
PLEROMA_ONION_PORT=8011
PLEROMA_REPO="https://git.pleroma.social/pleroma/pleroma.git"
PLEROMA_COMMIT='c50c7745bc8b8f52ba07c69c0d2505df54da0f59'
PLEROMA_COMMIT='7130e9ddb16286efd7d01088e816f05e82cfa2a1'
PLEROMA_ADMIN_PASSWORD=
PLEROMA_DIR=/etc/pleroma
PLEROMA_SECRET_KEY=""
@ -674,33 +674,26 @@ function configure_interactive_pleroma {
read_config_param PLEROMA_EXPIRE_MONTHS
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Pleroma" \
--radiolist $"Choose an operation:" 15 70 6 \
1 $"Set a background image" off \
2 $"Set the title" off \
3 $"Disable new account registrations" off \
4 $"Add a custom emoji" off \
5 $"Set post expiry period (currently $PLEROMA_EXPIRE_MONTHS months)" off \
6 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
W=(1 $"Set a background image"
2 $"Set the title"
3 $"Disable new account registrations"
4 $"Add a custom emoji"
5 $"Set post expiry period (currently $PLEROMA_EXPIRE_MONTHS months)")
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Pleroma" --menu $"Choose an operation, or ESC to exit:" 14 60 5 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) pleroma_set_background_image;;
2) pleroma_set_title;;
3) pleroma_disable_registrations;;
4) pleroma_add_emoji;;
5) pleroma_set_expire_months;;
6) rm -f "$data"
break;;
esac
rm -f "$data"
done
}
@ -1023,14 +1016,11 @@ function install_pleroma {
echo 'proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=100m inactive=80m use_temp_path=off;';
echo '';
echo 'server {';
echo ' listen 443 ssl;';
echo ' #listen [::]:443 ssl;';
echo ' listen 443 ssl http2;';
echo ' #listen [::]:443 ssl http2;';
echo " server_name $PLEROMA_DOMAIN_NAME;";
echo ''; } >> "$pleroma_nginx_site"
function_check nginx_compress
nginx_compress "$PLEROMA_DOMAIN_NAME"
echo '' >> "$pleroma_nginx_site"
echo ' # Security' >> "$pleroma_nginx_site"
echo '';
echo ' # Security'; } >> "$pleroma_nginx_site"
function_check nginx_ssl
nginx_ssl "$PLEROMA_DOMAIN_NAME"
@ -1046,10 +1036,28 @@ function install_pleroma {
echo " root $PLEROMA_DIR;";
echo '';
echo ' index index.html;';
echo ' location / {'; } >> "$pleroma_nginx_site"
function_check nginx_limits
nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
{ echo " add_header 'Access-Control-Allow-Origin' '*';";
echo '';
echo ' gzip_vary on;';
echo ' gzip_proxied any;';
echo ' gzip_comp_level 6;';
echo ' gzip_buffers 16 8k;';
echo ' gzip_http_version 1.1;';
echo ' gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml;';
echo '';
echo ' location / {';
echo ' client_max_body_size 15m;';
echo ' client_body_buffer_size 15m;';
echo '';
echo ' limit_conn conn_limit_per_ip 50;';
echo ' limit_req zone=req_limit_per_ip burst=50 nodelay;';
echo '';
echo " add_header 'Access-Control-Allow-Origin' '*' always;";
echo " add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always;";
echo " add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;";
echo " if (\$request_method = OPTIONS) {";
echo ' return 204;';
echo ' }';
echo '';
echo ' proxy_http_version 1.1;';
echo " proxy_set_header Upgrade \$http_upgrade;";
echo ' proxy_set_header Connection "upgrade";';
@ -1058,9 +1066,14 @@ function install_pleroma {
echo " proxy_pass http://localhost:$PLEROMA_PORT;";
echo ' }';
echo '';
echo ' location /proxy {'; } >> "$pleroma_nginx_site"
nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
{ echo ' proxy_cache pleroma_media_cache;';
echo ' location /proxy {';
echo ' client_max_body_size 15m;';
echo ' client_body_buffer_size 15m;';
echo '';
echo ' limit_conn conn_limit_per_ip 50;';
echo ' limit_req zone=req_limit_per_ip burst=50 nodelay;';
echo '';
echo ' proxy_cache pleroma_media_cache;';
echo ' proxy_cache_lock on;';
echo " proxy_pass http://localhost:$PLEROMA_PORT;";
echo ' }';
@ -1071,12 +1084,9 @@ function install_pleroma {
echo '' >> "$pleroma_nginx_site"
fi
{ echo 'server {';
echo " listen 127.0.0.1:$PLEROMA_ONION_PORT default_server;";
echo " listen 127.0.0.1:$PLEROMA_ONION_PORT default_server http2;";
echo " server_name $PLEROMA_ONION_HOSTNAME;";
echo ''; } >> "$pleroma_nginx_site"
function_check nginx_compress
nginx_compress "$PLEROMA_DOMAIN_NAME"
echo '' >> "$pleroma_nginx_site"
function_check nginx_security_options
nginx_security_options "$PLEROMA_DOMAIN_NAME"
{ echo '';
@ -1087,10 +1097,28 @@ function install_pleroma {
echo " root $PLEROMA_DIR;";
echo '';
echo ' index index.html;';
echo ' location / {'; } >> "$pleroma_nginx_site"
function_check nginx_limits
nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
{ echo " add_header 'Access-Control-Allow-Origin' '*';";
echo '';
echo ' gzip_vary on;';
echo ' gzip_proxied any;';
echo ' gzip_comp_level 6;';
echo ' gzip_buffers 16 8k;';
echo ' gzip_http_version 1.1;';
echo ' gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml;';
echo '';
echo ' location / {';
echo ' client_max_body_size 15m;';
echo ' client_body_buffer_size 15m;';
echo '';
echo ' limit_conn conn_limit_per_ip 50;';
echo ' limit_req zone=req_limit_per_ip burst=50 nodelay;';
echo '';
echo " add_header 'Access-Control-Allow-Origin' '*' always;";
echo " add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always;";
echo " add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;";
echo " if (\$request_method = OPTIONS) {";
echo ' return 204;';
echo ' }';
echo '';
echo ' proxy_http_version 1.1;';
echo " proxy_set_header Upgrade \$http_upgrade;";
echo ' proxy_set_header Connection "upgrade";';
@ -1099,9 +1127,14 @@ function install_pleroma {
echo " proxy_pass http://localhost:$PLEROMA_PORT;";
echo ' }';
echo '';
echo ' location /proxy {'; } >> "$pleroma_nginx_site"
nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
{ echo ' proxy_cache pleroma_media_cache;';
echo ' location /proxy {';
echo ' client_max_body_size 15m;';
echo ' client_body_buffer_size 15m;';
echo '';
echo ' limit_conn conn_limit_per_ip 50;';
echo ' limit_req zone=req_limit_per_ip burst=50 nodelay;';
echo '';
echo ' proxy_cache pleroma_media_cache;';
echo ' proxy_cache_lock on;';
echo " proxy_pass http://localhost:$PLEROMA_PORT;";
echo ' }';
@ -1185,12 +1218,18 @@ function install_pleroma {
echo 'WantedBy=multi-user.target';
echo 'Alias=pleroma.service'; } > /etc/systemd/system/pleroma.service
# avoid mixed content warnings
sed -i '/config :pleroma, :media_proxy/!b;n;c####enabled: true,' $PLEROMA_DIR/config/config.exs
sed -i 's|####enabled| enabled|g' $PLEROMA_DIR/config/config.exs
sed -i 's|redirect_on_failure:.*|redirect_on_failure: false|g' $PLEROMA_DIR/config/config.exs
# set registrations open initially
sed -i 's|registrations_open:.*|registrations_open: true,|g' $PLEROMA_DIR/config/config.exs
sed -i 's|"registrationOpen":.*|"registrationOpen": true,|g' $PLEROMA_DIR/priv/static/static/config.json
if ! grep -q "media_proxy" $PLEROMA_DIR/priv/static/static/config.json; then
sed -i '/"name":/a "media_proxy": false,' $PLEROMA_DIR/priv/static/static/config.json
sed -i '/"name":/a "media_proxy": true,' $PLEROMA_DIR/priv/static/static/config.json
sed -i 's|"media_proxy"| "media_proxy"|g' $PLEROMA_DIR/priv/static/static/config.json
else
sed -i 's|"media_proxy".*|"media_proxy": false,|g' $PLEROMA_DIR/priv/static/static/config.json

View File

@ -320,35 +320,28 @@ function configure_interactive_postactiv {
read_config_param "POSTACTIV_EXPIRE_MONTHS"
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"PostActiv" \
--radiolist $"Choose an operation:" 16 70 7 \
1 $"Set a background image" off \
2 $"Set the title" off \
3 $"Set post expiry period (currently $POSTACTIV_EXPIRE_MONTHS months)" off \
4 $"Select Qvitter user interface" off \
5 $"Select Pleroma user interface" off \
6 $"Select Classic user interface" off \
7 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
W=(1 $"Set a background image"
2 $"Set the title"
3 $"Set post expiry period (currently $POSTACTIV_EXPIRE_MONTHS months)"
4 $"Select Qvitter user interface"
5 $"Select Pleroma user interface"
6 $"Select Classic user interface")
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"PostActiv" --menu $"Choose an operation, or ESC to exit:" 15 60 6 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) postactiv_set_background_image;;
2) postactiv_set_title;;
3) postactiv_set_expire_months;;
4) gnusocial_use_qvitter postactiv;;
5) gnusocial_use_pleroma postactiv;;
6) gnusocial_use_classic postactiv;;
7) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -67,27 +67,20 @@ function scuttlebot_create_invite {
}
function configure_interactive_scuttlebot {
W=(1 $"Create an invite")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"Scuttlebot" \
--radiolist $"Choose an operation:" 10 50 2 \
1 $"Create an invite" off \
2 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
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)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) scuttlebot_create_invite;;
2) rm -f "$data"
break;;
esac
rm -f "$data"
done
}
@ -450,6 +443,8 @@ function install_scuttlebot {
mkdir -p /etc/scuttlebot
fi
npm install -g dat
# an unprivileged user to run as
useradd -d /etc/scuttlebot/ scuttlebot
@ -488,9 +483,19 @@ function install_scuttlebot {
exit 73528
fi
SCUTTLEBOT_ONION_HOSTNAME=$(add_onion_service scuttlebot 80 ${SCUTTLEBOT_ONION_PORT})
if [[ "$ONION_ONLY" == 'no' ]]; then
{ echo '{';
echo " \"host\": \"${DEFAULT_DOMAIN_NAME}\",";
echo " \"port\": ${SCUTTLEBOT_PORT},";
echo ' "tor-only": false,'; } > /etc/scuttlebot/.ssb/config
else
{ echo '{';
echo " \"host\": \"${SCUTTLEBOT_ONION_HOSTNAME}\",";
echo ' "tor-only": true,'; } > /etc/scuttlebot/.ssb/config
fi
{ echo " \"port\": ${SCUTTLEBOT_PORT},";
echo ' "timeout": 30000,';
echo ' "pub": true,';
echo ' "local": true,';
@ -505,15 +510,13 @@ function install_scuttlebot {
echo ' "logging": {';
echo ' "level": "error"';
echo ' }';
echo '}'; } > /etc/scuttlebot/.ssb/config
echo '}'; } >> /etc/scuttlebot/.ssb/config
chown scuttlebot:scuttlebot /etc/scuttlebot/.ssb/config
systemctl restart scuttlebot.service
firewall_add scuttlebot ${SCUTTLEBOT_PORT}
firewall_add git_ssb ${GIT_SSB_PORT}
SCUTTLEBOT_ONION_HOSTNAME=$(add_onion_service scuttlebot 80 ${SCUTTLEBOT_ONION_PORT})
scuttlebot_git_setup
git_ssb_script

View File

@ -175,29 +175,22 @@ function searx_enable_login {
}
function configure_interactive_searx {
W=(1 $"Set a background image"
2 $"Enable login")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"SearX Metasearch" \
--radiolist $"Choose an operation:" 12 70 3 \
1 $"Set a background image" off \
2 $"Enable login" off \
3 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"SearX" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) searx_set_background_image;;
2) searx_enable_login;;
3) rm -f "$data"
break;;
esac
rm -f "$data"
done
}

View File

@ -188,27 +188,25 @@ function edit_tahoelafs_shares {
}
function configure_interactive_tahoelafs {
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Configuration" \
--title $"Tahoe-LAFS" \
--radiolist $"The least authority is always the best" 11 50 5 \
1 "Add a storage node" off \
2 "Manually edit storage nodes" off \
3 "Shares settings" off \
4 "Back to main menu" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
exit 1;;
255) rm -f "$data"
exit 1;;
esac
case $(cat "$data") in
W=(1 $"Add a storage node"
2 $"Manually edit storage nodes"
3 $"Shares settings")
while true
do
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Tahoe-LAFS" --menu $"Choose an operation, or ESC to exit:" 12 60 3 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) add_tahoelafs_storage_node_interactive;;
2) edit_tahoelafs_nodes;;
3) edit_tahoelafs_shares;;
esac
rm -f "$data"
done
}
function tahoelafs_setup_client_config {

View File

@ -201,27 +201,20 @@ function configure_interactive_vpn {
read_config_param VPN_TLS_PORT
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"VPN Configuration" \
--radiolist $"Choose an operation:" 13 70 3 \
1 $"Change TLS port (currently $VPN_TLS_PORT)" off \
2 $"Regenerate keys for a user" off \
3 $"Exit" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
W=(1 $"Change TLS port (currently $VPN_TLS_PORT)"
2 $"Regenerate keys for a user")
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"VPN" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) vpn_change_tls_port;;
2) vpn_regenerate_client_keys;;
3) rm -f "$data"
break;;
esac
rm -f "$data"
done
}
@ -688,8 +681,8 @@ function install_vpn {
echo 'dh /etc/openvpn/dh2048.pem';
echo 'server 10.8.0.0 255.255.255.0';
echo 'push "redirect-gateway def1 bypass-dhcp"';
echo "push \"dhcp-option DNS 85.214.73.63\"";
echo "push \"dhcp-option DNS 213.73.91.35\"";
echo "push \"dhcp-option DNS 91.239.100.100\"";
echo "push \"dhcp-option DNS 89.233.43.71\"";
echo 'keepalive 5 30';
echo 'comp-lzo';
echo 'persist-key';

View File

@ -181,29 +181,22 @@ function xmpp_remove_onion_address_interactive {
}
function configure_interactive_xmpp {
W=(1 $"Add an ICANN to onion domain mapping"
2 $"Remove an ICANN to onion domain mapping")
while true
do
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Control Panel" \
--title $"XMPP" \
--radiolist $"Choose an operation:" 12 70 3 \
1 $"Add an ICANN to onion domain mapping" off \
2 $"Remove an ICANN to onion domain mapping" off \
3 $"Return to administrator control panel" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
case $(cat "$data") in
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"XMPP" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) xmpp_add_onion_address_interactive;;
2) xmpp_remove_onion_address_interactive;;
3) rm -f "$data"
break;;
esac
rm -f "$data"
done
}
@ -619,6 +612,7 @@ function remove_xmpp {
remove_onion_service xmpp 5222 5223 5269
sed -i '/HiddenServiceVersion 2/d' /etc/tor/torrc
apt-mark -q unhold prosody
apt-get -yq remove --purge prosody
rm /etc/cron.daily/prosody
if [ -f "$INSTALL_DIR/$prosody_modules_filename" ]; then

View File

@ -31,6 +31,9 @@
# the default email address
MY_EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME
# When sending mail to riseup.net route to this onion address
RISEUP_EMAIL_ONION='wy6zk3pmcwiyhiao.onion'
# If you want to run a public mailing list specify its name here.
# There should be no spaces in the name
PUBLIC_MAILING_LIST=
@ -68,6 +71,110 @@ GPGIT_COMMIT='583dc76119f19420f8a33f606744faa7c8922738'
# refresh gpg keys every few hours
REFRESH_GPG_KEYS_HOURS=2
exim_version='4.89'
function rebuild_exim_with_socks {
exim_socks_installed=$(get_completion_param "exim_socks")
if [[ "$exim_socks_installed" == 'true' ]]; then
return
fi
# shellcheck disable=SC2154
if [ ! -d "$INSTALL_DIR/exim4" ]; then
mkdir -p "$INSTALL_DIR/exim4"
fi
cd "$INSTALL_DIR/exim4" || exit 3468356
rm -rf "$INSTALL_DIR/exim4/"*
apt-get -qy install build-essential fakeroot devscripts
apt-get source exim4-daemon-heavy
apt-get -qy build-dep exim4-daemon-heavy
cd "${INSTALL_DIR}/exim4/exim4-${exim_version}" || exit 356835685
{ echo 'Description: Socks proxying';
echo ' Support for socks proxying of outgoing mail';
echo ' This is to support onion email addresses, which require support for SOCKS5';
echo ' .';
echo " exim4 (${exim_version}-2+deb9u3) stretch-security; urgency=high";
echo ' .';
echo ' * Non-maintainer upload by the Security Team.';
echo ' * Fix base64d() buffer size (CVE-2018-6789) (Closes: #890000)';
echo 'Author: Salvatore Bonaccorso <carnil@debian.org>';
echo 'Bug-Debian: https://bugs.debian.org/890000';
echo '';
echo '---';
echo 'The information above should follow the Patch Tagging Guidelines, please';
echo 'checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here';
echo 'are templates for supplementary fields that you might want to add:';
echo '';
echo 'Origin: <vendor|upstream|other>, <url of original patch>';
echo 'Bug: <url in upstream bugtracker>';
echo 'Bug-Debian: https://bugs.debian.org/<bugnumber>';
echo 'Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>';
echo 'Forwarded: <no|not-needed|url proving that it has been forwarded>';
echo 'Reviewed-By: <name and email of someone who approved the patch>';
echo "Last-Update: $(date +%Y-%m-%d)";
echo '';
echo '--- /dev/null';
echo "+++ exim4-${exim_version}/Local/Makefile";
echo '@@ -0,0 +1,32 @@';
echo '+BIN_DIRECTORY=/usr/exim/bin';
echo '+CONFIGURE_FILE=/usr/exim/configure';
echo '+EXIM_USER=';
echo '+SPOOL_DIRECTORY=/var/spool/exim';
echo '+ROUTER_ACCEPT=yes';
echo '+ROUTER_DNSLOOKUP=yes';
echo '+ROUTER_IPLITERAL=yes';
echo '+ROUTER_MANUALROUTE=yes';
echo '+ROUTER_QUERYPROGRAM=yes';
echo '+ROUTER_REDIRECT=yes';
echo '+TRANSPORT_APPENDFILE=yes';
echo '+TRANSPORT_AUTOREPLY=yes';
echo '+TRANSPORT_PIPE=yes';
echo '+TRANSPORT_SMTP=yes';
echo '+LOOKUP_DBM=yes';
echo '+LOOKUP_LSEARCH=yes';
echo '+LOOKUP_DNSDB=yes';
echo '+PCRE_CONFIG=yes';
echo '+EXIM_MONITOR=eximon.bin';
echo '+FIXED_NEVER_USERS=root';
echo '+HEADERS_CHARSET="ISO-8859-1"';
echo '+DLOPEN_LOCAL_SCAN=yes';
echo '+LDFLAGS += -rdynamic';
echo '+CFLAGS += -fvisibility=hidden';
echo '+SYSLOG_LOG_PID=yes';
echo '+EXICYCLOG_MAX=10';
echo '+COMPRESS_COMMAND=/usr/bin/gzip';
echo '+COMPRESS_SUFFIX=gz';
echo '+ZCAT_COMMAND=/usr/bin/zcat';
echo '+SUPPORT_SOCKS=yes';
echo '+SYSTEM_ALIASES_FILE=/etc/aliases';
echo '+EXIM_TMPDIR="/tmp"'; } > debian/patches/SOCKS
debuild -us -uc
cd "$INSTALL_DIR/exim4" || exit 3468356
mv exim4_${exim_version}-*.deb exim4_${exim_version}_all.deb
if [ ! -f exim4_${exim_version}_all.deb ]; then
ls -l "$INSTALL_DIR/exim4/exim4_"*.deb
echo "exim4_${exim_version}_all.deb not found"
exit 63857368
fi
apt-mark -q unhold exim4
dpkg -i exim4_${exim_version}_all.deb
apt-mark -q hold exim4
apt-get -yq remove --purge at
systemctl restart exim4
if [[ $(systemctl is-active exim4) != 'active' ]]; then
apt-mark -q unhold exim4
apt-get -yq install exim4 --reinstall
systemctl restart exim4
fi
rm -rf "$INSTALL_DIR/exim4"
set_completion_param "exim_socks" "true"
}
function email_create_template {
if [ ! -d /etc/skel/log ]; then
mkdir -m 700 /etc/skel/log
@ -117,20 +224,13 @@ function email_create_template {
fi
}
function configure_email_onion {
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
if [[ "$SYSTEM_TYPE" == "mesh"* ]]; then
return
fi
function create_email_onion_address {
if ! grep -q "hidden_service_email" /etc/tor/torrc; then
{ echo 'HiddenServiceDir /var/lib/tor/hidden_service_email/';
echo 'HiddenServiceVersion 3';
echo 'HiddenServicePort 25 127.0.0.1:25';
echo 'HiddenServicePort 587 127.0.0.1:587';
echo 'HiddenServicePort 465 127.0.0.1:465'; } >> /etc/tor/torrc
fi
function_check onion_update
onion_update
@ -147,17 +247,35 @@ function configure_email_onion {
onion_address=$(cat /var/lib/tor/hidden_service_email/hostname)
set_completion_param "email onion domain" "${onion_address}"
add_email_hostname "$onion_address"
else
onion_address=$(cat /var/lib/tor/hidden_service_email/hostname)
fi
}
apt-get -yq install tinycdb perl
function configure_email_onion {
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
if [[ "$SYSTEM_TYPE" == "mesh"* ]]; then
return
fi
create_email_onion_address
#apt-get -yq install tinycdb perl
# MX record should be:
# _onion-mx._tcp.$DEFAULT_DOMAIN_NAME. 3600 IN SRV 0 5 25 $onion_address
# _onion-mx._tcp
# 20:$onion_address
# 3600 IN SRV 0 5 25 $onion_address
echo "$DEFAULT_DOMAIN_NAME $onion_address" > /etc/exim4/onionrelay.txt
cdb -m -c -t ~/onionrelay.tmp /etc/exim4/onionrelay.cdb /etc/exim4/onionrelay.txt
# Test with: exim -d -bt username@$onion_address
#echo "$DEFAULT_DOMAIN_NAME $onion_address" > /etc/exim4/onionrelay.txt
#cdb -m -c -t ~/onionrelay.tmp /etc/exim4/onionrelay.cdb /etc/exim4/onionrelay.txt
{ echo "perl_startup = do '/etc/exim4/perl-routines.pl'";
echo "perl_at_start"; } > /etc/exim4/conf.d/main/perl
echo "perl_at_start"; } > /etc/exim4/conf.d/main/00_exim4-config_perl
{ echo "use Net::DNS::Resolver;";
echo "sub onionLookup {";
@ -172,21 +290,27 @@ function configure_email_onion {
echo " return 'no_such_host';";
echo "}"; } > /etc/exim4/perl-routines.pl
{ echo "ONION_RELAYDB=/etc/exim4/onionrelay.cdb";
echo "domainlist onion_relays = cdb;ONION_RELAYDB"; } > /etc/exim4/conf.d/domainlists
#{ echo "ONION_RELAYDB=/etc/exim4/onionrelay.cdb";
# echo "domainlist onion_relays = cdb;ONION_RELAYDB"; } > /etc/exim4/conf.d/main/48_exim4-config_onion_relays
{ echo "# send things over tor where we have an entry for it";
echo "onionrelays:";
{ echo "riseup:";
echo " driver = manualroute";
echo " domains = +onion_relays";
echo " domains = riseup.net";
echo " transport = onion_relay";
echo " # get the automap IP for the onion address from the tor daemon";
echo " route_data = \${perl{onionLookup}{\${lookup{\$domain}cdb{ONION_RELAYDB}}}}";
echo " no_more"; } > /etc/exim4/conf.d/router/50_exim4-config-onion
echo " route_data = \${perl{onionLookup}{$RISEUP_EMAIL_ONION}}"
echo " no_more"; } > /etc/exim4/conf.d/router/049_exim4-config-riseup
{ echo "onionrelays:";
echo " driver = manualroute";
echo " domains = *.onion";
echo " transport = onion_relay";
#echo " route_data = \${lookup dnsdb{a=\$domain}}";
echo " route_data = \${perl{onionLookup}{\$domain}}"
echo " no_more"; } > /etc/exim4/conf.d/router/050_exim4-config-onionrelays
{ echo "onion_relay:";
echo " driver = smtp";
echo " socks_proxy = 127.0.0.1 port=9050"; } > /etc/exim4/conf.d/transport/50_exim4-config_onion
echo " socks_proxy = 127.0.0.1 port=9050"; } > /etc/exim4/conf.d/transport/050_exim4-config_onion_relay
if ! grep -q "AutomapHostsOnResolve" /etc/tor/torrc; then
echo 'AutomapHostsOnResolve 1' >> /etc/tor/torrc
@ -209,6 +333,8 @@ function configure_email_onion {
sed -i 's|DNSListenAddress.*|DNSListenAddress 127.0.0.1|g' /etc/tor/torrc
fi
update-exim4.conf.template -r
update-exim4.conf
dpkg-reconfigure --frontend noninteractive exim4-config
systemctl restart tor
systemctl restart exim4
@ -237,6 +363,12 @@ function check_email_address_exists {
MY_EMAIL_ADDRESS="${MY_USERNAME}@${DEFAULT_DOMAIN_NAME}"
write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS"
fi
if [[ $ONION_ONLY != 'no' ]]; then
my_email=$onion_address
MY_EMAIL_ADDRESS=$onion_address
write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS"
fi
}
function backup_email {
@ -827,12 +959,18 @@ function install_email_basic {
sed -i 's|pam_mail.so standard noenv|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/sshd
sed -i 's|pam_mail.so nopen|pam_mail.so dir=~/Maildir nopen|g' /etc/pam.d/su
{ echo "dc_eximconfig_configtype='internet'";
echo "dc_other_hostnames='${DEFAULT_DOMAIN_NAME};mail.${DEFAULT_DOMAIN_NAME}'";
echo "dc_local_interfaces=''";
echo "dc_eximconfig_configtype='internet'" > /etc/exim4/update-exim4.conf.conf
if [[ $ONION_ONLY == 'no' ]]; then
echo "dc_other_hostnames='${DEFAULT_DOMAIN_NAME};mail.${DEFAULT_DOMAIN_NAME}'" >> /etc/exim4/update-exim4.conf.conf
else
echo "dc_other_hostnames='${onion_address}'" >> /etc/exim4/update-exim4.conf.conf
fi
{ echo "dc_local_interfaces=''";
echo "dc_readhost=''";
echo "dc_relay_domains=''";
echo "dc_minimaldns='false'"; } > /etc/exim4/update-exim4.conf.conf
echo "dc_minimaldns='false'"; } >> /etc/exim4/update-exim4.conf.conf
IPv4_address=$(get_ipv4_address)
IPv4_address_base=$(echo "$IPv4_address" | awk -F '.' '{print $1"."$2"."$3}')
RELAY_NETS="${IPv4_address_base}.0/24"
@ -1533,6 +1671,7 @@ function install_email {
return
fi
create_email_onion_address
check_email_address_exists
install_email_basic
configure_email_onion

View File

@ -323,52 +323,53 @@ function choose_default_domain_name {
}
function dynamic_dns_setup {
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Configuration" \
--radiolist $"Choose Dynamic DNS provider:" 40 40 40 \
1 dyn.com off \
2 freedns.afraid.org on \
3 zoneedit.com off \
4 no-ip.com off \
5 easydns.com off \
6 tzo.com off \
7 3322.org off \
8 dnsomatic.com off \
9 dns.he.net off \
10 tunnelbroker.net off \
11 dynsip.org off \
12 sitelutions.com off \
13 dnsexit.com off \
14 changeip.com off \
15 zerigo.com off \
16 dhis.org off \
17 nsupdate.info off \
18 duckdns.org off \
19 loopia.com off \
20 namecheap.com off \
21 domains.google.com off \
22 ovh.com off \
23 dtdns.com off \
24 giradns.com off \
25 duiadns.net off \
26 ddnss.de off \
27 dynv6.com off \
28 ipv4.dynv6.com off \
29 default@spdyn.de off \
30 strato.com off \
31 freemyip.com off \
32 cloudxns.net off \
33 none off 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
exit 1;;
255) rm -f "$data"
exit 1;;
esac
case $(cat "$data") in
1) DDNS_PROVIDER="default@www.dyn.com";;
2) DDNS_PROVIDER="default@freedns.afraid.org";;
W=(1 freedns.afraid.org
2 dyn.com
3 zoneedit.com
4 no-ip.com
5 easydns.com
6 tzo.com
7 3322.org
8 dnsomatic.com
9 dns.he.net
10 tunnelbroker.net
11 dynsip.org
12 sitelutions.com
13 dnsexit.com
14 changeip.com
15 zerigo.com
16 dhis.org
17 nsupdate.info
18 duckdns.org
19 loopia.com
20 namecheap.com
21 domains.google.com
22 ovh.com
23 dtdns.com
24 giradns.com
25 duiadns.net
26 ddnss.de
27 dynv6.com
28 ipv4.dynv6.com
29 default@spdyn.de
30 strato.com
31 freemyip.com
32 cloudxns.net)
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Dynamic DNS" --menu $"Choose Dynamic DNS provider, or ESC for none:" 24 60 32 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
if [ -f /etc/systemd/system/inadyn.service ]; then
systemctl stop inadyn
systemctl disable inadyn
fi
return
fi
case $selection in
1) DDNS_PROVIDER="default@freedns.afraid.org";;
2) DDNS_PROVIDER="default@www.dyn.com";;
3) DDNS_PROVIDER="default@www.zoneedit.com";;
4) DDNS_PROVIDER="default@www.no-ip.com";;
5) DDNS_PROVIDER="default@www.easydns.com";;
@ -400,10 +401,7 @@ function dynamic_dns_setup {
31) DDNS_PROVIDER="default@freemyip.com";;
32) DDNS_PROVIDER="default@www.cloudxns.net";;
33) DDNS_PROVIDER="none";;
255) rm -f "$data"
exit 1;;
esac
rm -f "$data"
save_configuration_values
valid_ddns_username=
@ -425,6 +423,7 @@ function dynamic_dns_setup {
if [ "$possible_username" ]; then
if [ ${#possible_username} -gt 1 ]; then
valid_ddns_username=$(cat "$data")
# shellcheck disable=SC2034
DDNS_USERNAME="$valid_ddns_username"
rm -f "$data"
break;
@ -491,121 +490,118 @@ function choose_dynamic_dns {
function choose_debian_repo {
if [[ "$MINIMAL_INSTALL" == "no" ]]; then
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Configuration" \
--radiolist $"Where to download Debian packages from:" 25 45 49 \
1 $"Australia" off \
2 $"Austria" off \
3 $"Belarus" off \
4 $"Belgium" off \
5 $"Bosnia and Herzegovina" off \
6 $"Brazil" off \
7 $"Bulgaria" off \
8 $"Canada" off \
9 $"Chile" off \
10 $"China" off \
11 $"Croatia" off \
12 $"Czech Republic" off \
13 $"Denmark" off \
14 $"El Salvador" off \
15 $"Estonia" off \
16 $"Finland" off \
17 $"France 1" off \
18 $"France 2" off \
19 $"Germany 1" off \
20 $"Germany 2" off \
21 $"Greece" off \
22 $"Hungary" off \
23 $"Iceland" off \
24 $"Iran" off \
25 $"Ireland" off \
26 $"Italy" off \
27 $"Japan" off \
28 $"Korea" off \
29 $"Lithuania" off \
30 $"Mexico" off \
31 $"Netherlands" off \
32 $"New Caledonia" off \
33 $"New Zealand" off \
34 $"Norway" off \
35 $"Poland" off \
36 $"Portugal" off \
37 $"Romania" off \
38 $"Russia" off \
39 $"Slovakia" off \
40 $"Slovenia" off \
41 $"Spain" off \
42 $"Sweden" off \
43 $"Switzerland" off \
44 $"Taiwan" off \
45 $"Thailand" off \
46 $"Turkey" off \
47 $"Ukraine" off \
48 $"United Kingdom" off \
49 $"United States" on 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
exit 1;;
255) rm -f "$data"
exit 1;;
W=(1 $"United Kingdom"
2 $"United States"
3 $"Australia"
4 $"Austria"
5 $"Belarus"
6 $"Belgium"
7 $"Bosnia and Herzegovina"
8 $"Brazil"
9 $"Bulgaria"
10 $"Canada"
11 $"Chile"
12 $"China"
13 $"Croatia"
14 $"Czech Republic"
15 $"Denmark"
16 $"El Salvador"
17 $"Estonia"
18 $"Finland"
19 $"France 1"
20 $"France 2"
21 $"Germany 1"
22 $"Germany 2"
23 $"Greece"
24 $"Hungary"
25 $"Iceland"
26 $"Iran"
27 $"Ireland"
28 $"Italy"
29 $"Japan"
30 $"Korea"
31 $"Lithuania"
32 $"Mexico"
33 $"Netherlands"
34 $"New Caledonia"
35 $"New Zealand"
36 $"Norway"
37 $"Poland"
38 $"Portugal"
39 $"Romania"
40 $"Russia"
41 $"Slovakia"
42 $"Slovenia"
43 $"Spain"
44 $"Sweden"
45 $"Switzerland"
46 $"Taiwan"
47 $"Thailand"
48 $"Turkey"
49 $"Ukraine")
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Debian Repo" --menu $"Where to download Debian packages from:" 24 60 49 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
selection='1'
fi
case $selection in
1) DEBIAN_REPO='ftp.uk.debian.org';;
2) DEBIAN_REPO='ftp.us.debian.org';;
3) DEBIAN_REPO='ftp.au.debian.org';;
4) DEBIAN_REPO='ftp.at.debian.org';;
5) DEBIAN_REPO='ftp.by.debian.org';;
6) DEBIAN_REPO='ftp.be.debian.org';;
7) DEBIAN_REPO='ftp.ba.debian.org';;
8) DEBIAN_REPO='ftp.br.debian.org';;
9) DEBIAN_REPO='ftp.bg.debian.org';;
10) DEBIAN_REPO='ftp.ca.debian.org';;
11) DEBIAN_REPO='ftp.cl.debian.org';;
12) DEBIAN_REPO='ftp.cn.debian.org';;
13) DEBIAN_REPO='ftp.hr.debian.org';;
14) DEBIAN_REPO='ftp.cz.debian.org';;
15) DEBIAN_REPO='ftp.dk.debian.org';;
16) DEBIAN_REPO='ftp.sv.debian.org';;
17) DEBIAN_REPO='ftp.ee.debian.org';;
18) DEBIAN_REPO='ftp.fi.debian.org';;
19) DEBIAN_REPO='ftp2.fr.debian.org';;
20) DEBIAN_REPO='ftp.fr.debian.org';;
21) DEBIAN_REPO='ftp2.de.debian.org';;
22) DEBIAN_REPO='ftp.de.debian.org';;
23) DEBIAN_REPO='ftp.gr.debian.org';;
24) DEBIAN_REPO='ftp.hu.debian.org';;
25) DEBIAN_REPO='ftp.is.debian.org';;
26) DEBIAN_REPO='ftp.ir.debian.org';;
27) DEBIAN_REPO='ftp.ie.debian.org';;
28) DEBIAN_REPO='ftp.it.debian.org';;
29) DEBIAN_REPO='ftp.jp.debian.org';;
30) DEBIAN_REPO='ftp.kr.debian.org';;
31) DEBIAN_REPO='ftp.lt.debian.org';;
32) DEBIAN_REPO='ftp.mx.debian.org';;
33) DEBIAN_REPO='ftp.nl.debian.org';;
34) DEBIAN_REPO='ftp.nc.debian.org';;
35) DEBIAN_REPO='ftp.nz.debian.org';;
36) DEBIAN_REPO='ftp.no.debian.org';;
37) DEBIAN_REPO='ftp.pl.debian.org';;
38) DEBIAN_REPO='ftp.pt.debian.org';;
39) DEBIAN_REPO='ftp.ro.debian.org';;
40) DEBIAN_REPO='ftp.ru.debian.org';;
41) DEBIAN_REPO='ftp.sk.debian.org';;
42) DEBIAN_REPO='ftp.si.debian.org';;
43) DEBIAN_REPO='ftp.es.debian.org';;
44) DEBIAN_REPO='ftp.se.debian.org';;
45) DEBIAN_REPO='ftp.ch.debian.org';;
46) DEBIAN_REPO='ftp.tw.debian.org';;
47) DEBIAN_REPO='ftp.th.debian.org';;
48) DEBIAN_REPO='ftp.tr.debian.org';;
49) DEBIAN_REPO='ftp.ua.debian.org';;
esac
case $(cat "$data") in
1) DEBIAN_REPO='ftp.au.debian.org';;
2) DEBIAN_REPO='ftp.at.debian.org';;
3) DEBIAN_REPO='ftp.by.debian.org';;
4) DEBIAN_REPO='ftp.be.debian.org';;
5) DEBIAN_REPO='ftp.ba.debian.org';;
6) DEBIAN_REPO='ftp.br.debian.org';;
7) DEBIAN_REPO='ftp.bg.debian.org';;
8) DEBIAN_REPO='ftp.ca.debian.org';;
9) DEBIAN_REPO='ftp.cl.debian.org';;
10) DEBIAN_REPO='ftp.cn.debian.org';;
11) DEBIAN_REPO='ftp.hr.debian.org';;
12) DEBIAN_REPO='ftp.cz.debian.org';;
13) DEBIAN_REPO='ftp.dk.debian.org';;
14) DEBIAN_REPO='ftp.sv.debian.org';;
15) DEBIAN_REPO='ftp.ee.debian.org';;
16) DEBIAN_REPO='ftp.fi.debian.org';;
17) DEBIAN_REPO='ftp2.fr.debian.org';;
18) DEBIAN_REPO='ftp.fr.debian.org';;
19) DEBIAN_REPO='ftp2.de.debian.org';;
20) DEBIAN_REPO='ftp.de.debian.org';;
21) DEBIAN_REPO='ftp.gr.debian.org';;
22) DEBIAN_REPO='ftp.hu.debian.org';;
23) DEBIAN_REPO='ftp.is.debian.org';;
24) DEBIAN_REPO='ftp.ir.debian.org';;
25) DEBIAN_REPO='ftp.ie.debian.org';;
26) DEBIAN_REPO='ftp.it.debian.org';;
27) DEBIAN_REPO='ftp.jp.debian.org';;
28) DEBIAN_REPO='ftp.kr.debian.org';;
29) DEBIAN_REPO='ftp.lt.debian.org';;
30) DEBIAN_REPO='ftp.mx.debian.org';;
31) DEBIAN_REPO='ftp.nl.debian.org';;
32) DEBIAN_REPO='ftp.nc.debian.org';;
33) DEBIAN_REPO='ftp.nz.debian.org';;
34) DEBIAN_REPO='ftp.no.debian.org';;
35) DEBIAN_REPO='ftp.pl.debian.org';;
36) DEBIAN_REPO='ftp.pt.debian.org';;
37) DEBIAN_REPO='ftp.ro.debian.org';;
38) DEBIAN_REPO='ftp.ru.debian.org';;
39) DEBIAN_REPO='ftp.sk.debian.org';;
40) DEBIAN_REPO='ftp.si.debian.org';;
41) DEBIAN_REPO='ftp.es.debian.org';;
42) DEBIAN_REPO='ftp.se.debian.org';;
43) DEBIAN_REPO='ftp.ch.debian.org';;
44) DEBIAN_REPO='ftp.tw.debian.org';;
45) DEBIAN_REPO='ftp.th.debian.org';;
46) DEBIAN_REPO='ftp.tr.debian.org';;
47) DEBIAN_REPO='ftp.ua.debian.org';;
48) DEBIAN_REPO='ftp.uk.debian.org';;
49) DEBIAN_REPO='ftp.us.debian.org';;
255) rm -f "$data"
exit 1;;
esac
rm -f "$data"
save_configuration_values
else
# shellcheck disable=SC2034
DEBIAN_REPO='ftp.de.debian.org'
fi
}
@ -634,6 +630,7 @@ function choose_rng {
exit 1;;
esac
else
# shellcheck disable=SC2034
HWRNG_TYPE="beaglebone"
fi
rm -f "$data"
@ -664,6 +661,7 @@ function choose_social_key_management {
save_configuration_values
else
# enable for the minimal case
# shellcheck disable=SC2034
ENABLE_SOCIAL_KEY_MANAGEMENT="yes"
fi
}
@ -775,6 +773,7 @@ function choose_full_name {
if [ "$possible_name" ]; then
if [ ${#possible_name} -gt 1 ]; then
valid_name="$possible_name"
# shellcheck disable=SC2034
MY_NAME="$possible_name"
break;
fi
@ -885,100 +884,98 @@ do
done
function interactive_select_language {
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone Configuration" \
--radiolist $"Select your language:" 26 40 24 \
1 $"Afrikaans" off \
2 $"Albanian" off \
3 $"Arabic" off \
4 $"Basque" off \
5 $"Belarusian" off \
6 $"Bosnian" off \
7 $"Bulgarian" off \
8 $"Catalan" off \
9 $"Croatian" off \
10 $"Chinese (Simplified)" off \
11 $"Chinese (Traditional)" off \
12 $"Czech" off \
13 $"Danish" off \
14 $"Dutch" off \
15 $"English" on \
16 $"English (US)" off \
17 $"Estonian" off \
18 $"Farsi" off \
19 $"Filipino" off \
20 $"Finnish" off \
21 $"French" off \
22 $"French (Canada)" off \
23 $"Gaelic" off \
24 $"Gallego" off \
25 $"Georgian" off \
26 $"German" off \
27 $"German (Personal)" off \
28 $"Greek" off \
29 $"Gujarati" off \
30 $"Hebrew" off \
31 $"Hindi" off \
32 $"Hungarian" off \
33 $"Icelandic" off \
34 $"Indonesian" off \
35 $"Italian" off \
36 $"Japanese" off \
37 $"Kannada" off \
38 $"Khmer" off \
39 $"Korean" off \
40 $"Lao" off \
41 $"Lithuanian" off \
42 $"Latvian" off \
43 $"Malayalam" off \
44 $"Malaysian" off \
45 $"Maori (Ngai Tahu)" off \
46 $"Maori (Waikoto Uni)" off \
47 $"Mongolian" off \
48 $"Norwegian" off \
49 $"Norwegian (Primary)" off \
50 $"Nynorsk" off \
51 $"Polish" off \
52 $"Portuguese" off \
53 $"Portuguese (Brazil)" off \
54 $"Romanian" off \
55 $"Russian" off \
56 $"Samoan" off \
57 $"Serbian" off \
58 $"Slovak" off \
59 $"Slovenian" off \
60 $"Somali" off \
61 $"Spanish (International)" off \
62 $"Swedish" off \
63 $"Tagalog" off \
64 $"Tamil" off \
65 $"Thai" off \
66 $"Turkish" off \
67 $"Ukrainian" off \
68 $"Vietnamese" off 2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
exit 1;;
255) rm -f "$data"
exit 1;;
esac
case $(cat "$data") in
1) DEFAULT_LANGUAGE='af_ZA.UTF-8';;
2) DEFAULT_LANGUAGE='sq_AL.UTF-8';;
3) DEFAULT_LANGUAGE='ar_SA.UTF-8';;
4) DEFAULT_LANGUAGE='eu_ES.UTF-8';;
5) DEFAULT_LANGUAGE='be_BY.UTF-8';;
6) DEFAULT_LANGUAGE='bs_BA.UTF-8';;
7) DEFAULT_LANGUAGE='bg_BG.UTF-8';;
8) DEFAULT_LANGUAGE='ca_ES.UTF-8';;
9) DEFAULT_LANGUAGE='hr_HR.UTF-8';;
10) DEFAULT_LANGUAGE='zh_CN.UTF-8';;
11) DEFAULT_LANGUAGE='zh_TW.UTF-8';;
12) DEFAULT_LANGUAGE='cs_CZ.UTF-8';;
13) DEFAULT_LANGUAGE='da_DK.UTF-8';;
14) DEFAULT_LANGUAGE='nl_NL.UTF-8';;
15) DEFAULT_LANGUAGE='en_GB.UTF-8';;
W=(1 $"English"
2 $"Afrikaans"
3 $"Albanian"
4 $"Arabic"
5 $"Basque"
6 $"Belarusian"
7 $"Bosnian"
8 $"Bulgarian"
9 $"Catalan"
10 $"Croatian"
11 $"Chinese (Simplified)"
12 $"Chinese (Traditional)"
13 $"Czech"
14 $"Danish"
15 $"Dutch"
16 $"English (US)"
17 $"Estonian"
18 $"Farsi"
19 $"Filipino"
20 $"Finnish"
21 $"French"
22 $"French (Canada)"
23 $"Gaelic"
24 $"Gallego"
25 $"Georgian"
26 $"German"
27 $"German (Personal)"
28 $"Greek"
29 $"Gujarati"
30 $"Hebrew"
31 $"Hindi"
32 $"Hungarian"
33 $"Icelandic"
34 $"Indonesian"
35 $"Italian"
36 $"Japanese"
37 $"Kannada"
38 $"Khmer"
39 $"Korean"
40 $"Lao"
41 $"Lithuanian"
42 $"Latvian"
43 $"Malayalam"
44 $"Malaysian"
45 $"Maori (Ngai Tahu)"
46 $"Maori (Waikoto Uni)"
47 $"Mongolian"
48 $"Norwegian"
49 $"Norwegian (Primary)"
50 $"Nynorsk"
51 $"Polish"
52 $"Portuguese"
53 $"Portuguese (Brazil)"
54 $"Romanian"
55 $"Russian"
56 $"Samoan"
57 $"Serbian"
58 $"Slovak"
59 $"Slovenian"
60 $"Somali"
61 $"Spanish (International)"
62 $"Swedish"
63 $"Tagalog"
64 $"Tamil"
65 $"Thai"
66 $"Turkish"
67 $"Ukrainian"
68 $"Vietnamese")
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Language" --menu $"Select your language:" 24 60 68 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
selection='1'
fi
case $selection in
1) DEFAULT_LANGUAGE='en_GB.UTF-8';;
2) DEFAULT_LANGUAGE='af_ZA.UTF-8';;
3) DEFAULT_LANGUAGE='sq_AL.UTF-8';;
4) DEFAULT_LANGUAGE='ar_SA.UTF-8';;
5) DEFAULT_LANGUAGE='eu_ES.UTF-8';;
6) DEFAULT_LANGUAGE='be_BY.UTF-8';;
7) DEFAULT_LANGUAGE='bs_BA.UTF-8';;
8) DEFAULT_LANGUAGE='bg_BG.UTF-8';;
9) DEFAULT_LANGUAGE='ca_ES.UTF-8';;
10) DEFAULT_LANGUAGE='hr_HR.UTF-8';;
11) DEFAULT_LANGUAGE='zh_CN.UTF-8';;
12) DEFAULT_LANGUAGE='zh_TW.UTF-8';;
13) DEFAULT_LANGUAGE='cs_CZ.UTF-8';;
14) DEFAULT_LANGUAGE='da_DK.UTF-8';;
15) DEFAULT_LANGUAGE='nl_NL.UTF-8';;
16) DEFAULT_LANGUAGE='en_US.UTF-8';;
17) DEFAULT_LANGUAGE='et_EE.UTF-8';;
18) DEFAULT_LANGUAGE='fa_IR.UTF-8';;
@ -1033,7 +1030,6 @@ function interactive_select_language {
67) DEFAULT_LANGUAGE='uk_UA.UTF-8';;
68) DEFAULT_LANGUAGE='vi_VN.UTF-8';;
esac
rm -f "$data"
save_configuration_values
please_wait

View File

@ -83,8 +83,8 @@ ROUTER_IP_ADDRESS="192.168.1.254"
BOX_IP_ADDRESS="192.168.1.55"
# DNS
NAMESERVER1='213.73.91.35'
NAMESERVER2='85.214.20.141'
NAMESERVER1='91.239.100.100'
NAMESERVER2='89.233.43.71'
NAMESERVER3='213.73.91.35'
NAMESERVER4='85.214.73.63'
NAMESERVER5='84.200.69.80'

View File

@ -62,8 +62,8 @@ ROUTER_IP_ADDRESS="192.168.1.254"
BOX_IP_ADDRESS="192.168.1.55"
# DNS
NAMESERVER1='85.214.73.63'
NAMESERVER2='213.73.91.35'
NAMESERVER1='91.239.100.100'
NAMESERVER2='89.233.43.71'
NAMESERVER3='87.118.100.175'
NAMESERVER4='94.75.228.29'
NAMESERVER5='85.25.251.254'
@ -242,11 +242,10 @@ configure_networking() {
if [[ $VARIANT != "meshclient" && $VARIANT != "meshusb" ]]; then
# change the motd to show further install instructions
echo $"
.---. . .
| | |
|--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
| | (.-' (.-' ( | ( )| | | | )( )| | (.-'
' ' --' --' -' - -' ' ' -' -' -' ' - --'
_____ _ _
| __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
| __| _| -_| -_| . | . | | . | . | | -_|
|__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
Initial base install
@ -259,11 +258,10 @@ following commands, then enter your details.
" > "$rootdir/etc/motd"
else
echo $"
.---. . .
| | |
|--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
| | (.-' (.-' ( | ( )| | | | )( )| | (.-'
' ' --' --' -' - -' ' ' -' -' -' ' - --'
_____ _ _
| __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
| __| _| -_| -_| . | . | | . | . | | -_|
|__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
Freedom in the Mesh
" > "$rootdir/etc/motd"
@ -1941,6 +1939,7 @@ image_preinstall_repos() {
fi
git clone "$CRYPTPAD_REPO" "$rootdir/repos/cryptpad"
git clone "$BLUDIT_REPO" "$rootdir/repos/bludit"
git clone "$DOKUWIKI_REPO" "$rootdir/repos/dokuwiki"
git clone "$ETHERPAD_REPO" "$rootdir/repos/etherpad"
git clone "$FRIENDICA_REPO" "$rootdir/repos/friendica"

View File

@ -60,8 +60,8 @@ ROUTER_IP_ADDRESS ?= "192.168.1.254"
BOX_IP_ADDRESS ?= "192.168.1.55"
# DNS
NAMESERVER1 ?= '213.73.91.35'
NAMESERVER2 ?= '85.214.20.141'
NAMESERVER1 ?= '91.239.100.100'
NAMESERVER2 ?= '89.233.43.71'
NAMESERVER3 ?= '213.73.91.35'
NAMESERVER4 ?= '85.214.73.63'
NAMESERVER5 ?= '84.200.69.80'

View File

@ -113,7 +113,7 @@ function create_syncthing_config {
if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
echo "" > $TEMP_IDS_FILE
while read -r line || [[ -n "$line" ]]; do
line2="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line2=$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'* && $line2 == *"-"* ]]; then
if [ ${#line2} -gt 10 ]; then
if ! grep -q "$line2" $TEMP_IDS_FILE; then
@ -150,7 +150,7 @@ function create_syncthing_config {
if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
while read -r line || [[ -n "$line" ]]; do
line2="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line2=$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'* && $line2 == *"-"* ]]; then
if [ ${#line2} -gt 10 ]; then
if ! grep -q "$line2" $TEMP_IDS_FILE; then
@ -189,7 +189,7 @@ function create_syncthing_config {
if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
while read -r line || [[ -n "$line" ]]; do
line2="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line2=$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'* && $line2 == *"-"* ]]; then
if [ ${#line2} -gt 10 ]; then
if ! grep -q "$line2" $TEMP_IDS_FILE; then

View File

@ -34,7 +34,6 @@ app_name='noapp'
app_name_lower=$(echo "${app_name}" | tr '[:upper:]' '[:lower:]')
app_name=$app_name_lower
app_name_upper=$(echo "${app_name}" | tr '[:lower:]' '[:upper:]')
echo "test: $app_name_upper"
app_repo="TODO"
app_repo_commit='TODO'
app_php=
@ -240,7 +239,7 @@ if [ $app_daemon ]; then
fi
fi
echo ''
echo "${app_name}=(ONION_ONLY"
echo "${app_name}_variables=(ONION_ONLY"
echo " ${app_name_upper}_DOMAIN_NAME"
echo " ${app_name_upper}_CODE"
echo ' DDNS_PROVIDER'
@ -257,28 +256,28 @@ echo ''
echo "function remove_user_${app_name} {"
echo " remove_username=\"\$1\""
echo ''
echo " \${PROJECT_NAME}-pass -u \$remove_username --rmapp ${app_name}"
echo " \"\${PROJECT_NAME}-pass\" -u \"\$remove_username\" --rmapp ${app_name}"
echo '}'
echo ''
echo "function add_user_${app_name} {"
echo " new_username=\"\$1\""
echo " new_user_password=\"\$2\""
echo ''
echo " \${PROJECT_NAME}-pass -u \$new_username -a ${app_name} -p \"\$new_user_password\""
echo " \"\${PROJECT_NAME}-pass\" -u \"\$new_username\" -a ${app_name} -p \"\$new_user_password\""
echo " echo '0'"
echo '}'
echo ''
echo "function install_interactive_${app_name} {"
if [ ! $app_onion_only ]; then
echo " if [ ! \$ONION_ONLY ]; then"
echo " if [ ! \"\$ONION_ONLY\" ]; then"
echo " ONION_ONLY='no'"
echo ' fi'
echo ''
echo " if [[ \$ONION_ONLY != \"no\" ]]; then"
echo " if [[ \"\$ONION_ONLY\" != \"no\" ]]; then"
echo " ${app_name_upper}_DOMAIN_NAME='${app_name}.local'"
echo " write_config_param \"${app_name_upper}_DOMAIN_NAME\" \"\$${app_name_upper}_DOMAIN_NAME\""
echo ' else'
echo " interactive_site_details \"${app_name}\" \"${app_name_upper}_DOMAIN_NAME\" \"${app_name}_CODE\""
echo " interactive_site_details \"${app_name}\" \"${app_name_upper}_DOMAIN_NAME\" \"${app_name_upper}_CODE\""
echo ' fi'
else
echo " echo -n ''"
@ -292,7 +291,7 @@ echo " new_user_password=\"\$2\""
echo ''
echo " read_config_param '${app_name_upper}_DOMAIN_NAME'"
echo ''
echo " \${PROJECT_NAME}-pass -u \"\$curr_username\" -a ${app_name} -p \"\$new_user_password\""
echo " \"\${PROJECT_NAME}-pass\" -u \"\$curr_username\" -a ${app_name} -p \"\$new_user_password\""
echo '}'
if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" || "$database_type" == "postgres"* ]]; then
@ -361,23 +360,23 @@ echo " if [[ \"\$CURR_${app_name_upper}_COMMIT\" == \"\$${app_name_upper}_COM
echo ' return'
echo ' fi'
echo ''
echo " if grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
echo " if grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
echo " ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
echo ' fi'
echo ''
echo ' # update to the next commit'
if [ ! "$app_dir" ]; then
echo " set_repo_commit /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
echo " chown -R www-data:www-data /var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
echo " set_repo_commit \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
echo " chown -R www-data:www-data \"/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs\""
else
echo " set_repo_commit ${app_dir} \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
echo " chown -R ${app_name}:${app_name} ${app_dir}"
echo " set_repo_commit \"${app_dir}\" \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
echo " chown -R ${app_name}:${app_name} \"${app_dir}\""
fi
echo '}'
echo ''
echo "function backup_local_${app_name} {"
echo " ${app_name_upper}_DOMAIN_NAME='${app_name}'"
echo " if grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
echo " if grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
echo " ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
echo ' fi'
echo ''
@ -387,10 +386,10 @@ else
echo " source_directory=${app_dir}"
fi
echo ''
echo " suspend_site \${${app_name_upper}_DOMAIN_NAME}"
echo " suspend_site \"\${${app_name_upper}_DOMAIN_NAME}\""
echo ''
echo " dest_directory=${app_name}"
echo " backup_directory_to_usb \$source_directory \$dest_directory"
echo " backup_directory_to_usb \"\$source_directory\" \$dest_directory"
echo ''
if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
echo " backup_database_to_usb ${app_name}"
@ -405,11 +404,11 @@ echo ' restart_site'
echo '}'
echo ''
echo "function restore_local_${app_name} {"
echo " if ! grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
echo " if ! grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
echo ' return'
echo ' fi'
echo " ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
echo " if [ \$${app_name_upper}_DOMAIN_NAME ]; then"
echo " if [ \"\$${app_name_upper}_DOMAIN_NAME\" ]; then"
echo " temp_restore_dir=/root/temp${app_name}"
if [ ! "$app_dir" ]; then
echo " ${app_name}_dir=/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
@ -438,15 +437,15 @@ if [[ "$database_type" == "postgres"* ]]; then
fi
echo " restore_directory_from_usb \$temp_restore_dir ${app_name}"
echo " if [ -d \$temp_restore_dir ]; then"
echo " if [ -d cp \$temp_restore_dir\$${app_name}_dir ]; then"
echo " cp -rp \$temp_restore_dir\$${app_name}_dir/* \$${app_name}_dir/"
echo " if [ -d \"\$temp_restore_dir\$${app_name}_dir\" ]; then"
echo " cp -rp \"\$temp_restore_dir\$${app_name}_dir\"/* \"\$${app_name}_dir\"/"
echo ' else'
echo " if [ ! -d \$${app_name}_dir ]; then"
echo " mkdir \$${app_name}_dir"
echo " if [ ! -d \"\$${app_name}_dir\" ]; then"
echo " mkdir \"\$${app_name}_dir\""
echo ' fi'
echo " cp -rp \$temp_restore_dir/* \$${app_name}_dir/"
echo " cp -rp \"\$temp_restore_dir\"/* \"\$${app_name}_dir\"/"
echo ' fi'
echo " chown -R www-data:www-data \$${app_name}_dir"
echo " chown -R www-data:www-data \"\$${app_name}_dir\""
echo " rm -rf \$temp_restore_dir"
echo ' fi'
echo ''
@ -455,7 +454,7 @@ echo '}'
echo ''
echo "function backup_remote_${app_name} {"
echo " ${app_name_upper}_DOMAIN_NAME='${app_name}'"
echo " if grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
echo " if grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
echo " ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
echo ' fi'
echo ''
@ -465,13 +464,13 @@ else
echo " source_directory=${app_dir}"
fi
echo ''
echo " suspend_site \${${app_name_upper}_DOMAIN_NAME}"
echo " suspend_site \"\${${app_name_upper}_DOMAIN_NAME}\""
echo ''
echo " dest_directory=${app_name}"
echo " backup_directory_to_friend \$source_directory \$dest_directory"
echo ''
echo " backup_directory_to_friend \"\$source_directory\" \$dest_directory"
if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
echo " backup_database_to_friend ${app_name}"
echo ''
fi
if [[ "$database_type" == "postgres"* ]]; then
echo ' USE_POSTGRESQL=1'
@ -483,11 +482,11 @@ echo ' restart_site'
echo '}'
echo ''
echo "function restore_remote_${app_name} {"
echo " if ! grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
echo " if ! grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
echo ' return'
echo ' fi'
echo " ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
echo " if [ \$${app_name_upper}_DOMAIN_NAME ]; then"
echo " if [ \"\$${app_name_upper}_DOMAIN_NAME\" ]; then"
echo " temp_restore_dir=/root/temp${app_name}"
if [ ! "$app_dir" ]; then
echo " ${app_name}_dir=/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
@ -499,7 +498,7 @@ if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
echo " ${app_name}_create_database"
echo ''
echo " restore_database_from_friend ${app_name}"
echo " if [ -d \$temp_restore_dir ]; then"
echo " if [ -d \"\$temp_restore_dir\" ]; then"
echo " rm -rf \$temp_restore_dir"
echo ' fi'
echo ''
@ -509,22 +508,22 @@ if [[ "$database_type" == "postgres"* ]]; then
echo ''
echo ' USE_POSTGRESQL=1'
echo " restore_database_from_friend ${app_name}"
echo " if [ -d \$temp_restore_dir ]; then"
echo " if [ -d \"\$temp_restore_dir\" ]; then"
echo " rm -rf \$temp_restore_dir"
echo ' fi'
echo ''
fi
echo " restore_directory_from_friend \$temp_restore_dir ${app_name}"
echo " if [ -d \$temp_restore_dir ]; then"
echo " if [ -d cp \$temp_restore_dir\$${app_name}_dir ]; then"
echo " cp -rp \$temp_restore_dir\$${app_name}_dir/* \$${app_name}_dir/"
echo " if [ -d \"\$temp_restore_dir\$${app_name}_dir\" ]; then"
echo " cp -rp \"\$temp_restore_dir\$${app_name}_dir\"/* \"\$${app_name}_dir\"/"
echo ' else'
echo " if [ ! -d \$${app_name}_dir ]; then"
echo " mkdir \$${app_name}_dir"
echo " if [ ! -d \"\$${app_name}_dir\" ]; then"
echo " mkdir \"\$${app_name}_dir\""
echo ' fi'
echo " cp -rp \$temp_restore_dir/* \$${app_name}_dir/"
echo " cp -rp \$temp_restore_dir/* \"\$${app_name}_dir\"/"
echo ' fi'
echo " chown -R www-data:www-data \$${app_name}_dir"
echo " chown -R www-data:www-data \"\$${app_name}_dir\""
echo " rm -rf \$temp_restore_dir"
echo ' fi'
echo ''
@ -536,8 +535,8 @@ if [[ "$app_node" == 'yes' ]]; then
echo " remove_nodejs ${app_name}"
echo ''
fi
echo " nginx_dissite \$${app_name_upper}_DOMAIN_NAME"
echo " remove_certs \$${app_name_upper}_DOMAIN_NAME"
echo " nginx_dissite \"\$${app_name_upper}_DOMAIN_NAME\""
echo " remove_certs \"\$${app_name_upper}_DOMAIN_NAME\""
echo ''
if [ $app_daemon ]; then
echo " if [ -f /etc/systemd/system/${app_name}.service ]; then"
@ -548,11 +547,11 @@ if [ $app_daemon ]; then
echo " userdel -r ${app_name}"
fi
echo ''
echo " if [ -d /var/www/\$${app_name_upper}_DOMAIN_NAME ]; then"
echo " rm -rf /var/www/\$${app_name_upper}_DOMAIN_NAME"
echo " if [ -d \"/var/www/\$${app_name_upper}_DOMAIN_NAME\" ]; then"
echo " rm -rf \"/var/www/\$${app_name_upper}_DOMAIN_NAME\""
echo ' fi'
echo " if [ -f /etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME ]; then"
echo " rm /etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME"
echo " if [ -f \"/etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME\" ]; then"
echo " rm \"/etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME\""
echo ' fi'
if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
echo " drop_database ${app_name}"
@ -566,13 +565,13 @@ echo " sed -i \"/${app_name}/d\" /etc/crontab"
echo ' fi'
echo " remove_app ${app_name}"
echo " remove_completion_param install_${app_name}"
echo " sed -i '/${app_name}/d' \$COMPLETION_FILE"
echo " sed -i '/${app_name}/d' \"\$COMPLETION_FILE\""
if [ "$app_port" ]; then
echo ''
echo " firewall_remove ${app_port} tcp"
fi
echo ''
echo " remove_ddns_domain \$${app_name_upper}_DOMAIN_NAME"
echo " remove_ddns_domain \"\$${app_name_upper}_DOMAIN_NAME\""
echo '}'
echo ''
echo "function install_${app_name} {"
@ -594,189 +593,204 @@ if [[ "$app_php" == 'yes' ]]; then
echo ' apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl'
echo ''
fi
echo " if [ ! -d /var/www/\$${app_name_upper}_DOMAIN_NAME ]; then"
echo " mkdir /var/www/\$${app_name_upper}_DOMAIN_NAME"
echo " if [ ! \"\$${app_name_upper}_DOMAIN_NAME\" ]; then"
echo " echo \$'No domain name was given'"
echo ' exit 3568356'
echo ' fi'
echo " if [ ! -d /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs ]; then"
echo ''
echo " if [ -d \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" ]; then"
echo " rm -rf \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
echo ' fi'
echo " if [ -d /repos/${app_name} ]; then"
echo " mkdir /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
echo " mkdir \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
if [ ! "$app_dir" ]; then
echo " cp -r -p /repos/${app_name}/. /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
echo " cd /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
echo " cp -r -p /repos/${app_name}/. \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
echo " cd \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" || exit 324687356"
else
echo " cp -r -p /repos/${app_name}/. ${app_dir}"
echo " cd ${app_dir}"
echo " cp -r -p /repos/${app_name}/. \"${app_dir}\""
echo " cd \"${app_dir}\" || exit 36487365"
fi
echo ' git pull'
echo ' else'
if [ ! "$app_dir" ]; then
echo " git_clone \$${app_name_upper}_REPO /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
echo " git_clone \$${app_name_upper}_REPO \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
else
echo " git_clone \$${app_name_upper}_REPO ${app_dir}"
echo " git_clone \$${app_name_upper}_REPO \"${app_dir}\""
fi
echo ' fi'
echo ''
if [ ! "$app_dir" ]; then
echo " if [ ! -d /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs ]; then"
echo " if [ ! -d \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" ]; then"
else
echo " if [ ! -d ${app_dir} ]; then"
echo " if [ ! -d \"${app_dir}\" ]; then"
fi
echo " echo \$'Unable to clone ${app_name} repo'"
echo ' exit 87525'
echo ' fi'
echo ' fi'
echo ''
if [ ! "$app_dir" ]; then
echo " cd /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
echo " cd \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" || exit 36587356"
else
echo " cd ${app_dir}"
echo " cd \"${app_dir}\" || exit 3463754637"
fi
echo " git checkout \$${app_name_upper}_COMMIT -b \$${app_name_upper}_COMMIT"
echo " set_completion_param \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\""
echo ''
echo " chmod g+w /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
echo " chown -R www-data:www-data /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
echo " chmod g+w \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
echo " chown -R www-data:www-data \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" || "$database_type" == "postgres"* ]]; then
echo ''
echo " ${app_name}_create_database"
fi
echo ''
echo " add_ddns_domain \$${app_name_upper}_DOMAIN_NAME"
echo " add_ddns_domain \"\$${app_name_upper}_DOMAIN_NAME\""
echo ''
echo " ${app_name_upper}_ONION_HOSTNAME=\$(add_onion_service ${app_name} 80 \${${app_name_upper}_ONION_PORT})"
echo ''
echo " ${app_name}_nginx_site=/etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME"
if [ $app_onion_only ]; then
if [ ! $app_onion_only ]; then
echo " if [[ \"\$ONION_ONLY\" == \"no\" ]]; then"
if [[ "$app_php" == 'yes' ]]; then
echo " nginx_http_redirect \$${app_name_upper}_DOMAIN_NAME \"index index.php\""
echo " nginx_http_redirect \"\$${app_name_upper}_DOMAIN_NAME\" \"index index.php\""
else
echo " nginx_http_redirect \$${app_name_upper}_DOMAIN_NAME \"index index.html\""
echo " nginx_http_redirect \"\$${app_name_upper}_DOMAIN_NAME\" \"index index.html\""
fi
echo " echo 'server {' >> \$${app_name}_nginx_site"
echo " echo ' listen 443 ssl;' >> \$${app_name}_nginx_site"
echo " echo ' #listen [::]:443 ssl;' >> \$${app_name}_nginx_site"
echo " echo \" server_name \$${app_name_upper}_DOMAIN_NAME;\" >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " nginx_compress \$${app_name_upper}_DOMAIN_NAME"
echo " echo '' >> \$${app_name}_nginx_site"
echo " echo ' # Security' >> \$${app_name}_nginx_site"
echo " nginx_ssl \$${app_name_upper}_DOMAIN_NAME"
echo " { echo 'server {';"
echo " echo ' listen 443 ssl;';"
echo " echo ' #listen [::]:443 ssl;';"
echo " echo \" server_name \$${app_name_upper}_DOMAIN_NAME;\";"
echo " echo ''; } >> \"\$${app_name}_nginx_site\""
echo " nginx_compress \"\$${app_name_upper}_DOMAIN_NAME\""
echo " echo '' >> \"\$${app_name}_nginx_site\""
echo " echo ' # Security' >> \"\$${app_name}_nginx_site\""
echo " nginx_ssl \"\$${app_name_upper}_DOMAIN_NAME\""
echo ''
echo " nginx_security_options \$${app_name_upper}_DOMAIN_NAME"
echo " nginx_security_options \"\$${app_name_upper}_DOMAIN_NAME\""
echo ''
echo " echo ' add_header Strict-Transport-Security max-age=15768000;' >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " echo ' # Logs' >> \$${app_name}_nginx_site"
echo " echo ' access_log /dev/null;' >> \$${app_name}_nginx_site"
echo " echo ' error_log /dev/null;' >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " echo ' # Root' >> \$${app_name}_nginx_site"
echo " echo \" root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\" >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " { echo ' add_header Strict-Transport-Security max-age=15768000;';"
echo " echo '';"
echo " echo ' # Logs';"
echo " echo ' access_log /dev/null;';"
echo " echo ' error_log /dev/null;';"
echo " echo '';"
echo " echo ' # Root';"
echo " echo \" root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\";"
echo " echo '';"
if [[ "$app_php" == 'yes' ]]; then
echo " echo ' index index.php;' >> \$${app_name}_nginx_site"
echo " echo ' location ~ \\.php {' >> \$${app_name}_nginx_site"
echo " echo ' include snippets/fastcgi-php.conf;' >> \$${app_name}_nginx_site"
echo " echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> \$${app_name}_nginx_site"
echo " echo ' fastcgi_read_timeout 30;' >> \$${app_name}_nginx_site"
echo " echo ' }' >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " echo ' index index.php;';"
echo " echo ' location ~ \\.php {';"
echo " echo ' include snippets/fastcgi-php.conf;';"
echo " echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';"
echo " echo ' fastcgi_read_timeout 30;';"
echo " echo ' fastcgi_param HTTPS on;';"
echo " echo ' }';"
echo " echo '';"
else
echo " echo ' index index.html;' >> \$${app_name}_nginx_site"
echo " echo ' index index.html;';"
fi
echo " echo ' # Location' >> \$${app_name}_nginx_site"
echo " echo ' location / {' >> \$${app_name}_nginx_site"
echo " nginx_limits \$${app_name_upper}_DOMAIN_NAME '15m'"
echo " echo ' # Location';"
echo " echo ' location / {'; } >> \"\$${app_name}_nginx_site\""
echo " nginx_limits \"\$${app_name_upper}_DOMAIN_NAME\" '15m'"
if [ ! $app_daemon ]; then
echo " echo ' try_files \$uri \$uri/ /index.html;' >> \$${app_name}_nginx_site"
if [[ "$app_php" != 'yes' ]]; then
echo " { echo \" try_files \\\$uri \\\$uri/ /index.html;\";"
else
echo " echo \" proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\" >> \$${app_name}_nginx_site"
echo " { echo \" try_files \\\$uri \\\$uri/ /index.php?\\\$args;\";"
fi
echo " echo ' }' >> \$${app_name}_nginx_site"
echo " echo '}' >> \$${app_name}_nginx_site"
else
echo " { echo \" proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\";"
fi
echo " echo ' }';"
echo " echo '}'; } >> \"\$${app_name}_nginx_site\""
echo ' else'
echo " echo -n '' > \$${app_name}_nginx_site"
echo " echo -n '' > \"\$${app_name}_nginx_site\""
echo ' fi'
else
echo " echo -n '' > \$${app_name}_nginx_site"
echo " echo -n '' > \"\$${app_name}_nginx_site\""
fi
echo " echo 'server {' >> \$${app_name}_nginx_site"
echo " echo \" listen 127.0.0.1:\$${app_name_upper}_ONION_PORT default_server;\" >> \$${app_name}_nginx_site"
echo " echo \" server_name \$${app_name_upper}_ONION_HOSTNAME;\" >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " nginx_compress \$${app_name_upper}_DOMAIN_NAME"
echo " echo '' >> \$${app_name}_nginx_site"
echo " nginx_security_options \$${app_name_upper}_DOMAIN_NAME"
echo " echo '' >> \$${app_name}_nginx_site"
echo " echo ' # Logs' >> \$${app_name}_nginx_site"
echo " echo ' access_log /dev/null;' >> \$${app_name}_nginx_site"
echo " echo ' error_log /dev/null;' >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " echo ' # Root' >> \$${app_name}_nginx_site"
echo " echo \" root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\" >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " { echo 'server {';"
echo " echo \" listen 127.0.0.1:\$${app_name_upper}_ONION_PORT default_server;\";"
echo " echo \" server_name \$${app_name_upper}_ONION_HOSTNAME;\";"
echo " echo ''; } >> \"\$${app_name}_nginx_site\""
echo " nginx_compress \"\$${app_name_upper}_DOMAIN_NAME\""
echo " echo '' >> \"\$${app_name}_nginx_site\""
echo " nginx_security_options \"\$${app_name_upper}_DOMAIN_NAME\""
echo " { echo '';"
echo " echo ' # Logs';"
echo " echo ' access_log /dev/null;';"
echo " echo ' error_log /dev/null;';"
echo " echo '';"
echo " echo ' # Root';"
echo " echo \" root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\";"
echo " echo '';"
if [[ "$app_php" == 'yes' ]]; then
echo " echo ' index index.php;' >> \$${app_name}_nginx_site"
echo " echo ' location ~ \\.php {' >> \$${app_name}_nginx_site"
echo " echo ' include snippets/fastcgi-php.conf;' >> \$${app_name}_nginx_site"
echo " echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> \$${app_name}_nginx_site"
echo " echo ' fastcgi_read_timeout 30;' >> \$${app_name}_nginx_site"
echo " echo ' }' >> \$${app_name}_nginx_site"
echo " echo '' >> \$${app_name}_nginx_site"
echo " echo ' index index.php;';"
echo " echo ' location ~ \\.php {';"
echo " echo ' include snippets/fastcgi-php.conf;';"
echo " echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';"
echo " echo ' fastcgi_read_timeout 30;';"
echo " echo ' fastcgi_param HTTPS off;';"
echo " echo ' }';"
echo " echo '';"
else
echo " echo ' index index.html;' >> \$${app_name}_nginx_site"
echo " echo ' index index.html;';"
fi
echo " echo ' # Location' >> \$${app_name}_nginx_site"
echo " echo ' location / {' >> \$${app_name}_nginx_site"
echo " nginx_limits \$${app_name_upper}_DOMAIN_NAME '15m'"
echo " echo ' # Location';"
echo " echo ' location / {'; } >> \"\$${app_name}_nginx_site\""
echo " nginx_limits \"\$${app_name_upper}_DOMAIN_NAME\" '15m'"
if [ ! $app_daemon ]; then
echo " echo ' try_files \$uri \$uri/ index.html;' >> \$${app_name}_nginx_site"
if [[ "$app_php" != 'yes' ]]; then
echo " { echo \" try_files \\\$uri \\\$uri/ index.html;\";"
else
echo " { echo \" try_files \\\$uri \\\$uri/ index.php?\\\$args;\";"
fi
else
echo " echo \" proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\" >> \$${app_name}_nginx_site"
echo " echo \" proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\";"
fi
echo " echo ' }' >> \$${app_name}_nginx_site"
echo " echo '}' >> \$${app_name}_nginx_site"
echo " echo ' }';"
echo " echo '}'; } >> \"\$${app_name}_nginx_site\""
if [[ "$app_php" == 'yes' ]]; then
echo ''
echo ' configure_php'
fi
if [ $app_daemon ]; then
echo ''
echo " useradd -d TODO_PATH_TO_INSTALL -s /bin/false ${app_name}"
echo " useradd -d \"TODO_PATH_TO_INSTALL\" -s /bin/false ${app_name}"
echo ''
echo " echo '[Unit]' > /etc/systemd/system/${app_name}.service"
echo " echo 'Description=${app_name}' >> /etc/systemd/system/${app_name}.service"
echo " echo 'After=syslog.target' >> /etc/systemd/system/${app_name}.service"
echo " echo 'After=network.target' >> /etc/systemd/system/${app_name}.service"
echo " echo '' >> /etc/systemd/system/${app_name}.service"
echo " echo '[Service]' >> /etc/systemd/system/${app_name}.service"
echo " echo 'Type=simple' >> /etc/systemd/system/${app_name}.service"
echo " echo 'User=${app_name}' >> /etc/systemd/system/${app_name}.service"
echo " echo 'Group=${app_name}' >> /etc/systemd/system/${app_name}.service"
echo " { echo '[Unit]';"
echo " echo 'Description=${app_name}';"
echo " echo 'After=syslog.target';"
echo " echo 'After=network.target';"
echo " echo '';"
echo " echo '[Service]';"
echo " echo 'Type=simple';"
echo " echo 'User=${app_name}';"
echo " echo 'Group=${app_name}'; } > \"/etc/systemd/system/${app_name}.service\""
if [ ! "$app_dir" ]; then
echo " echo 'WorkingDirectory=TODO' >> /etc/systemd/system/${app_name}.service"
echo " echo 'WorkingDirectory=TODO' >> \"/etc/systemd/system/${app_name}.service\""
else
echo " echo 'WorkingDirectory=${app_dir}' >> /etc/systemd/system/${app_name}.service"
echo " echo 'WorkingDirectory=${app_dir}' >> \"/etc/systemd/system/${app_name}.service\""
fi
echo " echo 'ExecStart=TODO' >> /etc/systemd/system/${app_name}.service"
echo " echo 'Restart=always' >> /etc/systemd/system/${app_name}.service"
echo " echo 'Environment=\"USER=${app_name}\"' >> /etc/systemd/system/${app_name}.service"
echo " echo '' >> /etc/systemd/system/${app_name}.service"
echo " echo '[Install]' >> /etc/systemd/system/${app_name}.service"
echo " echo 'WantedBy=multi-user.target' >> /etc/systemd/system/${app_name}.service"
echo " { echo 'ExecStart=TODO';"
echo " echo 'Restart=always';"
echo " echo 'Environment=\"USER=${app_name}\"';"
echo " echo '';"
echo " echo '[Install]';"
echo " echo 'WantedBy=multi-user.target'; } >> \"/etc/systemd/system/${app_name}.service\""
echo " systemctl enable ${app_name}"
if [ "$app_dir" ]; then
echo " chown -R ${app_name}:${app_name} ${app_dir}"
echo " chown -R ${app_name}:${app_name} \"${app_dir}\""
fi
echo " systemctl start ${app_name}"
fi
echo ''
echo " create_site_certificate \$${app_name_upper}_DOMAIN_NAME 'yes'"
echo " create_site_certificate \"\$${app_name_upper}_DOMAIN_NAME\" 'yes'"
echo ''
echo " nginx_ensite \$${app_name_upper}_DOMAIN_NAME"
echo " nginx_ensite \"\$${app_name_upper}_DOMAIN_NAME\""
echo ''
if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
echo ' systemctl restart mariadb'
@ -786,7 +800,7 @@ if [[ "$app_php" == 'yes' ]]; then
fi
echo ' systemctl restart nginx'
echo ''
echo " \${PROJECT_NAME}-pass -u \$MY_USERNAME -a ${app_name} -p \"\$${app_name_upper}_ADMIN_PASSWORD\""
echo " \"\${PROJECT_NAME}-pass\" -u \"\$MY_USERNAME\" -a ${app_name} -p \"\$${app_name_upper}_ADMIN_PASSWORD\""
echo " set_completion_param \"${app_name} domain\" \"\$${app_name_upper}_DOMAIN_NAME\""
if [ "$app_port" ]; then
echo ''

View File

@ -48,6 +48,8 @@ do
source "$f"
done
source "/usr/share/${PROJECT_NAME}/base/${PROJECT_NAME}-base-email"
read_config_param PROJECT_REPO
read_config_param DEVELOPMENT_BRANCH
read_config_param DEFAULT_DOMAIN_NAME
@ -61,9 +63,11 @@ if [ $DEVELOPMENT_BRANCH ]; then
fi
fi
if grep -q "cat /root/dbpass" /usr/bin/backupdatabases; then
if [ -f /usr/bin/backupdatabases ]; then
if grep -q "cat /root/dbpass" /usr/bin/backupdatabases; then
# update to using the password manager
sed -i "s|cat /root/dbpass|freedombone-pass -u root -a mariadb|g" /usr/bin/backupdatabases
fi
fi
#update-ca-certificates
@ -92,6 +96,8 @@ if [ -d "$PROJECT_DIR" ]; then
exit 453536
fi
#rebuild_exim_with_socks
nodejs_upgrade
apt-get -yq -t stretch-backports install certbot
email_install_tls
email_disable_chunking

View File

@ -65,8 +65,13 @@ function mesh_avahi {
sed -i "s|#host-name=.*|host-name=P$PEER_ID|g" "$rootdir/etc/avahi/avahi-daemon.conf"
sed -i "s|use-ipv4=.*|use-ipv4=no|g" "$rootdir/etc/avahi/avahi-daemon.conf"
sed -i "s|use-ipv6=.*|use-ipv6=yes|g" "$rootdir/etc/avahi/avahi-daemon.conf"
#sed -i "s|#allow-interfaces=.*|allow-interfaces=wlan0, wlan1, wlan2, wlan3, wlan4, wlan5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
#sed -i "s|allow-interfaces=.*|allow-interfaces=wlan0, wlan1, wlan2, wlan3, wlan4, wlan5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
# Note: wlan interfaces must be allowed within avahi, otherwise the
# *.local address will not resolve
sed -i "s|#allow-interfaces|allow-interfaces|g" "$rootdir/etc/avahi/avahi-daemon.conf"
sed -i "s|allow-interfaces=.*|allow-interfaces=wlan0, wlan1, wlan2, wlan3, wlan4, wlan5, eth0, eth1|g" "$rootdir/etc/avahi/avahi-daemon.conf"
#sed -i "s|#deny-interfaces=.*|deny-interfaces=eth0, eth1, eth2, eth3, eth4, eth5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
#sed -i "s|deny-interfaces=.*|deny-interfaces=eth0, eth1, eth2, eth3, eth4, eth5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
sed -i "s|#disallow-other-stacks=.*|disallow-other-stacks=yes|g" "$rootdir/etc/avahi/avahi-daemon.conf"

View File

@ -29,8 +29,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# DNS
NAMESERVER1='85.214.73.63'
NAMESERVER2='213.73.91.35'
NAMESERVER1='91.239.100.100'
NAMESERVER2='89.233.43.71'
NAMESERVER3='87.118.100.175'
NAMESERVER4='94.75.228.29'
NAMESERVER5='85.25.251.254'

View File

@ -603,6 +603,9 @@ function firewall_unblock_domain {
fi
sed -i "/${unblocked_domain}/d" "$FIREWALL_DOMAINS"
fi
if grep -q " $unblocked_domain" /etc/hosts; then
sed -i "/ $unblocked_domain/d" /etc/hosts
fi
}
function firewall_drop_spoofed_packets {

View File

@ -38,13 +38,14 @@ function change_login_message {
rm -f /etc/init.d/motd
fi
{ echo ".---. . . ";
echo "| | | ";
echo "|--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-. ";
echo "| | (.-' (.-' ( | ( )| | | | )( )| | (.-' ";
echo "' ' --' --' -' - -' ' ' -' -' -' ' - --'";
{ echo ' _____ _ _';
echo ' | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___';
echo ' | __| _| -_| -_| . | . | | . | . | | -_|';
echo ' |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|';
echo '';
echo $' Freedom in the Cloud';
echo ''; } > /etc/motd
mark_completed "${FUNCNAME[0]}"
}

View File

@ -35,9 +35,9 @@ VARIANTS='mesh'
# change these versions at your peril. Things will often crash if you don't
# have specifically the correct versions
NODEJS_VERSION='6.11.4'
NODEJS_N_VERSION='2.1.7'
NPM_VERSION='4.0.5'
NODEJS_VERSION='8.11.1'
NODEJS_N_VERSION='2.1.8'
NPM_VERSION='5.8.0'
# This file keeps track of the apps needing nodejs
# so that it can be removed if tere are no apps which need it
@ -60,6 +60,37 @@ function get_npm_arch {
fi
}
function nodejs_fix_cpu_detection {
# fix for failing cpu detection during image build with qemu, see https://github.com/npm/npm/issues/19265
if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js"
fi
if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js"
fi
if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js"
fi
if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js"
fi
if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/node-gyp/lib/build.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/node-gyp/lib/build.js"
fi
if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js" ]; then
sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js"
fi
# installing worker farm fixes the cpu detection bug
#$mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g worker-farm@1.6.0 --save
}
function mesh_install_nodejs {
mesh_install_nodejs_prefix=
if [ "$rootdir" ]; then
@ -72,23 +103,28 @@ function mesh_install_nodejs {
$mesh_install_nodejs_prefix wget https://deb.nodesource.com/gpgkey/nodesource.gpg.key -O /root/node.gpg.key
if [ ! -f "$rootdir/root/node.gpg.key" ]; then
echo $'Unable to obtain gpg key for nodejs repo'
NODE_UPGRADE=
exit 6389252
fi
$mesh_install_nodejs_prefix apt-key add /root/node.gpg.key
echo "deb https://deb.nodesource.com/node_6.x stretch main" > "$rootdir/etc/apt/sources.list.d/nodesource.list"
echo "deb-src https://deb.nodesource.com/node_6.x stretch main" >> "$rootdir/etc/apt/sources.list.d/nodesource.list"
echo "deb https://deb.nodesource.com/node_8.x stretch main" > "$rootdir/etc/apt/sources.list.d/nodesource.list"
echo "deb-src https://deb.nodesource.com/node_8.x stretch main" >> "$rootdir/etc/apt/sources.list.d/nodesource.list"
$mesh_install_nodejs_prefix apt-mark -q unhold nodejs
$mesh_install_nodejs_prefix apt-get update
$mesh_install_nodejs_prefix apt-get -yq remove --purge nodejs
if [ ! $NODE_UPGRADE ]; then
if [ -d "$rootdir/usr/local/lib/node_modules" ]; then
rm -rf "$rootdir/usr/local/lib/node_modules"
fi
fi
if [ -f "$rootdir/usr/local/bin/node" ]; then
rm "$rootdir/usr/local/bin/node"
fi
if [ -f "$rootdir/usr/bin/node" ]; then
rm /usr/bin/node
rm "$rootdir/usr/bin/node"
fi
if [ -f "$rootdir/usr/bin/nodejs" ]; then
rm "$rootdir/usr/bin/nodejs"
@ -100,10 +136,17 @@ function mesh_install_nodejs {
cp "$rootdir/usr/bin/nodejs" "$rootdir/usr/bin/node"
fi
if [ -f "$rootdir/usr/bin/node" ]; then
cp "$rootdir/usr/bin/node" "$rootdir/usr/local/bin/node"
fi
$mesh_install_nodejs_prefix apt-mark -q hold nodejs
if [ ! -f "${rootdir}/usr/bin/node" ]; then
if [ ! -f "${rootdir}/usr/local/bin/node" ]; then
if [ ! -f "${rootdir}/usr/bin/nodejs" ]; then
echo $'nodejs was not installed'
NODE_UPGRADE=
exit 63962
fi
fi
@ -111,29 +154,46 @@ function mesh_install_nodejs {
if [ ! -f "$rootdir/usr/bin/node" ]; then
echo $'/usr/bin/node not found'
NODE_UPGRADE=
exit 7235728
fi
get_npm_arch
$mesh_install_nodejs_prefix npm config set unsafe-perm true
nodejs_setup_global_modules
nodejs_fix_cpu_detection
$mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g npm@${NPM_VERSION} --save
if [ -f "$rootdir/.npm-global/bin/npm" ]; then
cp "$rootdir/.npm-global/bin/npm" "$rootdir/usr/local/bin/npm"
cp "$rootdir/.npm-global/bin/npm" "$rootdir/usr/bin/npm"
fi
if [ -f "$rootdir/usr/local/bin/npm" ]; then
cp "$rootdir/usr/local/bin/npm" /usr/bin/npm
cp "$rootdir/usr/local/bin/npm" "$rootdir/usr/bin/npm"
fi
cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
# update from the old debian nodejs version
$mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g n@${NODEJS_N_VERSION} --save
if [ ! "$rootdir" ]; then
# Don't do this if we're building an image,
# because cpu detection faults occur.
# This condition may no longer be needed in future once the bug is fixed
$mesh_install_nodejs_prefix n --arch $N_ARCH ${NODEJS_VERSION}
nodejs_fix_cpu_detection
cp "$rootdir/root/npm" "$rootdir/usr/bin/npm"
cp "$rootdir/root/npm" "$rootdir/usr/local/bin/npm"
# deliberate second install of npm
$mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g npm@${NPM_VERSION} --save
if [ -f "$rootdir/usr/local/bin/npm" ]; then
cp "$rootdir/usr/local/bin/npm" /usr/bin/npm
cp "$rootdir/usr/local/bin/npm" "$rootdir/usr/bin/npm"
fi
cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
fi
if [ -f "$rootdir/usr/bin/node" ]; then
cp "$rootdir/usr/bin/node" "$rootdir/usr/local/bin/node"
fi
# check the version numbers
cat <<EOF > "$rootdir/usr/bin/test_nodejs_install"
@ -152,9 +212,57 @@ EOF
chmod +x "$rootdir/usr/bin/test_nodejs_install"
if ! $mesh_install_nodejs_prefix /usr/bin/test_nodejs_install; then
echo $"nodejs version numbers did not match. Architecture is $NPM_ARCH."
NODE_UPGRADE=
exit 76835282
fi
rm "$rootdir/usr/bin/test_nodejs_install"
NODE_UPGRADE=
}
function nodejs_upgrade {
if [ ! -f /etc/apt/sources.list.d/nodesource.list ]; then
return
fi
nodejs_setup_global_modules
if grep -q "node_8.x" /etc/apt/sources.list.d/nodesource.list; then
if [ -f /usr/local/bin/node ]; then
CURR_NODE_VERSION=$(node --version)
if [[ "$CURR_NODE_VERSION" == "v${NODEJS_VERSION}" ]]; then
return
fi
fi
fi
if [ -f /usr/local/bin/node ]; then
CURR_NODE_VERSION=$(node --version)
if [[ "$CURR_NODE_VERSION" == "v${NODEJS_VERSION}" ]]; then
return
fi
fi
read_config_param ARCHITECTURE
get_npm_arch
NODE_UPGRADE=1
rootdir=
mesh_install_nodejs
npm update -g
}
function nodejs_setup_global_modules {
if [ ! -f /usr/local/bin/node ]; then
return
fi
if [ ! -d "$rootdir/root/.npm-global" ]; then
mkdir "$rootdir/root/.npm-global"
fi
$mesh_install_nodejs_prefix npm config set prefix '/root/.npm-global'
if ! grep -q "PATH=/root/.npm-global/bin" "$rootdir/root/.bashrc"; then
echo "PATH=/root/.npm-global/bin:\$PATH" >> "$rootdir/root/.bashrc"
fi
if ! grep -q "NPM_CONFIG_PREFIX=" "$rootdir/root/.bashrc"; then
echo "export NPM_CONFIG_PREFIX=/root/.npm-global" >> "$rootdir/root/.bashrc"
fi
# shellcheck disable=SC2086
$mesh_install_nodejs_prefix export PATH=/root/.npm-global/bin:$PATH
$mesh_install_nodejs_prefix export NPM_CONFIG_PREFIX=/root/.npm-global
}
function remove_nodejs {

View File

@ -38,7 +38,7 @@ function add_email_hostname {
extra_email_hostname="$1"
email_hostnames=$(grep "dc_other_hostnames" /etc/exim4/update-exim4.conf.conf | awk -F "'" '{print $2}')
if [[ "$email_hostnames" != *"$extra_email_hostname"* ]]; then
sed -i "s|dc_other_hostnames=.*|dc_other_hostnames='$email_hostnames;extra_email_hostname'|g" /etc/exim4/update-exim4.conf.conf
sed -i "s|dc_other_hostnames=.*|dc_other_hostnames='$email_hostnames;$extra_email_hostname'|g" /etc/exim4/update-exim4.conf.conf
update-exim4.conf
dpkg-reconfigure --frontend noninteractive exim4-config
systemctl restart saslauthd
@ -169,7 +169,7 @@ function set_default_onion_domains {
POSTACTIV_DOMAIN_NAME='postactiv.local'
GNUSOCIAL_DOMAIN_NAME='gnusocial.local'
HTMLY_DOMAIN_NAME='htmly.local'
GHOST_DOMAIN_NAME='ghost.local'
BLUDIT_DOMAIN_NAME='bludit.local'
DOKUWIKI_DOMAIN_NAME='dokuwiki.local'
DEFAULT_DOMAIN_NAME="${LOCAL_NAME}.local"
GIT_DOMAIN_NAME='gogs.local'

View File

@ -3,15 +3,15 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2018-02-21 Wed 16:16 -->
<!-- 2018-03-31 Sat 18:25 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>&lrm;</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Bob Mottram" />
<meta name="description" content="How to use Ghost"
<meta name="description" content="How to use Bludit"
/>
<meta name="keywords" content="freedombone, ghost" />
<meta name="keywords" content="freedombone, bludit, blog" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
@ -245,16 +245,16 @@ for the JavaScript code in this tag.
</div>
<center>
<h1>Ghost</h1>
<h1>Bludit</h1>
</center>
<p>
Ghost is a blogging system which uses markdown formatted posts. It's quite simple to use, and also looks nice even on small mobile screens.
This is a databaseless blogging system which uses markdown files. It's not very complex and so there is not much to go wrong, and it should run well on any server hardware.
</p>
<div id="outline-container-orgae93cef" class="outline-2">
<h2 id="orgae93cef">Installation</h2>
<div class="outline-text-2" id="text-orgae93cef">
<div id="outline-container-org09c48a1" class="outline-2">
<h2 id="org09c48a1">Installation</h2>
<div class="outline-text-2" id="text-org09c48a1">
<p>
Log into your system with:
</p>
@ -269,40 +269,15 @@ Using cursor keys, space bar and Enter key select <b>Administrator controls</b>
</p>
<p>
Select <b>Add/Remove Apps</b> then <b>ghost</b>. You will then be asked for a domain name and if you are using FreeDNS also the code for the domain which can be found under <b>Dynamic DNS</b> on the FreeDNS site (the random string from "<i>quick cron example</i>" which appears after <i>update.php?</i> and before <i>&gt;&gt;</i>). For more details on obtaining a domain and making it accessible via dynamic DNS see the <a href="./faq.html">FAQ</a>. Typically the domain name you use will be a subdomain, such as <i>blog.mydomainname.net</i>. It will need to be a domain which you have bought somewhere and own and not one of the FreeDNS subdomains, otherwise you won't be able to get a SSL/TLS certificate for it.
Select <b>Add/Remove Apps</b> then <b>bluit</b>. Enter the subdomain that you which to use, such as <b>blog.mydomain.net</b>, and optionally a FreeDNS code.
</p>
<p>
After the install has completed go to <b>Security settings</b> and select <b>Create a new Let's Encrypt certificate</b> and enter the domain name that you are using for Ghost. If you're using the "onion only" version of the system then you don't need to do this. If the certificate is obtained successfully then you will see a congratulations message.
</p>
</div>
</div>
<div id="outline-container-org1a75b29" class="outline-2">
<h2 id="org1a75b29">Initial setup</h2>
<div class="outline-text-2" id="text-org1a75b29">
<p>
If you have just obtained a Lets Encrypt certificate as above then go to <b>About</b> on the administrator control panel and you should see your Ghost blog domain listed there along with an onion address. You can then navigate to your site in a browser.
Now in a browser navigate to your subdomain. You will need to enter some details for the database. You'll be asked to provide an initial administrator password.
</p>
<p>
To see the login password for your site go to <b>Passwords</b> on the <b>Administrator control panel</b> and select the appropriate username and app. The passwords will be different for each user and may not be the same as the password which you used to originally ssh into the system.
</p>
<p>
Navigate to <a href="https://yourghostblogdomain/ghost">https://yourghostblogdomain/ghost</a> and click on <b>create your account</b>
</p>
<p>
Enter your email address, password and blog title.
</p>
<p>
When prompted to invite users click on <b>I'll do this later</b>
</p>
<p>
Under <b>Settings</b> on the <b>General</b> option you can set a description, background image and so on.
From there on it's all pretty straightforward. If you need to publish a draft the post status can be changed on a drop down list on the right hand side.
</p>
</div>
</div>

View File

@ -3,7 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2017-12-03 Sun 12:48 -->
<!-- 2018-04-01 Sun 20:32 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>&lrm;</title>
@ -244,14 +244,6 @@ for the JavaScript code in this tag.
</div>
</div>
<center>
<h1>PeerTube</h1>
</center>
<p>
This is a video hosting system similar to Mediagoblin but using <a href="https://webtorrent.io/">webtorrent</a> to help distribute the files to or between clients. This should be more practical for situations where a video becomes popular because the load is then spread across the network, with performance increasing with the number of nodes. However, the torrenting aspect of it only works with WebRTC enabled browsers and so this means it's unlikely to fully work with a Tor browser. Without WebRTC then from a user point of view it's effectively the same thing as Mediagoblin.
</p>
<div class="org-center">
<div class="figure">
@ -260,9 +252,13 @@ This is a video hosting system similar to Mediagoblin but using <a href="https:/
</div>
</div>
<div id="outline-container-orgd4e2d94" class="outline-2">
<h2 id="orgd4e2d94">Installation</h2>
<div class="outline-text-2" id="text-orgd4e2d94">
<p>
This is a video hosting system similar to Mediagoblin but using webtorrent to help distribute the files to or between clients. This should be more practical for situations where a video becomes popular because the load is then spread across the network, with performance increasing with the number of nodes. However, the torrenting aspect of it only works with WebRTC enabled browsers and so this means it's unlikely to fully work with a Tor browser. Without WebRTC then from a user point of view it's effectively the same thing as Mediagoblin.
</p>
<div id="outline-container-org244b57b" class="outline-2">
<h2 id="org244b57b">Installation</h2>
<div class="outline-text-2" id="text-org244b57b">
<p>
Log into your system with:
</p>
@ -282,15 +278,53 @@ Select <b>Add/Remove Apps</b> then <b>peertube</b>. You will then be asked for a
</div>
</div>
<div id="outline-container-org50ab03b" class="outline-2">
<h2 id="org50ab03b">Initial setup</h2>
<div class="outline-text-2" id="text-org50ab03b">
<div id="outline-container-orgc8779c8" class="outline-2">
<h2 id="orgc8779c8">Initial setup</h2>
<div class="outline-text-2" id="text-orgc8779c8">
<p>
Navigate to your site and select <b>Signup</b> to create a new account. By default the maximum number of accounts on your system is limited to a small number so that millions of random internet users can't then begin uploading dubious content. After that it's pretty straightforward.
</p>
<p>
One thing to be aware of is that after you upload a video it will take quite a while to transcode, and during that time you won't be able to play it or it will hang after playing. A way to avoid this wait is to ensure that your videos are already in mp4 format when you upload them.
If you wish it's possible to turn off further signups via the <b>Administrator control panel</b> under <b>App settings</b> for <b>peertube</b>.
</p>
</div>
</div>
<div id="outline-container-orgb28bda0" class="outline-2">
<h2 id="orgb28bda0">Importing videos from YouTube/Vimeo/Dailymotion</h2>
<div class="outline-text-2" id="text-orgb28bda0">
<p>
It's possible to import videos from the main proprietary video hosting sites. <i>Only do this if they're videos which you made, or if the license is Creative Commons</i>. Hosting arbitrary videos under nonfree licenses is likely to get you into trouble, and we know how that works out from the P2P wars of the 2000s (i.e. badly).
</p>
<p>
Go to the <b>Administrator control panel</b>, select <b>App settings</b> then <b>peertube</b> then <b>Import videos from YouTube/Vimeo/Dailymotion</b>. Enter your PeerTube login details and then you may specify either the individual video URL or the channel URL if you want to import a whole channel.
</p>
</div>
</div>
<div id="outline-container-orgcfb5e79" class="outline-2">
<h2 id="orgcfb5e79">Importing videos from your desktop</h2>
<div class="outline-text-2" id="text-orgcfb5e79">
<p>
The most convenient way to add new videos to PeerTube is if you have the <b>syncthing</b> app installed. Set up <a href="./app_syncthing.html">syncthing</a> with a folder called ~/Sync in your home directory. Create a subdirectory called <b>~/Sync/peertube_upload</b>. Within that directory make a text file called <b>login.txt</b>. This will contain your PeerTube login details.
</p>
<p>
The first line of login.txt should be your username, the second line should be the password and optionally the third line can contain the words <b>public</b> and/or <b>nsfw</b>, if you want to make imported videos immediately public or mark them as not suitable for work.
</p>
<p>
Prepare your videos in <b>ogv</b>, <b>mp4</b> or <b>webm</b> format. To minimize bandwidth usage try to keep your videos as small as possible. Giant videos with incredibly high resolution tend to result in a bad user experience. Often just converting your videos to <b>webm</b> using <b>ffmpeg</b> will keep the size down.
</p>
<p>
Now copy or drag and drop your videos into the <b>~/Sync/peertube_upload</b> directory. Syncthing will sync to the server and automatically add the videos to PeerTube. Depending on how large the videos are this may take some time.
</p>
<p>
Imported videos can be seen by logging into PeerTube, selecting <b>My account</b> then the <b>My videos</b> tab. You can then view them, add a description and select to make them public if you wish.
</p>
</div>
</div>

View File

@ -3,26 +3,33 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title></title>
<!-- 2018-03-10 Sat 21:13 -->
<!-- 2018-03-31 Sat 18:28 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="generator" content="Org-mode" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>&lrm;</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Bob Mottram" />
<meta name="description" content="List of apps available on freedombone"
/>
<meta name="keywords" content="freedombone, apps" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { color: green; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.right { margin-left: auto; margin-right: 0px; text-align: right; }
.left { margin-left: 0px; margin-right: auto; text-align: left; }
.center { margin-left: auto; margin-right: auto; text-align: center; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
@ -49,27 +56,111 @@
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
pre.src-sh:before { content: 'sh'; }
pre.src-bash:before { content: 'sh'; }
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-R:before { content: 'R'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.right { text-align: center; }
th.left { text-align: center; }
th.center { text-align: center; }
td.right { text-align: right; }
td.left { text-align: left; }
td.center { text-align: center; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara:nth-child(2) { display: inline; }
.footpara { display: block; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
@ -89,6 +180,7 @@
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
/*]]>*/-->
</style>
<link rel="stylesheet" type="text/css" href="freedombone.css" />
@ -97,7 +189,7 @@
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2013 Free Software Foundation, Inc.
Copyright (C) 2012-2017 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
@ -144,8 +236,7 @@ for the JavaScript code in this tag.
<a name="top" id="top"></a>
</div>
<div id="content">
<h1 class="title"></h1>
<div class="center">
<div class="org-center">
<div class="figure">
<p><img src="images/logo.png" alt="logo.png" />
@ -163,7 +254,7 @@ for the JavaScript code in this tag.
The base install of the system just contains an email server and Mutt client, but not much else. In addition from within the <b>Administrator control panel</b> under <b>Add/remove apps</b> the following are installable. This list only applies on the home server version, with the mesh network version having a different and smaller set of apps.
</p>
<div class="center">
<div class="org-center">
<div class="figure">
<p><img src="images/controlpanel/control_panel_apps.jpg" alt="control_panel_apps.jpg" />
@ -172,9 +263,9 @@ The base install of the system just contains an email server and Mutt client, bu
</div>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1">Akaunting</h2>
<div class="outline-text-2" id="text-1">
<div id="outline-container-org28b5697" class="outline-2">
<h2 id="org28b5697">Akaunting</h2>
<div class="outline-text-2" id="text-org28b5697">
<p>
A web based accounts system for small businesses or freelancers.
</p>
@ -184,9 +275,9 @@ A web based accounts system for small businesses or freelancers.
</p>
</div>
</div>
<div id="outline-container-sec-2" class="outline-2">
<h2 id="sec-2">BDS Mail</h2>
<div class="outline-text-2" id="text-2">
<div id="outline-container-org777bb3f" class="outline-2">
<h2 id="org777bb3f">BDS Mail</h2>
<div class="outline-text-2" id="text-org777bb3f">
<p>
It's like ordinary email, but with <a href="https://en.wikipedia.org/wiki/I2P">i2p</a> as the transport mechanism.
</p>
@ -196,9 +287,21 @@ It's like ordinary email, but with <a href="https://en.wikipedia.org/wiki/I2P">i
</p>
</div>
</div>
<div id="outline-container-sec-3" class="outline-2">
<h2 id="sec-3">CryptPad</h2>
<div class="outline-text-2" id="text-3">
<div id="outline-container-orgebcec42" class="outline-2">
<h2 id="orgebcec42">Bludit</h2>
<div class="outline-text-2" id="text-orgebcec42">
<p>
This is a simple databaseless blogging system which uses markdown files. It should run well on any hardware.
</p>
<p>
<a href="./app_bludit.html">How to use it</a>
</p>
</div>
</div>
<div id="outline-container-orgff63d63" class="outline-2">
<h2 id="orgff63d63">CryptPad</h2>
<div class="outline-text-2" id="text-orgff63d63">
<p>
Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
</p>
@ -208,9 +311,9 @@ Collaborate on editing documents, presentations and source code, or vote on thin
</p>
</div>
</div>
<div id="outline-container-sec-4" class="outline-2">
<h2 id="sec-4">DLNA</h2>
<div class="outline-text-2" id="text-4">
<div id="outline-container-orgbb60849" class="outline-2">
<h2 id="orgbb60849">DLNA</h2>
<div class="outline-text-2" id="text-orgbb60849">
<p>
Enables you to use the system as a music server which any DLNA compatible devices can connect to within your home network.
</p>
@ -220,9 +323,9 @@ Enables you to use the system as a music server which any DLNA compatible device
</p>
</div>
</div>
<div id="outline-container-sec-5" class="outline-2">
<h2 id="sec-5">Dokuwiki</h2>
<div class="outline-text-2" id="text-5">
<div id="outline-container-org5792c5f" class="outline-2">
<h2 id="org5792c5f">Dokuwiki</h2>
<div class="outline-text-2" id="text-org5792c5f">
<p>
A databaseless wiki system.
</p>
@ -232,9 +335,9 @@ A databaseless wiki system.
</p>
</div>
</div>
<div id="outline-container-sec-6" class="outline-2">
<h2 id="sec-6">Edith</h2>
<div class="outline-text-2" id="text-6">
<div id="outline-container-orgfe3cb28" class="outline-2">
<h2 id="orgfe3cb28">Edith</h2>
<div class="outline-text-2" id="text-orgfe3cb28">
<p>
Extremely simple and distraction-free notes system.
</p>
@ -244,9 +347,9 @@ Extremely simple and distraction-free notes system.
</p>
</div>
</div>
<div id="outline-container-sec-7" class="outline-2">
<h2 id="sec-7">Emacs</h2>
<div class="outline-text-2" id="text-7">
<div id="outline-container-org8962159" class="outline-2">
<h2 id="org8962159">Emacs</h2>
<div class="outline-text-2" id="text-org8962159">
<p>
If you use the Mutt client to read your email then this will set it up to use emacs for composing new mail.
</p>
@ -256,17 +359,17 @@ If you use the Mutt client to read your email then this will set it up to use em
</p>
</div>
</div>
<div id="outline-container-sec-8" class="outline-2">
<h2 id="sec-8">Email Server</h2>
<div class="outline-text-2" id="text-8">
<div id="outline-container-org1902633" class="outline-2">
<h2 id="org1902633">Email Server</h2>
<div class="outline-text-2" id="text-org1902633">
<p>
Since many apps require email registration an email server is installed by default. You can find advice on using the email system <a href="./usage_email.html">here</a>.
</p>
</div>
</div>
<div id="outline-container-sec-9" class="outline-2">
<h2 id="sec-9">Etherpad</h2>
<div class="outline-text-2" id="text-9">
<div id="outline-container-orgd4e27a5" class="outline-2">
<h2 id="orgd4e27a5">Etherpad</h2>
<div class="outline-text-2" id="text-orgd4e27a5">
<p>
Collaborate on creating documents in real time. Maybe you're planning a holiday with other family members or creating documentation for a Free Software project along with other volunteers. Etherpad is hard to beat for simplicity and speed. Only users of the system will be able to access it.
</p>
@ -276,9 +379,9 @@ Collaborate on creating documents in real time. Maybe you're planning a holiday
</p>
</div>
</div>
<div id="outline-container-sec-10" class="outline-2">
<h2 id="sec-10">Federated wiki</h2>
<div class="outline-text-2" id="text-10">
<div id="outline-container-org71dc0a8" class="outline-2">
<h2 id="org71dc0a8">Federated wiki</h2>
<div class="outline-text-2" id="text-org71dc0a8">
<p>
A new approach to creating wiki content.
</p>
@ -288,9 +391,9 @@ A new approach to creating wiki content.
</p>
</div>
</div>
<div id="outline-container-sec-11" class="outline-2">
<h2 id="sec-11">Friendica</h2>
<div class="outline-text-2" id="text-11">
<div id="outline-container-org6afa6fa" class="outline-2">
<h2 id="org6afa6fa">Friendica</h2>
<div class="outline-text-2" id="text-org6afa6fa">
<p>
Federated social network system.
</p>
@ -300,21 +403,9 @@ Federated social network system.
</p>
</div>
</div>
<div id="outline-container-sec-12" class="outline-2">
<h2 id="sec-12">Ghost</h2>
<div class="outline-text-2" id="text-12">
<p>
Modern looking blogging system.
</p>
<p>
<a href="./app_ghost.html">How to use it</a>
</p>
</div>
</div>
<div id="outline-container-sec-13" class="outline-2">
<h2 id="sec-13">GNU Social</h2>
<div class="outline-text-2" id="text-13">
<div id="outline-container-org0f25cd5" class="outline-2">
<h2 id="org0f25cd5">GNU Social</h2>
<div class="outline-text-2" id="text-org0f25cd5">
<p>
Federated social network based on the OStatus protocol. You can "<i>remote follow</i>" other users within the GNU Social federation.
</p>
@ -324,9 +415,9 @@ Federated social network based on the OStatus protocol. You can "<i>remote follo
</p>
</div>
</div>
<div id="outline-container-sec-14" class="outline-2">
<h2 id="sec-14">Gogs</h2>
<div class="outline-text-2" id="text-14">
<div id="outline-container-org7d5a232" class="outline-2">
<h2 id="org7d5a232">Gogs</h2>
<div class="outline-text-2" id="text-org7d5a232">
<p>
Lightweight git project hosting system. You can mirror projects from Github, or if Github turns evil then just host your own projects while retaining the familiar <i>fork-and-pull</i> workflow. If you can use Github then you can also use Gogs.
</p>
@ -336,9 +427,9 @@ Lightweight git project hosting system. You can mirror projects from Github, or
</p>
</div>
</div>
<div id="outline-container-sec-15" class="outline-2">
<h2 id="sec-15">HTMLy</h2>
<div class="outline-text-2" id="text-15">
<div id="outline-container-org5421983" class="outline-2">
<h2 id="org5421983">HTMLy</h2>
<div class="outline-text-2" id="text-org5421983">
<p>
Databaseless blogging system. Quite simple and with a markdown-like format.
</p>
@ -348,9 +439,9 @@ Databaseless blogging system. Quite simple and with a markdown-like format.
</p>
</div>
</div>
<div id="outline-container-sec-16" class="outline-2">
<h2 id="sec-16">Hubzilla</h2>
<div class="outline-text-2" id="text-16">
<div id="outline-container-org753029b" class="outline-2">
<h2 id="org753029b">Hubzilla</h2>
<div class="outline-text-2" id="text-org753029b">
<p>
Web publishing platform with social network like features and good privacy controls so that it's possible to specify who can see which content. Includes photo albums, calendar, wiki and file storage.
</p>
@ -360,9 +451,9 @@ Web publishing platform with social network like features and good privacy contr
</p>
</div>
</div>
<div id="outline-container-sec-17" class="outline-2">
<h2 id="sec-17">Icecast media stream</h2>
<div class="outline-text-2" id="text-17">
<div id="outline-container-org4588aff" class="outline-2">
<h2 id="org4588aff">Icecast media stream</h2>
<div class="outline-text-2" id="text-org4588aff">
<p>
Make your own internet radio station.
</p>
@ -372,9 +463,9 @@ Make your own internet radio station.
</p>
</div>
</div>
<div id="outline-container-sec-18" class="outline-2">
<h2 id="sec-18">IRC Server (ngirc)</h2>
<div class="outline-text-2" id="text-18">
<div id="outline-container-org0dc73d8" class="outline-2">
<h2 id="org0dc73d8">IRC Server (ngirc)</h2>
<div class="outline-text-2" id="text-org0dc73d8">
<p>
Run your own IRC chat channel which can be secured with a password and accessible via an onion address. A bouncer is included so that you can receive messages sent while you were offline. Works with Hexchat and other popular clients.
</p>
@ -384,18 +475,18 @@ Run your own IRC chat channel which can be secured with a password and accessibl
</p>
</div>
</div>
<div id="outline-container-sec-19" class="outline-2">
<h2 id="sec-19">Jitsi Meet</h2>
<div class="outline-text-2" id="text-19">
<div id="outline-container-orgc8faaa0" class="outline-2">
<h2 id="orgc8faaa0">Jitsi Meet</h2>
<div class="outline-text-2" id="text-orgc8faaa0">
<p>
Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
</p>
</div>
</div>
<div id="outline-container-sec-20" class="outline-2">
<h2 id="sec-20">KanBoard</h2>
<div class="outline-text-2" id="text-20">
<div id="outline-container-orgbc435d0" class="outline-2">
<h2 id="orgbc435d0">KanBoard</h2>
<div class="outline-text-2" id="text-orgbc435d0">
<p>
A simple kanban system for managing projects or TODO lists.
</p>
@ -405,9 +496,9 @@ A simple kanban system for managing projects or TODO lists.
</p>
</div>
</div>
<div id="outline-container-sec-21" class="outline-2">
<h2 id="sec-21">Key Server</h2>
<div class="outline-text-2" id="text-21">
<div id="outline-container-org3ced426" class="outline-2">
<h2 id="org3ced426">Key Server</h2>
<div class="outline-text-2" id="text-org3ced426">
<p>
An OpenPGP key server for storing and retrieving GPG public keys.
</p>
@ -417,9 +508,9 @@ An OpenPGP key server for storing and retrieving GPG public keys.
</p>
</div>
</div>
<div id="outline-container-sec-22" class="outline-2">
<h2 id="sec-22">Koel</h2>
<div class="outline-text-2" id="text-22">
<div id="outline-container-orgd689f61" class="outline-2">
<h2 id="orgd689f61">Koel</h2>
<div class="outline-text-2" id="text-orgd689f61">
<p>
Access your music collection from any internet connected device.
</p>
@ -429,9 +520,9 @@ Access your music collection from any internet connected device.
</p>
</div>
</div>
<div id="outline-container-sec-23" class="outline-2">
<h2 id="sec-23">Lychee</h2>
<div class="outline-text-2" id="text-23">
<div id="outline-container-org0b6e716" class="outline-2">
<h2 id="org0b6e716">Lychee</h2>
<div class="outline-text-2" id="text-org0b6e716">
<p>
Make your photo albums available on the web.
</p>
@ -441,9 +532,9 @@ Make your photo albums available on the web.
</p>
</div>
</div>
<div id="outline-container-sec-24" class="outline-2">
<h2 id="sec-24">Mailpile</h2>
<div class="outline-text-2" id="text-24">
<div id="outline-container-org5a5bf12" class="outline-2">
<h2 id="org5a5bf12">Mailpile</h2>
<div class="outline-text-2" id="text-org5a5bf12">
<p>
Modern email client which supports GPG encryption.
</p>
@ -453,9 +544,9 @@ Modern email client which supports GPG encryption.
</p>
</div>
</div>
<div id="outline-container-sec-25" class="outline-2">
<h2 id="sec-25">Matrix</h2>
<div class="outline-text-2" id="text-25">
<div id="outline-container-org23fcc5d" class="outline-2">
<h2 id="org23fcc5d">Matrix</h2>
<div class="outline-text-2" id="text-org23fcc5d">
<p>
Multi-user chat with some security and moderation controls.
</p>
@ -465,9 +556,9 @@ Multi-user chat with some security and moderation controls.
</p>
</div>
</div>
<div id="outline-container-sec-26" class="outline-2">
<h2 id="sec-26">Mediagoblin</h2>
<div class="outline-text-2" id="text-26">
<div id="outline-container-org152ef9d" class="outline-2">
<h2 id="org152ef9d">Mediagoblin</h2>
<div class="outline-text-2" id="text-org152ef9d">
<p>
Publicly host video and audio files so that you don't need to use YouTube/Vimeo/etc.
</p>
@ -477,9 +568,9 @@ Publicly host video and audio files so that you don't need to use YouTube/Vimeo/
</p>
</div>
</div>
<div id="outline-container-sec-27" class="outline-2">
<h2 id="sec-27">Mumble</h2>
<div class="outline-text-2" id="text-27">
<div id="outline-container-orgdf02288" class="outline-2">
<h2 id="orgdf02288">Mumble</h2>
<div class="outline-text-2" id="text-orgdf02288">
<p>
The popular VoIP and text chat system. Say goodbye to old-fashioned telephony conferences with silly dial codes. Also works well on mobile.
</p>
@ -489,9 +580,9 @@ The popular VoIP and text chat system. Say goodbye to old-fashioned telephony co
</p>
</div>
</div>
<div id="outline-container-sec-28" class="outline-2">
<h2 id="sec-28">NextCloud</h2>
<div class="outline-text-2" id="text-28">
<div id="outline-container-orga6e7867" class="outline-2">
<h2 id="orga6e7867">NextCloud</h2>
<div class="outline-text-2" id="text-orga6e7867">
<p>
Store files on your server and sync them with laptops or mobile devices. Includes many plugins including videoconferencing and collaborative document editing.
</p>
@ -501,9 +592,9 @@ Store files on your server and sync them with laptops or mobile devices. Include
</p>
</div>
</div>
<div id="outline-container-sec-29" class="outline-2">
<h2 id="sec-29">PeerTube</h2>
<div class="outline-text-2" id="text-29">
<div id="outline-container-org1f222c6" class="outline-2">
<h2 id="org1f222c6">PeerTube</h2>
<div class="outline-text-2" id="text-org1f222c6">
<p>
Peer-to-peer video hosting. Similar to Mediagoblin, but the P2P aspect better enables the streaming load to be shared across servers.
</p>
@ -513,9 +604,9 @@ Peer-to-peer video hosting. Similar to Mediagoblin, but the P2P aspect better en
</p>
</div>
</div>
<div id="outline-container-sec-30" class="outline-2">
<h2 id="sec-30">PI-Hole</h2>
<div class="outline-text-2" id="text-30">
<div id="outline-container-org93da9a8" class="outline-2">
<h2 id="org93da9a8">PI-Hole</h2>
<div class="outline-text-2" id="text-org93da9a8">
<p>
The black hole for web adverts. Block adverts at the domain name level within your local network. It can significantly reduce bandwidth, speed up page load times and protect your systems from being tracked by spyware.
</p>
@ -525,9 +616,9 @@ The black hole for web adverts. Block adverts at the domain name level within yo
</p>
</div>
</div>
<div id="outline-container-sec-31" class="outline-2">
<h2 id="sec-31">Pleroma</h2>
<div class="outline-text-2" id="text-31">
<div id="outline-container-org23c546e" class="outline-2">
<h2 id="org23c546e">Pleroma</h2>
<div class="outline-text-2" id="text-org23c546e">
<p>
Fediverse instance which is compatible with GNU Social and Mastodon, and suited for systems without much RAM or CPU resource.
</p>
@ -537,9 +628,9 @@ Fediverse instance which is compatible with GNU Social and Mastodon, and suited
</p>
</div>
</div>
<div id="outline-container-sec-32" class="outline-2">
<h2 id="sec-32">PostActiv</h2>
<div class="outline-text-2" id="text-32">
<div id="outline-container-org9916ff6" class="outline-2">
<h2 id="org9916ff6">PostActiv</h2>
<div class="outline-text-2" id="text-org9916ff6">
<p>
An alternative federated social networking system compatible with GNU Social, Pleroma and Mastodon. It includes some optimisations and fixes currently not available within the main GNU Social project.
</p>
@ -549,9 +640,9 @@ An alternative federated social networking system compatible with GNU Social, Pl
</p>
</div>
</div>
<div id="outline-container-sec-33" class="outline-2">
<h2 id="sec-33">PrivateBin</h2>
<div class="outline-text-2" id="text-33">
<div id="outline-container-orgd4b23b3" class="outline-2">
<h2 id="orgd4b23b3">PrivateBin</h2>
<div class="outline-text-2" id="text-orgd4b23b3">
<p>
A pastebin where the server has zero knowledge of the content being pasted.
</p>
@ -561,9 +652,9 @@ A pastebin where the server has zero knowledge of the content being pasted.
</p>
</div>
</div>
<div id="outline-container-sec-34" class="outline-2">
<h2 id="sec-34">Profanity</h2>
<div class="outline-text-2" id="text-34">
<div id="outline-container-org0082b2c" class="outline-2">
<h2 id="org0082b2c">Profanity</h2>
<div class="outline-text-2" id="text-org0082b2c">
<p>
A shell based XMPP client which you can run on the Freedombone server via ssh.
</p>
@ -573,9 +664,9 @@ A shell based XMPP client which you can run on the Freedombone server via ssh.
</p>
</div>
</div>
<div id="outline-container-sec-35" class="outline-2">
<h2 id="sec-35">Riot Web</h2>
<div class="outline-text-2" id="text-35">
<div id="outline-container-orga4c89c0" class="outline-2">
<h2 id="orga4c89c0">Riot Web</h2>
<div class="outline-text-2" id="text-orga4c89c0">
<p>
A browser based user interface for the Matrix federated communications system, including WebRTC audio and video chat.
</p>
@ -585,9 +676,9 @@ A browser based user interface for the Matrix federated communications system, i
</p>
</div>
</div>
<div id="outline-container-sec-36" class="outline-2">
<h2 id="sec-36">SearX</h2>
<div class="outline-text-2" id="text-36">
<div id="outline-container-orgfe0d758" class="outline-2">
<h2 id="orgfe0d758">SearX</h2>
<div class="outline-text-2" id="text-orgfe0d758">
<p>
A metasearch engine for customised and private web searches.
</p>
@ -597,9 +688,9 @@ A metasearch engine for customised and private web searches.
</p>
</div>
</div>
<div id="outline-container-sec-37" class="outline-2">
<h2 id="sec-37">tt-rss</h2>
<div class="outline-text-2" id="text-37">
<div id="outline-container-org1a8ec29" class="outline-2">
<h2 id="org1a8ec29">tt-rss</h2>
<div class="outline-text-2" id="text-org1a8ec29">
<p>
Private RSS reader. Pulls in RSS/Atom feeds via Tor and is only accessible via an onion address. Have "<i>the right to read</i>" without the Surveillance State knowing what you're reading. Also available with a user interface suitable for viewing on mobile devices via a browser such as OrFox.
</p>
@ -609,9 +700,9 @@ Private RSS reader. Pulls in RSS/Atom feeds via Tor and is only accessible via a
</p>
</div>
</div>
<div id="outline-container-sec-38" class="outline-2">
<h2 id="sec-38">Syncthing</h2>
<div class="outline-text-2" id="text-38">
<div id="outline-container-orgc31b9a5" class="outline-2">
<h2 id="orgc31b9a5">Syncthing</h2>
<div class="outline-text-2" id="text-orgc31b9a5">
<p>
Possibly the best way to synchronise files across all of your devices. Once it has been set up it "just works" with no user intervention needed.
</p>
@ -621,9 +712,9 @@ Possibly the best way to synchronise files across all of your devices. Once it h
</p>
</div>
</div>
<div id="outline-container-sec-39" class="outline-2">
<h2 id="sec-39">Tahoe-LAFS</h2>
<div class="outline-text-2" id="text-39">
<div id="outline-container-org84b0dd7" class="outline-2">
<h2 id="org84b0dd7">Tahoe-LAFS</h2>
<div class="outline-text-2" id="text-org84b0dd7">
<p>
Robust and encrypted storage of files on one or more server.
</p>
@ -633,9 +724,9 @@ Robust and encrypted storage of files on one or more server.
</p>
</div>
</div>
<div id="outline-container-sec-40" class="outline-2">
<h2 id="sec-40">Tox</h2>
<div class="outline-text-2" id="text-40">
<div id="outline-container-orge358056" class="outline-2">
<h2 id="orge358056">Tox</h2>
<div class="outline-text-2" id="text-orge358056">
<p>
Client and bootstrap node for the Tox chat/VoIP system.
</p>
@ -645,9 +736,9 @@ Client and bootstrap node for the Tox chat/VoIP system.
</p>
</div>
</div>
<div id="outline-container-sec-41" class="outline-2">
<h2 id="sec-41">Turtl</h2>
<div class="outline-text-2" id="text-41">
<div id="outline-container-org252f43c" class="outline-2">
<h2 id="org252f43c">Turtl</h2>
<div class="outline-text-2" id="text-org252f43c">
<p>
A system for privately creating and sharing notes and images, similar to Evernote but without the spying.
</p>
@ -657,18 +748,18 @@ A system for privately creating and sharing notes and images, similar to Evernot
</p>
</div>
</div>
<div id="outline-container-sec-42" class="outline-2">
<h2 id="sec-42">Vim</h2>
<div class="outline-text-2" id="text-42">
<div id="outline-container-orga8df5ec" class="outline-2">
<h2 id="orga8df5ec">Vim</h2>
<div class="outline-text-2" id="text-orga8df5ec">
<p>
If you use the Mutt client to read your email then this will set it up to use vim for composing new mail.
</p>
</div>
</div>
<div id="outline-container-sec-43" class="outline-2">
<h2 id="sec-43">Virtual Private Network (VPN)</h2>
<div class="outline-text-2" id="text-43">
<div id="outline-container-orga3f5966" class="outline-2">
<h2 id="orga3f5966">Virtual Private Network (VPN)</h2>
<div class="outline-text-2" id="text-orga3f5966">
<p>
Set up a VPN on your server so that you can bypass local internet censorship.
</p>
@ -678,9 +769,9 @@ Set up a VPN on your server so that you can bypass local internet censorship.
</p>
</div>
</div>
<div id="outline-container-sec-44" class="outline-2">
<h2 id="sec-44">XMPP</h2>
<div class="outline-text-2" id="text-44">
<div id="outline-container-org4a03248" class="outline-2">
<h2 id="org4a03248">XMPP</h2>
<div class="outline-text-2" id="text-org4a03248">
<p>
Chat server which can be used together with client such as Gajim or Conversations to provide end-to-end content security and also onion routed metadata security. Includes advanced features such as <i>client state notification</i> to save battery power on your mobile devices, support for seamless roaming between networks and <i>message carbons</i> so that you can receive the same messages while being simultaneously logged in to your account on more than one device.
</p>