
HTTP/3, QUIC 및 TLS 1.3을 기반으로 구축된 빠르고 안전한 셸 프로토콜입니다. OAuth2, OpenID Connect 및 클래식 SSH 인증을 지원하며 UDP 포트 포워딩 및 숨겨진 서버 기능을 제공합니다.
[!NOTE] SSH3는 아마 이름이 변경될 것입니다. 여전히 HTTP/3 Extended connect 위에서 실행되는 SSH 연결 프로토콜(RFC4254)이지만, 필요한 변경 사항이 많고 널리 사용되는 SSH 구현체의 철학과 너무 거리가 있어 통합을 고려하기 어렵습니다. 사양 초안은 이미 "HTTP/3을 통한 원격 터미널"로 이름이 변경되었지만, 좋은 영구적인 이름을 정하는 데 시간이 필요합니다.
SSH3는 SSH 프로토콜을 완전히 재검토하여 그 의미를 HTTP 메커니즘 위에 매핑합니다. 이는 우리의 연구 작업의 결과이며, 우리(연구자)는 최근 이를 인터넷 초안 (draft-michel-remote-terminal-http3-00)으로 제안했습니다.
간단히 말해, SSH3는 보안 채널 설정을 위해 QUIC+TLS1.3을 사용하고, 사용자 인증을 위해 HTTP Authorization 메커니즘을 사용합니다. 무엇보다도 SSH3는 다음과 같은 개선 사항을 제공합니다:
[!TIP] 빨리 시작하고 싶으신가요? SSH3 설치 방법을 확인하세요. SSH3 서버 설정 및 SSH3 클라이언트 사용 방법을 배울 수 있습니다.
세션 설정 속도가 빠른 것이지 처리량이 빠른 것은 아닙니다! SSH3는 SSHv2보다 훨씬 빠른 세션 설정을 제공합니다. SSHv2로 새 세션을 설정하는 데 5~7번의 네트워크 왕복 시간이 걸릴 수 있으며, 사용자가 쉽게 알아차릴 수 있습니다. SSH3는 단 3번의 왕복 시간만 필요합니다. 실행 중인 세션의 키 입력 지연 시간은 변경되지 않습니다.
SSH3(위쪽) VS SSHv2(아래쪽) 세션 설정 (서버에 대한 핑 100ms).
SSHv2가 사용자 인증 및 보안 채널 설정을 위해 자체 프로토콜을 정의하는 반면, SSH3는 TLS 1.3, QUIC 및 HTTP의 강력하고 검증된 메커니즘에 의존합니다. 이러한 프로토콜은 이미 전자상거래 및 인터넷 뱅킹과 같은 인터넷 상의 보안이 중요한 애플리케이션을 보호하는 데 광범위하게 사용되고 있습니다.
SSH3는 이미 일반적인 비밀번호 기반 및 공개 키(RSA 및 EdDSA/ed25519) 인증 방법을 구현하고 있습니다. 또한 OAuth 2.0과 같은 새로운 인증 방법을 지원하며 Google/Microsoft/Github 계정을 사용하여 서버에 로그인할 수 있습니다.
SSH3는 더 빠른 세션 설정에 대한 가능성을 보여주지만, 아직 초기 개념 증명 단계에 있습니다. 새로운 복잡한 프로토콜과 마찬가지로, 합리적인 보안 결론을 내리기 전에 전문가의 암호 검토가 장기간에 걸쳐 필요합니다.
우리는 커뮤니티의 피드백과 분석을 용이하게 하기 위해 SSH3를 오픈 소스 프로젝트로 개발하고 있습니다. 그러나 추가적인 동료 검토 없이는 생산 시스템에 적합하다고 보증할 수 없습니다. 관련 전문 지식이 있으시면 함께 협력해 주시기 바랍니다!
현재 프로토타입 상태를 고려하여, 샌드박스 환경이나 사설 네트워크에서 SSH3를 테스트하는 것이 좋습니다. 실험 서버를 인터넷에 직접 노출시키는 것은 철저한 보안 검증 전에 위험을 초래할 수 있습니다.
서버를 비밀 경로 뒤에 숨기는 것이 잠재적인 이점이 있지만, 프로덕션에 들어가기 전에 엄격한 취약점 분석의 필요성을 대체하지는 않습니다. 우리는 SSH3의 미래 가능성에 대해 기대하고 있지만, 추가적인 검토를 권장합니다.
SSH3를 사용하면 SSH 서버에 대한 일반적인 스캐닝 및 사전 공격(dictionary attacks)의 스트레스를 피할 수 있습니다. Google Drive의 비밀 문서와 마찬가지로, SSH3 서버는 비밀 링크 뒤에 숨겨져 이 특정 링크에 대한 HTTP 요청을 한 인증 시도에만 응답하도록 할 수 있습니다. 예를 들면 다음과 같습니다:
ssh3-server -bind 192.0.2.0:443 -url-path <my-long-secret>
<my-long-secret>을 임의의 값, 예를 들어 M3MzkxYWMxMjYxMjc5YzJkODZiMTAyMjU로 바꾸면, SSH3 서버는 https://192.0.2.0:443/M3MzkxYWMxMjYxMjc5YzJkODZiMTAyMjU URL로의 SSH3 연결 시도에만 응답하고 다른 요청에는 404 Not Found를 응답합니다. 따라서 인터넷의 공격자와 크롤러는 SSH3 서버의 존재를 감지할 수 없습니다. 그들은 모든 요청에 404 상태 코드를 응답하는 단순한 웹 서버만 보게 됩니다.
명심하세요: SSH3 서버를 비밀 URL 뒤에 두는 것은 스캐닝 공격의 영향을 줄일 수 있지만, 기존의 인증 메커니즘을 대체하지는 않으며 절대로 대체해서는 안 됩니다. 비밀 링크는 호스트가 발견되는 것을 방지하는 데만 사용해야 합니다. 비밀 URL을 아는 사람이 서버에 접근 권한을 부여받지 않아야 합니다. 위에서 설명한 기존 인증 메커니즘을 사용하여 서버를 보호하십시오.
SSH3는 SSHv2 프로토콜에서는 제공할 수 없었던 새로운 기능을 제공합니다.
이 SSH3 구현은 이미 OpenSSH의 많은 인기 기능을 제공하므로, OpenSSH에 익숙하다면 SSH3 채택 과정이 원활할 것입니다. SSH3가 구현한 OpenSSH 기능 중 일부는 다음과 같습니다:
~/.ssh/authorized_keys 파싱known_hosts 메커니즘ssh-agent 자동 사용-proxy-jump 매개변수 참조). A가 SSH3 클라이언트이고 B와 C가 모두 SSH3 서버인 경우, B를 게이트웨이/프록시로 사용하여 A에서 C로 연결할 수 있습니다. 프록시는 UDP 포워딩을 사용하여 A에서 C로 QUIC 패킷을 전달하므로, B는 A<->C SSH3 트래픽을 해독할 수 없습니다.~/.ssh/config를 파싱하고 Hostname, User, Port 및 IdentityFile 설정 옵션을 처리합니다 (다른 옵션은 현재 무시됨). 또한 OpenSSH의 ProxyJump와 유사하게 동작하는 새로운 UDPProxyJump 옵션도 파싱합니다.SSH3가 책임감 있게 발전할 수 있도록 도와주세요! 역량 있는 보안 연구자들이 코드베이스를 검토하고 피드백을 제공해 주시기 바랍니다. 또한, 시간이 지남에 따라 정식 IETF/IRTF 프로세스를 통해 SSH3를 발전시킬 수 있도록 관련 표준 기관에 저희를 연결해 주시기 바랍니다.
협력을 통해 반복적으로 SSH3를 안전한 생산 준비 상태로 개선할 수 있기를 바랍니다. 그러나 광범위한 전문가 암호 검토 및 권위 있는 보안 기관의 채택 증거 없이는 확실한 보안 주장을 신뢰성 있게 할 수 없습니다. SSH3의 가능성을 실현하기 위해 함께 노력합시다!
마지막 릴리스 바이너리를 다운로드하거나, Go install을 사용하여 설치하거나, 소스 코드를 컴파일하여 직접 바이너리를 생성할 수 있습니다.
[!TIP] SSH3는 아직 실험 단계이며 연구 작업의 결과입니다. 새로운 SSH3 서버를 공개적으로 배포하는 것이 두렵다면 SSH3의 비밀 경로 기능을 사용하여 비밀 URL 뒤에 숨길 수 있습니다.
go install github.com/francoismichel/ssh3/cmd/...@latest
최신 Golang 버전이 필요합니다. 소스 코드를 다운로드하고 바이너리를 컴파일하는 방법은 다음과 같습니다:
git clone https://github.com/francoismichel/ssh3 # 저장소 복제
cd ssh3
go build -o ssh3 cmd/ssh3/main.go # 클라이언트 빌드
CGO_ENABLED=1 go build -o ssh3-server cmd/ssh3-server/main.go # 서버 빌드, gcc 설치 필요
루트/sudo 권한이 있고 ssh3를 모든 사용자가 사용할 수 있게 하려면 바이너리를 /usr/bin에 직접 복사하면 됩니다:
cp ssh3 /usr/bin/ && cp ssh3-server /usr/bin
그렇지 않으면 .bashrc 또는 이와 동등한 파일의 끝에 다음 줄을 추가하여 실행 파일을 PATH 환경 변수에 추가할 수 있습니다:
export PATH=$PATH:/path/to/the/ssh3/directory
호스트에 연결하기 전에 SSH3 서버를 배포해야 합니다. 현재 SSH3 데몬은 없으므로, 지금은 screen 또는 유사한 유틸리티를 사용하여 ssh3-server 실행 파일을 백그라운드에서 실행해야 합니다.
[!NOTE] SSH3는 HTTP/3 위에서 실행되므로 서버는 X.509 인증서와 해당 개인 키가 필요합니다. 공용 도메인 이름에 대한 공용 인증서는 서버의
-generate-public-cert명령줄 인수를 통해 Let's Encrypt를 사용하여 자동으로 생성할 수 있습니다. 실제 인증 기관이 서명한 인증서를 생성하지 않으려거나 공용 도메인 이름이 없는 경우,-generate-selfsigned-cert명령줄 인수를 사용하여 자체 서명된 인증서를 생성할 수 있습니다. 자체 서명된 인증서는 SSHv2의 호스트 키 메커니즘과 유사한 보안 보장을 제공하며, 동일한 보안 문제가 있습니다: 서버에 처음 연결할 때 중간자 공격에 취약할 수 있습니다. Let's Encrypt와 같은 공용 인증 기관이 서명한 실제 인증서를 사용하면 이 문제가 해결됩니다.
다음은 ssh3-server 실행 파일의 사용법입니다:
Usage of ./ssh3-server:
-bind string
the address:port pair to listen to, e.g. 0.0.0.0:443 (default "[::]:443")
-cert string
the filename of the server certificate (or fullchain) (default "./cert.pem")
-key string
the filename of the certificate private key (default "./priv.key")
-enable-password-login
if set, enable password authentication (disabled by default)
-generate-public-cert value
Automatically produce and use a valid public certificate usingLet's Encrypt for the provided domain name. The flag can be used several times to generate several certificates.If certificates have already been generated previously using this flag, they will simply be reused without being regenerated. The public certificates are automatically renewed as long as the server is running. Automatically-generated IP public certificates are not available yet.
-generate-selfsigned-cert
if set, generates a self-self-signed cerificate and key that will be stored at the paths indicated by the -cert and -key args (they must not already exist)
-url-path string
the secret URL path on which the ssh3 server listens (default "/ssh3-term")
-v verbose mode, if set
-version
if set, displays the software version on standard output and exit
다음 명령은 유효한 Let's Encrypt 공용 인증서를 사용하여 도메인 my-domain.example.org에 대해 포트 443에서 공용 SSH3 서버를 시작하고, /ssh3 URL 경로를 쿼리하는 새 세션 요청에 응답합니다:
ssh3-server -generate-public-cert my-domain.example.org -url-path /ssh3
공용 도메인 이름이 없는 경우(즉, IP 주소만 있는 경우) -cert 및 -key 인수를 사용하여 IP 주소에 대한 기존 인증서를 사용하거나 -generate-selfsigned-cert 인수를 사용하여 자체 서명된 인증서를 생성할 수 있습니다.
기존 인증서와 키가 있는 경우 다음과 같이 서버를 실행하여 사용할 수 있습니다:
ssh3-server -cert /path/to/cert/or/fullchain -key /path/to/cert/private/key -url-path /ssh3
[!NOTE] OpenSSH와 마찬가지로, 서버는 다른 사용자로 로그인하려면 루트 권한으로 실행되어야 합니다.
기본적으로 SSH3 서버는 각 사용자의 ~/.ssh/authorized_keys 및 ~/.ssh3/authorized_identities 파일에서 아이덴티티를 찾습니다.
~/.ssh3/authorized_identities는 아래에서 설명하는 OpenID Connect(oidc)와 같은 새로운 아이덴티티를 허용합니다.
rsa, ed25519와 같은 인기 있는 키 유형과 OpenSSH 형식의 키를 사용할 수 있습니다.
SSH3 서버가 실행 중이면, 기존 SSHv2 도구를 사용했던 것과 유사하게 SSH3 클라이언트를 사용하여 연결할 수 있습니다.
다음은 ssh3 실행 파일의 사용법입니다:
Usage of ssh3:
-pubkey-for-agent string
if set, use an agent key whose public key matches the one in the specified path
-privkey string
private key file
-use-password
if set, do classical password authentication
-forward-agent
if set, forwards ssh agent to be used with sshv2 connections on the remote host
-forward-tcp string
if set, take a localport/remoteip@remoteport forwarding localhost@localport towards remoteip@remoteport
-forward-udp string
if set, take a localport/remoteip@remoteport forwarding localhost@localport towards remoteip@remoteport
-proxy-jump string
if set, performs a proxy jump using the specified remote host as proxy
-insecure
if set, skip server certificate verification
-keylog string
Write QUIC TLS keys and master secret in the specified keylog file: only for debugging purpose
-use-oidc string
if set, force the use of OpenID Connect with the specified issuer url as parameter
-oidc-config string
OpenID Connect json config file containing the "client_id" and "client_secret" fields needed for most identity providers
-do-pkce
if set, perform PKCE challenge-response with oidc
-v if set, enable verbose mode
다음 명령을 사용하여 ~/.ssh/id_rsa에 있는 개인 키를 사용하여 /my-secret-path에서 수신 중인 SSH3 서버 my-server.example.org에 연결할 수 있습니다:
ssh3 -privkey ~/.ssh/id_rsa [email protected]/my-secret-path
SSH3 클라이언트는 OpenSSH 에이전트와 함께 작동하며, 이 에이전트와 통신하기 위해 일반적인 SSH_AUTH_SOCK 환경 변수를 사용합니다.
OpenSSH와 마찬가지로 SSH3는 SSH 에이전트가 제공하는 키를 나열하고 기본적으로 에이전트가 나열한 첫 번째 키를 사용하여 연결합니다.
에이전트와 함께 사용할 특정 키를 지정하려면 위와 같이 -privkey 인수로 개인 키를 직접 지정하거나, -pubkey-for-agent 인수를 사용하여 해당 공개 키를 지정할 수 있습니다. 이렇게 하면 에이전트만 개인 키에 직접 액세스할 수 있고 공개 키에만 액세스할 수 있는 상황에서 인증할 수 있습니다.
권장되지는 않지만, 다음 명령을 사용하여 비밀번호로 서버에 연결할 수 있습니다(ssh3-server에서 명시적으로 활성화된 경우):
ssh3 -use-password [email protected]/my-secret-path
ssh3는 OpenSSH 설정을 파싱합니다. 현재는 Hostname; User, Port 및 IdentityFile OpenSSH 옵션만 처리합니다.
또한 SSH3에서만 사용되는 새로운 옵션(예: URLPath 또는 UDPProxyJump)도 추가합니다. URLPath를 사용하면 SSH3 명령에서 비밀 URL 경로를 생략할 수 있습니다. UDPProxyJump를 사용하면 SSH3 프록시 점프를 수행할 수 있으며 -proxy-jump 명령줄 인수와 동일한 의미를 갖습니다.
~/.ssh/config에 있는 OpenSSH 설정 파일에 다음과 같은 줄이 있다고 가정해 보겠습니다:
IgnoreUnknown URLPath
Host my-server
HostName 192.0.2.0
User username
IdentityFile ~/.ssh/id_rsa
URLPath /my-secret-path
OpenSSH가 하는 것과 유사하게, 다음 ssh3 명령은 .ssh/id_rsa에 있는 개인 키를 사용하여 공개 키 인증을 통해 UDP 포트 443에서 192.0.2.0에서 실행 중인 SSH3 서버에 연결합니다:
ssh3 my-server/my-secret-path
설정 기반 SSH3 사용을 원하지 않으면 아래 섹션을 읽고 ssh3의 CLI 매개변수를 사용하는 방법을 확인하십시오.
이 기능을 사용하면 회사의 ID 제공자나 Google Identity, Github, Microsoft Entra 등 OpenID Connect 표준을 구현하는 외부 제공자를 사용하여 연결할 수 있습니다. 인증 흐름은 아래 GIF에 설명되어 있습니다.
Google 계정을 사용한 개인 키 없는 보안 연결.
ID 제공자에 연결하는 방법은 ~/.ssh3/oidc_config.json 파일에 구성됩니다. 아래는 Google 계정과 함께 사용하기 위한 config.json 파일의 예입니다. 이 구성 파일은 배열이며 여러 ID 제공자 구성을 포함할 수 있습니다.
[
{
"issuer_url": "https://accounts.google.com",
"client_id": "<your_client_id>",
"client_secret": "<your_client_secret>"
}
]
향후 변경될 수 있지만, 현재 이 기능을 Google 계정에서 작동하게 하려면 Google Cloud 콘솔에서 새로운 실험 애플리케이션을 설정하고 이메일을 승인된 사용자로 추가해야 합니다.
그러면 client_id와 client_secret이 제공되며, 이를 ~/.ssh3/oidc_config.json에 설정할 수 있습니다. 서버 측에서는 ~/.ssh3/authorized_identities에 다음 줄을 추가하기만 하면 됩니다:
oidc <client_id> https://accounts.google.com <email>
향후 authorized_identities 파일에 client_id를 설정할 필요를 없애는 것을 고려하고 있습니다.
일부 SSH 호스트는 게이트웨이를 통해서만 액세스할 수 있는 경우가 많습니다. SSH3는 OpenSSH에서 제공하는 것과 유사한 프록시 점프를 수행할 수 있습니다. B를 게이트웨이/프록시로 사용하여 A에서 C로 연결할 수 있습니다. B와 C는 모두 유효한 SSH3 서버를 실행 중이어야 합니다. 이는 B에서 UDP 포트 포워딩을 설정하여 A에서 C로 QUIC 패킷을 전달하는 방식으로 작동합니다. 따라서 A에서 C로의 연결은 완전히 종단 간(end-to-end)이며, B는 A와 C 사이의 SSH3 트래픽을 해독하거나 수정할 수 없습니다.