-
-
Save ppmotskula/4288167460de27d22225e4959c44c6c4 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
ABOUT="piactl 0.10 | |
Copyright (c) 2018-2020 Peeter P. Mõtsküla <[email protected]> | |
https://gist.github.com/ppmotskula/4288167460de27d22225e4959c44c6c4 | |
License: MIT License (https://opensource.org/licenses/MIT) | |
piactl helps you to install, configure and control CNIL's PIA software | |
(https://www.cnil.fr/en/open-source-pia-software-helps-carry-out-data-protection-impact-assesment) | |
Special thanks to github.com/ylachgar for his runbook and github.com/kosmas58 for his pia_docker | |
NOTE: piactl has been successfully tested on a fresh DigitalOcean droplet | |
with 2 GB RAM and 1 VCPU running Ubuntu 18.04.2, and fresh VirtualBox VMs | |
running Ubuntu 18.04.1 (server and desktop editions). | |
" | |
USAGE="Usage: | |
piactl [status] | |
Display running PIA software if any | |
piactl start back|front|all | |
Start PIA software (pia-back, pia, or both) | |
piactl stop back|front|all | |
Stop running PIA software | |
piactl install back|front|all HOST [VERSION] | |
Download and install PIA software (latest version unless a | |
particular version number is given), and configure it to be | |
accessed via specified hostname | |
piactl reinstall back|front|all HOST [VERSION] | |
Shortcut for 'piactl remove OPTIONS && piactl install OPTIONS' | |
piactl secure back|front|all HOST | |
Reconfigure installed PIA software to be served via https, | |
obtaining letsencrypt (test) certificates unless already present | |
piactl certify HOST | |
Request non-test letsencrypt certificate for the given hostname. | |
Note that letsencrypt certificates expire in 90 days. To renew | |
them, run 'certbot renew' from time to time, or read certbot | |
documentation for how to configure your system to auto-renew them | |
piactl remove back|front|all | |
Remove installed PIA software. If you want to also remove the | |
dependencies and/or certificates, then you must do it manually | |
piactl resetcap | |
re-setcap /usr/bin/node to allow pia-front to run on :443 | |
(this may be needed when nodejs has been updated) | |
piactl help|--help|-h | |
Show this help message and exit | |
NOTE: you need root permissions to use piactl. | |
" | |
main() { | |
case "$1" in | |
""|"status") # piactl | |
pia-status | |
;; | |
"start") # piactl start back|front|all | |
if [ $# != 2 ] ; then | |
usage "piactl start back|front|all" | |
fi | |
case "$2" in | |
back) | |
start-back | |
;; | |
front) | |
start-front | |
;; | |
all) | |
start-back | |
start-front | |
;; | |
*) | |
usage "piactl start back|front|all"; | |
esac | |
;; | |
"stop") # piactl stop back|front|all | |
if [ $# != 2 ] ; then usage ; fi | |
case "$2" in | |
back) | |
stop-back | |
;; | |
front) | |
stop-front | |
;; | |
all) | |
stop-back | |
stop-front | |
;; | |
*) | |
usage "piactl stop back|front|all"; | |
esac | |
;; | |
"install") # piactl install back|front|all HOST [VERSION] | |
if [[ $# < 3 || $# > 4 ]] ; then | |
usage "piactl install back|front|all HOST [VERSION]" | |
fi | |
install $2 $3 $4 | |
;; | |
"reinstall") # piactl reinstall back|front|all HOST [VERSION] | |
if [[ $# < 3 || $# > 4 ]] ; then | |
usage "piactl reinstall back|front|all HOST [VERSION]" | |
fi | |
remove $2 && install $2 $3 $4 | |
;; | |
"secure") # piactl secure back|front|all HOST | |
if [ $# != 3 ] ; then | |
usage "piactl secure back|front|all HOST" | |
fi | |
case "$2" in | |
back) | |
secure-back $3 | |
;; | |
front) | |
secure-front $3 | |
;; | |
all) | |
secure-back $3 | |
secure-front $3 | |
;; | |
*) | |
usage "piactl secure back|front|all HOST"; | |
esac | |
;; | |
"certify") # piactl certify HOST | |
if [ $# != 2 ] ; then | |
usage "piactl certify HOST" | |
fi | |
certify $2 --prod | |
;; | |
"remove") # piactl remove back|front|all | |
remove $2 $3 $4 | |
;; | |
"resetcap") # piactl resetcap | |
resetcap | |
;; | |
"help"|"--help"|"-h") # piactl help | |
echo "$ABOUT" | |
echo "$USAGE" | |
exit | |
;; | |
*) # piactl <unrecognized params> | |
usage | |
;; | |
esac | |
} | |
usage() { | |
local MSG | |
if [ $# != 0 ] ; then | |
MSG="$@" | |
else | |
MSG="piactl [COMMAND] [OPTIONS]" | |
fi | |
echo "Usage: | |
$MSG | |
Run 'piactl help' for details" | |
exit 1 | |
} | |
pid-front() { | |
echo $(ps ax|grep -v grep|grep ' ng'|sed -e 's/\([0-9 ]*\).*/\1/'|sed -e 's/ //g') | |
} | |
pid-back() { | |
echo $(ps ax|grep -v grep|grep '\[pia-back]'|sed -e 's/\([0-9 ]*\).*/\1/'|sed -e 's/ //g') | |
} | |
pia-status() { | |
echo -n "PIA status: backend " | |
if [ ! -e ~/pia-back ] ; then echo -n "not installed" | |
else | |
if [ "$(pid-back)" != "" ] ; then echo -n "running ($(pid-back))" ; else echo -n "stopped" ; fi | |
fi | |
echo -n ", frontend " | |
if [ ! -e ~/pia ] ; then echo -n "not installed" | |
else | |
if [ "$(pid-front)" != "" ] ; then echo -n "running ($(pid-front))" ; else echo -n "stopped" ; fi | |
fi | |
echo | |
} | |
start-back() { | |
if ( ! sudo -v ) ; then nosudo ; fi | |
if [ ! -e ~/pia-back ] ; then | |
echo "piactl: warning: backend not installed" | |
elif [ "$(pid-back)" != "" ] ; then | |
echo "piactl: warning: backend is already running ($(pid-back))" | |
else | |
cd ~/pia-back | |
if [ -e ssl ] ; then | |
sudo -Hu www-data bin/rails s -b "ssl://0.0.0.0?key=ssl/server.key&cert=ssl/server.crt" & | |
else | |
sudo -Hu www-data bin/rails s -b 0.0.0.0 & | |
fi | |
fi | |
} | |
start-front() { | |
if ( ! sudo -v ) ; then nosudo ; fi | |
if [ ! -e ~/pia ] ; then | |
echo "piactl: warning: frontend not installed" | |
elif [ "$(pid-front)" != "" ] ; then | |
echo "piactl: warning: frontend is already running ($(pid-front))" | |
else | |
cd ~/pia | |
sudo -Hu www-data npm run-script start & | |
fi | |
} | |
stop-back() { | |
if ( ! sudo -v ) ; then nosudo ; fi | |
if [ ! -e ~/pia-back ] ; then | |
echo "piactl: warning: backend not installed" | |
elif [ "$(pid-back)" = "" ] ; then | |
echo "piactl: warning: backend not running" | |
else | |
sudo -Hu www-data kill $(pid-back) | |
fi | |
} | |
stop-front() { | |
if ( ! sudo -v ) ; then nosudo ; fi | |
if [ ! -e ~/pia ] ; then | |
echo "piactl: warning: frontend not installed" | |
elif [ "$(pid-front)" = "" ] ; then | |
echo "piactl: warning: frontend not running" | |
else | |
sudo -Hu www-data kill $(pid-front) | |
fi | |
} | |
nosudo() { | |
echo "piactl: ERROR: you need root permissions but sudo failed" | |
exit 1 | |
} | |
install() { # install back|front|all HOST [VERSION] | |
if [[ $# < 2 || $# > 3 ]] ; then | |
usage "piactl install back|front|all HOST [VERSION]" | |
fi | |
if ( ! sudo -v ) ; then nosudo ; fi | |
case "$1" in | |
back) | |
install-back $2 $3 | |
;; | |
front) | |
install-front $2 $3 | |
;; | |
all) | |
install-back $2 $3 | |
install-front $2 $3 | |
;; | |
*) | |
usage "piactl install back|front|all HOST [VERSION]"; | |
esac | |
} | |
install-back() { # install-back HOST [VERSION] | |
if [ -e ~/pia-back ] ; then | |
echo "piactl: ERROR: ~/pia-back exists; remove or reinstall. Run 'piactl help' for details'" | |
exit 1 | |
fi | |
echo Installing pia-back into ~/pia-back... | |
local HOST=$1 | |
local VERSION=$2 | |
# install dependencies | |
sudo apt update && sudo apt install -y git ruby-dev sqlite3 build-essential zlib1g-dev postgresql libpq-dev libssl-dev | |
sudo gem install rails | |
# set postgres password | |
local PGPASS | |
read -p 'Enter new password for PostgreSQL user (role) "postgres": ' PGPASS | |
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$PGPASS';" | |
# the following alternative would be more secure as it leaves no traces in user's history | |
# echo '\password postgres' | sudo -u postgres psql postgres | |
# download latest pia-back, checking out specific version if provided | |
cd | |
git clone https://github.com/LINCnil/pia-back.git | |
cd pia-back | |
if [ "$VERSION" != "" ] ; then | |
git checkout $VERSION | |
fi | |
# remove Gemfile.lock and install latest bundler | |
rm Gemfile.lock | |
sudo gem install bundler | |
# alternative: install specific version of bundler | |
#sudo gem install bundler -v `grep -A 1 "BUNDLED WITH" Gemfile.lock|tail -1` | |
# fix Gemfile to refer to Ruby 2.5.1 | |
# as 2.6.5 is not yet available in Ubuntu repos | |
sed -i "s/^\(ruby '~> 2\).6.5'/\1.5.1'/" Gemfile | |
# fix Gemfile to fix Chrome 70 SSL curve compatibility issue | |
# ( https://github.com/puma/puma/issues/1670 ) | |
sed -i "s/^gem 'puma'.*/gem 'puma', github: 'eric-norcross\/puma', branch: 'chrome_70_ssl_curve_compatiblity'/" Gemfile | |
# configure and build pia-back | |
sed -e "s/username:/username: postgres/" -e "s/password:/password: $PGPASS/" config/database.example.yml > config/database.yml | |
bundle install | |
bundle install --deployment # needed to get the SSL fix in | |
local SECRET=`bin/rake secret` | |
sed -e "s/__SECRET_KEY_HERE__/$SECRET/" config/application.example.yml > config/application.yml | |
# allow requests to $HOST | |
cat >> config/application.rb << . | |
Rails.application.configure do | |
config.hosts << "$HOST" | |
end | |
. | |
# create and initialise database | |
bin/rake db:create | |
bin/rake db:migrate | |
# make log and tmp writeable to www-data | |
sudo chgrp -R www-data tmp log | |
sudo chmod -R g+w tmp log | |
# create uploads and data and make them writeable to www-data | |
sudo mkdir uploads data | |
sudo chgrp -R www-data uploads data | |
sudo chmod -R g+w uploads data | |
# final message | |
echo "Done. pia-back should now be installed. Start it with 'piactl start back', then go to http://$HOST:3000" | |
} | |
install-front() { # install-front HOST [VERSION] | |
if [ -e ~/pia ] ; then | |
echo "piactl: ERROR: ~/pia exists; remove or reinstall. Run 'piactl help' for details'" | |
exit 1 | |
fi | |
echo "Installing pia (frontend) into ~/pia..." | |
local HOST=$1 | |
local VERSION=$2 | |
# enable universe repository if not enabled -- needed for installing nodejs | |
if ! grep -q universe /etc/apt/sources.list ; then | |
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu bionic universe" | |
fi | |
# install dependencies | |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - | |
sudo echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list | |
sudo apt update && sudo apt install -y nodejs npm yarn | |
# download latest pia, checking out specific version if needed | |
cd | |
git clone https://github.com/LINCnil/pia.git | |
cd pia | |
if [ "$VERSION" != "" ] ; then | |
git checkout $VERSION | |
fi | |
# configure pia | |
yarn install | |
cp src/environments/environment.prod.ts.example src/environments/environment.prod.ts | |
sed -i -e "s/version: ''/version: '$VERSION'/g" src/environments/environment.prod.ts | |
# if you want to BUILD pia for use with other webservers, use the following command | |
# node_modules/@angular/cli/bin/ng build --prod --build-optimizer --sourcemaps | |
# remove version number from package.json (might throw errors otherwise) | |
sed -i -e 's/^ *"version": .*//' package.json | |
# create npm startup script | |
sed -i -e 's/"ng",/"node_modules\/@angular\/cli\/bin\/ng",/g' package.json | |
sed -i -e 's/"ng serve",/"ng serve --host 0.0.0.0 --public-host '$HOST'",/g' package.json | |
# final message | |
echo "Done. pia should now be installed. Start it with 'piactl start front', then go to http://$HOST:4200" | |
} | |
remove() { # remove back|front|all | |
if [ $# != 1 ] ; then | |
usage "piactl remove back|front|all" | |
fi | |
case "$1" in | |
back) | |
remove-back | |
;; | |
front) | |
remove-front | |
;; | |
all) | |
remove-back | |
remove-front | |
;; | |
*) | |
usage "piactl remove back|front|all"; | |
esac | |
} | |
remove-back() { | |
if ( ! sudo -v ) ; then nosudo ; fi | |
if [ -e ~/pia-back ] ; then | |
stop-back | |
killall ruby # otherwise 'rake secret' will fail when reinstalling | |
local SURE | |
read -p "Removing ~/pia-back including any possible customizations. Continue (y/N)? " SURE | |
case "$SURE" in | |
y|Y) | |
sudo rm -rf ~/pia-back | |
echo "Removed ~/pia-back. You may remove database, dependencies and certificates manually." | |
;; | |
*) | |
exit 2 | |
;; | |
esac | |
else | |
echo "piactl: warning: ~/pia-back not found, nothing to remove" | |
fi | |
} | |
remove-front() { | |
if ( ! sudo -v ) ; then nosudo ; fi | |
if [ -e ~/pia ] ; then | |
stop-front | |
local SURE | |
read -p "Removing ~/pia including any possible customizations. Continue (y/N)? " SURE | |
case "$SURE" in | |
y|Y) | |
sudo rm -rf ~/pia | |
echo "Removed ~/pia. You may remove dependencies and certificates manually." | |
;; | |
*) | |
exit 2 | |
;; | |
esac | |
else | |
echo "piactl: warning: ~/pia not found, nothing to remove" | |
fi | |
} | |
secure-back() { # secure-back HOST | |
if ( ! sudo -v ) ; then nosudo ; fi | |
local HOST=$1 | |
if [ ! -e ~/pia-back ] ; then | |
echo "piactl: warning: pia-back is not installed, skipping" | |
elif [ -e ~/pia-back/ssl ] ; then | |
echo "piactl: warning: pia-back is already secured, skipping" | |
else | |
certify $HOST | |
mkdir ~/pia-back/ssl | |
cd ~/pia-back/ssl | |
ln -s /etc/letsencrypt/live/$HOST/fullchain.pem server.crt | |
ln -s /etc/letsencrypt/live/$HOST/privkey.pem server.key | |
## reinstall puma to get ssl support | |
#local PUMA=$(puma --version|sed -e "s/puma version //") | |
#sudo gem uninstall puma | |
#sudo gem install puma -v "$PUMA" | |
echo "Done. Restart pia-back, then go to https://$HOST:3000" | |
fi | |
} | |
secure-front() { # secure-front HOST | |
if ( ! sudo -v ) ; then nosudo ; fi | |
local HOST=$1 | |
if [ ! -e ~/pia ] ; then | |
echo "piactl: warning: pia is not installed, skipping" | |
elif [ -e ~/pia/ssl ] ; then | |
echo "piactl: warning: pia is already secured, skipping" | |
else | |
certify $HOST | |
mkdir ~/pia/ssl | |
cd ~/pia/ssl | |
ln -s /etc/letsencrypt/live/$HOST/fullchain.pem server.crt | |
ln -s /etc/letsencrypt/live/$HOST/privkey.pem server.key | |
cd ~/pia | |
sed -i -e "s/ng serve --host/ng serve --ssl --port 443 --ssl-cert=ssl\/server.crt --ssl-key=ssl\/server.key --host/" package.json | |
sed -i -e "s/--public-host [^ \"]*/--public-host $HOST/" package.json | |
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/node | |
echo "Done. Restart pia-front, then go to https://$HOST" | |
fi | |
} | |
certify() { # certify HOST [--prod] | |
if ( ! sudo -v ) ; then nosudo ; fi | |
local HOST=$1 | |
local PROD=$2 | |
local TYPE="--test-cert" | |
if [ "$PROD" = "--prod" ] ; then TYPE="" ; fi | |
if ! dpkg -l certbot >/dev/null 2>&1 ; then | |
# install certbot if not already installed | |
sudo apt install certbot | |
fi | |
if [[ (! -e /etc/letsencrypt/live/$HOST) || ("$PROD" = "--prod") ]] ; then | |
# request new certs if not yet requested or requested for production | |
sudo certbot $TYPE certonly --standalone -d $HOST | |
sudo chmod 755 /etc/letsencrypt/live /etc/letsencrypt/archive | |
fi | |
} | |
resetcap() { # resetcap | |
if ( ! sudo -v ) ; then nosudo ; fi | |
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/node | |
} | |
main "$@" |
The problem with @tresrob is fixed.
Hello,
First of all thank you very much for this script.
am looking to run on prod (it is on dev), can someone tell me which file should i modify ?
Thank you
@snelhard piactl allows you to install a specific version of PIA via back|front|all HOST VERSION
but in order to create a proper production environment you'll probably have to set up webserver etc manually anyway. Please refer to official PIA documentation for details.
Thank you @ppmotskula , i made it by crossing your script and the PIA Doc !
Automation of piactl using crontab not working on ubuntu 20.04. I've created a script under my user, when I run it under ssh it works perfect but when I run under crontab under my user I get my output but the ip doesn't change.
Here is my ssh output:
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-54-generic x86_64)
- Documentation: https://help.ubuntu.com
- Management: https://landscape.canonical.com
- Support: https://ubuntu.com/advantage
1 update can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable
Your Hardware Enablement Stack (HWE) is supported until April 2025.
Last login: Wed Nov 25 18:37:13 2020 from 192.168.2.27
----alias pia and pias point to enable and disable script pasted below------
----xxx is my ip address-----
J@T:$ pia wo 25 nov 2020 18:48:06 CET - old ip: xxx$ pias wo 25 nov 2020 18:48:25 CET - old ip: 89.187.174.197
wo 25 nov 2020 18:48:07 CET - getting new ip...
wo 25 nov 2020 18:48:14 CET - new ip: 89.187.174.197
done!
J@T:
wo 25 nov 2020 18:48:25 CET - quitting openvpn service...
wo 25 nov 2020 18:48:28 CET - new ip: xxx
done!
-----here is the script------
J@T:~$ cat /home/J/Headless/PIA.sh #!/bin/bash
echo
sleep 1
echo $(date) - getting new ip...
piactl background enable
sleep 3
piactl connect
sleep 3
echo
echo done!
Here is the cron output.
J@T:$ cat /home/J/Desktop/pia.txt wo 25 nov 2020 18:30:01 CET - old ip: xxx$
wo 25 nov 2020 18:30:02 CET - getting new ip...
wo 25 nov 2020 18:30:08 CET - new ip: xxx
done!
wo 25 nov 2020 18:45:01 CET - old ip: xxx
wo 25 nov 2020 18:45:01 CET - quitting openvpn service...
wo 25 nov 2020 18:45:04 CET - new ip: xxx
done!
J@T:
I've also tried to run using sudo crontab -e, same effect, unsuccessful.
The problem for @tresrob is that the server is on a private network 192.168.X.X
We must forward the port 3000 from the public IP address to the private IP address.