SSH 속도 향상: 연결 다중화를 통한 세션 가속화

연결 다중화를 사용하여 거의 즉각적인 SSH 연결을 구현하세요. 이 포괄적인 가이드는 중요한 SSH 클라이언트 지시문인 `ControlMaster`, `ControlPath` 및 강력한 `ControlPersist`를 구성하는 방법을 자세히 설명합니다. 후속 세션의 인증 오버헤드를 크게 줄이는 단일 지속 '마스터' 연결을 설정하는 방법을 알아보세요. 전역 및 호스트별 구성, 확인 기술, 더 빠른 워크플로를 위한 필수 문제 해결 팁에 대한 실용적인 예제가 포함되어 있습니다.

SSH 속도 향상: 연결 다중화를 통한 세션 가속화

SSH 연결 다중화를 사용하면 두 번째 명령이 기존 인증된 연결을 재사용할 수 있으므로 반복적인 SSH 명령이 훨씬 빨라집니다. ssh host uptime을 실행한 다음 ssh host df -h를 실행하고 동일한 호스트에 scp 파일을 실행하는 경우 첫 번째 연결만 전체 핸드셰이크 및 인증 경로가 필요합니다.

이는 많은 짧은 세션을 여는 관리자, 개발자 및 자동화 도구에 특히 유용합니다. 마법이 아니며 느린 원격 명령이 더 빨리 실행되지는 않습니다. 반복적인 설정 비용을 제거합니다.

SSH 연결 오버헤드 이해

모든 표준 SSH 세션은 기본적으로 새로운 TCP 연결을 설정하고 전체 핸드셰이크를 수행합니다. 이 프로세스에는 다음이 포함됩니다.

  1. 키 교환: 공유 비밀 및 암호화 알고리즘 결정.
  2. 인증: 사용자 자격 증명(암호, 키 파일 또는 2단계 토큰) 확인.
  3. 세션 설정: 터미널 또는 명령 채널 초기화.

이 설정 비용은 가까운 LAN에서는 작지만 대기 시간이 긴 링크, VPN, 배스천 호스트 또는 하드웨어 지원 키 또는 다단계 프롬프트가 필요한 계정에서는 매우 두드러집니다. 연결 다중화는 마스터 연결을 열어 두고 새 세션을 통해 라우팅하여 해당 작업의 대부분을 반복하지 않도록 합니다.

다중화 작동 방식

연결 다중화는 로컬 Unix 도메인 소켓(로컬 시스템의 파일)을 사용하여 마스터 SSH 프로세스와 새 슬레이브 프로세스 간에 통신합니다.

  • 마스터 연결: 실행하는 첫 번째 SSH 명령이 지속적인 연결을 생성하고 통신 소켓을 설정합니다.
  • 제어 경로: 후속 세션에서 마스터를 확인하고 연결하는 데 사용하는 지정된 로컬 파일 경로(소켓)입니다.
  • 재사용된 연결: 동일한 유효 호스트, 사용자 및 포트를 대상으로 하는 후속 SSH 명령은 로컬 소켓을 통해 마스터에 연결하여 새로운 전체 SSH 설정을 피합니다.

주요 구성 지시문

연결 다중화를 활성화하려면 일반적으로 사용자별 구성 파일(~/.ssh/config) 내에서 SSH 클라이언트 설정을 구성합니다. 세 가지 중요한 지시문은 ControlMaster, ControlPathControlPersist입니다.

1. ControlMaster

이 지시문은 SSH가 마스터 연결을 생성하려고 시도해야 하는지 아니면 기존 연결을 재사용해야 하는지 지정합니다.

설명
no (기본값) 표준 단일 연결 모드.
yes 세션이 마스터가 되고 슬레이브를 기다리도록 강제합니다. (오늘날 단독으로는 거의 사용되지 않음).
auto 선호되는 설정. 마스터 연결이 있으면 재사용하고, 그렇지 않으면 새 마스터 연결을 시작합니다.

대부분의 구성에서 ControlMaster auto는 실용적인 기본값입니다.

2. ControlPath

통신에 사용되는 Unix 도메인 소켓 파일의 경로입니다. 이 경로는 세션이 제어 채널을 혼합하지 않도록 원격 호스트, 사용자 및 포트 조합별로 고유해야 합니다.

