nginx - exclude all but two files - nginx

I need to allow the internet access to 2 files on my Nginx 1.6.0 web server:
[www.example.com/piwik.php][1]
[www.example.com/piwik.js][2]
Everything else needs to be blocked. What is the correct location directive to use? I have the below and it is only partially working:
# allow everyone to access piwik.php
location ~ /piwik.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# allow everyone to access piwik.js
location ~ /piwik.js$ {
root html;
index index.html index.htm;
}
# The below appears to allow index.php to load, but blocks
# files beneath it (e.g. js/file1.js, imgs/pic1.jpg) so the page
# is only half-rendered and I see a bunch of 403's in my NGINX logs.
# People are still able to access the half-loaded index.php webform
# and login!!!
location / {
allow 192.168.1.1
deny all;
root html;
index index.php index.html index.htm;
}
Access Log below:
1.2.3.4 - - [04/May/2014:20:04:22 -0400] "GET
/libs/jquery/stylesheets/jquery.smartbanner.css?cb=ef21e462d0300ea546811bec0ee6a912
HTTP/1.1" 403 162 "https://example.com/index.php" "Mozilla/5.0 (iPhone; CPU iPhone OS
7_1_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D201
Safari/9537.53"
1.2.3.4 - - [04/May/2014:20:04:22 -0400] "GET /plugins/Login/stylesheets/login.css?
cb=ef21e462d0300ea546811bec0ee6a912 HTTP/1.1" 403 162 "https://example.com/index.php"
"Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML,
like Gecko) Version/7.0 Mobile/11D201 Safari/9537.53"
1.2.3.4 - - [04/May/2014:20:03:15 -0400] "GET /plugins/Morpheus/images/logo.svg
HTTP/1.1" 403 162 "https://example.com/index.php" "Mozilla/5.0 (iPhone; CPU iPhone OS
7_1_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D201
Safari/9537.53"
The errors look like the below when users try to access the main page (index.php).
2014/05/06 14:17:51 [error] 6917#0: *385 access forbidden by rule, client: 180.76.X.X, server: example.com, request: "GET /robots.txt HTTP/1.1", host: "example.com"
2014/05/06 15:21:47 [error] 6917#0: *392 access forbidden by rule, client: 66.249.X.X, server: example.com, request: "GET / HTTP/1.1", host: "example.com"
2014/05/06 15:38:24 [error] 6917#0: *398 access forbidden by rule, client: 66.249.X.X, server: example.com, request: "GET / HTTP/1.1", host: "example.com"
2014/05/06 19:02:45 [error] 6917#0: *412 access forbidden by rule, client: 66.249.X.X, server: example.com, request: "GET / HTTP/1.1", host: "example.com"
2014/05/06 20:06:04 [error] 6917#0: *413 access forbidden by rule, client: 185.4.X.X, server: example.com, request: "GET http://24x7-allrequestsallowed.com/?PHPSESSID=1rmsxtj500143PRTJWQAY%40D%5EJFSX HTTP/1.1", host: "24x7-allrequestsallowed.com"
2014/05/06 20:09:22 [error] 6917#0: *414 access forbidden by rule, client: 66.249.X.X, server: example.com, request: "GET / HTTP/1.1", host: "example.com"

Related

Nginx custom 404 page fails when in a higher directory

I am trying to create a custom 404 page with Nginx. My nginx.conf file looks like this:
http {
server {
location / {
root /nginx/html;
}
error_page 404 /custom_404.html;
location = /custom_404.html {
root /nginx/html;
internal;
}
}
}
When I check with a URL like "/page_that_doesnt_exist", it works fine.
But if I add a trailing "/", eg "/page_that_doesnt_exist/" or "/page_that_doesnt_exist/and_more_stuff" it fails, returning a blank screen (not the default nginx 404 page).
When I check the server messages, it tells me the following:
"GET /page_that_doesnt_exist/ HTTP/1.1" 404 280 "-"
[error] 6#6: *3 open() "/nginx/html/page_that_doesnt_exist/error404.js" failed (2: No such file or directory), client: 172.17.0.1, server: , request: "GET /page_that_doesnt_exist/error404.js HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/page_that_doesnt_exist/"
"GET /page_that_doesnt_exist/error404.js HTTP/1.1" 404 280 "http://localhost:8080/page_that_doesnt_exist/"
Which I take to mean that instead of nginx searching for my "custom_404.html" file in my "nginx/html" folder, it is adding "page_that_doesnt_exist" to the directory. Thus it now searches in "nginx/html/page_that_doesnt_exist/" and doesn't find a "custom_404.html" file in that directory.
What am I doing wrong here?

