Хоёр холболтын горим ижил зурвасыг ижил реле бүртгэл рүү зөөдөг бөгөөд ялгаа нь 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-ыг сонгодог, зөвхөн алдааны мэдээлэл өөр өөр давхаргуудыг заадаг учраас. Тэр сонголт миний хувийн хүсэл бөгөөд энэ нь бодлого биш.

Юуг ч сонгосон, порт, итгэлцлийн материал болон илгээгчийн домайныг байршуулалтын хамт тэмдэглэ. Дараа нь нэг зөвшөөрөгдсөн туршилтын зурвас илгээж, реле үүнийг хүлээн авсныг баталгаажуул, илгээлтийн үр дүн болон дараагийн хүргэлтийн тайланг тусдаа бүртгэл болгон хадгал. Реле-д амжилттай хүлээлгэн өгөх нь програмын хариуцлагын төгсгөл бөгөөд зурвас ирсэн хайрцагт хүрсэн гэсэн нотолгоо биш.

Холбоотой нийтлэлүүд