방송 경로마다 고정 암호를 두는 방식에서 사용자별 암호를 받는 방식으로 바꾸려면, 인증 서버의 성공 응답을 어디까지 기다려야 할까요. PokeClip의 계정별 방송 전환을 준비하며 MediaMTX에 사용자별 SRT 암호를 제안했는데, 기능이 동작한다는 확인만으로는 끝낼 수 없었습니다.

암호를 얻으려고 HTTP 응답 본문을 읽자 다른 경로 작업도 기다리는 비용이 나타났습니다. 본문을 100ms 늦게 보내는 조건에서 후속 경로 조회까지의 관측 중앙값이 0.27ms에서 102.53ms로 늘었습니다. 사용자별 암호의 이점과 이 대기 비용을 함께 남겨야 하는 제안이었습니다.

그 결과가 MediaMTX PR #6306입니다. 2026년 10월 15일 기준 열린 제안이며, 정식 릴리스에 반영된 개인 기여 4건과 별개입니다. 저는 기존 경로 암호로 돌아가는 규칙을 남기고, 내부 사용자·HTTP 인증만 지원하며 JWT는 제외하는 범위를 정했습니다. 구현, 프로브 실행과 리뷰는 AI 협업으로 진행했습니다.

사용자별로 받되, 기존 경로 암호는 남겼습니다

SRT는 네트워크 손실에 대응하며 미디어를 전송하는 프로토콜입니다. 이 제안의 관심사는 전송 성능보다 연결마다 어떤 passphrase를 적용할지였습니다. 기존 경로 암호를 전부 폐기하면 사용자별 값을 쓰지 않는 구성까지 변경해야 합니다.

선택한 규칙은 사용자 암호가 있으면 그 값을 우선하고, 비어 있으면 기존 경로 암호로 돌아가는 것입니다. 지원 범위는 내부 사용자 설정과 HTTP 인증 응답으로 제한했습니다.

경계 제안한 동작 이유
사용자 암호 존재 경로 암호보다 우선 사용자 단위 선택을 연결에 반영
사용자 암호가 비어 있음 경로 설정으로 복귀 기존 구성과 호환
입력 길이 10–79자 검사 잘못된 값을 연결 경계에서 거부
관리 API 응답 비밀값 가림 조회 응답에서 원문 노출 방지
HTTP 인증 응답 본문 128KiB 제한, readTimeout 적용 읽기 자원과 대기 시간 제한

내부 사용자 설정의 passphrase는 SRT가 원문을 필요로 하므로 평문으로 저장합니다. API 응답에서 가리는 것과 저장 자체의 암호화는 다른 보장입니다. 또한 사용자 passphrase를 바꿔도 이미 열린 연결을 끊지는 않습니다. PR의 영향 범위에 이 제약을 함께 남겼습니다.

JWT에 암호를 넣는 방식은 포함하지 않았습니다. 이 경로에서는 토큰이 암호화되지 않은 SRT streamid로 전달될 수 있어, 비밀을 담는 수단으로 채택하지 않았습니다. 지원하지 않는 인증 방식과 그 이유도 제안의 일부로 남겼습니다.

암호를 얻기 위한 본문 읽기가 다른 경로 작업도 늦췄습니다

HTTP 인증 서버가 성공 상태를 보냈다고 일이 끝나는 것은 아닙니다. 사용자 암호를 얻으려면 응답 본문을 읽어야 합니다. 그동안 경로 관리자가 묶이면, 늦은 본문이 다른 경로 작업에 영향을 줄 수 있습니다.

publish/read의 실제 SRT 송수신은 12개 하위 테스트로, HTTP 응답의 유효성·누락·지연·잘림은 27개 하위 테스트로 확인했습니다. 통과 여부와 별도로 지연된 성공 본문의 비용도 측정했습니다. 인증 서버에 SRT 요청이 들어온 때부터, 그 직후 보낸 GET /v3/paths/list 응답을 모두 받을 때까지를 비교했습니다. 아래는 readTimeout: 2s, 각 조건 20회의 중앙값입니다. 관리자 루프 밖의 API 처리·전송도 들어 있으므로 정확한 루프 점유 시간이나 SRT 접속 완료 시간과는 구분합니다.

