From 6a549808243735b429d5c0dd2f1dc83cfb12c22b Mon Sep 17 00:00:00 2001 From: -LAN- Date: Mon, 1 Sep 2025 13:17:17 +0800 Subject: [PATCH] feat(ssrf_proxy): Add dev-mode and tests for ssrf_proxy Signed-off-by: -LAN- --- .../ssrf_proxy/TEST_CASES_README.md | 50 +++++- .../ssrf_proxy/test_cases_dev_mode.yaml | 168 ++++++++++++++++++ .../ssrf_proxy/test_ssrf_proxy.py | 95 ++++++++-- docker/docker-compose.middleware.yaml | 5 +- docker/ssrf_proxy/README.md | 39 ++++ .../conf.d.dev/00-development-mode.conf | 22 +++ docker/ssrf_proxy/docker-compose.dev.yaml | 21 +++ docker/ssrf_proxy/squid.conf.dev.template | 67 +++++++ 8 files changed, 446 insertions(+), 21 deletions(-) create mode 100644 api/tests/integration_tests/ssrf_proxy/test_cases_dev_mode.yaml create mode 100644 docker/ssrf_proxy/conf.d.dev/00-development-mode.conf create mode 100644 docker/ssrf_proxy/docker-compose.dev.yaml create mode 100644 docker/ssrf_proxy/squid.conf.dev.template diff --git a/api/tests/integration_tests/ssrf_proxy/TEST_CASES_README.md b/api/tests/integration_tests/ssrf_proxy/TEST_CASES_README.md index 3dbea7313d..1fb22eee64 100644 --- a/api/tests/integration_tests/ssrf_proxy/TEST_CASES_README.md +++ b/api/tests/integration_tests/ssrf_proxy/TEST_CASES_README.md @@ -36,6 +36,21 @@ Run tests from a specific YAML file: uv run python tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py --test-file test_cases_extended.yaml ``` +### Development Mode Testing + +**WARNING: Development mode DISABLES all SSRF protections! Only use in development environments!** + +Test the development mode configuration (used by docker-compose.middleware.yaml): +```bash +uv run python tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py --dev-mode +``` + +Development mode: +- Mounts `conf.d.dev/` configuration that allows ALL requests +- Uses `test_cases_dev_mode.yaml` by default (all tests expect ALLOW) +- Verifies that private networks, cloud metadata, and non-standard ports are accessible +- Should NEVER be used in production environments + ### Command Line Options - `--host HOST`: Proxy host (default: localhost) @@ -44,6 +59,7 @@ uv run python tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py --test-file - `--save-results`: Save test results to JSON file - `--test-file FILE`: Path to YAML file containing test cases - `--list-tests`: List all test cases without running them +- `--dev-mode`: Run in development mode (DISABLES all SSRF protections - DO NOT use in production!) ## YAML Test Case Format @@ -63,10 +79,11 @@ test_categories: ## Available Test Files -1. **test_cases.yaml** - Standard test suite with essential test cases +1. **test_cases.yaml** - Standard test suite with essential test cases (default) 2. **test_cases_extended.yaml** - Extended test suite with additional edge cases and scenarios +3. **test_cases_dev_mode.yaml** - Development mode test suite (all requests should be allowed) -Both files are located in `api/tests/integration_tests/ssrf_proxy/` +All files are located in `api/tests/integration_tests/ssrf_proxy/` ## Categories @@ -107,6 +124,35 @@ The tests validate the SSRF proxy configuration files in `docker/ssrf_proxy/`: - `squid.conf.template` - Squid proxy configuration - `docker-entrypoint.sh` - Container initialization script - `conf.d/` - Additional configuration files (if present) +- `conf.d.dev/` - Development mode configuration (when using --dev-mode) + +## Development Mode Configuration + +Development mode provides a zero-configuration environment for local development: +- Mounts `conf.d.dev/` instead of `conf.d/` +- Allows ALL requests including private networks and cloud metadata +- Enables access to any port +- Disables all SSRF protections + +### Using Development Mode with Docker Compose + +From the main Dify repository root: +```bash +# Use the development overlay +docker-compose -f docker-compose.middleware.yaml -f docker/ssrf_proxy/docker-compose.dev.yaml up ssrf_proxy +``` + +Or manually mount the development configuration: +```bash +docker run -d \ + --name ssrf-proxy-dev \ + -p 3128:3128 \ + -v ./docker/ssrf_proxy/conf.d.dev:/etc/squid/conf.d:ro \ + # ... other volumes + ubuntu/squid:latest +``` + +**CRITICAL**: Never use this configuration in production! ## Benefits diff --git a/api/tests/integration_tests/ssrf_proxy/test_cases_dev_mode.yaml b/api/tests/integration_tests/ssrf_proxy/test_cases_dev_mode.yaml new file mode 100644 index 0000000000..9d6658b51d --- /dev/null +++ b/api/tests/integration_tests/ssrf_proxy/test_cases_dev_mode.yaml @@ -0,0 +1,168 @@ +# Development Mode Test Cases for SSRF Proxy +# These test cases verify that development mode correctly disables all SSRF protections +# WARNING: All requests should be ALLOWED in development mode + +test_categories: + private_networks: + name: "Private Networks (Dev Mode)" + description: "In dev mode, private networks should be ALLOWED" + test_cases: + - name: "Loopback (127.0.0.1)" + url: "http://127.0.0.1" + expected_blocked: false # ALLOWED in dev mode + description: "IPv4 loopback - normally blocked, allowed in dev mode" + + - name: "Localhost" + url: "http://localhost" + expected_blocked: false # ALLOWED in dev mode + description: "Localhost hostname - normally blocked, allowed in dev mode" + + - name: "Private 10.x.x.x" + url: "http://10.0.0.1" + expected_blocked: false # ALLOWED in dev mode + description: "RFC 1918 private network - normally blocked, allowed in dev mode" + + - name: "Private 172.16.x.x" + url: "http://172.16.0.1" + expected_blocked: false # ALLOWED in dev mode + description: "RFC 1918 private network - normally blocked, allowed in dev mode" + + - name: "Private 192.168.x.x" + url: "http://192.168.1.1" + expected_blocked: false # ALLOWED in dev mode + description: "RFC 1918 private network - normally blocked, allowed in dev mode" + + - name: "Link-local" + url: "http://169.254.1.1" + expected_blocked: false # ALLOWED in dev mode + description: "Link-local address - normally blocked, allowed in dev mode" + + - name: "This network" + url: "http://0.0.0.0" + expected_blocked: false # ALLOWED in dev mode + description: "'This' network address - normally blocked, allowed in dev mode" + + cloud_metadata: + name: "Cloud Metadata (Dev Mode)" + description: "In dev mode, cloud metadata endpoints should be ALLOWED" + test_cases: + - name: "AWS Metadata" + url: "http://169.254.169.254/latest/meta-data/" + expected_blocked: false # ALLOWED in dev mode + description: "AWS EC2 metadata - normally blocked, allowed in dev mode" + + - name: "Azure Metadata" + url: "http://169.254.169.254/metadata/instance" + expected_blocked: false # ALLOWED in dev mode + description: "Azure metadata - normally blocked, allowed in dev mode" + + non_standard_ports: + name: "Non-Standard Ports (Dev Mode)" + description: "In dev mode, all ports should be ALLOWED" + test_cases: + - name: "Port 8080" + url: "http://example.com:8080" + expected_blocked: false # ALLOWED in dev mode + description: "Alternative HTTP port - normally blocked, allowed in dev mode" + + - name: "Port 3000" + url: "http://example.com:3000" + expected_blocked: false # ALLOWED in dev mode + description: "Node.js development port - normally blocked, allowed in dev mode" + + - name: "SSH Port 22" + url: "http://example.com:22" + expected_blocked: false # ALLOWED in dev mode + description: "SSH port - normally blocked, allowed in dev mode" + + - name: "Database Port 3306" + url: "http://example.com:3306" + expected_blocked: false # ALLOWED in dev mode + description: "MySQL port - normally blocked, allowed in dev mode" + + - name: "Database Port 5432" + url: "http://example.com:5432" + expected_blocked: false # ALLOWED in dev mode + description: "PostgreSQL port - normally blocked, allowed in dev mode" + + - name: "Redis Port 6379" + url: "http://example.com:6379" + expected_blocked: false # ALLOWED in dev mode + description: "Redis port - normally blocked, allowed in dev mode" + + - name: "MongoDB Port 27017" + url: "http://example.com:27017" + expected_blocked: false # ALLOWED in dev mode + description: "MongoDB port - normally blocked, allowed in dev mode" + + - name: "High Port 12345" + url: "http://example.com:12345" + expected_blocked: false # ALLOWED in dev mode + description: "Random high port - normally blocked, allowed in dev mode" + + localhost_ports: + name: "Localhost with Various Ports (Dev Mode)" + description: "In dev mode, localhost with any port should be ALLOWED" + test_cases: + - name: "Localhost:8080" + url: "http://localhost:8080" + expected_blocked: false # ALLOWED in dev mode + description: "Localhost with port 8080 - normally blocked, allowed in dev mode" + + - name: "Localhost:3000" + url: "http://localhost:3000" + expected_blocked: false # ALLOWED in dev mode + description: "Localhost with port 3000 - normally blocked, allowed in dev mode" + + - name: "127.0.0.1:9200" + url: "http://127.0.0.1:9200" + expected_blocked: false # ALLOWED in dev mode + description: "Loopback with Elasticsearch port - normally blocked, allowed in dev mode" + + - name: "127.0.0.1:5001" + url: "http://127.0.0.1:5001" + expected_blocked: false # ALLOWED in dev mode + description: "Loopback with API port - normally blocked, allowed in dev mode" + + public_internet: + name: "Public Internet (Dev Mode)" + description: "Public internet should still work in dev mode" + test_cases: + - name: "Example.com" + url: "http://example.com" + expected_blocked: false + description: "Public website - always allowed" + + - name: "Google HTTPS" + url: "https://www.google.com" + expected_blocked: false + description: "HTTPS public website - always allowed" + + - name: "GitHub API" + url: "https://api.github.com" + expected_blocked: false + description: "Public API over HTTPS - always allowed" + + special_cases: + name: "Special Cases (Dev Mode)" + description: "Edge cases that should all be allowed in dev mode" + test_cases: + - name: "Decimal IP notation" + url: "http://2130706433" + expected_blocked: false # ALLOWED in dev mode + description: "127.0.0.1 in decimal - normally blocked, allowed in dev mode" + + - name: "Private network in subdomain" + url: "http://192-168-1-1.example.com" + expected_blocked: false + description: "Domain that looks like private IP - always allowed as it resolves externally" + + - name: "IPv6 Loopback" + url: "http://[::1]" + expected_blocked: false # ALLOWED in dev mode + description: "IPv6 loopback - normally blocked, allowed in dev mode" + + - name: "IPv6 Link-local" + url: "http://[fe80::1]" + expected_blocked: false # ALLOWED in dev mode + description: "IPv6 link-local - normally blocked, allowed in dev mode" \ No newline at end of file diff --git a/api/tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py b/api/tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py index 790f8a5abd..1b18d56465 100755 --- a/api/tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py +++ b/api/tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py @@ -47,18 +47,32 @@ class TestCase: @final class SSRFProxyTester: - def __init__(self, proxy_host: str = "localhost", proxy_port: int = 3128, test_file: str | None = None): + def __init__( + self, + proxy_host: str = "localhost", + proxy_port: int = 3128, + test_file: str | None = None, + dev_mode: bool = False, + ): self.proxy_host = proxy_host self.proxy_port = proxy_port self.proxy_url = f"http://{proxy_host}:{proxy_port}" - self.container_name = "ssrf-proxy-test" + self.container_name = "ssrf-proxy-test-dev" if dev_mode else "ssrf-proxy-test" self.image = "ubuntu/squid:latest" self.results: list[dict[str, object]] = [] - self.test_file = test_file or "test_cases.yaml" + self.dev_mode = dev_mode + # Use dev mode test cases by default when in dev mode + if dev_mode and test_file is None: + self.test_file = "test_cases_dev_mode.yaml" + else: + self.test_file = test_file or "test_cases.yaml" def start_proxy_container(self) -> bool: """Start the SSRF proxy container""" - print(f"{Colors.YELLOW}Starting SSRF proxy container...{Colors.NC}") + mode_str = " (DEVELOPMENT MODE)" if self.dev_mode else "" + print(f"{Colors.YELLOW}Starting SSRF proxy container{mode_str}...{Colors.NC}") + if self.dev_mode: + print(f"{Colors.RED}WARNING: Development mode DISABLES all SSRF protections!{Colors.NC}") # Stop and remove existing container if exists _ = subprocess.run(["docker", "stop", self.container_name], capture_output=True, text=True) @@ -70,6 +84,12 @@ class SSRFProxyTester: project_root = os.path.abspath(os.path.join(script_dir, "..", "..", "..", "..")) docker_config_dir = os.path.join(project_root, "docker", "ssrf_proxy") + # Choose configuration template based on mode + if self.dev_mode: + config_template = "squid.conf.dev.template" + else: + config_template = "squid.conf.template" + # Start container cmd = [ "docker", @@ -82,7 +102,7 @@ class SSRFProxyTester: "-p", "8194:8194", "-v", - f"{docker_config_dir}/squid.conf.template:/etc/squid/squid.conf.template:ro", + f"{docker_config_dir}/{config_template}:/etc/squid/squid.conf.template:ro", "-v", f"{docker_config_dir}/docker-entrypoint.sh:/docker-entrypoint-mount.sh:ro", "-e", @@ -102,11 +122,16 @@ class SSRFProxyTester: "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\\r$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh", # noqa: E501 ] - # Add conf.d mount if directory exists - conf_d_path = f"{docker_config_dir}/conf.d" - if os.path.exists(conf_d_path) and os.listdir(conf_d_path): - cmd.insert(-3, "-v") - cmd.insert(-3, f"{conf_d_path}:/etc/squid/conf.d:ro") + # Mount configuration directory (only in normal mode) + # In dev mode, the dev template already allows everything + if not self.dev_mode: + # Normal mode: mount regular conf.d if it exists + conf_d_path = f"{docker_config_dir}/conf.d" + if os.path.exists(conf_d_path) and os.listdir(conf_d_path): + cmd.insert(-3, "-v") + cmd.insert(-3, f"{conf_d_path}:/etc/squid/conf.d:ro") + else: + print(f"{Colors.YELLOW}Using development mode configuration (all SSRF protections disabled){Colors.NC}") result = subprocess.run(cmd, capture_output=True, text=True) @@ -159,9 +184,17 @@ class SSRFProxyTester: else: # Other HTTP errors mean the request went through is_blocked = False - except (urllib.error.URLError, OSError, TimeoutError): - # Connection errors mean blocked by proxy - is_blocked = True + except (urllib.error.URLError, OSError, TimeoutError) as e: + # In dev mode, connection errors to 169.254.x.x addresses are expected + # These addresses don't exist locally, so timeout is normal + # The proxy allowed the request, but the destination is unreachable + if self.dev_mode and "169.254" in test_case.url: + # In dev mode, if we're testing 169.254.x.x addresses, + # a timeout means the proxy allowed it (not blocked) + is_blocked = False + else: + # In normal mode, or for other addresses, connection errors mean blocked + is_blocked = True except Exception as e: # Unexpected error print(f"{Colors.YELLOW}Warning: Unexpected error testing {test_case.url}: {e}{Colors.NC}") @@ -205,7 +238,13 @@ class SSRFProxyTester: test_cases = self.get_test_cases() print("=" * 50) - print(" SSRF Proxy Test Suite") + if self.dev_mode: + print(" SSRF Proxy Test Suite (DEV MODE)") + print("=" * 50) + print(f"{Colors.RED}WARNING: Testing with SSRF protections DISABLED!{Colors.NC}") + print(f"{Colors.YELLOW}All requests should be ALLOWED in dev mode.{Colors.NC}") + else: + print(" SSRF Proxy Test Suite") print("=" * 50) # Group tests by category @@ -295,9 +334,19 @@ class SSRFProxyTester: print(f"Tests Skipped: {Colors.YELLOW}{skipped}{Colors.NC}") if failed == 0: - print(f"\n{Colors.GREEN}✓ All tests passed! SSRF proxy is configured correctly.{Colors.NC}") + if hasattr(self, "dev_mode") and self.dev_mode: + print(f"\n{Colors.GREEN}✓ All tests passed! Development mode is working correctly.{Colors.NC}") + print( + f"{Colors.YELLOW}Remember: Dev mode DISABLES all SSRF protections - " + f"use only for development!{Colors.NC}" + ) + else: + print(f"\n{Colors.GREEN}✓ All tests passed! SSRF proxy is configured correctly.{Colors.NC}") else: - print(f"\n{Colors.RED}✗ Some tests failed. Please review the configuration.{Colors.NC}") + if hasattr(self, "dev_mode") and self.dev_mode: + print(f"\n{Colors.RED}✗ Some tests failed. Dev mode should allow ALL requests!{Colors.NC}") + else: + print(f"\n{Colors.RED}✗ Some tests failed. Please review the configuration.{Colors.NC}") print("\nFailed tests:") for r in self.results: if r["result"] == "failed": @@ -330,6 +379,7 @@ def main(): save_results: bool = False test_file: str | None = None list_tests: bool = False + dev_mode: bool = False def parse_args() -> Args: parser = argparse.ArgumentParser(description="Test SSRF Proxy Configuration") @@ -345,6 +395,11 @@ def main(): "--test-file", type=str, help="Path to YAML file containing test cases (default: test_cases.yaml)" ) _ = parser.add_argument("--list-tests", action="store_true", help="List all test cases without running them") + _ = parser.add_argument( + "--dev-mode", + action="store_true", + help="Run in development mode (DISABLES all SSRF protections - DO NOT use in production!)", + ) # Parse arguments - argparse.Namespace has Any-typed attributes # This is a known limitation of argparse in Python's type system @@ -360,18 +415,22 @@ def main(): save_results=bool(namespace.save_results), # pyright: ignore[reportAny] test_file=namespace.test_file if namespace.test_file else None, # pyright: ignore[reportAny] list_tests=bool(namespace.list_tests), # pyright: ignore[reportAny] + dev_mode=bool(namespace.dev_mode), # pyright: ignore[reportAny] ) args = parse_args() - tester = SSRFProxyTester(args.host, args.port, args.test_file) + tester = SSRFProxyTester(args.host, args.port, args.test_file, args.dev_mode) # If --list-tests flag is set, just list the tests and exit if args.list_tests: test_cases = tester.get_test_cases() + mode_str = " (DEVELOPMENT MODE)" if args.dev_mode else "" print("\n" + "=" * 50) - print(" Available Test Cases") + print(f" Available Test Cases{mode_str}") print("=" * 50) + if args.dev_mode: + print(f"\n{Colors.RED}WARNING: Dev mode test cases expect ALL requests to be ALLOWED!{Colors.NC}") # Group by category for display categories: dict[str, list[TestCase]] = {} diff --git a/docker/docker-compose.middleware.yaml b/docker/docker-compose.middleware.yaml index 7ffb00adce..ab81fe779e 100644 --- a/docker/docker-compose.middleware.yaml +++ b/docker/docker-compose.middleware.yaml @@ -141,7 +141,10 @@ services: volumes: - ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template - ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh - - ./ssrf_proxy/conf.d:/etc/squid/conf.d:ro + # DEVELOPMENT MODE: Mount dev configs that disable all SSRF protections + # WARNING: This configuration allows access to private networks! + # Only use this in development environments, never in production! + - ./ssrf_proxy/conf.d.dev:/etc/squid/conf.d:ro entrypoint: [ "sh", "-c", "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ] env_file: - ./middleware.env diff --git a/docker/ssrf_proxy/README.md b/docker/ssrf_proxy/README.md index 8a62e426aa..d984a6abc4 100644 --- a/docker/ssrf_proxy/README.md +++ b/docker/ssrf_proxy/README.md @@ -92,6 +92,39 @@ The following networks are blocked by default to prevent SSRF: - `fe80::/10` - IPv6 link-local - `::1/128` - IPv6 loopback +## Development Mode + +⚠️ **WARNING: Development mode DISABLES all SSRF protections! Only use in development environments!** + +Development mode provides a zero-configuration environment that: +- Allows access to ALL private networks and localhost +- Allows access to cloud metadata endpoints +- Allows connections to any port +- Disables all SSRF protections for easier development + +### Using Development Mode + +#### Option 1: Docker Compose Override (Recommended) +From the main Dify repository root: +```bash +# Use the development overlay with your existing docker-compose +docker-compose -f docker-compose.middleware.yaml -f docker/ssrf_proxy/docker-compose.dev.yaml up ssrf_proxy +``` + +#### Option 2: Manual Configuration +Mount the development configuration manually: +```bash +docker run -d \ + --name ssrf-proxy-dev \ + -p 3128:3128 \ + -v ./docker/ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template:ro \ + -v ./docker/ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint.sh:ro \ + -v ./docker/ssrf_proxy/conf.d.dev:/etc/squid/conf.d:ro \ + ubuntu/squid:latest +``` + +The development mode configuration is in `conf.d.dev/00-development-mode.conf`. + ## Testing Comprehensive integration tests are available to validate the SSRF proxy configuration: @@ -106,6 +139,9 @@ uv run python tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py --list-tests # Use extended test suite uv run python tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py --test-file test_cases_extended.yaml + +# Test development mode (all requests should be allowed) +uv run python tests/integration_tests/ssrf_proxy/test_ssrf_proxy.py --dev-mode ``` The test suite validates: @@ -137,5 +173,8 @@ docker/ssrf_proxy/ │ ├── 20-allow-external-domains.conf.example │ ├── 30-allow-additional-ports.conf.example │ └── 40-restrict-to-allowlist.conf.example +├── conf.d.dev/ # Development mode configuration +│ └── 00-development-mode.conf # Disables all SSRF protections +├── docker-compose.dev.yaml # Docker Compose overlay for dev mode └── README.md # This file ``` diff --git a/docker/ssrf_proxy/conf.d.dev/00-development-mode.conf b/docker/ssrf_proxy/conf.d.dev/00-development-mode.conf new file mode 100644 index 0000000000..4d03e34e3d --- /dev/null +++ b/docker/ssrf_proxy/conf.d.dev/00-development-mode.conf @@ -0,0 +1,22 @@ +################################## DEVELOPMENT MODE CONFIGURATION ################################## +# WARNING: This configuration DISABLES all SSRF protections! +# Only use this in development environments. NEVER use in production! + +# Override all previous access rules and allow everything +# This must be placed early in the configuration to take precedence + +# Allow all ports (not just 80/443) +acl Dev_All_Ports port 1-65535 + +# Allow all connections including private networks +# This effectively bypasses all SSRF protections +http_access allow all + +# Additional development conveniences +# Allow cache manager access from any source (useful for debugging) +http_access allow manager + +# Log everything for debugging +debug_options ALL,1 + +# Note: Since we're allowing all, the deny rules in the main config won't be reached diff --git a/docker/ssrf_proxy/docker-compose.dev.yaml b/docker/ssrf_proxy/docker-compose.dev.yaml new file mode 100644 index 0000000000..a6371a0e71 --- /dev/null +++ b/docker/ssrf_proxy/docker-compose.dev.yaml @@ -0,0 +1,21 @@ +# Development Mode Docker Compose Override +# WARNING: This configuration DISABLES all SSRF protections! +# Only use this in development environments, never in production! +# +# Usage (from main Dify repository): +# docker-compose -f docker-compose.middleware.yaml -f docker/ssrf_proxy/docker-compose.dev.yaml up +# +# This overlay modifies the ssrf_proxy service to mount development configurations +# that allow ALL requests including private networks and cloud metadata. + +version: '3.8' + +services: + ssrf_proxy: + volumes: + # Override the conf.d mount to use development configuration + - ./docker/ssrf_proxy/conf.d.dev:/etc/squid/conf.d:ro + environment: + # Optional: Add any development-specific environment variables + SQUID_DEV_MODE: "true" + container_name: dify-ssrf-proxy-dev diff --git a/docker/ssrf_proxy/squid.conf.dev.template b/docker/ssrf_proxy/squid.conf.dev.template new file mode 100644 index 0000000000..5369fc8124 --- /dev/null +++ b/docker/ssrf_proxy/squid.conf.dev.template @@ -0,0 +1,67 @@ +################################## DEVELOPMENT MODE CONFIGURATION ################################## +# WARNING: This configuration DISABLES all SSRF protections! +# Only use this in development environments. NEVER use in production! +# +# This is a special configuration for development that allows ALL requests +# including private networks, cloud metadata endpoints, and any ports. + +################################## Allow Everything ################################## +# In development mode, we allow all connections without restrictions + +# Define ACLs but don't use them for blocking +acl private_networks dst 0.0.0.0/8 +acl private_networks dst 10.0.0.0/8 +acl private_networks dst 127.0.0.0/8 +acl private_networks dst 169.254.0.0/16 +acl private_networks dst 172.16.0.0/12 +acl private_networks dst 192.168.0.0/16 +acl localhost src 127.0.0.1/32 ::1 +acl SSL_ports port 443 +acl Safe_ports port 1-65535 # Allow ALL ports in dev mode +acl CONNECT method CONNECT + +################################## Access Control Rules ################################## +# DEVELOPMENT MODE: Allow everything! + +# Special rule for reverse proxy port (sandbox access) +acl reverse_proxy_port myport ${REVERSE_PROXY_PORT} +http_access allow reverse_proxy_port + +# Explicitly allow link-local addresses (169.254.0.0/16) +acl link_local dst 169.254.0.0/16 +http_access allow link_local + +# Explicitly allow localhost and loopback +http_access allow localhost + +# Explicitly allow all private networks +http_access allow private_networks + +# ALLOW ALL REQUESTS - Development mode bypasses all security +http_access allow all + +# Note: No deny rules in development mode + +################################## Proxy Server Configuration ################################## +http_port ${HTTP_PORT} +coredump_dir ${COREDUMP_DIR} + +# Refresh patterns +refresh_pattern ^ftp: 1440 20% 10080 +refresh_pattern ^gopher: 1440 0% 1440 +refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 +refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims +refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims +refresh_pattern \/InRelease$ 0 0% 0 refresh-ims +refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims +refresh_pattern . 0 20% 4320 + +################################## Reverse Proxy To Sandbox ################################## +http_port ${REVERSE_PROXY_PORT} accel vhost +cache_peer ${SANDBOX_HOST} parent ${SANDBOX_PORT} 0 no-query originserver + +# Buffer size for file uploads +client_request_buffer_max_size 100 MB + +# Debug logging for development +debug_options ALL,1