Stalwart-mail+Discourse: EOF de POP3 alcanzado (de nuevo)

Continuando la discusión de Problema de SSL en la consulta POP3:

Hola,

Estoy probando el nuevo soporte POP3 de Stalwart-mail con Discourse…

Los registros DNS están completos
Registros DNS
Tipo	Nombre	Contenido
MX	hack2o.eu.	10 mx.z7l.eu.
CNAME	mail.hack2o.eu.	mx.z7l.eu.
TXT	202406e._domainkey.hack2o.eu.	v=DKIM1; k=ed25519; h=sha256; p=J7kVdkoSKjwJcdPOcqCvvR7YtJV3LtOKEQ09c00+/fY=
TXT	202406r._domainkey.hack2o.eu.	v=DKIM1; k=rsa; h=sha256; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuvXE8Nf0Q9C+/coc9RgACmoTwQ9OZMkJIuWxtT0fYr6UY3CYnjzOLp+VEKoqQA2OHfNM7Q3rQSw0ghjKcMW2OqzQKQAQTGrm3hvSjsJgQvUcgjHbZngpzfqBsCun6iONGuO33UJmzH4hpnm0ljLGiOw4wv6MA918wL71oZS7HWjYU9g31uasCVBpt0Ch1U6Vfs4/ejVSXbmvNb+BDQUU48E8SnpnZS6yLoMC7gByflVvoOlLvj8tV4HYdO74FXej4gUEUUacQUQPyWKDzHhhcuhG/nmoWOrbJyiTpoq4cflKTblg6wriBZ6XPXud2Og1U0SB1yPyEtV7q3b4ZLJ1AwIDAQAB
TXT	hack2o.eu.	v=spf1 mx ra=postmaster -all
SRV	_imaps._tcp.hack2o.eu.	0 1 143 mx.z7l.eu.
SRV	_imaps._tcp.hack2o.eu.	0 1 993 mx.z7l.eu.
SRV	_pop3s._tcp.hack2o.eu.	0 1 995 mx.z7l.eu.
SRV	_submissions._tcp.hack2o.eu.	0 1 465 mx.z7l.eu.
SRV	_submissions._tcp.hack2o.eu.	0 1 587 mx.z7l.eu.
CNAME	autoconfig.hack2o.eu.	mx.z7l.eu.
CNAME	autodiscover.hack2o.eu.	mx.z7l.eu.
CNAME	mta-sts.hack2o.eu.	mx.z7l.eu.
TXT	_mta-sts.hack2o.eu.	v=STSv1; id=16222476092926415687
TXT	_dmarc.hack2o.eu.	v=DMARC1; p=reject; rua=mailto:postmaster@hack2o.eu; ruf=mailto:postmaster@hack2o.eu
TXT	_smtp._tls.hack2o.eu.	v=TLSRPTv1; rua=mailto:postmaster@hack2o.eu
TLSA	_25._tcp.mail.hack2o.eu.	3 0 1 22eaf4d577f42a1ceeda1b8da12ab2c0eb20351b7e3f7035c2cac7dd700a3ab6
TLSA	_25._tcp.mail.hack2o.eu.	3 0 2 16c04cca276b0d880b843f35b8f8513b7b4157907cb19c5d5f36464ea5e04972e863f24a6cb18bcd39fe5cc0cff793d6a5225d8937654ab28b2c7096a12cd858
TLSA	_25._tcp.mail.hack2o.eu.	3 1 1 0a47742e724fe771934bbf9a5d9c721cf34b97135242042b9e0a2c030c634455
TLSA	_25._tcp.mail.hack2o.eu.	3 1 2 ab60f26c194e0467bade96dd1a0bffd5d465065b2740e577f28f889a019ec2b455af8b8a1b1bcd66b998bba91469c5c5430c0a9f52f27316b33f93997d48f3e7
TLSA	_25._tcp.mail.hack2o.eu.	2 0 1 76e9e288aafc0e37f4390cbf946aad997d5c1c901b3ce513d3d8fadbabe2ab85
TLSA	_25._tcp.mail.hack2o.eu.	2 0 2 afab698cbbbf892ebb555e09175056c1d4630fe7c350f44dcc6e71843d3b290df00d30ab4e356b630c69169d7633788338922fb637cf5b9f7be20a413eeaa518
TLSA	_25._tcp.mail.hack2o.eu.	2 1 1 d016e1fe311948aca64f2de44ce86c9a51ca041df6103bb52a88eb3f761f57d7
TLSA	_25._tcp.mail.hack2o.eu.	2 1 2 f8a2b4e23e82a4494e9998fcc4242bef1277656a118beede55ddfadcb82e20c5dc036dcb3b6c48d2ce04e362a9f477c82ad5a557b06b6f33b45ca6662b37c1c9

