Add sshpiper SSH reverse proxy documentation
This commit is contained in:
125
infra/sshpiper.md
Normal file
125
infra/sshpiper.md
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: sshpiper SSH 리버스 프록시
|
||||
updated: 2026-03-26
|
||||
tags: [infra, ssh, proxy, k3s]
|
||||
---
|
||||
|
||||
## 개요
|
||||
|
||||
sshpiper는 SSH를 위한 리버스 프록시. HTTP의 nginx처럼 SSH 연결을 중개하고 라우팅한다.
|
||||
- GitHub: https://github.com/tg123/sshpiper
|
||||
- 라이센스: MIT
|
||||
|
||||
## 배포 정보
|
||||
|
||||
K3s 클러스터(kr3 컨텍스트)에 Helm으로 설치 (2026-03-26)
|
||||
|
||||
| 항목 | 값 |
|
||||
|------|-----|
|
||||
| Namespace | sshpiper |
|
||||
| Chart | sshpiper/sshpiper 0.4.6 |
|
||||
| App | sshpiperd v1.5.0 |
|
||||
| Image | farmer1992/sshpiperd:v1.5.0 |
|
||||
| Plugin | kubernetes (CRD 기반) |
|
||||
| Service | NodePort 2222 → 31840 |
|
||||
| Helm repo | https://tg123.github.io/sshpiper-chart |
|
||||
|
||||
## 라우팅 구조
|
||||
|
||||
Pipe CRD (`pipes.sshpiper.com/v1beta1`)로 사용자명 기반 라우팅:
|
||||
|
||||
```
|
||||
ssh jp1@호스트:31840 → root@incus-jp1(100.109.123.1:22)
|
||||
```
|
||||
|
||||
## 인증 방식
|
||||
|
||||
### 패스워드 인증 (passthrough)
|
||||
|
||||
- 별도 키/시크릿 설정 불필요, Pipe CRD만 만들면 끝
|
||||
- 클라이언트가 입력한 패스워드를 sshpiper가 그대로 업스트림에 전달
|
||||
|
||||
### 키 기반 인증 (두 번 인증)
|
||||
|
||||
```
|
||||
유저(개인키A) → sshpiper(공개키A로 검증) → sshpiper(개인키S로 업스트림 접속) → 서버(공개키S 등록)
|
||||
```
|
||||
|
||||
- 키는 전달이 아니라 sshpiper가 자체 키로 업스트림에 별도 인증
|
||||
- `from.authorized_keys_data`: 유저의 공개키 등록
|
||||
- `to.private_key_secret`: sshpiper 전용 개인키 (K8s Secret)
|
||||
- 업스트림 서버의 `authorized_keys`에 sshpiper 공개키 등록
|
||||
- sshpiper 키 페어 하나로 모든 Pipe에서 공유 가능
|
||||
|
||||
| 구간 | 패스워드 방식 | 키 방식 |
|
||||
|------|-------------|---------|
|
||||
| 클라이언트 → sshpiper | 패스워드 통과(검증 안 함) | 유저 공개키로 검증 |
|
||||
| sshpiper → 서버 | 패스워드 그대로 전달 | sshpiper 전용 개인키로 별도 인증 |
|
||||
|
||||
## 지원 기능
|
||||
|
||||
SSH 세션을 통째로 프록시하므로 SSH로 할 수 있는 것 전부 지원:
|
||||
- 포트포워딩 (로컬 -L, 리모트 -R, 다이나믹 -D)
|
||||
- SCP, SFTP
|
||||
- 세션 녹화 (asciicast/typescript)
|
||||
|
||||
## 현재 Pipe 목록
|
||||
|
||||
- pipe-jp1: `jp1` → `root@100.109.123.1:22` (패스워드 인증)
|
||||
|
||||
## Pipe CRD 예시
|
||||
|
||||
### 패스워드 방식
|
||||
|
||||
```yaml
|
||||
apiVersion: sshpiper.com/v1beta1
|
||||
kind: Pipe
|
||||
metadata:
|
||||
name: pipe-jp1
|
||||
namespace: sshpiper
|
||||
spec:
|
||||
from:
|
||||
- username: jp1
|
||||
to:
|
||||
host: 100.109.123.1:22
|
||||
ignore_hostkey: true
|
||||
username: root
|
||||
```
|
||||
|
||||
### 키 방식
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: sshpiper-key
|
||||
namespace: sshpiper
|
||||
type: Opaque
|
||||
data:
|
||||
ssh-privatekey: <base64 인코딩된 개인키>
|
||||
---
|
||||
apiVersion: sshpiper.com/v1beta1
|
||||
kind: Pipe
|
||||
metadata:
|
||||
name: pipe-jp1
|
||||
namespace: sshpiper
|
||||
spec:
|
||||
from:
|
||||
- username: jp1
|
||||
authorized_keys_data: "ssh-ed25519 AAAA... user-pubkey"
|
||||
to:
|
||||
host: 100.109.123.1:22
|
||||
ignore_hostkey: true
|
||||
username: root
|
||||
private_key_secret:
|
||||
name: sshpiper-key
|
||||
```
|
||||
|
||||
## 관리 명령
|
||||
|
||||
```bash
|
||||
kubectl get pipes -n sshpiper # Pipe 목록
|
||||
kubectl get pipes -n sshpiper -o yaml # 상세 설정
|
||||
helm get values sshpiper -n sshpiper # Helm 설정값
|
||||
helm get manifest sshpiper -n sshpiper # 전체 매니페스트
|
||||
```
|
||||
Reference in New Issue
Block a user