Question about Headers IIS reverse proxy with NGINX

Albert Yang

Member
Oct 26, 2017
72
1
8
28
Hi


I was wondering if someone could shed some light on the issue im having,


Currently i have working great NGINX as reverse proxy for my IIS


Im trying to get working the Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options working my NGINX but it keeps showing that its not getting applied when i check


Analyse your HTTP response headers

1649039558336.png


Code:
#        listen 80;
   listen 443 ssl;
 server_name  sub.domain.com;

  ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_stapling on;
       ssl_stapling_verify on;

## security headers
# Block loading in an iFrame
add_header X-Frame-Options SAMEORIGIN;
# Enforce HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
# Blocks hidden malicious scripts
add_header X-Content-Type-Options nosniff;
# Stops scripts from unknown sources
add_header X-XSS-Protection "1; mode=block";
# Content security policy
add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';" always;
# Referal policy
add_header Referrer-Policy "origin-when-cross-origin" always;
# permision policy
add_header Feature-Policy "camera 'none'; microphone 'none'; geolocation 'none'" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

        location ~ /.well-known {
        root /var/www/letsencrypt;
        allow all;
    }
        location / {

               proxy_pass http://192.168.3.211:8096/;

#                headers setting

                proxy_set_header Host $host;

                proxy_set_header X-Real-IP $remote_addr;

                proxy_set_header X-Forwarded-For $remote_addr;

                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Client-IP $remote_addr;

                }

        }
im going to assume


proxy_set_header Host $host; is what shows the header of the IIS?


Thank you
 

Stephan

Well-Known Member
Apr 21, 2017
531
330
63
Germany
I suggest you look at output of wget -S -O/dev/null https://www.yoursite.com if you are emitting duplicate headers. Personally I like openresty (nginx with lua) because it contains the "headers-more" module (GitHub - openresty/headers-more-nginx-module: Set, add, and clear arbitrary output headers in NGINX http servers). Syntax is different:

server_tokens off;
more_clear_headers "X-Powered-By";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-Frame-Options: sameorigin";
more_set_headers "Strict-Transport-Security: max-age=15768000; includeSubDomains";

proxy_set_header is what gets passed to your IIS. Host for example is the $host which nginx got from the client, passing it on to the proxied IIS so if more than one site is configured, IIS will know which one the client wanted through that header.
 
Last edited:

Albert Yang

Member
Oct 26, 2017
72
1
8
28
Thanks for the reply currently i ran the command and i got this
So to accomplish the headers correctly i would need openresty?
I currently complied NGINX with NAXSI running this, im not sure how would i compile for openresty

Code:
./configure \
--conf-path=/etc/nginx/nginx.conf \
--add-module=../naxsi-master/naxsi_src/ \
--error-log-path=/var/log/nginx/error.log \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-log-path=/var/log/nginx/access.log \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--http-scgi-temp-path=/var/lib/nginx/scgi \
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
--lock-path=/var/lock/nginx.lock \
--pid-path=/var/run/nginx.pid \
--user=www-data \
--group=www-data \
--with-debug \
--with-compat \
--with-pcre-jit \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-http_auth_request_module \
--with-http_v2_module \
--with-http_dav_module \
--with-http_slice_module \
--with-threads \
--with-http_addition_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_image_filter_module=dynamic \
--with-http_sub_module \
--with-http_xslt_module=dynamic \
--with-stream=dynamic \
--with-stream_ssl_module \
--with-mail=dynamic \
--with-mail_ssl_module \
--prefix=/usr

Code:
HTTP request sent, awaiting response...
  HTTP/1.1 403 Forbidden
  Server: nginx
  Date: Mon, 04 Apr 2022 15:02:56 GMT
  Content-Type: text/html
  Content-Length: 1237
  Connection: keep-alive
  Content-Security-Policy: default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';
  Referrer-Policy: origin-when-cross-origin
  Feature-Policy: camera 'none'; microphone 'none'; geolocation 'none'
  Permissions-Policy: camera=(), microphone=(), geolocation=()
2022-04-04 10:02:57 ERROR 403: Forbidden.
Thank you
 

Stephan

Well-Known Member
Apr 21, 2017
531
330
63
Germany
You need to study documentation deeper.

Read Module ngx_http_headers_module

"Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). ... If the always parameter is specified (1.7.5), the header field will be added regardless of the response code."

Openresty is a "stable" self-contained nginx distribution with different and more modules activated. I use it on Arch Linux installed to /opt from AUR because I happened to have also a use for Lua. If you get the duplicate header problem, more_headers is the way to go and openresty already integrates it, so no need to compile everything from scratch yourself. On Arch "yay -S openresty" and after a couple minutes its compiled and ready to go.