Nagios Custom Plug-in(https authentication) not working as expected - plugins

I am writing a plugin to check authentication to a https site and then search for a text in the response html,body to confirm successful login. I have created the following plugin
#!/bin/bash
add_uri='--no-check-certificate https://'
end_uri='/'
result=$(wget -O- $add_uri$1$end_uri --post-data=$2)
flag=`echo $result|awk '{print match($0,"QC Domain")}'`;
echo $flag
echo "Nagios refreshes properly1"
if [[ $flag -gt 0 ]] ; then
echo 'ALL SEEMS FINE!!'
exit 0
else
echo 'Some Problem'
exit 2
fi;
When I execute this plugin directly from command line
./check_nhttps <url here> '<very long post data with credential information>'
The plugin works as expected(For both + & - test cases) and there seems to be no issues.
But when the plugin runs from Nagios,
check_command check_nhttps! <url here> '<very long post data with credential information>'
It always shows critical error(Prints else condition text "Some Problem" too).
P.S : Tried sending the post data with double quotes also.
Please help!!!

I'd think its very probable that your post data contains some characters that confuse nagios, maybe a space, or even a !. Better put the post data into some file and use --post-file. Also, you might insert echo "$2" > /tmp/this_is_my_post_data_when_executed_by_nagios into your script and check if the post data is ok.

Related

I am trying to create a tpm2-based auto unlock sh script, but the script fails with file not found

I am trying to create a TPM-based unlock script using tpm2-tools with instructions from Tevora Secure boot tpm2. I have set up the key, loaded it with cryptsetup luksAddKey secret.bin, then tested it using tpm2_unlock -c 0x81000000 --auth pci:sha1:0,2,3,7 and returns the value of secret.bin. For extra measures, to make sure it works, I loaded secret.bin into "/etc/crypttab", ran # update-initramfs -u -k all, and rebooted. Upon reboot, the system unlocked.
I copied over the following code into "/etc/initramfs-tools/hooks/tpm2"
#!/bin/sh -e
if [ "$1" = "prereqs" ]; then exit 0; fi
. /usr/share/initramfs-tools/hook-functions
copy_exec /usr/local/bin/tpm2_unseal
copy_exec /usr/local/lib/libtss2-tcti-device.so
I appended my etc/crypttab from cryptname UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx none luks to cryptname UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx none luks,keyscript=/usr/local/bin/passphrase-from-tpm
I rewrote the following script because the tpm2-tools command was outdated, edited in the new command, and stored it in /usr/local/bin/passphrase-from-tpm:
#!/bin/sh
set -e
echo "Unlocking via TPM" >&2
export TPM2TOOLS_TCTI="device:/dev/tpm0"
/usr/local/bin/tpm2_unseal -c 0x81000000 --auth pcr:sha1:0,2,3,7
if [ $? -eq 0 ]; then
exit
fi
/lib/cryptsetup/askpass "Unlocking the disk fallback $CRYPTTAB_SOURCE ($CRYPTTAB_NAME)\nEnter passphrase: "
I ran # update-initramfs -u -k all then rebooted. In reboot, I get the following error: /lib/cryptsetup/scripts/passphrase-from-tpm: line 5: /usr/local/bin/tpm2_unseal: not found
I have tried many times to edit passphrase-from-tpm unsuccessfully, including:
Moving both passphrase-from-tpm into "/boot/efi/EFI/BOOT/" and referencing crypttab to that file
Modifying passphrase-from-tpm to use a relative file path to tpm_unseal
Before I figured out how to create a backup linux boot using:
objcopy \
--add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
--add-section .cmdline=cmdline.txt --change-section-vma .cmdline=0x30000 \
--add-section .linux="/boot/vmlinuz" --change-section-vma .linux=0x40000 \
--add-section .initrd="/boot/initrd.img" --change-section-vma .initrd=0x3000000 \
/usr/lib/systemd/boot/efi/linuxx64.efi.stub /boot/EFI/BOOT/BOOT_RECX64.EFI
I would be locked out of the system completely because of the error and had to reinstall Ubuntu about 40 times. I have suffered a lot and want to quit but I am too stubborn to throw in the flag.
just copy tpm2_unseal to /usr/local/bin/
I'm trying to make a working setup following basically those instructions, plus a few others I have found. While not working 100% yet, check that both /etc/initramfs-tools/hooks/tpm2 and /usr/local/bin/passphrase-from-tpm are marked executable (sudo chmod ug+x $filename).
After making the initramfs, you can run the following to ensure that the TPM related files are actually in the image. Replace the path in the filename by whatever update-initramfs said it was generating:
$ lsinitramfs /boot/initrd.img-5.0.0-37-generic | egrep "(tpm|libtss)"
lib/cryptsetup/scripts/passphrase-from-tpm
lib/modules/5.0.0-37-generic/kernel/crypto/asymmetric_keys/tpm_key_parser.ko
lib/modules/5.0.0-37-generic/kernel/crypto/asymmetric_keys/asym_tpm.ko
lib/udev/rules.d/tpm-udev.rules
usr/local/lib/libtss2-sys.so.0
usr/local/lib/libtss2-mu.so.0
usr/local/lib/libtss2-sys.so.0.0.0
usr/local/lib/libtss2-tcti-device.so
usr/local/lib/libtss2-tcti-device.so.0
usr/local/lib/libtss2-tcti-device.so.0.0.0
usr/local/lib/libtss2-mu.so.0.0.0
usr/local/bin/tpm2_unseal
Additionally, I have modified /usr/local/bin/passphrase-from-tpm to the following:
#!/bin/sh
TPM_DEVICE=/dev/tpm0
TPM_REGISTER=0x81000001
TPM_SEAL_POLICY=sha256:0,2,4,7
export TPM2TOOLS_TCTI="device:$TPM_DEVICE"
if [ "$CRYPTTAB_TRIED" -eq 0 ]; then
echo "Unlocking via TPM" >&2
/usr/local/bin/tpm2_unseal -H $TPM_REGISTER -L $TPM_SEAL_POLICY
UNSEAL_STATUS=$?
echo "Unseal status $UNSEAL_STATUS" >&2
if [ $UNSEAL_STATUS -eq 0 ]; then
exit
fi
else
echo "TPM unlocking previously failed for $CRYPTTAB_SOURCE ($CRYPTTAB_NAME)" >&2
/lib/cryptsetup/askpass "Enter passphrase for $CRYPTTAB_SOURCE ($CRYPTTAB_NAME): "
fi
Note that the command line options to tpm2_unseal are for the 3.x versions of tpm2-tools. If you're using another version, you might need to update the options.
I pulled out various bits into variables at the top of the file. Modify TPM_REGISTER and TPM_SEAL_POLICY to match how you created the TPM object. set -e was removed since if any command failed, the whole script would exit, preventing the askpass fallback from ever running if tpm2_unseal failed.
Additionally, I noticed that if the script fails for some reason, systemd will attempt to run it again. If the secret in the TPM doesn't match the LUKS key, this will render the system unbootable, since the unseal succeeds, but unlocking fails, and systemd will run the script again.
Looking at the man page for crypttab, I discovered that one of the environment variables provided to the keyscript is CRYPTTAB_TRIED which is the number of tries it has attempted to unlock the volume. If CRYPTTAB_TRIED is 0, it'll attempt to use the TPM, as shown by this test (Running as non-root, so accessing the TPM device fails):
$ export CRYPTTAB_SOURCE=some_device
$ export CRYPTTAB_NAME=some_device_name
$ export CRYPTTAB_TRIED=0
$ ./passphrase-from-tpm
Unlocking via TPM
ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed to open device file /dev/tpm0: Permission denied
ERROR: tcti init allocation routine failed for library: "device" options: "/dev/tpm0"
ERROR: Could not load tcti, got: "device"
Unseal status 1
When it tries running the script again, CRYPTTAB_TRIED will be greater than 0, making it display the password prompt instead:
$ export CRYPTTAB_TRIED=1
$ ./passphrase-from-tpm
TPM unlocking previously failed for some_device (some_device_name)
Enter passphrase for some_device (some_device_name):
Hopefully this is still of use to you, and helpful to anyone else trying to get the house of cards that is disk encryption with a TPM on Linux working.

