Client fails to connect ejabberd with SSL on port 5223 - ssl

I configured ejabberd 18.09 to enable SSL on port 5223 with a valid SSL certificate and I can open it on the browser and I receive
<?xml version='1.0'?>
<stream:stream id='16717309979809466549' version='1.0' xml:lang='en'
xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'>
<stream:error>
<not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>
syntax error</text>
</stream:error>
</stream:stream>
with no SSL error, but I cannot connect with Converse or Smack. I have to say that Converse and Smack works fine without SSL with port 5222.
port 5223 config is:
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
tls: true

Its a new port that you configured right?
You enabled tls:true
So you need to provide the authentication options(certificate url). only then it will work

Related

HAProxy TLS/SSL with Apache Pulsar

I am using HAProxy as a TCP load balancer in front of a series of Apache Pulsar Proxy. I am trying to enable SSL/TLS encryption for my connection to Apache Pulsar cluster. For testing I am using a let's encrypt cert. Unfortunately, when I am trying to connect to the admin REST API of the Apache Pulsar broker through the HAProxy host, I am met with a warning about a insecure connection or connection refused.
Currently my HAProxy config for an SSL connection on port 8443 looks like this:
listen https_frontend
bind :8443 ssl crt /etc/letsencrypt/live/my_url/haproxy_cert.pem
mode tcp
option tcplog
balance roundrobin
server proxy1 10.0.0.X:8443 check maxconn 10000
server proxy2 10.0.0.X:8443 check maxconn 10000
server proxy3 10.0.0.X:8443 check maxconn 10000
server proxy4 10.0.0.X:8443 check maxconn 10000
Do the Apache Pulsar proxies and brokers need their own certs as well?
Thanks!
It looks like you are forwarding a SSL/TLS port on HAProxy to the SSL/TLS port on the Pulsar proxy/broker (8443), assuming you are using the default port for that on the Pulsar proxy/broker. If you don't want to have to configure certificates on Pulsar proxy/broker for SSL/TLS, you should configure HAProxy to send to the plain-text port on the Pulsar proxy/broker (80).

Haproxy TLS terminating and passthrough based on sni

I have similar path for the requests:
client mydomain.com -> nlb:443 -> haproxy -> cloudfront
client a.mydomain.com -> nlb:443 -> haproxy -> target_group_a
Main idea is do tls passthrough for the main domain name and send it to cloudfront without TLS termination. Requests into a.mydomain.com should pass to target_group_a and it should terminate tls. So my config for this is:
frontend main
bind *:443
mode tcp
option tcplog
log global
tcp-request inspect-delay 5s
acl is_main req_ssl_sni -i "${pDomainName}"
acl is_a req_ssl_sni -m beg "a"
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend main if is_main
use_backend a if is_a
backend main
mode tcp
option ssl-hello-chk
server cloudfront "${pCloudFrontUrl}:443" check resolvers aws
backend a
mode tcp
server local 127.0.0.1:9666 send-proxy
frontend a
bind *:9666 ssl crt server.pem ca-file ca.pem verify required accept-proxy
mode http
default_backend proxy_a
backend proxy_a
mode http
server elb "${pServer}:80" check resolvers aws
Main record pass successfull and I get CloudFront SSL termination and everything is okay, but not for a.mydomain.com.
Also I tried to watch what SNI Haproxy is capture but I got only capture0: - in logs. I did like (right after tcp inspect line)
tcp-request content capture req_ssl_sni len 15
log-format "capture0: %[capture.req.hdr(0)]"
and it's strange because routing works.
I've tried a lot of possibilities.. For now I get SSL peer handshake failed, the server most likely requires a client certificate to connect error, but if I do listen frontend a on another port and in http mode everyting works fine.
Maybe I miss something basic or not, but I'm stuck on it for ages and maybe someone could help me.
For someone who is suffering or will suffer with that situation, just be sure that you are testing with gnu version of curl (or build it with properly libraries) because it doesn't work for me with BSD curl. My curl version and libs
curl 7.66.0 (x86_64-apple-darwin17.7.0) libcurl/7.66.0 SecureTransport zlib/1.2.11
Release-Date: 2019-09-11
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile libz NTLM NTLM_WB SSL UnixSockets

