Ruby `gem` command fails SSL verification on self-hosted gemserver - ruby

I've got a Ruby Gemserver running via Geminabox over http on port 9392.
It's behind an HAProxy load balancer which is enforcing https and doing SSL termination. Here's the relevant chunk(s) of my haproxy.cfg:
global
daemon
maxconn 256
user nobody
tune.ssl.default-dh-param 2048
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
option httpclose
frontend http-in
bind *:80
reqadd X-Forwarded-Proto:\ http
redirect scheme https if !{ ssl_fc }
frontend www-https
reqadd X-Forwarded-Proto:\ https
bind *:443 ssl crt /usr/local/etc/haproxy/***********.pem
default_backend home_server
acl is_gems hdr(host) -i gems.example.com
use_backend gems if is_gems
backend gems
server gems1 192.168.100.102:9392 ssl verify none
When I try to add my gemserver from any other machine:
Error fetching https://gems.example.com:
SSL_connect returned=1 errno=0 state=error: certificate verify failed (https://gems.boynton.io/specs.4.8.gz)
What's interesting is this remains true whether the gemserver is running or not, leading me to believe my local ruby gem client is rejecting the cert out of the gate. (Otherwise I'd have stuck this question in ServerFault)
The cert is a Comodo PositiveSSL Wildcard cert, not a self-signed. I've confirmed the CA cert is in my local trust store (I'm on OS X El Cap, so it's been added to my keychain). It seems like maybe the gem command isn't using my system trust store.
I've googled around on this for two or three days to no avail -- everything I can find relates to rubygems.org and suggests gem update --system (I'm running the latest rubygems) or switching to http, both of which are rubygems.org-specific fixes.
How can I get gem to use my local trust store or take an additional cert?

Related

Failed Let's Encrypt standalone authorization procedure

First, thanks to all who may or may not try to help me.
My Problem: I'm trying to create an ssl certificate with Let's Encrypt. Already installed everything mentioned in the documentation. I decided to use certbot / since it seemed to be the easiest way for me to fulfill my needs.
We have freed both ports 80 and 443 and every request that comes to one of these ports are redirected to my Ubuntu 18.04 machine's internal IP address.
There are no configurations on this machine, so nothing listens on port 80 or 443, as you can see on my netstat command:
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 895/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1211/sshd
tcp6 0 0 :::22 :::* LISTEN 1211/sshd
After creating the certificate I'll run a spring boot application, which should use the certificate.
As far as I understood from the documentation, it isn't required to have running applications listening on these ports. It ought be possible to create the certificate by using the standalone parameter. So I guess certbot creates a small application listening to one of these ports on it's own to verify that I'm the one, who I claim to be. Right?
placeholder.example.com is as you will assume a placeholder. I think it's obvious why I'm not publishing my domainname, when having port 80 & 443 opened.
root#urlaub:/# certbot certonly --standalone --preferred-challenges http -d placeholder.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for placeholder.example.com
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. placeholder.example.com (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://placeholder.example.com/.well-known/acme-challenge/jCJ4waxV0aYPxjqDI3OcBXXPReNSrse1kd6piK9Dwdo: Connection refused
IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: placeholder.example.com
Type: connection
Detail: Fetching
http://placeholder.example.com/.well-known/acme-challenge/jCJ4waxV0aYPxjqDI3OcBXXPReNSrse1kd6piK9Dwdo:
Connection refused
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address. Additionally, please check that
your computer has a publicly routable IP address and that no
firewalls are preventing the server from communicating with the
client. If you're using the webroot plugin, you should also verify
that you are serving files from the webroot path you provided.
EDIT: I've had tried this a lot of times, without success. Now there are 13 .pem files in /etc/letsencrypt/keys
Can I convert them to .p12 file to use it in an spring boot application?
It was an issue with the redirection to my server machine. So the above used command works properly and I was able to create a certificate. If anyone wants to use it: go for it.
My intent was to use it in a spring boot application and needed a pkcs12 file. I was able to convert the .pem files created by certbot to a .p12 file by using following command:
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname tomcat
In your application.properties you've to put following:
server.port: PORTNUMBER
server.ssl.key-store:/etc/letsencrypt/live/<YOURDOMAIN>/keystore.p12
server.ssl.key-store-password: <PASSWORD YOU WERE PROMPTED WHEN CREATING THE CERTIFICATE>
server.ssl.keyStoreType: PKCS12
server.ssl.keyAlias: tomcat
With Let's Encrypt if you use HTTP validation, you will need a server serving requests on port 80 (HTTP) for placeholder.mydomain.com so that the Let's Encrypt server can download the file .well-known/acme-challenge/jCJ4waxV0aYPxjqDI3OcBXXPReNSrse1kd6piK9Dwdo. This is how Let's Encrypt validates that you have control over the domain. Note: That filename is generated dynamically and will be different each time you attempt validation.
Another option that I use is to use DNS validation and then create the special record in my DNS server. You can then create the certificates on your desktop for any service that requires SSL for that domain name.

How would yum ( on centos host ) work with proxy that requires an ssl cert

I am trying to setup proxy in /etc/yum.conf with https and ssl cert
Normally, i would have proxy=http://x.x.x.x:80 provided that is the proxy address and since my proxy does not require username and password, that would work. But now i have a requirement, to setup /etc/yum/conf with
proxy=https://x.x.x.x:433
and the yum hosting centos can only talk to internet via a proxy which accepts ssl cert based Authentication.
So how would i install the ssl Cert on the centos host for yum to work with the proxy host on port 443 and one that requires an SSL Cert
It looks like you should be able to use the following config directives taken from the yum.conf manual page.
sslclientcert
Path to the SSL client certificate yum should use to connect to
repos/remote sites Defaults to none. Note that if you are using curl
compiled against NSS (default in Fedora/RHEL), curl treats
sslclientcert values with the same basename as identical. This
version of yum will check that this isn't true and output an error
when the repositories "foo" and "bar" violate this, like so:
sslclientcert basename shared between foo and bar
sslclientkey
Path to the SSL client key yum should use to connect to repos/remote
sites Defaults to none.

Couchdb ssl not listening on port 6984

I've been setting up couchdb to run on SSL following the instructions from couch docs. Its pretty straight forward, you make 3 adjustments to local.ini:
httpsd = {chttpd, start_link, [https]}
cert_file = absolute/path/to/cert.pem
key_file = absolute/path/to/key.pem
I've made the key and certificate with openssl no problem, but whenever I ping port 6984 on the localhost (the port its supposed to run on by default) I just get a non active port:
==> curl https://127.0.0.1:6984/
curl: (7) Failed to connect to 127.0.0.1 port 6984: Connection refused
I've inspected the port, nothing is running there. I can put a node.js server on the port and it works fine too. I can't find a similar situation to this anywhere. I'm running the mac OSX couchdb application (v 2.1.2). It appears that the ssl server daemon is just straight up not running at all. Everything else in couch is working fine. Maybe I have to tweak the local.ini file to turn the daemon on? No idea really. Any suggestions are appreciated.
Not sure if this will ever be a very popular question but just thought I'd point out that a very popular way to set up SSL with couchdb is to use a proxy like haproxy due to annoyances with ssl and erlang (which couchdb is written in).
That being said, I solved my problem by setting up SSL termination at haproxy that then forwards traffic to couchdb on an internal port. For use on a mac OSX machine the steps were pretty easy.
1) Install haproxy with brew brew install haproxy
2) Create a self signed certificate with openssl that haproxy needs for ssl configuration (it's really just a concatenated file of your key and certificate):
openssl genrsa -out key.key 1024
openssl req -new -key key.key -out cert.csr
openssl x509 -req -days 365 -in cert.csr -signkey key.key -out certificate.crt
cat ./certificate.crt ./key.key | tee combined.pem
3) create haproxy configuration file (haproxy.cfg), this is just a pretty naive first implementation, but is a good starting point. Note that "/absolute/path/to/combined.pem" would be changed to wherever the combined.pem file is actually located.
global
maxconn 512
spread-checks 5
defaults
mode http
log global
monitor-uri /_haproxy_health_check
option log-health-checks
option httplog
balance roundrobin
option forwardfor
option redispatch
retries 4
option http-server-close
timeout client 150000
timeout server 3600000
timeout connect 500
stats enable
stats uri /_haproxy_stats
# stats auth admin:admin # Uncomment for basic auth
frontend http-in
# bind *:$HAPROXY_PORT
bind *:443 ssl crt /absolute/path/to/combined.pem no-tls-tickets ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA384:AES128-SHA256:AES128-SHA:AES256-SHA256:AES256-SHA:!MD5:!aNULL:!DH:!RC4
#Add these lines beneath bind, still within http-in
reqadd X-Forwarded-Proto:\ https
# Distinguish between secure and insecure requests
acl secure dst_port eq 8000
# Mark all cookies as secure if sent over SSL
rsprep ^Set-Cookie:\ (.*) Set-Cookie:\ \1;\ Secure if secure
# Add the HSTS header with a 1 year max-age
rspadd Strict-Transport-Security:\ max-age=31536000 if secure
# Redirect HTTP to HTTPS
redirect scheme https code 301 if !{ ssl_fc }
default_backend couchdbs
backend couchdbs
option httpchk GET /_up
http-check disable-on-404
server couchdb1 127.0.0.1:5984 check inter 5s
4) Run couchdb, run haproxy via changing directory to the directory housing the above haproxy.cfg file and running with that configuration: haproxy -f haproxy.cfg.
This is a simple point to start from. This set up can handle load balancing of multiple couchdbs, and in production would need a valid certificate from some authority. For anyone interested in, or having difficulty with ssl and couchdb in a mac OSX development environment, this is a decent solution that I found to work quite nicely.

cURL - Unkown SSL protocol error - OS X 10.9

I am trying to use cURL and get the following error on every https request I make. The error is always the same. HTTP requests work flawlessly. The verbose output is quite useless.
bash:$ curl https://google.com -vv
* Adding handle: conn: 0x7fe09b803a00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fe09b803a00) send_pipe: 1, recv_pipe: 0
* About to connect() to google.com port 443 (#0)
* Trying 74.125.226.129...
* Connected to google.com (74.125.226.129) port 443 (#0)
* Unknown SSL protocol error in connection to google.com:-9805
* Closing connection 0
curl: (35) Unknown SSL protocol error in connection to google.com:-9805
bash:$ curl https://google.com -V
curl 7.30.0 (x86_64-apple-darwin13.0) libcurl/7.30.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM NTLM_WB SSL libz
bash:$ openssl s_client -connect google.com:443 < /dev/null
CONNECTED(00000003)
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
24255:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_lib.c:182:
The results are the same on two different networks, so it does not appear to be network-specific. Attempting to connect using openssl s_client fails similarly so it is not library-dependent either (curl on the Mac uses SecureTransport). The debug output of s_client shows that the SSL handshake proceeds normally to the point where the client sends ChangeCipherSpec and the Finished messages but does not receive ChangeCipherSpec back from the server.
I have tried running these commands on a Debian VM on my Mac, and everything there runs correctly. In addition, using curl to connect to a local OpenSSL server (openssl s_server with a self-signed certificate) also works correctly.
I have looked through other answers on this forum and other places on the internet, but haven't found an answer. Most people's issues involve particular servers and the configuration of SSL on these servers. Mine however is problematic anytime HTTPS is used (with any website).
It was suggested that the issue might be in the certificate store. But if I understand it correctly, if the issue was with the certificate store, it would cause certificates to be rejected by all apps. However, all my browsers (chrome, safari, firefox) negotiate SSL with no problems. There is nothing suspicious in the environment variables for GUI applications or the shell.
Can someone please suggest what I should be looking into to solve the problem? Can it be that something is not properly configured? What should I be looking for?

How do I get Leopard to work with ssl from the command line

Everything I try and connect to via https fails. Bellow is a curl output, but it does this with git mongo and everything. darwin just doesn't like https.
About to connect() to github.com port 443 (#0)
Trying 207.97.227.239... connected
Connected to github.com (207.97.227.239) port 443 (#0)
successfully set certificate verify locations:
CAfile: /usr/share/curl/curl-ca-bundle.crt
CApath: none
SSLv2, Client hello (1):
SSLv3, TLS handshake, Server hello (2):
SSLv3, TLS handshake, CERT (11):
SSLv3, TLS alert, Server hello (2):
SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Closing connection #0
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
You might say not a problem just change https to http, yes this is fine when you only have
1 url like git clone but on rvm install about 50 of the required things fails to install because of this. I don't want to go into rvm and change all occurrences of https to http.
Take a look at this post, slightly different, but i think it will answer you questions:
SSL certificate rejected trying to access GitHub over HTTPS behind firewall
You can essentially have OSX ignore the SSL Cert Verify, and accept the connection.
It turned out that my version of curl was using an old certificate to validate https.
I cam across this issue on git for cURL under Leopard:
https://github.com/mxcl/homebrew/issues/11947
And the error went away and I am now able to download https files from cURL.
This looks like an issue with curl itself, rather than OSX. What version are you using? If it's particularly old, then the reference here to a "severely outdated CA file" probably applies.
Try installing up-to-date versions of curl and git from macports.

Resources