nginx chunked transfer encoding fails - java

I am using an implemention of nginx with jetty servlets.
For the purpose of my project I need to initialize two connection to the jetty servlet and keep them open.
To initialize the downlink I use a normal request and I get the inputstream back.
To initialize the uplink I use a chunked encoding request.
I use a 1.4.6 nginx version so the chunked encoding should be set by default, regardless I set it in my server definition.
#HTTPS server
server {
listen 443;
listen [::]:443;
server_name localhost;
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_http_version 1.1;
expires off;
proxy_buffering off;
chunked_transfer_encoding on;
proxy_pass https://127.0.0.1:8080;
# root html;
# index index.html index.htm;
}
}
I've searched through all the forums and I still can't come across a solution.
Enabled chunked encoding, proxy buffering off etc etc.
I can't get it to work. I have also done simple tests to make that it's not my apps implementation that's blocking it somehow and it still doesn't work.
Anything else I can try?

So I also posted on the nginx forum and I got a reply. The thing I am specifically looking for is called "unbuffered upload" and that is currently a feature that nginx does not provide.
Using websockets is out of the question because later this prototype will need to be implement in a bigger and older system that uses the http protocol. So the answer for this would be it's not possible with "nginx". A possible work around for anyone facing the same issue is using tengine which is an nginx fork.

Related

Open Trip Planner over HTTPS

I'm trying to deploy a solution using Open Trip Planner, and everything is OK if I use HTTP, but apparently the HTTPS connection doesn't work.
I've followed the official docs but with no success, apparently the internal server is running, it logs that the expected HTTPS port is listening and the port is actually shown as listening by the OS (Windows 10 Pro) but no secure connection can be established (I tried the "curl" and "open-ssl" tests in the page but both failed)
This is the document I refer to:
http://docs.opentripplanner.org/en/latest/Security/#security
Please any help is appreciated, thanks in advance
Is using a reverse proxy like nginx an option for you? That way nginx can handle the HTTPS requests, and then pass them onto opentripplanner.
Here's an example nginx configuration:
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/cacert.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
server_name opentripplanner.example.com;
proxy_pass http://127.0.0.1:8000;
}
References:
https://manual.seafile.com/deploy/https_with_nginx.html
https://nginx.org/en/docs/beginners_guide.html

How to disable ssl connection for specific api calls on tomcat 8?

I am setting up my tomcat 8 server to use a SSL connection and the application is working fine - the redirect from HTTP to HTTPS is good, but I need to find a way to allow HTTP for some pages (API calls).
Why do I need that? because those API calls are trying to upload/download something to/from the server and because the connection is secure, those files are firstly - encrypted, secondly - decrypted and finally - used. And because the CPU has low performance, the upload/download speed is very poor.
I've tried to change configuration from conf/web.xml file, with no success.
If I change the parameter from CONFIDENTIAL to NONE, but both connection types (HTTP /HTTPS) will be enabled - and this is not what I need.
Any help in this direction is appreciated.
Thank you,
If you are using the Linux system like Ubuntu, then, instead of setting up an SSL connection setup in Tomcat, you will use the Nginx server. Use the following link for installation. In the Nginx server configuration file, nginx.conf, you can define a location inside the server name setting and then you can filter the APIs that you do not want to enable as HTTPS.
For setting SSL in Nginx, you have to use the ssl_certificate & ssl_certificate_key setting.

Apache2 Proxy Error:Error reading from remote server

Environment:
Apache2
nanohttpd (web server (java))
The site itself is and has been working fine, I have added alot of entries to a database which the nanohttpd web server returns on some endpoints
I have figured out that is has todo with the length of the site being returned since when I move entries from one status to another, the one with alot of entries will always give me this error.
I already looked around a bit and think it may be a timeout issue but I have added timeouts to my virtual host and this problem still persists
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /foo
Reason: Error reading from remote server
Apache/2.4.10 (Debian) Server at foo.foo.foo Port 443
My current VirtualHost file for this:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/directory
ServerName foo.foo.foo
ServerAlias foo.foo.foo
ProxyPass "/" "http://foo.com:8080/"
ProxyPassReverse "/" "http://foo.com:8080/"
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Include /etc/path/options-ssl-apache.conf
SSLCertificateFile /etc/path/foo.com-0001/fullchain.pem
SSLCertificateKeyFile /etc/path/foo.com-0001/privkey.pem
</VirtualHost>
</IfModule>
What I had tried earlier was adding timeout=x and connectiontimeout=x behind ProxyPass but this didnt seem to help
Edit:
Since there is still no answer here is some more info, I will add a bounty once eligible.
As you can see in my VirtualHost file I am using Apache Reverse Proxy to enable SSL for my application
So my little nanohttpd server basically returns a very simplistic html page with a table and a row for each database entry. If the specific category has more than around 100 entries I will get the Proxy Error message.
At this point I am very certain that it has todo with something timeing out but I have went through so many posts and tried to add configs to mine and (yes I restarted Apache2 after every change) nothing worked so far.
Could it be something on my nanohttpd server that I am missing?
A simple Header or Cookie, I am sending none of those as of now.
If any required information is missing please let me know.
Some of your input may have been malformed.
Well funnily enough I figured it out and I feel horrible now..
The table data I was inserting included a dollar sign and apparently I did not think of escaping the replacement String