REST service health check on automatic deployment

I'm using the AWS CodeDeploy platform for automatic deployment of my REST services. The deployment script got a lot of steps that copy/configure/do other staff. If any of the steps fails - the entire deployment fails for this server and I got a clear notification about it. So, the last step I need is a health check - a validation that configuration was appropriate and all is up and running.
Of cause, I can make a couple curl POSTs, parse their results and use some extracted values within more curl POSTs to get some sanity coverage, but all this parsing sounds like a wheel invention.
Is there any convinient testing framework/tool that can be easily "packed" and invoked in scripts without installing a huge testing siutes on each of my production servers?
Given that you're doing REST you probably can rely on the status codes instead of parsing the body. If you get a code that's not in 2xx, then something is wrong.
If you want a more elaborate check you could add a special endpoint that does some DB queries and maybe sends some harmless queries to its integrations.
And the most complicated option would be to implement a smart post-deployment steps that follow some workflow procedure. You'd need either to use an elaborate bash-scripting, or use more advanced programming languages and frameworks (like RestAssured in Java or RestClient in Groovy).
Don't forget to introduce a loop with some timeout that does a health check since your first request may be sent too early while the app is still being deployed.
Here is an example of simple bash-script that checks the status and the version of the app:
#!/usr/bin/env bash
# Helps to define whether application deployment was successful by checking
# connection to HTTP resource. If the page is loaded and the response is 200
# or 201, then the script finishes successfully. In case connection refused
# is or Gateway Timeout (503) the script is trying to connect again within
# timeout period. Otherwise script finishes with fail.
# Needs required parameter url to application and optional parameters timeout
# (by default equals to 180) and artifact version. If artifact version
# parameter is given and the response is 200 or 201, then script also checks
# that # deployed version (gets from $url/version) equals to the passed
# version. If not, the script finishes with fail. Example of usage in bash
# script:
# sh post_deployment_test.sh http://blah.com/version 100 1.0.102-20160404.101644-5
# result=$?
#
# If $result value equals to 0, then connection is successfully established,
# otherwise, it is not established.
url=$1
timeout=$2
version=$3
if [ -z "$timeout" ]; then
timeout=180
fi
counter=0
delay=3
while [ $counter -le $timeout ]; do
command="curl -L -s -o /dev/null -w %{http_code} $url"
echo "Executing: $command"
status_code=$($command)
curl_code=$?
# Curl error code CURLE_COULDNT_CONNECT (7) means fail to connect to host or proxy.
# It occurs, in particular, in case when connection refused.
if [ $curl_code -ne 0 ] && [ $curl_code -ne 7 ]; then
echo "Connection is not established"
exit 1
fi
if [ $curl_code = 7 ] || [ $status_code = 503 ]; then
echo "Connection has not been established yet, because connection refused or service unavailable. Trying to connect again"
sleep $delay
let counter=$counter+$delay
continue
elif [ $status_code = 200 ] || [ $status_code = 201 ]; then
if [ -z "$version" ]; then
echo "Connection is successfully established"
exit 0
else
grep_result=`curl -L -s $url | grep $version`
if [ -z "$grep_result" ]; then
echo `curl -L -s $url`
echo "Deployed version doesn't equal to expected"
exit 1
else
echo "Connection is successfully established"
exit 0
fi
fi
else
echo "Connection is not established"
exit 1
fi
done
echo "Connection is not established"
exit 1
I've found something nice I was looking for: jasmine-node as a test runtime + frisby.js as a validation script tool.
It's both really portable (I just run npm install during the deployment) and really convenient in terms of scripting, e.g.(official example from frisby):
var frisby = require('frisby');
.get('https://api.twitter.com/1/statuses/user_timeline.json?screen_name=brightbit')
.expectStatus(200)
.expectHeaderContains('content-type', 'application/json')
.expectJSON('0', {
place: function(val) { expect(val).toMatchOrBeNull("Oklahoma City, OK"); }, // Custom matcher callback
user: {
verified: false,
location: "Oklahoma City, OK",
url: "http://brightb.it"
}
})
.expectJSONTypes('0', {
id_str: String,
retweeted: Boolean,
in_reply_to_screen_name: function(val) { expect(val).toBeTypeOrNull(String); }, // Custom matcher callback
user: {
verified: Boolean,
location: String,
url: String
}
})
.toss();

