{"title":"Akses SSH melalui proxy","slug":"ssh-proxy-access","category":"llm-cookbook","summary":"Bagaimana agen LLM menjalankan perintah di mesin jarak jauh dengan aman melalui API proxy SSH alih-alih kunci SSH mentah.","audience":["llm"],"tags":["cookbook","ssh","proxy","infrastructure","remote-execution"],"difficulty":"intermediate","updated":"2026-09-26","word_count":340,"read_minutes":2,"llm_context":"JANGAN PERNAH menyimpan kunci privat SSH mentah sebagai LLM. Gunakan HTTP API proxy SSH:\n1) POST /connect?target=<name> → session_id (persisten, bertahan berjam-jam).\n2) POST /<session_id>/exec {command, timeout} → exec_id.\n3) GET /<session_id>/exec/<exec_id> → keluaran saat selesai.\n4) Gunakan endpoint SFTP untuk unggah/unduh berkas alih-alih cat/heredoc.\nTarget adalah nama yang didaftarkan lebih dulu (mis. \"vps1\"), bukan IP — proxy\nadalah satu-satunya tempat kredensial hidup.\n","lang":"id","translated":true,"requested_lang":"id","content_markdown":"\n# Akses SSH melalui proxy\n\nAgen perlu menjalankan perintah di mesin jarak jauh — deploy kontainer, membaca log, memperbaiki config. Menyerahkan kunci privat SSH mentah kepada LLM adalah ide buruk: kunci berakhir di jendela konteks, log, dan transkrip. Proxy SSH menyelesaikannya: kredensial dipegangnya, agen hanya berbicara HTTP.\n\n## Modelnya\n\n```\nLLM ──HTTPS──► Proxy SSH ──SSH──► mesin target\n                (memegang kunci,\n                 log audit,\n                 batas laju)\n```\n\nProxy memaparkan sesi persisten dengan permukaan REST sederhana:\n\n| Endpoint | Tujuan |\n|---|---|\n| `POST /connect?target=vps1` | membuka sesi → `session_id` |\n| `POST /<sid>/exec` `{command, timeout}` | menjalankan perintah (async) → `exec_id` |\n| `GET /<sid>/exec/<exec_id>` | polling keluaran |\n| Endpoint SFTP | unggah/unduh berkas, `ls`, `mkdir`, `rm` |\n\nAutentikasi berupa token Bearer — pola yang sama seperti semua API lain yang kamu pakai.\n\n## Pola eksekusi\n\n```bash\n# 1. sambungkan sekali, pakai ulang sesi untuk seluruh tugas\nSID=$(curl -s -H \"Authorization: Bearer $KEY\" \\\n  \"https://ssh-proxy.example/connect?target=vps1\" | jq -r .session_id)\n\n# 2. jalankan perintah\nEID=$(curl -s -H \"Authorization: Bearer $KEY\" -H \"Content-Type: application/json\" \\\n  -X POST \"https://ssh-proxy.example/$SID/exec\" \\\n  -d '{\"command\": \"docker ps --format \\\"{{.Names}}\\\"\", \"timeout\": 120}' | jq -r .exec_id)\n\n# 3. polling hasilnya\ncurl -s -H \"Authorization: Bearer $KEY\" \"https://ssh-proxy.example/$SID/exec/$EID\"\n```\n\n## Aturan main\n\n1. **Pakai ulang sesi.** Menyambung per perintah memboroskan sumber daya dan memicu batas laju. Simpan `session_id` (mis. `/tmp/vps1_sid`) dan kirimkan heartbeat sebelum pakai ulang.\n2. **Namai target, jangan menemukannya.** Target terdaftar lebih dulu (`vps1`, `pi`, …). Proxy adalah satu-satunya sumber kebenaran — jangan pernah hardcode alamat IP di kode agen.\n3. **Utamakan SFTP daripada cat/heredoc shell untuk berkas.** Meloloskan data biner lewat `exec` merusak payload. Gunakan endpoint unggah/unduh khusus.\n4. **Kutip perintahmu.** Badan JSON diurai dua kali (HTTP + shell). Bungkus perintah jarak jauh dalam tanda kutip tunggal dan jaga satu baris.\n5. **Asumsikan audit.** Setiap exec masuk log audit proxy — bersikaplah seolah manusia membaca segalanya (ia bisa).\n\n## Kapan exec TIDAK dipakai\n\n- Membaca keadaan terstruktur yang punya API (Docker, basis data, Mind API Synapse) — selalu utamakan API daripada mengurai keluaran CLI.\n- Proses interaktif berdurasi panjang. `exec` fire-and-forget dengan batas waktu; pakai `nohup` + berkas status di target sebagai gantinya.\n- Apa pun yang merusak tanpa instruksi eksplisit. Proxy memberimu kekuatan — manusia memberimu izin.\n\n## Pemulihan kesalahan\n\n| Gejala | Solusi |\n|---|---|\n| 401 saat connect | token kedaluwarsa — baca ulang dari memory/settings, tidak pernah dari transkrip |\n| sesi 404 | sesi kedaluwarsa (batas 24 jam) — sambung ulang |\n| exec timeout | naikkan `timeout` atau pecah perintahnya; cek beban target |\n| isi berkas rusak | kamu memakai `exec` alih-alih SFTP — pindah ke endpoint SFTP |\n","content_html":"<h1>Akses SSH melalui proxy</h1>\n<p>Agen perlu menjalankan perintah di mesin jarak jauh — deploy kontainer, membaca log, memperbaiki config. Menyerahkan kunci privat SSH mentah kepada LLM adalah ide buruk: kunci berakhir di jendela konteks, log, dan transkrip. Proxy SSH menyelesaikannya: kredensial dipegangnya, agen hanya berbicara HTTP.</p>\n<h2>Modelnya</h2>\n<pre><code class=\"hljs language-plaintext\">LLM ──HTTPS──► Proxy SSH ──SSH──► mesin target\n                (memegang kunci,\n                 log audit,\n                 batas laju)</code></pre><p>Proxy memaparkan sesi persisten dengan permukaan REST sederhana:</p>\n<table>\n<thead>\n<tr>\n<th>Endpoint</th>\n<th>Tujuan</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>POST /connect?target=vps1</code></td>\n<td>membuka sesi → <code>session_id</code></td>\n</tr>\n<tr>\n<td><code>POST /&lt;sid&gt;/exec</code> <code>{command, timeout}</code></td>\n<td>menjalankan perintah (async) → <code>exec_id</code></td>\n</tr>\n<tr>\n<td><code>GET /&lt;sid&gt;/exec/&lt;exec_id&gt;</code></td>\n<td>polling keluaran</td>\n</tr>\n<tr>\n<td>Endpoint SFTP</td>\n<td>unggah/unduh berkas, <code>ls</code>, <code>mkdir</code>, <code>rm</code></td>\n</tr>\n</tbody></table>\n<p>Autentikasi berupa token Bearer — pola yang sama seperti semua API lain yang kamu pakai.</p>\n<h2>Pola eksekusi</h2>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># 1. sambungkan sekali, pakai ulang sesi untuk seluruh tugas</span>\nSID=$(curl -s -H <span class=\"hljs-string\">&quot;Authorization: Bearer <span class=\"hljs-variable\">$KEY</span>&quot;</span> \\\n  <span class=\"hljs-string\">&quot;https://ssh-proxy.example/connect?target=vps1&quot;</span> | jq -r .session_id)\n\n<span class=\"hljs-comment\"># 2. jalankan perintah</span>\nEID=$(curl -s -H <span class=\"hljs-string\">&quot;Authorization: Bearer <span class=\"hljs-variable\">$KEY</span>&quot;</span> -H <span class=\"hljs-string\">&quot;Content-Type: application/json&quot;</span> \\\n  -X POST <span class=\"hljs-string\">&quot;https://ssh-proxy.example/<span class=\"hljs-variable\">$SID</span>/exec&quot;</span> \\\n  -d <span class=\"hljs-string\">&#x27;{&quot;command&quot;: &quot;docker ps --format \\&quot;{{.Names}}\\&quot;&quot;, &quot;timeout&quot;: 120}&#x27;</span> | jq -r .exec_id)\n\n<span class=\"hljs-comment\"># 3. polling hasilnya</span>\ncurl -s -H <span class=\"hljs-string\">&quot;Authorization: Bearer <span class=\"hljs-variable\">$KEY</span>&quot;</span> <span class=\"hljs-string\">&quot;https://ssh-proxy.example/<span class=\"hljs-variable\">$SID</span>/exec/<span class=\"hljs-variable\">$EID</span>&quot;</span></code></pre><h2>Aturan main</h2>\n<ol>\n<li><strong>Pakai ulang sesi.</strong> Menyambung per perintah memboroskan sumber daya dan memicu batas laju. Simpan <code>session_id</code> (mis. <code>/tmp/vps1_sid</code>) dan kirimkan heartbeat sebelum pakai ulang.</li>\n<li><strong>Namai target, jangan menemukannya.</strong> Target terdaftar lebih dulu (<code>vps1</code>, <code>pi</code>, …). Proxy adalah satu-satunya sumber kebenaran — jangan pernah hardcode alamat IP di kode agen.</li>\n<li><strong>Utamakan SFTP daripada cat/heredoc shell untuk berkas.</strong> Meloloskan data biner lewat <code>exec</code> merusak payload. Gunakan endpoint unggah/unduh khusus.</li>\n<li><strong>Kutip perintahmu.</strong> Badan JSON diurai dua kali (HTTP + shell). Bungkus perintah jarak jauh dalam tanda kutip tunggal dan jaga satu baris.</li>\n<li><strong>Asumsikan audit.</strong> Setiap exec masuk log audit proxy — bersikaplah seolah manusia membaca segalanya (ia bisa).</li>\n</ol>\n<h2>Kapan exec TIDAK dipakai</h2>\n<ul>\n<li>Membaca keadaan terstruktur yang punya API (Docker, basis data, Mind API Synapse) — selalu utamakan API daripada mengurai keluaran CLI.</li>\n<li>Proses interaktif berdurasi panjang. <code>exec</code> fire-and-forget dengan batas waktu; pakai <code>nohup</code> + berkas status di target sebagai gantinya.</li>\n<li>Apa pun yang merusak tanpa instruksi eksplisit. Proxy memberimu kekuatan — manusia memberimu izin.</li>\n</ul>\n<h2>Pemulihan kesalahan</h2>\n<table>\n<thead>\n<tr>\n<th>Gejala</th>\n<th>Solusi</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>401 saat connect</td>\n<td>token kedaluwarsa — baca ulang dari memory/settings, tidak pernah dari transkrip</td>\n</tr>\n<tr>\n<td>sesi 404</td>\n<td>sesi kedaluwarsa (batas 24 jam) — sambung ulang</td>\n</tr>\n<tr>\n<td>exec timeout</td>\n<td>naikkan <code>timeout</code> atau pecah perintahnya; cek beban target</td>\n</tr>\n<tr>\n<td>isi berkas rusak</td>\n<td>kamu memakai <code>exec</code> alih-alih SFTP — pindah ke endpoint SFTP</td>\n</tr>\n</tbody></table>\n","urls":{"html":"/docs/llm-cookbook/ssh-proxy-access","text":"/docs/llm-cookbook/ssh-proxy-access?format=text","json":"/docs/llm-cookbook/ssh-proxy-access?format=json","llm":"/docs/llm-cookbook/ssh-proxy-access?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"],"wordCount":340,"readMinutes":2,"llmContext":"JANGAN PERNAH menyimpan kunci privat SSH mentah sebagai LLM. Gunakan HTTP API proxy SSH:\n1) POST /connect?target=<name> → session_id (persisten, bertahan berjam-jam).\n2) POST /<session_id>/exec {command, timeout} → exec_id.\n3) GET /<session_id>/exec/<exec_id> → keluaran saat selesai.\n4) Gunakan endpoint SFTP untuk unggah/unduh berkas alih-alih cat/heredoc.\nTarget adalah nama yang didaftarkan lebih dulu (mis. \"vps1\"), bukan IP — proxy\nadalah satu-satunya tempat kredensial hidup.\n","requestedLang":"id","contentMarkdown":"\n# Akses SSH melalui proxy\n\nAgen perlu menjalankan perintah di mesin jarak jauh — deploy kontainer, membaca log, memperbaiki config. Menyerahkan kunci privat SSH mentah kepada LLM adalah ide buruk: kunci berakhir di jendela konteks, log, dan transkrip. Proxy SSH menyelesaikannya: kredensial dipegangnya, agen hanya berbicara HTTP.\n\n## Modelnya\n\n```\nLLM ──HTTPS──► Proxy SSH ──SSH──► mesin target\n                (memegang kunci,\n                 log audit,\n                 batas laju)\n```\n\nProxy memaparkan sesi persisten dengan permukaan REST sederhana:\n\n| Endpoint | Tujuan |\n|---|---|\n| `POST /connect?target=vps1` | membuka sesi → `session_id` |\n| `POST /<sid>/exec` `{command, timeout}` | menjalankan perintah (async) → `exec_id` |\n| `GET /<sid>/exec/<exec_id>` | polling keluaran |\n| Endpoint SFTP | unggah/unduh berkas, `ls`, `mkdir`, `rm` |\n\nAutentikasi berupa token Bearer — pola yang sama seperti semua API lain yang kamu pakai.\n\n## Pola eksekusi\n\n```bash\n# 1. sambungkan sekali, pakai ulang sesi untuk seluruh tugas\nSID=$(curl -s -H \"Authorization: Bearer $KEY\" \\\n  \"https://ssh-proxy.example/connect?target=vps1\" | jq -r .session_id)\n\n# 2. jalankan perintah\nEID=$(curl -s -H \"Authorization: Bearer $KEY\" -H \"Content-Type: application/json\" \\\n  -X POST \"https://ssh-proxy.example/$SID/exec\" \\\n  -d '{\"command\": \"docker ps --format \\\"{{.Names}}\\\"\", \"timeout\": 120}' | jq -r .exec_id)\n\n# 3. polling hasilnya\ncurl -s -H \"Authorization: Bearer $KEY\" \"https://ssh-proxy.example/$SID/exec/$EID\"\n```\n\n## Aturan main\n\n1. **Pakai ulang sesi.** Menyambung per perintah memboroskan sumber daya dan memicu batas laju. Simpan `session_id` (mis. `/tmp/vps1_sid`) dan kirimkan heartbeat sebelum pakai ulang.\n2. **Namai target, jangan menemukannya.** Target terdaftar lebih dulu (`vps1`, `pi`, …). Proxy adalah satu-satunya sumber kebenaran — jangan pernah hardcode alamat IP di kode agen.\n3. **Utamakan SFTP daripada cat/heredoc shell untuk berkas.** Meloloskan data biner lewat `exec` merusak payload. Gunakan endpoint unggah/unduh khusus.\n4. **Kutip perintahmu.** Badan JSON diurai dua kali (HTTP + shell). Bungkus perintah jarak jauh dalam tanda kutip tunggal dan jaga satu baris.\n5. **Asumsikan audit.** Setiap exec masuk log audit proxy — bersikaplah seolah manusia membaca segalanya (ia bisa).\n\n## Kapan exec TIDAK dipakai\n\n- Membaca keadaan terstruktur yang punya API (Docker, basis data, Mind API Synapse) — selalu utamakan API daripada mengurai keluaran CLI.\n- Proses interaktif berdurasi panjang. `exec` fire-and-forget dengan batas waktu; pakai `nohup` + berkas status di target sebagai gantinya.\n- Apa pun yang merusak tanpa instruksi eksplisit. Proxy memberimu kekuatan — manusia memberimu izin.\n\n## Pemulihan kesalahan\n\n| Gejala | Solusi |\n|---|---|\n| 401 saat connect | token kedaluwarsa — baca ulang dari memory/settings, tidak pernah dari transkrip |\n| sesi 404 | sesi kedaluwarsa (batas 24 jam) — sambung ulang |\n| exec timeout | naikkan `timeout` atau pecah perintahnya; cek beban target |\n| isi berkas rusak | kamu memakai `exec` alih-alih SFTP — pindah ke endpoint SFTP |\n","contentHtml":"<h1>Akses SSH melalui proxy</h1>\n<p>Agen perlu menjalankan perintah di mesin jarak jauh — deploy kontainer, membaca log, memperbaiki config. Menyerahkan kunci privat SSH mentah kepada LLM adalah ide buruk: kunci berakhir di jendela konteks, log, dan transkrip. Proxy SSH menyelesaikannya: kredensial dipegangnya, agen hanya berbicara HTTP.</p>\n<h2>Modelnya</h2>\n<pre><code class=\"hljs language-plaintext\">LLM ──HTTPS──► Proxy SSH ──SSH──► mesin target\n                (memegang kunci,\n                 log audit,\n                 batas laju)</code></pre><p>Proxy memaparkan sesi persisten dengan permukaan REST sederhana:</p>\n<table>\n<thead>\n<tr>\n<th>Endpoint</th>\n<th>Tujuan</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>POST /connect?target=vps1</code></td>\n<td>membuka sesi → <code>session_id</code></td>\n</tr>\n<tr>\n<td><code>POST /&lt;sid&gt;/exec</code> <code>{command, timeout}</code></td>\n<td>menjalankan perintah (async) → <code>exec_id</code></td>\n</tr>\n<tr>\n<td><code>GET /&lt;sid&gt;/exec/&lt;exec_id&gt;</code></td>\n<td>polling keluaran</td>\n</tr>\n<tr>\n<td>Endpoint SFTP</td>\n<td>unggah/unduh berkas, <code>ls</code>, <code>mkdir</code>, <code>rm</code></td>\n</tr>\n</tbody></table>\n<p>Autentikasi berupa token Bearer — pola yang sama seperti semua API lain yang kamu pakai.</p>\n<h2>Pola eksekusi</h2>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># 1. sambungkan sekali, pakai ulang sesi untuk seluruh tugas</span>\nSID=$(curl -s -H <span class=\"hljs-string\">&quot;Authorization: Bearer <span class=\"hljs-variable\">$KEY</span>&quot;</span> \\\n  <span class=\"hljs-string\">&quot;https://ssh-proxy.example/connect?target=vps1&quot;</span> | jq -r .session_id)\n\n<span class=\"hljs-comment\"># 2. jalankan perintah</span>\nEID=$(curl -s -H <span class=\"hljs-string\">&quot;Authorization: Bearer <span class=\"hljs-variable\">$KEY</span>&quot;</span> -H <span class=\"hljs-string\">&quot;Content-Type: application/json&quot;</span> \\\n  -X POST <span class=\"hljs-string\">&quot;https://ssh-proxy.example/<span class=\"hljs-variable\">$SID</span>/exec&quot;</span> \\\n  -d <span class=\"hljs-string\">&#x27;{&quot;command&quot;: &quot;docker ps --format \\&quot;{{.Names}}\\&quot;&quot;, &quot;timeout&quot;: 120}&#x27;</span> | jq -r .exec_id)\n\n<span class=\"hljs-comment\"># 3. polling hasilnya</span>\ncurl -s -H <span class=\"hljs-string\">&quot;Authorization: Bearer <span class=\"hljs-variable\">$KEY</span>&quot;</span> <span class=\"hljs-string\">&quot;https://ssh-proxy.example/<span class=\"hljs-variable\">$SID</span>/exec/<span class=\"hljs-variable\">$EID</span>&quot;</span></code></pre><h2>Aturan main</h2>\n<ol>\n<li><strong>Pakai ulang sesi.</strong> Menyambung per perintah memboroskan sumber daya dan memicu batas laju. Simpan <code>session_id</code> (mis. <code>/tmp/vps1_sid</code>) dan kirimkan heartbeat sebelum pakai ulang.</li>\n<li><strong>Namai target, jangan menemukannya.</strong> Target terdaftar lebih dulu (<code>vps1</code>, <code>pi</code>, …). Proxy adalah satu-satunya sumber kebenaran — jangan pernah hardcode alamat IP di kode agen.</li>\n<li><strong>Utamakan SFTP daripada cat/heredoc shell untuk berkas.</strong> Meloloskan data biner lewat <code>exec</code> merusak payload. Gunakan endpoint unggah/unduh khusus.</li>\n<li><strong>Kutip perintahmu.</strong> Badan JSON diurai dua kali (HTTP + shell). Bungkus perintah jarak jauh dalam tanda kutip tunggal dan jaga satu baris.</li>\n<li><strong>Asumsikan audit.</strong> Setiap exec masuk log audit proxy — bersikaplah seolah manusia membaca segalanya (ia bisa).</li>\n</ol>\n<h2>Kapan exec TIDAK dipakai</h2>\n<ul>\n<li>Membaca keadaan terstruktur yang punya API (Docker, basis data, Mind API Synapse) — selalu utamakan API daripada mengurai keluaran CLI.</li>\n<li>Proses interaktif berdurasi panjang. <code>exec</code> fire-and-forget dengan batas waktu; pakai <code>nohup</code> + berkas status di target sebagai gantinya.</li>\n<li>Apa pun yang merusak tanpa instruksi eksplisit. Proxy memberimu kekuatan — manusia memberimu izin.</li>\n</ul>\n<h2>Pemulihan kesalahan</h2>\n<table>\n<thead>\n<tr>\n<th>Gejala</th>\n<th>Solusi</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>401 saat connect</td>\n<td>token kedaluwarsa — baca ulang dari memory/settings, tidak pernah dari transkrip</td>\n</tr>\n<tr>\n<td>sesi 404</td>\n<td>sesi kedaluwarsa (batas 24 jam) — sambung ulang</td>\n</tr>\n<tr>\n<td>exec timeout</td>\n<td>naikkan <code>timeout</code> atau pecah perintahnya; cek beban target</td>\n</tr>\n<tr>\n<td>isi berkas rusak</td>\n<td>kamu memakai <code>exec</code> alih-alih SFTP — pindah ke endpoint SFTP</td>\n</tr>\n</tbody></table>\n","translationsAvailable":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}