docs: SSHPiper on Incus 설치 및 설정 문서
- 개요 및 아키텍처 - 등록된 파이프 목록 - Alias와 실제 접속 사용자 설명 - SSH 키 인증 설정 (백엔드/클라이언트/양방향) - 관리 명령어 및 트러블슈팅 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
297
README.md
Normal file
297
README.md
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
# SSHPiper on Incus
|
||||||
|
|
||||||
|
SSH 리버스 프록시 서버로, 사용자 이름 기반 라우팅을 통해 여러 백엔드 서버에 SSH 접속을 중계합니다.
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
| 항목 | 값 |
|
||||||
|
|------|-----|
|
||||||
|
| 컨테이너 이름 | `sshpiper` |
|
||||||
|
| 호스트 OS | Debian 12 (bookworm) |
|
||||||
|
| SSHPiper 버전 | 1.5.1 |
|
||||||
|
| 리스닝 포트 | 2222 |
|
||||||
|
| IP 주소 | 10.253.100.34 |
|
||||||
|
| 플러그인 | yaml |
|
||||||
|
|
||||||
|
## 아키텍처
|
||||||
|
|
||||||
|
```
|
||||||
|
클라이언트 → [호스트:2222] → [sshpiper 컨테이너:2222] → 백엔드 서버:22
|
||||||
|
proxy device sshpiperd
|
||||||
|
```
|
||||||
|
|
||||||
|
## 접속 방법
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 형식: ssh -p 2222 <alias>@<호스트>
|
||||||
|
ssh -p 2222 baserow@localhost
|
||||||
|
ssh -p 2222 caddy@localhost
|
||||||
|
ssh -p 2222 k8s@localhost
|
||||||
|
```
|
||||||
|
|
||||||
|
## 등록된 파이프
|
||||||
|
|
||||||
|
| Alias | 백엔드 서버 | 대상 사용자 |
|
||||||
|
|-------|------------|-------------|
|
||||||
|
| `baserow` | 10.253.103.104 | root |
|
||||||
|
| `caddy` | 10.253.103.139 | root |
|
||||||
|
| `crowdsec` | 10.253.100.240 | root |
|
||||||
|
| `hey` | 10.253.103.80 | root |
|
||||||
|
| `k8s` | 10.253.103.124 | root |
|
||||||
|
| `log-collector`, `log` | 10.253.100.55 | root |
|
||||||
|
| `tor`, `tor-server` | 10.253.101.178 | root |
|
||||||
|
| `vaultwarden`, `vault` | 10.253.100.48 | root |
|
||||||
|
|
||||||
|
## Alias와 실제 접속 사용자
|
||||||
|
|
||||||
|
현재 설정에서는 모든 파이프가 `to.username: root`로 되어 있어서, **어떤 alias로 접속하든 백엔드 서버에는 root로 접속**합니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
ssh -p 2222 baserow@host → root@10.253.103.104
|
||||||
|
ssh -p 2222 caddy@host → root@10.253.103.139
|
||||||
|
ssh -p 2222 k8s@host → root@10.253.103.124
|
||||||
|
```
|
||||||
|
|
||||||
|
- `from.username`: sshpiper에 접속할 때 사용하는 **라우팅용 alias**
|
||||||
|
- `to.username`: 실제 백엔드 서버에 접속하는 **계정**
|
||||||
|
|
||||||
|
### 다른 사용자로 접속하려면
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# 예: deploy 사용자로 접속
|
||||||
|
- from:
|
||||||
|
- username: "baserow"
|
||||||
|
to:
|
||||||
|
host: 10.253.103.104:22
|
||||||
|
username: deploy # root 대신 다른 계정
|
||||||
|
ignore_hostkey: true
|
||||||
|
|
||||||
|
# 또는 원래 입력한 사용자 이름 유지 (username 생략)
|
||||||
|
- from:
|
||||||
|
- username_regex: ".*" # 모든 사용자
|
||||||
|
to:
|
||||||
|
host: 10.253.103.104:22
|
||||||
|
# username 생략 → 클라이언트가 입력한 사용자명 그대로 사용
|
||||||
|
ignore_hostkey: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## SSH 키 인증
|
||||||
|
|
||||||
|
SSHPiper는 비밀번호 인증 외에 SSH 키 인증도 지원합니다.
|
||||||
|
|
||||||
|
### 인증 방향
|
||||||
|
|
||||||
|
```
|
||||||
|
클라이언트 ──[①]──→ sshpiper ──[②]──→ 백엔드 서버
|
||||||
|
from.authorized_keys to.private_key
|
||||||
|
```
|
||||||
|
|
||||||
|
| 방향 | 설정 | 설명 |
|
||||||
|
|------|------|------|
|
||||||
|
| ① 클라이언트 → sshpiper | `from.authorized_keys` | 클라이언트 공개키 검증 |
|
||||||
|
| ② sshpiper → 백엔드 | `to.private_key` | 백엔드 접속용 개인키 |
|
||||||
|
|
||||||
|
### 백엔드 키 인증 설정 (sshpiper → 백엔드)
|
||||||
|
|
||||||
|
클라이언트는 비밀번호로 접속하고, sshpiper가 백엔드에는 키로 접속하는 방식입니다.
|
||||||
|
|
||||||
|
**1. sshpiper에서 키 생성**
|
||||||
|
```bash
|
||||||
|
incus exec sshpiper -- ssh-keygen -t ed25519 -f /etc/sshpiper/id_backend -N ''
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. 백엔드 서버에 공개키 등록**
|
||||||
|
```bash
|
||||||
|
# 공개키 확인
|
||||||
|
incus exec sshpiper -- cat /etc/sshpiper/id_backend.pub
|
||||||
|
|
||||||
|
# 백엔드 서버의 authorized_keys에 추가
|
||||||
|
incus exec <백엔드> -- bash -c 'echo "<공개키내용>" >> /root/.ssh/authorized_keys'
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. pipes.yaml 설정**
|
||||||
|
```yaml
|
||||||
|
- from:
|
||||||
|
- username: "myserver"
|
||||||
|
to:
|
||||||
|
host: 10.x.x.x:22
|
||||||
|
username: root
|
||||||
|
private_key: /etc/sshpiper/id_backend # 백엔드 접속용 개인키
|
||||||
|
ignore_hostkey: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 클라이언트 키 인증 설정 (클라이언트 → sshpiper)
|
||||||
|
|
||||||
|
특정 클라이언트 공개키만 허용하는 방식입니다.
|
||||||
|
|
||||||
|
**1. 허용할 공개키 파일 생성**
|
||||||
|
```bash
|
||||||
|
# 클라이언트의 공개키를 sshpiper에 등록
|
||||||
|
incus exec sshpiper -- bash -c 'cat > /etc/sshpiper/authorized_keys_myserver << EOF
|
||||||
|
ssh-ed25519 AAAA... user@client
|
||||||
|
EOF'
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. pipes.yaml 설정**
|
||||||
|
```yaml
|
||||||
|
- from:
|
||||||
|
- username: "myserver"
|
||||||
|
authorized_keys:
|
||||||
|
- /etc/sshpiper/authorized_keys_myserver # 허용할 클라이언트 공개키
|
||||||
|
to:
|
||||||
|
host: 10.x.x.x:22
|
||||||
|
username: root
|
||||||
|
private_key: /etc/sshpiper/id_backend
|
||||||
|
ignore_hostkey: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 양방향 키 인증 (가장 안전)
|
||||||
|
|
||||||
|
클라이언트도 키로, 백엔드도 키로 접속하는 방식입니다.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- from:
|
||||||
|
- username: "secure-server"
|
||||||
|
authorized_keys:
|
||||||
|
- /etc/sshpiper/authorized_keys_secure # 클라이언트 공개키
|
||||||
|
to:
|
||||||
|
host: 10.x.x.x:22
|
||||||
|
username: root
|
||||||
|
private_key: /etc/sshpiper/id_secure # 백엔드용 개인키
|
||||||
|
ignore_hostkey: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 인라인 키 데이터
|
||||||
|
|
||||||
|
파일 경로 대신 base64 인코딩된 키를 직접 설정할 수도 있습니다.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- from:
|
||||||
|
- username: "inline-example"
|
||||||
|
authorized_keys_data:
|
||||||
|
- "c3NoLWVkMjU1MTkgQUFBQS4uLg==" # base64 인코딩된 공개키
|
||||||
|
to:
|
||||||
|
host: 10.x.x.x:22
|
||||||
|
username: root
|
||||||
|
private_key_data: "LS0tLS1CRUdJTi4uLg==" # base64 인코딩된 개인키
|
||||||
|
ignore_hostkey: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## 설정 파일
|
||||||
|
|
||||||
|
### 파이프 설정 (`/etc/sshpiper/pipes.yaml`)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "1.0"
|
||||||
|
pipes:
|
||||||
|
- from:
|
||||||
|
- username: "서버별칭"
|
||||||
|
to:
|
||||||
|
host: 10.x.x.x:22
|
||||||
|
username: root
|
||||||
|
ignore_hostkey: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Systemd 서비스 (`/etc/systemd/system/sshpiper.service`)
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=SSHPiper - SSH Reverse Proxy
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/sshpiperd -l 0.0.0.0 -p 2222 -i /etc/sshpiper/host_key /usr/local/bin/plugins/yaml --config /etc/sshpiper/pipes.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
## 관리 명령어
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 서비스 상태 확인
|
||||||
|
incus exec sshpiper -- systemctl status sshpiper
|
||||||
|
|
||||||
|
# 서비스 재시작
|
||||||
|
incus exec sshpiper -- systemctl restart sshpiper
|
||||||
|
|
||||||
|
# 로그 확인
|
||||||
|
incus exec sshpiper -- journalctl -u sshpiper -f
|
||||||
|
|
||||||
|
# 설정 파일 편집
|
||||||
|
incus exec sshpiper -- nano /etc/sshpiper/pipes.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## 새 서버 추가
|
||||||
|
|
||||||
|
1. `pipes.yaml`에 새 파이프 추가:
|
||||||
|
```yaml
|
||||||
|
- from:
|
||||||
|
- username: "새서버"
|
||||||
|
to:
|
||||||
|
host: 10.x.x.x:22
|
||||||
|
username: root
|
||||||
|
ignore_hostkey: true
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 서비스 재시작:
|
||||||
|
```bash
|
||||||
|
incus exec sshpiper -- systemctl restart sshpiper
|
||||||
|
```
|
||||||
|
|
||||||
|
## 사용 가능한 플러그인
|
||||||
|
|
||||||
|
| 플러그인 | 설명 |
|
||||||
|
|---------|------|
|
||||||
|
| `yaml` | YAML 파일 기반 라우팅 (현재 사용 중) |
|
||||||
|
| `docker` | Docker 컨테이너 라우팅 |
|
||||||
|
| `kubernetes` | Kubernetes Pod 라우팅 |
|
||||||
|
| `workingdir` | 작업 디렉토리 기반 라우팅 |
|
||||||
|
| `fixed` | 고정 대상 라우팅 |
|
||||||
|
| `failtoban` | 실패 시 차단 기능 |
|
||||||
|
| `username-router` | 사용자 이름 기반 라우팅 |
|
||||||
|
|
||||||
|
## Incus 프록시 설정
|
||||||
|
|
||||||
|
컨테이너에 `proxy2222` 디바이스가 설정되어 호스트의 2222 포트가 컨테이너의 2222 포트로 포워딩됩니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 프록시 설정 확인
|
||||||
|
incus config device show sshpiper
|
||||||
|
|
||||||
|
# 프록시 추가 (이미 설정됨)
|
||||||
|
incus config device add sshpiper proxy2222 proxy listen=tcp:0.0.0.0:2222 connect=tcp:127.0.0.1:2222
|
||||||
|
```
|
||||||
|
|
||||||
|
## 트러블슈팅
|
||||||
|
|
||||||
|
### 접속 불가 시
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 서비스 상태 확인
|
||||||
|
incus exec sshpiper -- systemctl status sshpiper
|
||||||
|
|
||||||
|
# 포트 리스닝 확인
|
||||||
|
incus exec sshpiper -- ss -tlnp | grep 2222
|
||||||
|
|
||||||
|
# 프로세스 확인
|
||||||
|
incus exec sshpiper -- ps aux | grep sshpiper
|
||||||
|
```
|
||||||
|
|
||||||
|
### 로그 확인
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 실시간 로그
|
||||||
|
incus exec sshpiper -- journalctl -u sshpiper -f
|
||||||
|
|
||||||
|
# 최근 에러
|
||||||
|
incus exec sshpiper -- journalctl -u sshpiper -p err --since "1 hour ago"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 참고
|
||||||
|
|
||||||
|
- [SSHPiper GitHub](https://github.com/tg123/sshpiper)
|
||||||
|
- [SSHPiper 문서](https://github.com/tg123/sshpiper/wiki)
|
||||||
Reference in New Issue
Block a user