NGINX (Reverse Proxy - Bad Gateway - nginx

I searched a lot and tried a lot but on this point I dont get it... so here is my question:
I have a newly setup Proxmox and I wanna run a nginx reverse proxy and some VMs behind it. It is the first time with nginx and reverse proxy for me. I only used Apache before and never a reverse proxy.
So my reverse proxy has basicly three files: headers.conf, ssl.conf and my.domain.com.conf.
In headers.conf is the following:
#
# Add headers to serve security related headers
#
# HSTS (ngx_http_headers_module is required)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload;" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Robots-Tag none always;
add_header X-Download-Options noopen always;
add_header X-Permitted-Cross-Domain-Policies none always;
add_header Referrer-Policy no-referrer always;
add_header X-Frame-Options "SAMEORIGIN" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
#prox headers
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
Then there is the ssl.conf:
GNU nano 5.4 /etc/nginx/snippets/ssl.conf
#
# Configure SSL
#
# Diffie-Hellman parameter for DHE ciphersuites, recommended 4096 bits
ssl_dhparam /etc/nginx/dhparams/dhparams.pem;
# Not using TLSv1 will break:
# Android <= 4.4.40 IE <= 10 IE mobile <=10
# Removing TLSv1.1 breaks nothing else!
ssl_protocols TLSv1.2 TLSv1.3;
# SSL ciphers: RSA + ECDSA
# Two certificate types (ECDSA, RSA) are needed.
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-A>
# Use multiple curves.
ssl_ecdh_curve secp521r1:secp384r1;
# Server should determine the ciphers, not the client
ssl_prefer_server_ciphers on;
# SSL session handling
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# SSL stapling has to be done seperately, becuase it will not work with self signed certs
# OCSP Stapling fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
# DNS resolver
resolver 192.168.xxx.xx;
and the my.domain.com.conf:
server {
listen 80;
listen [::]:80;
server_name my.domain.com;
location ~ \.* {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my.domain.com;
# SSL configuration
# RSA certificates
ssl_certificate /etc/letsencrypt/my.domain.com/rsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/my.domain.com/rsa/key.pem;
# ECC certificates
ssl_certificate /etc/letsencrypt/my.domain.com/ecc/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/my.domain.com/ecc/key.pem;
# This should be ca.pem (certificate with the additional intermediate certificate)
# See here: https://certbot.eff.org/docs/using.html
# ECC
ssl_trusted_certificate /etc/letsencrypt/my.domain.com/ecc/ca.pem;
# Include SSL configuration
include /etc/nginx/snippets/ssl.conf;
# Include headers
include /etc/nginx/snippets/headers.conf;
# Set the access log location
access_log /var/log/nginx/my.domain.access.log;
location ~ \.* {
proxy_pass http://192.168.xxx.xxx:80;
proxy_read_timeout 90;
proxy_redirect http://192.168.xxx.xxx:80 https://my.domain.com;
}
}
That is the reverse proxy side.
The VM has nginx as well and the following file, my.domain.com.conf:
upstream php-handler {
server unix:/run/php/php7.4-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name my.domain.com;
#root /var/www;
# location / {
# return 301 https://$host$request_uri;
# }
# Path to the root of your installation
root /var/www/nextcloud;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
#location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
#location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_read_timeout 600;
fastcgi_send_timeout 600;
fastcgi_connect_timeout 600;
fastcgi_param PHP_VALUE "upload_max_filesize = 10G
post_max_size = 10G
max_execution_time = 3600
output_buffering = off";
}
location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite)$ {
try_files $uri /index.php$request_uri;
expires 6M; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
location ~ \.wasm$ {
default_type application/wasm;
}
}
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
}
I did all that from reading different tutorials and the manuals itself. But I totally don't get my mistake.... is there anything obvies you can see? I feel very happy for any hint you guys have for me!
Thank you a lot and good christmas time :)

This is the output:
root#HL-Reverse-Proxy:/var/www# telnet 192.168.178.100 80
Trying 192.168.178.100...
Connected to 192.168.178.100.
Escape character is '^]'.
GET /
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.21.4</center>
</body>
</html>
Connection closed by foreign host.
So connection is possible.

Related

nginx Nextcloud config not working (ERR_TOO_MANY_REDIRECTS)

