Created
April 30, 2020 05:23
-
-
Save bcalik/e180a15325ce6429018177873308a66b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
/** | |
* v1.0 - 2020-04-30 06:55:00 | |
* Usage: php install-pritunl <PRITUNL_PROFILE_URL> | |
* Profile URL must start with "pritunl:// | |
* | |
* @param array $argv | |
* @return void | |
*/ | |
function init($argv) { | |
validate($argv); | |
$profileUrl = $argv[1]; | |
installPritunlClient(); | |
importPritunlProfile($profileUrl); | |
$profileId = getPritunlProfileId(); | |
startPritunl($profileId); | |
addPritunlToCron($profileId); | |
echo 'Done!'.PHP_EOL; | |
} | |
/** | |
* Validate inputs, permissions, and environment. | |
* @param array $argv | |
* @return void | |
*/ | |
function validate($argv) | |
{ | |
exec('lsb_release -a 2>&1', $output, $returnVal); | |
if ($returnVal !== 0 | |
|| count($output) < 5 | |
|| (strpos($output[1], 'Ubuntu') === false) | |
|| (strpos($output[4], 'bionic') === false) | |
) { | |
echo 'Error: Only run in Ubuntu 18 Bionic.'.PHP_EOL; | |
exit(1); | |
} | |
if (posix_getuid() !== 0){ | |
echo 'Error: Run this using sudo.'.PHP_EOL; | |
exit(1); | |
} | |
if (!isset($argv[1]) || count($argv) !== 2) { | |
echo 'Usage: php macellan-bootstrap <PRITUNL_PROFILE_URL>'.PHP_EOL; | |
exit(1); | |
} | |
$profileUrl = $argv[1]; | |
if (!$profileUrl || substr($profileUrl, 0, 10) !== 'pritunl://') { | |
echo 'Profile URL must start with "pritunl://"'.PHP_EOL; | |
exit(1); | |
} | |
} | |
/** | |
* @return void | |
*/ | |
function installPritunlClient() | |
{ | |
// install necessary packages | |
$cmd = 'apt install gnupg2 -y'; | |
exec($cmd.' 1>&2', $output, $returnVal); | |
if ($returnVal !== 0) exit($returnVal); | |
// append repo | |
$append = 'deb https://repo.pritunl.com/stable/apt bionic main'; | |
$file = '/etc/apt/sources.list.d/pritunl.list'; | |
appendToFile($append, $file); | |
$cmd = 'apt-key adv --keyserver hkp://keyserver.ubuntu.com --recv 7568D9BB55FF9E5287D586017AE645C0CF8E292A'; | |
exec($cmd.' 1>&2', $output, $returnVal); | |
if ($returnVal !== 0) exit($returnVal); | |
$cmd = 'apt update'; | |
exec($cmd.' 1>&2', $output, $returnVal); | |
if ($returnVal !== 0) exit($returnVal); | |
$cmd = 'apt install pritunl-client'; | |
exec($cmd.' 1>&2', $output, $returnVal); | |
if ($returnVal !== 0) exit($returnVal); | |
} | |
/** | |
* @param string $url | |
* @return void | |
*/ | |
function importPritunlProfile($url) | |
{ | |
$cmd = 'pritunl-client import '.escapeshellarg($url); | |
exec($cmd.' 1>&2', $output, $returnVal); | |
if ($returnVal !== 0) exit($returnVal); | |
} | |
/** | |
* Get Pritunl Profile ID via `pritunl-client list` command. | |
* @return string | |
*/ | |
function getPritunlProfileId() | |
{ | |
exec('pritunl-client list 2>&1', $output, $returnVal); | |
if ($returnVal !== 0) { | |
printError('pritunl-client may not be installed.', $output); | |
exit($returnVal); | |
} | |
/** | |
* Output must be like: | |
* | |
* PROFILE_ID ENABLED STATE NAME | |
* 8e872e506d8540fe96d196b73662835f false ended foobar | |
*/ | |
if (count($output) < 2) { | |
printError('Pritunl profile is not imported.', $output); | |
exit(1); | |
} | |
$profileId = preg_split('/\s+/', $output[1], -1, PREG_SPLIT_NO_EMPTY)[0]; | |
if (!$profileId) { | |
printError('Could not get profile ID.', $output); | |
exit(1); | |
} | |
return $profileId; | |
} | |
/** | |
* @param string $profileId | |
*/ | |
function startPritunl($profileId) | |
{ | |
$cmd = 'pritunl-client start '.$profileId; | |
exec($cmd.' 1>&2', $output, $returnVal); | |
if ($returnVal !== 0) exit($returnVal); | |
} | |
/** | |
* This step is important. | |
* It will keep pritunl-client connected to the server in case of failure. | |
* @param string $profileId | |
*/ | |
function addPritunlToCron($profileId) | |
{ | |
$cmd = 'pritunl-client start '.$profileId; | |
// append cron | |
$append = '* * * * * root '.$cmd; | |
$file = '/etc/crontab'; | |
appendToFile($append, $file); | |
} | |
/** | |
* Print error | |
* @param string $message | |
* @param array $output | |
* @return void | |
*/ | |
function printError(string $message, array $output = []) | |
{ | |
echo "Error: ".$message.PHP_EOL; | |
if (!empty($output)) { | |
echo "==OUTPUT==".PHP_EOL; | |
var_dump($output); | |
echo "==OUTPUT==".PHP_EOL; | |
} | |
} | |
/** | |
* Append string to file if its not already exist. | |
* @param string $string | |
* @param string $file_path | |
* @return void | |
*/ | |
function appendToFile($string, $file_path) | |
{ | |
$contents = file_get_contents($file_path) ?: ''; | |
if (strpos($contents, $string) === false) { | |
$fh = fopen($file_path, 'a') or die("Can't open file: ".$file_path); | |
$stringData = $string . "\n"; | |
fwrite($fh, $stringData); | |
fclose($fh); | |
} | |
} | |
init($argv); | |
exit(0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment