설계 원칙 — 다중 사용자 동시 사용 시에도 서버에 영향 없음
각 사용자 세션은 독립된 임시 SSH config와 고유 프로세스로 완전 격리됩니다.
KeepAlive · 터널 자동 갱신 · 지수 백오프 재시도로 불필요한 재연결 시도를 최소화하여
서버에 누적 부하가 발생하지 않도록 설계되어 있습니다.
세션 격리
완전 독립
사용자마다 고유 config — 동시 접속 충돌 없음
Keepalive
15s
방화벽 타임아웃 방지 — 끊김 없는 장시간 작업
터널 갱신
5분 자동
장애 감지 즉시 복구 — 사용자 개입 불필요
자동 재시도
2× 백오프
서버 과부하 없이 2s → 4s 지수 간격으로 재연결
01
ProxyJump 3-hop 터널 구조
접속 경로 — 로컬 → InfluxDB
로컬 PC
Windows
Origin
PEM 인증
공인 IP
공인 IP
pub_bastion
공인 IP
Hop 1
ProxyJump
VPC 내부
VPC 내부
internal
VPC 사설 IP
Hop 2
ProxyJump
VPC 내부
VPC 내부
target
InfluxDB
Hop 3
StrictHostKeyChecking no 이유: 대상 서버가 AWS VPC 내부 사설 IP로 공개 인증서가 없음.
MITM 위험은 VPC 보안그룹 + 3-hop ProxyJump 구조로 대체 완화.
UserKnownHostsFile=NUL로 known_hosts 오염 차단.
02
SSH Config 전역 설정값
Host * 블록 — 모든 연결에 적용
사용자별 독립 임시 파일 · 앱 종료 시 자동 삭제
# ── 연결 안정성 ──────────────────────────────────────────── ServerAliveInterval 15 # 15s keepalive → AWS 방화벽 idle 타임아웃 방지 ServerAliveCountMax 2 # 2회 무응답 시 연결 종료 (좀비 방지) TCPKeepAlive yes # OS TCP 레이어 keepalive (보조) ConnectTimeout 10 # 연결 시도 타임아웃 ConnectionAttempts 1 # 재시도는 Python 레이어에서 제어 Compression yes # SSH 레벨 압축 — WAN 대역폭 절감 # ── 보안 ─────────────────────────────────────────────────── BatchMode yes # 패스워드 프롬프트 차단 StrictHostKeyChecking no # VPC 사설 IP 대상 (ProxyJump로 MITM 완화) UserKnownHostsFile NUL # known_hosts 오염 방지 IdentitiesOnly yes # 지정 PEM 키만 사용, ssh-agent 개입 차단 LogLevel ERROR # DEBUG 시 민감 정보 노출 방지 CheckHostIP no # VPC 내부 — IP 역방향 DNS 체크 불필요 ControlMaster no # 멀티플렉싱 비활성 (동시 작업 소켓 충돌 방지) # ── 명령 실행 플래그 ──────────────────────────────────────── -n # stdin → /dev/null (비대화형 백그라운드) -o ClearAllForwardings=yes # 불필요한 포트포워딩 차단
| 옵션 | 값 | 목적 | 없을 때 증상 |
|---|---|---|---|
ServerAliveInterval | 15s | AWS 방화벽 idle 세션 차단 방지 | 장시간 작업 중 연결 끊김 |
ServerAliveCountMax | 2 | 좀비 프로세스 조기 종료 | SSH 프로세스 무한 대기 |
BatchMode | yes | 패스워드 프롬프트 원천 차단 | GUI 앱이 프롬프트에 걸려 멈춤 |
ConnectTimeout | 10s | 빠른 실패 감지 | 연결 시도가 수십 초간 점유 |
Compression | yes | WAN 환경 전송 속도 향상 | 대용량 LP 파일 업로드 속도 저하 |
ControlMaster | no | 소켓 충돌 방지 | 동시 SSH 작업 시 세션 충돌 |
03
서버 연결 안정성 조치
🔄
터널 자동 갱신 — 5분 주기
연결 실패 시 즉시, 또는 마지막 갱신으로부터 300초 경과 시 SSH config를 재생성하고 터널을 재수립.
↩️
지수 백오프 자동 재시도
일시적 오류 감지 시 최대 2회 재시도. 대기 시간: 2s → 4s.
감지 키워드:
감지 키워드:
connection timed out · broken pipe · reset by peer · no route to host
🧩
프로세스 추적 & 강제 종료
실행 중인 모든 SSH/SCP 프로세스를 Set으로 추적. 작업 취소·앱 종료 시 순차 정리하며, 인터프리터 비정상 종료 시에도 종료 훅을 통해 보장.
🧹
임시 config 파일 자동 정리
앱 시작 시 1시간 이상 된 임시 config 파일 자동 삭제. config 교체 시 이전 파일도 즉시 삭제 (atomic swap).
📡
OFFLINE 감지 & RECONNECTING 상태 표시
연결 실패 시 사이드바에 즉시
OFFLINE 표시. 재시도 중에는 RECONNECTING으로 전환 — 사용자가 서버 상태를 실시간 인지.04
보안 조치
PEM 키 파일 권한 자동 교정
| 플랫폼 | 적용 조치 |
|---|---|
| Windows | icacls /inheritance:r /grant:r USER:R상속 제거 + 소유자 읽기 전용 |
| Linux/macOS | chmod 400소유자 읽기 전용 |
OpenSSH는 PEM 파일 권한이 너무 넓으면 연결을 거부. 수동 복사한 키는 권한 확인 필요.
비대화형 실행 보안 플래그
| 플래그 | 역할 |
|---|---|
BatchMode=yes | 패스워드·OTP 프롬프트 원천 차단 |
IdentitiesOnly=yes | ssh-agent 키 개입 차단, 지정 PEM만 사용 |
LogLevel=ERROR | DEBUG 로그의 민감 정보 노출 방지 |
-n 플래그 | stdin → /dev/null, 입력 하이재킹 차단 |
ClearAllForwardings | 불필요한 포트포워딩 차단 |
config 파일 보안
| 조치 | 내용 |
|---|---|
| 임시 파일 | 시스템 임시 디렉토리에만 기록 — 소스 디렉토리에 config가 남지 않음 |
| 유니크 ID | 사용자·세션마다 고유 ID 자동 부여 — 다중 사용자 동시 접속 시 config 충돌 없음 |
| Unix 권한 | chmod 0600 — Linux/macOS에서 소유자만 읽기/쓰기 |
| Atomic Swap | 새 config 생성 성공 후에만 경로 교체, 이전 파일 즉시 삭제 |
| NUL 디바이스 | 절대 경로 사용 — 현재 디렉토리에 nul 파일 생성 방지 (Windows) |
05
프로세스 생명주기 관리 — 세션 완전 격리
SSH/SCP 바이너리 우선순위
크로스플랫폼 자동 탐지
1. C:/Windows/System32/OpenSSH/ssh.exe # 내장 OpenSSH 2. PATH 탐색 (shutil.which) # Git Bash 등 3. "ssh" 폴백
Windows System32 OpenSSH 우선
Linux/macOS PATH 탐색
cp949 인코딩 오류 방지 — 바이너리 모드 stdout
Subprocess 추적 & 정리
threading.Lock · atexit
| 상황 | 동작 |
|---|---|
| 작업 중 취소 | terminate → wait(2s) → kill 순으로 정리 |
| 앱 정상 종료 | 종료 훅 등록 — 닫힐 때 자동 정리 보장 |
| 비정상 종료 | 인터프리터 종료 직전에도 훅 실행 보장 |
| 스트리밍 업로드 | stdin으로 데이터 주입 — 메모리 효율 전송 |
| 콘솔 창 숨김 | Windows cmd 팝업 방지 subprocess 플래그 |
06
PEM 키 관리 규칙
키 파일 네이밍 규칙 — 환경별 자동 탐지
~/Documents/_tunnel/pem/
| 환경 | 키 종류 | 파일명 키워드 (우선순위 순) | 폴백 |
|---|---|---|---|
| PRD / PRD2 | pub_bastion | SIT_DEV + Bastion → Bastion |
첫 번째 파일 |
| internal | SIT_PRD + Bastion → prd |
pub_bastion 키 | |
| target | SIT_PRD + DBSUB → DBSUB + Virginia → influx |
internal 키 | |
| DEV | internal | SIT_DEV + Bastion → dev |
pub_bastion 키 |
| target | SIT_DEV + DBSUB → DBSUB + Virginia → influx |
internal 키 |
허용 확장자:
.pem, .key 만 인식. 파일명에 환경(PRD/DEV)과 역할(Bastion/DBSUB) 키워드를 반드시 포함할 것.
07
데이터 전송 최적화 — 압축 파이프라인
LP 파일 전송 시 gzip 압축을 적용하여 네트워크 사용량을 60~80% 절감합니다.
업로드·다운로드 모두 파이프라인 방식으로 처리해 서버에 임시 파일이 남지 않으며,
Auto-Throttle이 서버 부하를 실시간 감시하여 다중 사용자 동시 작업 시에도 서버가 과부하되지 않습니다.
LP 업로드 파이프라인
로컬 → InfluxDB
단일 파일 스트리밍
LP 파일
로컬
gzip
SSH stdin
스트림
gunzip
InfluxDB
직접 적재
배치 파일 청킹
LP ×N
500MB 청크
tar.gz
SCP 전송
배치 격리
tar -xz
InfluxDB
순차 적재
데이터 추출 파이프라인
InfluxDB → 로컬
실시간 스트리밍 압축
InfluxDB
쿼리 실행
gzip -1
SSH Popen
스트림 수신
GzipFile
로컬 CSV
즉시 저장
서버에 임시 파일 없음 — 쿼리 결과가 gzip -1 (속도 우선) 으로 즉시 압축되어 스트리밍 전달
Auto-Throttle — 서버 부하 감시
배치 전송 전 자동 확인
| 지표 | 허용 임계값 | 적용 작업 | 초과 시 동작 |
|---|---|---|---|
| CPU Load avg | < 4.0 | 업로드 + 추출 | 15s 대기 후 재확인 조건 충족까지 반복 |
| 가용 메모리 | > 500 MB | 업로드 + 추출 | |
| Influx 메모리 | < 30 % | 업로드만 | |
| Influx 메모리 | < 60 % | 추출만 | |
| Disk I/O Wait | < 15 % | 추출만 |
* Disk I/O Wait:
iostat -c 1 2 로 측정 (추출 전용)
여러 명이 동시에 업로드·추출해도 서버 과부하 없음 — 각 작업이 서버 상태를 실시간 확인하고 자동 양보
압축 적용 옵션 요약
| 구분 | 방식 | 서버 명령 |
|---|---|---|
| LP 업로드 단일 |
gzip 스트리밍 | gunzip -c | influx -import |
| LP 업로드 배치 |
tar.gz 청킹 | tar -xzf | influx -import |
| 데이터 추출 | gzip -1 스트림 | influx -execute | gzip -1 |
| SSH 레이어 | Compression yes | SSH Config 전역 적용 |
| CPU 양보 | nice -n 15 | 서버 측 모든 명령에 적용 |
PRD 스마트 노드 선택
Node 140 vs 170
작업 시작
PRD 환경
CPU load
측정
측정
Node 140
load 측정
Node 170
load 측정
낮은 쪽
선택
선택
최적 노드
자동 배정
작업 시작 전 두 노드의 CPU loadavg를 비교해 부하가 낮은 노드로 자동 라우팅 — 특정 노드 쏠림 방지
서버 측 프로세스 격리
다중 사용자 안전
| 조치 | 내용 |
|---|---|
nice -n 15 |
서버 측 모든 명령(gunzip, influx, tar, gzip, sed)에 낮은 우선순위 적용 — 기타 서비스 CPU 점유에 영향 없음 |
pkill -u $(whoami) |
작업 취소 시 본인 소유 프로세스만 종료 — 다른 사용자 influx/gzip 프로세스 절대 건드리지 않음 |
| 세션별 독립 경로 | 사용자마다 고유 임시 디렉토리 사용 — 배치 파일 충돌 없음 |
N명이 동시 작업해도 서로 간섭 없음 — 각 세션은 자신의 프로세스만 관리, 서버 공유 자원 충돌 원천 차단
08
연결 장애 점검 순서
1
PEM 파일 존재 확인
지정 폴더에 .pem / .key 파일이 있는지 확인 후 앱 재시작
2
PEM 파일 권한 확인
권한이 너무 넓으면 OpenSSH 거부 — 앱 로그에서 자동 교정 여부 확인
3
OpenSSH 설치 확인
Windows 설정 → 선택적 기능 → OpenSSH 클라이언트 설치
4
네트워크 / VPN 상태 확인
pub_bastion 공인 IP가 사내 방화벽에서 열려 있는지 확인
5
5분 이상 OFFLINE 지속 시
앱 재시작 — 터널 즉시 강제 갱신 트리거
6
Verbose 로그로 원인 추적
SSH verbose 모드 활성화 — 상세 연결 로그로 정확한 실패 지점 확인