I wanted to switch from apache2 to nginx. Now I tried moving my nextcloud config to nginx (using following "template": https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html) but I only get ERR_TOO_MANY_REDIRECTS (since it worked before switching to nginx, it should be a nginx configuration problem).
upstream php-handler {
server 127.0.0.1:9000;
#server unix:/var/run/php/php7.4-fpm.sock;
}
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
"" "";
default "immutable";
}
server {
listen 80;
listen [::]:80;
server_name cloud.link.com;
# Prevent nginx HTTP Server Detection
server_tokens off;
# Enforce HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.link.com;
# Path to the root of your installation
root /var/www/cloud.link.com;
# Use Mozilla's guidelines for SSL/TLS settings
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
ssl_certificate /root/cloudflare/file.pem;
ssl_certificate_key /root/cloudflare/file.key;
# Prevent nginx HTTP Server Detection
server_tokens off;
# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Pagespeed is not supported by Nextcloud, so if your server is built
# with the `ngx_pagespeed` module, uncomment this line to disable it.
#pagespeed off;
# The settings allows you to optimize the HTTP2 bandwitdth.
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
# for tunning hints
client_body_buffer_size 512k;
# HTTP response headers borrowed from Nextcloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463, $asset_immutable";
access_log off; # Optional: Don't log access to assets
location ~ \.wasm$ {
default_type application/wasm;
}
}
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
Does anyone have a solution for this problem?

NGINX - Directive to Allow iPhone's IP address for accessing wordpress login page (mysite.com/wp-login.php), and Deny all other IP addresses