La cuenta POP3 funciona correctamente con Thunderbird, y su configuración se descubre automáticamente de manera adecuada.

Sin embargo, Discourse falla al activarla, a pesar de la solución temporal para TLS 1.3

Mensaje de error
Mensaje

EOFError (fin de archivo alcanzado)
app/services/email_settings_validator.rb:55:in `validate_pop3'
lib/validators/pop3_polling_enabled_setting_validator.rb:35:in `authentication_works?'
lib/validators/pop3_polling_enabled_setting_validator.rb:15:in `valid_value?'
lib/site_settings/type_supervisor.rb:284:in `validate_value'
lib/site_settings/type_supervisor.rb:165:in `to_db_value'
lib/site_setting_extension.rb:368:in `add_override!'
lib/site_setting_extension.rb:609:in `block in setup_methods'
lib/site_setting_extension.rb:435:in `public_send'
lib/site_setting_extension.rb:435:in `set'
lib/site_setting_extension.rb:448:in `set_and_log'
app/controllers/admin/site_settings_controller.rb:56:in `update'
app/controllers/application_controller.rb:422:in `block in with_resolved_locale'
app/controllers/application_controller.rb:422:in `with_resolved_locale'
lib/middleware/omniauth_bypass_middleware.rb:64:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:393:in `call'
lib/middleware/csp_script_nonce_injector.rb:12:in `call'
config/initializers/008-rack-cors.rb:14:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
lib/middleware/request_tracker.rb:289:in `call'

Rastreo

