Rielaborazione delle email: output del task rake di test

Ho recentemente esaminato le email:task e il codice correlato con l’obiettivo di testare tutti i percorsi di errore e ritoccare il testo degli errori.

Ho anche scoperto che gli effetti dell’impostazione di DISCOURSE_SMTP_ENABLE_STARTTLS=false sono (per lo più) nulli. L’impostazione di questo valore non disabilitava effettivamente STARTTLS e, di fatto, può coesistere senza problemi con TLS al momento della connessione (DISCOURSE_SMTP_FORCE_TLS=true).

Quindi ho:

Prima di unire questo, tuttavia, penso che un avviso per gli amministratori nella dashboard quando viene impostato DISCOURSE_SMTP_ENABLE_STARTTLS=false sia appropriato. Immagino che ci sia almeno un self-hoster che lo ha impostato ma non ne ha bisogno e si affida effettivamente a STARTTLS.

4 Mi Piace

Ottimo lavoro! Una cosa che ho (credo di aver) notato è che il task rake non utilizza lo stesso codice dell’invio effettivo (come dalla pagina di test delle email /admin/). Sono abbastanza sicuro di aver avuto un caso in cui ha funzionato nell’UX ma non nel task rake (o forse era il contrario?)

Mentre è fresco nella tua mente, se potessi assicurarti che quando invia effettivamente lo faccia utilizzando lo stesso codice che usa Discourse, sarebbe fantastico.

2 Mi Piace

Stiamo lavorando anche su questo, e sul miglioramento del logging quando un’email in coda fallisce. :+1:

4 Mi Piace

C’è qualcosa che devo fare sul forum che ospitate?

4 Mi Piace

No, questo avviso non dovrebbe apparire sul nostro hosting. Lo risolveremo, grazie come sempre per la segnalazione.

5 Mi Piace

@supermathie vale la pena inviare un messaggio privato a ogni amministratore su ogni sito che ha questa variabile impostata? Il nostro attuale sistema di controllo dei problemi lo farà, e non sono sicuro che sia giustificato qui, dato che per la maggior parte ha un effetto nil. Idealmente, vorrei mostrarlo solo sulla dashboard senza avvisare gli utenti amministratori, non sono sicuro che la nostra attuale struttura di controllo dei problemi supporti questo caso d’uso.

Penso di sì: trovo estremamente probabile che, dato quanto molti amministratori siano confusi riguardo alla configurazione dell’email, qualcuno abbia questa variabile impostata quando in realtà dipende da starttls.

Probabilmente nessuno dovrebbe averla impostata.

Preferirei un avviso errato piuttosto che interrompere silenziosamente la configurazione dell’email di qualcuno.

L’alternativa è rimuovere il controllo e neutralizzare la variabile in modo che non faccia nulla.

1 Mi Piace

Sarebbe bello se l’avviso non apparisse quando il server SMTP in uscita è localhost (cioè corrisponde al nome del dominio di Discourse) poiché TLS tra il container Docker e l’host non è necessario in quanto sono la stessa macchina.

1 Mi Piace

In questo caso puoi rimuovere la variabile dall’ambiente.

Utilizzerà STARTTLS solo se offerto.

1 Mi Piace

Nella versione attuale, il caso in cui la riga commentata (il valore predefinito è true) insieme a force_tls ha impedito l’invio di email. L’ho quindi decommentata e impostata su false. L’invio di email ora funziona, ma ho questo messaggio nel backend…

Dipende un po’ dalla porta su cui è in esecuzione il vostro provider di posta… non funzionano entrambe e hanno sicuramente un impatto.

Ho notato anche questo. Dopo aver aggiornato Discourse il 28 novembre, ho iniziato a vedere fallimenti nella consegna della posta con il messaggio di errore Job exception: :enable_starttls and :tls are mutually exclusive. Set :tls if you're on an SMTPS connection. Set :enable_starttls if you're on an SMTP connection and using STARTTLS for secure TLS upgrade.

