Python-ի SMTP ուղարկումը՝ STARTTLS 587-ում, թե՞ TLS 465-ում։
STARTTLS-ը 587-ում և անուղղակի TLS-ը 465-ում երկուսն էլ փոխանցում են Python-ի ուղարկում, բայց ձեր ռելեին համապատասխանում է միայն մեկը։ Համեմատեք ձեռքսեղմումը և ձախողման ձևերը։
Երկու միացման եղանակներն էլ նույն հաղորդագրությունն են տանում նույն ռելեի հաշիվ, և տարբերությունը նրանում է, թե որտեղ է սկսվում TLS-ը, ոչ թե ինչ է ուղարկվում։ Մեկը բացվում է բաց տեքստով և թարմացվում է կապուղու ներսում, մյուսը գաղտնագրված է առաջին բայթից։ Այդ միակ տարբերությունը որոշում է, թե ինչ կընդունի խիստ ռելեի քաղաքականությունը, ինչ կարող է նկատել միջանկյալ սարքը, և որ սխալի հաղորդագրության վրա կանցկացնեք մի ամբողջ կեսօր՝ կարդալով։ Ահա թե ինչպես եմ ընտրում նրանց միջև, երբ մասնավոր ցանցում գործող հավելվածը հաղորդագրություն է հանձնում ներքին ուղարկման ծառայությանը։
Որտեղ են իրականում տարբերվում երկու եղանակները
Խնդիրը նույնն է երկու դեպքում էլ՝ նույնականանալ որպես հաստատված հաշիվ, նշել թույլատրված ուղարկող, թվարկել ստացողներին և սպասել, որ ռելեն ստանձնի պատասխանատվությունը։ Փոխվում է գործողությունների հերթականությունը։ 587 պորտը սկսվում է որպես բաց տեքստով SMTP նստաշրջան, EHLO պատասխանում հայտարարում է STARTTLS և թարմացվում է միայն այն դեպքում, երբ հաճախորդը խնդրում է։ 465 պորտը սպասում է TLS ձեռքսեղմման՝ նախքան որևէ SMTP հրահանգ կհնչի։
Ուղարկումը և ռելեն տարբեր աշխատանքներ են, այդ պատճառով պորտերի համարները փոխանակելի սովորություններ չեն։ RFC 6409-ը նկարագրում է հաղորդագրությունների ուղարկումը որպես առանձին ծառայություն, իսկ RFC 8314-ը ներառում է անուղղակի TLS տարբերակը, որը ժամանակակից ռելեների մեծ մասը տրամադրում է 465-ում։ Եթե ձեր ռելեն փաստագրում է երկուսից մեկը, այդ փաստաթուղթը գերազանցում է նախկին գործատուից ստացած ցանկացած նախապատվության։
Ինչ է տալիս STARTTLS-ը 587-ում
Թարմացումը տեղի է ունենում SMTP զրույցի ներսում, ուստի ռելեն կարող է հայտարարել այն, և հաճախորդը կարող է հրաժարվել առանց դրա շարունակելուց։ Python-ում starttls() բացառություն է նետում, երբ սերվերը չի առաջարկում այդ ընդլայնումը, ինչը իջեցման փորձը դարձնում է տեսանելի ձախողում՝ լուռ բաց տեքստով մուտքի փոխարեն։ Այդ վարքագիծը եղանակի գլխավոր փաստարկն է, և արժե դիտավորյալ ապավինել դրան, ոչ պատահաբար։
Ազդեցության պատուհանը փոքր է, բայց իրական. սկզբնական EHLO փոխանակումը ընթեռնելի է, և թարմացումից առաջ ոչինչ չի կրում հավատարմագրեր։ Հավելվածի ենթացանցի և ներքին ռելեի միջև մասնավոր ուղու վրա այդ պատուհանը սովորաբար ընդունելի է։ Այն ուղու վրա, որը դուք չեք վերահսկում, հենց դա է պատճառը, որ որոշ թիմեր պնդում են մյուս եղանակը։
Գաղտնալսման սարքը, որը հեռացնում է STARTTLS հնարավորությունը, առաջացնում է ձախողված ուղարկում, ոչ թե հետընթաց։ Դա այն արդյունքն է, որ ուզում եք, և դա նաև ամենաարագ ձևն է պարզելու, որ ինչ-որ բան վերագրում է SMTP-ն ուղու վրա։
Ինչ է փոխում անուղղակի TLS-ը 465-ում
Բաց տեքստի փուլ ընդհանրապես չկա։ Հաճախորդը 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-ը՝ այն ծառայության, որտեղ մարդը հետևում է առաջին տեղակայմանը, միայն այն պատճառով, որ ձախողման հաղորդագրերը մատնանշում են տարբեր շերտեր։ Այդ նախապատվությունը իմն է, և դա քաղաքականություն չէ։
Ինչ էլ ընտրեք, գրանցեք պորտը, վստահության նյութը և ուղարկողի տիրույթը տեղակայման կողքին։ Այնուհետև ուղարկեք մեկ լիազորված փորձնական հաղորդագրություն և հաստատեք, որ ռելեն ընդունել է այն՝ պահելով ուղարկման արդյունքը և ցանկացած հետագա առաքման հաշվետվություն որպես առանձին գրառումներ։ Ռելեին հաջող հանձնումը հավելվածի պատասխանատվության ավարտն է, ոչ թե ապացույց, որ հաղորդագրությունը հասել է փոստարկղ։