/usr/local/lib/ruby/3.3.0/net/protocol.rb:237:in `rbuf_fill'
/usr/local/lib/ruby/3.3.0/net/protocol.rb:199:in `readuntil'
/usr/local/lib/ruby/3.3.0/net/protocol.rb:209:in `readline'
net-pop (0.1.2) lib/net/pop.rb:1000:in `recv_response'
net-pop (0.1.2) lib/net/pop.rb:996:in `get_response'
net-pop (0.1.2) lib/net/pop.rb:984:in `block in quit'
net-pop (0.1.2) lib/net/pop.rb:1016:in `critical'
net-pop (0.1.2) lib/net/pop.rb:984:in `quit'
net-pop (0.1.2) lib/net/pop.rb:603:in `do_finish'
net-pop (0.1.2) lib/net/pop.rb:533:in `start'
net-pop (0.1.2) lib/net/pop.rb:316:in `auth_only'
app/services/email_settings_validator.rb:55:in `validate_pop3'
lib/validators/pop3_polling_enabled_setting_validator.rb:35:in `authentication_works?'
lib/validators/pop3_polling_enabled_setting_validator.rb:15:in `valid_value?'
lib/site_settings/type_supervisor.rb:284:in `validate_value'
lib/site_settings/type_supervisor.rb:165:in `to_db_value'
lib/site_setting_extension.rb:368:in `add_override!'
lib/site_setting_extension.rb:609:in `block in setup_methods'
lib/site_setting_extension.rb:435:in `public_send'
lib/site_setting_extension.rb:435:in `set'
lib/site_setting_extension.rb:448:in `set_and_log'
app/controllers/admin/site_settings_controller.rb:56:in `update'
actionpack (7.0.8.4) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (7.0.8.4) lib/abstract_controller/base.rb:215:in `process_action'
actionpack (7.0.8.4) lib/action_controller/metal/rendering.rb:165:in `process_action'
actionpack (7.0.8.4) lib/abstract_controller/callbacks.rb:234:in `block in process_action'
activesupport (7.0.8.4) lib/active_support/callbacks.rb:118:in `block in run_callbacks'
app/controllers/application_controller.rb:422:in `block in with_resolved_locale'
i18n (1.14.5) lib/i18n.rb:351:in `with_locale'
app/controllers/application_controller.rb:422:in `with_resolved_locale'
activesupport (7.0.8.4) lib/active_support/callbacks.rb:127:in `block in run_callbacks'
activesupport (7.0.8.4) lib/active_support/callbacks.rb:138:in `run_callbacks'
actionpack (7.0.8.4) lib/abstract_controller/callbacks.rb:233:in `process_action'
actionpack (7.0.8.4) lib/action_controller/metal/rescue.rb:23:in `process_action'
actionpack (7.0.8.4) lib/action_controller/metal/instrumentation.rb:67:in `block in process_action'
activesupport (7.0.8.4) lib/active_support/notifications.rb:206:in `block in instrument'
activesupport (7.0.8.4) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (7.0.8.4) lib/active_support/notifications.rb:206:in `instrument'
actionpack (7.0.8.4) lib/action_controller/metal/instrumentation.rb:66:in `process_action'
actionpack (7.0.8.4) lib/action_controller/metal/params_wrapper.rb:259:in `process_action'
activerecord (7.0.8.4) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (7.0.8.4) lib/abstract_controller/base.rb:151:in `process'
actionview (7.0.8.4) lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler (3.3.1) lib/mini_profiler/profiling_methods.rb:115:in `block in profile_method'
actionpack (7.0.8.4) lib/action_controller/metal.rb:188:in `dispatch'
actionpack (7.0.8.4) lib/action_controller/metal.rb:251:in `dispatch'
actionpack (7.0.8.4) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (7.0.8.4) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (7.0.8.4) lib/action_dispatch/routing/mapper.rb:18:in `block in <class:Constraints>'
actionpack (7.0.8.4) lib/action_dispatch/routing/mapper.rb:48:in `serve'
actionpack (7.0.8.4) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (7.0.8.4) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (7.0.8.4) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (7.0.8.4) lib/action_dispatch/routing/route_set.rb:852:in `call'
lib/middleware/omniauth_bypass_middleware.rb:64:in `call'
rack (2.2.9) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.9) lib/rack/conditional_get.rb:40:in `call'
rack (2.2.9) lib/rack/head.rb:12:in `call'
actionpack (7.0.8.4) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:393:in `call'
lib/middleware/csp_script_nonce_injector.rb:12:in `call'
config/initializers/008-rack-cors.rb:14:in `call'
rack (2.2.9) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.9) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/cookies.rb:704:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.8.4) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.8.4) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/show_exceptions.rb:29:in `call'
logster (2.19.1) lib/logster/middleware/reporter.rb:40:in `call'
railties (7.0.8.4) lib/rails/rack/logger.rb:40:in `call_app'
railties (7.0.8.4) lib/rails/rack/logger.rb:27:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/request_id.rb:26:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
rack (2.2.9) lib/rack/method_override.rb:24:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/executor.rb:14:in `call'
rack (2.2.9) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.8.4) lib/action_dispatch/middleware/host_authorization.rb:131:in `call'
rack-mini-profiler (3.3.1) lib/mini_profiler.rb:334:in `call'
message_bus (4.3.8) lib/message_bus/rack/middleware.rb:60:in `call'
lib/middleware/request_tracker.rb:289:in `call'
railties (7.0.8.4) lib/rails/engine.rb:530:in `call'
railties (7.0.8.4) lib/rails/railtie.rb:226:in `public_send'
railties (7.0.8.4) lib/rails/railtie.rb:226:in `method_missing'
rack (2.2.9) lib/rack/urlmap.rb:74:in `block in call'
rack (2.2.9) lib/rack/urlmap.rb:58:in `each'
rack (2.2.9) lib/rack/urlmap.rb:58:in `call'
unicorn (6.1.0) lib/unicorn/http_server.rb:634:in `process_client'
unicorn (6.1.0) lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn (6.1.0) lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn (6.1.0) lib/unicorn/http_server.rb:143:in `start'
unicorn (6.1.0) bin/unicorn:128:in `<top (required)>'
vendor/bundle/ruby/3.3.0/bin/unicorn:25:in `load'
vendor/bundle/ruby/3.3.0/bin/unicorn:25:in `<main>'