Bash/Curl example of pocket oAuth login

I'm trying to get a simple bash script working with the pocket api. All I want to do is authenticate with pocket and download my list of articles (actually, only the count)
I'm a little confused by the way that the oauth process works.
I've registered my app with the pocket api and have a consumer key
its marked as in "development" - I'm not sure if this is important.
The bit that's confusing me is that it seems that the way that the oAuth flow works with it's redirect uris is that it only really works with a gui (i.e a browser) - is it possible to do this with a bash script?
Here is what I have below. it works up until I have the TOKEN, but then I'm not sure what to do next.
#!/bin/bash
REDIR="redirect_uri=pocketapp1234:authorizationFinished"
KEY=21004-xxxxxxabcabcabc # you can assume this is the consumer key pocket issues for my app.
CODE=`curl -X POST --data "consumer_key=$KEY&$REDIR" https://getpocket.com/v3/oauth/request`
echo "OK - code is $CODE"
TOKEN=$(echo $CODE | awk -F"=" '{print $2}')
echo "OK - token is $TOKEN"
AUTH="consumer_key=$KEY&$CODE"
# This line seems not to work
curl -v "https://getpocket.com/auth/authorize?request_token=$TOKEN&$REDIR"
Yes, the browser portion is required. At the authorize phase, there is a page from getpocket.com prompting the user to login and authorise the bash script to access the user's Pocket account.
You can refer to Step 3 of the Pocket API Docs.
This is the Python v3.8 script I'm using and seems to work.
#!/usr/bin/env python
from os import environ as env
import requests
import webbrowser
def authorize_pocket_app():
data = {
"consumer_key": env['POCKET_CONSUMER_KEY'],
"redirect_uri": env['POCKET_APP_NAME'],
}
resp = requests.post(url="https://getpocket.com/v3/oauth/request", data=data)
code = resp.text.split("=")[1]
webbrowser.open(f"https://getpocket.com/auth/authorize?request_token={code}"
"&redirect_uri=https://duckduckgo.com")
input("Authorize %s app in the browser, then click enter" % env['POCKET_APP_NAME'])
get_token(code)
def get_token(code):
resp = requests.post(
url="https://getpocket.com/v3/oauth/authorize",
data={
"consumer_key": env["POCKET_CONSUMER_KEY"],
"code": code,
})
token = resp.text.split("&")[0].split("=")[1]
print("Secret token:", token)
if __name__ == "__main__":
authorize_pocket_app()
To use it as is you need to install requests external library and export POCKET_CONSUMER_KEY and POCKET_APP_NAME in your shell environment. E.g.
pip install requests
export POCKET_CONSUMER_KEY=xxx-yyy-zzz
export POCKET_APP_NAME=my-pocket-app
python <filename>.py
HTH

Want to call Progress 4GL 91.D procedure through Ajax call

