DEBI PRAHARADIKA
← Back to Blog Index
Network Servers2026-07-1712 min read

Membangun API Dynamic Credentials Menggunakan Asterisk Realtime Architecture (ARA)

Membangun API berbasis PHP untuk manajemen akun SIP dinamis menggunakan Asterisk Realtime Architecture (ARA) dan PJSIP.

Membangun server VoIP (Voice over IP) berskala enterprise dengan Asterisk sering kali membentur satu batasan lama yaitu konfigurasi berbasis file teks. Secara tradisional, setiap kali Anda ingin menambahkan ekstensi baru atau mengubah password pengguna, Anda harus mengedit file pjsip.conf dan melakukan perintah core reload atau setidaknya module reload agar konfigurasi tersebut terbaca oleh Asterisk.

Dalam kebutuhan seperti sistem SaaS (Software as a Service) atau aplikasi Cloud PBX, kita membutuhkan sistem yang mampu membuat akun pengguna baru dari halaman web/dashboard dan akun tersebut langsung aktif detik itu juga, tanpa perlu me-restart layanan telepon. Maka Asterisk Realtime Architecture (ARA) bisa menjadi salah satu solusinya.


Sekilas Asterisk Realtime Architecture (ARA)

ARA merupakan fitur bawaan Asterisk yang memungkinkan sistem untuk tidak lagi membaca konfigurasi dari file .conf statis, melainkan melakukan query langsung ke database relasional (seperti MySQL atau PostgreSQL) secara real-time (pada saat proses inisialisasi panggilan atau registrasi terjadi).

Asterisk ARA Architecture Alur Arsitektur ARA: Web API (PHP) menulis data akun ke dalam database MySQL. Ketika ada perangkat (softphone/IP Phone) yang mencoba melakukan registrasi, Asterisk secara otomatis membaca tabel tersebut via ODBC tanpa perlu reload.

Dengan arsitektur ini, peran developer akan bergeser dari sekadar mengedit config file menjadi membangun API untuk berinteraksi dengan database. Selama API Anda mampu menulis data dengan benar ke database, Asterisk akan menangani sisanya. Misalnya: membuat akun, mengubah password, menghapus akun, dan sebagainya bisa dilakukan melalui API yang Anda bangun. Ini sangat berguna untuk bisnis VoIP kecil, layanan PBX berbasis cloud, atau sistem telepon yang terintegrasi dengan aplikasi bisnis Anda.

Ada tiga hal yang perlu dipersiapkan sebelum membangun sistem ini, antara lain Endpoint, Auth, dan Address of Record (AOR) dalam PJSIP.


Memahami Endpoint, Auth, dan AOR dalam PJSIP

Sebelum membahas lebih jauh mengenai database, kita harus paham bagaimana Asterisk (menggunakan driver PJSIP) mendefinisikan sebuah "Akun SIP". PJSIP memecah satu entitas akun menjadi tiga komponen utama yaitu Endpoint, Auth, dan AOR.

PJSIP System Thinking System Thinking PJSIP: Sebuah akun SIP modern bukanlah satu kesatuan tunggal, melainkan gabungan dari Endpoint (Profil), Auth (Kredensial), dan AOR (Lokasi Kontak).

  1. Endpoint (ps_endpoints): Ini adalah inti dari akun. Dan disinilah profil teknis didefinisikan (codec apa yang diizinkan, apakah mendukung video, dll).
  2. Auth (ps_auths): Ini adalah brankas keamanan. Menyimpan kredensial (username dan password) untuk otentikasi.
  3. AOR / Address of Record (ps_aors): Ini adalah alamat lokasi. Menentukan berapa banyak perangkat yang boleh login menggunakan nomor ekstensi yang sama secara bersamaan (max_contacts).

Ketiga tabel ini diikat oleh field ID yang saling merujuk. Misalnya, untuk membuat satu akun SIP, Anda harus mengisi minimal satu baris di ketiga tabel tersebut dengan ID yang cocok.


Skema Database

Langkah pertama implementasi adalah menyiapkan database MySQL Anda. Berikut adalah skema untuk membangun sistem otentikasi dinamis.

ARA Data Model ERD

-- Tabel AOR
CREATE TABLE ps_aors (
    id VARCHAR(40) PRIMARY KEY,
    max_contacts INT DEFAULT 1,
    remove_existing ENUM('yes', 'no') DEFAULT 'yes'
);

-- Tabel Auth
CREATE TABLE ps_auths (
    id VARCHAR(40) PRIMARY KEY,
    auth_type ENUM('md5', 'userpass') DEFAULT 'userpass',
    password VARCHAR(40),
    username VARCHAR(40)
);

-- Tabel Endpoint
CREATE TABLE ps_endpoints (
    id VARCHAR(40) PRIMARY KEY,
    transport VARCHAR(40) DEFAULT 'transport-udp',
    aors VARCHAR(200),
    auth VARCHAR(40),
    context VARCHAR(40) DEFAULT 'default',
    disallow VARCHAR(200) DEFAULT 'all',
    allow VARCHAR(200) DEFAULT 'ulaw,alaw,gsm'
);

(Catatan: Anda dapat memperoleh skema tabel terlengkap menggunakan tool alembic yang disediakan dalam source code Asterisk di folder contrib/ast-db-manage/)


Mengonfigurasi Asterisk agar Membaca Database

Asterisk berkomunikasi dengan MySQL melalui ODBC. Anda harus menyambungkan driver Linux ODBC Anda ke Asterisk melalui file res_odbc.conf:

; /etc/asterisk/res_odbc.conf
[asterisk_db]
enabled => yes
dsn => asterisk-mysql
username => dbuser
password => dbpass
pre-connect => yes
max_connections => 20

Selanjutnya, beri tahu Asterisk (lewat extconfig.conf) bahwa konfigurasi PJSIP kini berada di database, bukan di file lokal:

; /etc/asterisk/extconfig.conf
[settings]
ps_endpoints => odbc,asterisk_db,ps_endpoints
ps_auths => odbc,asterisk_db,ps_auths
ps_aors => odbc,asterisk_db,ps_aors

Restart atau reload penuh Asterisk sekali saja. Setelah proses ini, Asterisk Anda sudah sepenuhnya berbasis database untuk hal-hal yang sudah Anda definisikan di extconfig.conf. Untuk hal lainnya, Asterisk akan tetap menggunakan file konfigurasi lokal. Berikut adalah contoh implementasi API menggunakan PHP.


Implementasi API menggunakan PHP

Rancangan sebuah halaman dashboard admin yang dapat membuat ekstensi SIP secara otomatis pada Asterisk. Anda ingin ketika tombol "Create Account" ditekan, ekstensi tersebut langsung aktif di softphone. Atau bisa juga untuk aplikasi click to call di website pemasaran / landing page yang secara otomatis membuat ekstensi baru ketika ada user yang ingin menghubungi via telepon.

Admin UI Concept Desain Konseptual Antarmuka Admin: API yang akan kita bangun berperan sebagai mesin di balik tombol "Create SIP Account" ini.

Berikut adalah implementasi kode menggunakan PHP (dengan ekstensi PDO) untuk menangani permintaan (request) API tersebut secara aman dan profesional.

<?php
// api/v1/create_sip_account.php

header('Content-Type: application/json');

// Pastikan request menggunakan metode POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(["status" => "error", "message" => "Method not allowed"]);
    exit;
}

// Konfigurasi Database
$host = '127.0.0.1';
$db   = 'asterisk_realtime';
$user = 'dbuser';
$pass = 'dbpass';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    http_response_code(500);
    echo json_encode(["status" => "error", "message" => "Database connection failed"]);
    exit;
}

// Mengambil data JSON dari Body POST
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE);

$extension = $input['extension'] ?? '';
$password  = $input['password'] ?? '';

// Validasi input sederhana
if (empty($extension) || empty($password)) {
    http_response_code(400);
    echo json_encode(["status" => "error", "message" => "Extension and password are required"]);
    exit;
}

try {
    // Memulai Database Transaction agar proses insert ke 3 tabel bersifat atomic
    $pdo->beginTransaction();

    // 1. Insert ke tabel ps_aors
    $stmtAor = $pdo->prepare("INSERT INTO ps_aors (id, max_contacts) VALUES (?, ?)");
    $stmtAor->execute([$extension, 2]); // Mengizinkan login maksimal di 2 perangkat

    // 2. Insert ke tabel ps_auths
    $stmtAuth = $pdo->prepare("INSERT INTO ps_auths (id, auth_type, username, password) VALUES (?, 'userpass', ?, ?)");
    $stmtAuth->execute([$extension, $extension, $password]);

    // 3. Insert ke tabel ps_endpoints (Mengikat ketiganya)
    $stmtEndpoint = $pdo->prepare("INSERT INTO ps_endpoints (id, transport, aors, auth, context) VALUES (?, 'transport-udp', ?, ?, 'default')");
    $stmtEndpoint->execute([$extension, $extension, $extension]);

    // Jika sukses, simpan secara permanen
    $pdo->commit();

    echo json_encode([
        "status" => "success", 
        "message" => "SIP Account {$extension} successfully provisioned!"
    ]);

} catch (Exception $e) {
    // Jika ada error pada salah satu query, batalkan semua (Rollback)
    $pdo->rollBack();
    
    http_response_code(500);
    echo json_encode(["status" => "error", "message" => "Failed to provision account: " . $e->getMessage()]);
}
?>

Menguji API

Anda dapat menguji (test) API ini menggunakan cURL atau Postman:

curl -X POST http://localhost/api/v1/create_sip_account.php \
-H "Content-Type: application/json" \
-d '{"extension":"1005", "password":"StrongPassword123"}'

Jika merespons dengan "success", maka di saat yang sama Anda bisa langsung membuka aplikasi Softphone (Zoiper, MicroSIP, dll), memasukkan 1005 sebagai username dan password yang baru Anda buat. Panggilan akan langsung terdaftar ke server Asterisk tanpa reload!


Best Practices

  1. Keamanan (Security):
    • Anda sangat disarankan mengganti auth_type dari userpass (plaintext) menjadi PASSWORD (hash) di kolom auth_type tabel ps_auths.
    • Jangan pernah meletakkan API ini terbuka ke publik tanpa Authentication Header (seperti JWT atau API Key).
  2. Caching: Walau disebut "realtime", jika sistem Anda diserang ribuan request registrasi per detik, database MySQL akan kewalahan menahan query ARA Asterisk. Di lingkungan enterprise skala besar, disarankan menggunakan modul Sorcery Caching milik Asterisk agar kredensial di-cache sementara di memori setelah dibaca dari database. Atau menggunakan rate limiting untuk membatasi jumlah request per detik ke API ini.

Dengan menguasai API Asterisk ARA ini, Anda sudah ada bayangan pengembangan sistem telekomunikasi Cloud layaknya Twilio atau sistem VoIP layaknya GoJek/Tokopedia - walaupun implementasinya jauh lebih kompleks.