Entorno

HOSTS HTTP: forum.hack2o.eu

El error se puede reproducir con Net::POP3 puro en Ruby, pero la autenticación no falla. Es solo un error sin sentido de OpenSSL. La conexión con openssl s_client funciona correctamente tanto para TLS 1.2 como para TLS 1.3. No estoy seguro de qué hacer aquí, ya que todo parece funcionar fuera de la advertencia de OpenSSL en el momento de la desconexión.


Aquí hay una prueba mínima en Ruby:

Prueba de Net::POP3
require 'net/pop'

puts "Probando conexión POP3 para #{ENV['POP3_USER']} en #{ENV['POP3_HOST']}"

Net::POP3.enable_ssl

pop = Net::POP3.new(ENV['POP3_HOST'], 995)

print " usando SSL: ", pop.use_ssl?? "sí":"no", "\n"

begin
  pop.auth_only(ENV['POP3_USER'], ENV['POP3_PASS'])
  puts "¡Autenticación exitosa!"
rescue Net::POPAuthenticationError => err
  puts "Autenticación fallida."
#  p ENV['POP3_USER']
#  p ENV['POP3_PASS']
#  p pop
  exit
end

Nota que también probé establecer ssl_params para enable_ssl con:

  • min_version: OpenSSL::SSL::TLS1_3_VERSION
  • max_version: OpenSSL::SSL::TLS1_2_VERSION

con los mismos resultados.

Aquí hay una sesión de OpenSSL (idéntica tanto para TLS 1.2 como 1.3):

openssl s_client -quiet -tls1_3 mail.example:995
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = E5
verify return:1
depth=0 CN = mail.example
verify return:1
+OK Stalwart POP3 at your service.
USER user@mail.example
+OK user@mail.example is a valid mailbox
PASS redacted
+OK Authentication successful
QUIT
40771049E17F0000:error:0A000126:SSL routines:ssl3_read_n:unexpected eof while reading:../ssl/record/rec_layer_s3.c:303:
openssl s_client -quiet -tls1_2 mail.example:995
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = E5
verify return:1
depth=0 CN = mail.example
verify return:1
+OK Stalwart POP3 at your service.
USER user@mail.example
+OK user@mail.example is a valid mailbox
PASS redacted
+OK Authentication successful
QUIT
40771049E17F0000:error:0A000126:SSL routines:ssl3_read_n:unexpected eof while reading:../ssl/record/rec_layer_s3.c:303:

Me pregunto qué hace que otras implementaciones no propaguen el error de OpenSSL.

Creo que esto es un error de Stalwart-mail y los informaré en este tema para su revisión.

No pude encontrar dónde informaste esto a Stalwart, así que lo reporté aquí: [bug]: discourse pop3 polling doesn't work · Issue #567 · stalwartlabs/stalwart · GitHub

Gracias @programmerjake, tu arreglo POP3 QUIT must write a response by programmerjake · Pull Request #568 · stalwartlabs/stalwart · GitHub solucionó el problema de sondeo.

(Había informado del problema en el canal de Matrix ya que no sabía cómo depurarlo y caracterizar el problema real).