Reply by email SSL self signed certificate error

I’m trying to set up the reply by email feature, but am getting these errors in the logs:

Job exception: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

/usr/local/lib/ruby/2.0.0/net/pop.rb:552:in `connect'
/usr/local/lib/ruby/2.0.0/net/pop.rb:552:in `do_start'
/usr/local/lib/ruby/2.0.0/net/pop.rb:530:in `start'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:88:in `poll_pop3'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:18:in `execute'
/var/www/discourse/app/jobs/base.rb:153:in `block (2 levels) in perform'
current_db: default
current_hostname: metaruby.com
job: Jobs::PollMailbox
problem_db: default
hostname: my.host.com-app
process_id: 76

opts:

I have a self signed cert, but SMTP on the same server/domain is working fine - any ideas why this might be happening?

This should be the troublemaker. By default, Discourse uses a secure connection, and since the certificate is not trusted, this won’t work.

I don’t think you can easily trust your certificate. You might be able to make it work by using an unencrypted connection (look for the pop3 polling ssl setting), but I wouldn’t do that unless the connection is to localhost.

The best solution might be to get a (possibly free) signed certificate.

2 Likes

Thanks for the reply @fefrei

The mail server is on the same domain but does not point to localhost in the Discourse admin settings (just mail.mysite.com) so I guess it wouldn’t be safe to turn off SSL when connecting to the POP server? Or would it be fine?

Is there a way to set it up different given both postfix and Discourse are on the same server?

Being on the same domain isn’t relevant – running on the same server is.

I’m not sure how you can set this up correctly – entering localhost should refer to the container, not the host. Also, you want to be safe that no DNS hiccup can cause your password to be sent out unencrypted.

Is getting a signed certificate not doable in your case?

1 Like

They’re on the same server.

I don’t think I have ever used a signed cert - do you have to get one for every Discourse instance?

You mentioned free - are they any good?

Do you know if Discourse will at any point support self-signed certs? Apple mail just asks me if I trust it or not on first connection - maybe it is something we can add to the config?

Do you use HTTPS for Discourse? If so, which certificate do you use for that?

1 Like

Use a file: directive in your app.yml to drop your certificate into the container CA root store.

3 Likes

Do you mean something like this Kane?

file:
  /home/mysite/ssl.cert

It’s still not working (I rebuilt the app after making the change to app.yml)

(@fefrei - no I’m not yet running in https)

Then you have two option: Either trust the certificate (I don’t know the exact syntax), or get a signed certificate which you can use for both HTTPS and POP3.

That’s what I’m opting for - hopefully @riking will be able to see what I’ve done wrong above…

No, that’s quite wrong…

More like this:

https://github.com/discourse/discourse_docker/blob/master/templates/cloudflare.template.yml#L2

2 Likes

Could you expand on that a little please @riking? (Or are there any docs you can point me to?)

Total guess here, but something like the following?

run:
- file:
    path: /tmp/cert-to-copy
    contents: |
      # Download cert, move and update
      wget https://my-cert-file
      mv my-cert-file /usr/local/share/ca-certificates/
      update-ca-certificates

More like:

run:
  - file:
    path: /usr/local/share/ca-certificates/aston-email.crt
    contents: |
      -----BEGIN CERTIFICATE-----
      MIIGajCCBVKgAwIBAgIQCn1PE//Ffo4Be8tPBlsAZDANBgkqhkiG9w0BAQsFADBw
      MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
      d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
      dXJhbmNlIFNlcnZlciBDQTAeFw0xMzEwMjIxMjAwMDFaFw0xNjA3MDYxMjAwMDBa
      MGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsx
      HTAbBgNVBAoTFFN0YWNrIEV4Y2hhbmdlLCBJbmMuMRwwGgYDVQQDDBMqLnN0YWNr
      ......
      -----END CERTIFICATE-----

1 Like

Sorry to keep bothering you @riking but I’m still have problems with this.

When rebuilding the app by using the code in your example my server grinds to a halt requiring a datacenter reset.

If I add a chmod: "744" line below the path: line it fails to bootstrap:

cd /pups && git pull && /pups/bin/pups --stdin
Already up-to-date.
I, [2015-07-10T14:08:31.984347 #36]  INFO -- : Loading --stdin
/pups/lib/pups/cli.rb:15:in `split': invalid byte sequence in US-ASCII (ArgumentError)
	from /pups/lib/pups/cli.rb:15:in `run'
	from /pups/bin/pups:8:in `<main>'
