Dërgimi SMTP me Python: STARTTLS në 587 apo TLS në 465?
STARTTLS në 587 dhe TLS i nënkuptuar në 465 të dyja mbartin dërgimin nga Python, por vetëm një i përshtatet releut tuaj. Krahasoni shtrëngimin e duarve dhe mënyrat e dështimit.
Të dyja mënyrat e lidhjes mbartin të njëjtin mesazh në të njëjtin llogari rele, dhe ndryshimi është ku fillon TLS, jo çfarë dërgohet. Njëra hapet në tekst të qartë dhe përmirësohet brenda lidhjes; tjetra është e kriptuar që nga bajti i parë. Ky ndryshim i vetëm vendos çfarë do të pranojë një politikë e rreptë rele, çfarë mund të vëzhgojë një pajisje e ndërmjetme dhe cilin mesazh gabimi do të kaloni një pasdite duke lexuar. Ja si zgjedh mes tyre kur një aplikacion në një rrjet privat i dorëzon një mesazh një shërbimi të brendshëm dërgimi.
Ku ndryshojnë vërtet dy mënyrat
Detyra është e njëjtë në të dyja rastet: të vërtetohesh si llogari e miratuar, të emërtosh një dërgues të lejuar, të listosh marrësit dhe të presësh që releu të marrë përgjegjësinë. Ajo që ndryshon është radha e veprimeve. Porta 587 fillon si sesion SMTP në tekst të qartë, njofton STARTTLS në përgjigjen EHLO dhe përmirësohet vetëm nëse klienti e kërkon. Porta 465 pret një shtrëngim duarsh TLS përpara se të shqiptohet çdo komandë SMTP.
Dërgimi dhe releu janë punë të ndryshme, prandaj numrat e portave nuk janë zakone të këmbyeshme. RFC 6409 e përshkruan dërgimin e mesazheve si shërbim më vete, dhe RFC 8314 mbulon variantin e TLS të nënkuptuar që shumica e releve moderne e ofrojnë në 465. Nëse releu juaj dokumenton njërën nga të dyja, ai dokumentacion ka përparësi ndaj çdo preference të fituar nga një punëdhënës i mëparshëm.
Çfarë ju jep STARTTLS në 587
Përmirësimi ndodh brenda bisedës SMTP, kështu që releu mund ta njoftojë dhe klienti mund të refuzojë të vazhdojë pa të. Në Python, starttls() hedh një përjashtim kur serveri nuk e ofron atë zgjerim, gjë që e kthen një përpjekje për ulje niveli në një dështim të dukshëm në vend të një hyrjeje të heshtur në tekst të qartë. Ai sjellje është argumenti kryesor për mënyrën, dhe ia vlen të mbështetesh tek ai me qëllim dhe jo rastësisht.
Dritarja e ekspozimit është e vogël por reale: shkëmbimi fillestar EHLO është i lexueshëm, dhe asgjë përpara përmirësimit nuk mbart kredenciale. Në një rrugë private midis një nënrrjeti aplikacioni dhe një releu të brendshëm, ajo dritare zakonisht është e pranueshme. Në një rrugë që nuk e kontrolloni, pikërisht kjo është arsyeja pse disa ekipe këmbëngulin për mënyrën tjetër.
Një pajisje përgjimi që heq aftësinë STARTTLS prodhon një dërgim të dështuar, jo një kthim pas. Ky është rezultati që dëshironi, dhe është gjithashtu mënyra më e shpejtë për të zbuluar se diçka po rishkruan SMTP në rrugë.
Çfarë ndryshon TLS i nënkuptuar në 465
Nuk ka fare fazë teksti të qartë. Klienti kryen një shtrëngim duarsh TLS sapo hapet socket-i, vërteton certifikatën kundrejt magazinës së tij të besimit dhe vetëm pastaj shkëmben EHLO, AUTH dhe mesazhin. Asgjë nuk mund ta ulë nivelin e sesionit sepse nuk ekziston një gjendje teksti të qartë për të negociuar, dhe kjo eliminon një klasë të tërë dështimesh përgjimi.
Shkëmbimi është diagnozueshmëria. Një rele që përgjigjet në 465 me SMTP tekst të qartë, ose një balancues ngarkese që përfundon TLS me emrin e gabuar të certifikatës, dështon në shtrëngimin e duarsh dhe ju jep një gabim SSL në vend të një gabimi poste. Kur kjo ndodh, problemi është nën aplikacion, dhe asnjë sasi ndërtimi i mesazhit nuk e rregullon.
Një funksion dërgimi, dy transportues
Kodi pothuajse nuk ndryshon midis mënyrave, prandaj zgjedhja duhet bërë nga politika e releut dhe jo nga komoditeti i bibliotekës. Eksportoni fillimisht cilësimet, pastaj ekzekutoni një skript të vetëm që zgjedh transportuesin sipas portës së konfiguruar.
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() verifikon zinxhirin dhe emrin e hostit, prandaj një CA private duhet të instalohet në magazinën e besimit në vend që të anashkalohet me një kontekst të paverifikuar. send_message() kthen një fjalor të marrësve që releu refuzoi; një fjalor bosh do të thotë se i pranoi të gjithë. Afati kohor prej pesëmbëdhjetë sekondash është një pikënisje, jo një vlerë e akorduar për rrjetin tuaj.
Mbajeni fjalëkalimin jashtë imazhit dhe jashtë regjistrave. Një sekret i montuar në kohë ekzekutimi dhe i lexuar në mjedis është në rregull; të pasqyrosh mjedisin në një rresht regjistri nuk është, dhe as një gjurmë korrigjimi i shkëmbimit AUTH.
Zgjidhni sipas politikës së releut dhe rrugës, jo sipas zakonit
Tre kushte e vendosin. Së pari, çfarë reklamon releu në të vërtetë: një shërbim që dëgjon vetëm në 587 me STARTTLS nuk arrihet në 465, sado që preferoni TLS të nënkuptuar. Së dyti, nëse rruga midis aplikacionit dhe releut është mjaftueshëm e besueshme për të pranuar një shkëmbim EHLO të lexueshëm. Së treti, nëse diçka në mes rishkruan ose proxyzon SMTP, sepse kjo vendos nëse rreziku i uljes së nivelit është teorik apo real.
Kur releu ofron të dyja, marr 465 për një shërbim që funksionon pa mbikëqyrje dhe 587 për një ku një person po ndjek vendosjen e parë, vetëm sepse mesazhet e dështimit tregojnë shtresa të ndryshme. Ai preferim është imi dhe nuk është politikë.
Çfarëdo që të zgjidhni, regjistroni portën, materialin e besimit dhe domenin e dërguesit bashkë me vendosjen. Pastaj dërgoni një mesazh prove të autorizuar dhe konfirmoni që releu e pranoi, duke i mbajtur rezultatin e dërgimit dhe çdo raport shpërndarjeje të mëvonshëm si regjistrime të veçanta. Një dorëzim i suksesshëm releut është fundi i përgjegjësisë së aplikacionit, jo prova që mesazhi arriti në një kuti hyrëse.