Home > OS >  bash rest-api call authentication problem, I propaly use wrong syntax in my rest-api call but can�
bash rest-api call authentication problem, I propaly use wrong syntax in my rest-api call but can�

Time:08-12

I wrote a powershell script for setting downtimes in our monitoring software "checkmk" and now I have to convert that so a bash script because we are switching from windows server to linux.

user will be "XXX" password will be "YYY" and the hostname will be "ZZZ"

For that I used the documentation from CheckMK: documentation for show sheduled downtimes documentation for setting a downtime

and in the end it looks like that:

    <#
.Synopsis
   Downtime per Rest API bei Check MK Setzen
.DESCRIPTION
   Doku https://apt-omd-vip.ads.vhv.de/umbrella/check_mk/openapi/#operation/cmk.gui.plugins.openapi.endpoints.downtime.create_host_related_downtime
   30 min Downtime Setzen  = 1800 sekunden
.EXAMPLE
   Example of how to use this cmdlet
.EXAMPLE
   Another example of how to use this cmdlet
#>
function set-Downtime
{
    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        $USERNAME="XXX",
        $PASSWORD="XXX",
        [Parameter(Mandatory=$true)]
        $HOSTNAME,
        #Zeit soll die Downtime in Minuten angeben, wird dieseer Parameter leer gelassen wird Standdardmäßig 30min verwendet.
        [Parameter(Mandatory=$false)]
        [Int]$TIME=30
    )

    Begin
    {
    }
    Process
    {
    

    #=============
    # Abfrage der DownTimes, sonst kein Connect möglich
    #=============

    $headers = @{
    ‘Accept’ = ‘application/json’
    ‘Authorization’ = “Bearer $USERNAME $PASSWORD”
    }

    $body = @{
             'host_name' = $HOSTNAME
              }   
 
    
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12 

    
    $result = Invoke-RestMethod -uri “here was a URL” -Headers $headers -Body  $body 
 

   
    #write-host($rest_uri)
    

    #=============
    # DownTime
    #=============


    $headers = @{
    'Content-Type' = 'application/json'
    ‘Accept’ = ‘application/json’
    ‘Authorization’ = “Bearer $USERNAME $PASSWORD”
    }

    $datum_start = (get-date).AddHours(-2).ToString("u") 
    $datum_ende = (get-date).AddHours(-2).addminutes($TIME).ToString("u") ;
    $comment = "$TIME min Restart Downtime, $EXTRAINFO"

    $body =@{
            start_time = $datum_start;
            end_time =   $datum_ende;
            comment =  $comment;
            host_name = $HOSTNAME;
            downtime_type = 'host';
             }  | ConvertTo-Json -Compress
        
    
    $result = Invoke-RestMethod -Method Post -uri "here was a URL" -Headers $headers -Body $body
    
    
    }
    End
    {
    }
}

I apologize for the english-german mix in the script but in theory you shouldn't need my comments.

I reconstructed the command from this bash to powershell help blog Here is one time my bash script hole and after that I will only post the part I changed:

#!/bin/bash

##Variables

base_url='here was a URL'
request_url="$base_url/all"
post_url="$base_url/host"
user="XXX"
passwd="YYY"
hostname="ZZZ"
user_pass="$user:$passwd"

#header=["Accep"t = "application/json"
#"Authorisation" = "Bearer $user $passwd"]
#body1=["host_name" = "ZZZ"]


curl -u $user_pass -X GET --header 'Accept: application/json' -d {'host_name: ZZZ'} 'here was an URL'

as I am still unexperienced in bash I tried my decleration of variables with the '' and "" quotes because I am still not shure when to use what (but thats not the question here) Answer is following:

{"title": "You need to be authenticated to use the REST API.", "status": 401}

Next thing I tried was a header construct similar to my ps script:

header=( ["Accept"]="application/json" ["Authorization"]="Bearer XXX YYY")


curl --anyauth -X GET --header $header -d {'host_name: ZZZ'} 'here was an URL'

the answer this times was way longer but in the end I got the same error message:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "censored doc url">
<html>
<!-- FileName: index.html
     Language: [en]
-->
<!--Head-->
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  <meta http-equiv="X-UA-Compatible" content="IE=7" />
  <title>McAfee Web Gateway - Notification</title>
  <script src="censored" type="text/vascript" ></script>
  <link rel="stylesheet" href="censored" />
</head>
<!--/Head-->
<!--Body-->
<body onl oad="swOnLoad();">
  <table class='bodyTable'>
    <tr>
      <td class='bodyData' background='censored'>
<!--Logo-->
<table class='logoTable'>
  <tr>
    <td class='logoData'>
      <a href='http://www.mcafee.com'>
        <img src='censored'>a>
    </td>
  </tr>
</table>
<!--/Logo-->
<!--Contents-->
<!-- FileName: authenticationrequired.html
     Language: [en]
