SignalR SSL trust issue with reverse proxy(Nginx) for Android - nginx

I am facing issue with SignalR using reverse proxy(Nginx) which has Certificates(Server, client and CA) and these certificates are self signed certificates, generated using OPENSSL.
Nginx Configuration is as below.
http
{
include 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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
error_log "C:/Error/error1.log" debug;
listen 8080;
server_name localhost;
location /MyService
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /MyService/signalr/
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService/signalr/;
}
}
server {
error_log "C:/Error/error1.log" debug;
listen 443 ssl;
server_name localhost;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate "C:\Certificates\server.crt";
ssl_certificate_key "C:\Certificates\server.key";
ssl_client_certificate "C:\Certificates\ca.crt";
ssl_verify_client on;
location /
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /MyService
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService;
}
location /MyService/signalr
{
root html;
index index.html index.htm;
proxy_pass http://XX.XX.XX.XX/MyService/signalr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
}
I have an Android APP which enforce the user to select the client certificate(P12 certificate, which has CA and Client certificates packaged) for authentication through nginx and route it to server XX.XX.XX.XX. I have a logic which will successfully establishes the connection to the XX.XX.XX.XX server through Nginx. Authentication to server XX.XX.XX.XX through Nginx is successful.
I am facing issues with signalR in this scenario, wherein I am making a hubconnection to the server XX.XX.XX.XX like $"https://{hostname}:{port}/MyService/signalr/". When I try to start the hubconnection
_hubConnection.Start().Wait(); Getting error as One or more errors occurred. (The SSL connection could not be established, see inner exception.) because of which my hub is not receiving any notfication from the server.
I have Referred the following links and tried the suggestions as suggested. Unfortunately I am not getting any breakthrough. Request your help on this.
https://forums.asp.net/t/2029050.aspx?SignalR+Unable+to+Authentication+with+Certificate
https://learn.microsoft.com/en-us/aspnet/signalr/overview/security/hub-authorization
SignalR - Could not establish trust relationship for the SSL/TLS secure channel
https://forums.asp.net/t/2095053.aspx?SignalR+and+reverse+proxy

Related

I need to redirect http to https connection with nginx on rest service and need to test it on postman or soapui

