This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Sophos XG API/CLI: Certificate in WAF rule cannot be changed due to error

Hi, 

This is a second post with regards to updating a WAF rule via CLI. The original post was answered for MR-4. And probably not monitored. 

I had a quick chat with Samil from support to verifify if this is een know issue.

That is not the case and he suggested to reopen the post. Though I am not to OP I can not, hence this post. 

Currently running SFOS 17.5.8 MR-8 in home edition and want to use lets encrypt certificates.
Got everything in place except the last step. Assigning the new certificate to a HTTPBased security policy. 

 

1. Retrieved the response of a HTTPBased SecurityPolicy

2. Modified the certificate name 

3. Posted the modified security policy 

Resulting in response

<Response APIVersion="1702.1" IPS_CAT_VER="1">
    <Login>
        <status>Authentication Successful</status>
    </Login>
    <SecurityPolicy transactionid="">
        <Status code="501">Configuration parameters validation failed.</Status>
        <InvalidParams />
    </SecurityPolicy>
</Response>

SFVUNL_HV01_SFOS 17.5.8 MR-8# cat /log/apiparser.log
INFO      Oct 21 20:42:34 [27013]: Start Login Handler,Component : Login
ERROR     Oct 21 20:42:34 [27013]: Key:ISCrEntity is not found in RequestMap File for Login.
INFO      Oct 21 20:42:34 [27013]: Mapping file for Login component is /_conf/csc/IOMappingFiles//1702.1/Login/Login.xml
ERROR     Oct 21 20:42:34 [27013]: Flag setting for this opcode is 18.
INFO      Oct 21 20:42:35 [27013]: Opcode response: status:200
INFO      Oct 21 20:42:35 [27013]: Authentication Successful
INFO      Oct 21 20:42:35 [27013]: Start Set Handler,Component : SecurityPolicy
ERROR     Oct 21 20:42:35 [27013]: Key:ISCrEntity is not found in RequestMap File for SecurityPolicy.
ERROR     Oct 21 20:42:35 [27013]: Parser Error: xmlvalue for jsonkey="tempsourceid", xmlelement="/SecurityPolicy/SourceNetworks/Network" cannot be found in request file.
ERROR     Oct 21 20:42:35 [27013]: Parser Error: xmlvalue for jsonkey="tempexceptionid", xmlelement="/SecurityPolicy/ExceptionNetworks/Network" cannot be found in request file.
ERROR     Oct 21 20:42:35 [27013]: json object not found with key="tempsourceid" to handle logicaloperator.
ERROR     Oct 21 20:42:35 [27013]: Parser Error: xmlvalue for jsonkey="sourceid", xmlelement="/SecurityPolicy/SourceNetworks/Network" cannot be found in request file.
ERROR     Oct 21 20:42:35 [27013]: json object not found with key="tempexceptionid" to handle logicaloperator.
ERROR     Oct 21 20:42:35 [27013]: Parser Error: xmlvalue for jsonkey="exceptionid", xmlelement="/SecurityPolicy/ExceptionNetworks/Network" cannot be found in request file.
ERROR     Oct 21 20:42:35 [27013]: Flag setting for this opcode is 16.
INFO      Oct 21 20:42:36 [27013]: Opcode response: status:500
INFO      Oct 21 20:42:36 [27013]: End  SET Handler, Status : Success,  Component : SecurityPolicy, Transaction : , Operation : update.
MESSAGE   Oct 21 20:42:36 [27013]: ENTITY 'SecurityPolicy' IMPORT Success
INFO      Oct 21 20:42:36 [27013]: Command:/scripts/apiparser_generate_tar.sh /sdisk/api-1571683354644446.txt /sdisk/API-1571683354644446 /sdisk/APIXMLOutput/1571683354484.xml /sdisk/API-1571683354644446.tar /sdisk/API-1571683354644446.log 0 status:3
INFO      Oct 21 20:42:36 [27013]: No need to create Tar file. Response file is /sdisk/APIXMLOutput/1571683354484.xml
 
SourceNetworks and ExeptionNetworks are not part of the HTTPBased policy type. Is this a bug? 
I can if needed post the complete request. 