RESOLVED NginX location / SafariPushNotification agent 404 on request

I am in need of some NginX expertise.
I am configuring a Safari Push Notifications web service with NginX. When the front end requests permission, the Safari agent fails to connect and fetch the push package with a 404:
NginX access log:
159.192.217.13 - - [09/Jul/2018:06:26:15 +0100] "POST /push/v2/pushPackages/web.com.domain.co HTTP/1.1" 404 56 "-" "SafariNotificationAgent (unknown version) CFNetwork/901.1 Darwin/17.6.0 (x86_64)" "-"
159.192.217.13 - - [09/Jul/2018:06:26:15 +0100] "POST /push/v1/pushPackages/web.com.domain.co HTTP/1.1" 301 185 "-" "SafariNotificationAgent (unknown version) CFNetwork/901.1 Darwin/17.6.0 (x86_64)" "-"
159.192.217.13 - - [09/Jul/2018:06:26:16 +0100] "GET /push/v1/pushPackages/web.com.domain.co HTTP/1.1" 403 169 "-" "SafariNotificationAgent (unknown version) CFNetwork/901.1 Darwin/17.6.0 (x86_64)" "-"
NginX error log:
2018/07/09 06:26:15 [error] 2774#0: *23 FastCGI sent in stderr: "Unable to open primary script: /www/data/push/v2/pushPackages/web.com.domain.co (No such file or directory)" while reading response header from upstream, client: 159.192.217.13, server: domain.com, request: "POST /push/v2/pushPackages/web.com.domain.co HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "domain.com"
2018/07/09 06:26:16 [error] 2774#0: *23 directory index of "/www/data/push/v1/pushPackages/web.com.domain.co/" is forbidden, client: 159.192.217.13, server: domain.com, request: "GET /push/v1/pushPackages/web.com.domain.co/ HTTP/1.1", host: "domain.com"
2018/07/09 06:26:18 [error] 2774#0: *25 directory index of "/www/data/push/v1/log/" is forbidden, client: 159.192.217.13, server: domain.com, request: "GET /push/v1/log/ HTTP/1.1", host: "domain.com"
(replaced server with domain.com)
NginX location conf:
location /push/v2/pushPackages/web.com.domain.co {
add_header "Access-Control-Allow-Origin" *;
allow all;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
I am convinced this configuration is not correct.
It is pointing to the directory /push/v2/pushPackages/web.com.domain.co where index.php then generates the push package zip, however it appears that index cannot be found.

docker wordpress and nginx user permission

Trying to setup wordpress and nginx in docker containers while sharing the volume from wordpress to nginx. While doing so, nginx is unable to read the files from the volume as the users are different. How do I solve this?
This is currently causing this error below:
wordpress_1 | 172.18.0.17 - 18/Feb/2018:15:39:27 +0000 "GET /index.php" 404
nginx_1 | 2018/02/18 15:39:27 [error] 7#7: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.18.0.1, server: galaxycard.in, request: "GET / HTTP/1.1", upstream: "fastcgi://172.18.0.13:9000", host: "127.0.0.1:3000"
nginx_1 | 172.18.0.1 - - [18/Feb/2018:15:39:27 +0000] "GET / HTTP/1.1" 404 47 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"

Using nginx as a proxy to to java web servlet

I'm trying to use nginx as a load balancer / proxy server which points to a series to tomcat servers. This is my current nginx configuration.
server {
listen 80;
server_name _;
rewrite ^ https://$http_host$request_uri? permanent;
}
server {
listen 443;
resolver 127.0.0.11 valid=5s;
ssl on;
ssl_certificate /etc/nginx/certs/default.crt; # path to your cacert.pem
ssl_certificate_key /etc/nginx/certs/default.key; # path to your privkey.pem
ssl_verify_client off;
server_name localhost;
fastcgi_param HTTPS on;
fastcgi_param HTTP_SCHEME https;
charset utf-8;
client_max_body_size 200M;
set $app https://app:8443;
set $auth https://auth:8443/authentication/;
set $discovery https://discovery:8443/discovery/;
location / {
proxy_pass $app;
}
location /authentication {
proxy_pass $auth;
}
location /discovery {
proxy_pass $discovery;
proxy_set_header Host $http_host;
proxy_set_header X_FORWARDED_PROTO https;
}
}
This is dockerized if it makes any difference, but provisioning fails to resolve correctly while docs is working fine. The only difference between docs and provisioning is that 'docs' is serving pure html files via tomcat. (The tomcat7 standard /docs/) while provisioning is actually a java servlet (JaxRS/spring etc ).
If I hit the image directly it works as expected, while if I try to hit the same endpoint via the nginx it fails to resolve.
My docker-compose configuration for reference.
version: '2'
services:
db:
image: db:nodata
expose:
- 5433
zk:
image: zookeeper
ports:
- 2181:2181
discovery:
image: services_discovery:latest
env_file: docker_environment
expose:
- 8443
ports:
- 8443:8443
links:
- db
- zk
app:
image: tomcat-jsse-ssl:7-jdk8
volumes:
- ./app/www/:/usr/local/tomcat7/webapps/ROOT/
expose:
- 8443
ports:
- 8444:8443
auth:
image: tomcat-jsse-ssl:7-jdk8
volumes:
- ./authentication/www/authentication/:/usr/local/tomcat7/webapps/authentication/
expose:
- 8443
proxy:
build: ./proxy/
depends_on:
- 'auth'
- 'app'
- 'discovery'
ports:
- 443:443
restart: always
With the images running I can resolve the following URLs just fine.
https://localhost:8443/discovery/ready
https://localhost:8444/
ie. both containers are running fine:
https://localhost/ loaded via nginx works fine.
https://localhost/authentication/ loaded via nginx works fine.
https://localhost/discovery/ready ==> 404.
Server Logs:
proxy_1 | 172.20.0.1 - - [24/Apr/2017:00:04:28 +0000] "GET /discovery/ready HTTP/1.1" 404 400 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
proxy_1 | 172.20.0.1 - - [24/Apr/2017:00:04:43 +0000] "GET /discovery/api/swagger.json HTTP/1.1" 404 400 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
proxy_1 | 172.20.0.1 - - [24/Apr/2017:00:04:57 +0000] "GET /discovery/ready HTTP/1.1" 404 400 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
Discovery Tomcat Access Log (when access directly)
172.20.0.1 - - [23/Apr/2017:00:02:38 +0000] "GET /discovery/ready HTTP/1.1" 200 70
172.20.0.2 - - [24/Apr/2017:00:04:28 +0000] "GET /discovery/ HTTP/1.0" 404 949
172.20.0.2 - - [24/Apr/2017:00:04:43 +0000] "GET /discovery/ HTTP/1.0" 404 949
172.20.0.2 - - [24/Apr/2017:00:04:57 +0000] "GET /discovery/ HTTP/1.0" 404 949
The first entry is when I hit the server directly via https://localhost:8443/discovery/ready everything else
is when nginx sends the request to the server. For some reason it's not translating the request correctly.
Any thoughts/suggestions would be appreciated?
Note: I simplified my example/config for the purposes of this question and any references to "provisioning" are now "discovery".
UPDATE: I figured out why it's breaking for the 'servlet'. It's actually breaking constantly. It's stripping away all of the URL except the base.
for example.
https://localhost/authentication?q=dummy
becomes
172.20.0.3 - - [24/Apr/2017:03:22:06 +0000] "GET /authentication/ HTTP/1.0" 200 28
note that the query parameters are stripped away.
The nginx documentation says that you are responsable to rebuild the url:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
So, you can try to capture the rest of the URI using regex and send it on the proxy_pass section:
location ~* ^/discovery/(.*) {
proxy_pass $discovery$1$is_args$args;
.... other configs....
}

How do I see the actual filepath that nginx is trying to access for a file?

Right now I've got Nginx setup to serve what I'm pretty sure is a valid filepath. However, it's giving me a 404 not found.
I've looked in /var/log/nginx/access.log and it shows me:
[05/Oct/2016:19:15:50 -0500] "GET /menu.html HTTP/1.1" 404 571 "-" "Mozilla/5.0 ....
But not what path it was trying to access on localhost, which should be /usr/share/nginx/html/menu.html. How do I configure Nginx to show me this information?
I recommend to try log_format directive with $realpath_root (or $document_root) and $request_filename attribute.
Read this documentations and customize Your logs as You wish:
http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format
http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
https://www.digitalocean.com/community/tutorials/how-to-configure-logging-and-log-rotation-in-nginx-on-an-ubuntu-vps
I believe the full path is shown in the error_log file for a 404.
Example:
2017/02/10 12:20:45 [error] : *239 open() "/usr/local/files/myFile.js" failed (2: No such file or directory), client: xxx.xxx.xxx.xxx, server: myserver.com, request: "GET /path/to/myFile.js HTTP/1.1", host: "myserver.com", referrer: "http://myserver.com/home"

Resources