I want to create web service for my Phonegap Android application which will further call progress 4GL 91.D procedure.
Does any one knowy idea how to create web service for this.
That will be a struggle. You CAN create a server that listens to a socket but you will have to handle everything yourself!
Look at this example.
However, you are likely better off writing the webservice in a language with a better support and then finding another way of getting the data out of the DB. If youre really stuck with a 10+ year old version you really should consider migrating to something else.
You don't have to upgrade everything -- you could just obtain a license for a version 10 client. V10 clients can connect to v9 databases (the rule is that the client can be up to one major release higher) so you could use that to build a SOAP service. Or you could get a v10 "webspeed" license.
Or you could write a simple enough CGI wrapper to some 4GL code if you have those sorts of skills. I occasionally toss together something like this:
#!/bin/bash
#
LOGFILE=/tmp/myservice.log
SVC=sample
# if a FIFO does not exist for the specified service then create it in /tmp
#
# $1 = direction -- in or out
# $2 = unique service name
#
pj_fifo() {
if [ ! -p /tmp/$2.$1 ]
then
echo `date` "Creating FIFO $2.$1" >> ${LOGFILE}
rm -f /tmp/$2.$1 >> ${LOGFILE} &2>&1
/bin/mknod -m 666 /tmp/$2.$1 p >> ${LOGFILE} &2>&1
fi
}
if [ "${REQUEST_METHOD}" = "POST" ]
then
read QUERY_STRING
fi
# header must include a blank line
#
# we're returning XML
#
echo "Content-type: text/xml" # or text/html or text/plain
echo
# debugging echo...
#
# echo $QUERY_STRING
#
# echo "<html><head><title>Sample CGI Interface</title></head><body><pre>QUERY STRING = ${QUERY_STRING}</pre></body></html>"
# ensure that the FIFOs exist
#
pj_fifo in $SVC
pj_fifo out $SVC
# make the request
#
echo "$QUERY_STRING" > /tmp/${SVC}.in
# send the response back to the requestor
#
cat /tmp/${SVC}.out
# all done!
#
echo `date` "complete" >> ${LOGFILE}
Then you just arrange for a background session to be reading /tmp/sample.in:
/* sample.p
*
* mbpro dbname -p sample.p > /tmp/sample.log 2>&1 &
*
*/
define variable request as character no-undo.
define variable result as character no-undo.
input from value( "/tmp/sample.in" ).
output to value( "/tmp/sample.out" ).
do while true:
import unformatted request.
/* parse it and do something with it... */
result = '<?xml version="1.0"?>~n<status>~n'.
result = result + "ok". /* or whatever turns your crank... */
result = result + "</status>~n".
end.
When input arrives parse the line and do whatever. Spit the answer back out to /tmp/sample.out and loop. It's not very fancy but if your needs are modest it is easy to do. If you need more scalability, robustness or security then you might ultimately need something more sophisticated but this will at least let you get started prototyping.

VOD server performance test

I have two VOD servers (RTSP) each on a different machine in a local network at home (vlc and Darwin streaming server).
What i am trying to do is a performance test that goes as follows:
* send in 10 requests, 50, then 100.
* redo the same but request multiple files instead of emulating multiple access to a single file.
* output statistics (speed, quality...etc).
What i have right now is OpenRstp which uses "-Q" to output Qos info but it is nowhere near what i need.
What i need is a free tool that can help me with this...all the ones i found (divesifeye and IxLoad) are not free.
Could anyone please suggest something useful?
I found a method that should do. It is based on openRTSP with "-Q" for Qos statistics.
the trick is how to redirect the data to a file as the Qos info only shows up after the feed is cut off. i wrote the following script to manage N-readings of a video feed/playlist. It will create a file that will contain the Qos info.
#!/bin/bash
f_rtsp(){
clear
echo -e "ENTER THE NUMBER OF STREAM USERS:"
echo -n "USER:"
read usr
for((i=1; i <= $usr;i++))
do
exec &> /$HOME/Desktop/results
echo -e "******************************* $i *****************************"
openRTSP -Q rtsp://<url>/<playlist-name>.sdp &
done
}
while : #Loop forever
do
cat <<!
Benchmark.RTSP
1.RTSP consumers
2.EXIT
!
echo -n "YOUR CHOICHE? :"
read choice
case $choice in
1|[rR]) f_rtsp ;;
2|[eE]) exit ;;
*) echo "\"$choice\"is not valid"; sleep 2 ;;
esac
done