Njia zote mbili za muunganisho hubeba ujumbe ule ule kwenda akaunti ile ile ya relay, na tofauti ni mahali TLS inapoanza, si kile kinachotumwa. Moja hufunguka kwa maandishi wazi na hupandishwa ndani ya muunganisho; nyingine imesimbwa kwa njia fiche kuanzia baiti ya kwanza. Tofauti hiyo moja huamua sera kali ya relay itakubali nini, kifaa cha kati kinaweza kuona nini, na ujumbe gani wa hitilafu utakao kutumia mchana mzima kuusoma. Hivi ndivyo ninavyochagua kati yao wakati programu kwenye mtandao wa kibinafsi inawasilisha ujumbe kwa huduma ya ndani ya utumaji.

Mahali njia mbili zinatofautiana kwa kweli

Kazi ni ile ile katika hali zote mbili: kuthibitisha kama akaunti iliyoidhinishwa, kutaja mtumaji anayeruhusiwa, kuorodhesha wapokeaji, na kusubiri relay ichukue jukumu. Kinachobadilika ni mpangilio wa shughuli. Bandari 587 huanza kama kikao cha SMTP cha maandishi wazi, hutangaza STARTTLS katika jibu la EHLO, na hupandishwa tu ikiwa mteja ataomba. Bandari 465 inatarajia makubaliano ya mkono ya TLS kabla ya amri yoyote ya SMTP kutamkwa.

Utumaji na relay ni kazi tofauti, ndiyo sababu namba za bandari si tabia zinazobadilishana. RFC 6409 inaelezea utumaji wa ujumbe kama huduma yake yenyewe, na RFC 8314 inashughulikia aina ya TLS isiyo wazi ambayo relay nyingi za kisasa hutoa kwenye 465. Ikiwa relay yako inaandika moja ya hizo mbili, nyaraka hizo zinapita mapendeleo yoyote uliyopata kutoka kwa mwajiri wa awali.

STARTTLS kwenye 587 inakupa nini

Upandishaji hufanyika ndani ya mazungumzo ya SMTP, kwa hivyo relay inaweza kuutangaza na mteja anaweza kukataa kuendelea bila huo. Katika Python, starttls() hutupa ubaguzi wakati seva haitoi kiendelezi hicho, jambo ambalo hugeuza jaribio la kupunguza ngazi kuwa kushindwa kunakoonekana badala ya kuingia kwa maandishi wazi kwa utulivu. Tabia hiyo ndiyo hoja kuu ya njia hii, na inafaa kuitegemea kwa makusudi na si kwa bahati.

Dirisha la kufichuliwa ni dogo lakini la kweli: mabadilishano ya kwanza ya EHLO yanaweza kusomwa, na hakuna kinachobeba vitambulisho kabla ya upandishaji. Kwenye njia ya kibinafsi kati ya subneti ya programu na relay ya ndani, dirisha hilo kwa kawaida linakubalika. Kwenye njia usiyoidhibiti, hiyo ndiyo sababu baadhi ya timu zinasisitiza njia nyingine.

Kifaa cha kukatiza kinachoondoa uwezo wa STARTTLS huzalisha utumaji ulioshindwa, si kurudi nyuma. Hiyo ndiyo matokeo unayotaka, na pia ni njia ya haraka zaidi ya kugundua kuwa kitu fulani kinaandika upya SMTP kwenye njia.

TLS isiyo wazi kwenye 465 inabadilisha nini

Hakuna awamu ya maandishi wazi hata kidogo. Mteja hufanya makubaliano ya mkono ya TLS mara tu soketi inapofunguka, huthibitisha cheti dhidi ya hifadhi yake ya uaminifu, na kisha tu hubadilishana EHLO, AUTH na ujumbe. Hakuna kinachoweza kupunguza ngazi ya kikao kwa sababu hakuna hali ya maandishi wazi ya kujadiliana kutoka humo, na hilo huondoa tabaka zima la kushindwa kwa kukatiza.

Badilishano ni uwezo wa utambuzi. Relay inayojibu kwenye 465 kwa SMTP ya maandishi wazi, au kisawazishaji cha mzigo kinachomaliza TLS kwa jina la cheti lisilo sahihi, hushindwa kwenye makubaliano ya mkono na kukupa hitilafu ya SSL badala ya hitilafu ya barua. Hilo linapotokea, tatizo liko chini ya programu, na hakuna kiasi cha ujenzi wa ujumbe kitakacholirekebisha.

Kazi moja ya utumaji, usafirishaji mbili

Msimbo hautofautiani sana kati ya njia, kwa hivyo uchaguzi unapaswa kufanywa kutokana na sera ya relay na si urahisi wa maktaba. Hamisha mipangilio kwanza, kisha endesha script moja inayochagua usafirishaji kutoka bandari iliyosanidiwa.

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() huthibitisha mnyororo na jina la mwenyeji, kwa hivyo CA ya kibinafsi lazima isakinishwe katika hifadhi ya uaminifu badala ya kupitwa kwa muktadha usiothibitishwa. send_message() hurudisha kamusi ya wapokeaji ambao relay iliwakataa; kamusi tupu inamaanisha iliwakubali wote. Muda wa sekunde kumi na tano ni mahali pa kuanzia, si thamani iliyorekebishwa kwa mtandao wako.

Weka nenosiri nje ya picha na nje ya kumbukumbu. Siri iliyowekwa wakati wa utekelezaji na kusomwa katika mazingira ni sawa; kurudia mazingira kwenye mstari wa kumbukumbu si sawa, na athari ya utatuzi wa mabadilishano ya AUTH pia si sawa.

Chagua kwa sera ya relay na njia, si kwa tabia

Masharti matatu yanaamua. Kwanza, kile relay inatangaza kwa kweli: huduma inayosikiliza tu kwenye 587 na STARTTLS haiwezi kufikiwa kwenye 465, hata ukipendelea TLS isiyo wazi kiasi gani. Pili, ikiwa njia kati ya programu na relay inaaminika vya kutosha kukubali mabadilishano ya EHLO yanayosomeka. Tatu, ikiwa kitu katikati kinaandika upya au kufanya proksi ya SMTP, kwa sababu hilo huamua ikiwa hatari ya kupunguza ngazi ni ya kinadharia au ya kweli.

Relay inapotoa zote mbili, mimi huchukua 465 kwa huduma inayoendeshwa bila usimamizi na 587 kwa ile ambapo mtu anafuatilia usambazaji wa kwanza, kwa sababu tu ujumbe wa kushindwa unaonyesha matabaka tofauti. Upendeleo huo ni wangu na si sera.

Chochote utakachochagua, rekodi bandari, nyenzo ya uaminifu na kikoa cha mtumaji pamoja na usambazaji. Kisha tuma ujumbe mmoja wa jaribio ulioidhinishwa na uthibitishe kuwa relay iliupokea, ukihifadhi matokeo ya utumaji na ripoti yoyote ya uwasilishaji ya baadaye kama kumbukumbu tofauti. Uwasilishaji uliofanikiwa kwa relay ni mwisho wa jukumu la programu, si uthibitisho kwamba ujumbe ulifika kwenye kikasha cha barua.

Makala zinazohusiana