Commit 14d35322 authored by Ilja's avatar Ilja

Merge branch 'v3.0' into 'master'

Release v0.3.0

Closes #5

See merge request !7
parents bbeaeb4a 6ce03a43
# Neutrinet YunoHost App
# Overview
This application is for Neutrinet members that have an Internet Cube configured has expected.
For now it does 2 things:
* fixed the situation where your certificate is outdated
* install neutrinet app list for YunoHost so you get updates for this app
* install labrique internet/internet cube app list for YunoHost so you get updates for this app
The neutrinet application is for Neutrinet members that have an Internet Cube configured and does 2 things:
* It renews the vpn-certificates
* Adds a webpage with genral information about Neutrinet
# Installation
## From the webinterface
Either put `https://github.com/neutrinet/neutrinet_ynh` in the administration interface at the bottom of the installation page or do this command in ssh:
yunohost app install https://github.com/Neutrinet/neutrinet_ynh --verbose
First make sure you have the neutrinet_app list
1. Go to the admin interface on your cube
2. Click *Applications* > *Install* > At the bottom click *Manage application lists* > Check in the Application list if you have *neutrinet*
3. If you don't have it > under Custom applications lists you give *neutrinet* under Name. Under URL you give *https://neutrinet.be/apps.json* > Add
The we can install the application
1. Click *Applications* at the top of the page
2. click *Install* > select *All apps* > search for *neutrinet*> click *Install* > Fill in the form (or just keep the defaults) and press Install just like you would install any app from the webinterface
# Known and "normal" warning/error messages during installation
## From the CLI
If you see those, don't worry, it's not a bug.
First check if you have a list, probably named *neutrinet*, with *https://neutrinet.be/apps.json* as url.
After `+ sudo virtualenv ve --system-site-packages`
`yunohost app listlists`
Compiling /tmp/pip-build-0Vk8QK/pexpect/pexpect/async.py ...
File "/tmp/pip-build-0Vk8QK/pexpect/pexpect/async.py", line 16
transport, pw = yield from asyncio.get_event_loop()\
^
SyntaxError: invalid syntax
If you don't have the list yet, you can add it using
This is due to the fact that we don't use python3 but python2 and that doesn't change anything here.
`yunohost app fetchlist --name neutrinet -u https://neutrinet.be/apps.json`
After `Running command 'yunohost app setting vpnclient login_passphrase -v "xxxxxxxxxxxxxxxxxxxxx"' ... done`
Once you have the list, you can install the app using
Failed to open /dev/tty: No such device or address
Failed to open /dev/tty: No such device or address
Failed to open /dev/tty: No such device or address
Failed to open /dev/tty: No such device or address
Failed to open /dev/tty: No such device or address
Failed to open /dev/tty: No such device or address
Failed to open /dev/tty: No such device or address
`yunohost app install neutrinet --debug`
It doesn't prevent the script from running.
# For contributers
## Publish a new version of the app
# Publish a new version of the app
* Edit the [manifest](manifest.json) file to bump the version
* Edit the [upgrade](scripts/upgrade) script with the needed upgrades for previous installations
* Test the updated version both for new installs and upgrades and make sure the other scripts ([backup](scripts/backup), [remove](scripts/remove) and [upgrade](scripts/upgrade)) also still work
* In the [apps.json](https://neutrinet.be/apps.json) file you must update the `revision` with the current `sha` on the `master` branch of the package and update the `lastUpdate` field. If you added things to the manifest file, you should add these changes ass well
- edit the [upgrade](scripts/upgrade) script to bump the version
- update the `revision` with the current `sha` on the `master` branch, update the `lastUpdate` field in the [apps.json](https://neutrinet.be/apps.json) file
- test the updated version:
- check current version of the app on your cube: `yunohost app setting neutrinet version`
- update the app with the latest version from master: `yunohost app upgrade neutrinet -u https://github.com/Neutrinet/neutrinet_ynh`
- check the app has been updated: `yunohost app setting neutrinet version`
- set the app to a previous version if you want to re-test the update: `yunohost app setting neutrinet version -v "0.2.2"`
location PATHTOCHANGE/ {
alias ALIASTOCHANGE;
if ($scheme = http) {
rewrite ^ https://$server_name$request_uri? permanent;
}
index index.html;
}
......@@ -2,20 +2,28 @@
"name": "Neutrinet",
"id": "neutrinet",
"description": {
"en": "Specific configs for Neutrinet",
"fr": "Application gérant les configurations spécifiques à Neutrinet"
"en": "Auto renewall for the Neutrinet vpn-certificates",
"fr": "Renouvellement automatique des certificats vpn Neutrinet"
},
"version": "0.3.0~ynh1",
"license": "GPL-3+",
"maintainer": {
"name": "bram",
"email": "cortex@worlddomination.be",
"url": "http://worlddomination.be"
"name": "ilja",
"email": "neutrinet@spectraltheorem.be",
"url": "https://gitlab.com/Spctrl"
},
"requirements": {
"yunohost": ">= 3.2.0"
},
"multi_instance": "false",
"services": [
"nginx"
],
"arguments": {
"install" : [
{
"name": "domain",
"type": "domain",
"ask": {
"en": "Choose a domain for Neutrinet application",
"fr": "Choisissez un domaine pour l'application Neutrinet"
......@@ -23,7 +31,8 @@
"example": "domain.org"
},
{
"name": "path",
"name": "path_url",
"type": "path",
"ask": {
"en": "Choose a path for Neutrinet application",
"fr": "Choisissez un chemin pour l'application Neutrinet"
......
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source /usr/share/yunohost/helpers
source _common.sh
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
ynh_abort_if_errors
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
domain=$(ynh_app_setting_get $app domain)
path_url=$(ynh_app_setting_get $app path_url)
app_user=$(ynh_app_setting_get $app app_user)
www_path=$(ynh_app_setting_get $app www_path)
opt_path=$(ynh_app_setting_get $app opt_path)
#=================================================
# STANDARD BACKUP STEPS
#=================================================
# BACKUP THE NGINX CONFIGURATION
#=================================================
ynh_print_info "Backing up..."
ynh_backup "$www_path"
ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf"
ynh_backup "$opt_path"
ynh_backup "/etc/cron.daily/$app-renew-cert"
RENEW_CERT_PATH=/opt/neutrinet/renew_cert
get_out_of_testing() {
set -e
if [ -e /etc/apt/sources.list.d/yunohost.list ]; then
sudo sed -ri 's#^(deb http://repo\.yunohost\.org/debian[/]? jessie) (stable )?testing#\1 stable#g' /etc/apt/sources.list.d/yunohost.list
fi
}
set -e
#!/bin/bash
source ./commons
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
# Retrieve arguments
domain=$1
path=$2
source /usr/share/yunohost/helpers
source _common.sh
path=${path%/}
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
# Check domain/path availability
sudo yunohost app checkurl $domain$path -a neutrinet
if [[ ! $? -eq 0 ]]; then
exit 1
ynh_abort_if_errors
#=================================================
# RETRIEVE ARGUMENTS FROM THE MANIFEST
#=================================================
domain=$YNH_APP_ARG_DOMAIN
path_url=$YNH_APP_ARG_PATH_URL
app=$YNH_APP_INSTANCE_NAME
app_user=$app
#==================================================
# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS
#==================================================
www_path=/var/www/$app
if [[ -e $www_path ]]
then
ynh_die "The path $www_path already contains a folder"
fi
install_static_file() {
set -e
opt_path=/opt/$app
if [[ -e $opt_path ]]
then
ynh_die "The path $opt_path already contains a folder"
fi
final_path=/var/www/neutrinet/
sudo mkdir -p $final_path
sudo cp -a ../sources/. $final_path
# Normalize the url path syntax
path_url=$(ynh_normalize_url_path $path_url)
sudo chown -R www-data: $final_path
# Check web path availability
if ! ynh_webpath_available $domain $path_url
then
ynh_die "$domain$path_url is not available"
fi
if [[ "$path" == "" ]]; then
sed -i "s@PATHTOCHANGE@/@g" ../conf/nginx.conf
else
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
fi
# Register (book) web path
ynh_webpath_register $app $domain $path_url
sed -i "s@ALIASTOCHANGE@$final_path@g" ../conf/nginx.conf
#=================================================
# STORE SETTINGS
#=================================================
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/neutrinet.conf
ynh_app_setting_set $app domain $domain
ynh_app_setting_set $app path_url $path_url
ynh_app_setting_set $app app_user $app_user
ynh_app_setting_set $app www_path $www_path
ynh_app_setting_set $app opt_path $opt_path
sudo service nginx reload
}
#=================================================
# STANDARD MODIFICATIONS
#=================================================
# INSTALL DEPENDENCIES
#=================================================
install_renew_cert() {
set -e
ynh_print_info "Installing dependencies…"
install_dir=$(pwd)
ynh_install_app_dependencies git python3-venv libssl-dev libffi-dev python3-dev
if [ -e $RENEW_CERT_PATH ]; then
sudo rm -rf $RENEW_CERT_PATH
fi
#=================================================
# CREATE DEDICATED USER
#=================================================
sudo apt-get update
sudo apt-get install -y python-virtualenv
ynh_print_info "Creating app's user…"
sudo git clone https://github.com/neutrinet/renew_cert $RENEW_CERT_PATH
mkdir -p $www_path
ynh_system_user_create $app_user $www_path
cd $RENEW_CERT_PATH
#=================================================
# INSTALL STATIC FILE
#=================================================
sudo git checkout ccc5b6b58010bb4166c2ae1a72df340395827f99 || echo ""
ynh_print_info "Installing static site…"
# I need system site packages otherwise moulinette is broken
sudo virtualenv ve --system-site-packages
sudo ve/bin/pip install -r requirements.txt
cp -a ../sources/. $www_path
chown -R $app_user: $www_path
cd $install_dir
}
sed -i "s@PATHTOCHANGE@$path_url@g" ../conf/nginx.conf
sed -i "s@ALIASTOCHANGE@$www_path@g" ../conf/nginx.conf
renew_cert() {
set -e
cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
install_dir=$(pwd)
nginx -tq
service nginx reload
cd $RENEW_CERT_PATH
sudo ve/bin/python renew_from_cube.py
#=================================================
# INSTALL RENEW CERT
#=================================================
cd $install_dir
}
renew_cert_repo="https://github.com/neutrinet/renew_cert"
renew_cert_version=$(jq .version ../manifest.json -r -e | cut -d '~' -f 1)
renew_cert_path="$opt_path/renew_cert"
renew_cert_virtualenv="$renew_cert_path/ve"
renew_cert_python="$renew_cert_virtualenv/bin/python3"
renew_cert_cron_script="renew_cert_cron.sh"
install_neutrinet_apps_list() {
if ! sudo yunohost app listlists | grep -q "neutrinet:"; then
sudo yunohost app fetchlist -n neutrinet -u https://neutrinet.be/apps.json
fi
}
ynh_print_info "Installing automatic VPN certificate renewal…"
install_labriqueinternet_apps_list() {
if ! sudo yunohost app listlists | grep -q "labriqueinternet:"; then
sudo yunohost app fetchlist -n labriqueinternet -u https://labriqueinter.net/apps/labriqueinternet.json
fi
}
git clone $renew_cert_repo $renew_cert_path
git -C $renew_cert_path checkout $renew_cert_version
sudo yunohost app setting neutrinet version -v "0.2"
# We wrap the python3 script that actually renew the VPN certificate
# This wrapper will be used as a daily cron task
cp $renew_cert_cron_script $renew_cert_path/$renew_cert_cron_script
install_neutrinet_apps_list
install_labriqueinternet_apps_list
# From now on we work in the renew_cert directory
cd $renew_cert_path
get_out_of_testing
# We need system site packages otherwise moulinette is broken
python3 -m venv $renew_cert_virtualenv --system-site-packages
ve/bin/pip install wheel
ve/bin/pip install -r requirements.txt
install_static_file
ynh_print_info "Setting up permissions"
chown -R $app_user: $opt_path
install_renew_cert
chmod 0755 $renew_cert_cron_script
chown root: $renew_cert_cron_script
# vpn is not running, let's assume for now that this mean that the vpn is broken
if [ ! "$(grep '^port 1195' /etc/openvpn/client.conf)" ]; then
renew_cert
fi
#=================================================
# SETTING UP CRONTAB
#=================================================
ynh_print_info "Setting up cron job for certificate renewal…"
cat <<EOF > /etc/cron.daily/$app-renew-cert
#!/bin/bash
cd $renew_cert_path
RENEW_CERT_PYTHON="$renew_cert_python" $renew_cert_path/$renew_cert_cron_script
EOF
chown root:root /etc/cron.daily/$app-renew-cert
chmod 0755 /etc/cron.daily/$app-renew-cert
#=================================================
# FINALIZATION
#=================================================
ynh_print_info "Checking certificates…"
/etc/cron.daily/$app-renew-cert
source ./commons
#!/bin/bash
domain=$(sudo yunohost app setting neutrinet domain)
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
sudo rm -rf $RENEW_CERT_PATH
sudo rm -rf /var/www/neutrinet/
source /usr/share/yunohost/helpers
source _common.sh
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
domain=$(ynh_app_setting_get $app domain)
path_url=$(ynh_app_setting_get $app path_url)
app_user=$(ynh_app_setting_get $app app_user)
www_path=$(ynh_app_setting_get $app www_path)
opt_path=$(ynh_app_setting_get $app opt_path)
#=================================================
# STANDARD REMOVE
#=================================================
ynh_print_info "Removing static site..."
rm -rf $www_path
rm -f /etc/nginx/conf.d/$domain.d/$app.conf
nginx -t > /dev/null
service nginx reload
ynh_print_info "Removing automatic vpn certificate renewal..."
rm -rf $opt_path
rm -rf /etc/cron.daily/$app-renew-cert
#=================================================
# REMOVE DEPENDENCIES
#=================================================
ynh_print_info "Removing dependencies..."
ynh_remove_app_dependencies
#=================================================
# REMOVE DEDICATED USER
#=================================================
ynh_print_info "Removing system user..."
ynh_system_user_delete $app_user
sudo rm -f /etc/nginx/conf.d/$domain.d/neutrinet.conf
#!/bin/bash
set -e
OPENVPN_CONF_DIR="/etc/openvpn"
OPENVPN_KEYS_DIR="${OPENVPN_CONF_DIR}/keys"
OPENVPN_CREDENTIALS_FILE="${OPENVPN_KEYS_DIR}/credentials"
OPENVPN_AUTH_FILE="${OPENVPN_KEYS_DIR}/auth"
OPENVPN_USER_CERT="${OPENVPN_KEYS_DIR}/user.crt"
OPENVPN_USER_KEY="${OPENVPN_KEYS_DIR}/user.key"
OPENVPN_SERVER_CERT="${OPENVPN_KEYS_DIR}/ca-server.crt"
OPENVPN_CONF_TEMPLATE="${OPENVPN_CONF_DIR}/client.conf.tpl"
OPENVPN_CLIENT_LOGS="/var/log/openvpn-client.log"
NEUTRINET_CONF_TEMPLATE="neutrinet_openvpn_config"
if [[ -z $RENEW_CERT_PATH ]]
then
RENEW_CERT_PATH=$PWD
fi
if [[ -z $RENEW_CERT_PYTHON ]]
then
RENEW_CERT_PYTHON=$(command -v python3)
fi
RENEW_CERT_SCRIPT="${RENEW_CERT_PATH}/renew.py"
if [[ -f $OPENVPN_CREDENTIALS_FILE ]]
then
credentials_file=$OPENVPN_CREDENTIALS_FILE
elif [[ -f $OPENVPN_AUTH_FILE ]]
then
credentials_file=$OPENVPN_AUTH_FILE
else
>&2 echo "ERROR: Cannot find credentials for Neutrinet VPN since neither ${OPENVPN_CREDENTIALS_FILE} nor ${OPENVPN_AUTH_FILE} exists."
exit 1
fi
login=$(head -n 1 "$credentials_file")
password=$(tail -n 1 "$credentials_file")
run_date=$(date +'%Y-%m-%d_%H:%M:%S')
renew_dir="certs_$run_date"
$RENEW_CERT_PYTHON $RENEW_CERT_SCRIPT "$login" -p "$password" -c "$OPENVPN_USER_CERT" -d "$renew_dir" -v
if [[ ! -d $renew_dir || ! -f $renew_dir/ca.crt || ! -f $renew_dir/client.crt || ! -f $renew_dir/client.key ]]
then
echo "Cleaning $renew_dir directory."
rm -rf "$renew_dir"
exit 0
fi
echo "Saving old OpenVPN config"
cp -r $OPENVPN_CONF_DIR{,.old_${run_date}}
echo "Copying new OpenVPN config"
cp "$NEUTRINET_CONF_TEMPLATE" "$OPENVPN_CONF_TEMPLATE"
echo "Copying new certificates"
cp "$renew_dir/ca.crt" "$OPENVPN_SERVER_CERT"
cp "$renew_dir/client.crt" "$OPENVPN_USER_CERT"
cp "$renew_dir/client.key" "$OPENVPN_USER_KEY"
echo "Adding user credentials"
echo -e "$login\n$password" > "$OPENVPN_CREDENTIALS_FILE"
echo "Updating VPNClient config"
yunohost app setting vpnclient server_name -v "vpn.neutrinet.be"
yunohost app setting vpnclient server_port -v "1195"
yunohost app setting vpnclient server_proto -v "udp"
yunohost app setting vpnclient service_enabled -v "1"
yunohost app setting vpnclient login_user -v "$login"
yunohost app setting vpnclient login_passphrase -v "$password"
echo "Critical part 1: reloading VPNClient"
if ! ynh-vpnclient restart && ynh-vpnclient status
then
>&2 echo "ERROR: Failed to restart VPNClient"
tail -n 200 "$OPENVPN_CLIENT_LOGS"
exit 1
fi
echo "Critical part 2: restarting OpenVPN"
if ! service openvpn restart
then
>&2 echo "ERROR: Failed to restart OpenVPN"
journalctl -u openvpn -n 200 --no-pager
exit 1
fi
sleep 15
if ! command -v ynh-hotspot > /dev/null
then
exit 0
fi
echo "Few, we're done, let's wait 2min to be sure the VPN is running, then restart hotspot"
sleep 120
echo "Restarting hotspot"
if ! ynh-hotspot restart && ynh-hotspot status
then
>&2 echo "ERROR: Failed to restart hotspot"
echo "Since it's not a critical part, let's continue"
fi
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source /usr/share/yunohost/helpers
source _common.sh
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
ynh_abort_if_errors
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
domain=$(ynh_app_setting_get $app domain)
path_url=$(ynh_app_setting_get $app path_url)
app_user=$(ynh_app_setting_get $app app_user)
www_path=$(ynh_app_setting_get $app www_path)
opt_path=$(ynh_app_setting_get $app opt_path)
#=================================================
# CHECK IF THE APP CAN BE RESTORED
#=================================================
ynh_print_info "Checking for conflicts…"
[[ ! -e $www_path ]] || ynh_die "The path $www_path already contains a folder"
[[ ! -e $opt_path ]] || ynh_die "The path $opt_path already contains a folder"
# Check web path availability
if ! ynh_webpath_available "$domain" "$path_url"
then
ynh_die "$domain$path_url is no longer available"
fi
#=================================================
# STANDARD MODIFICATIONS
#=================================================
# INSTALL DEPENDENCIES
#=================================================
ynh_print_info "Installing dependencies…"
ynh_install_app_dependencies git python3-venv libssl-dev libffi-dev python3-dev
#=================================================
# CREATE DEDICATED USER
#=================================================
mkdir -p "$www_path"
ynh_system_user_create $app_user "$www_path"
#=================================================
# RESTORE STATIC FILES
#=================================================
ynh_print_info "Restoring static site…"
ynh_restore_file "$www_path"
ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf"
chown -R $app_user: "$www_path"
nginx -tq
service nginx reload
#=================================================
# RESTORE RENEW CERT
#=================================================
ynh_print_info "Restoring automatic VPN certificates renewal…"
ynh_restore_file "$opt_path"
ynh_restore_file "/etc/cron.daily/$app-renew-cert"
chown -R $app_user: $opt_path
chown root:root /etc/cron.daily/$app-renew-cert \
$opt_path/renew_cert/renew_cert_cron.sh
chmod 0755 /etc/cron.daily/$app-renew-cert \
$opt_path/renew_cert/renew_cert_cron.sh
#=================================================
# FINALIZATION
#=================================================
ynh_print_info "Checking certificates…"
/etc/cron.daily/$app-renew-cert
set -e
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source /usr/share/yunohost/helpers
source _common.sh
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
source ./commons
domain=$(ynh_app_setting_get $app domain)
path_url=$(ynh_app_setting_get $app path_url)
app_user=$(ynh_app_setting_get $app app_user)
www_path=$(ynh_app_setting_get $app www_path)
opt_path=$(ynh_app_setting_get $app opt_path)
version=$(sudo yunohost app setting neutrinet version)
# There are two ways to get the version:
# - before 0.3.0~ynh1: version is only stored in app settings
# - after 0.3.0~ynh1: version is only stored in the manifest
# We don't use ynh_app_upstream_version, because it would return "null"
# when the version isn't in the manifest
manifest=/etc/yunohost/apps/$app/manifest.json
version=$(jq '.version // empty' -r -e $manifest || ynh_app_setting_get $app version)
# 0.1.1 -> 0.2
if [[ "$version" == "0.1.1" ]]; then
#=================================================
# ENSURE DOWNWARD COMPATIBILITY
#=================================================
get_out_of_testing
if [[ -z $www_path ]]; then
www_path=/var/www/$app
ynh_app_setting_set $app www_path $www_path
sudo yunohost app setting neutrinet version -v "0.2"
version="0.2"
mkdir -p $www_path
fi
# 0.2 -> 0.2.1
if [[ "$version" == "0.2" ]]; then
sudo yunohost app setting neutrinet version -v "0.2.1"
version="0.2.1"
if [[ -z $opt_path ]]; then
opt_path=/opt/$app
ynh_app_setting_set $app opt_path $opt_path
cd $RENEW_CERT_PATH
sudo ve/bin/python renew_from_cube.py
mkdir -p $opt_path
fi
# 0.2.1 -> 0.2.2
if [[ "$version" == "0.2.1" ]]; then
sudo yunohost app setting neutrinet version -v "0.2.2"
version="0.2.2"
if [[ -z $app_user ]]; then
app_user=$app
ynh_app_setting_set $app app_user $app_user
fi
cd $RENEW_CERT_PATH
sudo git fetch
sudo git checkout 01b9306e51e74a2dac5b06f3fb6c29a0fb2fe755
sudo ve/bin/python renew_from_cube.py --cron
if [[ -z $path_url ]]; then
path_url=$(ynh_app_setting_get $app path)
cat <<EOF > /etc/cron.daily/neutrinet-renew-cert
#!/bin/bash
cd $RENEW_CERT_PATH
ve/bin/python renew_from_cube.py --cron
EOF
sudo chown root:root /etc/cron.daily/neutrinet-renew-cert
sudo chmod 0755 /etc/cron.daily/neutrinet-renew-cert
if [[ -z $path_url ]]; then
ynh_die "Missing path url!"