Python аркылуу SMTP жөнөтүү: 587-порттогу STARTTLS же 465-порттогу TLS?
587-порттогу STARTTLS жана 465-порттогу жашыруун TLS экөө тең Python жөнөтүүсүн ташыйт, бирок сиздин релеңизге бирөө гана туура келет. Кол алышууну жана ката режимдерин салыштырыңыз.
Эки туташуу режими тең бирдей билдирүүнү бирдей реле эсебине жеткирет, ал эми айырма TLS кайсы жерден башталарында, эмне жөнөтүлөрүндө эмес. Бири ачык текст менен ачылып, каналдын ичинде жаңыртылат; экинчиси биринчи байттан эле шифрленген. Ушул бир айырма катуу реле саясаты эмнени кабыл аларын, ортолук түзмөк эмнени байкай аларын жана кайсы ката билдирүүсүн түштөн кечке чейин окуй турганыңызды аныктайт. Жеке тармактагы колдонмо билдирүүнү ички жөнөтүү кызматына тапшырганда мен бул экөөнүн ортосунда кантип тандаарымды келтирем.
Эки режим чындыгында кайсы жерден ажырайт
Эки учурда тең милдет бирдей: бекитилген эсеп катары аутентификациялоо, уруксат берилген жөнөтүүчүнү атоо, алуучуларды тизмелөө жана реленин жоопкерчиликти өзүнө алышын күтүү. Өзгөргөн нерсе — операциялардын тартиби. 587-порт ачык тексттик SMTP сессиясы катары башталат, EHLO жообунда STARTTLS жарыялайт жана кардар сураса гана жаңыртылат. 465-порт кандайдыр бир SMTP буйругу айтылганга чейин TLS кол алышуусун күтөт.
Жөнөтүү менен реле — ар башка иштер, ошондуктан порт номерлери алмаштырыла турган адаттар эмес. RFC 6409 билдирүү жөнөтүүнү өзүнчө кызмат катары сүрөттөйт, ал эми RFC 8314 азыркы релелердин көбү 465-портто сунуш кылган жашыруун TLS вариантын камтыйт. Эгер сиздин реле экөөнүн бирин документтештирсе, ал документ мурунку жумуш берүүчүдөн алган ар кандай тандоодон жогору турат.
587-порттогу STARTTLS сизге эмне берет
Жаңыртуу SMTP сүйлөшүүсүнүн ичинде болот, ошондуктан реле аны жарыялай алат, ал эми кардар ансыз улантуудан баш тарта алат. Python'до starttls() сервер бул кеңейтүүнү сунуш кылбаганда өзгөчө жагдай ыргытат, бул төмөндөтүү аракетин тынч ачык тексттик кирүүнүн ордуна көрүнүктүү ийгиликсиздикке айландырат. Ушул жүрүм-турум режимдин негизги далили, жана ага кокустан эмес, атайын таянууга татыктуу.
Таасир этүү терезеси кичине, бирок чыныгы: баштапкы EHLO алмашуусу окулат, ал эми жаңыртууга чейин эч нерсе эсептик маалыматтарды ташыбайт. Колдонмонун ички тармагы менен ички реленин ортосундагы жеке жолдо бул терезе адатта кабыл алынат. Өзүңүз көзөмөлдөбөгөн жолдо дал ушул себеп айрым топтордун башка режимди талап кылышына алып келет.
STARTTLS мүмкүнчүлүгүн алып салган кармоочу түзмөк ийгиликсиз жөнөтүүнү жаратат, артка чегинүүнү эмес. Бул — каалаган натыйжа, жана жолдо бир нерсе SMTP'ни кайра жазып жатканын аныктоонун эң тез жолу.
465-порттогу жашыруун TLS эмнени өзгөртөт
Ачык текст баскычы такыр жок. Кардар сокет ачылаары менен TLS кол алышуусун аткарат, сертификатты өз ишеним кампасына каршы текшерет, ошондон кийин гана EHLO, AUTH жана билдирүүнү алмашат. Сессияны эч нерсе төмөндөтө албайт, анткени сүйлөшүү жүргүзө турган ачык текст абалы жок, жана бул кармоо ийгиликсиздиктеринин бүтүндөй классын жоёт.
Алмашуу — диагностикалык мүмкүнчүлүк. 465-портто ачык тексттик SMTP менен жооп берген реле же TLS'ти туура эмес сертификат аты менен аяктаган жүктөм теңдештиргич кол алышууда ийгиликсиз болот жана почта катасынын ордуна сизге SSL катасын берет. Бул болгондо, маселе колдонмонун астында, жана билдирүү куруунун эч канча өлчөмү аны оңдобойт.
Бир жөнөтүү функциясы, эки транспорт
Код режимдердин ортосунда араң айырмаланат, ошондуктан тандоо китепкананын ыңгайлуулугунан эмес, реле саясатынан жасалышы керек. Адегенде жөндөөлөрдү экспорттоп, андан кийин конфигурацияланган порттон транспортту тандаган бир скриптти иштетиңиз.
export SMTP_HOST=smtp.relay.internal export SMTP_PORT=587 export SMTP_USER=svc-notify export [email protected] export [email protected] export SMTP_PASSWORD="$(cat /run/secrets/smtp_password)"
import os, smtplib, ssl
from email.message import EmailMessage
ctx = ssl.create_default_context()
msg = EmailMessage()
msg["From"] = os.environ["MAIL_FROM"]
msg["To"] = os.environ["MAIL_TEST_TO"]
msg["Subject"] = "relay submission test"
msg.set_content("One authorized test message from the app.")
host = os.environ["SMTP_HOST"]
port = int(os.environ.get("SMTP_PORT", "587"))
if port == 465:
client = smtplib.SMTP_SSL(host, port, context=ctx, timeout=15)
else:
client = smtplib.SMTP(host, port, timeout=15)
client.ehlo()
client.starttls(context=ctx)
client.ehlo()
with client:
client.login(os.environ["SMTP_USER"], os.environ["SMTP_PASSWORD"])
refused = client.send_message(msg)
print("refused:", refused)
create_default_context() чынжырды жана хост атын текшерет, ошондуктан жеке CA ишеним кампасына орнотулушу керек, текшерилбеген контекст менен айланып өтүүгө болбойт. send_message() реле четке каккан алуучулардын сөздүгүн кайтарат; бош сөздүк анын баарын кабыл алганын билдирет. Он беш секундалык таймаут — баштапкы чекит, тармагыңыз үчүн жөндөлгөн маани эмес.
Сырсөздү образдан жана журналдардан тышкары кармаңыз. Аткаруу учурунда бекитилип, чөйрөгө окулган купуя нерсе туура; чөйрөнү журнал сабына чагылдыруу туура эмес, AUTH алмашуусунун жөндөө изи да эмес.
Адат боюнча эмес, реле саясаты жана жол боюнча тандаңыз
Үч шарт чечет. Биринчиден, реле чындыгында эмнени жарыялайт: 587-портто STARTTLS менен гана угуучу кызматка 465-порттон жетүү мүмкүн эмес, жашыруун TLS'ти канчалык кааласаңыз да. Экинчиден, колдонмо менен реленин ортосундагы жол окула турган EHLO алмашуусун кабыл алууга жетиштүү ишенимдүүбү. Үчүнчүдөн, ортодо бир нерсе SMTP'ни кайра жазабы же проксилейби, анткени бул төмөндөтүү тобокелдигинин теориялык же реалдуу экенин аныктайт.
Реле экөөнү тең сунуштаганда, көзөмөлсүз иштеген кызмат үчүн 465'ти, ал эми биринчи жайгаштырууну адам көзөмөлдөгөн кызмат үчүн 587'ни алам, себеби ката билдирүүлөрү ар башка катмарларды көрсөтөт. Бул тандоо — менин жеке каалоом, ал саясат эмес.
Эмнени тандабаңыз, портту, ишеним материалын жана жөнөтүүчү доменин жайгаштыруу менен бирге жазып коюңуз. Анан бир уруксат берилген сыноо билдирүүсүн жөнөтүп, реле аны кабыл алганын ырастаңыз, жөнөтүү натыйжасын жана кийинки жеткирүү отчетун өзүнчө жазуулар катары сактаңыз. Релеге ийгиликтүү өткөрүп берүү — колдонмонун жоопкерчилигинин аягы, билдирүү кирүү кутусуна жеткенин далилдебейт.