Upload 2 files
Browse files- Dockerfile +49 -0
- app.py +51 -0
Dockerfile
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Use the official Alpine image as the base
|
2 |
+
FROM docker.io/library/alpine:latest@sha256:8a1f59ffb675680d47db6337b49d22281a139e9d709335b492be023728e11715
|
3 |
+
|
4 |
+
# Switch to root user to install dependencies
|
5 |
+
USER root
|
6 |
+
|
7 |
+
# Install Tor, Nyx, Python, and pip
|
8 |
+
RUN apk update && apk upgrade && \
|
9 |
+
apk add tor nyx python3 py3-pip && \
|
10 |
+
rm -rf /var/cache/apk/*
|
11 |
+
|
12 |
+
# Create a virtual environment and install Python dependencies
|
13 |
+
RUN python3 -m venv /venv
|
14 |
+
ENV PATH="/venv/bin:$PATH"
|
15 |
+
RUN pip install --no-cache-dir fastapi uvicorn requests pysocks
|
16 |
+
|
17 |
+
# Create Tor data directory and set permissions
|
18 |
+
RUN mkdir -p /var/lib/tor && \
|
19 |
+
chown 1000:1000 /var/lib/tor && \
|
20 |
+
chmod 700 /var/lib/tor
|
21 |
+
|
22 |
+
# Configure torrc
|
23 |
+
RUN echo "SocksPort 0.0.0.0:9050" >> /etc/tor/torrc && \
|
24 |
+
echo "ControlPort 9051" >> /etc/tor/torrc && \
|
25 |
+
echo "CookieAuthentication 1" >> /etc/tor/torrc && \
|
26 |
+
echo "Log notice stdout" >> /etc/tor/torrc && \
|
27 |
+
echo "DataDirectory /var/lib/tor" >> /etc/tor/torrc
|
28 |
+
|
29 |
+
# Set permissions for torrc
|
30 |
+
RUN chmod 644 /etc/tor/torrc && chown 1000:1000 /etc/tor/torrc
|
31 |
+
|
32 |
+
# Create app directory and copy the FastAPI app
|
33 |
+
RUN mkdir -p /app
|
34 |
+
COPY app.py /app/app.py
|
35 |
+
|
36 |
+
# Verify app.py exists, is readable, and contains the expected content
|
37 |
+
RUN ls -la /app && \
|
38 |
+
cat /app/app.py && \
|
39 |
+
chmod 644 /app/app.py && \
|
40 |
+
chown 1000:1000 /app/app.py
|
41 |
+
|
42 |
+
# Expose ports (9050 for Tor SOCKS, 7860 for FastAPI)
|
43 |
+
EXPOSE 9050 7860
|
44 |
+
|
45 |
+
# Switch to non-root user (Hugging Face runs as UID 1000)
|
46 |
+
USER 1000
|
47 |
+
|
48 |
+
# Start Tor in the background and run FastAPI
|
49 |
+
CMD sh -c "tor -f /etc/tor/torrc & sleep 10 && /venv/bin/uvicorn --app-dir /app app:app --host 0.0.0.0 --port 7860"
|
app.py
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI
|
2 |
+
import requests
|
3 |
+
import socks
|
4 |
+
import socket
|
5 |
+
import logging
|
6 |
+
import time
|
7 |
+
|
8 |
+
app = FastAPI(title="Tor IP Checker")
|
9 |
+
|
10 |
+
# Configure logging
|
11 |
+
logging.basicConfig(level=logging.INFO)
|
12 |
+
logger = logging.getLogger(__name__)
|
13 |
+
|
14 |
+
@app.get("/")
|
15 |
+
async def check_tor_ip():
|
16 |
+
max_retries = 3
|
17 |
+
retry_delay = 5
|
18 |
+
for attempt in range(max_retries):
|
19 |
+
try:
|
20 |
+
with requests.Session() as session:
|
21 |
+
session.proxies = {
|
22 |
+
"http": "socks5h://localhost:9050",
|
23 |
+
"https": "socks5h://localhost:9050"
|
24 |
+
}
|
25 |
+
|
26 |
+
logger.info("Requesting IP via Tor proxy...")
|
27 |
+
response = session.get("https://check.torproject.org/api/ip", timeout=10)
|
28 |
+
response.raise_for_status()
|
29 |
+
|
30 |
+
data = response.json()
|
31 |
+
ip_address = data.get("IP", "Unknown")
|
32 |
+
is_tor = data.get("IsTor", False)
|
33 |
+
|
34 |
+
return {
|
35 |
+
"status": "success",
|
36 |
+
"tor_enabled": is_tor,
|
37 |
+
"ip_address": ip_address,
|
38 |
+
"message": "You are using Tor!" if is_tor else "You are not using Tor."
|
39 |
+
}
|
40 |
+
|
41 |
+
except requests.RequestException as e:
|
42 |
+
logger.error(f"Attempt {attempt + 1}/{max_retries} - Error: {str(e)}")
|
43 |
+
if attempt < max_retries - 1:
|
44 |
+
time.sleep(retry_delay)
|
45 |
+
continue
|
46 |
+
return {
|
47 |
+
"status": "error",
|
48 |
+
"tor_enabled": False,
|
49 |
+
"ip_address": "Unknown",
|
50 |
+
"message": f"Failed to check Tor IP after {max_retries} attempts: {str(e)}"
|
51 |
+
}
|