Skip to content

Instantly share code, notes, and snippets.

@okomestudio
Created February 18, 2020 21:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okomestudio/35d1af1b5cab08703d8d78ad80ea2c41 to your computer and use it in GitHub Desktop.
Save okomestudio/35d1af1b5cab08703d8d78ad80ea2c41 to your computer and use it in GitHub Desktop.
Shutdown script for Netgear ReadyNAS (RN312)
#!/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