HTTP 본문 조건 상류 main 제안 브랜치 해석
100ms 본문 지연 0.27ms 102.53ms 본문 대기가 경로 작업까지 이어짐
1초 본문 지연 0.29ms 1.00초 긴 응답 비용이 남음
끝나지 않는 본문 0.36ms 2초 timeout까지 대기

결과는 인증 서버가 본문을 늦게 보낼수록 후속 경로 조회도 비슷한 시간만큼 늦어진다는 쪽이었습니다. 끝나지 않는 본문도 2초 제한에 도달할 때까지 기다렸습니다. 따라서 128KiB와 timeout 제한은 유지하되, 이를 지연 문제의 해결로 보지는 않았습니다. 제한 안에서 발생하는 대기는 남아 있고, 사용자별 암호 기능을 도입할 때 그 비용도 고려해야 합니다.

포크에서 사용할 수 있음과 상류 채택은 별개입니다

제품 포크에 구현을 넣고 태그를 발행하는 것과, 외부 유지보수자가 상류 변경으로 받아들이는 것은 다른 단계입니다. #6306은 포크 반영과 상류 게시까지 진행했지만, 이 글의 기준일에는 병합되지 않았습니다. 따라서 릴리스 성과의 개수에 넣지 않았습니다.

초기 글에서 검증한 범위는 해당 송수신 fixture와 지연 프로브였습니다. 이후 개발 서버 연동 결과는 아래에 분리해 추가합니다. 운영 부하 검증의 완료를 뜻하지는 않습니다.

사용자 단위로 암호를 선택할 수 있게 되면 경로 설정과 계정 인증을 연결하기 쉬워집니다. 그러나 그 값을 받아오는 과정도 연결 처리의 일부가 됩니다. 이번에는 기존 경로 암호와의 호환성을 지키고, 비밀을 노출할 수 있는 JWT 경로를 제외하며, 느린 성공 응답의 비용을 수치로 확인했습니다. 기능의 지원 여부와 실제 도입 비용을 함께 판단할 수 있도록 만드는 것이 이 제안의 핵심이었습니다.

10월 19일 후속: 개발 서버에서 계정별 송출과 차단을 연결했습니다

2026년 10월 28일 추가. 상류 제안과 별도로, 제품 포크 v1.21.1-pokeclip.2를 개발 서버에 반영했습니다. MediaMTX가 연결마다 같은 서버의 ingest-auth 응답기에 HTTP 인증을 요청하고, 응답기는 Auth 서비스의 계정 조회 계약을 통해 해당 계정의 passphrase를 반환합니다. 계정마다 경로 설정을 복제하던 초기 설계 대신 연결 시점에 인증하는 방식을 선택했습니다.

Control API는 미디어 서버와 응답기가 붙는 내부 제어망에서만 사용하고, 요청 자체에도 인증을 적용했습니다. 네트워크 격리만으로 호출 권한이 검증된다고 보지 않았습니다. 제 역할은 미디어·인증 사이의 계약, 적용 범위와 검증 조건을 정하는 것이었고, Auth 서비스 구현은 팀원의 담당입니다. 미디어 측 구현·실험은 AI와 협업했습니다.

10월 19일 개발 서버 확인 항목 결과
정상 계정 송출 / 잘못된 passphrase 정상 수락 / MediaMTX에서 거부
SRT 읽기 요청 / 같은 토큰의 두 번째 연결 각각 거부
OBS 플러그인 7트랙 송출 HLS 응답 200 확인
거부 목록 추가 후 연결 ID로 강제 종료 기존 연결 종료, 재접속 거부
차단 해제 후 응답기 재시작 같은 키로 재송출 허용

차단 해제는 키 교체가 아닙니다. 유출된 키는 그대로 해제해서는 안 되며, 운영자가 쓸 키 교체 수단은 별도 과제로 남겼습니다. Auth 조회 장애와 passphrase가 없는 성공 응답은 이 개발 서버 실측에서 판정하지 못했습니다. 정상·거부 경로 일부의 통과를 장애 대응 전체의 완료로 확대하지 않습니다.

이후 PR #304에서 비밀 파일 입력과 호출자 Basic 인증을 보강했고, PR #308에서 송출자 IP별 요청 한도를 추가했습니다. 둘은 10월 22일 병합된 후속 변경입니다. 10월 19일 송출 실험의 검증 대상이 아니며, 병합을 서버 배포 완료와 같은 말로 쓰지 않습니다.


개발 사례 전체 모음 · 초기 10월 15일 판 포트폴리오 PDF