-->
<!--Title-->
<table class='titleTable' background='censored.jpg'>
  <tr>
    <td class='titleData'>
      Authentication Required
    </td>
  </tr>
</table>
<!--/Title-->

<!--Content-->
<table >
  <tr>
    <td >
      You must be authenticated to access this URL.
    </td>
  </tr>
</table>

<script language="javascript" type="text/javascript">
   urlprotocol = "http";
   statuscode=407;

   if(statuscode==401 && urlprotocol == "ftp"){
      document.write("<form name=\"ftpform\" method=\"get\" action=\"\">");
      document.write("<table class=\"contentData\">");
      document.write("<tr><td class=\"contentData\" colspan=2>Please enter youcredentials in the form below and click \"Access FTP\" button if your browser esn't present authentication prompt for FTP sites.</td></tr>");
      document.write("<tr><td class=\"contentData\">Username:</td><td><input te=\"text\" id=\"ftpUsername\" name=\"ftpUsername\" size=40 /></td></tr>");
      document.write("<tr><td class=\"contentData\">Password:</td><td><input te=\"password\" id=\"ftpPassword\" name=\"ftpPassword\" size=40 /></td></tr>");
      document.write("<tr><td class=\"contentData\" colspan=2 align=center><int type=\"button\" onclick=\"redirectToFTP();\" value=\"Access FTP\" /></td></t");
      document.write("</table>");
      document.write("</form>");
   }

   function redirectToFTP(){
      var username=escape(document.getElementById("ftpUsername").value);
      var password=escape(document.getElementById("ftpPassword").value);
      location.href = "ftp://" username ":" password "@XXX:80/"
   }
</script>
<!--/Content-->

<!--Info-->
<table >
  <tr>
    <td >
      <b>URL: </b><script type="censored");</script><br />
    </td>
  </tr>
</table>
<!--/Info-->

<!--/Contents-->
<!--Policy-->
<table class='policyTable'>
  <tr>
    <td class='policyHeading'>
      <hr>
      Company Acceptable Use Policy
    </td>
  </tr>
  <tr>
    <td class='policyData'>
      This is an optional acceptable use disclaimer that appears on every pageYou may change the wording or remove this section entirely in index.html.
    </td>
  </tr>
</table>
<!--/Policy-->
<!--Foot-->
<table class='footTable'>
  <tr>
    <td class='helpDeskData' background='censored'>
      For assistance, please contact your system administrator.
    </td>
  </tr>
  <tr>
    <td class='footData'>
      generated <span id="time">2022-08-09 14:58:22</span> by McAfee Web Gatew
      <br />
      curl/7.60.0<br />
Node: censored<br />
Client IP: censored<br />
User: <br />
User-Groups:  <br />
Authentication Method: <br />
Rule Set: Authentication with Kerberos and NTLM Fallback<br />
Rule: Perform Authentication<br />

    </td>
  </tr>
</table>
<!--/Foot-->
      </td>
    </tr>
  </table>
</body>
<!--/Body-->
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "censored">
<html>
<!-- FileName: index.html
     Language: [en]
-->
<!--Head-->
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  <meta http-equiv="X-UA-Compatible" content="IE=7" />
  <title>McAfee Web Gateway - Notification</title>
  <script src="censored" type="text/vascript" ></script>
  <link rel="stylesheet" href="/mwg-internal/de5fs23hu73ds/files/default/styleeet.css" />
</head>
<!--/Head-->
<!--Body-->
<body onl oad="swOnLoad();">
  <table class='bodyTable'>
    <tr>
      <td class='bodyData' background='censored'>
<!--Logo-->
<table class='logoTable'>
  <tr>
    <td class='logoData'>
      <a href='http://www.mcafee.com'>
        <img src='censored'>a>
    </td>
  </tr>
</table>
<!--/Logo-->
<!--Contents-->
<!-- FileName: authenticationrequired.html
     Language: [en]
-->
<!--Title-->
<table class='titleTable' background='/mwg-internal/de5fs23hu73ds/files/defaulimg/bg_navbar.jpg'>
  <tr>
    <td class='titleData'>
      Authentication Required
    </td>
  </tr>
</table>
<!--/Title-->

<!--Content-->
<table >
  <tr>
    <td >
      You must be authenticated to access this URL.
    </td>
  </tr>
</table>