경로 내에서 변수를 사용하면 고유성이 보장됩니다.

변수 설명
%r 원격 사용자 이름
%h 원격 호스트 이름
%p 원격 포트

예제 ControlPath:

ControlPath ~/.ssh/sockets/%r@%h:%p

팁: 이러한 소켓 전용 디렉토리를 만들고(mkdir -p ~/.ssh/sockets) 보안 권한을 설정했는지 확인하세요(chmod 700 ~/.ssh/sockets).

3. ControlPersist

이 지시문은 초기 명령이 완료된 후 마스터 연결이 얼마나 오래 열려 있어야 하는지 지정합니다.

ControlPersist(OpenSSH 5.6에서 도입) 이전에는 마스터 연결이 터미널 세션에 연결된 상태로 유지되어야 했습니다. ControlPersist를 사용하면 마스터 프로세스가 분리되어 백그라운드에서 활성 상태로 유지됩니다.

설명
no 터미널이 닫히면 마스터 연결이 즉시 닫힙니다.
yes 마스터 연결이 무기한 유지됩니다(수동으로 닫거나 시스템이 재부팅될 때까지).
시간 값 기간을 지정합니다(예: 5m은 5분, 1h는 1시간). 이 비활성 기간 후에 연결이 닫힙니다.

일반적인 작업 세션의 경우 ControlPersist 10m 또는 15m으로 설정하는 것이 합리적인 시작점입니다. 공유 워크스테이션이나 민감한 점프 호스트에서는 더 짧은 값을 사용하세요.

~/.ssh/config의 실제 구현

아래는 SSH 클라이언트 구성 파일에서 다중화를 구성하는 방법을 보여주는 예제입니다.

예제 1: 전역 구성

이 구성은 표준 포트 22에서 실행 중이라고 가정하고 연결하는 모든 원격 호스트에 연결 다중화를 적용합니다.

# 모든 호스트(*)에 대한 구성
Host *
    # 연결 재사용 또는 시작 활성화
    ControlMaster auto

    # 마지막 세션이 닫힌 후 15분 동안 연결 유지
    ControlPersist 15m

    # 사용자, 호스트 및 포트를 기반으로 고유성을 보장하는 소켓 경로 정의
    ControlPath ~/.ssh/sockets/%r@%h:%p

    # 선택 사항: 일부 저대역폭 링크에서 유용하지만 항상 더 빠른 것은 아님
    Compression yes

예제 2: 호스트별 구성

자주 액세스하는 호스트 또는 그룹으로 다중화를 제한하는 것이 더 나은 방법인 경우가 많습니다.

# 'prod-*'와 일치하는 호스트에 대한 특정 구성
Host prod-*
    HostName %h.example.com
    ControlMaster auto
    ControlPersist 5m
    ControlPath ~/.ssh/sockets/%r@%h:%p

# 점프 호스트에 대한 특정 구성(더 긴 지속성이 필요할 수 있음)
Host jumpbox
    ControlMaster auto
    ControlPersist 1h
    ControlPath ~/.ssh/sockets/%r@%h:%p

사용, 확인 및 관리

1. 속도 향상 확인

time 명령을 사용하여 성능 향상을 쉽게 확인할 수 있습니다.

첫 번째 연결:

$ time ssh myhost exit

real    0m1.234s
user    0m0.045s
sys     0m0.015s

마스터가 활성화된 후속 연결:

$ time ssh myhost exit

real    0m0.045s
user    0m0.005s
sys     0m0.003s

2. 마스터 연결 상태 확인

마스터 연결이 설정되면 지정된 ControlPath에 소켓 파일이 존재합니다. -O(제어 옵션) 플래그를 사용하여 연결 상태를 확인할 수 있습니다.

# myhost에 대한 연결이 활성 상태인지 확인
ssh -O check myhost

성공하면 출력에 소켓 연결이 열려 있음이 확인됩니다.

3. 마스터 연결 종료

지속적인 마스터 연결을 즉시 닫아야 하는 경우(예: 인증 자격 증명이 변경되었거나 새 구성을 테스트해야 하는 경우) exit 제어 옵션을 사용하세요.

