Excon SSL Verify issue for ONEBOX

Hi Everyone,

I’ve just setup and started testing a Discourse server and so far it’s great. I have an issue where onebox fails to work due to what I think is a SSL inspection filter that fails to verify with excon gem. I have downloaded the custom root cert and added it to /etc/ssl/certs on host, and even inside the container (to test) to no avail. I still get the below error in the /log/rails/production.log any time I past a url for embedding.

Failed to onebox [youtube url] SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certifciate) (OpenSSL::SSL::SSLError) Unable to verify certificate.

It mentions changing the excon defaults to point to a different ssl_path, but i’m unsure how I can do that safely and still allow discourse to update. Can anyone advise how I might be able to ensure that a custom root cer is seen as valid within excon? Is there a rails -r exec command I can put into the app.yml?

Thanks a bunch,

Glenn.

Which URL is showing the issue? Are you using the official Docker based install of Discourse?

Looks like by default excon bundles its own certificate bundle but since other people had similar issues, he’s added the ability to configure it in the environment? And it’ll use the system one if the certificate is in properly.

It might need the hash link to work. Can you try the following and see if it solves the problem?

  • do both:
    • add your custom cert to /etc/ssl/certs inside the container

    • add the hash link: e.g.

      ln -s my_custom_cert.pem /etc/ssl/certs/$(openssl x509 -hash -noout -in /etc/ssl/certs/my_custom_cert.pem).0
2 Likes

Thanks Michael,

I set the environment variable and created the hash, and I’m not seeing a visible SSL error now, but still onebox is not doing anything. Don’t know if Jeff has any advice on what I might be doing wrong? @codinghorror.

I’m concerned that making changes inside the container will just get destroyed upon a rebuild though, so i’m not sure what the best approach here is.

Glenn.

It may have cached the failure, but let’s test one thing at a time.

You shouldn’t need to add the environment variable, but you can check to see whether adding the certificate worked by doing, for example:

root:~# /var/discourse/launcher enter app
root@app:/var/www/discourse# rails console
[1] pry(main)> Net::HTTP.get URI 'https://meta.discourse.org/about.json'

If you get a result (and you didn’t before), that means the certificate is properly installed. Then you can add commands to the container definition to install that certificate on every rebuild so it’ll persist.

Thanks Michael, the rails console command worked fine, it’s able to download the json file you linked.

I’m not sure if that wouldn’t have worked previously, but I had previously installed the root cer into /etc/ssl/certs/ and it wasn’t working still.

I ran export SSL_CERT_DIR="/etc/ssl/certs/" in the container and the SSL error seemed to go away after that. At least i’m no longer seeing anything in the production.log

Thanks,

Glenn.

Actually, I think I may have worked out the issue now. It’s an authentication prompt with the corporate filter I believe. I did the Net::HTTP.get in the console using a youtube oembed uri to retrieve the embed JSON and instead it provided back an authentication html document. So I think that’s what is getting in the way now. Thanks a bunch Michael.

2 Likes

Did you also create the symlink? That’s a very important part.

To get the certificate permanently in place, you want to amend the app.yml file add or modify a hooks section to something like the following:

hooks:
  before_code:
    - file:
        path: /etc/ssl/certs/custom-root.crt
        chmod: 644
        contents: |
          -----BEGIN CERTIFICATE-----
          …
          -----END CERTIFICATE-----
    - exec:
        cmd:
          - bash -c "ln -s custom-root.crt /etc/ssl/certs/$(openssl x509 -hash -noout -in /etc/ssl/certs/custom-root.crt).0"

Ah, likely nothing we can add into the app.yml file to fix that.

1 Like