Backtrace
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:159:in `build_smtp_session'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:154:in `start_smtp_session'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:108:in `deliver!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/message.rb:269:in `deliver!'
/usr/local/lib/ruby/3.3.0/delegate.rb:87:in `method_missing'
/var/www/discourse/lib/email/sender.rb:296:in `send'
/var/www/discourse/app/jobs/regular/user_email.rb:80:in `send_user_email'
/var/www/discourse/app/jobs/regular/user_email.rb:40:in `execute'
/var/www/discourse/app/jobs/base.rb:318:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-7.0.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-7.0.0/lib/rails_multisite/connection_management.rb:17:in `with_connection'
/var/www/discourse/app/jobs/base.rb:305:in `block in perform'
/var/www/discourse/app/jobs/base.rb:301:in `each'
/var/www/discourse/app/jobs/base.rb:301:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in `block (4 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/suppress_user_email_errors.rb:6:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/discourse_event.rb:6:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/pausable.rb:131:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in `track'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in `block (3 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in `local'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/config.rb:39:in `block in <class:Config>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in `global'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:10:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:19:in `block in safe_thread'

Proprio come Johann Christoph, in precedenza avevo DISCOURSE_SMTP_ENABLE_START_TLS commentato e DISCOURSE_SMTP_FORCE_TLS impostato su true per TLS implicito e funzionava perfettamente. Ma ora devo impostare esplicitamente DISCOURSE_SMTP_ENABLE_START_TLS su false affinché la consegna della posta funzioni, il che ovviamente attiva il messaggio sopra menzionato nella dashboard di amministrazione.

1 Mi Piace

Sarà force_tls a impedire l’invio di email: impone TLS al momento della connessione ed è probabilmente adatto solo per la porta 465.

Un unicorno!

Quali parametri SMTP stai utilizzando (escluso nome utente/password)?

Porta 465 con ENABLE_START_TLS=false, FORCE_TLS=true e OPEN_TIMEOUT=10. Quest’ultima è dovuta a strani errori di timeout che ho iniziato a vedere dopo un aggiornamento di sistema circa tre anni fa, ma mi taglio un orecchio se è correlata al problema descritto sopra.

Nel frattempo ho dato un’occhiata alla cronologia dei commit e ho notato che la gem mail è stata aggiornata alla versione 2.9.0 solo tre giorni prima dell’aggiornamento che ha introdotto il problema da parte mia (#36254). C’è una nota nelle note di rilascio di quella che dice “SMTP: refactor and accept starttls :always and :auto by @eval in #1536”. Non so molto di Ruby, ma questa modifica nel PR referenziato mi sembra un po’ sospetta:

Dato che DISCOURSE_SMTP_ENABLE_START_TLS è documentato come true per impostazione predefinita (cioè se commentato), è possibile che questa sia la causa del problema?

Come ho scritto, ho impostato force_TLS:

DISCOURSE_SMTP_FORCE_TLS = true

e ENABLE_START_TLS esplicitamente su false… quindi l’invio di posta funziona, a condizione che il server di posta sia in esecuzione sulla porta 465.

Con i server di posta che sono in esecuzione sulla porta 567, deve essere esattamente il contrario.

Da allora ho un avviso sulla dashboard nel backend… ma l’invio di posta funziona senza problemi.

Per poter impostare DISCOURSE_SMTP_ENABLE_START_TLS su false, è necessario decommentarlo, poiché altrimenti è impostato su true per impostazione predefinita. È stato esattamente questo a causarmi il problema. Tuttavia, solo con la build più recente (2025.12.0-latest).

Wow, questo è stato un pessimo cambiamento.

enable_starttls RICHIEDERÀ l’uso di starttls, ma enable_starttls_auto è opportunistico: negozierà tls solo se viene offerto.

E se il server di posta fosse stato connesso tramite TLS iniziale, non offrirà starttls:

○ → openssl s_client -connect localhost:5587 -starttls smtp
250 CHUNKING
EHLO localhost
250-testmailrelay
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 CHUNKING

Perché diavolo l’hanno fatto? :facepalm:
La difficoltà qui è che non avremmo mai dovuto offrire questa configurazione in primo luogo, avrebbe dovuto essere qualcosa come:

DISCOURSE_SMTP_TLS_MODE = starttls_auto # [ none | starttls | starttls_auto (default) | tls ]

Nell’interesse di cercare di far sì che le persone facciano meno configurazione, non di più, penso che questo approccio sia il migliore:

1 Mi Piace

Questo è ora unito, non è più necessario disabilitare esplicitamente STARTTLS, Discourse se ne occuperà se TLS è abilitato.

Sì, funziona di nuovo correttamente. Grazie!