I know that, this question has been asked multiple times on different forums, but still I can not manage to find a solution, which solves my problem... The situation: We have a nginx, php-fpm and MySQL stack on a server. The server sits behind a nginx reverse proxy. The problem is that on the upstream server there are clean error logs and on the reverse proxy I am getting multiple messages
connect() failed (110: Connection timed out) while connecting to >upstream, client: ++++++++++, server: domain.com, request: "GET >/files/imagecache/FrontBullet/blog1/dknasda.jpg HTTP/1.1", upstream: >"http://192.168.158.142:80/files/imagecache/FrontBullet/blog1/dknasda.jpg>", host: "somedomain.com"
For some reason this error occurs every 1-5 minutes for different resources or files.
My nginx config on the reverse proxy is the following one :
user ++++;
worker_processes 3;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
use epoll;
}
http {
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;
tcp_nodelay on;
keepalive_timeout 60s; #keeps the connection open with the client; MS default is 60.
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
upstream main_upstream {
server 192.168.158.142:80 max_fails=3 fail_timeout=60s; # New Server. Sent to 192.168.90
# server 192.168.158.143:80; # HSB
keepalive 32;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name domain.com;
location / {
proxy_buffers 32 32k;
proxy_buffer_size 64k;
proxy_pass http://main_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;
send_timeout 600s;
proxy_http_version 1.1;
proxy_set_header Connection "";
client_max_body_size 32M;
client_body_buffer_size 512k;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
Any Idea why is this happening? I am using centos 7.1 abd nginx 1.6.3
Thanks in advance,
Todor
Finally found the reason and it has been clean for hours now. It turned out that there were 2 overlapping problems. The first one was the kernel dropping requests after the queue is full. Here is a nice manual about tuning the kernel linux kernel parameters - https://www.nginx.com/blog/tuning-nginx/
After the problems started we migrated the site to a new server and used DHCP to assign IP address - BIG MISTAKE. Every hour or so the dhcp restarted the network Interface. Examining the entire system log I noticed that the IP of the network interface is reassigned on regular intervals. Those intervals coincided with the bursts of errors in the log. So the solution was to go back to static IPs.
You have a upstream block like this:
upstream main_upstream {
server 192.168.158.142:80 max_fails=3 fail_timeout=60s; # New Server. Sent to 192.168.90
# server 192.168.158.143:80; # HSB
keepalive 32;
}
The first line fetches requests from 192.168.158.142:80 and stop trying after 3 fails for 60 seconds.
The second line is commented out, so it doesn't work.
Also there are other ip's listed on your other comments, which obviously won't work.
Assuming you want to fetch requests from 192.168.158.142:80 and failover to another ip 192.168.158.143:80 if it fails, this is how you do it:
upstream main_upstream {
keepalive 30;
server 192.168.158.142:80; # main server
server 192.168.158.143:80 backup; # failover
}
Or if you want to distribute the load evenly in a round robin style:
upstream main_upstream {
keepalive 30;
server 192.168.158.142:80; # server 1
server 192.168.158.143:80; # server 2
}
In both cases, make sure you can access both 192.168.158.142:80 and 192.168.158.143:80
Also bear in mind that you're using keepalive, meanning that if your backend servers are set to limit requests in any way, they might start refusing to serve requests to your frontend nginx (I will assume this is your load balancer).
Related
I have a MySQL database and React front end that work in development using a Node server to connect the two. I have a VPS that I just created and am using Nginx to control the integration. Unfortunately, I am new to this and can't connect to the Node server when it's running on the box. I know it's listening on the correct port because netstat -tulpn shows it is (see below).
I can connect directly to the MySQL database via SSH from my laptop so I know that's working properly. Like I said, the front end loads but can't connect to the server to log in (see below).
I suspect I have made an error with my Nginx configuration but after trying various ideas for the past five hours, I'm at a loss.
Nginx default.conf
server {
listen 443 default_server ssl;
#listen [::]:443 default_server ssl;
server_name thesystem.co.za;
#ssl_certificate /etc/letsencrypt/live/thesystem.co.za/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/thesystem.co.za/privkey.pem;
expires 0;
add_header Cache-Control public;
add_header Cache-Control no-store;
add_header Cache-Control no-cache;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options nosniff;
add_header 'Referrer-Policy' 'origin';
add_header X-XSS-Protection "1; mode=block";
add_header Set-Cookie "HTTPOnly; HttpOnly; Secure";
location / {
root /usr/share/nginx/html/thesystem;
}
location /integration/ {
charset_types application/json;
charset UTF-8;
proxy_pass http://localhost:8081/api/;
}
}
If anyone is able to offer some insight as to what I'm doing wrong, I would really appreciate. I have a test client starting in a few hours and I'm stuck at the last hurdle!
**** UPDATE ******
If I hit the server directly using curl when I'm logged on to the box, I get a response so I know it is listening. I must be doing something wrong with the nginx config like I said but I don't know what...
**** Included nginx.conf
nginx.conf
user nginx;
worker_processes 1;
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;
#large_client_header_buffers 16 64k;
#client_max_body_size 100M;
# Added By Willie for security
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers On;
ssl_ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS;
# Added By Willie, hide Nginx version
server_tokens off;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
image/svg+xml;
include /etc/nginx/conf.d/*.conf;
}
*** Second update ***
I've reduced the default.conf to the bare minimum and it doesn't redirect to the proper location for the webpage or the server. All I get served is a 404 page.
server {
listen 80 default_server;
server_name thesystem.co.za;
location / {
root /usr/share/nginx/html/thesystem;
}
location /integration/ {
charset_types application/json;
charset UTF-8;
proxy_pass http://localhost:8081/;
proxy_set_header Proxy "";
}
}
what's your local api path? is it like http://localhost:8081/api/admin/session?
Usually it is because of the wrong proxy_pass route config. sometimes it is with or without slash problem. sometimes the alias name is not correct...
Change the ``proxy_pass```,
then you can access to
https://thesystem.co.za/integration/api/admin/sessions/
nginx.conf:
location /integration/ {
#....
proxy_pass http://localhost:8081/;
}
It turns out there was nothing wrong with my nginx configuration. My host provider hadn't updated the DNS records properly so it was pointing to the website instead of the VPS!
If anyone else runs into the same problem, check here to ensure the Remote Address is correct. All I did was copy and paste it into my browser and when I ended up somewhere else, I knew something was wrong.
Thank you for your help, everyone, especially #dunhuang
I am running a web server on Sinatra behind an Nginx reverse proxy server. It is a requirement that HTTP requests are all redirected to HTTPS, so that is my current configuration.
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
## Listen on port 80 for HTTP requests, redirect to https
server {
listen 80 default;
listen [::]:80 default;
return 308 https://$host$request_uri;
}
## Use HTTPS when requests are made
server {
listen 443 ssl;
# don't allow old ssl protocols
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ensure that our ciphers are preferred, and give a list of preferred ciphers
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
# enable session tickets
ssl_session_tickets on;
# TLS session cache 4 hours, 40 MB
ssl_session_cache shared:SSL:40m;
ssl_session_timeout 4h;
ssl_certificate /data/projects/cloudpeel-next/cloudpeel.crt;
ssl_certificate_key /data/projects/cloudpeel-next/cloudpeel.key;
location / {
proxy_pass http://localhost:4567;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
This works great in most cases, except when a POST request occurs from the client. Ideally the 308 (or 307) redirect is supposed to preserve the POST data and request the client again to request a different address (in this case the HTTPS version of the site).
However, what occurs in Chrome, is that the request is handled (as far as I can tell more like a 301 redirect, and the request is interpreted as GET, for which my backend has different behavior, redirecting the user to an incorrect page.
I have tried using return 301 and 307, with neither producing the desired results.
The curious thing, is that when tested in Edge and Firefox, the application works exactly as expected.
The network tab in the developer shows the following: a 303 code for a POST attempt and a 308 GET, which is not the desired behavior. In Firefox, only code 200 is shown. Is there anything I can do about this in my Nginx configuration?
Edit: I tried changing my redirect in Nginx to 301, and Firefox still works as intended, while Chrome is still broken.
Well, I figured out my problem. I edited my location / {} block and here is what finally got it working for me - hope it helps someone!
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
## Listen on port 80 for HTTP requests, redirect to https
server {
listen 80 default_server;
server_name localhost;
return 301 https://$host$request_uri;
}
## Use HTTPS when requests are made
server {
listen 443 ssl;
# don't allow old ssl protocols
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ensure that our ciphers are preferred, and give a list of preferred ciphers
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
# enable session tickets
ssl_session_tickets on;
# TLS session cache 4 hours, 40 MB
ssl_session_cache shared:SSL:40m;
ssl_session_timeout 4h;
ssl_certificate /etc/ssl/certs/cloudpeel.crt;
ssl_certificate_key /etc/ssl/certs/cloudpeel.key;
location / {
#HTTPS Config
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-SSL on;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://localhost:4567;
#WebSocket config
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
#proxy_set_header X-Real-IP $remote_addr;
}
}
I am working on Ubuntu 18 and trying to render an HTML page via NGINX. Following this link I did these steps:
Created html directory using sudo mkdir -p /var/www/sample/html
Placed my Web files directory webui under the html above
Created a nginx conf file using sudo vi /etc/nginx/sites-available/sample.conf
Placed below in the sample.conf
server {
listen 80;
listen [::]:80;
root /var/www/sample/html;
index index.html index.htm index.nginx-debian.html;
server_name 123.54.67.235;
location / {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://localhost/webui/;
}
location /app {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://123.54.67.235:7000;
}
}
Created a link from it to the sites-enabled directory using sudo ln -s /etc/nginx/sites-available/sample.conf /etc/nginx/sites-enabled/
Un-commented server_names_hash_bucket_size 64;
Did sudo nginx -t. Got below message:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Did sudo systemctl restart nginx. No error came.
Now when I try to go to http://123.54.67.235 from my browser, I get nginx 500 Internal Server Error.
Not sure what's the mistake I am making as I am very new to and in-experienced with this. Can anyone suggest what's the reason for this?
UPDATE: When I go to my Nginx Error log I see below error there:
2019/05/05 05:52:51 [alert] 29779#29779: *2588 768 worker_connections are not enough while connecting to upstream, client: 123.54.67.235, server: 134.209.113.22, request: "GET /webui/webui/webui/webui/webui/webui/webui/webui/.....
Note: I am using my server's ip address in the server_name field of conf file as I do not have a domain name assigned to my server.
The proxy_pass http://localhost/webui/; statement points into the same server and generates a recursive loop by adding an endless number of /webui/ path elements. The proxy_pass directive is intended for a reverse proxy, and is used to forward requests to some other server.
To serve static content, you should use a root statement.
If the URI /foo should serve the file at /var/www/sample/html/webui/foo, use root /var/www/sample/html/webui;.
For example:
server {
...
root /var/www/sample/html/webui;
...
location / { }
location /app {
include proxy_params;
proxy_...;
proxy_pass ...;
}
}
The location / block is empty.
Currently have a pure HTML website with some embedded JS code to control flow between HTML files along with graph configuration details. The directories are as follows: html, css, fonts, img, js, sound. On my local machine, I can easily open the HTML files and navigate the site. I am using an Ubuntu Amazon EC2 instance with nginx as the reverse proxy. When running a express.js controlled website on the instance I usually just edit the nginx config file and start the app/server.js file. However, I am unsure as to how to do this with a set of static HTML files that have CSS and other assets associated with them. Below is my attempt at writing the nginx file but I'm not sure if what I'm proposing is possible.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/website-dashboard/;
index index.html;
# Make site accessible from http://localhost/
server_name localhost;
location / {
default_type "text/html";
try_files $uri.html $uri $uri/ /index.html;
access_log off;
}
}
You shouldn't have a problem opening HTML files with NGINX - The question is, considdering you're running NGINX as a reverse proxy, what are you running as your web server?
If you're running Apache then you need to make sure it's running on port 8080 and the below NGINX configuration should meet your requirements.
upstream apachebackend {
server 127.0.0.1:8080; #apachebackend
}
server {
listen 80 default;
server_name www.domain.com domain.com;
access_log /var/log/nginx/domain.com.access.log main;
error_log /var/log/nginx/domain.com.error.log;
root /usr/share/nginx/html;
index index.html index.htm index.php;
## send request back to apachebackend ##
location / {
proxy_pass http://apachebackend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering on;
proxy_buffers 12 12k;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
If you're running NGINX as your web server then you need to set it up accordingly. The default set-up should suffice, just drop your files in the default vhost directory, but I recommend setting it up correctly using separate directories and log files.
I set up a Vagrant VirtualBox box for Debian Wheezy following this instruction.
I installed nginx and php5-fpm on this virtual machine. I can access my guest machine via 127.0.0.1:8080 from host. It can also serve php files and phpinfo() works correctly, too.
However, when I try to access a remote MySQL server from a php file, the request always times out and I get a 504 Gateway Timeout error.
I noticed the followings.
In my nginx conf file, I have this line fastcgi_pass unix:/var/run/php5-fpm.sock;.
In /etc/php5/fpm/pool.d/www.conf, I have listen = /var/run/php5-fpm.sock.
php5-fpm.sock exists in /var/run/.
If I use 127.0.0.1:9000 instead of the socket, I still get the 504 Gateway Timeout error, but I get the error immediately without any waiting.
I added proxy_read_timeout 300; in my nginx conf, but this did not solve the issue.
My Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "wheezy32"
config.vm.provision :shell, :path => "dev/bootstrap.sh"
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
config.vm.network :forwarded_port, guest: 80, host: 8080
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network :private_network, ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network :public_network
end
My nginx conf
server {
root /var/www/sites/mysite/public_html;
index index.html index.htm index.php;
# Make site accessible from http://localhost/
server_name localhost;
access_log /var/www/logs/mysite/mysite.access_log;
error_log /var/www/logs/mysite/mysite.error_log;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
proxy_read_timeout 300;
}
location /doc/ {
alias /usr/share/doc/;
autoindex on;
allow 127.0.0.1;
allow ::1;
deny all;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
/var/www/logs/mysite/mysite.error_log
2013/06/16 23:47:27 [error] 2567#0: *23 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.0.2.2, server: localhost, request: "GET /test.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock", host: "127.0.0.1:8080"
2013/06/16 23:47:27 [error] 2567#0: *23 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 10.0.2.2, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "127.0.0.1:8080"
Here is how I attempt to connect to the remote MySQL server.
require_once('/var/www/sites/mysite/includes/db_constants.php');
try {
$dsn = 'mysql:host=172.16.0.51;dbname=' . DB_NAME . ';charset=utf8';
$db = new PDO($dsn,DB_USER,DB_PASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e) {
header('HTTP/1.1 500');
exit;
} catch (Exception $e) {
header('HTTP/1.1 500');
exit;
}
What am I missing?
As #cmur2 said, I was using the private IP to connect to the remove server, and that was why it did not work. I changed it to a public IP and now it is working correctly.