I am trying to passwoard protect the default server in my Nginx config. However, no username/password dialog is shown when I visit the site. Nginx returns the content as usual. Here is the complete configuration:
worker_processes 1;
events
{
multi_accept on;
}
http
{
include mime.types;
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
tcp_nodelay on;
gzip on;
# Set path for Maxmind GeoLite database
geoip_country /usr/share/GeoIP/GeoIP.dat;
# Get the header set by the load balancer
real_ip_header X-Forwarded-For;
set_real_ip_from 0.0.0.0/0;
real_ip_recursive on;
server {
listen 80;
server_name sub.domain.com;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd/sub.domain.com.htpasswd;
expires -1;
access_log /var/log/nginx/sub.domain.com.access default;
error_log /var/log/nginx/sub.domain.com.error debug;
location / {
return 200 '{hello}';
}
}
}
Interestingly, when I tried using an invalid file path as the value of auth_basic_user_file, the configtest still passes. This should not be the case.
Here's the Nginx and system info:
[root#ip nginx]# nginx -v
nginx version: nginx/1.8.0
[root#ip nginx]# uname -a
Linux 4.1.7-15.23.amzn1.x86_64 #1 SMP Mon Sep 14 23:20:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
We are using the Nginx RPM available through yum.
You need to add auth_basic and auth_basic_user_file inside of your location block instead of the server block.
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd/sub.domain.com.htpasswd;
return 200 '{hello}';
}
Did you tried to reload/stop-and-start your nginx after basic auth was added to config? It is necessary to reload nginx with something like:
sudo -i service nginx reload
---- in order to make new settings work.
Also I would double check the URLs that are under your tests.
(Once I tried to test Nginx Basic Auth in an Nginx proxy configuration accessing the actual URL of the resource that was behind the Nginx proxy and not the actual URL of Nginx.)
P.S.
Using an invalid file path as the value of auth_basic_user_file still doesn't cause the configtest to fail in 2018 as well.
Here's my version of Nginx:
nginx version: nginx/1.10.2
Though an invalid file path causes Basic Auth check to be failed and results in:
403 Forbidden
---- HTTP response after credentials provided.
In my case, adding the directives to /etc/nginx/sites-available/default worked, whereas adding the directives to /etc/nginx/nginx.conf did not.
Of course this only happens if you have this in your nginx.conf file:
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
The config is simple (put it under location for specific part of your website, or under server for your whole website):
server {
location /foo/ {
auth_basic "This part of website is restricted";
auth_basic_user_file /etc/apache2/.htpasswd;
}
}
Related
I have a full stack site designed to run on port 80 with the Node backend using port 5000. This site runs without fail on a Windows 10 machine.
When I copy it to a domain server running on 2012 R2 I cannot get it to function on port 80, although port 90 shows with no problems.
IIS is turned off and netstat -aon shows that Node is the PID using port 80. I then tried building the page and serving it with NGINX and am getting the same results, except that NGINX is now the process using port 80.
Here is the code I believe to be relevant but am uncertain of what to do with it.
My .env file for react-app is simple:
PORT=80
When switching to port 90 it functions successfully.
If I attempt to run through NGINX (with which I am unfamiliar) using the following configuration:
worker_processes 1;
events {
worker_connections 1024;
}
http {
# include mime.types;
# default_type application/octet-stream;
# sendfile on;
# keepalive_timeout 65;
# gzip on;
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:90;
root C:\intranet\New_Test\frontend\build;
index $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:5000;
}
}
}
I still get nothing.
I have also tried it without forwarding port 80 to port 90 with the same results.
Do I have an incorrect configuration somewhere? The netstat also says that SYSTEM is using port 80 for some reason but it is also using a number of other HTTP ports.
** Edit **
I have since updated my nginx.conf file to this:
worker_processes 1;
events {
worker_connections 1024;
}
http {
# include mime.types;
# default_type application/octet-stream;
# sendfile on;
# keepalive_timeout 65;
# gzip on;
include mime.types;
server {
listen 90;
server_name localhost;
root html;
index /index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:5000;
}
}
}
This is working fine to display the site in port 90 but for whatever reason port 80 in inaccessible to me on this machine.
Switched to a different model. Putting this answer to close the question. Went with nssm (https://alex.domenici.net/archive/deploying-a-node-js-application-on-windows-iis-using-a-reverse-proxy - step 5) and hosted the built React portion through IIS and using NSSM to run node as a service. Works well on local machine if I set my REACT_APP_HOST to localhost. Now experimenting with pathing so that the server can be reached from any client, not just a page on the localhost server.
I'm trying to use Nginx to expose my Web APIs on port 80 using proxy_pass. The Web APIs are written in Node using Express and they are all running on separate port numbers.
I have locations working in the nginx.conf file when pulling static files from the root and /test, but receive a 404 error when trying to redirect to the API. The API I'm testing with runs on port 8080 and I'm able to access and test it using Postman.
This is using Nginx 1.16.1 being hosted on a Windows 2016 Server
http {
include mime.types;
default_type application/octet-stream;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost crowdtrades.com;
//Root and /test locations are working correctly
location / {
root c:/CrowdTrades;
index index.html index.htm;
}
location /test/ {
root c:/CrowdTrades/test;
index test.html;
}
// #Test2 this is the location I'm not able to get working
location /test2/ {
proxy_set_header Host $host;
proxy_pass http://localhost:8080/api/signup/;
}
}
}
So after trying all kinds of configuration changes and restarting Nginx each time I gave up for the night. My cloud VM is scheduled to shut down at night, when I picked this up in the AM it was working. I have no idea why it's working now but restarting the server seemed to help.
I try to setup a web server with Docker, so I will use the main domain of my server "server.domain.com" for admin use (server.domain.com/phpmyadmin, ect...) and I want to redirect all the other domain to an apache container who listen on port 81.
So I have this code on my default.conf:
server {
listen 80;
listen [::]:80 default_server;
location / {
proxy_pass http://web/;
}
}
main.conf:
server {
listen 80;
listen [::]:80;
server_name server.domain.com;
location /phpmyadmin/ {
proxy_pass http://phpmyadmin/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
(Updated conf)
And my nginx.conf:
user nginx;
worker_processes 2;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_comp_level 5;
gzip_http_version 1.0;
gzip_min_length 0;
gzip_types *;
gzip_vary on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites/*;
}
a part of ‘docker-compose.yml‘:
nginx:
build: ./server/proxy
ports:
- "80:80"
#volumes:
#- nginx_conf:/etc/nginx/
networks:
- web_network
depends_on:
- web
- phpmyadmin
- panel
At this moment I use "depends_on" for use the name of the container on my config but you talk only about network so I think "depends_on" is not obliged ?
But that gives me an error connection refused.
If I replace the 127.0.0.1 by server.domain.com the first vhost not working and redirect to nginx webRoot.
So I have no idea why ...
Thank you !
As far as I understand this nginx container is listening on port 80 and all connection requests going to your machine will be passed to it. So it's a proxy container only. I have a project with similar implementation. Let's try to make it out.
I suggest that you have 2 conf files for clarity.
1) main.conf - will serve your "server.domain.com"
server {
listen 80;
listen [::]:80;
server_name server.domain.com;
location /phpmyadmin {
proxy_pass http://server.domain.com:82;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
That's all of the configuration you basically need here. Later if you need them, you'll pass headers.
2) default.conf - will serve any other domain
server {
listen 80;
listen [::]:80 default_server;
location / {
proxy_pass http://server.domain.com:81;
}
}
This configuration assumes that:
1) There is a container running apache and requests coming to your machine on port 81 will be passed to apache2 container's port 80 (or whatever it's listening to)
2) There is a container running phpmyadmin and requests coming to your machine on port 82 will be passed to phpmyadmin container's port 80 (or whatever...)
SOME IMPROVEMENTS YOU SHOULD CONSIDER:
1) If you start all those containers with docker-compose you'll be able to set up a virtual network for them. This would allow you to proxy pass requests straight to the container by name. In my project I do it like:
proxy_pass http://adminer;
where adminer is defined as:
adminer:
image: phpmyadmin/phpmyadmin
volumes:
- ./db_interface/conf/config.inc.php/:/etc/phpmyadmin/config.inc.php
networks:
- demo_webnet
- prod_webnet
If you have questions just ask, I'll explain.
2) You could place another nginx server together with your apache2 server in its container. They work nice in bundle. Nginx is better to server statics. Apache2 better suits PHP in your case. I can show you how to do that as well.
IN CASE YOU NEED IT
It looks like you're trying to do something similar to what I did for our company's needs. If you're interested I can give you access to my project. I've built up a whole server infrastructure with docker and it now perfectly deployed on our server. In short it works as follows:
nginx proxy container above all
a container with apache2-nginx-php5.6 for demo apps
a container with apache2-nginx-php7.0 for demo apps
a container with apache2-nginx-php5.6 for production apps
a container with apache2-nginx-php7.0 for production apps
a container with maria db for demo
a container with maria db for production
a container with phpmyadmin to access both db services
Any request comes to nginx proxy.
It matches some virtual host and gets proxied to one of the 4 containers that have apache2 and nginx inside.
Also there is a lot of cool stuff like cron configured to autoreload apache2 and nginx when it detects changes to files, supervising services, https support and so on..
I'm planning to further develop it as an open source project, whoever is interested should let me know.
Multiple virtual hosts on my workstation, just stopped working. Upon an update of nginx to v1.10.2 and a new Passenger locations.ini file pointer in the nginx.conf file, I'm getting 403 Forbidden permissions errors on all of these vhosts. No clue what to look at.
passenger_root /usr/local/opt/passenger/libexec/src/ruby_supportlib/phusion_passenger/locations.ini;
passenger_ruby /usr/bin/ruby;
But, which ruby:
/Users/rich/.rbenv/shims/ruby
So I changed that directive to the one above. Restart nginx, and still the same. The error reported:
2017/10/23 19:51:36 [error] 10863#0: *61 directory index of "/Library/WebServer/Documents/alpha/public/" is forbidden, client: 127.0.0.1, server: alpha.local, request: "GET / HTTP/1.1", host: "alpha.local"
Permissions haven't changed ever. Not to mention they are relaxed (only seen by me):
drwxrwxrwx 20 rich admin 680B Jun 17 01:52 HQ
cd HQ:
drwxr-xr-x 8 rich admin 272B Jul 12 17:32 public
nginx.conf:
user root admin;
worker_processes 8;
error_log /usr/local/var/log/error.log debug;
pid /usr/local/var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
# index index.html index.erb;
access_log /usr/local/var/log/access.log;
passenger_root /usr/local/Cellar/passenger/5.1.11/libexec/src/ruby_supportlib/phusion_passenger/locations.ini;
passenger_ruby /Users/rich/.rbenv/shims/ruby;
passenger_friendly_error_pages on;
include /usr/local/etc/nginx/servers/*; # see below
}
server {
listen 80;
server_name alpha.local;
include /usr/local/etc/nginx/mime.types;
access_log /usr/local/var/log/access_alpha.log;
error_log /usr/local/var/log/error_alpha.log debug;
error_page 404 /404.html;
root /Library/WebServer/Documents/alpha/public;
passenger_enabled on;
passenger_base_uri /;
location / {
autoindex off;
# try_files $uri $uri/ /index.html?$query_string;
# index /;
# allow 192.168.1.0/24;
}
location = /img/favicon.ico { access_log off;}
}
nginx error log:
2017/10/24 15:35:39 [error] 10868#0: *86 directory index of "/Library/WebServer/Documents/alpha/public/" is forbidden, client: 127.0.0.1, server: alpha.local, request: "GET / HTTP/1.1", host: "alpha.local"
Odd stuff. Any ideas appreciated how to get all this serving again properly. It seems permissions were completely thrown off, and I'm not sure if it was the nginx update or not. Cheers
==============
Update 2: (changed alpha/HQ). Also, replicated on a completely separate box. Homebrew update, trips over nginx's dependency on openssl, which wants to update to version 1.1. I've posted in Github there. While I have no proof, it's the only feedback I have that shows a non-upgrade (still serving 1.12.0 instead of 1.12.2). So I am thinking it is that.
https://github.com/Homebrew/homebrew-core/issues/19810
Fixed. Homebrew issue, conditional if Passenger is installed, choosing version of openssl (openssl, openssl#1.1).
I am running Ubuntu Hardy 8.04 and nginx 0.7.65, and when I try starting my nginx server:
$ sudo /etc/init.d/nginx start
I get the following error:
Starting nginx: [emerg]: bind() to IP failed (99: Cannot assign requested address)
where "IP" is a placeholder for my IP address. Does anybody know why that error might be happening? This is running on EC2.
My nginx.conf file looks like this:
user www-data www-data;
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /usr/local/nginx/logs/access.log;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 3;
gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml
application/xml+rss text/javascript;
include /usr/local/nginx/sites-enabled/*;
}
and my /usr/local/nginx/sites-enabled/example.com looks like:
server {
listen IP:80;
server_name example.com;
rewrite ^/(.*) https://example.com/$1 permanent;
}
server {
listen IP:443 default ssl;
ssl on;
ssl_certificate /etc/ssl/certs/myssl.crt;
ssl_certificate_key /etc/ssl/private/myssl.key;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP;
server_name example.com;
access_log /home/example/example.com/log/access.log;
error_log /home/example/example.com/log/error.log;
}
With Amazon EC2 and elastic IPs, the server doesn't actually know its IP as with most any other server.
So you need to tell your linux to allow processes to bind to the non-local address. Just add the following line into /etc/sysctl.conf file:
# allow processes to bind to the non-local address
# (necessary for apache/nginx in Amazon EC2)
net.ipv4.ip_nonlocal_bind = 1
and then reload your sysctl.conf by:
$ sysctl -p /etc/sysctl.conf
which will be fine on reboots.
To avoid hard-coding the IP address in the config, do this:
listen *:80;
listen [::]:80;
As kirpit mentioned above you'll want to allow linux processes to bind to a local IP address:
nano /etc/sysctl.conf
# allow processes to bind to the non-local address
net.ipv4.ip_nonlocal_bind = 1
sysctl -p /etc/sysctl.conf
Then you want to add the private ip address that is associated with your elastic ip and add that to your sites config:
nano /etc/nginx/sites-available/example.com
Reload nginx:
service nginx reload
All done!
There might be remaining process/program that's using/listening at port 80.
You can check that using netstat -lp.
Kill that process and start nginx.
With Amazon EC2 and elastic IPs, the server doesn't actually know its IP as with most any other server. So in the apache virtual host files at least you put *:80 rather than your elastic ip :80
Then it works properly. So theoretically, doing *:80 for nginx should work the same but when you do you get [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use). Haven't found a solution yet.
.
For people who might be dealing with this in the future, I just looked up my private IP in the AWS instance and bound to that. I verified that nginx was able to listen publicly and perform my rewrite after that. I could not do *:PORT as I had an internal server I was proxying to.
If you are using Network Manager, you have to wait to raise the network interface before starting the service:
systemctl enable NetworkManager-wait-online.service
For Amazon EC2 and elastic IPs, sysctl.conf will not work as nginx still not listen on eth0.
So, you need to listen *;