如何在Flask结合Stem的Tor隐藏服务中使用Socket?
Hey there! Let's break down how you can integrate Socket functionality with your existing Flask + Tor hidden service setup. I'll cover two common approaches depending on what you're trying to build:
If you want to add real-time web features (like chat, live updates) to your Tor hidden service, Flask-SocketIO is the way to go—it integrates seamlessly with Flask and works over Tor's hidden service network.
Step 1: Install Dependencies
First, install the required packages:
pip install flask-socketio eventlet
Eventlet is required because Flask's default Werkzeug server doesn't support long-lived WebSocket connections.
Step 2: Update Your Code
Here's how to modify your existing code to include SocketIO, while keeping the Tor hidden service setup intact:
import os from stem.control import Controller from flask import Flask from flask_socketio import SocketIO, emit app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key-here' # Required for SocketIO security socketio = SocketIO(app, cors_allowed_origins="*") # Allow cross-origin (safe for hidden services) # Your existing Flask route @app.route('/') def index(): return "Hello from Flask + Tor! Check the console for Socket events." # SocketIO event handler for incoming messages @socketio.on('message') def handle_message(data): print(f"Received message: {data}") emit('response', f"Echo: {data}") # Send a response back to the client if __name__ == '__main__': print(' * Connecting to Tor control port') with Controller.from_port(port=9051) as controller: controller.authenticate() # Add your Tor control password if set, e.g., controller.authenticate("your-pass") # Set up hidden service directory in Tor's data folder data_dir = controller.get_conf('DataDirectory') hidden_service_dir = os.path.join(data_dir, 'my_hidden_service') # Configure Tor to map hidden service port 80 to local port 5000 (where Flask-SocketIO runs) controller.set_options([ ("HiddenServiceDir", hidden_service_dir), ("HiddenServicePort", "80 127.0.0.1:5000") ]) # Fetch and print your .onion hostname with open(os.path.join(hidden_service_dir, 'hostname')) as f: hostname = f.read().strip() print(f" * Tor hidden service running at: {hostname}") # Run Flask-SocketIO with eventlet server (supports WebSockets) socketio.run(app, host='127.0.0.1', port=5000, debug=False) # Disable debug for production
How It Works
- Tor will expose your Flask-SocketIO app at the
.onionhostname, and WebSocket traffic will be routed through Tor automatically. - Clients can connect to the SocketIO endpoint using the
.onionURL (e.g.,http://<your-onion-hostname>/socket.io/) just like a regular web Socket.
If you need a separate, non-web Socket server (e.g., for custom TCP/UDP communication), you can run it alongside your Flask app and configure Tor to expose that port too.
Step 1: Create a Standalone Socket Server
Here's a simple TCP Socket server example:
import socket import threading def run_socket_server(): host = '127.0.0.1' port = 5001 # Local port for the Socket server server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(5) print(f" * Socket server listening on {host}:{port}") while True: client_socket, addr = server_socket.accept() print(f" * Connected from {addr}") data = client_socket.recv(1024).decode('utf-8') print(f" * Received: {data}") client_socket.send(f"Socket server response: {data}".encode('utf-8')) client_socket.close()
Step 2: Integrate With Flask and Tor
Update your main code to run both the Flask app and Socket server using threads:
import os import threading from stem.control import Controller from flask import Flask from flask_socketio import SocketIO # ... (Paste the run_socket_server function from above here) app = Flask(__name__) socketio = SocketIO(app) @app.route('/') def index(): return "Hello from Flask! The Socket server is running in the background." if __name__ == '__main__': # Start Socket server in a separate daemon thread socket_thread = threading.Thread(target=run_socket_server, daemon=True) socket_thread.start() print(' * Connecting to Tor control port') with Controller.from_port(port=9051) as controller: controller.authenticate() data_dir = controller.get_conf('DataDirectory') hidden_service_dir = os.path.join(data_dir, 'my_multi_service') # Map TWO ports: 80 for Flask, 9000 for the standalone Socket server controller.set_options([ ("HiddenServiceDir", hidden_service_dir), ("HiddenServicePort", "80 127.0.0.1:5000"), ("HiddenServicePort", "9000 127.0.0.1:5001") ]) with open(os.path.join(hidden_service_dir, 'hostname')) as f: hostname = f.read().strip() print(f" * Tor hidden service running at: {hostname}") print(f" * Socket server accessible via Tor at {hostname}:9000") # Run Flask app socketio.run(app, host='127.0.0.1', port=5000, debug=False)
Key Notes
- Tor allows multiple
HiddenServicePortentries for the same hidden service by default. - Clients can connect to your standalone Socket server using the
.onionhostname and port 9000 (e.g., usingsocket.connect(('<your-onion-hostname>', 9000))in Python).
- Ensure your Tor control port (default 9051) is enabled in your
torrcfile (addControlPort 9051if missing). - If you've set a control password, pass it to
controller.authenticate("your-password"). - Never run Flask in debug mode on a public hidden service—it exposes sensitive internal information.
内容的提问来源于stack exchange,提问作者johanDa9u