Ejabberd with haproxy ssl termination

anyone got successful with ejabberd + ssl termination with haproxy 1.7?
frontend ejabberd
bind *:4000 ssl crt /etc/haproxy/certs/my-domain.com.pem
mode tcp
timeout client 3h
option tcplog
option clitcpka
default_backend ejabberd
backend ejabberd
mode tcp
timeout server 60m
option redispatch
option srvtcpka
option independent-streams
balance leastconn
default-server inter 5s rise 3 fall 3 on-marked-down shutdown-sessions
server ejabberd localhost:5222 check slowstart 120s
it works fine without ssl crt. My smack client gives me a No response received within reply timeout. Timeout was 5000ms (~5s). While waiting for establishing TLS.
I also tried with or without ttls on ejabberd conf
I was able to have the exact configuration working, you need to:
Disable tls in ejabberd since HAProxy is doing the ssl offloading and ejabberd is hosted in the same machine:
Comment the certfile line
Comment the starttls line
Correctly configure your client, I have used pidgin, but you should be able to do the same with smack:
Configure correctly address and port (4000 here)
Ensure that you use "old style TLS" and not STARTTLS, the latter won't work with HAProxy.
Otherwise, if you want clients to use STARTTLS configuration, then you have to configure HAProxy to proxy XMPP encrypted traffic (removing "ssl crt .." )

Yaws with SSL gives the error "SSL accept failed: timeout"

I used certbot to generate a Let's encrypt certificate for my website, but Yaws gives me an SSL accept failed: timeout error when I try to connect to it (after it times out of course). Interestingly it works when I redirect example.com to the local ip address of the server in the hosts file on my machine and connect to example.com:8080, but not when I connect to example.com without editing the hosts file or when I connect from my phone over 4G. Here's my webserver's configuration file (it is the only configuration file in conf.d):
<server www.example.com>
port = 8080
listen = 0.0.0.0
docroot = /usr/share/yaws
<ssl>
keyfile = /etc/letsencrypt/live/example.com/privkey.pem
certfile = /etc/letsencrypt/live/example.com/fullchain.pem
</ssl>
</server>
I made sure that the keyfile and the certificate are both readable by the yaws user. Next to the keyfiles is a README that contains the following:
`privkey.pem` : the private key for your certificate.
`fullchain.pem`: the certificate file used in most server software.
`chain.pem` : used for OCSP stapling in Nginx >=1.3.7.
`cert.pem` : will break many server configurations, and should not be used
without reading further documentation (see link below).
We recommend not moving these files. For more information, see the Certbot
User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates.
So I'm relatively sure I've used the right file (the other ones gave me errors like badmatch and {tls_alert,"decrypt error"}). I also tried trivial things like writing https:// before the URL, but it didn't fix the issue, also, everything works fine when the server is running without SSL. The version of Erlang running on my server is Erlang/OTP 19. Also, if it's unclear, the domain isn't actually example.com.
Also, example.com is redirected via cname to examplecom.duckdns.org, if that matters.
UPDATE:
My server was listening on port 8080, that was forwarded from the external port 80, for https connections, when the default https port is port 443. My other mistake was connecting to http://example.com instead of https://example.com. Forwarding the external port 443 to the internal port 8443 and configuring yaws to listen on port 8443 fixed everything.
Just to be sure to understand, when you do something like curl -v https://example.com:8080, you get a timeout, that's it ? (here https protocol and port 8080 are mandatory of course)
SSL timeout during accept can be triggered when an unencrypted request is received on a SSL vhost.
Could you also provide the output of the following command:
echo -e "HEAD / HTTP/1.0\r\n\r\n" | openssl s_client -connect mysite.com:8080 -ign_eof
And finally, which version of Yaws are you running ? on which OS ?

How to change a socat tcp4 connection into an SSL connection at a later point (Using XMPP protocol)

I'm looking at creating a very simple XMPP proxy. The XMPP protocol starts with plain text and then converts the socket to SSL if supported and continues on.
Here is an example XMPP session, I've trimmed it down to the basic parts:
Checking features:
(11:49:48) jabber: Sending (chris#localhost): <?xml version='1.0' ?>
(11:49:48) jabber: Sending (chris#localhost): <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
(11:49:48) jabber: Recv (358): <?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='localhost' id='5dea6b36-2da5-485a-8bed-16884e56d6f3' xml:lang='en' xmlns='jabber:client'><stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls><register xmlns='http://jabber.org/features/iq-register'/></stream:features>
Telling the server to start communicating in SSL and exchange keys:
(11:49:48) jabber: Sending (chris#localhost): <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
(11:49:48) jabber: Recv (50): <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
(11:49:48) nss: SSL version 3.3 using 256-bit AES with 256-bit SHA256 MAC
Server Auth: 2048-bit RSA, Key Exchange: 2048-bit RSA, Compression: NULL
Cipher Suite Name: TLS_RSA_WITH_AES_256_CBC_SHA256
(11:49:48) certificate: Successfully verified certificate for localhost
We are now in an SSL session:
(11:49:48) jabber: Sending (ssl) (chris#localhost): <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
(11:49:48) jabber: Recv (ssl)(447): <?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='localhost' id='74a00818-e037-4405-ada1-02bb3dbfe023' xml:lang='en' xmlns='jabber:client'>
When I try to create a socat SSL "server" and connect to it with Pidgin I get unknown protocol:
$ socat openssl-listen:5222,reuseaddr,cert=$HOME/server.pem,cafile=$HOME/client.crt,fork -
2016/01/13 14:00:59 socat[28586] E SSL_accept(): error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol
I tried the same thing with a socat non-SSL "server" and it worked up until it needed to change to SSL (I've added "Client:" and "Server:" to this output for readability. All the "Server:" lines were pasted by me into the terminal):
$ socat tcp4-listen:5222,reuseaddr,fork -
Client: <?xml version='1.0' ?><stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
Server: <?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='localhost' id='5dea6b36-2da5-485a-8bed-16884e56d6f3' xml:lang='en' xmlns='jabber:client'><stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls><register xmlns='http://jabber.org/features/iq-register'/></stream:features>
Client: <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Server: <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Client: tp�C?�f�Q��|_pV��j���=�^(�32g98kf�/<5=
On the last line the client is now trying to talk to us in SSL, so I need a way to tell socat to switch to SSL at that point. Socat obviously doesn't know anything about the XMPP protocol so it doesn't know when to switch. Can socat be told to switch dynamically like that or should I be looking at other ways to do this?
Edit: I did some more research.
Many protocols, HTTPS for example use "always encrypted" connections.
XMPP uses starttls which basically means unencrypted connection until the client and server agree to upgrade the connection to encrypted.
Edit: I just looked at openssl and it has a -starttls for s_client, but not for s_server which indicates to me that it is an architectural issue, it is tricky to know or be told when and how to upgrade the connection to encrypted.
So I guess my real question is, can socat handle protocols that use starttls with or without some manual intervention to tell it when to switch? I don't think openssl can. Is there some other tool that can do this or should I just be writing my own using an SSL library of course?
There are two ways of using SSL/TLS:
XMPP uses STARTTLS where the client and server discuss their security features and then the client requests converting the socket to TLS at an arbitrary point in the communication.
HTTPS and others use two sockets, one for discussing security features and then communication is switched to a second socket setup purely for encrypted communications.
socat:
Does not support STARTTLS.
openssl:
Supports STARTTLS on the client side:
openssl s_client -starttls ...
On the server side as far as I can tell custom code is required for each situation. I found this useful Python script.