Assume my web app is hosted on https://example.com, I am testing my HTTP verbs on my server, I have nginx there,
curl -v -X TRACE https://example.com
For above I am getting a response. Instead, I should get 404 or other.
I had tried the below conf in Nginx server location block.
if ($request_method !~ ^(GET|HEAD|POST)$ ){
return 444;
}
This works for me but TRACE is still allowed. How should I stop it?
You could try using limit_except instead, like this:
location / {
limit_except GET HEAD POST { deny all; }
}
Related
I'm trying to do something which seems fairly trivial to me, but can't seem to get it right with Caddy.
I have the following site configured with Caddy:
foo.com {
tls {
dns cloudflare ...
}
reverse_proxy /* http://proxy-foo
}
I'm now trying to enable a maintenance page, such that all requests serve the maintenance html, and return a 503 status code. But, I can either serve the page, or the status code, but not both.
I first tried the handle_errors directive, with a respond directive
foo.com {
tls {
dns cloudflare ...
}
# reverse_proxy /* http://proxy-foo
handle_errors {
rewrite * /503.html
file_server
}
respond * 503
}
only to later read the caveat that respond doesn't trigger the error handlers.
Also tried removing all other directives, thinking that would trigger a 404, which would in turn call the handle_errors block, but that too doesn't work. It just ends up returning 200, but with no body.
Any pointers as to where I'm going wrong much appreciated.
You can try configure reverse_proxy directive.
That code similar to docs example is worked for me:
:80
reverse_proxy localhost:8000 {
#error status 500 503
handle_response #error {
respond "Something bad happened. If the error occurs again, please contact me at example#mail.com"
# i guess we can use other directives like redirect
}
}
Consider the following nginx config file:
server {
listen 443;
ssl on;
ssl_certificate /etc/tls/cert.pem;
ssl_certificate_key /etc/tls/key.pem;
location / {
proxy_pass http://api.default.svc.cluster.local;
}
}
All incoming TCP requests on 443 should redirect to my server running on api.default.svc.cluster.local:80 (which is a node REST-Api btw). This works fine, I can curl https://<nginx-IP>/ nginx and get a correct response, as expected.
Now, I'd like to change the location from / to /api, so I can fire a curl https://<nginx-IP>/api in order to get the same response as before.
1. Attempt
So I change the location line in the config to:
location /api {
Unfortunately this won't work, instead I get an error Cannot GET /api which is a node error, so obviously it gets routed to the api but something's still smelly.
2. Attempt
It seems as the trailing slash in an URI is required so I added it to the location:
location /api/ {
Now something changed. I won't get the same error as before, instead I get an "301 moved permanently". How can I fix my nginx config file?
Additional information regarding the environment
I'm using a kubernetes deployment that deploys the nginx reverse proxy incl. the config introduced. I then expose nginx using a kubernetes service. Also, I tried using kubernetes ingress to deal with this situation, using the same routes, however, the ingress service would respond with a default backend - 404 message.
As mentioned in the question, trailing slashes in URIs are important. I fixed this in the location, however, I didn't add it to the URI I pass using proxy_pass.
As for the nginx proxy I got it to work using the following config:
server {
listen 443;
ssl on;
ssl_certificate /etc/tls/cert.pem;
ssl_certificate_key /etc/tls/key.pem;
location /api/ {
proxy_pass http://api.default.svc.cluster.local/;
}
}
Concerning the ingress solution, I was not able to get it to work by adding the missing trailing slash to the path. The service is specified due its name and therefore no trailing slash can be added (i.e. it would result in an error).
I'm writing a web application using MEAN Stack and I've encountered a problem that I cannot solve, no matter what I try or search.
I'm trying to login using passport/passport-facebook with ExpressJS. If I write in the URL of my browser localhost/api/auth/facebook everything runs fine.
However if I create an element in my HTML code like this Login with Facebook it takes me to my 404 page (see nginx below).
And if I try with the Angular way, like this <button ng-click="login_fb()">Login with Facebook</button>, I get a No 'Access-Control-Allow-Origin' header is present on the requested resource. error.
I believe that I should use the <a href="..."> element but I think my nginx script is blocking it, since I enabled CORS on my NodeJS Server, with this:
server.all('/*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
next();
});
I'll leave my nginx script too (ignore the blocks inside '<' and '>'):
worker_processes 4;
events {
worker_connections 1024;
}
http {
upstream backend {
server 127.0.0.1:8080;
}
# To optimize the response of static files
sendfile on;
server {
# Listen to normal port
listen 80;
# Let through files like CSS, JPG, JS, ...
include mime.types;
# Alias for this server
server_name <my-domain>;
# Where the HTML files are located
root <my-folder>;
# Route for API calls
location /api/ {
proxy_pass http://backend;
}
# Route for the index
location ~ ^/*$ {
index index.html index.htm;
}
# Route for 404 page
error_page 404 /index.html;
}
}
EDIT: Using the link like this Login with Facebook but it forces me to use the URL hardcoded and I'll eventually put this app under a domain.
NEW EDIT: I realise that using like this Login with Facebook doesn't work because it thinks it a Angular route, and since I haven't declared in $routeProvider, it takes me to 404.
To avoid the 404, add target="_self" to your link Login with Facebook. It will bypass the angular router.
With the other method, I think you get No 'Access-Control-Allow-Origin' because when you use the angular $http service it's blocked by CORS same-origin policy at the FB API.
You should stick to the link, if you want to do this on the angular end, I recommend this plugin: https://github.com/sahat/satellizer.
I've got stuck with this problem for 3 days.
My Server is Centos, and use wordpress (WP) in Httpd service.
Its IP is '103.232.120.178'
I want to use nginx as reverse proxy for WP.
Httpd is in port 2101
Nginx is in port 80
WP is in sub directory: 'bongda69' (url: '103.232.120.178:2101/bongda69')
I want if visit mywebsite, it redirect to wordpress.
Ex: visit '103.232.120.178', it will display as WP site: '103.232.120.178:2101/bongda69'
My nginx.conf is:
user apache apache;
worker_processes 4;
error_log /var/log/nginx/error.log;
events {
worker_connections 1024;
}
http {
upstream backend {
server localhost:2101; # IP goes here.
}
server {
listen 103.232.120.178:80; # IP goes here.
location / {
proxy_pass http://backend/bongda69/;
}
} # End server
} # End http
and in General Settings in WP, I configure:
WordPress Adress(URL): http://103.232.120.178/bongda69
Site Adress(URL): http://103.232.120.178/bongda69
But, when visit 'http://103.232.120.178', error display:
Not Found
The requested URL /index.php was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
If I configure nginx like this:
location / {
proxy_pass http://backend/;
}
Everything is Okie. But I must visit site "http://103.232.120.178/bongda69", and I don't want it.
What is my mistake?
Anyone can help me?
Thanks a lott!!!
This should work
worker_processes 4;
error_log /var/log/nginx/error.log;
events {
worker_connections 1024;
}
http {
upstream backend {
server 103.232.120.178:2101; # IP goes here.
}
server {
listen 0.0.0.0:80; # IP goes here.
location / {
proxy_pass http://backend/bongda69;
}
} # End server
} # End http
added
I suggest adding
/var/log/nginx/access.log;
in order to see whats happens with your request
How to pass parameters in nginx url. When I hit http://127.0.0.1:1000/samp/test1/result?num1=10&num2=30, it should redirect me to http://127.0.0.1:80/samp/test1/result?num1=10&num2=30. Is this possible? Below is my nginx config file.
upstream apache {
server 127.0.0.1:1000;
}
server {
listen 80;
server_name 127.0.0.1;
location / {
#root html;
#index index.html index.htm;
#return 503;
proxy_pass http://apache;
}
}
I think what you want to do is possibe, but you'd have to make that configuration change on the apache end of things.
If 'apache' handles a request coming into port 1000 directly, it will see a URI like this:
http://127.0.0.1:1000/samp/test1/result?num1=10&num2=30
However, if it is sent through nginx, it will look more like this:
http://apache/samp/test1/result?num1=10&num2=30
So, you could check the incoming URL for :1000 and then rewrite the request on the apache side to go to port 80 instead ( which is the default, so you don't need :80 - you can just leave the port unspecified entirely.
If the backend really is apache, you can use a rewrite rule there to handle the rewriting.
However, if you're not already on port 80, you're not connecting to nginx - so nginx can't rewrite this for you.
Hope it makes sense!
Here's how I tested:
Apache side I used a quick sinatra (ruby) app to print out the full URI of the request it sees:
require 'sinatra'
set :bind, "0.0.0.0"
set :port, 1025
get "/*" do
"<p>Hello from \"apache\"! You've just requested:
<code>#{request.url}</code></p>
"
end
Then nginx is configured thusly:
upstream apache {
server 192.168.70.1:1025;
}
server {
server_name localhost;
location / {
proxy_pass http://apache;
}
}
Note I used port 1025, because port 1000 is a privileged port.
I used curl to generate the requests to test:
$ curl 'http://192.168.70.1:1025/samp/test1/result?num1=10&num2=30'
<p>Hello from "apache"! You've just requested:
<code>http://192.168.70.1:1025/samp/test1/result?num1=10&num2=30</code></p>
$curl 'http://127.0.0.1:80/samp/test1/result?num1=10&num2=30'
<p>Hello from "apache"! You've just requested:
<code>http://apache/samp/test1/result?num1=10&num2=30</code></p>
If I wanted to do the redirect you're describing, I could match with a regular expression of IPV4 address and port and redirect as such:
get "/*" do
if request.url =~ %r|^http://([0-9]{1,3}\.){3}[0-9]{1,3}:1025/|
redirect "http://localhost:80/#{request.fullpath}"
else
"<p>Hello from \"apache\"! Tou've just requested:
<code>#{request.url}</code></p>
"
end
end
Now I tell curl to follow redirects (-L) and we see it redirect me over to the "correct" route.
$ curl -L 'http://192.168.70.1:1025/samp/test1/result?num1=10&num2=30'
<p>Hello from "apache"! Tou've just requested:
<code>http://apache/samp/test1/result?num1=10&num2=30</code></p>
I know it's not the language you're using, but I hope it iwll help you get started.