Here is my nginx.conf file
What should i change to make it work and how to get certificate;
I need to redirect http to https connection with nginx on rest service and need to test it on postman or soapui.
Is there any difference in configuring nginx for website and for webservice?
user nginx;
worker_processes auto;
error log /var/log/nginx/error.log;
pid /run/nginx.pid;
#Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
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 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
server {
listen 80;
server_name hostname_of_virtual_machine http://ipaddress:port;
return 301 https://$ipaddress:port$request_uri;
}
# Settings for a TLS enabled server.
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name hostname_of_virtual_machine;
root /usr/share/nginx/html;
#ssl_certificate "/etc/pki/nginx/server.crt";
#ssl_certificate_key "/etc/pki/nginx/private/server.key";
#ssl_session_cache shared:SSL:1m;
#ssl_session_timeout 10m;
#ssl_ciphers PROFILE=SYSTEM;
#ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
When i try to test service in postman via http connection post method it still doesn't get any information;
Any idea what should i do?
EDIT
I have SSL Cert but don't know how to use it and where to put it. This is my conf file for now, and after talking with a colleague he told me that i just need a truststore in this file but i don't know how to create it.
So now, i need to edit existing conf file
First of all you need to remove the configuration codes after include /etc/nginx/conf.d/*.conf;
Note: The example below using Ubuntu 20.04 LTS
Go to /etc/nginx/sites-available and create a new file myapp01 and put your configuration there.
cd /etc/nginx/sites-available
sudo vi myapp01
Refer below snippet:
upstream appname-server {
server 127.0.0.1:8080;
}
server {
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name appname.com;
access_log /var/log/nginx/appname-access.log;
error_log /var/log/nginx/appname-error.log;
location / {
proxy_pass http://appname-server;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 5m;
proxy_send_timeout 5m;
}
listen 443 ssl;
ssl_certificate /path/to/your/ssl/cert.pem;
ssl_certificate_key /path/to/your/ssl/cert_key.pem;
}
server {
if ($host = appname.com) {
return 301 https://$host$request_uri;
}
server_name appname.com;
listen 80;
return 404;
}
Don't for get to add include /etc/nginx/sites-enabled/*; in nginx.conf. (Thanks to Drifter104 for notifying)
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
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;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Next, go to /etc/nginx/sites-enabled and create symbolic links for myapp01, refer instructions below.
Go to sites-enabled
cd /etc/nginx/sites-enabled/
Create symbolic links for myapp01
ln -s /etc/nginx/sites-available/myapp01 .
After that, test your nginx configuration using sudo nginx -t. If everything is successful, proceed to step 5.
Reload nginx sudo systemctl reload nginx
Hope it helps you, cheers.

nginx: how to set up server blocks to allow subdomain

I have openresty running on my aws instance (Instance A) and the ip address of the server is already tied to the domain name myapp.john.com.
My app is running on another aws instance (Instance B) within the same private network. It has private ip address of 192.42.56.87 and the app is running on port :80.
I want to set up my openresty / nginx such that when visiting prod.myapp.john.com, nginx directs me to 192.42.56.87:80. And when visiting test.myapp.john.com, nginx directs me to another instance (Instance C) running the test version of my app, say on 192.xx.xx.xx:80
Below are code in (Instance A):
Main config file /usr/local/openresty/nginx/conf/nginx.conf is defined as:
# Main NGNX Config File
#user www-data;
worker_processes auto;
pid logs/nginx.pid;
error_log logs/error.log info;
error_log logs/error.log notice;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
http {
include 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 logs/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 100000;
resolver 8.8.8.8 valid=30s ipv6=off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
gzip on;
# Include all the sites for the domain
include /usr/local/openresty/nginx/sites/*;
}
/usr/local/openresty/nginx/sites/prod.myapp.john.com is defined as:
server {
listen 80;
listen [::]:80;
server_name prod.myapp.john.com; // this does not work; but "myapp.john.com" works
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name prod.myapp.john.com; // this does not work; but "myapp.john.com" works
ssl_certificate /etc/letsencrypt/live/myapp.john.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.john.com/privkey.pem;
location / {
proxy_pass http://192.42.56.87:80/;
expires 0;
proxy_set_header 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 $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
Now, in chrome browser when I visit prod.myapp.john.com, there is no response at all since the request never get to my Instance A;
However, if I change
server_name prod.myapp.john.com
to
server_name myapp.john.com
it works and the web page gets rendered.
Why?
How can I include more site files in /usr/local/openresty/nginx/sites/ and set the server blocks in config correctly to provide more subdomains on my site?

Global variable on NGINX

I'm using NGINX to serve static files, reverse proxy to Django and verify client certificates.
I don't want the certificate to be asked at the url root, so I created another server on Nginx.conf to ask for the certificate on port 8443. This server is intended just to ask for the certificate and redirect the client back to port 443, where the reverse proxy to Django occurs.
This is my Nginx.conf:
events {
worker_connections 1024;
}
http {
include 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"';
sendfile on;
keepalive_timeout 65;
gzip on;
upstream app {
server django:8000;
}
# Redirect from HTTP to HTTPS
server {
listen *:80;
server_name localhost;
return 301 https://localhost$request_uri;
}
server {
listen *:443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/ssl/certificate.pem;
ssl_certificate_key /etc/nginx/ssl/certificate.key;
ssl_password_file /etc/nginx/ssl/certificate.pass;
ssl_verify_client off;
ssl_client_certificate /etc/nginx/ssl/chain.cer;
ssl_verify_depth 3;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_prefer_server_ciphers on;
server_tokens off;
underscores_in_headers on;
location /static/ {
autoindex off;
alias /static_files/;
}
location / {
try_files $uri $uri/ #app_web;
}
location #app_web {
proxy_pass http://app;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header CERTINFO $http_certinfo;
proxy_redirect off;
}
}
server {
listen *:8443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/ssl/certificate.pem;
ssl_certificate_key /etc/nginx/ssl/certificate.key;
ssl_password_file /etc/nginx/ssl/certificate.pass;
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ssl/certificate.cer
ssl_verify_depth 3;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_prefer_server_ciphers on;
add_header CERTINFO $ssl_client_s_dn;
return 301 https://$host$request_uri;
}
}
When the client authenticates on port 8443 and I return him to port 443, I need to forward his certificate information, the $ssl_client_s_dn to be more specific. To do so, I'm trying to use the method add_header on the server of the port 8443 (CERTINFO) and the method proxy_set_header capturing the value with $http_certinfo on the server of the port 443. But this solution is not working. The header is not forwarded from port 8443 to port 443 server.
My question is: is there a way to do that? Can I set some kind of "global" variable on the http block, change its value on port 8443 and than use the updated value on port 443 to forward it to Django?
Thank you so much!

How to configure NGINX to distribute PWA in https

I'm trying to redirect an APP that already works, to https.
The app is a PWA that is running locally, on 8080 port.
I know that's something in my configuration, because the root works ok, but the sub apps doesn't.
The root is just a html with the routes for the sub apps.
This is the app that I'm trying to redirect: https://github.com/PolymerLabs/multitenant-prpl
This is my configuration file, that I've made with searching around and mixing things into the main nginx configuration file.
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;
sendfile on;
keepalive_timeout 65;
upstream node-app {
least_conn;
server 192.168.0.9:8080 weight=10 max_fails=3 fail_timeout=30s;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# https redirection
location / {
return 301 https://$host$request_uri;
}
}
server {
# http2 setup
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name node-app;
# ssl setup
ssl_certificate /etc/nginx/certs/nginx.crt;
ssl_certificate_key /etc/nginx/certs/nginx.key;
ssl_dhparam /etc/nginx/certs/dhparam.pem;
# server redirection
location / {
proxy_pass http://node-app$request_uri;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header 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 $scheme;
proxy_cache_bypass $http_upgrade;
}
}
}
Probably something is missing.
Thanks in advance.
Images:
The root working.
Another route with the dev tools open, the error is a bit longer.

https not redirecting to mongrel upstream

Normal http is working fine for me with nginx and mongrel, however when i attempt to use https I am directed to the "welcome to nginx page".
http {
# passenger_root /opt/passenger-2.2.11;
# passenger_ruby /usr/bin/ruby1.8;
include 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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
upstream mongrel {
server 00.000.000.000:8000;
server 00.000.000.000:8001;
}
server {
listen 443;
server_name domain.com;
ssl on;
ssl_certificate /etc/ssl/localcerts/domain_combined.crt;
ssl_certificate_key /etc/ssl/localcerts/www.domain.com.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# ssl_prefer_server_ciphers on;
location / {
root /current/public/;
index index.html index.htm;
proxy_set_header X_FORWARDED_PROTO https;
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_pass http://mongrel;
}
}
}
Do you have an explicit server entry for port 80? It could be that an nginx default directive is intercepting the regular HTTP traffic.
Add a another server block just to be sure:
server {
listen 80;
server_name domain.com www.domain.com;
rewrite ^(.*) https://domain.com$1 permanent;
}
This will redirect all traffic for your app to https, which even if it isn't what you ultimately want to happen, at least you know you're missing the non-https block and you can then replace this with the directives you need.

Resources