File upload using aXAPI 3.0
As documented at https://documentation.a10networks.com/ACOS/411x/411-P1/ACOS_4_1_1-P1/html/axapiv3/file.html I'm trying to upload text/plain files to use as axflex scripts or bw-lists.
So far I haven't been able to POST files with any success. Each API call pushes the control CPU to 100% until the device has been rebooted.
Getting the authresponse signature, switching partitions and running clideploy commands all work like a charm.
I've tested my scripts on TH1030S running 4.1.1-P6 and vThunder running 4.1.4-GR1-P5.
As a last resort I tried to mimic the documented API call and configured the scripts to connect to 'netcat' instead of the A10 ADC to be able to see all headers and postdata:
# nc -l -p 888 POST /axapi/v3/file/aflex HTTP/1.1 Host: 127.0.0.1:888 Accept: */* Authorization: A10 61916a9b734956575c34ae00d28fd7 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryHf1lBo4wM6uXCQm3 Content-Length: 468 ------WebKitFormBoundaryHf1lBo4wM6uXCQm3 Content-Disposition: form-data; name="json"; filename="blob" Content-Type: application/json {"aflex":{"file":"abc","file-handle":"aflex-script.txt","action":"import"}} ------WebKitFormBoundaryHf1lBo4wM6uXCQm3 Content-Disposition: form-data; name="file"; filename="aflex-script.txt" Content-Type: text/plain when HTTP_REQUEST { HTTP::redirect https://[HTTP::host][HTTP::uri] } ------WebKitFormBoundaryHf1lBo4wM6uXCQm3-- ###
API Client (php, curl, verbose enabled):
Debug output: Headers: Array ( [0] => Authorization: A10 61e173c17e60458536e094240c9475 [1] => Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryHf1lBo4wM6uXCQm3 [2] => Content-Length: 468 ) Postdata: ------WebKitFormBoundaryHf1lBo4wM6uXCQm3 Content-Disposition: form-data; name="json"; filename="blob" Content-Type: application/json {"aflex":{"file":"abc","file-handle":"aflex-script.txt","action":"import"}} ------WebKitFormBoundaryHf1lBo4wM6uXCQm3 Content-Disposition: form-data; name="file"; filename="aflex-script.txt" Content-Type: text/plain when HTTP_REQUEST { HTTP::redirect https://[HTTP::host][HTTP::uri] } ------WebKitFormBoundaryHf1lBo4wM6uXCQm3-- CURL: * Expire in 0 ms for 6 (transfer 0x5595ba964e30) * Trying 10.100.4.80... * TCP_NODELAY set * Expire in 200 ms for 4 (transfer 0x5595ba964e30) * Connected to 10.100.4.80 (10.100.4.80) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: none CApath: /etc/ssl/certs * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server did not agree to a protocol * Server certificate: * subject: CN=vThunder * start date: Apr 8 13:43:32 2016 GMT * expire date: Apr 8 13:43:32 2018 GMT * issuer: CN=vThunder * SSL certificate verify result: self signed certificate (18), continuing anyway. > POST /axapi/v3/file/aflex HTTP/1.1 Host: 10.100.4.80 Accept: */* Authorization: A10 61e173c17e60458536e094240c9475 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryHf1lBo4wM6uXCQm3 Content-Length: 468 * upload completely sent off: 468 out of 468 bytes
This is when the CPU goes straight to 100% load and the client just keeps waiting for a response.
Any help would be appreciated!
Comments
Hi Fabian, here is something I tried and see it working using curl, the example if for an aflex file but the same concept should appy to /axapi/v3/file/bw-list
curl -F "filename=@aflextest2" -H "Authorization: A10 "$var1"" -F "json=@aflexjson.txt;type=application/json" http://$1$2
My test file is on the directory where I run curl as well as the aflexjson.txt, the latter is just a filename, see it below for content - $var1 is just the token to use after you got an auth token; $1=A10 IP address and $2=/axapi/v3/file/aflex - note I am using http, in your case it may be https
cat aflexjson.txt
{
"aflex" : {
"file":"aflextest2",
"dst-file":"aflextest2",
"file-handle":"aflextest2",
"action":"create"
}
}
I used curl with -v and here is the output:
* TCP_NODELAY set
* Connected to th1b (172.31.31.47) port 80 (#0)
> POST /axapi/v3/file/aflex HTTP/1.1
> Host: th1b
> User-Agent: curl/7.64.1
> Accept: */*
> Authorization: A10 613575aea9c540701d66a392c54a03
> Content-Length: 712
> Content-Type: multipart/form-data; boundary=------------------------3c393243ab0224de
>
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< Date: Wed, 23 Dec 2020 20:52:04 GMT
< Server: Apache
< X-Frame-Options: SAMEORIGIN
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Referrer-Policy: no-referrer-when-downgrade
< Cache-Control: max-age=0, no-cache, no-store, must-revalidate
< Content-Length: 102
< Connection: close
< Content-Type: application/json
<
{
"response": {
"status": "OK",
"msg": "aFleX aflextest2 created; syntax check passed"
}
* Closing connection 0
}HTTP/1.1 200 OK
Date: Wed, 23 Dec 2020 20:52:04 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: no-referrer-when-downgrade
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Content-Length: 42
Connection: close
Content-Type: application/json
{
"response": {
"status": "OK"
}
}
Thanks a lot! Using your curl example is was able to compare the requests and results between your example and my PHP generated requests.
The issue is that A10 requires \r\n newlines at the end of all Form header lines and I was using \n newlines.
It's a shame that this causes the control CPU to instantly go to 100% which effectively means that incorrect headers in axAPI requests always causes a DOS.
Thanks for your feedback Fabian. I will make sure that, if not yet corrected on latest version, that this is taken care of. Cheers.