Երկու միացման եղանակներն էլ նույն հաղորդագրությունն են տանում նույն ռելեի հաշիվ, և տարբերությունը նրանում է, թե որտեղ է սկսվում 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-ը՝ այն ծառայության, որտեղ մարդը հետևում է առաջին տեղակայմանը, միայն այն պատճառով, որ ձախողման հաղորդագրերը մատնանշում են տարբեր շերտեր։ Այդ նախապատվությունը իմն է, և դա քաղաքականություն չէ։

Ինչ էլ ընտրեք, գրանցեք պորտը, վստահության նյութը և ուղարկողի տիրույթը տեղակայման կողքին։ Այնուհետև ուղարկեք մեկ լիազորված փորձնական հաղորդագրություն և հաստատեք, որ ռելեն ընդունել է այն՝ պահելով ուղարկման արդյունքը և ցանկացած հետագա առաքման հաշվետվություն որպես առանձին գրառումներ։ Ռելեին հաջող հանձնումը հավելվածի պատասխանատվության ավարտն է, ոչ թե ապացույց, որ հաղորդագրությունը հասել է փոստարկղ։

Առնչվող հոդվածներ