처음 질문은 아주 단순했다.
QueryPie 11.2.0에서 사용하는 mongosh 버전이 뭔가요?
좋다. 버전 확인 정도야 금방 끝나겠지.
그런데 막상 열어보니, 이 질문은 생각보다 재밌는 미로였다.
왜냐하면 QueryPie 안에는 우리가 흔히 떠올리는 그런 mongosh가 없었기 때문이다.
터미널에서 이렇게 찾는 그 녀석 말이다.
which mongosh
find / -name mongosh
없다.
그럼 QueryPie는 MongoDB Shell 기능을 안 쓰는 걸까?
아니다. 쓴다. 다만 아주 QueryPie다운 방식으로 쓴다.
먼저 mongosh가 뭔데?
mongosh는 MongoDB 공식 Shell이다.
쉽게 말하면 MongoDB에 접속해서 쿼리를 날리고, collection을 둘러보고, aggregation을 테스트하고, admin command를 실행하는 CLI 도구다.
일반적으로는 이렇게 쓴다.
mongosh "mongodb://user:***@mongo.example.com:27017/admin"
접속한 뒤에는 JavaScript처럼 명령을 실행한다.
db.users.find()
db.orders.aggregate([{ $match: { status: "paid" } }])
db.runCommand({ serverStatus: 1 })
그러니까 mongosh는 MongoDB 세계의 만능 리모컨 같은 도구다.
개발자는 디버깅할 때 쓰고, 운영자는 상태를 확인할 때 쓰고, 보안팀은 SBOM이나 CVE를 볼 때 “그래서 이거 몇 버전인데요?”라고 묻는다.
문제는 QueryPie가 이 리모컨을 그냥 책상 위에 올려두지 않는다는 점이다.
일반 mongosh는 직접 운전이다
보통의 mongosh 구조는 단순하다.
사용자 터미널
└─ mongosh 실행 파일
└─ MongoDB 서버
사용자가 직접 mongosh를 실행한다.
MongoDB 주소와 계정을 넣고 접속한다.
그다음 명령을 친다.
이 구조는 자유롭다. 그래서 개발자에게는 편하다.
하지만 QueryPie 입장에서는 너무 자유롭다.
QueryPie는 단순한 DB client가 아니라 접근 제어 제품이다. 누가 어떤 DB에 접근할 수 있는지, 어떤 명령이 가능한지, 어떤 정책이 적용되는지 통제해야 한다.
그래서 QueryPie는 “사용자가 직접 운전하는 자동차” 같은 mongosh CLI를 그대로 쓰지 않는다.
대신 운전대를 QueryPie Engine 쪽으로 가져온다.
QueryPie에서는 mongosh가 서버 안쪽에 숨어 있다
QueryPie 11.2.0의 구조를 단순화하면 이렇다.
사용자 브라우저
└─ QueryPie Web/API
└─ QueryPie Engine (.NET)
└─ QueryPie.EngineBackend.dll
└─ querypie-engine-backend native binary
└─ qp-mongo-shell-server
└─ @qp-mongosh/* packages
└─ mongodb Node driver
└─ MongoDB 서버
핵심은 이거다.
사용자가 서버에서 mongosh를 직접 실행하지 않는다.
QueryPie Engine이 내부의 EngineBackend를 통해 Mongo Shell 기능을 빌려 쓰고, 실제 MongoDB와의 통신은 내부에 패키징된 qp-mongo-shell-server와 mongodb Node driver가 처리한다.
조금 더 쉬운 비유로 말하면 이렇다.
일반 mongosh CLI
= 사용자가 직접 운전하는 자동차
QueryPie의 Mongo Shell server
= QueryPie가 운전 규칙, 권한, 경로를 통제하는 운전 대행 시스템
자동차는 움직인다.
하지만 운전자가 다르다.
그리고 그게 QueryPie에서는 중요하다.
실제 요청은 어떻게 흐를까?
예를 들어 사용자가 QueryPie Web에서 MongoDB collection을 조회한다고 해보자.
겉으로 보기에는 “조회 버튼 클릭” 정도다.
하지만 안쪽에서는 이런 일이 벌어진다.
1. 사용자
QueryPie Web에서 MongoDB 조회 요청
2. QueryPie API / Engine
사용자 권한, connection 정보, policy 확인
3. Engine의 MongoDB session
MongoShell이 필요하면 EngineBackend에 lease 요청
4. EngineBackend
내부 querypie-engine-backend native binary에서 Mongo Shell server 준비
port / uuid 반환
5. Engine
반환된 port로 MongoShellService gRPC client 연결
6. Mongo Shell server
@qp-mongosh shell API와 mongodb Node driver로 실제 MongoDB 요청 수행
7. 결과 반환
MongoDB 결과가 Engine/API/Web으로 돌아와 화면에 표시
여기서 재미있는 포인트는 lease다.
QueryPie Engine이 “나 Mongo Shell 하나 필요해”라고 EngineBackend에 요청한다.
그러면 EngineBackend가 내부 shell server를 준비하고, Engine은 거기에 gRPC로 붙는다.
즉 QueryPie의 Mongo Shell은 터미널에서 열리는 창이 아니라, Engine이 통제하는 내부 서비스에 더 가깝다.
그럼 버전은 뭘 봐야 할까?
처음 질문으로 돌아가자.
QueryPie 11.2.0에서 사용하는 mongosh 버전이 뭔가요?
공식 mongosh 최신 버전은 확인 시점 기준 2.8.3이었다.
그런데 QueryPie 11.2.0은 이 2.8.3을 그대로 쓰지 않는다.
실제 배포 이미지에서 확인한 구성은 이렇다.
QueryPie 11.2.0 image
└─ /app/engine/QueryPie.EngineBackend.dll
└─ 10.2.8
└─ /app/engine/querypie-engine-backend
└─ qp-mongo-shell-server 10.2.8
└─ @qp-mongosh/* 0.0.0-dev.27
└─ mongodb 5.9.2
└─ mongodb-client-encryption 2.9.1
└─ bson 4.7.2 / 5.5.1
또 mongosh-internal repo를 따라가 보니, release/10.2.x 브랜치의 HEAD가 10.2.8 tag였고, 공식 mongosh 계열 tag 기준으로는 이렇게 설명할 수 있었다.
mongosh v1.1.9 이후 fork
+ QueryPie custom commits
+ qp-mongo-shell-server 10.2.8 패키징
그러니까 가장 정확한 문장은 이거다.
QueryPie 11.2.0의 Mongo Shell 기능은 공식 MongoDB mongosh v1.1.9 이후 fork를 기반으로 QueryPie에서 커스텀한 qp-mongo-shell-server 10.2.8 구성으로 제공된다. 최신 공식 mongosh 2.8.3을 standalone CLI로 사용하는 구조는 아니다.
조금 길다.
하지만 정확하다.
“mongosh 1.1.9 쓰네요?”도 살짝 위험하다
여기서 함정이 하나 더 있다.
“아, 그럼 QueryPie는 mongosh 1.1.9를 쓰는군요?”라고 말하고 싶어진다.
그런데 이것도 살짝 위험하다.
왜냐하면 QueryPie 안에 들어 있는 것은 공식 mongosh 1.1.9 바이너리 그 자체가 아니기 때문이다.
더 정확히는:
공식 mongosh v1.1.9 이후의 fork 기반
+ QueryPie 변경사항
+ qp-mongo-shell-server 10.2.8 형태로 패키징
이다.
이 차이는 보안/SBOM 대응에서 꽤 중요하다.
공식 mongosh 하나만 보고 CVE를 판단하면 실제 포함된 패키지를 놓칠 수 있다.
실제로 봐야 할 것은 이런 구성요소들이다.
| 구분 | 확인된 버전 |
|---|---|
| qp-mongo-shell-server | 10.2.8 |
| @qp-mongosh/* | 0.0.0-dev.27 |
| mongodb Node driver | 5.9.2 |
| mongodb-client-encryption | 2.9.1 |
| bson | 4.7.2 / 5.5.1 |
SBOM은 이름표 싸움이 아니라 실제 들어 있는 부품 목록 싸움이다.
mongosh라는 큰 이름 하나만 보고 끝내면 안 된다.
왜 이렇게 복잡하게 만들었을까?
처음 보면 이런 생각이 든다.
“그냥 최신 mongosh CLI 넣고 실행하면 되는 거 아닌가?”
하지만 QueryPie 관점에서는 그게 그렇게 단순하지 않다.
QueryPie는 MongoDB에 “접속만” 하는 제품이 아니다.
접근 제어를 해야 한다.
정책을 적용해야 한다.
사용자와 connection의 관계를 알아야 한다.
실행 흐름을 Engine이 통제해야 한다.
결과를 QueryPie 방식으로 돌려줘야 한다.
그래서 QueryPie는 mongosh를 독립 실행 파일로 던져두는 대신, 내부 server 형태로 감싸서 Engine과 gRPC로 연결한다.
이 구조는 버전 설명을 어렵게 만든다.
하지만 제품의 제어 지점은 분명해진다.
고객에게는 이렇게 말하면 된다
고객이 묻는다.
서버에서 mongosh 파일이 안 보이는데 정상인가요?
이렇게 답하면 된다.
네, 정상일 수 있습니다. QueryPie는 서버 OS에 mongosh 실행 파일을 별도로 설치해 사용하는 방식이 아니라, QueryPie EngineBackend 내부에 Mongo Shell server 기능을 포함해 제공합니다. 따라서 OS에서 which mongosh 또는 find 명령으로 standalone mongosh 파일이 보이지 않을 수 있습니다.
고객이 묻는다.
그럼 mongosh 버전은 무엇인가요?
이렇게 답하면 된다.
공식 standalone mongosh CLI 버전으로는 안내하기 어렵습니다. QueryPie 11.2.0은 공식 mongosh v1.1.9 이후 fork를 기반으로 QueryPie에서 커스텀한 qp-mongo-shell-server 10.2.8을 사용합니다. 배포 이미지 기준으로는 qp-mongo-shell-server 10.2.8, @qp-mongosh/* 0.0.0-dev.27, mongodb Node driver 5.9.2가 확인됩니다.
고객이 묻는다.
최신 mongosh와 버전 차이가 있나요?
이렇게 답하면 된다.
네, 있습니다. 현재 공식 mongosh 최신 버전은 2.8.3이지만, QueryPie 11.2.0의 Mongo Shell 기능은 공식 mongosh v1.1.9 이후 fork 기반의 QueryPie 커스텀 구성입니다. 다만 QueryPie는 standalone mongosh CLI를 직접 제공하는 제품이 아니라 접근 제어와 정책 적용을 위해 EngineBackend 내부 Mongo Shell server 형태로 사용합니다.
이번 분석에서 배운 것
이번 분석은 버전 하나 확인하는 작업처럼 보였다.
하지만 실제로는 제품 아키텍처를 이해해야만 답할 수 있는 질문이었다.
mongosh가 있냐 없냐.
몇 버전이냐.
최신이냐 아니냐.
이 질문들은 겉으로는 단순하지만, 제품이 외부 오픈소스를 어떻게 감싸고, 어떤 런타임 경계 안에 넣고, 어떤 제어 지점을 만드는지와 연결되어 있었다.
이번 케이스의 교훈은 이거다.
보안 질문에 제대로 답하려면, 패키지 이름만 볼 게 아니라 제품이 그 패키지를 어떤 형태로 사용하는지까지 봐야 한다.
mongosh는 QueryPie 안에서 사라진 게 아니었다.
그냥 터미널 앞자리가 아니라, EngineBackend 안쪽으로 자리를 옮겼을 뿐이다.
그리고 거기서 QueryPie의 규칙에 맞게 일하고 있었다.