Does jAgent support https endpoints? - api

We currently have some API endpoints on jAgent. These are all Http ones. I am calling these APIs from my Angular application to communicate with the jBase backend. We just hosted the Angular app on Https with a Self-signed certificate only to realise the API calls fail with the error message, "The page at 'https://*' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://'. This request has been blocked; the content must be served over HTTPS."
Is there a way to make the endpoints on jAgent https so that we can resolve this?

You can indeed configure jAgent to use SSL so that you can serve requests over HTTPS. There's too much to copy/paste here in full but in short please refer to jAgent Administration: jAgent Configuration File and note these comments:
; For SSL connections, specify the path of the x509 certificate to
; use. When a certificate is specified, a private key must also be
; specified. This option duplicates the -c (--certificate) command
; line option.
;certificate = <path to certificate (.pem) file>
; For SSL connections, specify the path of the private key for the
; certificate being used. This option duplicates the -k (--private_key)
; command line option.
;private_key = <path to private key (.pem) file>
And also please refer to jAgent Security for additional context. It is possible to specify the cert and key via command line args when running jAgent, or (recommended) to set within the config and take care to specify the config. This command illustrates both:
jbase_agent -c cert.pem -k key.pem --config %HOME%\jagent_config

Related

Is it recommended to disable ssl verification instead of providing ca certificate in production?

Our client has provided self signed certificate for one of the internal service. We are acceessing this service in our shell script using curl. In order to connect to that service we need to provide certiface in our curl command or we can disable ssl verification using -k in our curl command. We wanted to know is it safe to disable ssl verification on production?
NO
Disabling certificate verification removes all security properties from the HTTPS connection. It is strongly advised that you do not disable it.

How do I have Apache2 httpd use the ubuntu's CA cert for outbound SSL connections from Apache?

Note this is not a question about having apache accept inbound SSL connections.
I have an apache module that needs to make outbound SSL connections. When it attempts to, it gets this error:
Failed to send events: The OpenSSL library reported an error: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed:s3_clnt.c:1269:
This is indicating the SSL library that apache is using doesn't know about the (valid) certificate of the server that my module is trying to connect to.
The CA cert on my ubuntu system where this is running is fine, knows about this downstream cert, openssl s_client tells me everything is ok.
How do I tell Apache2 to use ubuntu's system CA cert to make outbound connections work?
update - I did an strace -e open httpd -X to see where it was trying to load certificates from. I see apache opening libssl.so, but then I don't see it even trying to open up the usual ssl.cnf or any certificates file.
snipped useless strace output
update2: As to how I'm creating the https request - I'm making the request from inside my custom apache module. My module .so is written in Rust, so the connection code looks basically like:
in mod_mine.so:
use hyper::Client;
use hyper_tls::HttpsConnector;
use tokio_core::reactor::Core;
let mut core = Core::new()?;
let handle = core.handle();
let client = Client::configure()
.connector(HttpsConnector::new(4, &handle)?)
.build(&handle);
//actually a POST, but this gets the same error
let request = client.get("https://saas.mycompany.io".parse()?);
let result = core.run(request)?;
... //process result
I found a solution that works, though I'm not sure it is optimal.
openSSL takes the environment variable SSL_CERT_FILE. I can set this in my apache module source code.
use std::env;
let cert_file = figure_out_cert_path(); //on ubuntu: /etc/ssl/certs/ca-certificates.crt
env::set_var("SSL_CERT_FILE", cert_file);

How to simulate non-SNI browsers (without SNI support)?