MY ENVIRONMENT:
I am running a LEMP server which is working and running wordpress quite properly. As of now, I have my wordpress web login (www.mysite/wp-login.php) blacklisted by all IP addresses EXCEPT any IP on my LAN with the following directive:
server {
# Allow LAN only on wp-login page (www.mysite.com/wp-login.php)
location ~ /wp-login.php {
allow 192.168.1.0/24;
deny all;
}
This directive sucessfully blocks all internet traffic to "mywebsite.com/wp-login.php", which is the wordpress admin login page.
In other words, with this directive set, I can access the wordpress login page anywhere on my internal LAN, but the directive denys any outside internet traffic from seeing the "mywebsite.com/wp-login.php" page. GREAT!
WHAT I WANT TO DO,
is to whitelist the IP address of my phone, so that I can access the wordpress login page from my phone's IP address, while still blocking any other outside internet traffic. To do so, I go to www.whatsmyip.org on my phone, copy the ip address that it gives me, then modify the previous directive to look like the following:
server {
# Allow LAN and CellPhone access to to wp-login page (www.mysite.com/wp-login.php)
location ~ /wp-login.php {
allow 77.232.28.46; # my phones ip address as shown on whatsmyip.org
allow 192.168.1.0/24;
deny all;
}
HOWEVER,
after reloading nginx, I still cannot access the wp-login (wordpress login) page from my phone.
MY QUESTION IS:
Using NGINX, How can I properly whitelist my phones IP address, while blacklisting everything else access to the wordpress login page locate at www.mysite.com/wp-login.php ?
FOR REFERENCE:
Below is my NGINX.CONF file:
# This is the /etc/nginx/nginx.conf file for Danrancan's LEMP server
#
user www-data;
worker_processes 4;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
load_module /usr/share/nginx/modules/ngx_http_modsecurity_module.so;
events {
worker_connections 1024;
# multi_accept on;
}
http {
##
# Mod Security
##
modsecurity on;
#modsecurity off;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
##
# Basic Settings
##
client_max_body_size 512M;
fastcgi_read_timeout 300;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 4096;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
# Create a custom Nginx log format called netdata that includes information about request_time, and upstream_response_time, measured in seconds with millisecond resolution.
log_format netdata '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'$request_length $request_time $upstream_response_time '
'"$http_referer" "$http_user_agent"';
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_session_cache shared:SSL:10m; #SSL session cache
ssl_session_timeout 1h;
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component
text/javascript
text/xml;
# Extra Http Header response to determine whether a request is being served from the cache
#add_header Fastcgi-Cache $upstream_cache_status;
##
# Virtual Host Configs
##
upstream local_php {
server unix:/run/php/php7.4-fpm.sock;
}
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
include /etc/nginx/perfect-forward-secrecy.conf;
##
# Harden nginx against DDOS. #noted from www.pestmeester.nl
##
client_header_timeout 10;
# For good security, set client_body_timeout to 10. For uploading large files, set to higher.
client_body_timeout 10;
keepalive_timeout 10;
send_timeout 10;
}
and my VIRTUAL HOST CONFIG:
# Danrancan's Virtual host config for /etc/nginx/sites-available/mysite.com.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name mysite.com www.mysite.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
###
# SSL (From Mozilla Config Generator: Modern Configuration)
###
# Add Strict Transport Security Response Header with "always Paramater", to help prevent MITM attacks.
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
## Prevent click jacking by adding an X-Frame header
# Add X-Frame-Options header to nginx with the following line:
add_header x-frame-options "SAMEORIGIN" always;
# Add a content security policy header
add_header Content-Security-Policy "frame-ancestors 'self';";
# Secure MIME Types with X-Content-Type-Options. Below line adds the X-Fram-Options header in Nginx.
add_header X-Content-Type-Options nosniff;
# Enable X-XSS-Protection header in Nginx
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin";
add_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()";
# Path to signerd certificate + Intermediate certificates
ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem; # Managed by admin
ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem; # Managed by admin
# Perfect Forward Secrecy Diffie-Hellman 4096 parameters
ssl_dhparam /etc/ssl/private/dhparams4096.pem; # Managed by admin
# Include "perfect-forward-secrecy.conf" file in this virtual host. NOTE: No need to do this, as its already included in the nginx.conf file, so you should comment this out.
#include /etc/nginx/perfect-forward-secrecy.conf; # Managed by admin
# Modern SSL configuration with OCSP stapling turned on
#ssl_protocols TLSv1.3; # commented out because its already in the nginx.conf file
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;
# Verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/mysite.com/chain.pem; # Managed by admin
server_name mysite.com www.mysite.com;
root /var/www/mysite.com;
# Error & Access Logs
#error_log /var/www/mysite.com.logs/error.log error;
#access_log /var/www/mysite.com.logs/access.log;
access_log /var/log/nginx/mysite.com.access.log netdata;
error_log /var/log/nginx/mysite.com.error.log warn;
# This should be in your http block and if it is, it's not needed here.
index index.php index.html index.htm;
# Only allow access of /admin via internal IP
location ^~ /admin {
allow 192.168.1.0/24;
deny all;
error_page 403 =444;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
}
# Allow local only to wp-login page
location ~ /wp-login.php {
allow 192.168.1.0/24;
deny all;
error_page 403 =444;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ /.well-known {
allow all;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Cache Static Files For As Long As Possible
location ~*\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off;
log_not_found off;
expires max;
}
# Security Settings For Better Privacy Deny Hidden Files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Disallow PHP In Upload Folder
location /wp-content/uploads/ {
location ~ \.php$ {
deny all;
}
}
# Pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php-fpm (or other unix sockets):
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Below was Added from recommended by pestmeester.nl
fastcgi_intercept_errors on;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
What you are doing should work.
Since it is not, it seems that for some reason nginx doesn't see your phone IP as a match to what you have configured.
It sounds like your WP box is running on a private network (because of the 192.168.1.0/ IP addresses you mentioned).
When you connect to the WP box from the internet, is it going through a router with port forwarding/NAT?
First thing I would do is just tail your nginx access log (access_log /var/log/nginx/access.log;) when trying to access with your iphone and see what is reported.
If the request is coming through a proxy/reverse-proxy you may need to make sure the proxy is adding X-Forwarded-For to pass along the remote (iphone) ip address. The request to nginx/wp would be coming from the proxy IP and there would be a header X-Forwarded-For added to the request containing the original remote address.
When nginx is used this way you need to use nginx's realip module...something like:
real_ip_header X-Forwarded-For;
set_real_ip_from 192.168.1.1; # proxy ip
http://nginx.org/en/docs/http/ngx_http_realip_module.html

I'm facing issues trying to configure reverse proxy in Nginx, for an app running in localhost

I've got Pterodactyl set up on a Digital Ocean droplet running Ubuntu v18.04.4 LTS. About a year ago I set it up along with Nginx, set up A records (panel.example.com), and it works splendidly with a Let's Encrypt SSL certificate.
A couple days ago I decided to set up The Lounge, a self hosted Web IRC client. By default it runs on port 9000. I followed their recommended instructions, changing a few things recommended by the people on their help IRC channel. Unlike the Pterodactyl panel, I want this to show up on my personal domain. So, I set up my A record to point to my DO droplet, with a host value of irc, so it would show up at irc.yash.gg. Then I used acme.sh to generate Let's Encrypt keys in standalone mode. Then, I added the config below to /etc/nginx/sites-available/thelounge.conf, symlinked that to /etc/nginx/sites-enabled/thelounge.conf. But for some reason, with the config below, it started redirecting to the "you've set up nginx correctly" page instead. And now, a couple days later, I get directed to my Pterodactyl panel at panel.sneakycraft.com instead.
I am completely lost, and I don't understand what is going on. I would really appreciate some help with this. Please let me know, if I can provide anything else to help diagnose this issue.
Thanks!
server {
listen 80;
listen [::]:80;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name irc.yash.gg;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] valid=300s;
resolver_timeout 5s;
charset utf-8;
location ^~ /irc/ {
proxy_pass https://127.0.0.1:9000/;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
# by default nginx times out connections in one minute
proxy_read_timeout 1d;
# proxy_redirect http://127.0.0.1:9000 https://irc.yash.gg;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /var/log/nginx/thelounge.app-access.log;
error_log /var/log/nginx/thelounge.app-error.log error;
# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;
sendfile off;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/irc.yash.gg/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/irc.yash.gg/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_trusted_certificate /etc/letsencrypt/live/irc.yash.gg/fullchain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
# See https://hstspreload.org/ before uncommenting the line below.
# add_header Strict-Transport-Security "max-age=15768000; preload;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header Content-Security-Policy "frame-ancestors 'self'";
add_header X-Frame-Options DENY;
add_header Referrer-Policy same-origin;
# location ~ \.php$ {
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
# fastcgi_pass unix:/run/php/php7.2-fpm.sock;
# fastcgi_index index.php;
# include fastcgi_params;
# fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# fastcgi_param HTTP_PROXY "";
# fastcgi_intercept_errors off;
# fastcgi_buffer_size 16k;
# fastcgi_buffers 4 16k;
# fastcgi_connect_timeout 300;
# fastcgi_send_timeout 300;
# fastcgi_read_timeout 300;
# }
location ~ /\.ht {
deny all;
}
}
The Lounge binds to my public IP. changed config to point to serverip:port instead of localhost and that worked.

Ngx_pagespeed is loaded, but do nothing on HTTPS website. Why is that?

The module ngx_pagespeed(Nginx) works very well for HTTP. However, I cannot get it working with HTTPS. My whole website is using HTTPS and ngx_pagespeed seems to have none of their filters working. The module itself is loaded, but do nothing. I'm using WordPress for the website with the latest ngx_pagespeed module on CentOS 7.
Here my nginx.conf
user nginx nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
http {
##
# MIME types
##
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Update charset_types due to updated mime.types
charset_types text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml text/css application/javascript application/json;
##
# Misc
##
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
client_max_body_size 20m;
client_body_buffer_size 128k;
client_body_timeout 15;
client_header_timeout 15;
keepalive_timeout 65;
reset_timedout_connection on;
send_timeout 15;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
server_tokens off;
##
# Logging Settings
##
access_log /var/log/nginx/access.log main;
##
# Gzip Settings - Ngx_pagespeed to by default.
##
# gzip on;
# gzip_min_length 256;
# gzip_comp_level 4;
# gzip_proxied any;
# gzip_vary on;
# gzip_types
# application/atom+xml
# application/javascript
# application/json
# application/rss+xml
# application/vnd.ms-fontobject
# application/x-font-ttf
# application/x-web-app-manifest+json
# application/xhtml+xml
# application/xml
# font/opentype
# image/svg+xml
# image/x-icon
# text/css
# text/plain
# text/x-component;
## Enable clickjacking protection in modern browsers.
## https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header
add_header X-Frame-Options sameorigin;
##
# Host Configs
##
include /etc/nginx/conf.d/*.conf;
}
And here is my example.conf
##
# WWW to NON-WWW
##
server {
listen 80;
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
##
# Force HTTPS
##
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
##
# The right way to add support for HSTS.
# http://trac.nginx.org/nginx/ticket/289
##
map $scheme $hsts_header {
https max-age=31536000;
}
##
# Phuchan site
##
server {
listen 443 ssl spdy;
# Certs sent to the client in SERVER HELLO are concatenated in ssl_certificate.
ssl on;
ssl_certificate /etc/ssl/certs/ssl-bundle.crt;
ssl_certificate_key /etc/ssl/private/myserver.key;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits.
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Intermediate configuration.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_session_timeout 10m;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/trustchain.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;
# PageSpeed
pagespeed on;
pagespeed FetchHttps enable;
#pagespeed MapOriginDomain "http://localhost" "https://example.com";
# Needs to exist and be writable by nginx. Use tmpfs for best performance.
pagespeed FileCachePath /var/ngx_pagespeed_cache;
# Ensure requests for pagespeed optimized resources go to the pagespeed handler
# and no extraneous headers get set.
location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
add_header "" "";
}
location ~ "^/pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon$" { }
# Honoring no-transform Cache-Control Headers
pagespeed DisableRewriteOnNoTransform off;
# Lower-casing HTML element and attribute names
pagespeed LowercaseHtmlNames on;
pagespeed RewriteLevel OptimizeForBandwidth;
# Preserve URL Relativity
pagespeed PreserveUrlRelativity on;
# Misc
add_header Strict-Transport-Security $hsts_header;
add_header X-Content-Type-Options nosniff;
server_name example.com;
root /srv/www/example.com;
index index.php index.htm index.html;
error_log /var/log/nginx/error-example.log error;
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
##
# PHP-FPM
##
location ~ \.php$ {
try_files $uri = 404;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
##
# Server the assets folder
##
location ^~ /assets {
alias /srv/assets;
}
##
# Simple cache for static files. Tweaked for SSL use.
##
location ~ \.(js|css|png|jpeg|jpg|gif|ico|swf|flv|pdf|zip)$ {
expires 24h;
add_header Cache-Control public;
}
##
# WordPress stuff
##
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
try_files $uri $uri/ /index.php?$args;
log_not_found off;
access_log off;
}
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
deny all;
}
# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
# Set variable $skip_cache to 0
set $skip_cache 0;
# Do not cache POST/HEAD requests
if ($request_method ~ ^(HEAD|POST)$) {
set $skip_cache 1;
}
# Do not cache URLs with a query string
if ($query_string != "") {
set $skip_cache 1;
}
# Do not cache URLs containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
set $skip_cache 1;
}
# Do not cache logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
}
##
# Rewrite for XML Sitemap Generator
##
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/index.php?xml_sitemap=params=$2" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;
}
You must provide https-specific configuration to enable rewriting of https resources.
From https://developers.google.com/speed/pagespeed/module/https_support :
PageSpeed rewrites HTML documents requested via https. PageSpeed is able to serve these documents because the server passes the HTML document through all its output filters, including *_pagespeed. But by default, PageSpeed will only rewrite non-HTML resources which are served via http. Due to the complexity and security required to manage client SSL certificates, PageSpeed requires the server administrator to explicitly enable https fetching.
https://developers.google.com/speed/pagespeed/module/https_support provides more details on what configuration is needed in different situations.
I fixed that with https://developers.google.com/speed/pagespeed/module/https_support#load_from_file. The second argument should point to the root of your website.

Rails 2 and Ngnix: https pages can't load css or js (but will load graphics)

I'm adding some https pages to my rails site. In order to test it locally, i'm running my site under one mongrel_rails instance (on 3000) and nginx.
I've managed to get my nginx config to the point where i can actually go to the https pages, and they load. Except, the javascript and css files all fail to load: looking in the Network tab in chrome web tools, i can see that it is trying to load them via an https url. Eg, one of the non-working file urls is
https://cmw-local.co.uk/stylesheets/cmw-logged-out.css?1383759216
I have these set up (or at least think i do) in my nginx config to redirect to the http versions of the static files. This seems to be working for graphics, but not for css and js files.
If i click on this in the Network tab, it takes me to the above url, which redirects to the http version. So, the redirect seems to be working in some sense, but not when they're loaded by an https page. Like i say, i thought i had this covered in the second try_files directive in my config below, but maybe not.
Can anyone see what i'm doing wrong? thanks, Max
Here's my nginx config - sorry it's a bit lengthy! I think the error is likely to be in the first (ssl) server block:
NOTE: the urls in here (elearning.dev, cmw-dev.co.uk, etc) are all just local host names, ie they're all just aliases for 127.0.0.1.
server {
listen 443 ssl;
keepalive_timeout 70;
ssl_certificate /home/max/work/charanga/elearn_container/elearn/config/nginx/certs/max-local-server.crt;
ssl_certificate_key /home/max/work/charanga/elearn_container/elearn/config/nginx/certs/max-local-server.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
server_name elearning.dev cmw-dev.co.uk cmw-dev.com cmw-nginx.co.uk cmw-local.co.uk;
root /home/max/work/charanga/elearn_container/elearn;
# ensure that we serve css, js, other statics when requested
# as SSL, but if the files don't exist (i.e. any non /basket controller)
# then redirect to the non-https version
location / {
try_files $uri #non-ssl-redirect;
}
# securely serve everything under /basket (/basket/checkout etc)
# we need general too, because of the email/username checking
location ~ ^/(basket|general|cmw/account/check_username_availability) {
# make sure cached copies are revalidated once they're stale
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
# this serves Rails static files that exist without running
# other rewrite tests
try_files $uri #rails-ssl;
expires 1h;
}
location #non-ssl-redirect {
return 301 http://$host$request_uri;
}
location #rails-ssl {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_read_timeout 180;
proxy_next_upstream off;
proxy_pass http://127.0.0.1:3000;
expires 0d;
}
}
#upstream elrs {
# server 127.0.0.1:3000;
#}
server {
listen 80;
server_name elearning.dev cmw-dev.co.uk cmw-dev.com cmw-nginx.co.uk cmw-local.co.uk;
root /home/max/work/charanga/elearn_container/elearn;
access_log /home/max/work/charanga/elearn_container/elearn/log/access.log;
error_log /home/max/work/charanga/elearn_container/elearn/log/error.log debug;
client_max_body_size 50M;
index index.html index.htm;
# gzip html, css & javascript, but don't gzip javascript for pre-SP2 MSIE6 (i.e. those *without* SV1 in their user-agent string)
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; #text/html
# make sure gzip does not lose large gzipped js or css files
# see http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl
gzip_buffers 16 8k;
# Disable gzip for certain browsers.
#gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_disable "MSIE [1-6]";
# blank gif like it's 1995
location = /images/blank.gif {
empty_gif;
}
# don't serve files beginning with dots
location ~ /\. { access_log off; log_not_found off; deny all; }
# we don't care if these are missing
location = /robots.txt { log_not_found off; }
location = /favicon.ico { log_not_found off; }
location ~ affiliate.xml { log_not_found off; }
location ~ copyright.xml { log_not_found off; }
# convert urls with multiple slashes to a single /
if ($request ~ /+ ) {
rewrite ^(/)+(.*) /$2 break;
}
# X-Accel-Redirect
# Don't tie up mongrels with serving the lesson zips or exes, let Nginx do it instead
location /zips {
internal;
root /var/www/apps/e_learning_resource/shared/assets;
}
location /tmp {
internal;
root /;
}
location /mnt{
root /;
}
# resource library thumbnails should be served as usual
location ~ ^/resource_library/.*/*thumbnail.jpg$ {
if (!-f $request_filename) {
rewrite ^(.*)$ /images/no-thumb.png
break;
}
expires 1m;
}
# don't make Rails generate the dynamic routes to the dcr and swf, we'll do it here
location ~ "lesson viewer.dcr" {
rewrite ^(.*)$ "/assets/players/lesson viewer.dcr" break;
}
# we need this rule so we don't serve the older lessonviewer when the rule below is matched
location = /assets/players/virgin_lesson_viewer/_cha5513/lessonViewer.swf {
rewrite ^(.*)$ /assets/players/virgin_lesson_viewer/_cha5513/lessonViewer.swf break;
}
location ~ v6lessonViewer.swf {
rewrite ^(.*)$ /assets/players/v6lessonViewer.swf break;
}
location ~ lessonViewer.swf {
rewrite ^(.*)$ /assets/players/lessonViewer.swf break;
}
location ~ lgn111.dat {
empty_gif;
}
# try to get autocomplete school names from memcache first, then
# fallback to rails when we can't
location /schools/autocomplete {
set $memcached_key $uri?q=$arg_q;
memcached_pass 127.0.0.1:11211;
default_type text/html;
error_page 404 =200 #rails; # 404 not really! Hand off to rails
}
location / {
# make sure cached copies are revalidated once they're stale
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
# this serves Rails static files that exist without running other rewrite tests
try_files $uri #rails;
expires 1h;
}
location #rails {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_read_timeout 180;
proxy_next_upstream off;
proxy_pass http://127.0.0.1:3000;
expires 0d;
}
}
EDIT: It just occurred to me that this might be better on superuser or serverfault, or perhaps both. I'm not sure what the cross-site posting rules are.

Resources