이 글은 Shadowrocket에서 Config를 가져와 선택할 수 있지만 .conf 텍스트를 읽거나 점검해야 하는 사용자를 위한 안내입니다. 네 섹션의 처리 단계, 규칙 순서, 도메인 매핑과 URL Rewrite의 차이를 확인하고 최소 예제로 일반적인 문법 문제를 찾습니다.
먼저 .conf의 섹션과 처리 순서 이해하기
Shadowrocket의 .conf 파일은 첫 줄부터 마지막 줄까지 실행되는 스크립트가 아니라, 대괄호로 구분된 여러 섹션으로 구성된 선언형 설정입니다. 섹션 이름에 따라 이후 행을 처리할 모듈이 결정됩니다. 예를 들어 [General]에는 일반 매개변수가, [Rule]에는 분기 규칙이 저장됩니다. 빈 줄은 보통 가독성을 위한 것이며, 행 앞의 주석은 설명용으로 매칭에 참여하지 않습니다.
설정을 읽을 때는 먼저 섹션 이름의 철자를 확인하고, 각 행의 구분 기호를 확인한 뒤, 같은 섹션 안에 순서 의존성이 있는지 점검합니다. 오른쪽 대괄호가 빠졌거나, 쉼표가 한국어 문장부호로 입력되었거나, 정책 이름의 철자가 틀리면 해당 행이 작동하지 않을 수 있습니다. 편집 후에는 Config로 돌아가 설정을 다시 선택하고, 파일을 가져올 수 있는지만 보지 말고 실제 도메인 요청으로 확인해야 합니다.
네 핵심 섹션이 모두 같은 단계에서 작동하는 것은 아닙니다. [Host]는 특정 도메인이 어떤 주소를 얻을지에 영향을 주고, [Rule]은 요청에 적용할 정책을 결정하며, [URL Rewrite]는 식별 가능한 URL을 대상으로 리디렉션이나 거부를 처리합니다. 이 기능들을 하나의 섹션에 섞어 넣으면 각 행이 맞아 보여도 예상한 결과가 나오지 않습니다.
결론: 먼저 섹션별로, 다음에 행별로 확인하기
일부 규칙만 작동하지 않을 때는 먼저 문제가 있는 행이 올바른 섹션에 있는지 확인한 뒤, 영문 쉼표와 필드 수 및 배열 순서를 점검합니다. 연결을 반복해서 껐다 켜는 것만으로는 설정 구조 오류를 해결하기 어렵습니다.
[General]: DNS, bypass 및 기본 동작
[General]은 설정의 일반 매개변수 영역입니다. 이곳의 항목은 DNS 해석, 시스템 우회 동작, 로컬 네트워크 주소 처리 및 기타 기본 옵션에 영향을 줍니다. 분기 규칙 목록이 아니므로 DOMAIN-SUFFIX나 FINAL을 이곳에 넣어서는 안 됩니다. 출처에 따라 설정 항목은 다를 수 있으므로, 점검할 때는 현재 Shadowrocket에서 가져오고 내보낼 수 있는 필드를 기준으로 삼아야 합니다.
dns-server는 설정에서 사용할 DNS 해석 진입점을 지정합니다. system으로 작성하면 시스템에서 사용할 수 있는 해석 설정을 적용합니다. 주소를 직접 입력할 때는 먼저 현재 네트워크에서 해당 주소에 연결할 수 있는지 확인해야 합니다. DNS는 도메인을 주소로 변환하지만 최종적으로 PROXY를 사용할지 DIRECT를 사용할지 결정하지는 않습니다. 정책은 Global Routing과 [Rule]이 함께 결정합니다.
[General]
bypass-system = true
dns-server = system
ipv6 = false
skip-proxy = 127.0.0.1, localhost, *.local, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
bypass-system은 시스템 관련 우회 처리를 사용할지 제어하고, skip-proxy는 프록시로 처리하지 않을 호스트나 주소 범위를 명시합니다. 위 예시에는 루프백 주소, .local 이름, 세 가지 일반적인 사설 주소 대역이 포함되어 있어 문법 설명에 적합하지만 모든 네트워크에 그대로 적용해야 한다는 뜻은 아닙니다. 기업 내부망, 가정용 저장 장치 또는 프린터는 다른 대역을 사용할 수 있으므로 수정하기 전에 장치가 현재 할당받은 로컬 네트워크 주소를 확인해야 합니다.
ipv6 = false는 해당 설정에서 IPv6 동작을 명시적으로 끄는 예시입니다. 하지만 이를 일반적인 해결책으로 간주해서는 안 됩니다. 현재 네트워크, 기존 서비스 설정, 대상 사이트가 모두 IPv6를 정상 지원한다면 오히려 해석 결과가 달라질 수 있습니다. 문제를 확인할 때는 한 번에 하나의 항목만 조정하고, 변경 전후의 DNS 결과와 접속 현상을 기록하세요.
DNS 점검
- 필드
- dns-server
- 시스템 값
- system
- 일반 포트
- 53
- 확인 대상
- 도메인이 주소를 얻는지 여부
DNS가 해석된다고 해서 규칙 정책이 올바른 것은 아닙니다. Rule도 계속 확인해야 합니다.
bypass 점검
- 전체 스위치
- bypass-system
- 명시 목록
- skip-proxy
- 로컬 호스트 이름
- localhost
- 로컬 네트워크 접미사
- *.local
사설 주소 범위는 현재 로컬 네트워크의 실제 대역에 맞춰 입력해야 합니다.
[Rule]: 위에서 아래로 매칭하고 FINAL로 마무리하기
[Rule]은 순서의 영향을 가장 많이 받는 섹션입니다. Global Routing을 Config로 설정하면 Shadowrocket은 설정에 배열된 순서대로 요청을 위에서 아래로 확인합니다. 적용 가능한 첫 규칙과 일치하면 해당 행 끝의 정책을 사용하고, 뒤에 있는 더 구체적인 규칙을 계속 찾지 않습니다. 따라서 구체적인 도메인은 일반적인 접미사 규칙이나 지역 규칙보다 앞에 배치하는 것이 일반적입니다.
일반적인 규칙은 영문 쉼표로 구분합니다. DOMAIN은 전체 도메인을, DOMAIN-SUFFIX는 도메인 접미사를, IP-CIDR은 주소 범위를, GEOIP는 주소가 속한 지역을 기준으로 매칭합니다. FINAL은 앞의 어떤 규칙에도 일치하지 않은 요청을 처리합니다. 정책은 보통 PROXY, DIRECT 또는 REJECT로 작성합니다.
[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY
위 예시의 첫 번째 행은 api.example.com을 우선 DIRECT로 연결합니다. 두 번째 행을 첫 번째 행보다 앞에 두면 전체 도메인이 먼저 DOMAIN-SUFFIX,example.com과 일치하므로 뒤의 예외 규칙이 실행되지 않습니다. no-resolve는 해당 IP 규칙이 매칭을 위해 추가 도메인 해석을 수행하지 않도록 하는 옵션으로, 대상 주소만 확인하면 되는 규칙에 적합합니다.
| 규칙 키워드 | 확인 대상 | 예시 | 정렬 핵심 |
|---|---|---|---|
DOMAIN |
전체 도메인 | api.example.com |
일반적으로 같은 접미사 규칙보다 앞에 배치 |
DOMAIN-SUFFIX |
도메인 및 하위 도메인 | example.com |
범위가 넓으므로 구체적인 예외를 덮어쓰지 않는지 확인 |
IP-CIDR |
IPv4 주소 범위 | 192.168.0.0/16 |
로컬 네트워크 범위는 일반적으로 앞에서 처리 |
GEOIP |
해석된 주소의 지역 | CN |
일반적으로 구체적인 도메인 및 주소 규칙 뒤에 배치 |
FINAL |
모든 미매칭 요청 | FINAL,PROXY |
마지막에 두어 기본 처리로 사용 |
Global Routing은 규칙이 의사 결정에 참여할지 변경합니다. Config는 현재 설정의 규칙을 사용하고, Proxy는 프록시 정책을 강제하며, Direct는 직접 연결합니다. Scene은 설정된 장면 조건에 따라 동작을 결정합니다. 단일 규칙을 테스트할 때는 Proxy나 Direct에 머물러 있지 않은지 먼저 확인해야 합니다. 그렇지 않으면 [Rule]을 수정해도 예상한 차이가 나타나지 않습니다.
- Home에서 테스트할 서버 설정이 선택되어 있는지 확인합니다.
- Global Routing을
Config로 전환합니다. - Config에서 대상 .conf가 선택된 상태인지 확인합니다.
- 검증할 구체적인 규칙을 일반적인 규칙보다 앞에 배치합니다.
- 요청을 다시 보내 매칭된 정책이 예상과 일치하는지 확인합니다.
- 마지막으로
FINAL이 규칙 섹션의 끝에 있는지 확인합니다.
[Host]: 고정 도메인 매핑과 분기 규칙의 차이
[Host]는 지정한 도메인을 특정 주소에 매핑하며, 설정 내부에서 도메인 해석 결과를 덮어쓰는 기능으로 이해할 수 있습니다. 이는 도메인이 어떤 주소를 얻을지 해결할 뿐, 요청을 PROXY, DIRECT 또는 REJECT 중 어디로 보낼지는 결정하지 않습니다. 최종 정책은 여전히 [Rule]이 처리해야 합니다.
아래에서는 문서용 예약 주소로 형식을 설명합니다. 192.0.2.0/24와 2001:db8::/32는 문서 예시에만 사용하는 주소이므로 실제 서비스 주소로 사용해서는 안 됩니다. 실제 설정에는 직접 관리하거나 사용 가능 여부를 확인한 대상 주소를 입력해야 합니다.
[Host]
example.com = 192.0.2.10
api.example.com = 192.0.2.20
ipv6.example.com = 2001:db8::10
Host 매핑에서 가장 흔한 점검 오류는 도메인 계층이 일치하지 않는 것입니다. 예를 들어 example.com만 작성했다고 해서 api.example.com에도 같은 매핑이 자동으로 적용된다고 볼 수 없습니다. 하위 도메인까지 적용하려면 현재 설정이 지원하는 매칭 방식을 항목별로 확인하고 실제 해석 결과로 검증해야 합니다. 겉보기에 비슷한 도메인만 보고 추측하지 마세요.
| 현상 | 우선 확인할 항목 | 원인 판단 |
|---|---|---|
| 도메인이 예상과 다른 주소를 얻음 | [Host]에 같은 이름의 매핑이 있는지 |
고정 매핑이 일반 DNS 결과를 덮어쓸 수 있음 |
| 주 도메인은 적용되지만 하위 도메인은 변하지 않음 | 하위 도메인에 별도 매핑을 작성했는지 | 주 도메인과 하위 도메인은 서로 다른 이름임 |
| 주소는 올바르지만 정책이 잘못됨 | [Rule] 순서와 Global Routing |
Host는 아웃바운드 정책을 선택하지 않음 |
| 로컬 네트워크 이름에 접속할 수 없음 | skip-proxy와 현재 네트워크 대역 |
문제는 Host가 아니라 General에 있을 수 있음 |
Host의 역할
- 입력
- 전체 도메인
- 출력
- IPv4 또는 IPv6 주소
- 영향
- 해석 결과
- 결정하지 않는 항목
- PROXY / DIRECT
주소 매핑이 완료된 뒤에도 요청은 Rule에서 정책 판단을 받아야 합니다.
Rule의 역할
- 입력
- 도메인 또는 대상 주소
- 확인
- 위에서 아래로
- 출력
- 정책
- 기본 처리
- FINAL
Host 매핑으로 분기를 대신하지 말고, Rule로 주소 매핑을 대신하지 마세요.
[URL Rewrite]: 리디렉션, 거부 및 HTTPS 가시성
[URL Rewrite]는 URL 매칭 표현식에 따라 요청 결과를 변경합니다. 일반적인 용도는 302 리디렉션을 반환하거나 reject를 사용해 조건에 맞는 요청을 차단하는 것입니다. 이 기능은 URL을 처리하는 반면 [Rule]은 주로 도메인, 주소 또는 지역을 기준으로 정책을 선택하므로 서로 대체할 수 없습니다.
표현식의 마침표는 이스케이프하고 경로의 경계도 가능한 한 명확하게 작성해야 합니다. 지나치게 넓은 표현식은 페이지, API, 정적 리소스를 동시에 매칭해 웹 페이지 구조가 깨지거나 앱 요청이 실패할 수 있습니다. 작성할 때는 먼저 하나의 테스트 도메인과 하나의 경로로 범위를 제한하고 결과를 확인한 뒤 확대하세요.
[URL Rewrite]
^http://example\.com/old$ http://example.com/new 302
^http://api\.example\.com/private - reject
첫 번째 행은 정확히 일치하는 이전 주소를 새 주소로 리디렉션하며, 끝의 302는 임시 리디렉션 상태입니다. 두 번째 행은 하이픈으로 대체 대상 위치를 표시하고 reject를 처리 동작으로 사용합니다. 필드 사이에는 공백을 사용하며 정규식 내부에 한국어 문장부호를 넣어서는 안 됩니다.
HTTPS 요청의 경로는 암호화된 내용 안에 있으므로 도메인 연결만으로 전체 URL을 확인할 수는 없습니다. HTTPS 경로를 확인하거나 변경하려면 Shadowrocket에서 사용자가 명시적으로 승인한 인증서 및 복호화 범위를 설정하고, 직접 확인한 테스트 도메인에만 활성화해야 합니다. 해당 범위를 설정하지 않았다면 HTTP 예시는 작동하지만 HTTPS 예시는 작동하지 않을 수 있습니다. 이는 암호화 가시성의 차이이며 반드시 정규식 오류를 뜻하지는 않습니다.
- 먼저 시작 기호
^와 종료 기호$를 모두 사용해 정확한 테스트 주소를 제한합니다. - 도메인의 영문 마침표는
\.로 작성해 임의의 문자를 매칭하지 않도록 합니다. - 먼저 규칙 하나만 테스트해 앞쪽의 기존 표현식이 먼저 매칭되는 상황을 배제합니다.
- 페이지 리소스가 누락되면 최근 추가한 Rewrite 행을 잠시 비활성화한 뒤 다시 테스트합니다.
- HTTPS는 확인과 승인이 완료된 도메인 범위에 대해서만 점검합니다.
최소 완성 설정과 가져온 뒤의 점검 절차
네 섹션을 조합할 때는 소수의 테스트 행만 포함한 최소 설정부터 만드는 것이 좋습니다. 최소 설정의 목적은 모든 요구 사항을 다루는 것이 아니라 각 현상을 하나의 행과 연결하는 것입니다. DNS는 General, 주소 덮어쓰기는 Host, 분기는 Rule, URL 동작은 URL Rewrite가 제어합니다.
[General]
bypass-system = true
dns-server = system
skip-proxy = 127.0.0.1, localhost, *.local, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
[Host]
test.example.com = 192.0.2.10
[Rule]
DOMAIN,test.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY
[URL Rewrite]
^http://example\.com/old$ http://example.com/new 302
가져온 뒤 Config로 들어가 해당 설정이 선택되어 있는지 확인하고, Home으로 돌아와 Global Routing을 Config로 설정합니다. 기존 서비스 제공자의 설정 구독을 사용한다면 업데이트 후 로컬 수정 사항이 남아 있는지 다시 확인해야 합니다. 원격 업데이트가 기존 내용을 새 내용으로 교체할 수 있기 때문입니다. URL 형식을 테스트할 때는 https://example.com/sub?token=xxxx처럼 분명한 예시 주소로 필드 위치를 이해할 수 있지만, 예시 값을 실제 사용 가능한 서비스로 간주해서는 안 됩니다.
- 원본 .conf 사본을 보관하고 테스트 파일에는 쉽게 구별할 수 있는 이름을 사용합니다.
- 모든 섹션 이름이 영문 대괄호를 사용하는지, 섹션 이름 뒤에 불필요한 문자가 붙지 않았는지 확인합니다.
- Rule 행이 영문 쉼표를 사용하는지, 정책이 행 끝에 있는지 확인합니다.
- 구체적인 규칙이 일반적인 규칙보다 앞에 있고
FINAL이 마지막에 있는지 확인합니다. - Host의 주소 형식이 올바르고 도메인에 프로토콜 접두사나 경로가 없는지 확인합니다.
- URL Rewrite의 정규식, 대체 대상, 동작 필드 수가 모두 완전한지 확인합니다.
- Home에서 Global Routing을 확인한 다음 해석, 분기, Rewrite를 각각 테스트합니다.
설정이 정상적으로 작동하지 않으면 여러 섹션을 동시에 수정하지 마세요. 먼저 [General]과 FINAL 한 줄만 남겨 기본 연결을 확인합니다. 이후 DOMAIN 테스트 규칙 하나를 추가하고, 다음으로 Host 매핑을 추가한 뒤 마지막에 URL Rewrite를 테스트합니다. 단계적으로 복원하면 오류가 해석, 매칭, Rewrite 중 어디에 있는지 빠르게 확인할 수 있습니다.
설정은 가져와지지만 사용자 지정 Rule이 반응하지 않나요?
먼저 Home에서 Global Routing이 Config인지 확인하고, Config에서 선택한 항목이 방금 편집한 파일인지 확인합니다. 그런 다음 대상 DOMAIN 규칙을 같은 도메인의 DOMAIN-SUFFIX와 FINAL보다 앞에 배치합니다.
Host를 추가했는데도 도메인이 여전히 기존 주소를 사용하나요?
요청에 사용된 도메인이 완전히 같은지 확인하고, 주 도메인과 하위 도메인을 각각 점검합니다. 그런 다음 설정을 다시 선택하고 새 요청을 보내 이전 연결의 결과로 새 매핑을 판단하지 않도록 합니다.
HTTP Rewrite는 작동하지만 HTTPS Rewrite는 작동하지 않나요?
먼저 정규식 자체가 대상 URL과 일치하는지 확인합니다. 경로가 HTTPS 암호화 내용 안에 있다면 해당 테스트 도메인에 대해 사용자가 승인한 인증서 및 복호화 범위가 설정되어 있는지도 확인해야 합니다.
로컬 네트워크 장치에 접속할 때 계속 실패하나요?
장치 주소가 현재 Wi-Fi의 사설 네트워크 대역에 속하는지 확인한 다음, skip-proxy와 IP-CIDR에 해당 범위가 포함되는지 점검합니다. 더 구체적인 앞쪽 규칙이 먼저 다른 정책과 일치하지 않는지도 확인해야 합니다.
기존 설정을 업데이트한 뒤 로컬 수정 사항이 사라졌나요?
원격 설정 업데이트가 현재 내용을 교체할 수 있습니다. 수정하기 전에 별도 사본을 보관하고, 업데이트 후 General, Rule, Host, URL Rewrite 네 섹션을 비교한 뒤 계속 사용할 로컬 규칙을 올바른 순서로 다시 병합하세요.
설정 점검의 최종 판단 기준
설정이 올바른지는 연결 스위치가 켜져 있는지만으로 판단할 수 없습니다. 완전한 검증에는 최소한 네 가지가 포함됩니다. 도메인이 예상한 주소를 얻는지, Global Routing이 예상한 모드인지, 요청이 올바른 정책과 일치하는지, URL Rewrite가 대상 경로에만 영향을 주는지 확인해야 합니다. 각 항목은 명확한 섹션과 구체적인 설정 행으로 연결되어야 합니다.
Shadowrocket은 Apple 플랫폼의 클로즈드 소스 상용 앱으로, iPhone과 iPad를 중심으로 사용합니다. Mac, Apple TV, Apple Vision의 호환성 및 시스템 요구 사항은 App Store 페이지 표기를 기준으로 합니다. 정품 구매 경로는 App Store이며 개발자 이름은 Shadow Launch Technology Limited, 앱 ID는 932747118입니다. 일회성 구매 방식으로 제공됩니다. 클라이언트 구매와 사용자가 이미 보유한 서비스 설정은 별개의 사항입니다.
결론: 재현 가능한 단일 변수 테스트로 설정 검수하기
매번 한 줄만 수정하고 테스트 도메인, 현재 Global Routing, 예상 정책과 실제 현상을 기록하세요. 어떤 행이 어떤 결과를 바꿨는지 안정적으로 재현할 수 있어야 설정 구조를 올바르게 이해했다고 판단할 수 있습니다.