# myhost에 대한 마스터 연결 종료
ssh -O exit myhost

이 명령은 마스터 프로세스가 정상적으로 종료되도록 지시합니다. 그러면 후속 세션이 새 마스터 연결을 생성해야 합니다.

더 안전한 기본 구성

최신 OpenSSH 클라이언트에서는 %C%r, %h%p를 수동으로 결합하는 것보다 더 나은 ControlPath 토큰인 경우가 많습니다. 연결 세부 정보의 해시로 확장되어 긴 Unix 소켓 경로와 호스트 이름의 어색한 문자를 방지합니다.

Host *
    ControlMaster auto
    ControlPersist 10m
    ControlPath ~/.ssh/sockets/%C

Unix 도메인 소켓에는 플랫폼별 제한이 있으므로 소켓 경로 길이가 중요합니다. ~/.ssh/sockets/[email protected]:2222와 같은 긴 경로는 일부 시스템에서 실패할 수 있습니다. 제어 경로가 너무 길다는 오류가 표시되면 %C로 전환하세요.

또한 이 구성을 사용하기 전에 소켓 디렉토리가 있는지 확인하세요.

mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/sockets

다중화를 피해야 하는 경우

모든 상황에 대해 맹목적으로 다중화를 활성화하지 마십시오. 몇 가지 경우 주의가 필요합니다.

  • 계정 권한 변경: 세션 중에 그룹 구성원, 강제 명령 또는 서버측 계정 정책이 변경되면 마스터가 닫힐 때까지 재사용된 연결이 새 상태를 반영하지 않을 수 있습니다.
  • 배스천 및 점프 호스트 문제 해결: 연결 실패를 테스트할 때 각 명령이 새 경로를 생성하는지 확인하려면 다중화를 비활성화하세요.
  • 매우 민감한 호스트: 지속적인 마스터 연결은 ControlPersist가 만료될 때까지 로컬 계정에서 인증된 채널을 사용할 수 있도록 유지합니다. 일반적으로 올바른 권한이 있는 개인 워크스테이션에서는 괜찮지만 모든 보안 정책에 적합하지 않을 수 있습니다.

한 명령의 경우 다음과 같이 재사용을 비활성화합니다.

ssh -o ControlMaster=no -o ControlPath=none user@host

자동화 도구와의 다중화

Ansible, rsync, Git over SSH 및 배포 스크립트는 종종 많은 짧은 세션을 열기 때문에 다중화의 이점을 누릴 수 있습니다. 특히 Ansible의 경우 SSH 인수는 일반적으로 ansible.cfg에 있습니다.

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=10m -o ControlPath=~/.ssh/sockets/%C

자동화가 CI에서 실행되는 경우 실행기 수명 주기에 대해 생각하세요. 수명이 짧은 CI 작업은 작업 영역이 작업 후에 사라지기 때문에 많은 이점을 얻지 못할 수 있습니다. 수명이 긴 배포 호스트는 많은 이점을 얻을 수 있지만 정리 및 예측 가능한 권한도 필요합니다. 보안 영향을 완전히 이해하고 개인 하위 디렉토리를 사용하지 않는 한 /tmp와 같은 공유 세계 쓰기 가능 디렉토리에 제어 소켓을 두지 마세요.

rsync의 경우 워크플로가 동일한 호스트에 대해 여러 개의 개별 rsync 또는 ssh 명령을 실행할 때 다중화가 가장 도움이 됩니다.

rsync -az ./release/ app@web01:/opt/app/releases/current/
ssh app@web01 'systemctl --user restart app'
ssh app@web01 'systemctl --user status app --no-pager'

첫 번째 명령이 마스터를 엽니다. 다음 두 명령은 호스트, 사용자, 포트 및 유효 SSH 옵션이 일치하는 경우 이를 재사용할 수 있습니다.

오래된 소켓 문제 디버깅

때로는 마스터 연결이 종료된 후에도 소켓 파일이 남아 있을 수 있습니다. 이런 일이 발생하면 이후 SSH 명령이 제어 소켓에 연결하는 중 오류를 인쇄한 다음 일반 연결로 대체되거나 사용 중인 옵션에 따라 실패할 수 있습니다.

