Akhir-akhir ini sedang seru bereksplorasi dengan kapabilitas sistem email, terlebih sedang banyak hari libur yang bisa membuat proses eksplorasi berjalan semakin yoi.

Hampir setiap hari saya (atau kita semua?) membuka email, bahkan—khususnya saya—tanpa mengenal hari libur. Ada banyak informasi menarik yang masuk ke email saya: Surat kabar dari milis langganan saya, daftar bacaan yang ingin saya baca nanti, dan juga kabar akan uang masuk ke Paypal.

Sudah banyak penyedia yang memberikan layanan terkait per-surat-an elektronik, ada Gmail, Rocket Mail, Yandex, Proton, termasuk yang sedang hits dewasa ini: Hey nya Basecamp.

Berbicara tentang Hey, ada hal menarik yang bisa dibahas: Ada sebuah organisasi for-profit yang ingin mengubah cara pengguna email dalam menggunakan email. Hey bukanlah satu-satu nya organisasi yang bergerak dalam bisnis email, ada Tutanota dan Proton yang fokus di keamanan & privasi, Fastmail, dsb.

Tapi yang membedakannya, Hey membuat lapisan lagi diatas protokol email di level layanan: Screening, Papertail, dan yang paling digaris bawahi adalah Tracker blocker, yang meskipun, sejauh yang saya satu, satu-satunya cara untuk "tracking" pengguna di domain email adalah dengan membuat gambar eksternal.

Oke selesai basa-basinya, sekarang, sebelum kita membahas lebih lanjut ke topik inti, mari kita bahas sedikit tentang bagaimana protokol email bekerja.

Kita mulai dari level DNS

In a nutshell

Internet adalah tentang pertukaran data, halaman yang kamu sedang baca sekarang, adalah proses permintaan peramban ketika mengakses alamat ini, lalu server memberikan response akan halaman yang kamu minta, berdasarkan alamat yang ber-format protokol://hostname:port/path.

Dan karena blog ini menggunakan protokol HTTPS, jadi, peramban tidak perlu menampilkan (di alamat) bahwa kamu mengirim permintaan ke port 443, karena itu sudah by default, dan peramban sudah tau itu.

Permintaan tersebut pada dasarnya hanyalah sebuah "instruksi" seperti ini, untuk kasus mengakses halaman google.com misalnya:

GET /bermain-dengan-email-server-for-fun-and-profit HTTP/2
Host: blog.evilfactory.id

Kamu bisa menggunakan telnet untuk mencobanya, tapi karena telnet tidak berjalan untuk HTTP/2, jadi bisa ganti HTTP/2 tersebut menjadi HTTP/1.0 dan lihat apa yang terjadi

Tulisan ini belum di publish, jadi pakai path / dulu

Di response nya diberitahu bahwa halaman yang diminta melakukan redirect ke versi HTTPS nya, karena konfigurasi load balancer yang saya buat untuk melakukan itu, intinya, data yang dikirim ke server kurang lebih seperti itu untuk menampilkan halaman ini.

Sekarang pertanyaannya, data apa yang dikirim ketika kita mengirim (dan menerima) email?

Ini salah satu data email yang saya miliki di mutt untuk salah satu email yang saya simpan:

From: Fariz <redacted@icloud.com>
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_<redacted>-4BFB-9085-F2FD58AFE913"
Mime-Version: 1.0 (Mac OS X Mail 12.0 \(3445.100.15\))
Subject: Re: <Redacted>
X-Universally-Unique-Identifier: <redacted>-4A68-9387-5C3DCD638BA5
Date: Wed, 5 Sep 2018 19:10:39 +0700
References: <[redacted]Q4hVRCJQ@mail.gmail.com>
 <[redacted]M3pGRr0VvauNta92QwKi4w@mail.gmail.com>
To: <Redacted> <[redacted]@google.com>
In-Reply-To: <[Redacted]pGRr0VvauNta92QwKi4w@mail.gmail.com>
Message-Id: <6F33DFEE-[Redacted]-81FB-EC0DEADA8EDB@icloud.com>

...ini isi email...

