TN-010 β Implement and Verify Enterprise SMTP Configuration and Headers¶
| Field | Value |
|---|---|
| Status | Completed |
| Activity Type | Implementation |
| Record Type | Live |
| Project | Tomcat Monitoring |
| Phase | Monitoring Platform Integration |
| Activity Date | 2026-09-10 |
| Recorded Date | 2026-09-10 |
| Owner | Eddy Wiyatno |
| Working Mode | Mixed |
| Authorization Status | Approved |
| Approved By | Eddy Wiyatno |
| Approval Date | 2026-09-10 |
π― Objective¶
Menuntaskan backlog TASK-TM-015 (Konfigurasi Enterprise SMTP Relay & Otentikasi Terenkripsi) pada Tomcat Diagnostic Service dengan memperbarui skema konfigurasi aplikasi (requireTLS), menambahkan header email standar enterprise RFC (Auto-Submitted, X-Priority, X-Incident-Target, X-Diagnostic-Rule), mengisolasi kredensial SMTP melalui mounted secret files (0400/0444), menstandarisasi tata letak berkas konfigurasi di config/diagnostic-service/, serta memverifikasi pengiriman laporan diagnosis insiden 7-seksi SRE secara end-to-end melalui jalur secure authenticated relay bridge.
Target Utama & Kriteria Keberhasilan:
- Penyempurnaan Skema JSON Konfigurasi Aplikasi (
application-config-v1.schema.json): Menambahkan properti opsional"requireTLS": { "type": "boolean" }pada blok"smtp", serta memastikan validasi ketat Ajv Draft 2020-12 tetap ditegakkan tanpa membeberkan kredensial rahasia saat terjadi kesalahan konfigurasi. - Standardisasi Header Email Enterprise RFC: Memperkaya modul
SmtpAdapterdengan header kepatuhan RFC: Auto-Submitted: auto-generated(RFC 3834): Mencegah infinite auto-reply loop dari sistem autoreply mailbox operator/SRE.X-Priority: "1"(High) untuk insidenfiringberbobotCRITICALdan"3"(Normal) untuk insidenresolvedatau non-critical.X-Incident-Target: Mengidentifikasi target insiden (<environment>/<host>/<instance>).X-Diagnostic-Rule: Mempreservasi nama aturan diagnosis (TomcatDown,TomcatGCPauseHigh, dll.).- Penguatan Enkripsi & Manajemen Kredensial Terisolasi: Mengonfigurasi transport Nodemailer dengan
requireTLS: true, memanfaatkan volume mount rootless untuk filesmtp-usernamedansmtp-passworddengan izin0444/0400, serta mengintegrasikan CA truststore (NODE_EXTRA_CA_CERTS) untuk verifikasi sertifikat TLS internal. - Standardisasi Tata Letak Konfigurasi Statis: Menempatkan konfigurasi runtime kanonikal pada
tomcat-monitoring/config/diagnostic-service/(application.json,targets.json,README.md) dan memisahkan kredensial persisten di${HOME}/.local/share/tomcat-monitoring/diagnostic-service-secrets/(0400), mengeliminasi pembuatan konfigurasi temporer di/tmp. - Pembangunan Versioned Container Image v0.1.8: Membangun image
localhost/tomcat-diagnostic-service:0.1.8(digestsha256:4519277d6a36d8ce0ce9cf01434ee0f0302e1ba4a63e3b0abe883e4497b5ab2e) yang lolos seluruh static validator (100%) dan 62 unit/integration tests (100% pass). - Verifikasi Empiris Penuh Jalur Relay Terotentikasi: Membuktikan pertahanan keamanan Submission Port 587 via automated test suite
scripts/verify-postfix-relay.shdanscripts/test-tomcatdown-live.shyang mencakup negative testing SASL, STARTTLS submission, insiden webhook firing/resolved, dan audit kepatuhan header RFC pada Mailpit API.
π Background¶
Pada fase awal pengembangan Diagnostic MVP Pilot (TN-008 dan TN-031), Diagnostic Service dikonfigurasi untuk mengirimkan email langsung ke server Mailpit lokal tanpa otentikasi SASL dan tanpa enkripsi TLS wajib (secure: false, port 1025).
Meskipun memadai untuk pengujian awal, pola pengiriman langsung tersebut menyisakan celah kesiapan produksi (production readiness gap):
- Ketiadaan Enkripsi Mandatory (requireTLS): Tanpa penegakan requireTLS, klien email dapat mengalami downgrade attack (plaintext fallback) jika server perantara tidak menawarkan kapabilitas STARTTLS.
- Ketiadaan Header Otomatisasi Enterprise: Tanpa header Auto-Submitted: auto-generated, pengiriman laporan insiden otomatis berisiko memicu balasan otomatis (out-of-office autoreply storm) dari sistem email korporat.
- Ketiadaan Metadata Routing SRE: Tanpa header X-Priority dan X-Incident-Target, sistem filter email atau ticketing enterprise tidak dapat melakukan triaging otomatis terhadap laporan insiden.
- Kebutuhan Pengujian Jalur Relay Terotentikasi: Untuk mensimulasikan lingkungan produksi enterprise secara realistis, Diagnostic Service harus diuji terhadap relay MTA yang menerapkan otentikasi Cyrus SASL ketat pada port 587.
π Scope¶
Pekerjaan implementasi mencakup:
tomcat-diagnostic-service(v0.1.8):config/schemas/application-config-v1.schema.json: Penambahan properti"requireTLS": { "type": "boolean" }pada skema konfigurasismtp.src/application/config-loader.js: Pemetaan propertirequireTLSke dalam objek konfigurasismtpyang di-freeze secara immutable.src/adapters/smtp-adapter.js: KonfigurasirequireTLSpada transport Nodemailer dan penyematan header RFC enterprise (Auto-Submitted,X-Priority,X-Incident-Target,X-Diagnostic-Rule).test/unit/config-loader.test.js&test/unit/smtp-adapter.test.js: Pengujian unit untuk validasi skema dan verifikasi pembentukan header email.VERSION,package.json,package-lock.json: Pembaruan versi semantik ke0.1.8.tomcat-monitoring:config/diagnostic-service/application.json: Berkas konfigurasi statis kanonikal memuat konfigurasi server, TLS, timeouts, rules, and SMTP relay.config/diagnostic-service/targets.json: Berkas target allowlist instans Tomcat.config/diagnostic-service/README.md: Dokumentasi teknis parameter konfigurasi dan panduan integrasi SMTP.scripts/deploy-diagnostic-service.sh: Pembaruan deploy script untuk me-mount langsung dariconfig/diagnostic-service/dan host secrets${HOME}/.local/share/tomcat-monitoring/diagnostic-service-secrets/(0400).scripts/verify-postfix-relay.sh: Suite verifikasi otomatis 7-seksi mencakup pengujian keamanan SASL, negative tests, STARTTLS submission, insiden webhook end-to-end, dan audit header RFC pada Mailpit API.scripts/test-tomcatdown-live.sh: Skrip pengujian end-to-end simulasi insidenTomcatDownlive (fase FIRING dan RESOLVED).scripts/validate.sh: Pendaftaranconfig/diagnostic-service/*danscripts/verify-postfix-relay.shke dalamREQUIRED_FILES.devops-handbook:docs/projects/tomcat-monitoring/engineering-journal/monitoring-platform-integration/TN-010-implement-and-verify-enterprise-smtp-configuration-and-headers.md: Jurnal teknik kanonikal implementasi dan verifikasi live.docs/projects/tomcat-monitoring/follow-up-tasks.md: Pembaruan status backlogTASK-TM-015menjadiCompletedβ .docs/projects/tomcat-monitoring/engineering-journal/monitoring-platform-integration/index.md: Penambahan entriTN-010pada tabel hasil dan daftar catatan teknis.
π Prerequisites¶
| Prerequisite | State | Keterangan |
|---|---|---|
| Diagnostic Service Baseline | Image 0.1.7 (Commit 3fa918f) |
Multi-Domain Engine, Stale Lock Recovery, SQLite Retention, Shared Logs, dan Daemonized Spool aktif. |
| Node.js Immutable Base | localhost/nodejs:24.18.0 |
Base image Node.js v24.18.0 exact-pinned tanpa devDependencies. |
| Enterprise Relay Testbed | postfix-relay:587 |
Containerized Postfix Relay Bridge dengan Cyrus SASL dan STARTTLS pada network devops-lab. |
| Downstream Sink / Viewer | mailpit:1025 / 8025 |
Mailpit viewer untuk inspeksi Laporan Investigasi 7-Seksi SRE dan audit header MIME. |
| Implementation Authorization | Approved (2026-09-10) | Otorisasi penuh oleh Project Owner. |
βοΈ Execution Decision¶
Implementasi ini menegakkan keputusan arsitektur platform:
+-----------------------------------------------------------------------------+
| Enterprise SMTP Notification Pipeline (TASK-TM-015) |
+-----------------------------------------------------------------------------+
| |
| 1. Mandatory Transport Security (requireTLS = true): |
| Mencegah fallback ke koneksi plaintext tanpa enkripsi saat berkomunikasi |
| dengan server relay eksternal pada Submission Port 587. |
| |
| 2. Standard Enterprise MIME Headers (RFC 3834 / RFC 2156): |
| - Auto-Submitted: auto-generated -> Perlindungan infinite auto-reply. |
| - X-Priority: 1 (Critical) / 3 -> Triaging otomatis sistem on-call. |
| - X-Incident-Target & X-Rule -> Traceability identitas insiden. |
| |
| 3. Zero Credential Leakage & File Isolation (0400/0444): |
| Kredensial username dan password dibaca dari file mounted terisolasi |
| tanpa pernah dicatat dalam log aplikasi atau diekspos ke output error. |
| |
+-----------------------------------------------------------------------------+
π Technical Workflow¶
%%{init: {themeVariables: { fontSize: 12px }}}%%
flowchart TD
subgraph INGEST["1. Alert Ingestion & Analysis"]
AM["Alertmanager Webhook<br/>(:8443)"] --> DS["Diagnostic Service v0.1.8<br/>(Rulepack Engine)"]
DS <--> DB[("SQLite Database<br/>(diagnostic_data)")]
end
subgraph RELAY["2. Enterprise Secure SMTP Relay"]
SA["SmtpAdapter<br/>(requireTLS: true)"] -->|Port 587: STARTTLS<br/>+ SASL PLAIN| PR["Enterprise Relay Bridge<br/>(postfix-relay:587)"]
PR -->|Downstream Relay<br/>Port 1025| MP["Mailpit Container<br/>(mailpit:1025)"]
end
subgraph AUDIT["3. Inspection & Verification"]
SRE["SRE Operations Viewer<br/>(Mailpit UI :8025)"]
end
DS -->|Laporan 7-Seksi & RFC Headers| SA
MP -->|Pemeriksaan RFC Headers & Delivery| SRE
Workflow Activity Details¶
1. Alert Ingestion & Analysis¶
- Diagnostic Service menerima webhook alert dari Alertmanager pada port HTTPS 8443.
- Worker mengklaim event, mengumpulkan bukti multi-domain, mengevaluasi rulepack, dan menyimpan Canonical Result ke database SQLite persisten.
2. Enterprise Secure SMTP Relay Submission¶
SmtpAdaptermembungkus laporan investigasi 7-seksi SRE dengan 4 header kepatuhan enterprise RFC (Auto-Submitted,X-Priority,X-Incident-Target,X-Diagnostic-Rule).- Koneksi diinisiasi ke Postfix Relay port 587 menggunakan perintah
STARTTLS(requireTLS: true) dan autentikasi Cyrus SASL PLAIN via berkas secret terisolasi (0400).
3. Downstream Delivery & SRE Inspection¶
- Postfix Relay memvalidasi kredensial SASL dan sertifikat TLS, meneruskan pesan ke mailbox Mailpit port 1025.
- Tim SRE dan operator memeriksa struktur header MIME asli dan format laporan 7-seksi melalui Mailpit Web UI pada port 8025.
π§ Implementation Plan¶
| Tahap | Rencana & Tanggung Jawab Teknis |
|---|---|
| Enhance SMTP Configuration Schema and Header Standards | Memperbarui application-config-v1.schema.json untuk menambahkan properti requireTLS, menyesuaikan config-loader.js, memperkaya smtp-adapter.js dengan header standar enterprise RFC (Auto-Submitted, X-Priority, X-Incident-Target, X-Diagnostic-Rule), serta memvalidasi unit test suite 62 test passing. |
| Standardize Static Configuration and Host Secret Storage | Menyediakan berkas konfigurasi statis kanonikal application.json, targets.json, dan README.md pada tomcat-monitoring/config/diagnostic-service/, serta mengisolasi secret files smtp-username, smtp-password, dan bearer-token pada ${HOME}/.local/share/tomcat-monitoring/diagnostic-service-secrets/ dengan izin 0400. |
| Build Versioned Container Image and Verify Static Boundaries | Memperbarui versi ke 0.1.8, membangun image localhost/tomcat-diagnostic-service:0.1.8, dan menjalankan static validator (validate.sh, test-image.sh). |
| Deploy Runtime with Persistent Configuration Mounts | Memperbarui scripts/deploy-diagnostic-service.sh untuk me-mount langsung dari config/diagnostic-service/ dan host persistent secrets, mengeliminasi pembuatan konfigurasi temporer /tmp. |
| Verify Authenticated Submission and Live TomcatDown Incident Delivery | Mengeksekusi test suite otomatis scripts/verify-postfix-relay.sh dan scripts/test-tomcatdown-live.sh untuk memvalidasi negative test autentikasi SASL, STARTTLS submission, evaluasi insiden TomcatDown (FIRING & RESOLVED), serta kepatuhan 7-seksi SRE di Mailpit. |
βοΈ Implementation¶
Enhance SMTP Configuration Schema and Header Standards¶
Menambahkan properti "requireTLS": { "type": "boolean" } pada config/schemas/application-config-v1.schema.json:
"smtp": {
"type": "object", "additionalProperties": false,
"required": ["host", "port", "secure", "from", "to"],
"properties": {
"host": { "type": "string", "minLength": 1 },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"secure": { "type": "boolean" },
+ "requireTLS": { "type": "boolean" },
"from": { "type": "string", "minLength": 3 },
"to": { "type": "string", "minLength": 3 },
"usernameFile": { "type": "string", "minLength": 1 },
"passwordFile": { "type": "string", "minLength": 1 }
},
"dependentRequired": { "usernameFile": ["passwordFile"], "passwordFile": ["usernameFile"] }
},
Memperbarui src/application/config-loader.js agar properti requireTLS dipetakan dengan default false:
smtp: Object.freeze({
...raw.smtp,
requireTLS: raw.smtp.requireTLS ?? false,
timeoutMs: raw.timeouts.smtpMs,
username: raw.smtp.usernameFile ? readMountedFile(raw.smtp.usernameFile, "smtp.usernameFile", { secret: true }) : undefined,
password: raw.smtp.passwordFile ? readMountedFile(raw.smtp.passwordFile, "smtp.passwordFile", { secret: true }) : undefined
})
Memperbarui src/adapters/smtp-adapter.js untuk menerapkan opsi transport requireTLS dan 4 header RFC enterprise:
export class SmtpAdapter {
constructor(config, { transport } = {}) {
this.from = config.from; this.to = config.to;
this.transport = transport ?? nodemailer.createTransport({
host: config.host,
port: config.port,
secure: config.secure ?? false,
requireTLS: config.requireTLS ?? false,
auth: config.username ? { user: config.username, pass: config.password } : undefined,
connectionTimeout: config.timeoutMs,
greetingTimeout: config.timeoutMs,
socketTimeout: config.timeoutMs,
disableFileAccess: true,
disableUrlAccess: true
});
}
async send(result, rendered) {
const isResolved = result.lifecycleStatus === "resolved";
const env = (result.targetId?.split("/")[0] || "lab").toUpperCase();
const alertName = result.ruleId || "TomcatDown";
const severity = (result.event?.labels?.severity || (alertName === "TomcatDown" ? "critical" : "warning")).toUpperCase();
const prefix = isResolved ? "[RESOLVED]" : `[${severity}]`;
const subject = isResolved
? `${prefix} [${env}] Tomcat Service: ${alertName} Restored (Target: ${result.targetId})`
: `${prefix} [${env}] Tomcat Service: ${alertName} (Target: ${result.targetId})`;
const priority = (!isResolved && severity === "CRITICAL") ? "1" : "3";
const headers = {
"Auto-Submitted": "auto-generated",
"X-Priority": priority,
"X-Incident-Target": result.targetId || "unknown",
"X-Diagnostic-Rule": alertName
};
return this.transport.sendMail({ from: this.from, to: this.to, subject, text: rendered.text, html: rendered.html, headers });
}
}
Menjalankan pengujian unit suite:
cd /home/eddywiyatno/git/tomcat-diagnostic-service
podman run --rm --userns=keep-id \
--volume "/home/eddywiyatno/git/tomcat-diagnostic-service:/app:ro,Z" \
--workdir /app \
localhost/nodejs:24.18.0 \
node --test test/unit/*.test.js test/integration/*.test.js
Hasil:
β SMTP adapter produces bounded multipart message with enterprise headers (19.540902ms)
β SMTP adapter sets normal priority for resolved and non-critical alerts (3.2806ms)
β loads versioned non-secret configuration and mounted files (122.829873ms)
β rejects invalid configuration without exposing mounted secret (55.607842ms)
βΉ tests 62
βΉ pass 62
βΉ fail 0
Standardize Static Configuration and Host Secret Storage¶
- Menstandarisasi direktori konfigurasi statis pada
config/diagnostic-service/application.jsondanconfig/diagnostic-service/targets.json:
| Komponen | Jalur Berkas di Host | Jalur Mount di Container | Izin Akses | Keterangan |
|---|---|---|---|---|
| Konfigurasi Utama | config/diagnostic-service/application.json |
/run/tomcat-diagnostic/application.json:ro,z |
0644 |
Definisi server, TLS, timeouts, dan konfigurasi SMTP relay. |
| Target Allowlist | config/diagnostic-service/targets.json |
/run/tomcat-diagnostic/targets.json:ro,z |
0644 |
Daftar target instance Tomcat lab/prod yang diizinkan dievaluasi. |
| Panduan Konfigurasi | config/diagnostic-service/README.md |
N/A (Dokumentasi Git) | 0644 |
Panduan parameter konfigurasi dan troubleshooting. |
| Secret: Username | ${HOME}/.local/share/.../smtp-username |
/run/tomcat-diagnostic/secrets/smtp-username:ro,z |
0400 |
Username SASL untuk autentikasi SMTP (diagnostic-agent). |
| Secret: Password | ${HOME}/.local/share/.../smtp-password |
/run/tomcat-diagnostic/secrets/smtp-password:ro,z |
0400 |
Password SASL untuk autentikasi SMTP (DiagnosticPass123!). |
| Secret: Bearer Token | ${HOME}/.local/share/.../bearer-token |
/run/tomcat-diagnostic/secrets/bearer-token:ro,z |
0400 |
Token autentikasi incoming Alertmanager webhook. |
| CA Certificate | postfix-relay/tls/ca.crt |
/run/tomcat-diagnostic/tls/postfix-ca.crt:ro,z |
0644 |
Sertifikat root CA internal untuk validasi STARTTLS Relay. |
{
"smtp": {
"host": "postfix-relay",
"port": 587,
"secure": false,
"requireTLS": true,
"from": "diagnostic@tomcat-monitoring.invalid",
"to": "operator@tomcat-monitoring.invalid",
"usernameFile": "/run/tomcat-diagnostic/secrets/smtp-username",
"passwordFile": "/run/tomcat-diagnostic/secrets/smtp-password"
}
}
- Menyiapkan direktori secret persisten pada host dengan proteksi izin ketat
0400:
readonly SECRETS_HOST_DIR="${HOME}/.local/share/tomcat-monitoring/diagnostic-service-secrets"
mkdir -p "${SECRETS_HOST_DIR}"
chmod 0700 "${SECRETS_HOST_DIR}"
echo -n "diagnostic-agent" > "${SECRETS_HOST_DIR}/smtp-username"
echo -n "DiagnosticPass123!" > "${SECRETS_HOST_DIR}/smtp-password"
echo -n "test-token-12345" > "${SECRETS_HOST_DIR}/bearer-token"
chmod 0400 "${SECRETS_HOST_DIR}"/*
Actual Result: Seluruh berkas konfigurasi statis tersimpan di repositori dan seluruh rahasia terisolasi di direktori host persisten berizin 0400, sepenuhnya meniadakan dependensi /tmp.
Expected Result
Konfigurasi runtime terbaca dari berkas statis config/diagnostic-service/ dan rahasia terisolasi dengan proteksi izin 0400.
Build Versioned Container Image and Verify Static Boundaries¶
Memperbarui versi semantik ke 0.1.8 pada VERSION, package.json, dan package-lock.json, lalu membangun image baru:
cd /home/eddywiyatno/git/tomcat-diagnostic-service
./scripts/validate.sh
./scripts/build.sh
./scripts/test-image.sh
Output Identitas Image:
- Image Reference: localhost/tomcat-diagnostic-service:0.1.8
- Pinned Digest: sha256:4519277d6a36d8ce0ce9cf01434ee0f0302e1ba4a63e3b0abe883e4497b5ab2e
Deploy Runtime with Persistent Configuration Mounts¶
Memperbarui scripts/deploy-diagnostic-service.sh untuk me-mount berkas konfigurasi langsung dari repositori dan direktori secrets host:
Output:
Verify Authenticated Submission and Live TomcatDown Incident Delivery¶
Mengeksekusi rangkaian pengujian otomatis end-to-end:
cd /home/eddywiyatno/git/tomcat-monitoring
./scripts/validate.sh
./scripts/verify-postfix-relay.sh
./scripts/test-tomcatdown-live.sh
Hasil:
Seluruh 7 seksi pengujian verify-postfix-relay.sh dan seluruh tahapan test-tomcatdown-live.sh berhasil lulus 100% (PASS).
π οΈ Troubleshooting¶
| Gejala Masalah | Penyebab Utama | Solusi & Tindakan Perbaikan |
|---|---|---|
Pemeriksaan queue Postfix sempat gagal (07EA79A650B* in active queue) |
postqueue -p dieksekusi instan beberapa milidetik setelah pengiriman saat MTA masih memproses flushing |
Tambahkan polling loop toleransi latensi (hingga 10 detik) disertai perintah postqueue -f pada skrip pengujian. |
Endpoint webhook Diagnostic Service menolak request manual dengan HTTP 400 invalid_request |
Payload pengujian tidak memuat envelope wajib skema v4 ("version": "4" dan "groupKey") |
Sesuaikan pembentukan JSON payload pengujian dengan JSON Schema Alertmanager v4 (alertmanager-webhook-v4.schema.json). |
β¨οΈ Commands Executed¶
Phase 1: Unit & Component Testing¶
# 1. Validasi statis dan unit testing tomcat-diagnostic-service
cd /home/eddywiyatno/git/tomcat-diagnostic-service
./scripts/validate.sh
podman run --rm --userns=keep-id -v "$(pwd):/app:ro,Z" -w /app localhost/nodejs:24.18.0 node --test test/unit/*.test.js test/integration/*.test.js
# 2. Build dan smoke test image container
./scripts/build.sh
./scripts/test-image.sh
Phase 2: Runtime Deployment with Persistent Config¶
# 3. Deployment Diagnostic Service dengan persistent config
cd /home/eddywiyatno/git/tomcat-monitoring
./scripts/deploy-diagnostic-service.sh
# 4. Validasi baseline repository
./scripts/validate.sh
Phase 3: Automated Verification Suites & Live Incident Injection¶
# 5. Eksekusi pengujian otomatis terpadu Postfix Relay Bridge
./scripts/verify-postfix-relay.sh
# 6. Eksekusi pengujian live siklus insiden TomcatDown (Firing & Resolved)
./scripts/test-tomcatdown-live.sh
# 7. Kompilasi dan sinkronisasi handbook
cd /home/eddywiyatno/git/devops-handbook
./scripts/build-and-sync-site.sh
π Artifact Manifest¶
Table Guide¶
Tabel di bawah mengelompokkan berkas berdasarkan peran teknis dan lapisannya:
- Berkas (Path): Lokasi berkas relatif terhadap root repositori.
- Layer / Kategori: Lapisan arsitektural (Diagnostic Service, Monitoring Config, Test Suites, Handbook).
- Status: Status berkas (Baru = dibuat baru; Modifikasi = diperbarui).
- Tanggung Jawab Teknis: Peran fungsional komponen dalam sistem pengiriman SMTP dan verifikasi insiden.
Artifact Manifest Table¶
| Berkas (Path) | Layer / Kategori | Status | Tanggung Jawab Teknis |
|---|---|---|---|
tomcat-diagnostic-service/config/schemas/application-config-v1.schema.json |
Diagnostic Service (Schema) | Modifikasi | Skema konfigurasi aplikasi memuat properti requireTLS. |
tomcat-diagnostic-service/src/application/config-loader.js |
Diagnostic Service (Config) | Modifikasi | Loader konfigurasi dengan mapping requireTLS: raw.smtp.requireTLS ?? false. |
tomcat-diagnostic-service/src/adapters/smtp-adapter.js |
Diagnostic Service (Adapter) | Modifikasi | Adapter SMTP terotentikasi dengan STARTTLS dan 4 header enterprise RFC. |
tomcat-diagnostic-service/test/unit/smtp-adapter.test.js |
Diagnostic Service (Test) | Modifikasi | Unit test verifikasi RFC headers dan transport options. |
tomcat-monitoring/config/diagnostic-service/application.json |
Monitoring Config | Baru | Berkas konfigurasi statis resmi untuk runtime deployment. |
tomcat-monitoring/config/diagnostic-service/targets.json |
Monitoring Config | Baru | Berkas target allowlist instans Tomcat. |
tomcat-monitoring/config/diagnostic-service/README.md |
Monitoring Config | Baru | Dokumentasi parameter konfigurasi dan panduan SMTP. |
tomcat-monitoring/scripts/deploy-diagnostic-service.sh |
Orchestration | Modifikasi | Skrip deployment runtime me-mount config/diagnostic-service/ dan host secrets. |
tomcat-monitoring/scripts/verify-postfix-relay.sh |
Test Automation | Baru | Test suite 7-seksi otomatis untuk verifikasi Postfix SASL/STARTTLS relay bridge. |
tomcat-monitoring/scripts/test-tomcatdown-live.sh |
Test Automation | Baru | Test suite live simulasi insiden TomcatDown (fase FIRING dan RESOLVED). |
tomcat-monitoring/scripts/validate.sh |
Governance | Modifikasi | Skrip validasi baseline kontrak dan tata letak repositori. |
devops-handbook/docs/projects/tomcat-monitoring/engineering-journal/monitoring-platform-integration/TN-010-implement-and-verify-enterprise-smtp-configuration-and-headers.md |
Tata Kelola (Handbook) | Baru | Dokumentasi Technical Note kanonikal 20 seksi. |
Artifact Dependency & Relationship Graph¶
flowchart TD
subgraph CONFIG["1. Static Configuration & Secrets Layer"]
direction TB
C_CONF["config/diagnostic-service/application.json<br/>(requireTLS: true & SMTP block)"]
C_TARG["config/diagnostic-service/targets.json<br/>(Allowlist target instances)"]
S_SEC[("Host Secrets: 0400<br/>(~/.local/share/.../secrets/)")]
C_CONF --> D_APP["diagnostic-service v0.1.8"]
C_TARG --> D_APP
S_SEC --> D_APP
end
subgraph RELAY["2. Authenticated Relay Bridge"]
direction TB
D_APP -->|Port 587: STARTTLS + SASL| P_RELAY["postfix-relay<br/>(Cyrus SASL Validation)"]
P_RELAY -->|Port 1025 Relay| M_SINK["mailpit<br/>(RFC MIME Headers & 7-Section Report)"]
end
subgraph AUDIT["3. Verification & Test Automation"]
direction TB
T_POST["verify-postfix-relay.sh<br/>(7-Section Relay Bridge Test)"]
T_LIVE["test-tomcatdown-live.sh<br/>(Firing & Resolved Lifecycle Test)"]
D_TN["TN-010 Journal<br/>(Enterprise SMTP Verification)"]
T_POST -.-> P_RELAY
T_LIVE -.-> D_APP
M_SINK -.-> D_TN
end
π§ͺ Test-Scenario Matrix¶
| ID | Skenario Uji | Metode & Target | Kriteria Keberhasilan | Status |
|---|---|---|---|---|
| TS-01 | Validasi Skema & Transport Nodemailer | Unit Test smtp-adapter.test.js |
requireTLS: true disematkan, 4 header RFC terisi |
PASS β
|
| TS-02 | Keamanan Port 587 (Negative Test Unauthenticated) | SMTP direct submit tanpa kredensial | Postfix menolak dengan kode 554 5.7.1 Access denied |
PASS β
|
| TS-03 | Keamanan Port 587 (Negative Test Bad Password) | SMTP direct submit dengan password salah | Postfix menolak dengan kode 535 5.7.8 Authentication failed |
PASS β
|
| TS-04 | Pengiriman Terotentikasi STARTTLS + SASL | SMTP direct submit kredensial valid | Diterima oleh Postfix (250 2.0.0 Ok: queued) |
PASS β
|
| TS-05 | E2E Incident Webhook TomcatDown (FIRING) |
Webhook Alertmanager HTTPS :8443 | Status 202 Accepted, evaluasi insiden, pengiriman laporan 7-seksi | PASS β
|
| TS-06 | Audit Header MIME Enterprise di Mailpit API | HTTP GET /api/v1/message/{id}/headers |
Auto-Submitted, X-Priority: 1, X-Incident-Target, X-Diagnostic-Rule |
PASS β
|
| TS-07 | E2E Incident Webhook TomcatDown (RESOLVED) |
Webhook Alertmanager HTTPS :8443 | Status 202 Accepted, subjek [RESOLVED], X-Priority: 3 |
PASS β
|
| TS-08 | Audit Antrean Postfix Relay | CLI postqueue -p di kontainer relay |
Mail queue is empty (0 pesan tertahan) |
PASS β
|
β Verification¶
1. Log Eksekusi Test Suite Postfix Relay (verify-postfix-relay.sh)¶
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β POSTFIX ENTERPRISE SMTP RELAY BRIDGE (POLA A) VERIFICATION SUITE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
======================================================================
βΆ 1. Pre-Flight Infrastructure & Container Readiness
======================================================================
β PASS: Network devops-lab aktif
β PASS: Container mailpit berjalan (status: running)
β PASS: Container postfix-relay berjalan (status: running)
β PASS: Container diagnostic-service berjalan (status: running)
======================================================================
βΆ 2. Postfix Image & Service Smoke Inspection
======================================================================
βΉ INFO: Postfix runtime version: mail_version = 3.11.7
β PASS: Postfix runtime engine terverifikasi
======================================================================
βΆ 3. SASL Authentication Negative Testing (Port 587 Security Defense)
======================================================================
βΉ INFO: Menguji penolakan pengiriman tanpa otentikasi SASL...
βΉ INFO: Response penolakan unauth: REJECTED_AS_EXPECTED:Can't send mail - all recipients were rejected: 554 5.7.1 <operator@tomcat-monitoring.invalid>: Recipient address rejected: Access denied
β PASS: Postfix menolak koneksi relay tanpa kredensial SASL
βΉ INFO: Menguji penolakan otentikasi dengan kredensial salah...
βΉ INFO: Response penolakan salah password: REJECTED_AS_EXPECTED:Invalid login: 535 5.7.8 Error: authentication failed: authentication failure
β PASS: Postfix menolak kredensial SASL yang salah (Authentication Failed)
======================================================================
βΆ 4. Direct STARTTLS + SASL Submission to Downstream Mailpit Relay
======================================================================
βΉ INFO: Mengirimkan email uji STARTTLS + SASL terotentikasi langsung ke Postfix Port 587...
βΉ INFO: Hasil pengiriman: SUCCESS:250 2.0.0 Ok: queued as 720919A6517
β PASS: Postfix menerima email terotentikasi, mengantrekan pesan, dan meneruskan ke Mailpit
======================================================================
βΆ 5. End-to-End Incident Webhook -> Diagnostic Service -> Postfix -> Mailpit
======================================================================
βΉ INFO: Mengirimkan webhook insiden TomcatDown ke Diagnostic Service...
βΉ INFO: Response webhook Diagnostic Service: HTTP_202:{"accepted":1,"duplicate":0}
β PASS: Diagnostic Service menerima webhook dan memproses evaluasi insiden
βΉ INFO: Menunggu Diagnostic Service memproses dan mengirim laporan 7-seksi via Postfix...
======================================================================
βΆ 6. Mailpit Web UI & SRE 7-Section Report Content Verification
======================================================================
βΉ INFO: Memverifikasi email laporan di Mailpit Web UI API (http://127.0.0.1:8025)...
βΉ INFO: Mailpit audit result:
LATEST_SUBJECT=[CRITICAL] [LAB] Tomcat Service: TomcatDown (Target: lab/tomcat-01/default)
LATEST_SENDER=diagnostic@tomcat-monitoring.invalid
LATEST_RECIPIENTS=['operator@tomcat-monitoring.invalid']
HEADER_AUTO_SUBMITTED=['auto-generated']
HEADER_X_PRIORITY=['1']
HEADER_X_TARGET=['lab/tomcat-01/default']
HEADER_X_RULE=['TomcatDown']
ENTERPRISE_HEADERS_VERIFIED=true
SEVEN_SECTION_REPORT_VERIFIED=true
β PASS: Header RFC Enterprise dan Laporan 7-Seksi SRE lengkap diterima di Mailpit via Postfix Relay
======================================================================
βΆ 7. Postfix Queue & Resource Audit
======================================================================
βΉ INFO: Postfix Queue Status: Mail queue is empty
β PASS: Postfix Queue bersih (0 pesan tertahan / Mail queue is empty)
======================================================================
======================================================================
β¨ ALL VERIFICATION CHECKS PASSED: Postfix Relay Bridge is fully operational!
======================================================================
2. Bukti Struktur Header MIME Asli dari Mailpit API¶
Query API ke endpoint http://127.0.0.1:8025/api/v1/message/{msg_id}/headers membuktikan keberadaan seluruh header enterprise dan rantai pengiriman terenkripsi:
{
"Auto-Submitted": [
"auto-generated"
],
"Content-Type": [
"multipart/alternative; boundary=\"--_NmP-5d358c89bef39037-Part_1\""
],
"Date": [
"Thu, 10 Sep 2026 14:45:48 +0000"
],
"From": [
"diagnostic@tomcat-monitoring.invalid"
],
"Message-Id": [
"<3a7e5069-0e70-ec56-19bf-274bfdf029a4@tomcat-monitoring.invalid>"
],
"Mime-Version": [
"1.0"
],
"Received": [
"from postfix-relay.devops-lab (postfix-relay. [10.89.0.124]) by a5b1c6e3e36c (Mailpit) with SMTP for <operator@tomcat-monitoring.invalid>; Thu, 10 Sep 2026 14:45:48 +0000 (UTC)",
"from [127.0.0.1] (8b87734af32d [10.89.0.134]) by postfix-relay.devops-lab (Postfix) with ESMTPSA id 46D149A650B for <operator@tomcat-monitoring.invalid>; Thu, 10 Sep 2026 14:45:48 +0000 (UTC)"
],
"Return-Path": [
"<diagnostic@tomcat-monitoring.invalid>"
],
"Subject": [
"[CRITICAL] [LAB] Tomcat Service: TomcatDown (Target: lab/tomcat-01/default)"
],
"To": [
"operator@tomcat-monitoring.invalid"
],
"X-Diagnostic-Rule": [
"TomcatDown"
],
"X-Incident-Target": [
"lab/tomcat-01/default"
],
"X-Priority": [
"1"
]
}
3. Log Eksekusi Pengujian Live Insiden TomcatDown (test-tomcatdown-live.sh)¶
======================================================================
βΆ SIMULASI LIVE INSIDEN TOMCATDOWN (FIRING & RESOLVED LIFECYCLE)
======================================================================
1. Verifikasi Kesiapan Stack
β PASS: Stack devops-lab siap
2. Simulasi Webhook Alertmanager: FIRING
β PASS: Webhook FIRING diterima (HTTP 202)
3. Verifikasi Pemrosesan & Pengiriman Notifikasi FIRING
β PASS: Subjek: [CRITICAL] [LAB] Tomcat Service: TomcatDown (Target: lab/tomcat-01/default)
β PASS: Header RFC: Auto-Submitted: auto-generated
β PASS: Header RFC: X-Priority: 1
β PASS: Header RFC: X-Incident-Target: lab/tomcat-01/default
β PASS: Header RFC: X-Diagnostic-Rule: TomcatDown
β PASS: Format Laporan 7-Seksi lengkap terverifikasi
4. Simulasi Webhook Alertmanager: RESOLVED
β PASS: Webhook RESOLVED diterima (HTTP 202)
5. Verifikasi Pemrosesan & Pengiriman Notifikasi RESOLVED
β PASS: Subjek: [RESOLVED] [LAB] Tomcat Service: TomcatDown Restored (Target: lab/tomcat-01/default)
β PASS: Header RFC: Auto-Submitted: auto-generated
β PASS: Header RFC: X-Priority: 3
β PASS: Header RFC: X-Incident-Target: lab/tomcat-01/default
β PASS: Header RFC: X-Diagnostic-Rule: TomcatDown
6. Postfix Queue & Delivery Channel Audit
β PASS: Postfix Relay Queue bersih (0 pesan tertahan / Mail queue is empty)
π₯ Operator Validation¶
Panduan validasi langsung bagi operator dan tim SRE:
- Inspeksi Antarmuka Web Mailpit (
http://localhost:8025): - Buka pesan email laporan
TomcatDowndan pilih tab Headers. - Pastikan terdapat header:
Auto-Submitted: auto-generated,X-Priority: 1,X-Incident-Target: lab/tomcat-01/default, danX-Diagnostic-Rule: TomcatDown. - Inspeksi Pengiriman Aman Postfix Relay:
- Periksa log container Postfix:
podman logs postfix-relayuntuk memastikan koneksi TLS ESTABLISHED dan autentikasi SASL berhasil (sasl_username=diagnostic-agent).
π₯οΈ Source-Control Handoff¶
Setelah penutupan verifikasi teknis ini, berkas yang siap dicommit mencakup:
- tomcat-diagnostic-service/config/schemas/application-config-v1.schema.json
- tomcat-diagnostic-service/src/application/config-loader.js
- tomcat-diagnostic-service/src/adapters/smtp-adapter.js
- tomcat-diagnostic-service/test/unit/smtp-adapter.test.js
- tomcat-monitoring/config/diagnostic-service/application.json
- tomcat-monitoring/config/diagnostic-service/targets.json
- tomcat-monitoring/config/diagnostic-service/README.md
- tomcat-monitoring/scripts/deploy-diagnostic-service.sh
- tomcat-monitoring/scripts/verify-postfix-relay.sh
- tomcat-monitoring/scripts/test-tomcatdown-live.sh
- tomcat-monitoring/scripts/validate.sh
- devops-handbook/docs/projects/tomcat-monitoring/engineering-journal/monitoring-platform-integration/TN-010-implement-and-verify-enterprise-smtp-configuration-and-headers.md
π§Ή Cleanup Evidence¶
| Sumber Daya | Status Retensi | Bukti Integritas (Integrity Evidence) |
|---|---|---|
Mailbox Mailpit (:8025) |
Bersih & Terkontrol | Reset via DELETE /api/v1/messages sebelum dan sesudah verifikasi |
| Temporary Webhook Payloads | Terhapus Otomatis | Perintah rm -f /tmp/tomcatdown-*.json setelah pengujian |
| Postfix Relay Spool Queue | Kosong (0 Pesan) | postqueue -p $\rightarrow$ Mail queue is empty |
Container diagnostic-service |
Active (Running) | podman inspect diagnostic-service $\rightarrow$ Status=running |
π§ Reproduction Boundary¶
- Host Environment: Linux OS (
/home/eddywiyatno/git/) dengan Podman rootless networkdevops-lab. - Port Allocations:
diagnostic-service: Port HTTPS8443(Internal network devops-lab).postfix-relay: Port SMTP Submission587(Internal network devops-lab).mailpit: Port SMTP1025(Internal) dan Web UI / API8025(http://localhost:8025).- File Permissions:
- Direktori secrets di host:
${HOME}/.local/share/tomcat-monitoring/diagnostic-service-secrets/(0700). - Berkas secret:
smtp-username,smtp-password,bearer-token(0400).
π§Ύ Outcome¶
Backlog TASK-TM-015 telah diselesaikan secara penuh dengan status Completed β
:
- Penguatan Protokol & Enkripsi: Transport email Diagnostic Service kini mewajibkan
requireTLS: truepada Submission Port 587, mencegah downgrade attack dan penyadapan jaringan. - Kepatuhan Standar RFC Enterprise: Seluruh email laporan diagnostik dan notifikasi pemulihan kini memuat 4 header kepatuhan enterprise (
Auto-Submitted,X-Priority,X-Incident-Target,X-Diagnostic-Rule). - Penyempurnaan Arsitektur Konfigurasi: Konfigurasi runtime telah distandarisasi di direktori
tomcat-monitoring/config/diagnostic-service/dengan isolasi kredensial pada direktori host persisten (0400), menghilangkan sepenuhnya ketergantungan pada/tmp. - Verifikasi Terpadu: Rangkaian pengujian otomatis (
verify-postfix-relay.shdantest-tomcatdown-live.sh) membuktikan keandalan pipeline dari penolakan akses tidak sah, pengiriman STARTTLS + SASL, evaluasi insidenTomcatDown(FIRING & RESOLVED), hingga verifikasi struktur 7-seksi SRE pada Mailpit.
| Aspek Operasional | Sebelum TN-010 | Sesudah TN-010 | Keuntungan SRE / Sistem |
|---|---|---|---|
| Protokol Keamanan Transport | STARTTLS opsional tanpa enforcement | requireTLS: true wajib pada transport client |
Perlindungan penuh terhadap downgrade attack dan penyadapan jaringan (man-in-the-middle). |
| Autoreply Loop Prevention | Tidak ada header penanda otomatis | Header Auto-Submitted: auto-generated (RFC 3834) |
Mencegah ledakan email balasan otomatis (out-of-office autoreply storm) dari inbox operator. |
| Severity Triaging SRE | Penandaan hanya pada subjek teks email | Header X-Priority: "1" (Critical) / "3" (Normal) |
Memungkinkan filter email enterprise dan gateway PagerDuty memilah prioritas secara otomatis. |
| Target & Rule Tracing | Metadata tertanam di dalam isi HTML laporan | Header X-Incident-Target dan X-Diagnostic-Rule |
Memungkinkan perutean cerdas (smart routing) tiket insiden tanpa harus melakukan parsing bodi email. |
| Tata Letak Konfigurasi | Pembuatan konfigurasi temporer di /tmp |
Konfigurasi terpusat di config/diagnostic-service/ |
Repositori bersih, auditable, dan selaras dengan standar Infrastructure as Code. |
| Manajemen Kredensial | Pengujian dasar tanpa relay autentikasi | Kredensial Cyrus SASL terisolasi via Secret Files 0400 |
Menjamin kepatuhan standar keamanan Least Privilege dan Zero Hardcoded Secret Policy. |
π Lessons Learned¶
- Pemisahan Konfigurasi Statis dan Secret: Menyimpan konfigurasi statis (
application.json,targets.json) di direktoriconfig/repositori dan kredensial rahasia di direktori persisten host${HOME}/.local/share/...dengan mode0400memberikan kepatuhan IaC yang jauh lebih bersih, aman, dan mudah diaudit dibanding membuat konfigurasi dinamis di/tmp. - Asinkronitas Siklus Antrean Postfix: Pemeriksaan status antrean MTA (
postqueue -p) memerlukan penanganan toleransi latensi (retry/flush loop) karena proses pemindahan pesan dari antrean aktif ke pengiriman downstream memerlukan waktu beberapa ratus milidetik. - Pentingnya Header RFC 3834 pada Sistem Otomatis: Menambahkan
Auto-Submitted: auto-generatedadalah praktik wajib pada sistem telemetri otomatis untuk mencegah bencana infinite loop ketika email dikirim ke mailbox dengan auto-responder aktif.
βοΈ Next Steps¶
- TASK-TM-006: Endpoint Audit Log Konfirmasi Tindakan Operator (TM-ADR-0014): Menyediakan API pencatatan umpan balik tindakan operasional manual SRE pada TN-011.
- TASK-TM-009: Dashboard Observabilitas Grafana: Membangun dashboard visualisasi terpusat JVM, Tomcat, dan infrastruktur monitoring.
π Related Documentation¶
- Follow-up Tasks Backlog
- Diagnostic MVP Target and Evidence Contract
- TM-ADR-0014 β Enforce Zero Automatic Remediation for Diagnostic Service
- TM-ADR-0015 β Adopt Asynchronous Webhook Ingestion with Durable SQLite Acceptance Pattern
- TM-ADR-0016 β Designate Diagnostic Service as Canonical Incident Notification Authority
- TM-ADR-0023 β Adopt Multi-Domain Diagnostic Dispatcher and Rule ID Fidelity
- TN-008 β Integrate Live Prometheus Evidence Adapter and Shared Persistent Tomcat Logs
- TN-009 β Implement and Verify Event Collector Daemonization and Persistent Spool
- Engineering Journal Standards