Logstash pattern for nginx error log - nginx

This is my sample error log:
2017/03/29 17:32:56 [error] 21924#21924: *212595 access forbidden by rule, client: 172.31.0.14, server: , request: "POST /app/etc/local.xml HTTP/1.1", host: "www.overcart.com"
I want a grok pattern that matches this. I don't know how to proceed. Don't know how to create one. I have tried various but none of them worked.
I am currently parsing this using the following grok pattern:
%{DATESTAMP:mydate} [%{DATA:severity}] (%{NUMBER:pid:int}#%{NUMBER}: *%{NUMBER}|*%{NUMBER}) %{GREEDYDATA:mymessage}(?:, client: (?<client_ip>%{IP}|%{HOSTNAME})) (?:, server: %{IPORHOST:server})(?:, request: %{QS:request})?(?:, host: %{QS:host})?(?:, referrer: \"%{URI:referrer})
but it's not parsing from (?:, server: onwards.

Here's the grok pattern I use. It's not perfect and can be improved, but it works and parses also an additional upstream token.
(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) \[%{LOGLEVEL:severity}\] %{POSINT:pid}#%{NUMBER:threadid}\: \*%{NUMBER:connectionid} %{GREEDYDATA:errormessage}, client: %{IP:client}, server: %{GREEDYDATA:server}, request: "(?<httprequest>%{WORD:httpcommand} %{UNIXPATH:httpfile} HTTP/(?<httpversion>[0-9.]*))"(, )?(upstream: "(?<upstream>[^,]*)")?(, )?(host: "(?<host>[^,]*)")?

this is what I use for nginx-error pattern, it can parse all fields in my error log.:
(?<timestamp>\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[%{DATA:err_severity}\] (%{NUMBER:pid:int}#%{NUMBER}: \*%{NUMBER}|\*%{NUMBER}) %{DATA:err_message}(?:, client: (?<clientip>%{IP}|%{HOSTNAME}))(?:, server: %{IPORHOST:server})(?:, request: "%{WORD:verb} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}")?(?:, upstream: "%{DATA:upstream}")?(?:, host: "%{IPORHOST:host}")?(?:, referrer: "%{URI:referrer}”)?

I'm using #mavlarn's grok pattern and it works well for my use case. I'm sure #dr01 will work as well. Remember to test to see what works for you!
Pro-tip: Because there are double quotes inside these grok patterns, in order to make them work properly I needed to surround the pattern with single quotes instead of double.
To highlight, here is an example.
grok {
match => { "message" => "This "double quote" pattern won't work. Backslashes to cancel/close the regex won't work either. Logstash will fail to start.."}
}
grok {
match => { "message" => 'But this "double quote" pattern will work when surrounding with single quotes instead.'}
}
Example solution.
grok {
match => { "message" => '(?<timestamp>\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[%{DATA:err_severity}\] (%{NUMBER:pid:int}#%{NUMBER}: \*%{NUMBER}|\*%{NUMBER}) %{DATA:err_message}(?:, client: (?<clientip>%{IP}|%{HOSTNAME}))(?:, server: %{IPORHOST:server})(?:, request: "%{WORD:verb} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}")?(?:, upstream: "%{DATA:upstream}")?(?:, host: "%{IPORHOST:host}")?(?:, referrer: "%{URI:referrer}”)?' }
}
(Tested with Logstash v6.x and v7.x)

Related

How to Remove Data from WC API Endpoint Request?

I'm shipping off order data to a 3rd party piece of fulfillment software. They integrate by default with the WooCommerce REST API. However some recent changes to my site and order data have added additional order meta. Now when grabbing the same amount of orders as it always has the request times out with a 504. The request is now unreasonably large, to fix this I've decided to optimize by reducing the irrelevant and unnecessary data produced by the request. Also I have to be able to process 100 at a time I cannot reduce the filter limit, its automatically set by the 3rd party application.
Endpoint in Question
wc-api/v2/orders?status=processing&page=1&filter%5Blimit%5D=100
This endpoint grabs the first 100 orders in processing and displays them as a piece of JSON.
Things to Remove
customer_user_agent
avatar_url
cogs_cost
cogs_total_cost
Example Response
{
"orders":[
{
"id":137314,
"order_number":"137314",
"created_at":"2019-09-18T18:37:06Z",
"updated_at":"2019-09-18T18:37:07Z",
"completed_at":"1970-01-01T00:00:00Z",
"status":"processing",
"currency":"USD",
"total":"49.50",
"subtotal":"55.00",
"total_line_items_quantity":1,
"total_tax":"0.00",
"total_shipping":"0.00",
"cart_tax":"0.00",
"shipping_tax":"0.00",
"total_discount":"0.00",
"shipping_methods":"Free shipping",
"payment_details":{
"method_id":"nmipay",
"method_title":"Pay with Credit Card",
"paid":true
},
"billing_address":{
"first_name":"XXX",
"last_name":"XXXX",
"company":"",
"address_1":"XXXX",
"address_2":"",
"city":"XXXX",
"state":"XX",
"postcode":"XXXXX",
"country":"US",
"email":"XXXXXX",
"phone":"XXXX"
},
"shipping_address":{
"first_name":"XXX",
"last_name":"XX",
"company":"",
"address_1":"XXXXX",
"address_2":"",
"city":"XXX",
"state":"XXX",
"postcode":"XXX",
"country":"XXXX"
},
"note":"",
"customer_ip":"98.216.25.236",
"customer_user_agent":"mozilla\/5.0 (iphone; cpu iphone os 12_4_1 like mac os x) applewebkit\/605.1.15 (khtml, like gecko) version\/12.1.2 mobile\/15e148 safari\/604.1",
"customer_id":127116,
"view_order_url":"XXXXX",
"line_items":[
{
"id":198261,
"subtotal":"55.00",
"subtotal_tax":"0.00",
"total":"55.00",
"total_tax":"0.00",
"price":"55.00",
"quantity":1,
"tax_class":"",
"name":"Core Hoodie - Black, Large",
"product_id":351,
"sku":"ss-hoodie-core-zip-blk-lg",
"meta":[
],
"bundled_by":"",
"bundled_item_title":"",
"bundled_items":[
],
"cogs_cost":"23.15",
"cogs_total_cost":"23.15"
}
],
"shipping_lines":[
{
"id":198263,
"method_id":"free_shipping",
"method_title":"Free shipping",
"total":"0.00"
}
],
"tax_lines":[
],
"fee_lines":[
{
"id":198262,
"title":"VIP Discount",
"tax_class":"0",
"total":"-5.50",
"total_tax":"0.00"
}
],
"coupon_lines":[
],
"cogs_total_cost":"23.15"
}
]
}
This is the furthest i've gotten
I found the following hooks but cannot get anything to trigger.
woocommerce_rest_prepare_shop_order_object
woocommerce_rest_prepare_shop_order
function remove_user_agent_from_rest_api( $response, $object, $request ) {
unset($response->data['customer_user_agent']);
return $response;
}
function test_rest_api() {
add_filter( "woocommerce_rest_pre_insert_shop_order", "remove_user_agent_from_rest_api", 10, 2 );
add_filter( "woocommerce_rest_pre_insert_shop_order_object", "remove_user_agent_from_rest_api", 10, 2 );
}
add_action( 'rest_api_init', 'test_rest_api', 0 );
Is this a performance tuning issue?
Here is a sample trace from new relic & a sample from my NGINX Error Log. What could I tune to keep the server open long enough to process this request.
2019/10/02 10:59:25 [error] 10270#10270: *5 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: XXX, server: X.net, request: "GET /?km_source=blog HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.0-fpm.sock:", host: "X.net", referrer: "https://www.X.net/"
2019/10/02 11:00:42 [error] 10270#10270: *34 upstream timed out (110: Connection timed out) while reading response header from upstream, client: XXX, server: XXX.net, request: "GET /wc-api/v2/orders?status=processing&page=10&filter%5Blimit%5D=100&consumer_key=ck_XXX&consumer_secret=cs_XXX HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.0-fpm.sock", host: "X.net"
2019/10/02 11:07:53 [error] 13021#13021: *62 upstream timed out (110: Connection timed out) while reading response header from upstream, client: XXX, server: XXX.net, request: "GET /wc-api/v2/orders?status=processing&page=1&filter%5Blimit%5D=100&consumer_key=ck_XXX&consumer_secret=cs_XXX HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.0-fpm.sock", host: "X.net"
2019/10/02 11:13:45 [error] 15270#15270: *66 upstream timed out (110: Connection timed out) while reading response header from upstream, client: XXX, server: XXX.net, request: "GET /wc-api/v2/orders?status=processing&page=1&filter%5Blimit%5D=100&consumer_key=ck_XXX&consumer_secret=cs_XXX HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.0-fpm.sock", host: "XXX.net"
2019/10/02 11:15:44 [error] 16010#16010: *79 upstream timed out (110: Connection timed out) while reading response header from upstream, client: XXX, server: X.net, request: "GET /wc-api/v2/orders?status=processing&page=1&filter%5Blimit%5D=100&consumer_key=ck_XXX&consumer_secret=cs_XXX HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.0-fpm.sock", host: "X.net"
The first issue I'd notice it that your filters are only passing 2 variables, when they should be passing 3.
add_filter( "woocommerce_rest_pre_insert_shop_order", "remove_user_agent_from_rest_api", 10, 3 );
Should do it.

How to add a "Authorization=Bearer" header with Indy in Delphi?

I'm trying to do a POST request using an access_token, and it works fine using POSTMAN, but when I try to do the same request on Delphi, I can't find a way to add the "Authorization=Bearer eyxxxxxx..." to the Request header, as POSTMAN does.
POSTMAN Request (working well):
POST /somepath HTTP/1.1
Host: someurl.com.br
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.....
Content-Type: application/json
(body content ommited)
Indy Request generated by Delphi, captured by HTTP Analyzer (always returning 401 Forbidden error, because the absence of "Authorization=Bearer" part):
POST /somepath HTTP/1.1
Host: someurl.com.br
Content-Type: application/json
(body content ommited)
I've tried to add the header using the code below, but the header part with the "Authorization=Bearer eyxxxxxx..." isn't generated on Request, returning the 401 Forbidden error.
FIdHTTP.Request.CustomHeaders.FoldLines := False;
FIdHTTP.Request.CustomHeaders.Add('Authorization=Bearer ' + txtToken.Text);
Just found the problem. I added the wrong separator between the "Authorization" and "Bearer" words.
Wrong:
FIdHTTP.Request.CustomHeaders.FoldLines := False;
FIdHTTP.Request.CustomHeaders.Add('Authorization=Bearer ' + txtToken.Text);
Correct:
FIdHTTP.Request.CustomHeaders.FoldLines := False;
FIdHTTP.Request.CustomHeaders.Add('Authorization:Bearer ' + txtToken.Text);
After replacing the '=' by ':', I received the expected response, like the one received by POSTMAN.

golang - HTTP client always escaped the URL

Is there anyway for golang HTTP client,not to escape the requested URL.
For example, a request for URL "/test(a)", gets escaped to "/test%28a%29".
I'm running the code from https://github.com/cmpxchg16/gobench
You can set an opaque url.
Assuming you want the url to point to http://example.com/test(a) you would want to do:
req.NewRequest("GET", "http://example.com/test(a)", nil)
req.URL = &url.URL{
Scheme: "http",
Host: "example.com",
Opaque: "//example.com/test(a)",
}
client.Do(req)
Example: http://play.golang.org/p/09V67Hbo6H
Documentation: http://golang.org/pkg/net/url/#URL
This appears to be a bug in the URL package:
https://code.google.com/p/go/issues/detail?id=6784
and https://code.google.com/p/go/issues/detail?id=5684
You need to set Unescaped Path to URL Path and Encoded Path to RawURL or else it will double escape e.g.
package main
import (
"fmt"
"net/url"
)
func main() {
doubleEncodedURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/id/EbnfwIoiiXbtr6Ec44sfedeEsjrf0RcXkJneYukTXa%2BIFVla4ZdfRiMzfh%2FEGs7f/events",
}
rawEncodedURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/id/EbnfwIoiiXbtr6Ec44sfedeEsjrf0RcXkJneYukTXa+IFVla4ZdfRiMzfh/EGs7f/events",
RawPath: "/id/EbnfwIoiiXbtr6Ec44sfedeEsjrf0RcXkJneYukTXa%2BIFVla4ZdfRiMzfh%2FEGs7f/events",
}
fmt.Printf("doubleEncodedURL is : %s\n", doubleEncodedURL)
fmt.Printf("rawEncodedURL is : %s\n", rawEncodedURL)
}
Playground link: https://play.golang.org/p/rOrVzW8ZJCQ

How can I disable nginx logging with limit_conn and limit_req?

How can I completely disable logging from HttpLimitConnModule and HttpLimitReqModule?
At least limit the damage done from extensive logging in case of a DOS-attack. I still want some error-logging but not when the request is denied.
Such messages:
2013/07/12 20:20:10 [error] 31544#0: *78 limiting requests, excess: 0.519 by zone "limit", client: *.*.*.*, server: example.com, request: "GET /static.html HTTP/1.1", host: "example.com", referrer: ""
One solution is to enable error_log just where it is needed.
server {
error_log /dev/null crit;
location ~\.php$ {
error_log /var/log/nginx_error.log;
}
}

Expected a HTTP 302 but get a HTTP 301 using NodeJS http client

I have this NodeJS snippnet :
require('http').get({
secure: true,
host: 'github.com',
method: 'GET',
path: '/downloads/Graylog2/graylog2-web-interface/graylog2-web-interface-0.9.6.tar.gz',
'headers': {
Host: 'github.com'
}}).on('response', function(response) {
console.log(response.statusCode);
});
It is suppose to do a simple GET request on https://github.com/downloads/Graylog2/graylog2-web-interface/graylog2-web-interface-0.9.6.tar.gz (sample)
The problem I face is the HTTP status, using the NodeJS client I have 301 Moved Permanently. I am expected a 302 Found (actually what I get with Chrome, cUrl, http://web-sniffer.net,...).
Thanks
There is no secure option for request. What you want is to instead use the https module.
require('https')

Resources