[남용 금지] AWS Lambda에서 Tor 사용
39260 단어 TypeScriptLambdaTortech
※ 설치는 타입 스크립트에 따라 진행됩니다.
계층형 Tor
'브라우저'이 있어 오해받기 쉽지만, 타워는 타워 브라우저에만 국한된 것이 아니라 평소 사용하던 크롬과 같은 일반적인 브라우저도'타워화'할 수 있는 자체 실행
tor
명령이다.tor
명령은 여기.의 Tor 프로젝트에서 버전 관리를 하고 다운로드와 컴파일을 통해 누구나 쉽게 사용할 수 있다.또한 자신이 컴파일하지 않아도 예를 들어 MacOS는 Homebrewbrew install tor
를 통해 간단하게 설치할 수 있다.Lambda에서 사용하면 Linux 환경에서 컴파일된 파일을 사용하지 않으면 오류가 발생할 수 있으므로 Docker 컨테이너에서 다운로드하고 컴파일하는 것이 좋습니다.이번에는 그 절차를 생략하지만, zip화된 물건을 미리 컴파일해서 여기. 창고에 준비했기 때문에, zip 파일을 람바다 도면층으로 업로드하기만 하면 간단하게 참조할 수 있습니다.실행 파일의 경로는
/opt/bin/tor
입니다.또 창고 안
serverless.yml
에도 같이 쓰여 있기 때문에 실행sls deploy
만 하면 업로드를 완료할 수 있다.tor
파일 자체는 15MB 미만이며 Lambda로 처리하기에 충분한 크기입니다.Headless Chrome
※ 최종 결과는 GiitHub 웨어하우스 올라왔습니다.우리도 서버리스를 지원합니다.
Tor의 도면화가 끝났기 때문에 다음에는 Headless Chrome에서 호출하기만 하면 됩니다.예전에는 헤드리스화를 위해 애를 썼던 기억이 나는데, 지금은 간단하게 설치해서 사용할 수 있게 되었다.
$ yarn add chrome-aws-lambda
에 모듈을 설치한 후 아래의 chromium
만 가져오면 준비가 완료됩니다.import chromium from 'chrome-aws-lambda'
다음await chromium.puppeteer.launch({ options })
Headless Chrome을 시작할 수 있습니다.Lambda에서 Tor 사용하기tor
options
에서 Tor를 사용하는 의미이런 흐름.
Tor의 모듈식(클래스)
간단하게 가동
tor
할 수 있도록 분류부터 할게요.tor
설정 파일로 본 .torrc
파일로 다음 2개를 써야 한다.SOCKSPort
: SOCKS 프록시 통신 포트DataDirectory
: 데이터 송수신 디렉터리 경로.torrc
및 DataDirectory
에 대응하는 디렉터리를 만들 수 있습니다.그 결과 주로 이루어져야 할 부분은 다음과 같은 세 가지가 있다.
tor
의 실행 /* tor.ts */
import { spawn, execSync, ChildProcessWithoutNullStreams } from 'child_process'
import tempfile from 'tempfile'
import { IS_LOCAL } from './env' // ローカル環境かどうかの判別。ファイルの中身は後述
export default class Tor {
port: number // SOCKSPort に対応
dataDir: string // DataDirectory に対応
torrcPath: string // 一時ファイルとしての .torrc のパス
torPath: string = `/opt/bin/tor`
proc: ChildProcessWithoutNullStreams
constructor(port: number) {
this.port = port
}
async launch() {
if (IS_LOCAL) { // ローカルでは tor は起動済という前提
return
}
this.createTempfiles() // 一時ファイル・ディレクトリを作成
// tor の起動には時間がかかるため Promise を返しておく
return new Promise((resolve, reject) => {
// tor の起動
this.proc = spawn(this.torPath, ['-f', this.torrcPath], {
cwd: this.dataDir,
})
// 起動完了まで待機
this.proc.stdout.on('data', (data: Buffer) => {
if (data.toString().match(/100%/)) { // 起動完了
resolve()
}
})
this.proc.stderr.on('data', (data) => {
reject(`Failed tor initialization: ${data}`)
})
this.proc.on('close', (code) => {
if (code) {
reject()
} else {
resolve()
}
})
})
}
createTempfiles() {
// 一時ファイル・ディレクトリのパス生成
this.dataDir = tempfile('.data')
this.torrcPath = tempfile('.torrc')
// .data および .torrc の作成
const cmds = [
`mkdir ${this.dataDir}`,
`touch ${this.torrcPath}`,
`echo 'SOCKSPort ${this.port}\n' > ${this.torrcPath} && echo 'DataDirectory ${this.dataDir}\n' >> ${this.torrcPath}`,
]
for (let cmd of cmds) {
execSync(cmd)
}
}
close() {
if (IS_LOCAL) {
return
}
// tor の終了
this.proc.kill('SIGINT')
const cmds = [`rm -rf ${this.dataDir}`, `rm -rf ${this.torrcPath}`]
for (let cmd of cmds) {
execSync(cmd)
}
}
}
상기 코드 내의 env
파일은 다음과 같다./* env.ts */
export const IS_LOCAL = process.env.IS_LOCAL === 'true' ? true : false
로컬에서 Lambda를 시도할 수 있는 경우 serverless-offline
$ sls invoke local -f <function_name>
로 실행할 수 있는 함수로서 이 설정IS_LOCAL=true
환경 변수입니다.boolean으로 잘 평가할 수 있도록 기술한 것이다.Headless Chromew/Tor의 모듈식(분류)
그럼 여기까지는 헤드리스 크롬과 토어를 활용할 준비가 됐으니 둘을 조합해 사용할 수 있도록 실장해 주세요.
위에서 설명한 대로 Tor는
chromium.puppeteer.launch({ options })
의 매개변수에서만 사용됩니다./* browser.ts */
import 'source-map-support/register'
import chromium from 'chrome-aws-lambda'
import { Browser } from 'puppeteer-core'
import { IS_LOCAL } from './env'
import os from './os' // ローカルで Win/Mac の判別用。ファイルの中身は後述
import Tor from './tor'
// Tor のポート
const PORT = 9050
// Chromium のデフォルトのユーザーエージェントは `webdriver`
export const UA =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5)' +
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'
// ローカルの場合は、インストールしてある Chrome を起動
let path: string = ''
switch (os) {
case 'win':
path = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
break
case 'mac':
path = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
break
}
export interface LaunchOptions {
headless?: boolean
useTor?: boolean
}
export class Chrome {
browser?: Browser // Headless Chrome 本体
tor: Tor | undefined
async launch({ headless, useTor }: LaunchOptions) {
headless = headless === false ? false : true
let { args } = chromium
if (useTor) {
// 事前に tor を実行
this.tor = new Tor(PORT)
await this.tor.launch()
// Tor を利用するために、引数にSOCKSプロキシの設定を追加
args.push(`--proxy-server=socks5://127.0.0.1:${PORT}`)
}
this.browser = await chromium.puppeteer.launch({
args,
defaultViewport: chromium.defaultViewport,
executablePath: IS_LOCAL ? path : await chromium.executablePath,
headless,
ignoreHTTPSErrors: true,
})
}
async close() {
if (this.tor) {
this.tor.close()
}
if (this.browser != null) {
await this.browser.close()
}
}
}
코드 내의 OS 판별은 아래 설치를 통해 진행된다./* os.ts */
export const platform = process.platform
export let os: 'win' | 'mac' | 'linux' | 'unknown' = 'unknown'
switch (platform) {
case 'win32':
os = 'win'
break
case 'darwin':
os = 'mac'
break
case 'linux':
os = 'linux'
break
}
export default os
다음const chrome = new Chrome({ headless: true, useTor: true })
면 Tor 브라우저화가 완료됩니다.Let's Try!
실제로 해보세요!
/* main.ts */
import 'source-map-support/register'
import { Handler } from 'aws-lambda'
import { Chrome } from './browser'
export const handler: Handler = async (_event, _context, callback) => {
const chrome = new Chrome()
const url = 'https://ipinfo.io/'
let content: string[]
try {
await chrome.launch({ headless: true, useTor: true })
const page = await chrome.browser.newPage()
await page.goto(url, { waitUntil: 'networkidle2' })
await page.waitForSelector('.json-widget-entry')
content = await page.$$eval('.json-widget-entry', (elems: any) => {
return elems.map((el: any) =>
(el.textContent as string).replace(/\n|\s/g, '')
)
})
} catch (e) {
console.error(e, e.stack)
return callback(e, null)
} finally {
await chrome.close()
}
return callback(null, content)
}
위에서 디버깅 및 실행결과
[
...
"city:\"Wiesbaden\"",
"region:\"Hesse\"",
"country:\"DE\"",
...
"tor:true",
]
로 해외 방문이 확인됐다.tor:true
라는 표시가 있어'Tor화'가 가능하다는 것도 안다.지금까지 설치였습니다!람다에서 Tor화하는 것은 사실 매우 간단하다는 것을 여러분이 알고 싶습니다.이렇게 되면 자신의 신분을 숨길 수 있지만 절대 남용하지 마세요.
(또한, 위에서 말한 바와 같이
tor:true
Tor인지 아닌지를 판단할 수 있기 때문에 서비스에 따라 탄주 방문도 있습니다.)창고. 내에
Chrome
류에서도 preventBotDetection
의 코드를 기술했다.크롬을 통한 방문을 숨기기 위해 실시된 것으로, 이 내용에 대해서는 다른 기회에 소개하고 싶다.
Reference
이 문제에 관하여([남용 금지] AWS Lambda에서 Tor 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/yusugomori/articles/cadf35f5f26a50fe9401텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)