From e4c9e975fb09b2625b872828bc5554787d2f697d Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Thu, 19 Mar 2020 02:11:22 -0500 Subject: [PATCH] add Unraid.net plugin file --- Unraid.net.plg | 813 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 813 insertions(+) create mode 100644 Unraid.net.plg diff --git a/Unraid.net.plg b/Unraid.net.plg new file mode 100644 index 000000000..097f93305 --- /dev/null +++ b/Unraid.net.plg @@ -0,0 +1,813 @@ + + + + + + + + + +]> + + + + +##&name; + +###&version; +- initial release + + + + + +if [ -e /etc/rc.d/rc.unraid-api ]; then + /etc/rc.d/rc.unraid-api stop + rm -f /etc/rc.d/rc.unraid-api + rm -f /usr/local/emhttp/plugins/dynamix/Unraid.net.page + rm -f /usr/local/emhttp/plugins/dynamix/include/UpdateFlashBackup.php + rm -rf /boot/config/plugins/Unraid.net + mv -f /usr/local/emhttp/plugins/dynamix/include/UpdateDNS.php- /usr/local/emhttp/plugins/dynamix/include/UpdateDNS.php +fi + + + + + +&graphql-api; + + + +&plugins; + + + + +/var/log/${i}.log 2>&1 & + done + exit 0 + fi +} +stop() { + for i in ${node_apps[@]}; do + pkill ${i} + done +} +reload() { + kill -SIGHUP $(ps -C gql-supervisor --no-headers -o pid) +} +logs() { + if [ -f "/var/log/graphql-api.log" ]; then + tail -f /var/log/graphql-api.log + else + echo "Process hasn't been started yet, try the \"start\" command." + fi +} +install() { + mkdir -p /usr/local/node + for i in ${downloads[@]}; do + tar -C /usr/local/node -xf /boot/config/plugins/Unraid.net/unraid-${i}.tgz + rm -rf /usr/local/node/${i} + mv /usr/local/node/package /usr/local/node/${i} + done + start +} +uninstall() { + stop + for i in ${node_apps[@]}; do + rm -rf /usr/local/node/${i} + done + rm -rf /var/run/graphql-api.sock +} +case "$1" in +'status') + status + ;; +'version') + version + ;; +'start') + start + ;; +'stop') + stop + ;; +'reload') + reload + ;; +'logs') + logs + ;; +'install') + install + ;; +'uninstall') + uninstall + ;; +*) + echo "usage $0 status|start|stop|reload|logs|install|uninstall" +esac +]]> + + + + + + +**Unraid.net** + +Unraid.net provides access to a set web-based services: + +* Server status such as online/offline, storage used/available, etc. +* Links for local and remote access to your server webGUI. +* Backup and Restore of your USB Flash boot device. +* much more to come + +A server is registered using your Unraid Community Forum credentials. Registered servers appear under the My Servers forum sub-menu. + +This is work in progress. Use this for testing purposes only! + + + + + + + "", + "wanaccess" => "no", + "wanport" => "443" + ]; +} +if (empty($remote['wanport'])) { + $remote['wanport'] = 443; +} + +$hasCert = file_exists('/boot/config/ssl/certs/certificate_bundle.pem'); +$isRegistered = !empty($remote['apikey']); +$boolWebUIAuth = $isRegistered || file_exists('/etc/nginx/htpasswd'); + +$isActivated = false; +$isUptodate = false; +if ($isRegistered) { + exec("/usr/bin/php -f $docroot/webGui/include/UpdateFlashBackup.php status", $output, $retval); + $isActivated = ($retval == 0); + if ($isActivated) $isUptodate = empty($output); +} +?> + +
+ +Unraid.net Status: +: Unregistered + +Unraid.net Username: +: + +Unraid.net Password: +: + + +Unraid.net Status: +: Registered + + + +Allow Remote Access: +: + +
+WAN Port: +: Disabled until your root user account is password-protected + +> WAN Port is the external TCP port number setup on your router to NAT/Port Forward traffic from the internet to this +> Unraid server SSL port for secure web traffic. +
+ + + + +  +: + +
+ +
+ +Flash backup: +: Not activated + +  +: + +> Click Activate to set up a local git repo for your local USB Flash boot device and connect to a dedicated remote on unraid.net tied tothis server. + + +Flash backup: +: Activated: Not up-to-dateUp-to-date + + +  +: + +> The Not Up-to-date status indicates there are local files which are changed vs. the remote on unraid.net. + +> Click Update to push changes to the remote. + +> Click Changes to see what has changed. + + +  +: + +> The Up-to-date status indicates your local configuration matches that stored on the unraid.net remote. + + +  +: + +> Click Deactivate to pause communication with your remote on unraid.net. + +> Click Reinitialize to erase all change history in both local and unraid.net remote. + + +
+ +]]> +
+
+ + + + +mv -f /usr/local/emhttp/plugins/dynamix/include/UpdateDNS.php /usr/local/emhttp/plugins/dynamix/include/UpdateDNS.php- + + + + + + "", + "wanaccess" => "no", + "wanport" => "443" + ]; +} +if (empty($remote['wanport'])) { + $remote['wanport'] = 443; +} +if ($cli) { + $remoteaccess = $remote['wanaccess']; + $externalport = $remote['wanport']; + $username = ''; + $password = ''; +} else { + $remoteaccess = $_POST['remoteaccess']; + $externalport = $_POST['externalport']; + $username = $_POST['username']; + $password = $_POST['password']; +} +$isRegistered = !empty($remote['apikey']); + +// protocol, hostname, internalport +list($protocol, $hostname, $internalport) = explode(":", rtrim(file_get_contents("/var/run/nginx.origin"))); +$hostname = substr($hostname, 2); + +if (!$isRegistered && empty($username) && !preg_match('/.*\.unraid\.net$/', $hostname)) { + response_complete(406, '{"error":"Nothing to do"}'); +} + +// keyfile +$var = parse_ini_file('/var/local/emhttp/var.ini'); +$keyfile = @file_get_contents($var['regFILE']); +if ($keyfile === false) { + response_complete(406, '{"error":"Registration key required"}'); +} +$keyfile = @base64_encode($keyfile); + +// internalip +extract(parse_ini_file('/var/local/emhttp/network.ini',true)); +$internalip = $eth0['IPADDR:0']; + +$ch = curl_init('https://keys.lime-technology.com/account/server/register'); +curl_setopt($ch, CURLOPT_POST, 1); + +if (!$isRegistered && empty($username)) { + curl_setopt($ch, CURLOPT_POSTFIELDS, [ + 'internalip' => $internalip, + 'keyfile' => $keyfile + ]); +} else { + // servername, servercomment + $servername = $var['NAME']; + $servercomment = $var['COMMENT']; + if (empty($username)) { + curl_setopt($ch, CURLOPT_POSTFIELDS, [ + 'servername' => $servername, + 'servercomment' => $servercomment, + 'protocol' => $protocol, + 'hostname' => $hostname, + 'internalport' => $internalport, + 'internalip' => $internalip, + 'remoteaccess' => $remoteaccess, + 'externalport' => $externalport, + 'keyfile' => $keyfile + ]); + } else { + curl_setopt($ch, CURLOPT_POSTFIELDS, [ + 'servername' => $servername, + 'servercomment' => $servercomment, + 'protocol' => $protocol, + 'hostname' => $hostname, + 'internalport' => $internalport, + 'internalip' => $internalip, + 'remoteaccess' => $remoteaccess, + 'externalport' => $externalport, + 'username' => $username, + 'password' => $password, + 'keyfile' => $keyfile + ]); + } +} + +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +$result = curl_exec($ch); +$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); +$error = curl_error($ch); +curl_close($ch); + +if ($result === false) { + response_complete(500, '{"error":"'.$error.'"}'); +} + +response_complete($httpcode, $result, 'success'); +?> +]]> + + + + + + + 1) $command = $argv[1]; +} else { + $command = $_POST['command']; +} +if (empty($command)) $command='init'; + +// keyfile +$var = parse_ini_file("/var/local/emhttp/var.ini"); +$keyfile = @file_get_contents($var['regFILE']); +if ($keyfile === false) { + response_complete(406, '{"error":"Registration key required"}'); +} +$keyfile = @base64_encode($keyfile); + +// check if activated +if ($command != 'activate') { + exec('git -C /boot config --get remote.origin.url', $config_output, $return_var); + if (($return_var != 0) || (strpos($config_output[0],'backup.unraid.net') === false)) { + response_complete(406, '{"error":"Not activated"}'); + } +} + +// if deactivate command, just remove our origin +if ($command == 'deactivate') { + exec('git --git-dir /boot/.git remote remove origin &>/dev/null'); + response_complete(200, '{}'); +} + +// build a list of sha256 hashes of the bzfiles +$bzfilehashes = []; +$allbzfiles = ['bzimage','bzfirmware','bzmodules','bzroot','bzroot-gui']; +foreach ($allbzfiles as $bzfile) { + $sha256 = trim(@file_get_contents("/boot/$bzfile.sha256")); + if (strlen($sha256) != 64) { + response_complete(406, '{"error":"Invalid or missing '.$bzfile.'.sha256 file"}'); + } + $bzfilehashes[] = $sha256; +} + +$ch = curl_init('https://keys.lime-technology.com/backup/flash/activate'); +curl_setopt($ch, CURLOPT_POST, 1); +curl_setopt($ch, CURLOPT_POSTFIELDS, [ + 'keyfile' => $keyfile, + 'version' => $var['version'], + 'bzfiles' => implode(',', $bzfilehashes) +]); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +$result = curl_exec($ch); +$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); +$error = curl_error($ch); +curl_close($ch); + +if ($result === false) { + response_complete(500, '{"error":"'.$error.'"}'); +} + +$json = json_decode($result, true); +if (empty($json) || empty($json['ssh_privkey'])) { + response_complete(406, $result); +} + +// save the public and private keys +if (!file_exists('/root/.ssh')) { + mkdir('/root/.ssh', 0700); +} +file_put_contents('/root/.ssh/unraidbackup_id_ed25519', $json['ssh_privkey']); +chmod('/root/.ssh/unraidbackup_id_ed25519', 0600); +file_put_contents('/root/.ssh/unraidbackup_id_ed25519.pub', $json['ssh_pubkey']); +chmod('/root/.ssh/unraidbackup_id_ed25519.pub', 0644); + +// add configuration to use our keys +if (!file_exists('/root/.ssh/config') || strpos(file_get_contents('/root/.ssh/config'),'Host backup.unraid.net') === false) { + file_put_contents('/root/.ssh/config', 'Host backup.unraid.net +IdentityFile ~/.ssh/unraidbackup_id_ed25519 +IdentitiesOnly yes +', FILE_APPEND); + chmod('/root/.ssh/config', 0644); +} + +// add our server as a known host +if (!file_exists('/root/.ssh/known_hosts') || strpos(file_get_contents('/root/.ssh/known_hosts'),'backup.unraid.net,54.70.72.154') === false) { + file_put_contents('/root/.ssh/known_hosts', 'backup.unraid.net,54.70.72.154 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKrKXKQwPZTY25MoveIw7fZ3IoZvvffnItrx6q7nkNriDMr2WAsoxu0DrU2QrSLH5zFF1ibv4tChS1hOpiYObiI=', FILE_APPEND); + chmod('/root/.ssh/known_hosts', 0644); +} + +// blow away existing repo if reinit command +if ($command == 'reinit') { + exec('rm -rf /boot/.git'); +} + +// ensure git repo is setup on the flash drive +if (!file_exists('/boot/.git/info/exclude')) { + exec('git init /boot &>/dev/null'); +} + +// setup git ignore for files we dont need in the flash backup +if (strpos(file_get_contents('/boot/.git/info/exclude'),'Unraid') === false) { + file_put_contents('/boot/.git/info/exclude', '# Unraid OS Flash Backup + +# Blacklist everything +/* + +# Whitelist selected root files +!*.sha256 +!changes.txt +!license.txt + +!EFI*/ +EFI*/boot/* +!EFI*/boot/syslinux.cfg + +!syslinux/ +syslinux/* +!syslinux/syslinux.cfg +!syslinux/syslinux.cfg- + +# Whitelist entire config directory +!config/ +# except for selected files +config/drift +config/plugins/unRAIDServer.plg +config/random-seed +config/shadow +config/smbpasswd +config/wireguard/privatekey +'); +} + +// ensure git user is configured +exec('git --git-dir /boot/.git config user.email \'gitbot@unraid.net\' &>/dev/null'); +exec('git --git-dir /boot/.git config user.name \'gitbot\' &>/dev/null'); + +// ensure upstream git server is configured and in-sync +exec('git --git-dir /boot/.git remote add -f -t master -m master origin git@backup.unraid.net:~/flash.git &>/dev/null'); +if ($command != 'reinit') { + exec('git --git-dir /boot/.git reset origin/master &>/dev/null'); + exec('git --git-dir /boot/.git checkout -B master origin/master &>/dev/null'); +} + +// establish status +exec('git -C /boot status --porcelain', $status_output, $return_var); +if ($return_var != 0) { + response_complete(406, '{"error":"'.${status_output[0]}.'"}'); +} + +if ($command == 'status') { + $data = implode("\n", $status_output); + response_complete($httpcode, '{"data":"'.$data.'"}', $data); +} + +if (($command == 'update') || ($command == 'reinit')) { + // push changes upstream + if (!empty($status_output)) { + exec('git -C /boot add -A &>/dev/null'); + if ($command == 'reinit') { + exec('git -C /boot commit -m \'Initial commit\' &>/dev/null'); + exec('git -C /boot push --force origin master &>/dev/null'); + } else { + exec('git -C /boot commit -m \'Config change\' &>/dev/null'); + exec('git -C /boot push &>/dev/null'); + } + } +} + +response_complete($httpcode, '{}'); +?> +]]> + + + + + + +echo "/etc/rc.d/rc.unraid-api install" | at -M now + 1 min + + + +