java 1.6 TLS1.2 support using proxy nginx/ squid solution issues

I have a legacy java web application that makes calls to an external webservice. The provider of that service is turning off TLS1.0 support. So, I am trying to see how the application can continue to work with the service.
The options I have seen are a) use BouncyCastle JCE instead of Java JCE http://boredwookie.net/index.php/blog/how-to-use-bouncy-castle-lightweight-api-s-tlsclient/, which I guess requires code change/ recompile (we don't have the luxury of doing it) or 2) use proxy servers https://www.reddit.com/r/sysadmin/comments/48gzbi/proxy_solution_to_bump_tls_10_connection_to_tls_12/
I have tried nginx proxy - it doesn't seem to handle the switch between TLS1.0 incoming and TLS1.2 that the end server expects.
server { listen 443 ssl; server_name proxy.mydomain.com;
ssl_certificate D:/apps/openssl/proxy.mydomain.com.cert;
ssl_certificate_key D:/apps/openssl/proxy.mydomain.com.private;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP;
ssl_prefer_server_ciphers on;
location / {
proxy_pass https://fancyssl.hboeck.de/;
}
This fails with a 502/ bad gateway error since https://fancyssl.hboeck.de only support TLS1.2 but works with https://www.google.com that supports TLS1.0.
I am doing this on Windows.
It's not TLSv1.2, it's lack of SNI leading to renegotiation.
First, I set up nginx (1.8.1/Windows) with a config like yours except using my own key&cert and proxying to my own test server. It worked fine, connecting from Java6 requester with TLSv1.0 and to server with TLSv1.2 (and even ECDHE-RSA-AES256GCM-SHA384, one of the 'best' ciphersuites) and returned pages just fine. I tried fancyssl.hboek.de and got 502 like you.
With wireshark I saw that nginx does not send SNI (by default) and at least using the IPv4 address 46.4.40.249 (I don't have IPv6) that server apparently hosts more than one domain because without SNI it provides a different (and expired!) certificate, for *.schokokeks.org, and after the first application data (the request) it sends an encrypted handshake (a renegotiation request -- which nginx does not honor). Testing with openssl s_client confirms that the server with SNI immediately sends the page but without it renegotiates first; repointing nginx to openssl s_server confirms that if the server requests renegotiation, receives no response, and closes nginx treats that as 502.
I would guess that Apache is renegotiating because it realizes the requested Host is not covered by the certificate -- except that it again uses the 'wrong' certificate. I haven't tried to track that part down.
Google does support TLSv1.2 (and ECDHE-RSA-AESGCM) when I connect, but even without SNI doesn't renegotiate, presumably because it's such high volume nothing else runs on www.google.com servers and there's no ambiguity. My test server doesn't have vhosts so didn't need SNI.
The nginx documentation reveals a directive proxy_ssl_server_name which can be set on to enable SNI, and then proxying to this server works.
FYI: several of the statements on that webpage are wrong, although its conclusion (if possible use TLSv1.2 with ECDHE or DHE and AES-GCM) is good.
Also, most of your ssl_ciphers string is useless, but you didn't ask about that.
ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP
HIGH is an excellent start.
SEED is useless in a server used (only) by Java/JSSE client, because it's not implemented on the Java side. Even outside of Java it was pretty much used only in South Korea, where it was created as an alternative to DES or IDEA, and even there it is mostly obsoleted by ARIA which is an alternative to AES -- but is not implemented by OpenSSL and hence nginx.
aNULL is probably unneeded because JSSE disables 'anonymous' suites by default, but here it's worth it as defense in depth.
!eNULL does nothing; no eNULL suites are in HIGH, or DEFAULT, or even ALL. You can only get them explicitly or with the bizarre COMPLEMENTOFALL -- which you shouldn't.
!EXPORT !DES !RC4 do nothing; none of them are in HIGH. If instead you started from DEFAULT on older versions of OpenSSL, or from ALL, then they would be good.
!PSK is unneeded; nginx doesn't appear to configure for PSK and JSSE doesn't implement it anyway.
!RSAPSK is ignored because OpenSSL doesn't implement that keyexchange, and if it did those suites are already covered as above.
!aDH !aECDH are covered by !aNULL and thus do nothing.
!EDH-DSS-DES-CBC3-SHA is silly; there's no reason to exclude this one suite when you keep other DHE_DSS and 3DES suites.
!KRB5-DES-CBC3-SHA is ignored because OpenSSL doesn't implement Kerberos, and if it did nginx wouldn't be configured for it plus again it would be silly to exclude one suite while keeping similars.
!SRP is unneeded; like PSK nginx apparently doesn't configure and JSSE doesn't implement.
So: HIGH:!aNULL is all you need.

PlayFramework return absolute url in http instead of httpS?

I've implemented a project in Play!Framework with NGinx using only https.
Everything works fine, the SSL is well recognized and I can use my app from anywhere but when Play! returns an absolute URL, it's in http, not https.
This is problematic, and I don't know where the problem is.
I tried to start Play with -Dhttps.port=XXXX instead of -Dhttp.port=XXXX but it didn't changed the output of "http" instead of "https".
I'm suspecting an Nginx bad configuration (a parameter I forgot?).
Here's my sites-enabled/website config file :
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme "https"; # I also tried $scheme without any luck
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
server {
listen 80;
server_name my.website.com;
return 301 https://my.website.com;
}
upstream my-backend {
server 127.0.0.1:9100;
}
server {
listen 443;
ssl on;
root /var/www/website/errors/;
# http://www.selfsignedcertificate.com/ is useful for development testing
ssl_certificate /etc/nginx/ssl/my.website.com.crt;
ssl_certificate_key /etc/nginx/ssl/my.website.com.key;
# From https://bettercrypto.org/static/applied-crypto-hardening.pdf
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive
ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA';
add_header Strict-Transport-Security max-age=15768000; # six months
# use this only if all subdomains support HTTPS!
# add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"
keepalive_timeout 70;
server_name my.website.com;
location / {
#proxy_pass http://my-backend;
proxy_pass http://127.0.0.1:9100;
}
location ~ /\.git {
deny all;
}
error_page 502 #maintenance;
location #maintenance {
rewrite ^(.*)$ /error502.html break;
}
}
What am I missing?
Update: Here's the code that generate the absolute url :
controllers.routes.Pages.loginToken(getToken()).absoluteURL(play.mvc.Http.Context.current().request());
What you actually need is to add the scheme in the X-Forwarded-Proto header. None of the X-Forwarded-* headers are standard, but the convention (or defacto standard) is to put the scheme in X-Forwarded-Proto, and Play has support this since 2.3.0:
https://github.com/playframework/playframework/pull/1823
So, if you add the following to your nginx config:
proxy_set_header X-Forwarded-Proto $scheme;
And have configured Play to trust the x forwarded headers, by adding this to your application.conf:
trustxforwarded=true
Then RequestHeader.secure will return true.
Note that in Play 2.4, we've improved the support dramatically, implementing the full specification for the new standard Forwarded header, as well as being able to specify which hosts to trust forwarded headers from.
There are a couple overloads for absoluteURL. You're using this one:
public String absoluteURL(Http.Request request) {
return absoluteURL(request.secure(), request.host());
}
The problem with this is that since you're reverse proxying to Play via nginx, Play is actually receiving all the requests through HTTP, and not HTTPS. This means that request.secure() is false, and absoluteURL will return a URL containing http://....
Instead, manually set secure to true in one of the overloads:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(play.mvc.Http.Context.current().request(), true);
Additionally, what I normally do is have a configuration variable for secure so it can generate non-https URLs when developing locally.
In application.conf:
application.secure = false # for local dev
And in production I add the command line option -Dapplication.secure=true when starting the application, to override the value in application.conf.
Then generating the URL would look like this:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(
play.mvc.Http.Context.current().request(),
play.Play.application().configuration().getBoolean("application.secure", true) // default to true
);

Categories