먼저 마스터를 확인하세요.

ssh -O check web01

실패하고 ~/.ssh/sockets 아래에 이전 소켓이 표시되면 해당 오래된 파일을 제거하세요. 이런 일이 자주 발생하는 경우 워크스테이션이 절전 모드로 전환되거나 VPN 연결이 끊어지거나 네트워크 변경으로 인해 마스터 연결이 끊어지는지 확인하세요. 불안정한 네트워크에서는 수명이 긴 마스터보다 짧은 ControlPersist가 더 나을 수 있습니다.

디버깅하는 동안 SSH에 더 명시적으로 요청할 수도 있습니다.

ssh -vvv web01 exit

ControlPath, mux_client 또는 기존 마스터를 언급하는 줄을 찾으세요. 다중화가 관련되어 있음을 알게 되면 마스터를 닫고 DNS, 키 또는 원격 SSH 데몬을 비난하기 전에 다시 테스트하세요.

점프 호스트 및 옵션 일치

다중화는 유효 SSH 대상 및 옵션에 연결됩니다. 동일한 서버에 한 번은 직접 연결하고 다른 한 번은 점프 호스트를 통해 연결하는 경우 반드시 동일한 제어 연결은 아닙니다. 한 명령이 호스트 별칭을 사용하고 다른 명령이 다른 User, Port, ProxyJump 또는 ID 파일 설정과 함께 원시 호스트 이름을 사용하는 경우에도 마찬가지입니다.

예측 가능한 재사용을 위해 실제 연결 세부 정보를 ~/.ssh/config에 넣고 모든 곳에서 별칭을 사용하세요.

Host app-prod-1
    HostName 10.20.30.41
    User deploy
    ProxyJump bastion-prod
    IdentityFile ~/.ssh/prod_deploy
    ControlMaster auto
    ControlPersist 10m
    ControlPath ~/.ssh/sockets/%C

그런 다음 ssh app-prod-1, scp file app-prod-1:/tmp/app-prod-1에 대한 자동화를 실행하세요. 별칭, IP 주소 및 일회성 -J 플래그를 혼합하면 명령이 기존 마스터를 재사용해야 하는지 이해하기가 더 어려워집니다.

이것이 팀이 runbook에서 선호하는 호스트 별칭을 문서화해야 하는 이유이기도 합니다. 공유 규칙은 배포 중에 혼란스러운 반쯤 재사용된 연결을 방지합니다.

문제 해결 및 모범 사례

디렉토리 및 권한

보안이 가장 중요합니다. SSH에서 생성한 소켓 파일에는 잠재적인 제어 명령을 포함하여 연결에 대한 메타데이터가 포함되어 있습니다. 소켓 디렉토리에 제한된 권한이 있는지 확인하세요.

# 디렉토리가 없으면 생성
mkdir -p ~/.ssh/sockets

# 엄격한 권한 설정(소유자만 액세스 가능)
chmod 700 ~/.ssh/sockets

여러 사용자 제어

동일한 호스트에 연결하기 위해 다른 사용자 이름을 사용하는 경우 ControlPath%r(원격 사용자) 변수가 user1@hostuser2@host에 대해 별도의 소켓을 생성하므로 다중화가 자동으로 처리합니다.

다른 클라이언트와의 충돌

SSH에 의존하는 자동화된 스크립트나 도구를 실행하는 경우 동일한 다중화 설정을 사용하거나 필요한 경우 명시적으로 비활성화하도록 구성되어 있는지 확인하세요. 스크립트가 새 연결을 보장해야 하는 경우 명령줄에서 비다중화 동작을 강제할 수 있습니다.

ssh -o ControlMaster=no user@host

SSH 연결 다중화는 빈번한 SSH 사용에 대한 가장 간단한 삶의 질 향상 중 하나입니다. ControlMaster auto를 구성하고, 고유하고 짧은 ControlPath를 사용하고, 합리적인 ControlPersist를 설정하고, ssh -O check host로 확인하세요. 문제 해결 중에 연결이 비정상적으로 작동하면 ssh -O exit host로 마스터를 닫고 새 세션으로 다시 테스트하세요.