I'm setting up Apache with several distinct SSL certificates for different domains that reside on the same server (and thus sharing the same IP address).
With Qualys SSL Test I discovered that there are clients (i.e. BingBot as of december 2013) that do not support the SNI extension.
So I'm thinking about crafting a special default web application that can gather the requests of such clients, but how can I simulate those clients?
I'm on Windows 8, with no access to Linux boxes, if that matters.
You can use the most commonly used SSL library, OpenSSL. Windows binaries are available to download.
openssl s_client -connect domain.com:443 command serves very well to test SSL connection from client side. It doesn't support SNI by default. You can append -servername domain.com argument to enable SNI.
If you are using OpenSSL 1.1.0 or earlier version, use openssl s_client -connect $ip:$port, and OpenSSL wouldn't enable the SNI extension
If you are using OpenSSL 1.1.1, you need add -noservername flag to openssl s_client.
Similar to openssl s_client is gnutls-cli
gnutls-cli --disable-sni www.google.com
You could install Strawberry Perl and then use the following script to simulate a client not supporting SNI:
use strict;
use warnings;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new(ssl_opts => {
# this disables SNI
SSL_hostname => '',
# These disable certificate verification, so that we get a connection even
# if the certificate does not match the requested host or is invalid.
# Do not use in production code !!!
SSL_verify_mode => 0,
verify_hostname => 0,
});
# request some data
my $res = $ua->get('https://example.com');
# show headers
# pseudo header Client-SSL-Cert-Subject gives information about the
# peers certificate
print $res->headers_as_string;
# show response including header
# print $res->as_string;
By setting SSL_hostname to an empty string you can disable SNI, disabling this line enables SNI again.
The approach of using a special default web application simply would not work.
You can't do that because said limited clients not just open a different page, but they fail completely.
Consider you have a "default" vhost which a non-SNI client will open just fine.
You also have an additional vhost which is supposed to be open by an SNI-supporting client.
Obviously, these two must have different hostnames (say, default.example.com and www.example.com), else Apache or nginx wouldn't know which site to show to which connecting client.
Now, if a non-SNI client tries to open https://www.example.com, he'll be presented a certificate from default.example.com, which would give him a certificate error. This is a major caveat.
A fix for this error is to make a SAN (multi-domain) certificate that would include both www.example.com and default.example.com. Then, if a non-SNI client tries to open https://www.example.com, he'll be presented with a valid certificate, but even then his Host: header would still point to www.example.com, and his request will get routed not to default.example.com but to www.example.com.
As you can see, you either block non-SNI clients completely or forward them to an expected vhost. There's no sensible option for a default web application.
With a Java HTTP client you can disable the SNI extension by setting the system property jsse.enableSNIExtension=false.
More here: Java TLS: Disable SNI on client handshake

RFC5766-turn-server with TLS

I'm trying to start my TURN server with TLS enabled. I use the following line to start the server:
daemon --user=$USER $TURN $OPTIONS --tls-listening-port 3478 --cert /root/cert_2014_11/my_domain_nl.crt --pkey /root/cert_2014_11/my_domain_nl.key --CA-file /root/cert_2014_11/PositiveSSLCA2.crt
The environment variables in there are set in the config file. The server works fine without TLS using the same startup line, but if I add the three SSL related arguments, the server still isn't reachable over TLS. I tried setting a different port for SLL instead of the standard port, but it still didn't work. Whatever I do, I can reach the server without SLL, but over TLS I can't reach it. The certificate chain I use if fine, I use it for our website as well.
I've run into this exact problem before. Have a look at the documentation for the --CA-file argument:
--CA-file <filename> CA file in OpenSSL format.
Forces TURN server to verify the client SSL certificates.
By default, no CA is set and no client certificate check is performed.
This argument is needed only when you will be verifying client certificates. It's not for the certificate chain for your server certificate.
Drop the --CA-file argument, keeping the --cert and --pkey arguments.
EDIT: FYI, the certificate file you give to the --cert option can contain the entire certificate chain (yours and your CA's).

Send client certificate to Server in Tcl

Currently my application (in C) authenticates to a web server using an SSL certificate. I'm now moving most of the funcitions (if not all) to Tcl.
I couldn't find any tutorial or example on how to do it (I'd prefere to use Tcl ::http:: but TclCurl would be fine).
Any suggestions?
Thanks
Johannes's answer is right, except if you want to provide different identities to different sites. In that case you use tls::init, which allows you to set default TLS-related options to tls::socket prior to that command being called.
package require http
package require tls
http::register https 443 ::tls::socket
# Where is our identity?
tls::init -keyfile "my_key.p12" -cafile "the_server_id.pem"
# Now, how to provide the password (don't know what the arguments are)
proc tls::password args {
return "the_pass"; # Return whatever the password is
}
# Do the secure connection
set token [http::geturl https://my.secure.site/]
# Disable the key
tls::init -keyfile {}
Note that the way of providing the password is bizarre, and I know for sure that this mechanism isn't going to be nice when doing asynchronous connections. (There's a standing Feature Request for improving the integration between the http and tls packages…)
To use https with tcl you usually use the tls package. The man page for the http package gives you an example how to do that:
package require http
package require tls
::http::register https 443 ::tls::socket
set token [::http::geturl https://my.secure.site/]
If you read the documentation of the tls package for tls::socket, you find that there are some options to pass client certificates. Combining that gives you:
::http::register https 443 [list ::tls::socket \
-cafile caPublic.pem -certfile client.pem]
You might have to specify the -password callback parameter if the certificate file is protected by a password.
Note that this solution uses the client certificate for each https (regardless of the target) request from your application.
Edit: As Donal suggested, it might be better to use tls::init than to specify it with ::http::register.
An example:
package require http
package require tls
::http::register https 443 ::tls::socket
proc ::get_cert_pass {} {
return "passw0rd"
}
# Add the options here
::tls::init -cafile caPublic.pem -certfile client.pem -password ::get_cert_pass
set tok [::http::geturl https://my.secure.site/]
To do a request, always use the last 2 line then.