Ya, email pada dasarnya adalah sebuah berkas dengan format tertentu. Jika halaman web adalah sebuah berkas yang biasanya ber-ekstensi .html dan memiliki content-type dengan nilai text/html, yang dimulai dengan <!doctype html>, email kurang lebih sama namun dimulai dengan From: yang menandakan email tersebut dikirim dari siapa.

Server

Ketika pengguna mengakses port 80/443, ada sebuah program yang khusus untuk mengatur permintaan tersebut. Bisa itu Nginx, HAProxy, Traefik, apapun.

Port tersebut dikenal untuk mengatur permintaan yang menggunakan protokol HTTP/HTTPS. Internet pada dasarnya adalah tentang terhubung dari 1 komputer ke komputer lain melalui sebuah "pintu" bernama port.

Ketika kamu mengakses halaman ini, komputermu (peramban) mengunduh data/berkas yang dikirim oleh server, lalu menampilkannya berdasarkan standar yang sudah ada.

Lalu, bagaimana dengan email?

Kurang lebih sama, peramban tersebut bisa bernama Apple Mail, Spark, ataupun Mutt.

Data yang diunduh? Yang tadi saya lampirkan diatas!

Bedanya, port yang dikunjungi bukanlah 80/443.

Melainkan 143/994 (secure).

Kenapa?

Karena sudah standarnya.

Haha bercanda, karena memang memiliki tujuan yang berbeda.

Ada aturannya.

Seperti, kenapa motor tidak boleh masuk jalan tol sedangkan sama-sama sebuah jalan untuk kendaraan bermotor?

Kamu sudah dapat poinnya.

Mail Server

Oke kita sudah membahas sekilas tentang bagaimana email bekerja dengan membandingkan cara kerja protokol HTTP, sekarang, apa Nginx nya untuk email?

Good question, kalau kata bos gue. Hahaha.

Sebelum kita membahas kesitu, perlu diingat bahwa protokol yang mengatur per-email-an ini ada 2: SMTP dan IMAP/POP3.

SMTP bekerja untuk mengatur email keluar (outbound email) dan IMAP/POP3 untuk email masuk (inbound email).

Disini kita akan fokus membahas protokol IMAP/POP3, karena protokol SMTP relatif lebih mudah dan sudah banyak yang membahas di Internet.

Yang sederhananya, siapa sih yang mengatur ketika ada seseorang yang mengirim email ke fariz@evilfactory.id?

Nah, si IMAP/POP3 inilah jawabannya.

Pertanyaan-pertanyaan lainnya adalah seperti:

  • Siapa pemilik fariz@evilfactory.id tersebut?
  • Apakah alamat tersebut ada?
  • Apakah alamat tersebut dapat dikirim email (anggap ketika sudah kehabisan quota)?
  • Bagaimana agar email yang dikirim sampai ke alamat tersebut dan hanya bisa (well, not actually) diakses oleh penerima dari email tersebut?

Karena kita tidak sedang membahas hal-hal yang advance (termasuk tentang relaying), jadi mari kita persingkat pembahasan ini.

Kembali ke pertanyaan "Nginx untuk IMAP", ada sebuah program yang bernama Dovecot yang sudah pasti free.

Sekarang mari kita coba jalankan Dovecot, dan karena sekarang tahun 2020, yang kita butuhkan adalah Docker 😛

Menjalankan Dovecot

Pastikan Docker sudah berjalan, oke?

Sekarang, kita pull image dari instrumentisto/dovecot karena menurut saya itu sangat cocok untuk konfigurasi minimum.

Setelah itu, jalankan dengan mem-binding port 143 yang ada di container ke port terserah kamu, misal 143 aja deh biar sederhana.

docker run -p 143:143 instrumentisto/dovecot

Lalu kita lakukan telnet untuk memastikan!

telnet localhost 143

Oke kita sudah terhubung, lalu sekarang apa?

Membuat pengguna!

Ada banyak cara untuk membuat sistem "otentikasi", termasuk menggunakan basis data SQL.

Tapi untuk mempersingkat tulisan, kita akan menggunakan metode "virtual users" yakni via berkas /etc/passwd-like dan menggunakan plaintext.

Karena kita sudah menjalankan dovecot kita, sekarang waktunya membuat konfigurasi! Kita akan pakai cara kotor dengan masuk ke instance yang sedang berjalan saja agar lebih singkat hahaha.

docker exec -ti <container_id_dovecot> bash

Lalu kita pergi ke direktori /etc/dovecot, dan silahkan lihat berkas bernama dovecot.conf.

Di baris terakhir, dovecot akan memuat secara opsional konfigurasi yang ada di berkas bernama local.conf. Untuk menghormati konfigurasi default, kita akan melakukan konfigurasi singkat di berkas tersebut, dan karena belum ada vim atau nano, jadi silahkan lakukan apt update; apt install terlebih dahulu, lalu buat konfigurasi tersebut seperti ini:

# /etc/dovecot/local.conf
protocols = imap pop3

log_path = /var/log/dovecot.log
info_log_path = /var/log/dovecot-info.log

ssl = no
disable_plaintext_auth = no

mail_location = maildir:~/Maildir

auth_verbose = yes
auth_mechanisms = plain

passdb {
  driver = passwd-file
  args = /etc/dovecot/passwd
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/home/vmail/%u
}

Berdasarkan konfigurasi diatas, ada beberapa upacara yang harus kita lakukan, berarti:

  1. Membuat berkas log: touch /var/log/{dovecot,dovecot-info}.log
  2. Membuat berkas sebagai "database": touch /etc/devcot/passwd
  3. Membuat pengguna dan grup dengan nama "vmail": useradd vmail; groupadd vmail
  4. Membuat direktori vmail di /home dan berikan ownership ke vmail:vmail: mkdir -p /home/vmail; chown -R vmail:vmail

Oke, setelah itu, mari kita buat pengguna pertama kita, misal fariz@relay.local dengan kata sandi rahasia.

# /etc/dovecot/passwd

fariz@relay.local:{PLAIN}rahasia

Setelah itu, seharusnya kita sudah bisa melakukan "otentikasi" menggunakan data tersebut, misal via telnet (di remote host, bukan docker container):

# telnet localhost 143

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.

a login "fariz@relay.local" "rahasia"

Nanti akan ada response seperti:

a OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE SPECIAL-USE] Logged in

Yang intinya ngasih tau kalau itu sudah berhasil, sekarang, mari kita cek "inbox" kita:

b select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 0 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1598097243] UIDs valid
* OK [UIDNEXT 1] Predicted next UID
b OK [READ-WRITE] Select completed (0.000 + 0.000 secs).

Disitu dijelaskan bahwa ada direktori "Answered", "Flagged", "Deleted", "Seen", dan "Draft", serta tidak ada email masuk huhuhu.

Sampai sini intinya proses instalasi dan sistem otentikasi yang kotor ini berhasil, sekarang, mari kita testing konfigurasi IMAP kita!

Testing IMAP

Disinisaya akan menggunakan Apple Mail & smtplib nya Python. Sebenarnya prosesnya hampir sama dengan cara telnet, tinggal sesuaikan dengan GUI saja :))

Saya akan mengirim email dengan judul "Haloo" ke fariz@relay.local. Jangan kirim dari Gmail/iCloud/dsb karena tidak akan sampai, kecuali kita memiliki publik IP :))

Konfigurasi IMAP

Dan ini contoh mengambilnya via imaplib nya Python:

Skrinsut

Eksperimen yang menarik!

Penutup

Jika serius, pertama-pertama, jangan gunakan "bare" dovecot, melainkan bisa pakai poste.io, mailu, atau omav/docker-mailserver jika tidak ingin berurusan dengan hal-hal terkait postfix.

Kedua, kalau untuk just for fun dan untuk belajar-belajar, yaa bisa gunakan 3 pilihan diatas juga, jangan bare dovecot hahaha.

Next time kita akan coba membuat "email-to-webhook" ataupun "webhook-to-email" sederhana menggunakan teknologi yang sudah ada dan ehm production ready, biar inbound & outbound ter-cover semua.

Terima kasih!