
12ft.io 및 1ft.io의 자체 호스팅 대안. CORS 헤더를 제거하고 HTML을 수정하는 프록시.
<p align="center">
<img src="https://raw.githubusercontent.com/everywall/ladder/HEAD/assets/pigeon.svg" width="100px">
</p>
<h1 align="center">Ladder</h1>
<div><img alt="License" src="https://img.shields.io/github/license/everywall/ladder"> <img alt="go.mod Go version " src="https://img.shields.io/github/go-mod/go-version/everywall/ladder"> <img alt="GitHub tag (with filter)" src="https://img.shields.io/github/v/tag/everywall/ladder"> <img alt="GitHub (Pre-)Release Date" src="https://img.shields.io/github/release-date-pre/everywall/ladder"> <img alt="GitHub Downloads all releases" src="https://img.shields.io/github/downloads/everywall/ladder/total"> <img alt="GitHub Build Status (with event)" src="https://img.shields.io/github/actions/workflow/status/everywall/ladder/release-binaries.yaml"></div>
*Ladder는 http 웹 프록시입니다.*
[简体中文](https://github.com/everywall/ladder/blob/main/README.zh-CN.md)
Ladder는 최신 웹사이트에서 페이월(paywall) 구현 및 콘텐츠 전달 동작을 테스트하고 분석하기 위한 개발자 도구입니다.
개발자, 연구자, 게시자는 다양한 클라이언트 환경(예: 브라우저 및 크롤러)을 시뮬레이션하고 다양한 조건에서 콘텐츠가 제공되는 방식을 관찰할 수 있습니다. 이를 통해 페이월 구성을 디버깅하고, 액세스 제어 및 http 헤더를 검증하며, 다양한 사용자 에이전트에서 일관된 동작을 보장하는 데 유용합니다.
Ladder는 합법적인 테스트, 연구 및 품질 보증 목적으로만 사용됩니다. 반드시 관련 법률과 대상 웹사이트의 서비스 약관을 준수하여 사용해야 합니다.

### 작동 원리
```mermaid
sequenceDiagram
client->>+ladder: GET
ladder-->>ladder: apply RequestModifications
ladder->>+website: GET
website->>-ladder: 200 OK
ladder-->>ladder: apply ResultModifications
ladder->>-client: 200 OK
```
### 기능
- [x] 응답, 에셋, 이미지의 CORS 헤더 제거/수정 ...
- [x] 기타 헤더 제거/수정 (예: Content-Security-Policy)
- [x] 페이지에서 커스텀 코드(HTML, CSS, JavaScript) 제거/삽입
- [x] 도메인 기반 규칙셋/코드를 적용하여 응답/요청 URL 수정
- [x] 사이트 탐색 가능 상태 유지
- [x] API
- [x] RAW HTML 가져오기
- [x] 사용자 정의 User Agent
- [x] 사용자 정의 X-Forwarded-For IP
- [x] [Docker 컨테이너](https://github.com/everywall/ladder/pkgs/container/ladder) (amd64, arm64)
- [x] Linux 바이너리
- [x] Mac OS 바이너리
- [x] Windows 바이너리(테스트되지 않음)
- [x] Basic Auth
- [x] 액세스 로그
- [x] 추적, 광고 및 기타 타사 콘텐츠를 손상시킬 수 있음
- [x] 프록시를 도메인 목록으로 제한
- [x] 규칙셋을 다른 Ladder에 노출
- [ ] Robots.txt 테스트
- [ ] 선택적 TOR 프록시
- [ ] 프록시된 URL을 공유하는 키
### 제한 사항
일부 웹사이트는 접근하는 클라이언트 유형(예: 검색 엔진 크롤러 vs. 일반 웹 브라우저)에 따라 다른 콘텐츠(Cloaking)를 제공합니다. Ladder는 테스트, 자동화 또는 연구 목적으로 공개적으로 접근 가능한 콘텐츠를 검색하기 위해 다양한 클라이언트 유형을 에뮬레이션하도록 구성할 수 있습니다.
그러나 많은 웹사이트는 핑거프린팅, 속도 제한, 행동 분석 등 자동화된 접근을 제한하는 고급 메커니즘을 구현합니다. Ladder는 이러한 보호를 우회하지 않으며, 적극적으로 접근을 제한하거나 통제하는 서비스에서는 제대로 작동하지 않을 수 있습니다.
FlareSolverr와 같은 타사 도구가 존재하며, 헤드리스 브라우저 환경에서 웹 페이지를 렌더링하기 위해 독립적으로 사용될 수 있습니다. 이러한 도구는 Ladder의 일부가 아니며, 사용 시 법적 및 계약상 제한을 받을 수 있습니다. 사용자는 자신의 사용이 모든 관련 규정을 준수하는지 확인할 전적인 책임이 있습니다.
## 설치
> **경고:** 인스턴스를 공개적으로 접근 가능하게 할 경우 Basic Auth를 활성화하십시오. 이렇게 하면 권한 없는 사용자가 프록시를 사용하는 것을 방지할 수 있습니다. Basic Auth를 활성화하지 않으면 누구나 프록시를 사용하여 불쾌하거나 불법적인 콘텐츠를 탐색할 수 있으며, 이에 대한 책임은 사용자에게 있습니다.
### 바이너리
1) [여기](https://github.com/everywall/ladder/releases/latest)에서 바이너리 다운로드
2) 바이너리의 압축을 풀고 `./ladder -r https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml` 실행
3) 브라우저 열기 (기본값: http://localhost:8080)
### Docker
```bash
docker run -p 8080:8080 -d --env RULESET=https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml --name ladder ghcr.io/everywall/ladder:latest
```
### Docker Compose
```bash
curl https://raw.githubusercontent.com/everywall/ladder/main/docker-compose.yaml --output docker-compose.yaml
docker-compose up -d
```
### Helm
자세한 정보는 helm-chart 하위 디렉터리의 [README.md](https://github.com/everywall/ladder/blob/main/helm-chart/README.md)를 참조하세요.
## 사용법
### 브라우저
1) 브라우저 열기 (기본값: http://localhost:8080)
2) URL 입력
3) Enter 키 누르기
또는 URL을 프록시 URL 끝에 추가하여 직접 접근:
http://localhost:8080/https://www.example.com
또는 다음 URL로 북마크 생성:
```javascript
javascript:window.location.href="http://localhost:8080/"+location.href
```
### API
```bash
curl -X GET "http://localhost:8080/api/https://www.example.com"
```
### RAW
http://localhost:8080/raw/https://www.example.com
### 규칙셋 실행
http://localhost:8080/ruleset
## 구성
### 환경 변수
| 변수 | 설명 | 값 |
| --- | --- | --- |
| `PORT` | 수신 대기 포트 | `8080` |
| `PREFORK` | 여러 서버 인스턴스 생성 | `false` |
| `USER_AGENT` | 에뮬레이션할 사용자 에이전트 | `Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)` |
| `X_FORWARDED_FOR` | IP 전달자 주소 | `66.249.66.1` |
| `USERPASS` | Basic Auth 활성화, 형식 `admin:123456` | `` |
| `LOG_URLS` | 가져온 URL 로깅 | `true` |
| `DISABLE_FORM` | URL 양식 첫 페이지 비활성화 | `false` |
| `FORM_PATH` | 커스텀 Form HTML 경로 | `` |
| `RULESET` | 규칙셋 파일의 경로 또는 URL, 로컬 디렉터리 허용 | `https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml` 또는 `/path/to/my/rules.yaml` 또는 `/path/to/my/rules/` |
| `EXPOSE_RULESET` | 규칙셋을 다른 Ladder에서 사용 가능하게 함 | `true` |
| `ALLOWED_DOMAINS` | 허용 도메인의 쉼표로 구분된 목록. 비어 있음 = 제한 없음 | `` |
| `ALLOWED_DOMAINS_RULESET` | 규칙셋의 도메인 허용. false = 제한 없음 | `false` |
| `FLARESOLVERR_HOST` | Cloudflare 우회를 위한 FlareSolverr 서비스 URL (선택 사항) | `http://localhost:8191` |
`ALLOWED_DOMAINS`와 `ALLOWED_DOMAINS_RULESET`은 함께 결합됩니다. 둘 다 비어 있으면 제한이 적용되지 않습니다.
| `BASE_PATH` | 프록시의 기본 경로. 하위 경로에서 프록시를 실행하려는 경우 유용합니다 (예: http://localhost:8080/proxy/) | `` |
### 규칙셋
응답 또는 요청된 URL을 수정하기 위해 사용자 정의 규칙을 적용할 수 있습니다. 이는 페이지에서 원하지 않는 요소를 제거하거나 수정하는 데 사용할 수 있습니다. 규칙셋은 YAML 파일, YAML 파일이 있는 디렉터리 또는 각 도메인에 대한 규칙 목록이 포함된 YAML 파일의 URL입니다. 이러한 규칙은 시작 시 로드됩니다.
기본 규칙셋은 별도의 저장소 [ruleset.yaml](https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml)에서 사용할 수 있습니다. 자신만의 규칙을 추가하고 풀 리퀘스트를 생성하세요.
```yaml
- domain: example.com # Includes all subdomains
domains: # Additional domains to apply the rule
- www.example.de
- www.beispiel.de
headers:
x-forwarded-for: none # override X-Forwarded-For header or delete with none
referer: none # override Referer header or delete with none
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
content-security-policy: script-src 'self'; # override response header
cookie: privacy=1
regexRules:
- match: <script\s+([^>]*\s+)?src="(/)([^"]*)"
replace: <script $1 script="/https://www.example.com/$3"
injections:
- position: head # Position where to inject the code
append: | # possible keys: append, prepend, replace
<script>
window.localStorage.clear();
console.log("test");
alert("Hello!");
</script>
- domain: www.anotherdomain.com # Domain where the rule applies
useFlareSolverr: false # Use FlareSolverr for Cloudflare bypass (optional, default: false)
paths: # Paths where the rule applies
- /article
googleCache: false # Use Google Cache to fetch the content
regexRules: # Regex rules to apply
- match: <script\s+([^>]*\s+)?src="(/)([^"]*)"
replace: <script $1 script="/https://www.example.com/$3"
injections:
- position: .left-content article .post-title # Position where to inject the code into DOM
replace: |
<h1>My Custom Title</h1>
- position: .left-content article # Position where to inject the code into DOM
prepend: |
<h2>Subtitle</h2>
- domain: demo.com
headers:
content-security-policy: script-src 'self';
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
urlMods: # Modify the URL
query:
- key: amp # (this will append ?amp=1 to the URL)
value: 1
domain:
- match: www # regex to match part of domain
replace: amp # (this would modify the domain from www.demo.de to amp.demo.de)
path:
- match: ^ # regex to match part of path
replace: /amp/ # (modify the url from https://www.demo.com/article/ to https://www.demo.de/amp/article/)
```
## FlareSolverr 통합
Ladder는 이제 Cloudflare 보호 및 기타 안티봇 챌린지를 우회하기 위해 [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr) 통합을 지원합니다. 이는 정교한 봇 탐지 메커니즘을 사용하는 사이트에 특히 유용합니다.
### FlareSolverr 설정
1. **Docker Compose 사용 (권장):**
```yaml
# docker-compose.yaml
services:
ladder:
image: ghcr.io/everywall/ladder:latest
ports:
- "8080:8080"
environment:
- RULESET=https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml
# - FLARESOLVERR_HOST=http://flaresolverr:8191
depends_on:
- flaresolverr
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
ports:
- "8191:8191"
environment:
- LOG_LEVEL=info
```
2. **FlareSolverr 별도 실행:**
```bash
docker run -d \
--name flaresolverr \
-p 8191:8191 \
ghcr.io/flaresolverr/flaresolverr:latest
```
그런 다음 FlareSolverr URL로 Ladder를 시작합니다:
```bash
FLARESOLVERR_HOST=http://localhost:8191 ./ladder
```
### FlareSolverr용 규칙 구성
특정 도메인에 FlareSolverr를 사용하려면 규칙셋에 `useFlareSolverr: true` 플래그를 추가하세요:
```yaml
# Example ruleset with FlareSolverr
- domain: cloudflare-protected-site.com
useFlareSolverr: true # Enable FlareSolverr for this domain
headers:
user-agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
# Regular site without FlareSolverr
- domain: regular-site.com
headers:
user-agent: "Custom User Agent 1.0"
```
### 사용 사례
FlareSolverr 통합은 특히 다음 경우에 유용합니다:
- **Cloudflare로 보호되는 사이트**: Cloudflare의 안티봇 챌린지를 사용하는 사이트
- **JavaScript 챌린지가 있는 사이트**: 콘텐츠에 접근하기 위해 JavaScript 실행이 필요한 페이지
- **동적 콘텐츠 로딩**: JavaScript를 통해 콘텐츠를 동적으로 로드하는 사이트
- **고급 봇 탐지**: 정교한 핑거프린팅 및 봇 탐지 기술을 사용하는 사이트
### 중요 참고 사항
- FlareSolverr는 챌린지를 해결해야 하므로 요청에 추가 지연 시간이 발생합니다
- 성능을 유지하려면 실제로 필요한 도메인에만 `useFlareSolverr`을 활성화하세요
- FlareSolverr는 헤드리스 브라우저를 실행하므로 더 많은 리소스가 필요합니다
- 규칙셋에서 활성화하기 전에 FlareSolverr가 실행 중이고 접근 가능한지 확인하세요
## 개발
http://localhost:8080에서 개발 서버를 실행하려면:
```bash
echo "dev" > handlers/VERSION
RULESET="./ruleset.yaml" go run cmd/main.go
```
### 선택 사항: [cosmtrek/air](https://github.com/cosmtrek/air)를 사용한 실시간 리로드 개발 서버
[설치 지침](https://github.com/cosmtrek/air#installation)에 따라 air를 설치합니다.
http://localhost:8080에서 개발 서버를 실행합니다:
```bash
air # or the path to air if you haven't added a path alias to your .bashrc or .zshrc
```
이 프로젝트는 [pnpm](https://pnpm.io/)을 사용하여 [Tailwind CSS](https://tailwindcss.com/) 클래스로 스타일시트를 빌드합니다. 로컬 개발 시 `form.html`에서 스타일을 수정하는 경우 `pnpm build`를 실행하여 새 스타일시트를 생성하세요.