Created
February 18, 2020 21:12
-
-
Save okomestudio/35d1af1b5cab08703d8d78ad80ea2c41 to your computer and use it in GitHub Desktop.
Shutdown script for Netgear ReadyNAS (RN312)
This file contains hidden or 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 bash | |
set -e | |
function usage() { | |
cat <<USAGE >&2 | |
Usage: ${0##*/} [OPTION] [host] | |
Shut down the network attached server (NAS). This script has been | |
tested on Netgear ReadyNAS 312 (RN312). | |
Instead of supplying as arguments described below, the NAS parameters | |
can also be provided via environment variable; see in the parentheses. | |
Arguments: | |
host Host name or IP address of the NAS (NAS_HOST) | |
-u Username of the NAS account (NAS_USER) | |
-p Password of the NAS account (NAS_PASSWORD) | |
-q SSH port of the NAS over which rsync runs (NAS_PORT, default: 22) | |
Note: | |
This script depends on the following command(s) to be available: | |
- curl | |
- nc | |
USAGE | |
exit "${1:-1}" | |
} | |
function error() { | |
>&2 echo "ERROR: $1" | |
exit "${2:-1}" | |
} | |
function log() { | |
logger -s -t backup "$1" | |
} | |
# Check if the NAS is alive | |
function nas_is_alive() { | |
local host=$1 | |
local port=$2 | |
if nc -w 5 -z "${host}" "${port}"; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
# Get a CSRF token from the NAS | |
function get_token() { | |
local host=$1 | |
local user=$2 | |
local password=$3 | |
local tf | |
local token | |
tf=$(mktemp) | |
curl -u "$user:$password" "http://$host/admin/csrf.html" > "$tf" | |
token=$(cat "$tf" | grep csrfInsert | cut -d'"' -f 4) | |
rm "$tf" | |
echo "$token" | |
} | |
readonly shutdown_request_body=$(cat <<-BODY | |
<?xml version="1.0" encoding="UTF-8"?> | |
<xs:nml xmlns:xs="http://www.netgear.com/protocol/transaction/NMLSchema-0.9" | |
xmlns="urn:netgear:nas:readynasd" | |
src="dpv_1445852944000" | |
dst="nas"> | |
<xs:transaction id="njl_id_2269"> | |
<xs:custom id="njl_id_2268" | |
name="Halt" | |
resource-id="Shutdown" | |
resource-type="System"> | |
<Shutdown halt="true" fsck="false"/> | |
</xs:custom> | |
</xs:transaction> | |
</xs:nml> | |
BODY | |
) | |
# Issue a shutdown command to the NAS | |
function issue_shutdown() { | |
local host=$1 | |
local user=$2 | |
local password=$3 | |
local token=$4 | |
curl -u "$user:$password" \ | |
--retry 10 \ | |
-k "http://${host}/dbbroker" \ | |
-H "Content-Type: application/x-www-form-urlencoded;" \ | |
-H "X-Requested-With: XMLHttpRequest" \ | |
-H "csrfpid: ${token}" \ | |
--data "$shutdown_request_body" | |
} | |
# Shut down the NAS | |
function shut_down_nas() { | |
local host=$1 | |
local port=$2 | |
local user=$3 | |
local password=$4 | |
local token | |
while nas_is_alive "$host" "$port" ; do | |
token=$(get_token "$host" "$user" "$password") | |
issue_shutdown "$host" "$user" "$password" "$token" | |
sleep 30 | |
done | |
} | |
function main() { | |
local host=${NAS_HOST} | |
local user=${NAS_USER} | |
local password=${NAS_PASSWORD} | |
local port=${NAS_PORT:-22} | |
shut_down_nas "$host" "$port" "$user" "$password" | |
} | |
while getopts "hp:q:u:" opt; do | |
case $opt in | |
h|\?) | |
if [ "$opt" = "h" ]; then usage 0; else usage; fi | |
;; | |
p) | |
NAS_PASSWORD=$OPTARG | |
;; | |
q) | |
NAS_PORT=$OPTARG | |
;; | |
u) | |
NAS_USER=$OPTARG | |
;; | |
esac | |
done | |
shift $((OPTIND - 1)) | |
NAS_HOST=${1:-$NAS_HOST} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment