Why nginx $request_uri contains only one parameter? - nginx

My nginx config:
server {
listen 80;
server_name test.app;
location / {
echo $request_uri;
}
}
Then i perform GET request via curl and i can see only first parameter. All others are lost:
# curl http://test.app?p1=v1&p2=v2
> /?p1=v1
As i understand, $request_uri should contains all GET arguments. Why they are lost?
Nginx is installed via apt-get.

You have to escape the & if you do a curl on the command line otherwise you will do curl http://test.app?p1=v1 and send it to the background.
curl http://test.app?p1=v1\&p2=v2 should do the trick.

Related

Nginx sever block not function as expected

I'm using this config file with nginx:
server {
listen 80;
server_name harrybilney.co.uk;
location / {
proxy_pass http://localhost:8080;
}
}
server {
listen 80;
server_name kyra-mcd.co.uk;
location / {
proxy_pass http://localhost:8080;
}
}
Which is stored in /etc/nginx/sites-avaliable. The server block for the domain kyra-mcd.co.uk works perfectly as expected but the server block for harrybilney.co.uk does not and my browser cannot find the server for harrybilney.co.uk.
Both domains are hosted with GoDaddy and have the exact same DNS settings pointing towards my static IP (IPv4 and IPv6 with A and AAAA records).
Can anyone explain why I'm having this issue as I've tried changing the config but getting luck. I understand this is a very basic config file for nginx but for now I'm just trying to get both domains working on my 1 static IP before I add in anything complex.
Having both server blocks in a single file IS NO PROBLEM!
Here is a default.conf file:
server {
listen 80;
server_name harrybilney.co.uk;
location / {
return 200 "$host\n";
}
}
server {
listen 80;
server_name kyra-mcd.co.uk;
location / {
return 200 "Host should match kyra-mcd.co.uk = $host\n";
}
}
Test and reload your config by issuing sudo nginx -t && sudo nginx -s reload
The curl test:
$# curl -H "Host: kyra-mcd.co.uk" localhost
Host should match kyra-mcd.co.uk = kyra-mcd.co.uk
$# curl -H "Host: harrybilney.co.uk" localhost
harrybilney.co.uk
As you can see both servers are in a single file and the server_name taking care of finding the correct server-block based on the Host header.
Check your DNS one more time. Worh it:
kyra-mcd.co.uk. 600 IN A 90.255.228.109
harrybilney.co.uk. 3600 IN A 90.255.228.109
Looks good to me as well. So the traffic should hit the server.
So your configuration looks good for me. Make sure everything is loaded by issuing sudo nginx -T.
curl is working on my end. So looks like the problem is related to DNS on your end. Can you confirm curl is working from your end as well?

403 response when trying to redirect using nginx to API Gateway

I have the following API: https://kdhdh64g.execute-api.us-east-1.amazonaws.com/dev/user/${user-id} which proxies to a Lambda function.
When the user hits /user/1234 the function checks if 1234 exists and return the info for that user or a redirection to /users
What I want is to create is a redirection with nginx. For SEO, I want a simple 302: return 302 the-url. If someone goes to mySite.com it should redirect to https://kdhdh64g.execute-api.us-east-1.amazonaws.com/dev
No matter what I do, I always receive a 403 with the following:
x-amzn-errortype: MissingAuthenticationTokenException
x-amz-apigw-id: QrFd6GByoJHGf1g=
x-cache: Error from cloud-front
via: 1.1 dfg35721fhfsgdv36vs52fa785f5g.cloudfront.net (CloudFront)
I will appreciate help.
If you are using the reverse proxy set up in nginx, add the below line in the config file and restart or reload the nginx configuration.
proxy_set_header Host $proxy_host;
I run into the same issue trying to run a proxy on Nginx towards an API Gateway which triggers a Lambda function on AWS. When I read the error logs on Nginx, I noticed that it had to do with the SSL version which Nginx was using to connect to API Gateway, the error was the following:
*1 SSL_do_handshake() failed (SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number) while SSL handshaking to upstream
I managed to fix it by adding this line:
proxy_ssl_protocols TLSv1.3;
I attach the complete Nginx configuration in case anyone wants to build a static IP proxy on Nginx that redirects traffic towards a Lambda function:
server {
listen 443 ssl;
server_name $yourservername;
location / {
proxy_pass https://$lambdafunctionaddress;
proxy_ssl_server_name on;
proxy_redirect off;
proxy_ssl_protocols TLSv1.3;
}
ssl_certificate /home/ubuntu/.ssl/ca-chain.crt;
ssl_certificate_key /home/ubuntu/.ssl/server.key;
}
Also it is important to consider that all required information must be included on the request:
curl -X POST https://$yourservername/env/functionname -H "Content-Type: application/json" -H "x-api-key: <yourapikey>" -d $payload

How to ignore Content Length in Nginx?

Faced with a problem: if GET request was supplied with non-zero Content-Length property and there is no body, nginx will not proxy this request. Example of how to reproduce it:
nginx version: nginx/1.10.3 (Ubuntu)
# conf.d/main.conf
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:5060;
}
}
When listen 5060 port via netcat: nc -l -p 5060
After, make CURL request:
curl -vvv -X GET http://example.com/ -H 'Content-Length: 1'
This request will be closed after default proxy_send_timeout 60s.
As i understand, Nginx see Content-Length and wait body before transmit request to proxy. How to resolve it, without changing the reqest header?
Please note: i tried to do it with Haproxy - it work despite non-zero Content-Length and zero body.

nginx redirection to another server

I compiled the nginx 'echo-nginx-module' module to log the request body.
My goal is to log and reverse proxy all the traffic coming to nginx to another DNS.
I am using proxy_pass to redirect the traffic to the second DNS and it successfully started to log the traffic body.
However, what's missing is I also need to log the traffic header and timestamp.
I've added the lines below to the proxy_pass config file and it does not seem to log headers. What am I missing?
location / {
# the below four lines do not log header and body
echo "headers are:"
echo $echo_client_request_headers;
echo_read_request_body;
echo $request_body;
# this works and logs traffic envelope
proxy_pass https://offexserver-test-internal.leapaws.com.au;
root html;
index index.html index.htm;
}
You should be doing something like this
http {
log_format custom '$request_body';
server {
server_name default_server;
listen 80;
location / {
echo_read_request_body;
}
}
}
You cannot log all the headers, the only thing you can do is, specify the headers individually you want to log. or you will have to use an additional module to configure headers.

Nginx Stripping POST body on proxy_pass

I have a server running behind a firewall, with a single external IP, which therefore has requests proxied by domain through via an Nginx box.
When I run cURL behind the firewall, everything goes to plan:
HTTP/1.1 200 OK
The cURL is:
curl -H "Content-Type: application/json" -X POST --data #test.json 111.111.111.111/endpoint/ -i
As soon as I run this in Postman/Hurl.it/whatever from outside the network, I get 400 errors. The code throws a 400 when it is missing the POST body (JSON). Echoing this out shows that no JSON is being received.
The relevant Nginx configuration is thus:
server {
listen 80;
server_name domain.co;
location / {
proxy_pass http://111.111.111.111/;
proxy_set_header Host $host;
}
}
The domain does sit behind CloudFlare, and I've switched it to DNS only and tried that - I'd be very surprised if that was the issue.
I've had a look at other solutions, and tried some stuff out but I'm not really sure what I'm doing wrong here, unless I fundamentally misunderstand how proxy_pass works?

Resources