
Reddit OSINT을 사용자 이름으로 수행합니다. 색인된 게시물, 댓글, 삭제된 콘텐츠와 실시간 콘텐츠, 활동 패턴, 노출된 식별자, 그리고 전반적인 노출 점수를 확인합니다.
사용자 이름으로 하는 Reddit OSINT. 사용자 이름을 주면 공개 Reddit 아카이브가 해당 계정에 대해 색인한 모든 것을 반환합니다: 게시물, 댓글, 삭제된 것과 아직 살아 있는 것, 활동 패턴, 유출된 식별자, 그리고 노출 점수.
의존성 없음, API 키 없음, 로그인 없음. 그냥 python3.

python3 reddit_osint.py someuser
동일한 분석은 LLM 클라이언트용 MCP 도구로도 제공됩니다. MCP 서버를 참조하세요.
pip install -r requirements.txt && python mcp_server.py
Reddit은 게시물을 삭제하지만, 제3자 데이터 아카이브는 삭제 이전에 존재했던 사본(또는 최소한 [removed] / [deleted] 표시)을 보관한다. 이 도구는 그러한 아카이브를 조회하여 계정의 활동 프로필을 재구성한다.
이것이 h3kz-reddint 웹 도구의 전제이며, 이 스크립트의 참조 구현이다. 이 스크립트는 해당 파이프라인(두 소스, 병합, PII 정규식, 그래프, 점수)을 테스트와 선택적 프록시 지원을 갖춘 독립 실행형 CLI로 재구현한다.
| 소스 | 설명 | 역할 |
|---|---|---|
Arctic Shift (arctic-shift.photon-reddit.com) | 무료 Reddit 아카이브로, Pushshift의 커뮤니티 운영 후속 서비스. 2022년부터 현재까지를 포괄하며 원본 스크레이프(selftext, removed_by_category, media_metadata, flair)를 보존한다. API 키 불필요, IP당 속도 제한. | 주 소스. 유용한 데이터의 100%를 제공한다. |
PullPush (api.pullpush.io) | 동일한 Reddit 데이터의 또 다른 인덱스(과거 Pushshift 덤프). | 대체 소스. 병렬로 조회되며 id 기준으로 병합된다. 서브레딧 API가 404를 반환하므로 게시물/댓글만 제공한다. |
reddit.com | — | 절대 조회하지 않음. 보고서에서 permalink URL을 생성하는 데만 사용된다. 공식 Reddit API는 사용되지 않으며(로그인 없음), 이것이 정지된 계정에서도 작동하는 이유이다. |
실제 샘플 계정에서 측정한 결과: Arctic Shift는 게시물 39개 / 댓글 139개를 반환했고, PullPush는 ID가 중복되는 게시물 38개를 반환했다. Arctic Shift가 우세하며, --source arctic이 더 빠르고 충분하다.
pip install 불필요. 표준 라이브러리만 사용.pip install pysocks (선택 사항, socks5://에만 필요)pip install -r requirements.txt (FastMCP). CLI에는 필요하지 않음.python3 reddit_osint.py someuser
stdout에 JSON 형식으로 보고서를 출력하며(요약만, 항목별 덤프 제외), 로그는
stderr에 기록합니다.
python3 reddit_osint.py someuser --json report.json
python3 reddit_osint.py someuser --json report.json --quiet > /dev/null
report.json에는 모든 게시물과 댓글(텍스트, 서브레딧, 점수, 날짜, 상태, permalink)이 포함된 all_items 키가 있습니다. 화면 요약에서는 200 KB를 덤프하지 않도록 이를 생략합니다.
python3 reddit_osint.py someuser --subreddit dotnet # one subreddit only
python3 reddit_osint.py someuser --keywords "kubernetes" # posts mentioning X
python3 reddit_osint.py someuser --over18 true # NSFW only
python3 reddit_osint.py someuser --source arctic # single source (faster)
python3 reddit_osint.py someuser --max-pages 10 # cap pagination (100 items/page)
python3 reddit_osint.py someuser --delay 1.0 # slower, better with proxies
python3 reddit_osint.py someuser --rate-limit-retries 0 # fail fast when throttled
python3 reddit_osint.py someuser --proxies proxies.txt
proxies.txt, 한 줄에 프록시 하나. 허용되는 형식:
http://1.2.3.4:8080
https://1.2.3.4:8443
socks5://1.2.3.4:1080
socks5://user:[email protected]:1080
1.2.3.4:8080 # no scheme -> assumed http://
# comments and blank lines are ignored
중복은 제거된다. 파일에 유효한 프록시가 없으면 스크립트는 코드 2로 종료하고 어떤 요청도 하지 않는다.
로테이션. 프록시는 라운드 로빈 방식으로 순환된다. 요청이 차단/속도 제한
코드로 돌아오면, 해당 프록시는 --cooldown초 동안 쿨다운 상태가 되고 스크립트는 다음 프록시로 넘어간다:
| 플래그 | 기본값 | 하는 일 |
|---|---|---|
--proxies FILE | — | 프록시 목록. 없으면: 직접 연결. |
--cooldown SECONDS | 30 | 차단된 프록시가 제외 상태로 유지되는 시간. |
--max-attempts N | (proxies+1) × 3 | 포기하기 전 요청당 최대 시도 횟수. |
--no-direct-fallback | off | 모든 프록시가 쿨다운 중일 때 직접 연결하는 대신 대기. |
--shuffle-proxies | off | 시작 시 목록을 섞음 (첫 요청부터 부하를 분산). |
--proxy-stats | off | 보고서에 proxy_stats를 추가: 프록시별 ok / banned / errors. |
--rate-limit-retries N | 2 | API가 429/422를 응답할 때 지수 백오프(30초, 60초, 최대 120초)로 전체 페이지를 재시도. |
차단으로 처리되는 코드(프록시를 로테이션시키는 코드): 401 403 407 422 429 500 502 503 504 520 521 522 523 524, 그리고 본문에 slow down / rate limit /
too many requests / timeout이 포함된 모든 400/409. Arctic Shift는 속도 제한에
**422 "Timeout. Maybe slow down a bit"**를 사용하므로, 의도적으로 차단으로 처리된다.
404는 로테이션시키지 않는다: 이는 잘못된 프록시가 아니라 잘못된 요청이며, 다른 곳에서
재시도해도 해결되지 않는다.
백오프. 차단 후에는 min(cooldown, 10 s)만큼 대기한다 — 이는 직접 연결에도 적용되며,
여기서 가장 큰 영향을 준다. 페이지가 시도 횟수를 모두 소진하면, fetch_all은 지수 백오프로
페이지를 재시도한다(--rate-limit-retries, 기본 2회 시도 = 30초와 60초). 이것이 실행 중
속도 제한에 걸렸을 때 스크립트가 댓글을 조용히 잃는 것을 막아준다.
로테이션이 포함된 샘플 로그:
[proxy] http://1.2.3.4:8080 blocked (429), backing off 10s -> rotating
[proxy] http://5.6.7.8:1080 failed (Connection refused), rotating
[proxy] direct connection blocked (422), backing off 10s -> rotating
[!] arctic/comments rate limited, backing off 30s (retry 1/2)
모든 프록시가 쿨다운 중일 때, 스크립트는 남은 쿨다운 중 가장 긴 시간을 기다린 후 재시도합니다
(또는 --no-direct-fallback이 전달되지 않은 경우 직접 연결을 사용합니다).
경고: 프록시는 사용자의 IP가 제3자에게 도달하는 이그레스 경로입니다. 프록시 공급업체를 신뢰하지 않는다면, 이 도구와 함께 프록시를 사용하지 마십시오.
| 변수 | 용도 |
|---|---|
REDDIT_OSINT_ARCTIC | Arctic Shift URL 재정의 (미러, 테스트). |
REDDIT_OSINT_PULLPUSH | PullPush URL 재정의. |
id, title, selftext, body, author, subreddit, created_utc, score, permalink,
url, over_18, num_comments, link_flair_text, preview.images, media_metadata,
removed_by_category.
| 상태 | 감지 |
|---|---|
removed | 텍스트 = [removed] 또는 [ Removed by Reddit ], 또는 removed_by_category 존재 (게시물) → 중재자가 제거함. |
deleted | 텍스트 = [deleted] 또는 author == "[deleted]" → 작성자가 삭제함. |
live | 그 외 모든 경우. |
이것이 이 도구의 핵심입니다: 아카이브는 콘텐츠가 없더라도 제거의 사실을 포착하며, 그것만으로도 유용한 메타데이터입니다.
deleted_pct와 함께 live/removed/deleted 분석.total_karma, post_karma, comment_karma, num_posts,
num_comments, earliest_post_at, last_comment_at (/api/users/search에서).Americas (UTC-8..UTC-5)Europe / Middle East / Africa (UTC+0..UTC+3)Asia / Oceania (UTC+7..UTC+11)Unknown / distributed| 유형 | 패턴 |
|---|---|
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} (잘못된 .png/.jpg 매칭 거부) | |
| BTC | bc1… (bech32), 1… / 3… (legacy/base58), 26–59자 |
| ETH | 0x + 40 hex |
| XMR | 4 + 94자 (총 95자) |
| Telegram | t.me/<user>, telegram: @<user> |
| Phone | 구분자가 있는 10–15자리 숫자 |
| Domains | 모든 https?://host (reddit.com, redd.it, redditmedia.com, imgur.com 제외) |
| Mentions | u/<username> (대상 계정 자체는 제외) |
이들은 identifiers, external_domains, mentioned_users 아래에 나타납니다.
score_exposure_0_100: 콘텐츠가 계정 뒤의 인물을 식별할 가능성. 이메일(10),
BTC(8), ETH/XMR(6), Telegram/전화(4), 도메인/멘션(각 2)에 가중치를 부여하고,
30으로 나눈 후 100으로 상한을 둡니다. PII 노출이 없는 프로필은 0점입니다.
분류 용도로 사용하십시오: 높은 점수는 "해킹됨"을 의미하지 않고, "이 텍스트를 주의해서 다루라"는 의미입니다.collect() -> fetch_all() for each (source, kind)
|
+-> build_search_url() GET .../search?limit=100&sort=asc&author=U&after=<ts>
+-> PoolSession.get() PoolSession -> ProxyPool.pick() -> urllib
| 429/403 -> flag proxy, rotate, wait cooldown
+-> dedup by id Set over rows from both sources
+-> cursor = min(created_utc) + 1 and page again
|
analyze() -> status, counters, histograms, regexes, score
중요한 세부 사항: