
Rust로 작성된 간단한 TCP 터널로, 로컬 포트를 원격 서버에 노출하여 NAT 방화벽을 우회합니다. 가볍고 자체 호스팅이 가능하며 설치가 쉽습니다.
Rust로 작성된 현대적이고 간단한 TCP 터널로, 표준 NAT 연결 방화벽을 우회하여 로컬 포트를 원격 서버에 노출합니다. 이것이 전부입니다: 그 이상도 이하도 아닙니다.

# 설치 (Rust 필요, 아래 대안 참조)
cargo install bore-cli
# 로컬 머신에서
bore local 8000 --to bore.pub
이렇게 하면 로컬 포트 localhost:8000이 bore.pub:<PORT>를 통해 공개 인터넷에 노출됩니다. 여기서 포트 번호는 무작위로 할당됩니다.
localtunnel 및 ngrok과 유사하지만, bore는 매우 효율적이고, 의견이 개입되지 않은 TCP 트래픽 전달 도구로, 설치가 간단하고 자체 호스팅이 쉬우며 불필요한 기능이 없도록 설계되었습니다.
(bore는 안전한 비동기 Rust 코드 약 400줄로 구성되어 있으며, 설정이 간단합니다. 클라이언트와 서버 모두 단일 바이너리만 실행하면 됩니다.)
bore는 Homebrew 핵심 공식으로 패키징되어 있습니다.
brew install bore-cli
bore는 AUR에 bore로 제공됩니다.
yay -S bore # 또는 선호하는 AUR 헬퍼 사용
bore는 gentoo-zh 오버레이에서 사용할 수 있습니다.
sudo eselect repository enable gentoo-zh
sudo emerge --sync gentoo-zh
sudo emerge net-proxy/bore
그 외에는 사전 빌드된 바이너리로 bore를 설치하는 것이 가장 쉽습니다. macOS, Windows, Linux용 바이너리는 릴리스 페이지에서 제공됩니다. 플랫폼에 맞는 파일의 압축을 풀고 bore 실행 파일을 PATH에 있는 폴더로 이동하기만 하면 됩니다.
Rust 패키지 매니저인 Cargo를 사용하여 소스에서 bore를 빌드할 수도 있습니다. 이 명령은 사용자가 액세스할 수 있는 경로에 bore 바이너리를 설치합니다.
cargo install bore-cli
각 릴리스에 대해 버전이 지정된 Docker 이미지도 게시합니다. 이미지는 AMD 64비트 아키텍처용으로 빌드됩니다. 특정 버전으로 태그가 지정되어 있으며, 최소한의 "scratch" 컨테이너에서 정적으로 링크된 bore 바이너리를 실행할 수 있습니다.
docker run -it --init --rm --network host ekzhang/bore <ARGS>
이 섹션에서는 bore CLI 명령의 상세 사용법을 설명합니다.
bore local 명령을 사용하여 로컬 머신의 포트를 포워딩할 수 있습니다. 이 명령은 위치 인수로 로컬 포트를 받고, 필수 --to 옵션으로 원격 서버의 주소를 지정합니다.
bore local 5000 --to bore.pub
선택적으로 --port 옵션을 사용하여 원격에서 노출할 특정 포트를 선택할 수 있지만, 해당 포트를 사용할 수 없으면 명령이 실패합니다. 또한 --local-host를 전달하면 루프백 주소 localhost 대신 로컬 영역 네트워크의 다른 호스트를 노출할 수 있습니다.
전체 옵션은 아래와 같습니다.
Starts a local proxy to the remote server
Usage: bore local [OPTIONS] --to <TO> <LOCAL_PORT>
Arguments:
<LOCAL_PORT> The local port to expose [env: BORE_LOCAL_PORT=]
Options:
-l, --local-host <HOST> The local host to expose [default: localhost]
-t, --to <TO> Address of the remote server to expose local ports to [env: BORE_SERVER=]
-p, --port <PORT> Optional port on the remote server to select [default: 0]
-s, --secret <SECRET> Optional secret for authentication [env: BORE_SECRET]
-h, --help Print help
시작 안내에서 언급했듯이 bore.pub에서 실행되는 공개 인스턴스가 있습니다. 그러나 자체 네트워크에서 bore를 자체 호스팅하려면 다음 명령으로 수행할 수 있습니다:
bore server
그게 전부입니다! 서버가 지정된 주소에서 실행을 시작한 후, bore local 명령에 --to <ADDRESS> 옵션을 추가하여 로컬 포트를 이 원격 서버로 포워딩할 수 있습니다.
제어 서버와 터널에 대해 서로 다른 IP 주소를 지정할 수 있습니다. 이 설정은 제어 서버를 개인 네트워크에 두고 터널 연결은 공용 인터페이스를 통해 허용하거나 그 반대의 경우에 유용합니다.
bore server 명령의 전체 옵션은 아래와 같습니다.
Runs the remote proxy server
Usage: bore server [OPTIONS]
Options:
--min-port <MIN_PORT> Minimum accepted TCP port number [env: BORE_MIN_PORT=] [default: 1024]
--max-port <MAX_PORT> Maximum accepted TCP port number [env: BORE_MAX_PORT=] [default: 65535]
-s, --secret <SECRET> Optional secret for authentication [env: BORE_SECRET]
--bind-addr <BIND_ADDR> IP address to bind to, clients must reach this [default: 0.0.0.0]
--bind-tunnels <BIND_TUNNELS> IP address where tunnels will listen on, defaults to --bind-addr
-h, --help Print help
암시적인 _제어 포트_가 7835에 있으며, 필요에 따라 새 연결을 만드는 데 사용됩니다. 초기화 시 클라이언트는 TCP 제어 포트를 통해 서버에 "Hello" 메시지를 보내 선택한 원격 포트의 프록시를 요청합니다. 그러면 서버는 확인 응답을 보내고 외부 TCP 연결을 수신하기 시작합니다.
서버가 원격 포트에서 연결을 획득할 때마다 해당 연결에 대해 보안 UUID를 생성하여 클라이언트에 다시 보냅니다. 그러면 클라이언트는 서버에 별도의 TCP 스트림을 열고 해당 스트림에 UUID가 포함된 "Accept" 메시지를 보냅니다. 그러면 서버는 두 연결을 서로 프록시합니다.
정확성과 메모리 누수 방지를 위해, 들어오는 연결은 클라이언트가 수락하지 않으면 서버에 의해 최대 10초 동안만 저장된 후 폐기됩니다.
bore server의 사용자 지정 배포에서 다른 사람이 서버를 사용하지 못하도록 선택적으로 _비밀_을 요구할 수 있습니다. 프로토콜은 클라이언트가 HMAC 코드 형태의 무작위 챌린지에 응답하여 각 TCP 연결에서 비밀을 소유했음을 확인하도록 요구합니다. (이 비밀은 초기 핸드셰이크에만 사용되며, 기본적으로 추가 트래픽은 암호화되지 않습니다.)
# 서버에서
bore server --secret my_secret_string
# 클라이언트에서
bore local <LOCAL_PORT> --to <TO> --secret my_secret_string
인수에 비밀이 없으면 bore는 BORE_SECRET 환경 변수에서도 읽으려고 시도합니다.
Eric Zhang (@ekzhang1)이 만들었습니다. MIT 라이선스에 따라 사용이 허가됩니다.
저자는 Rust로 인체공학적이고 효율적인 네트워크 서비스를 작성할 수 있게 해준 Tokio 프로젝트의 기여자와 유지 관리자에게 감사드립니다.