I'm testing proxying an HTTPS request from a server running Nginx (which I will call client-side) to another (server-side) that will proxy the request to a local Alertmanager. The server-side is TLS with a self-signed certificate. When I set proxy_ssl_verify to on on the client-side with the self-signed certificate in proxy_ssl_trusted_certificate, the client-side Nginx returns 503 Unavailable without logging any error.
Any help understanding why the client-side Nginx closes the connection silently and returns 503 would be much appreciated!
**Server-side Nginx config **
nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/sites-enabled/*.conf;
}
alertmanager.conf:
upstream alertmanager {
server 127.0.0.1:9193;
}
server {
listen 127.0.0.1:9093 ssl;
listen 192.168.128.2:9093 ssl;
server_name 172.29.49.202;
include /etc/nginx/conf.d/common.conf;
include /etc/nginx/conf.d/ssl.conf;
ssl_certificate /etc/ssl/private/alertmanager-cert.pem;
ssl_certificate_key /etc/ssl/private/alertmanager-key.pem;
location / {
proxy_pass http://alertmanager;
include /etc/nginx/conf.d/common_location.conf;
auth_basic alertmanager;
auth_basic_user_file /etc/nginx/conf.d/alertmanager/.htpasswd;
add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Content-Type, Origin' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header X-XSS-Protection "1; mode=block";
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $http_origin always;
add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Content-Type, Origin' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header X-XSS-Protection "1; mode=block";
return 200;
}
}
}
ssl.conf:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/private/dhparams.pem;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
Nginx version on the server-side is 1.21.6.
Client-side Nginx config
nginx.conf:
user nginx;
worker_processes 4;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
worker_rlimit_nofile 99999;
events {
worker_connections 32768;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
limit_req_zone $server_name zone=one:10m rate=1800r/s;
keepalive_timeout 86400s;
keepalive_requests 150000;
client_header_timeout 86400s;
client_max_body_size 50M;
include /etc/nginx/conf.d/*.conf;
}
default.conf:
upstream alertmanager {
server 172.29.49.202:9093;
}
server {
listen 8080 ssl;
listen [::]:8080 ssl;
server_name management;
ssl_certificate /etc/ssl/nginx.crt;
ssl_certificate_key /etc/ssl/nginx.key;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-
RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location /alertmanager/ {
limit_rate 1024k;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass_header Server;
add_header X-XSS-Protection "1; mode=block";
# Allow backend with keepalive connections
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Authorization "Basic <redacted>";
proxy_pass https://alertmanager/;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/rbbn/ids/nginx/appsvc/alertmanager-cert.pem;
proxy_next_upstream error timeout http_500;
}
}
Note that alertmanager-cert.pem on both servers are the same self-signed cert. The nginx version is 1.22.1.
Validating connection with the certificate
I can see that validating the upstream connection with the self-signed cert works fine.
# curl -v -H "Authorization: Basic <redacted>" https://172.29.49.202:9093 --cacert alertmanager-cert.pem
* Rebuilt URL to: https://172.29.49.202:9093/
* Trying 172.29.49.202...
* TCP_NODELAY set
* Connected to 172.29.49.202 (172.29.49.202) port 9093 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/rbbn/ids/nginx/appsvc/alertmanager-cert.pem
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=blabla
* start date: Jan 11 23:46:27 2023 GMT
* expire date: Jan 11 23:46:27 2024 GMT
* subjectAltName: host "172.29.49.202" matched cert's IP address!
* issuer: CN=blabla
* SSL certificate verify ok.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET / HTTP/1.1
> Host: 172.29.49.202:9093
> User-Agent: curl/7.61.1
> Accept: */*
> Authorization: Basic <redacted>
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 200 OK
...
Running the command through Nginx with proxy_ssl_verify
When trying to do it through Nginx, I get a 503 response though.
# curl -v -k https://127.0.0.1:8080/alertmanager/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: ...
* start date: Jan 11 01:52:36 2023 GMT
* expire date: Dec 18 01:52:36 2122 GMT
* issuer: ...
* SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET /alertmanager/ HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 503 Service Temporarily Unavailable
< Server: nginx/1.22.1
< Date: Thu, 12 Jan 2023 19:18:50 GMT
< Content-Type: application/json
< Content-Length: 32
< Connection: keep-alive
< ETag: "63bf5851-20"
< Retry-After: 1
<
{"error":"Service Unavailable"}
I tried capturing traffic on the server-side and I see that the TLS handshake gets done, but then the client-side Nginx closes the connection.
TLS handshake
I see this error in the client-side Nginx's logs, but nothing on the server-side.
[info] 17#17: *272 client closed connection while waiting for request, client: 172.29.49.112, server: 192.168.128.2:9093
Testing without proxy_ssl_verify
When proxy_ssl_verify is disabled, the connection succeeds.
# curl -v -k https://127.0.0.1:8080/alertmanager/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: ...
* start date: Jan 11 01:52:36 2023 GMT
* expire date: Dec 18 01:52:36 2122 GMT
* issuer: ...
* SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET /alertmanager/ HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 200 OK
< Date: Thu, 12 Jan 2023 19:33:21 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 1381
< Connection: keep-alive
< Server: nginx/1.21.6
< Accept-Ranges: bytes
< Cache-Control: no-cache, no-store, must-revalidate
< Expires: 0
< Last-Modified: Thu, 01 Jan 1970 00:00:01 GMT
< Pragma: no-cache
< Access-Control-Allow-Headers: Accept, Authorization, Content-Type, Origin
< Access-Control-Allow-Methods: GET, POST, OPTIONS
< Access-Control-Allow-Credentials: true
< X-XSS-Protection: 1; mode=block
< X-XSS-Protection: 1; mode=block
getting a little confused, a test directory structure:
/usr/share/nginx/html/public:
index.php - uses rewrite
test.html
When i access example.com/test.html it returns 404, but index.php loads up the application with the rewrite rules all working perfectly.
I really don't understand what is happening when the test.html file exists in the same folder as index.php, so shouldn't try_files $uri pick that up?
Here is the nginx config:
server {
listen 80;
root /usr/share/nginx/html/public;
server_name example.com;
location / {
try_files $uri $uri/ /index.php$is_args$args;
#try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_next_upstream_timeout 10s;
fastcgi_next_upstream_tries 2;
fastcgi_pass localhost:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
internal;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
}
# deny access to apache .htaccess
location ~ /\.ht {
deny all;
}
error_log /usr/share/nginx/logs/error.log;
access_log /usr/share/nginx/logs/access.log;
}
EDIT
Before this part is executed there is a reverse proxy before it which is configured like this:
server {
listen 443 ssl;
ssl_certificate /usr/local/etc/ssl/certs/live/example.com/cert.pem;
ssl_certificate_key /usr/local/etc/ssl/certs/live/example.com/privkey.pem;
ssl_session_timeout 10m;
ssl_verify_client off;
server_name example.com;
error_log /usr/share/nginx/logs/error-api.log;
access_log /usr/share/nginx/logs/access-api.log;
location / {
proxy_next_upstream error timeout http_502;
proxy_next_upstream_tries 10;
proxy_pass http://api;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_ssl_session_reuse on;
proxy_set_header Origin https://gofollow.vip;
proxy_hide_header Access-Control-Allow-Origin;
add_header Access-Control-Allow-Origin $http_origin;
proxy_set_header Referer $host:$server_port;
proxy_http_version 1.1;
proxy_set_header X-XSS-Protection 1;
proxy_set_header X-Content-Type-Options nosniff;
proxy_set_header Referrer-Policy origin;
proxy_set_header X-Frame-Options DENY;
proxy_buffering on;
proxy_cache STATIC;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
}
}
Here is the output of a curl request to the test.html file via the reverse proxy, i have replaced domain with example.com and ip with 111.11.111.111:
* Trying 111.11.111.111:443...
* Connected to example.com (111.11.111.111) port 443 (#0)
* ALPN, offering http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=example.com
* start date: May 20 12:10:16 2022 GMT
* expire date: Aug 18 12:10:15 2022 GMT
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET /test.html HTTP/1.1
> Host: example.com
> User-Agent: curl/7.82.0
> Accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Server: nginx/1.21.6
< Date: Sat, 21 May 2022 11:00:16 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/7.4.29
< Cache-Control: no-cache, private
< X-Frame-Options: DENY
< X-XSS-Protection: 1
< X-Content-Type-Options: nosniff
< Referrer-Policy: origin
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Access-Control-Expose-Headers: link
<
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex,nofollow,noarchive" />
<title>An Error Occurred: Not Found</title>
<style>body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
.container { margin: 30px; max-width: 600px; }
h1 { color: #dc3545; font-size: 24px; }
h2 { font-size: 18px; }</style>
</head>
<body>
<div class="container">
<h1>Oops! An Error Occurred</h1>
<h2>The server returned a "404 Not Found".</h2>
<p>
Something is broken. Please let us know what you were doing when this error occurred.
We will fix it as soon as possible. Sorry for any inconvenience caused.
</p>
</div>
</body>
* Connection #0 to host example.com left intact
</html>%
my certificates is valid
there is another webServer in my ec2 and use 443 port.
so I planed use 8443 port rather then 443 port.
but Ive got 400 error
I think the ssl what I typed in my config isn't work well in the url.
ssl absolute path also not working.
would you help me?
this is my config.
NGINX.conf
user nginx;
worker_processes auto;
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"';
error_log /var/log/nginx/error.log;
access_log off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
}
and
/etc/nginx/conf.d/myTest.conf
server {
listen 80;
listen 8443 default ssl;
server_name ;
ssl_certificate star_cyberskyshop_com_NginX_cert.pem;
ssl_certificate_key star_cyberskyshop_com_NginX_nopass_key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /var/www/code/img1/public;
Index index.html index.htm index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/code/img1/public$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}
}
this is curl log
jangbyeongwoo#jangbyeong-uui-MacBookAir ~ % curl -v https://img1.cyberskyshop.com:8443/sample.jpg
* Trying 52.78.41.24:8443...
* Connected to (52.78.41.24) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
* CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=KR; L=Seoul; O=Cybersky Co., Ltd.; OU=Development Team; CN=*.e-skyshop.com
* start date: Mar 26 00:00:00 2021 GMT
* expire date: Apr 26 23:59:59 2022 GMT
* subjectAltName does not match img1.cyberskyshop.com
* SSL: no alternative certificate subject name matches target host name 'img1.cyberskyshop.com'
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
curl: (60) SSL: no alternative certificate subject name matches target host name 'img1.cyberskyshop.com'
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
below picture is i added ssl pem file.
it's CN is present well(*.cyberskyshop.com). but curl log isnt show correct one.
enter image description here
I'm trying to setup websocket proxy for a defined location (/ws) and it doesn't work. But using root (/) as location works for me.
works:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://echo.websocket.org;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
}
doesn't work:
server {
listen 80;
server_name localhost;
location /ws {
proxy_pass http://echo.websocket.org;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
}
I also inspected the server response:
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost:8888" -H "Origin: http://localhost:8888/ws" http://localhost:8888/ws
HTTP/1.1 404 WebSocket Upgrade Failure
Server: nginx/1.13.12
Date: Thu, 17 Jan 2019 15:15:50 GMT
Content-Type: text/html
Content-Length: 77
Connection: keep-alive
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Headers: x-websocket-extensions
Access-Control-Allow-Headers: x-websocket-version
Access-Control-Allow-Headers: x-websocket-protocol
Access-Control-Allow-Origin: http://localhost:8888/ws
<html><head></head><body><h1>404 WebSocket Upgrade Failure</h1></body></html>
what am I doing wrong?
I think the problem here is with the pattern matching. You first have to give websocket url from client side as ws://localhost:80/ws/
Note here you have to give (/) at the end of the url, and at the NGINX server side, configure it in this way :
server {
listen 80;
server_name localhost;
location /ws/ {
proxy_pass http://echo.websocket.org;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}}
Note here that you have to give /ws/ reference to location.
I am trying to set up nginx with this config. To access backend.mygreat.server.com I have to go through my corporate proxy, which is myproxy.server.com:80.
Hence, I have added this in /etc/environment
https_proxy=myproxy.server.com:80
Yet, nginx is unable to reach https://backend.mygreat.server.com:443. I'm seeing 504 as HTTP status in nginx logs.
I could use wget or curl to load the page (goes via corporate proxy)
server {
listen 443;
server_name mygreat.server.com;
ssl on;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!SEED:!DSS:!CAMELLIA;
ssl_certificate /etc/nginx/ssl/mygreat.server.com.pem;
ssl_certificate_key /etc/nginx/ssl/mygreat.server.com.key;
access_log /var/log/nginx/access.ssl.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host-Real-IP $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-Pcol http;
proxy_intercept_errors on;
error_page 301 302 307 = #handle_redirects;
proxy_pass https://backend.mygreat.server.com:443;
}
location #handle_redirects {
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
}
Any help is greatly appreciated.
Thanks
Update :
Here is the sample error log from nginx
2017/10/18 06:55:51 [warn] 34604#34604: *1 upstream server temporarily disabled while connecting to upstream, client: <ip-address>, server: mygreat.server.com, request: "GET / HTTP/1.1", upstream: "https://<ip-of-backend>:443/", host: "mygreat.server.com"
If I run curl -v https://backend.mygreat.server.com/ below is the response
* About to connect() to proxy corp-proxy.server.com port 80 (#0)
* Trying <some-ip-address>...
* Connected to corp-proxy.server.com (<ip-of-proxy>) port 80 (#0)
* Establish HTTP proxy tunnel to backend.mygreat.server.com:443
> CONNECT backend.mygreat.server.com:443 HTTP/1.1
> Host: backend.mygreat.server.com:443
> User-Agent: curl/7.29.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied OK to CONNECT request
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=backend.mygreat.server.com,OU=Technology Operations,O=MyCompany.,L=San Diego,ST=California,C=US
* start date: Mar 15 00:00:00 2017 GMT
* expire date: Mar 15 23:59:59 2020 GMT
* common name: backend.mygreat.server.com
* issuer: CN=Symantec Class 3 Secure Server CA - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: backend.mygreat.server.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: openresty/1.11.2.5
< Date: Wed, 18 Oct 2017 14:03:10 GMT
< Content-Type: text/html;charset=UTF-8
< Content-Length: 5642
< Connection: keep-alive
< X-XSS-Protection: 1; mode=block
< Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private
< Expires: 0
< P3P: policyref="http://backend.mygreat.server.com/w3c/p3p.xml" CP="CURa OUR STP UNI INT"
< Content-Language: en
< Set-Cookie: qboeuid=127.0.0.1.1508335390550307; path=/; expires=Thu, 18-Oct-18 14:03:10 GMT; domain=.server.com
< Set-Cookie: JSESSIONID=784529AA39C10C3DB4B0ED0D61CC8F31.c23-pe2ec23uw2apu012031; Path=/; Secure; HttpOnly
< Set-Cookie: something.blah_blah=testme; Domain=.server.com; Path=/; Secure
< Vary: Accept-Encoding
<
<!DOCTYPE html>
<html>
....
</html>
So first of all I am not sure if Nginx is suppose to respect http_proxy and https_proxy variables. I didn't find any documentation on the same. So I assume your issues is related to nginx not using proxy at a all
So now you have an option to use something which actually uses proxy. This is where socat comes to rescue.
Running socat forwarder
If you have a transparent proxy then run
socat TCP4-LISTEN:8443,reuseaddr,fork TCP:<proxysever>:<proxyport>
And if you have CONNECT proxy then use below
socat TCP4-LISTEN:8443,reuseaddr,fork PROXY:yourproxy:backendserver:443,proxyport=<yourproxyport>
Then in your nginx config use
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host-Real-IP $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-Pcol http;
proxy_intercept_errors on;
proxy_set_header Host backend.mygreat.server.com;
proxy_pass https://127.0.0.1:8443;
proxy_redirect https://backend.mygreat.server.com https://mygreat.server.com;
}
You probably want to use Systemd service to launch the socat, so it runs on startup and is handled as a service
Nginx's proxy_pass does not support https proxy.
http proxy can be supported, but the request url only supports http.
this is a example:
server {
listen 8880;
server_name localhost;
location / {
rewrite ^(.*)$ "://developer.android.com$1";
rewrite ^(.*)$ "http$1" break;
proxy_set_header Proxy-Connection Keep-Alive;
proxy_set_header Host developer.android.com;
proxy_pass http://127.0.0.1:1080;
proxy_redirect ~^https?://developer\.android\.com(.*)$ http://$host:8080$1;
}
}
see: https://serverfault.com/a/683955/418613