890fb766f58a4d913796458e6799254a3211b0701de7030e750a8235c06cd29d
FAILED TO BOOTSTRAP

I’ve also tried chmod with “-rwxrwxrwx” (same thing, fails to bootstrap).

Any idea what I am doing wrong?

Ok so now I’m on the new server I am going to try to get this set up again :smile:

The snippet above doesn’t work Kane, the app fails to bootstrap with /pups/lib/pups/config.rb:93:in block (2 levels) in run_commands’: Invalid run command path (SyntaxError)`

So I’ve tried with:

run:
 - file:
     path: /tmp/add-cert
     chmod: +x
     contents: |
       #!/bin/bash -e
       #Download cert
       wget http://mysite.com/cert/cert.txt -O - > /usr/local/share/ca-certificates/aston-email.cert
       update-ca-certificates

 - exec: "/tmp/add-cert"

But on checking logs I see:

Job exception: SSL_connect returned=1 errno=0 state=unknown state: unknown protocol

/usr/local/lib/ruby/2.0.0/net/pop.rb:552:in `connect'
/usr/local/lib/ruby/2.0.0/net/pop.rb:552:in `do_start'
/usr/local/lib/ruby/2.0.0/net/pop.rb:530:in `start'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:91:in `poll_pop3'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:18:in `execute'
/var/www/discourse/app/jobs/base.rb:153:in `block (2 levels) in perform'

There was also this from last night, but I only activated reply by email earlier today:

`Job exception: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed``

Any ideas on what I could try next or what might be going wrong?

Coming back to this question: Is there a reason a free SSL certificate from someone like StartSSL wouldn’t work?

Personally I would prefer to use my own self-signed cert.

Self-signed is going to be a world of hurt. Not sure if we can even help you if you willingly opt in to the extreme pain scenario.

I seem to be making some progress… the only error I’m getting now is:

Job exception: SSL_connect returned=1 errno=0 state=unknown state: unknown protocol

With backtrace:

/usr/local/lib/ruby/2.0.0/net/pop.rb:552:in `connect'
/usr/local/lib/ruby/2.0.0/net/pop.rb:552:in `do_start'
/usr/local/lib/ruby/2.0.0/net/pop.rb:530:in `start'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:91:in `poll_pop3'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:18:in `execute'
/var/www/discourse/app/jobs/base.rb:153:in `block (2 levels) in perform'

That seems to point to this: ruby on rails - OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=unknown state: unknown protocol - Stack Overflow with the three options being:

So the indicated approaches seem to be:

  1. Upgrade the server to handle more Client Hello variants, or
  2. Install a ruby that uses an older OpenSSL library, or
  3. Change your program to send a different Client Hello.

I think in the interest of keeping barriers low for Discourse, 1 and 2 would not be ideal options. Do you have any ideas which CH Discourse uses? And whether it would be feasible to add another (that is perhaps more widely compatible or helps make things more widely compatible)?

Edit: I guess I’d still be having this problem even if I got a free SSL cert as this is a protocol miss-match. Should I start a dedicated topic for it?

Ok I think I’ve found the solution @downey @riking @codinghorror :slight_smile:

Just need to add a site setting pop3 polling ssl verify none

Then update this code:

from:

    def poll_pop3
      connection = Net::POP3.new(SiteSetting.pop3_polling_host, SiteSetting.pop3_polling_port)
      connection.enable_ssl if SiteSetting.pop3_polling_ssl

      connection.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
        unless pop.mails.empty?
          pop.each do |mail|
            handle_mail(mail)
          end
        end
        pop.finish
      end
    rescue Net::POPAuthenticationError => e
      Discourse.handle_job_exception(e, error_context(@args, "Signing in to poll incoming email"))
    end

to:

    def poll_pop3
      connection = Net::POP3.new(SiteSetting.pop3_polling_host, SiteSetting.pop3_polling_port)
      if SiteSetting.pop3_polling_ssl
        if SiteSetting.pop3_polling_ssl_verify_none
          connection.enable_ssl(OpenSSL::SSL::VERIFY_NONE)
        else
          connection.enable_ssl
        end 
      end
        
      connection.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
        unless pop.mails.empty?
          pop.each do |mail|
            handle_mail(mail)
          end
        end
        pop.finish
      end
    rescue Net::POPAuthenticationError => e
      Discourse.handle_job_exception(e, error_context(@args, "Signing in to poll incoming email"))
    end

If this is ok, and if someone can point me in the right direction of how to add the site setting I can send a PR (but quite happy for one of you guys to do it instead as that’d be quicker.)

1 Like