{"title":"Dostęp SSH przez proxy","slug":"ssh-proxy-access","category":"llm-cookbook","summary":"Jak agent LLM bezpiecznie wykonuje polecenia na zdalnych maszynach przez API proxy SSH zamiast surowych kluczy SSH.","audience":["llm"],"tags":["cookbook","ssh","proxy","infrastructure","remote-execution"],"difficulty":"intermediate","updated":"2026-09-26","word_count":342,"read_minutes":2,"llm_context":"NIGDY nie trzymaj surowych kluczy prywatnych SSH jako LLM. Używaj HTTP-API proxy SSH:\n1) POST /connect?target=<name> → session_id (trwałe, przeżywa godziny).\n2) POST /<session_id>/exec {command, timeout} → exec_id.\n3) GET /<session_id>/exec/<exec_id> → wyjście po zakończeniu.\n4) Do wysyłania/pobierania plików używaj endpointów SFTP zamiast cat/heredoc.\nCele to predefiniowane nazwy (np. \"vps1\"), nie IP — proxy jest jedynym miejscem,\ngdzie żyją dane uwierzytelniające.\n","lang":"pl","translated":true,"requested_lang":"pl","content_markdown":"\n# Dostęp SSH przez proxy\n\nAgenty muszą wykonywać polecenia na zdalnych maszynach — wdrażać kontener, czytać log, naprawiać konfigurację. Oddawanie surowych kluczy prywatnych SSH LLM to zły pomysł: klucze trafiają do okien kontekstu, logów i transkrypcji. Proxy SSH rozwiązuje to: to on posiada dane uwierzytelniające, agent mówi tylko HTTP.\n\n## Model\n\n```\nLLM ──HTTPS──► Proxy SSH ──SSH──► maszyny docelowe\n                (posiada klucze,\n                 dziennik audytu,\n                 limity zapytań)\n```\n\nProxy udostępnia trwałe sesje przez prostą powierzchnię REST:\n\n| Endpoint | Cel |\n|---|---|\n| `POST /connect?target=vps1` | otwarcie sesji → `session_id` |\n| `POST /<sid>/exec` `{command, timeout}` | wykonanie polecenia (async) → `exec_id` |\n| `GET /<sid>/exec/<exec_id>` | odpytanie o wyjście |\n| Endpointy SFTP | wysyłanie/pobieranie plików, `ls`, `mkdir`, `rm` |\n\nUwierzytelnianie to token Bearer — ten sam wzorzec, co w każdej innej API, którą używasz.\n\n## Wzorzec wykonania\n\n```bash\n# 1. połącz raz, używaj sesji przez całe zadanie\nSID=$(curl -s -H \"Authorization: Bearer $KEY\" \\\n  \"https://ssh-proxy.example/connect?target=vps1\" | jq -r .session_id)\n\n# 2. wykonaj polecenie\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. odpytaj o wynik\ncurl -s -H \"Authorization: Bearer $KEY\" \"https://ssh-proxy.example/$SID/exec/$EID\"\n```\n\n## Reguły postępowania\n\n1. **Używaj sesji ponownie.** Łączenie na każde polecenie marnuje zasoby i uruchamia limity. Zapisz `session_id` (np. `/tmp/vps1_sid`) i daj mu heartbeat przed ponownym użyciem.\n2. **Nazywaj cele, nie odkrywaj ich.** Cele są predefiniowane (`vps1`, `pi`, …). Proxy jest jedynym źródłem prawdy — nigdy nie zaszywaj adresów IP w kodzie agenta.\n3. **Preferuj SFTP nad cat/heredoc shella dla plików.** Escapowanie danych binarnych przez `exec` psuje ładunki. Używaj dedykowanych endpointów wysyłania/pobierania.\n4. **Cytuj swoje polecenia.** Treść JSON jest parsowana dwukrotnie (HTTP + shell). Owiń zdalne polecenia w pojedyncze cudzysłowy i trzymaj je w jednej linii.\n5. **Zakładaj audyt.** Każdy exec trafia do dziennika audytu proxy — zachowuj się tak, jakby człowiek czytał wszystko (może).\n\n## Kiedy NIE używać exec\n\n- Czytanie ustrukturyzowanego stanu, który ma API (Docker, bazy danych, Mind API Synapse) — zawsze preferuj API nad parsowaniem wyjścia CLI.\n- Długotrwałe procesy interaktywne. `exec` to fire-and-forget z timeoutem; użyj `nohup` + pliku statusu na celu.\n- Cokolwiek destrukcyjnego bez wyraźnego polecenia. Proxy daje ci moc — człowiek daje ci pozwolenie.\n\n## Odzyskiwanie po błędach\n\n| Objaw | Rozwiązanie |\n|---|---|\n| 401 przy connect | token wygasł — odczytaj go ponownie z memory/settings, nigdy z transkrypcji |\n| sesja 404 | sesja wygasła (limit 24h) — połącz ponownie |\n| timeout exec | zwiększ `timeout` albo podziel polecenie; sprawdź obciążenie celu |\n| zepsuta zawartość pliku | użyłeś `exec` zamiast SFTP — przejdź na endpointy SFTP |\n","content_html":"<h1>Dostęp SSH przez proxy</h1>\n<p>Agenty muszą wykonywać polecenia na zdalnych maszynach — wdrażać kontener, czytać log, naprawiać konfigurację. Oddawanie surowych kluczy prywatnych SSH LLM to zły pomysł: klucze trafiają do okien kontekstu, logów i transkrypcji. Proxy SSH rozwiązuje to: to on posiada dane uwierzytelniające, agent mówi tylko HTTP.</p>\n<h2>Model</h2>\n<pre><code class=\"hljs language-plaintext\">LLM ──HTTPS──► Proxy SSH ──SSH──► maszyny docelowe\n                (posiada klucze,\n                 dziennik audytu,\n                 limity zapytań)</code></pre><p>Proxy udostępnia trwałe sesje przez prostą powierzchnię REST:</p>\n<table>\n<thead>\n<tr>\n<th>Endpoint</th>\n<th>Cel</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>POST /connect?target=vps1</code></td>\n<td>otwarcie sesji → <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>wykonanie polecenia (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>odpytanie o wyjście</td>\n</tr>\n<tr>\n<td>Endpointy SFTP</td>\n<td>wysyłanie/pobieranie plików, <code>ls</code>, <code>mkdir</code>, <code>rm</code></td>\n</tr>\n</tbody></table>\n<p>Uwierzytelnianie to token Bearer — ten sam wzorzec, co w każdej innej API, którą używasz.</p>\n<h2>Wzorzec wykonania</h2>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># 1. połącz raz, używaj sesji przez całe zadanie</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. wykonaj polecenie</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. odpytaj o wynik</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>Reguły postępowania</h2>\n<ol>\n<li><strong>Używaj sesji ponownie.</strong> Łączenie na każde polecenie marnuje zasoby i uruchamia limity. Zapisz <code>session_id</code> (np. <code>/tmp/vps1_sid</code>) i daj mu heartbeat przed ponownym użyciem.</li>\n<li><strong>Nazywaj cele, nie odkrywaj ich.</strong> Cele są predefiniowane (<code>vps1</code>, <code>pi</code>, …). Proxy jest jedynym źródłem prawdy — nigdy nie zaszywaj adresów IP w kodzie agenta.</li>\n<li><strong>Preferuj SFTP nad cat/heredoc shella dla plików.</strong> Escapowanie danych binarnych przez <code>exec</code> psuje ładunki. Używaj dedykowanych endpointów wysyłania/pobierania.</li>\n<li><strong>Cytuj swoje polecenia.</strong> Treść JSON jest parsowana dwukrotnie (HTTP + shell). Owiń zdalne polecenia w pojedyncze cudzysłowy i trzymaj je w jednej linii.</li>\n<li><strong>Zakładaj audyt.</strong> Każdy exec trafia do dziennika audytu proxy — zachowuj się tak, jakby człowiek czytał wszystko (może).</li>\n</ol>\n<h2>Kiedy NIE używać exec</h2>\n<ul>\n<li>Czytanie ustrukturyzowanego stanu, który ma API (Docker, bazy danych, Mind API Synapse) — zawsze preferuj API nad parsowaniem wyjścia CLI.</li>\n<li>Długotrwałe procesy interaktywne. <code>exec</code> to fire-and-forget z timeoutem; użyj <code>nohup</code> + pliku statusu na celu.</li>\n<li>Cokolwiek destrukcyjnego bez wyraźnego polecenia. Proxy daje ci moc — człowiek daje ci pozwolenie.</li>\n</ul>\n<h2>Odzyskiwanie po błędach</h2>\n<table>\n<thead>\n<tr>\n<th>Objaw</th>\n<th>Rozwiązanie</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>401 przy connect</td>\n<td>token wygasł — odczytaj go ponownie z memory/settings, nigdy z transkrypcji</td>\n</tr>\n<tr>\n<td>sesja 404</td>\n<td>sesja wygasła (limit 24h) — połącz ponownie</td>\n</tr>\n<tr>\n<td>timeout exec</td>\n<td>zwiększ <code>timeout</code> albo podziel polecenie; sprawdź obciążenie celu</td>\n</tr>\n<tr>\n<td>zepsuta zawartość pliku</td>\n<td>użyłeś <code>exec</code> zamiast SFTP — przejdź na endpointy 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":342,"readMinutes":2,"llmContext":"NIGDY nie trzymaj surowych kluczy prywatnych SSH jako LLM. Używaj HTTP-API proxy SSH:\n1) POST /connect?target=<name> → session_id (trwałe, przeżywa godziny).\n2) POST /<session_id>/exec {command, timeout} → exec_id.\n3) GET /<session_id>/exec/<exec_id> → wyjście po zakończeniu.\n4) Do wysyłania/pobierania plików używaj endpointów SFTP zamiast cat/heredoc.\nCele to predefiniowane nazwy (np. \"vps1\"), nie IP — proxy jest jedynym miejscem,\ngdzie żyją dane uwierzytelniające.\n","requestedLang":"pl","contentMarkdown":"\n# Dostęp SSH przez proxy\n\nAgenty muszą wykonywać polecenia na zdalnych maszynach — wdrażać kontener, czytać log, naprawiać konfigurację. Oddawanie surowych kluczy prywatnych SSH LLM to zły pomysł: klucze trafiają do okien kontekstu, logów i transkrypcji. Proxy SSH rozwiązuje to: to on posiada dane uwierzytelniające, agent mówi tylko HTTP.\n\n## Model\n\n```\nLLM ──HTTPS──► Proxy SSH ──SSH──► maszyny docelowe\n                (posiada klucze,\n                 dziennik audytu,\n                 limity zapytań)\n```\n\nProxy udostępnia trwałe sesje przez prostą powierzchnię REST:\n\n| Endpoint | Cel |\n|---|---|\n| `POST /connect?target=vps1` | otwarcie sesji → `session_id` |\n| `POST /<sid>/exec` `{command, timeout}` | wykonanie polecenia (async) → `exec_id` |\n| `GET /<sid>/exec/<exec_id>` | odpytanie o wyjście |\n| Endpointy SFTP | wysyłanie/pobieranie plików, `ls`, `mkdir`, `rm` |\n\nUwierzytelnianie to token Bearer — ten sam wzorzec, co w każdej innej API, którą używasz.\n\n## Wzorzec wykonania\n\n```bash\n# 1. połącz raz, używaj sesji przez całe zadanie\nSID=$(curl -s -H \"Authorization: Bearer $KEY\" \\\n  \"https://ssh-proxy.example/connect?target=vps1\" | jq -r .session_id)\n\n# 2. wykonaj polecenie\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. odpytaj o wynik\ncurl -s -H \"Authorization: Bearer $KEY\" \"https://ssh-proxy.example/$SID/exec/$EID\"\n```\n\n## Reguły postępowania\n\n1. **Używaj sesji ponownie.** Łączenie na każde polecenie marnuje zasoby i uruchamia limity. Zapisz `session_id` (np. `/tmp/vps1_sid`) i daj mu heartbeat przed ponownym użyciem.\n2. **Nazywaj cele, nie odkrywaj ich.** Cele są predefiniowane (`vps1`, `pi`, …). Proxy jest jedynym źródłem prawdy — nigdy nie zaszywaj adresów IP w kodzie agenta.\n3. **Preferuj SFTP nad cat/heredoc shella dla plików.** Escapowanie danych binarnych przez `exec` psuje ładunki. Używaj dedykowanych endpointów wysyłania/pobierania.\n4. **Cytuj swoje polecenia.** Treść JSON jest parsowana dwukrotnie (HTTP + shell). Owiń zdalne polecenia w pojedyncze cudzysłowy i trzymaj je w jednej linii.\n5. **Zakładaj audyt.** Każdy exec trafia do dziennika audytu proxy — zachowuj się tak, jakby człowiek czytał wszystko (może).\n\n## Kiedy NIE używać exec\n\n- Czytanie ustrukturyzowanego stanu, który ma API (Docker, bazy danych, Mind API Synapse) — zawsze preferuj API nad parsowaniem wyjścia CLI.\n- Długotrwałe procesy interaktywne. `exec` to fire-and-forget z timeoutem; użyj `nohup` + pliku statusu na celu.\n- Cokolwiek destrukcyjnego bez wyraźnego polecenia. Proxy daje ci moc — człowiek daje ci pozwolenie.\n\n## Odzyskiwanie po błędach\n\n| Objaw | Rozwiązanie |\n|---|---|\n| 401 przy connect | token wygasł — odczytaj go ponownie z memory/settings, nigdy z transkrypcji |\n| sesja 404 | sesja wygasła (limit 24h) — połącz ponownie |\n| timeout exec | zwiększ `timeout` albo podziel polecenie; sprawdź obciążenie celu |\n| zepsuta zawartość pliku | użyłeś `exec` zamiast SFTP — przejdź na endpointy SFTP |\n","contentHtml":"<h1>Dostęp SSH przez proxy</h1>\n<p>Agenty muszą wykonywać polecenia na zdalnych maszynach — wdrażać kontener, czytać log, naprawiać konfigurację. Oddawanie surowych kluczy prywatnych SSH LLM to zły pomysł: klucze trafiają do okien kontekstu, logów i transkrypcji. Proxy SSH rozwiązuje to: to on posiada dane uwierzytelniające, agent mówi tylko HTTP.</p>\n<h2>Model</h2>\n<pre><code class=\"hljs language-plaintext\">LLM ──HTTPS──► Proxy SSH ──SSH──► maszyny docelowe\n                (posiada klucze,\n                 dziennik audytu,\n                 limity zapytań)</code></pre><p>Proxy udostępnia trwałe sesje przez prostą powierzchnię REST:</p>\n<table>\n<thead>\n<tr>\n<th>Endpoint</th>\n<th>Cel</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>POST /connect?target=vps1</code></td>\n<td>otwarcie sesji → <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>wykonanie polecenia (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>odpytanie o wyjście</td>\n</tr>\n<tr>\n<td>Endpointy SFTP</td>\n<td>wysyłanie/pobieranie plików, <code>ls</code>, <code>mkdir</code>, <code>rm</code></td>\n</tr>\n</tbody></table>\n<p>Uwierzytelnianie to token Bearer — ten sam wzorzec, co w każdej innej API, którą używasz.</p>\n<h2>Wzorzec wykonania</h2>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># 1. połącz raz, używaj sesji przez całe zadanie</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. wykonaj polecenie</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. odpytaj o wynik</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>Reguły postępowania</h2>\n<ol>\n<li><strong>Używaj sesji ponownie.</strong> Łączenie na każde polecenie marnuje zasoby i uruchamia limity. Zapisz <code>session_id</code> (np. <code>/tmp/vps1_sid</code>) i daj mu heartbeat przed ponownym użyciem.</li>\n<li><strong>Nazywaj cele, nie odkrywaj ich.</strong> Cele są predefiniowane (<code>vps1</code>, <code>pi</code>, …). Proxy jest jedynym źródłem prawdy — nigdy nie zaszywaj adresów IP w kodzie agenta.</li>\n<li><strong>Preferuj SFTP nad cat/heredoc shella dla plików.</strong> Escapowanie danych binarnych przez <code>exec</code> psuje ładunki. Używaj dedykowanych endpointów wysyłania/pobierania.</li>\n<li><strong>Cytuj swoje polecenia.</strong> Treść JSON jest parsowana dwukrotnie (HTTP + shell). Owiń zdalne polecenia w pojedyncze cudzysłowy i trzymaj je w jednej linii.</li>\n<li><strong>Zakładaj audyt.</strong> Każdy exec trafia do dziennika audytu proxy — zachowuj się tak, jakby człowiek czytał wszystko (może).</li>\n</ol>\n<h2>Kiedy NIE używać exec</h2>\n<ul>\n<li>Czytanie ustrukturyzowanego stanu, który ma API (Docker, bazy danych, Mind API Synapse) — zawsze preferuj API nad parsowaniem wyjścia CLI.</li>\n<li>Długotrwałe procesy interaktywne. <code>exec</code> to fire-and-forget z timeoutem; użyj <code>nohup</code> + pliku statusu na celu.</li>\n<li>Cokolwiek destrukcyjnego bez wyraźnego polecenia. Proxy daje ci moc — człowiek daje ci pozwolenie.</li>\n</ul>\n<h2>Odzyskiwanie po błędach</h2>\n<table>\n<thead>\n<tr>\n<th>Objaw</th>\n<th>Rozwiązanie</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>401 przy connect</td>\n<td>token wygasł — odczytaj go ponownie z memory/settings, nigdy z transkrypcji</td>\n</tr>\n<tr>\n<td>sesja 404</td>\n<td>sesja wygasła (limit 24h) — połącz ponownie</td>\n</tr>\n<tr>\n<td>timeout exec</td>\n<td>zwiększ <code>timeout</code> albo podziel polecenie; sprawdź obciążenie celu</td>\n</tr>\n<tr>\n<td>zepsuta zawartość pliku</td>\n<td>użyłeś <code>exec</code> zamiast SFTP — przejdź na endpointy 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"]}