<script language="javascript" type="text/javascript">
   urlprotocol = "http";
   statuscode=407;

   if(statuscode==401 && urlprotocol == "ftp"){
      document.write("<form name=\"ftpform\" method=\"get\" action=\"\">");
      document.write("<table class=\"contentData\">");
      document.write("<tr><td class=\"contentData\" colspan=2>Please enter youcredentials in the form below and click \"Access FTP\" button if your browser esn't present authentication prompt for FTP sites.</td></tr>");
      document.write("<tr><td class=\"contentData\">Username:</td><td><input te=\"text\" id=\"ftpUsername\" name=\"ftpUsername\" size=40 /></td></tr>");
      document.write("<tr><td class=\"contentData\">Password:</td><td><input te=\"password\" id=\"ftpPassword\" name=\"ftpPassword\" size=40 /></td></tr>");
      document.write("<tr><td class=\"contentData\" colspan=2 align=center><int type=\"button\" onclick=\"redirectToFTP();\" value=\"Access FTP\" /></td></t");
      document.write("</table>");
      document.write("</form>");
   }

   function redirectToFTP(){
      var username=escape(document.getElementById("ftpUsername").value);
      var password=escape(document.getElementById("ftpPassword").value);
      location.href = "ftp://" username ":" password "@YYY:80/"
   }
</script>
<!--/Content-->

<!--Info-->
<table >
  <tr>
    <td >
      <b>URL: </b><script type="text/javascript">break_line("http://setDownTim");</script><br />
    </td>
  </tr>
</table>
<!--/Info-->

<!--/Contents-->
<!--Policy-->
<table class='policyTable'>
  <tr>
    <td class='policyHeading'>
      <hr>
      Company Acceptable Use Policy
    </td>
  </tr>
  <tr>
    <td class='policyData'>
      This is an optional acceptable use disclaimer that appears on every pageYou may change the wording or remove this section entirely in index.html.
    </td>
  </tr>
</table>
<!--/Policy-->
<!--Foot-->
<table class='footTable'>
  <tr>
    <td class='helpDeskData' background='/mwg-internal/de5fs23hu73ds/files/deflt/img/bg_navbar.jpg'>
      For assistance, please contact your system administrator.
    </td>
  </tr>
  <tr>
    <td class='footData'>
      generated <span id="time">2022-08-09 14:58:22</span> by McAfee Web Gatew
      <br />
      curl/7.60.0<br />
Node:censored<br />
Client IP: censored<br />
User: <br />
User-Groups:  <br />
Authentication Method: <br />
Rule Set: Authentication with Kerberos and NTLM Fallback<br />
Rule: Perform Authentication<br />

    </td>
  </tr>
</table>
<!--/Foot-->
      </td>
    </tr>
  </table>
</body>
<!--/Body-->
</html>
{"title": "You need to be authenticated to use the REST API.", "status": 401}

I needed to cut that part because I was over the characterlimit for the post...

I think that my error is not that hard to solve but I dont know enough about bash to search for the right things so please get easy on me. I used bash the first time in june this year so try to keep the answers a bit simpler than to an usual bash user please, thank you in advance for your help and consideration.

CodePudding user response:

Like I guessed my problem was a minor one... only thing wrong was the ":" in my headers, just had to exchange them for "=".

Well got a new problem but I doubt that you guys can help me when I am not allowed to share more information about our server and applications.

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>

afer that message I did the same thing in the body like in my header but that didnt do the thing.

CodePudding user response:

Here's a rewrite of your script in bash using curl, because it'll be easier to discuss against an example rather than an abstract in comments.

This, at least to my eyes, does exactly what your Powershell script is doing.

#!/bin/bash

url="https://YOUR-URL"
username="XXX"
password="YYY"
hostname="ZZZ"

# first Invoke-RestMethod, which is a GET with JSON...

# -1 means "use TLS1 or newer"

# -XGET is required here to force it to be a request
# that uses GET with a body, since curl would default to POST
# if '-d' is specified

# -w "%{http_code}\n" means output the http code

# if you want to suppress all other output and only 
# get the http code output, specify these additional options:
# -o /dev/null -s

curl $url -1 -XGET \
    -H "Accept: application/json" \
    -H "Authorization: Bearer $username $password" \
    -w "%{http_code}\n" \
    -d "{ \"host_name\": \"$hostname\" }"
   
# Downtime Invoke-RestMethod

minutes_diff=30
start_diff=120

# because in your original, you do (now - 2 hours)   $minutes_diff 
# so it's just now -(120 - $minutes_diff) minutes
end_diff=$(( 120 - $minutes_diff ))

# This was based on you using the .NET -u specifier which is
# intended for use with UTC DateTime objects

# I don't know if you actually want your timestamps derived
# from UTC time, which is what "-u" does for the date command

start_time=$(date -u -d "$start_diff minutes ago"  "%Y-%m-%d %H:%M:%SZ")

end_time=$(date -u -d "$end_diff  minutes ago"  "%Y-%m-%d %H:%M:%SZ")

# you didn't have an EXTRAINFO in your original script
# so I left it out
comment="$minutes_diff min Restart Downtime"

# The -d @- <<-JSON uses a heredoc so I can
# more nicely express the JSON you send

curl $url -1 \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "Authorization: Bearer $username $password" \
    -w "%{http_code}\n" \
    -d @- <<-JSON
{
    "start_time": "$start_time",
    "end_time": "$end_time",
    "comment": "$comment",
    "host_name": "$hostname",
    "downtime_type": "host"
}
JSON
  • Related