tobychui / zoraxy

A general purpose HTTP reverse proxy and forwarding tool. Now written in Go!
https://zoraxy.aroz.org
GNU Affero General Public License v3.0
3.01k stars 182 forks source link

[HELP] Is it possible to access gRPC as vdir #381

Open johnny15243 opened 6 days ago

johnny15243 commented 6 days ago

What happened? I tried to get Netbird running. I started with the advanced installation.
After configuring the vdir for proxy, have the following errors

[2024-11-06 17:00:48.902245] [router:vdir-http] [origin:127.0.0.1] [client <clientIP>] POST /management.ManagementService/GetServerKey 521

[2024-11-06 17:00:48.902348] [router:vdir-http] [origin:127.0.0.1] [client <clientIP>] POST /management.ManagementService/GetServerKey 502

If i use the vdir as proxy target, and call uri. No errors appear

Here is my Configuration

{
    "ProxyType": 1,
    "RootOrMatchingDomain": "",
    "MatchingDomainAlias": [],
    "ActiveOrigins": [
        {
            "OriginIpOrDomain": "127.0.0.1:8081",
            "RequireTLS": false,
            "SkipCertValidations": false,
            "SkipWebSocketOriginCheck": true,
            "Weight": 1,
            "MaxConn": 0
        }
    ],
    "InactiveOrigins": [],
    "UseStickySession": true,
    "UseActiveLoadBalance": false,
    "Disabled": false,
    "BypassGlobalTLS": false,
    "VirtualDirectories": [
        {
            "MatchingPath": "/api/",
            "Domain": "127.0.0.1:33073/api/",
            "RequireTLS": false,
            "SkipCertValidations": false,
            "Disabled": false
        },
        {
            "MatchingPath": "/signalexchange.SignalExchange/",
            "Domain": "127.0.0.1:10000/signalexchange.SignalExchange/",
            "RequireTLS": true,
            "SkipCertValidations": true,
            "Disabled": false
        },
        {
            "MatchingPath": "/management.ManagementService/",
            "Domain": "127.0.0.1:33073/management.ManagementService/",
            "RequireTLS": true,
            "SkipCertValidations": true,
            "Disabled": false
        }
    ],
    "UserDefinedHeaders": [],
    "RequestHostOverwrite": "",
    "HSTSMaxAge": 31536000,
    "EnablePermissionPolicyHeader": false,
    "PermissionPolicy": {
        "accelerometer": [
            ""
        ],
        "ambient_light_sensor": [
            ""
        ],
        "autoplay": [
            ""
        ],
        "battery": [
            ""
        ],
        "camera": [
            ""
        ],
        "cross_origin_isolated": [
            ""
        ],
        "display_capture": [
            ""
        ],
        "document_domain": [
            ""
        ],
        "encrypted_media": [
            ""
        ],
        "execution_while_not_rendered": [
            ""
        ],
        "execution_while_out_of_viewport": [
            ""
        ],
        "fullscreen": [
            ""
        ],
        "geolocation": [
            ""
        ],
        "gyroscope": [
            ""
        ],
        "keyboard_map": [
            ""
        ],
        "magnetometer": [
            ""
        ],
        "microphone": [
            ""
        ],
        "midi": [
            ""
        ],
        "navigation_override": [
            ""
        ],
        "payment": [
            ""
        ],
        "picture_in_picture": [
            ""
        ],
        "publickey_credentials_get": [
            ""
        ],
        "screen_wake_lock": [
            ""
        ],
        "sync_xhr": [
            ""
        ],
        "usb": [
            ""
        ],
        "web_share": [
            ""
        ],
        "xr_spatial_tracking": [
            ""
        ],
        "clipboard_read": [
            ""
        ],
        "clipboard_write": [
            ""
        ],
        "gamepad": [
            ""
        ],
        "speaker_selection": [
            ""
        ],
        "conversion_measurement": [
            ""
        ],
        "focus_without_user_activation": [
            ""
        ],
        "hid": [
            ""
        ],
        "idle_detection": [
            ""
        ],
        "interest_cohort": [
            ""
        ],
        "serial": [
            ""
        ],
        "sync_script": [
            ""
        ],
        "trust_token_redemption": [
            ""
        ],
        "unload": [
            ""
        ],
        "window_placement": [
            ""
        ],
        "vertical_scroll": [
            ""
        ]
    },
    "DisableHopByHopHeaderRemoval": false,
    "RequireBasicAuth": false,
    "BasicAuthCredentials": [],
    "BasicAuthExceptionRules": [],
    "UseSSOIntercept": false,
    "RequireRateLimit": false,
    "RateLimit": 1000,
    "AccessFilterUUID": "default",
    "DefaultSiteOption": 0,
    "DefaultSiteValue": ""
}

Describe the networking setup you are using Here are some example, commonly asked questions from our maintainers:

Additional context Add any other context or screenshots about the feature request here. The following uri-Path are gRPC-Services and normally called via h2c [http2] within caddy /management.ManagementService/ and /signalexchange.SignalExchange/

tobychui commented 5 days ago

@johnny15243 I guess gRPC service you are running do not support vdir or have an invalid base URL (or similar) setting.

To be exact, vdir rule share the same reverse proxy router object as proxy rules but with automatic rewrites on the path name. Zoraxy will rewrite the hostname automatically on vdir requests (i.e. yourdomain.com/vdir/myresources -> upstream_ip:port/myresources), in this case, I guess there is a misconfiguration in your upstream gRPC server or your gRPC server do not support such path rewrite.

johnny15243 commented 5 days ago

@tobychui Thanks for the response :-)

First. The path rewrite is no problem. If i add the path to the proxy target, it appends it. So it works fine. See

{
"MatchingPath": "/api/",
"Domain": "127.0.0.1:33073/api/",
"RequireTLS": false,
"SkipCertValidations": false,
"Disabled": false
},

To day i scanned the packets via tcpdump.

tcpdump -i lo -A -q '(tcp port 33073) or (udp port 33073)'

I recognized that the request is done via h2 (http2 with tls). But the target needs a communication via h2c (http2 without tls). Http1 is also not allowed via gRPC. Is this a feature you can add?

Here is a caddy.conf-sample for netbird.

netbird.example.net {
    reverse_proxy /* netbird-dash:80
    reverse_proxy /signalexchange.SignalExchange/* h2c://netbird-signal
    reverse_proxy /api/* netbird-mgmt
    reverse_proxy /management.ManagementService/* h2c://netbird-mgmt
    header * {
        Strict-Transport-Security "max-age=3600; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        X-XSS-Protection "1; mode=block"
        -Server
        Referrer-Policy strict-origin-when-cross-origin
    }
}