This thread was automatically locked due to age.
Parents
  • 1a. XML Request to get Policyrule

    <Request>
        <Login>
            <Username>admin</Username>
            <Password passwordform="plain">SecretPassword</Password>
        </Login>
        <Get>
            <SecurityPolicy>
                <Filter>
                    <key name="Name" criteria="=">RDG 2019</key>
                </Filter>
            </SecurityPolicy>
        </Get>
    </Request>

    1b. XML Response

    <Response APIVersion="1702.1" IPS_CAT_VER="1">
        <Login>
            <status>Authentication Successful</status>
        </Login>
        <SecurityPolicy transactionid="">
            <Name>RDG 2019</Name>
            <Description />
            <IPFamily>IPv4</IPFamily>
            <Status>Enable</Status>
            <Position>After</Position>
            <PolicyType>HTTPBased</PolicyType>
            <After>
                <Name>Allow-Internet</Name>
            </After>
            <HTTPBasedPolicy>
                <HostedAddress>#PortB:0</HostedAddress>
                <HTTPS>Enable</HTTPS>
                <ListenPort>443</ListenPort>
                <AccessPaths>
                    <AccessPath>
                        <allowed_networks>Any IPv4</allowed_networks>
                        <auth_profile />
                        <backend>rdg-01</backend>
                        <be_path />
                        <hot_standby>0</hot_standby>
                        <path>/</path>
                        <stickysession_status>0</stickysession_status>
                        <websocket_passthrough>0</websocket_passthrough>
                    </AccessPath>
                </AccessPaths>
                <Exceptions>
                    <Exception>
                    </Exception>
                </Exceptions>
                <ProtocolSecurity>Microsoft RDG 2019</ProtocolSecurity>
                <CompressionSupport>Disable</CompressionSupport>
                <RewriteHTML>0</RewriteHTML>
                <PassHostHeader>Disable</PassHostHeader>
                <Domains>
                    <Domain>rdg.contoso.com</Domain>
                </Domains>
                <RewriteCookies>Disable</RewriteCookies>
                <Certificate>201910182150-rdg.contoso.com</Certificate>
                <RedirectHTTP>Disable</RedirectHTTP>
            </HTTPBasedPolicy>
            <IntrusionPrevention>None</IntrusionPrevention>
            <TrafficShapingPolicy>None</TrafficShapingPolicy>
        </SecurityPolicy>
    </Response>


    2a. Set Request (updated certificate)
    <Request>
        <Login>
            <Username>admin</Username>
            <Password passwordform="plain">SecretPassword</Password>
        </Login>
        <Set operation="update">
            <SecurityPolicy transactionid="">
                <Name>RDG 2019</Name>
                <Description />
                <IPFamily>IPv4</IPFamily>
                <Status>Enable</Status>
                <Position>After</Position>
                <PolicyType>HTTPBased</PolicyType>
                <After>
                    <Name>Allow-Internet</Name>
                </After>
                <HTTPBasedPolicy>
                    <HostedAddress>#PortB:0</HostedAddress>
                    <HTTPS>Enable</HTTPS>
                    <ListenPort>443</ListenPort>
                    <AccessPaths>
                        <AccessPath>
                            <allowed_networks>Any IPv4</allowed_networks>
                            <auth_profile />
                            <backend>rdg-01</backend>
                            <be_path />
                            <hot_standby>0</hot_standby>
                            <path>/</path>
                            <stickysession_status>0</stickysession_status>
                            <websocket_passthrough>0</websocket_passthrough>
                        </AccessPath>
                    </AccessPaths>
                    <Exceptions>
                        <Exception>
                            <op>and</op>
                            <path>/remoteDesktopGateway/</path>
                            <skipav>0</skipav>
                            <skipbadclients>0</skipbadclients>
                            <skipcookie>0</skipcookie>
                            <skipform>0</skipform>
                            <skipurl>0</skipurl>
                        </Exception>
                    </Exceptions>
                    <ProtocolSecurity>Microsoft RDG 2019</ProtocolSecurity>
                    <CompressionSupport>Disable</CompressionSupport>
                    <RewriteHTML>0</RewriteHTML>
                    <PassHostHeader>Disable</PassHostHeader>
                    <Domains>
                        <Domain>rdg.contoso.com</Domain>
                    </Domains>
                    <RewriteCookies>Disable</RewriteCookies>
                    <Certificate>201910212041-rdg.contoso.com</Certificate>
                    <RedirectHTTP>Disable</RedirectHTTP>
                </HTTPBasedPolicy>
                <IntrusionPrevention>None</IntrusionPrevention>
                <TrafficShapingPolicy>None</TrafficShapingPolicy>
            </SecurityPolicy>
        </Set>
    </Request>


    2b. Set Response (apiparser.log already included)

    <Response APIVersion="1702.1" IPS_CAT_VER="1">
        <Login>
            <status>Authentication Successful</status>
        </Login>
        <SecurityPolicy transactionid="">
            <Status code="501">Configuration parameters validation failed.</Status>
            <InvalidParams />
        </SecurityPolicy>
    </Response>
  • I should have asked a couple more questions before also...

    1. How are you sending/receiving data to the API?  Are you using curl?
    2. Are you saving the XML to a file and then sending or are you sending it "inline"
    If sending "inline" are you properly escaping the quotes?

Reply
  • I should have asked a couple more questions before also...

    1. How are you sending/receiving data to the API?  Are you using curl?
    2. Are you saving the XML to a file and then sending or are you sending it "inline"
    If sending "inline" are you properly escaping the quotes?

Children
  • I am using powershell. Contrusting MultipartFormDataContent object. With single form-data field reqxml. 

     

    Following code is used to retrieve the Securitypolicy

    ```

    Add-Type -AssemblyName System.Net.Http

    $httpClientHandler = New-Object System.Net.Http.HttpClientHandler
    $httpClient = New-Object System.Net.Http.Httpclient $httpClientHandler

    $xml = [xml]@"
    <Request>
    <Login>
    <Username>admin</Username>
    <Password passwordform=`"plain`">SecretPassword</Password>
    </Login>
    <Get>
    <SecurityPolicy>
    <Filter>
    <key name="Name" criteria="=">RDG 2019</key>
    </Filter>
    </SecurityPolicy>
    </Get>
    </Request>
    "@

    $multipartContent = [System.Net.Http.MultipartFormDataContent]::new()

    $stringHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
    $stringHeader.Name = "reqxml"
    $StringContent = [System.Net.Http.StringContent]::new($xml.OuterXml)
    $StringContent.Headers.ContentDisposition = $stringHeader
    $StringContent.Headers.ContentType = 'application/xml'
    $StringContent.Headers.ContentType.CharSet = 'utf-8'
    $multipartContent.Add($stringContent)

    $uri = 'https://xg-01:4444/webconsole/APIController'

     

    $response = $httpClient.PostAsync($Uri, $multipartContent).Result

    $result = [xml]$response.Content.ReadAsStringAsync().Result
    $result.Response

    ```

    which results in the following post : 

    Method: POST, RequestUri: 'xg-01:4444/.../APIController', Version: 1.1, Content: System.Net.Http.MultipartFormDataContent, Headers:
    {
    Content-Type: multipart/form-data; boundary="358a0f19-2b25-4a7b-9ec7-49d6b08eb4ee"
    Content-Length: 393
    }
    --358a0f19-2b25-4a7b-9ec7-49d6b08eb4ee
    Content-Type: application/xml; charset=utf-8
    Content-Disposition: form-data; name=reqxml

    <Request><Login><Username>admin</Username><Password passwordform="plain">SecretPassword</Password></Login><Get><SecurityPolicy><Filter><key name="Name" criteria="=">RDG 2019</key></Filter></SecurityPolicy></Get></Request>
    --358a0f19-2b25-4a7b-9ec7-49d6b08eb4ee--

    I could place something in between to get the raw request. This is what worked uploading a certificate by adding the file to the MultipartFormDataContent object. So I was assuming the post is correct. 

    Thank you for the quick responses. 

  • This is what I uploaded via Curl and it just changed the name of the certificate on the system I am working on:

    PLEASE NOTE:  the parts in ( ) are there for others that are still learning how to do this...  They cannot be in the actual XML file
    Yellow highlights should be replaced with your own data


    <Request APIVersion="1702.1">
            <Login>
                <Username>apiuser</Username> 
                <Password>your password</Password>
            </Login>
            <Set operation="update">
                    <SecurityPolicy>
                            <Name>policy name</Name>                                               (Name from Protect->Firewall)
                            <PolicyType>HTTPBased</PolicyType>
                            <HTTPBasedPolicy>
                                    <HostedAddress>#Port2</HostedAddress>
                                    <HTTPS>Enable</HTTPS>
                                    <ListenPort>443</ListenPort>
                                    <AccessPaths>
                                            <AccessPath>
                                                    <allowed_networks>Any IPv4</allowed_networks>
                                                    <auth_profile/>
                                                    <backend>websever name</backend>           (Name from Protect->Web server->Web servers)
                                                    <be_path/>
                                                    <hot_standby>0</hot_standby>
                                                    <path>/</path>
                                            </AccessPath>
                                    </AccessPaths>
                                    <Domains>
                                            <Domain>www.example.com</Domain>.               (DNS Domain Name)
                                    </Domains>
                                    <Certificate>name of certificate you provided when you uploaded the certificate to the XG</Certificate> (Certificate name from System->Certificates)
                            </HTTPBasedPolicy>
                    </SecurityPolicy>
            </Set>
    </Request>

     

    The above is saved as a file named update.xml and sent via curl with the following command:
    curl -k -F "reqxml=<update.xml" "https://ip of router here:4444/webconsole/APIController?"

    Curl man page: https://curl.haxx.se/docs/manpage.html
    Look for -F and you will find this: This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388
    The < indicates to Curl that it should send the contents of the file named update.xml for the "form field" called "reqxml"

    The XML probably still needs some tweaking as the update removed the firewall rule from the group that it was in...

    Hopefully this helps, maybe the key is to make sure your sending the XML as form-data?  I will be tackling this from PowerShell next as I have some windows servers that will be using PowerShell to retrieve a cert from Let's Encrypt then upload and modify the firewall rule...

  • Hi JamieBah1, thank you for the response. 

    I actually got the same result using curl or postman. 

    After which I cleared the exception part of the rule. After that all worked just fine. 

    The exception section was left there from getting it all to work and not needed. 

    Though it looks like there is some mapping issues within the api controller. 

     

    Thanks for you help.