Skip to content

Conversation

@PMExtra
Copy link
Contributor

@PMExtra PMExtra commented Dec 15, 2022

Background

I'm using Xray as a general network tool without pass GFW purpose.

In my case, I made all network traffic from the private subnet be forwarded to Xray with TPROXY.

Then Xray will do some sniffing to override the destination, then forward the request to a Squid service by HTTP Proxy protocol.

Then I need to take access controlling and auditing with Squid.

So I have to know what's the original source IP address.

Fortunately, Squid support solve source address from X-Forwarded-For header which send with CONNECT proxy request.

Changes

So I made this change to support append custom headers with HTTP PROXY:

I added a new optional setting headers in OutboundConfigurationObject of HTTP outbound.

It support text/template format.

For now, there are 2 properties can be accessed: Source net.Destination and target net.Destination.

There is an configuration example:

{
  "outbounds": [
    {
      "protocol": "http",
      "settings": {
        "servers": [
          {
            "address": "proxy.my.domain",
            "port": 8080
          },
          "headers": {
            "X-Forwarded-For": "{{.Source.Address}}",
            "X-Forwarded-Host": "my.domain",
            "X-Real-IP": "{{if .Source.Address.Family.IsIP}}{{.Source.Address}}{{end}}",
            "Forwarded": "by=4.3.2.1;for={{if .Source.Address.Family.IsIPv4}}{{.Source.Address}}{{else if .Source.Address.Family.IsIPv6}}\"{{.Source.Address}}\"{{end}};host=my.domain;proto=http"
          }
        ]
      }
    }
  ]
}

According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded , ipv6 should be quoted and enclosed in square brackets but ipv4 not.

Postscript

I'm sorry for that I'm a beginner of GoLang. Please let me know if there is any bad practice, thanks for your patiences.

I'm still learning to write unit tests with GoLang. So there is no unit test for now, but I've already checked that it works fine in my production workflow.

Copy link
Member

@yuhan6665 yuhan6665 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for you work! Left a few comments.
I'm beginner in Golang as well. We can learn from each other :)

message ClientConfig {
// Sever is a list of HTTP server addresses.
repeated xray.common.protocol.ServerEndpoint server = 1;
repeated Header header = 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, we can use
repeated xray.transport.internet.headers.http.Header header

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xray.transport.internet.headers.http.Header is designed to pick a random value for a key.
I referenced from xray.transport.internet.websocket.Config to make the current solution.

type Client struct {
serverPicker protocol.ServerPicker
policyManager policy.Manager
header []*Header
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

headers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to xray.transport.internet.websocket.Config and xray.transport.internet.http.Config, the Header property is always in singular form. But in xray.infra.conf.* they are plural form. So I think it should be plural only in config file but singular in other codes.


data := struct {
Source net.Destination
Target net.Destination
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems not used in your examples. Is target needed? I feel the receiving end would have it anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's not needed in my case. I just want to make it more extendable for other usages.

@yuhan6665 yuhan6665 merged commit c9b6fc0 into XTLS:main Dec 19, 2022
@yuhan6665
Copy link
Member

感谢 pr!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants