Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On redirect, requests are not sending orignal headers to subsequent locations #188

Closed
kcajmagic opened this issue Jul 12, 2024 · 10 comments
Closed
Assignees

Comments

@kcajmagic
Copy link
Member

Description

When starting the xmidt-agent, the auth header from themis is not being added to requests after receiving a redirect from petasos.

Reproduce

  1. Stand up xmidt cluster with themis, and set talaria to not fail open.
  2. tail logs of talaria

Here is an example of a log line notice no auth is present.

{"level":"error","ts":"2024-07-10T15:59:44Z","msg":"no authorization header","requestHeaders":{"Accept-Encoding":["gzip"],"Connection":["Upgrade"],"Referer":["https://petasos.example.com:8080/api/v2/device"],"Sec-Websocket-Key":["AOlEYfKBp3Fza5mflg6ePg=="],"Sec-Websocket-Version":["13"],"Upgrade":["websocket"],"User-Agent":["Go-http-client/1.1"],"X-Webpa-Convey":["eyJib290LXRpbWUiOiIxOTcwLTAxLTAxIDAwOjAwOjAwICswMDAwIFVUQyIsImJvb3QtdGltZS1yZXRyeS13YWl0IjoiMSIsImZ3LW5hbWUiOiJ2MC4wLjEiLCJody1sYXN0LXJlYm9vdC1yZWFzb24iOiJzbGVlcHkiLCJody1tYW51ZmFjdHVyZXIiOiJiYXJNYW51ZmFjdHVyZXIiLCJody1tb2RlbCI6ImZvb01vZGVsIiwiaHctc2VyaWFsLW51bWJlciI6IjE4MDBkZWFkYmVlZiIsImludGVyZmFjZXMtYXZhaWxhYmxlIjoiZXRoMCIsIndlYnBhLWludGVyZmFjZS11c2VkIjoiZXJvdXRlcjAiLCJ3ZWJwYS1wcm90b2NvbCI6InByb3RvY29sIn0="],"X-Webpa-Device-Name":["mac:4ca161000108"]},"requestURL":"/api/v2/device","method":"GET","requestURI":"/api/v2/device","remoteAddr":"","ts":"2024-07-10T15:59:44Z","auth":""}

Expected behavior

The device should be connect to the cluster with some trust level.

kcajmagic added a commit to kcajmagic/xmidt-agent that referenced this issue Jul 12, 2024
schmidtw added a commit that referenced this issue Jul 12, 2024
fix(#188): add headers from original request to redirects
@denopink
Copy link
Contributor

Hi @kcajmagic !

Thanks for the ticket. I took a quick look and setup the following local cluster:

  • themis
  • petasos
  • talaria (with openfail disabled)

TL;DR

I wasn't able to reproduce your issue.

I'm seeing xmidt-agent -> petasos -> talaria behaving as expected, i.e.: talaria is still receiving the Authorization header.

Here's the headers that my local talaria is receiving:

[
    "Authorization": [
        "Bearer SOME-THEMIS-JWT"
    ],
    "Referer": [
        "http://localhost:6400/api/v2/device"
    ],
    "Sec-Websocket-Key": [
        "i5aIEZN5QLU6Enq+puDXaA=="
    ],
    "Sec-Websocket-Version": [
        "13"
    ],
    "User-Agent": [
        "Go-http-client/1.1"
    ],
    "Connection": [
        "Upgrade"
    ],
    "Upgrade": [
        "websocket"
    ],
    "X-Webpa-Convey": [
        "SOME-CONVEY-DATA"
    ],
    "X-Webpa-Device-Name": [
        "mac:1800deadbeef"
    ],
    "Accept-Encoding": [
        "gzip"
    ],
]

I think your issue is likely a xmidt-agent configuration issue, can you share your config?

If your using the default config, here's what your config suppose to look like when you want to your xmidt-agent to fetch a themis token (section xmidt_credentials):

websocket:
  url_path: api/v2/device
  # petasos server
  back_up_url: http://localhost:6400
xmidt_credentials:
  # themis server
  url: https://localhost:8080/issue
  file_name: themis-creds.jwt
  file_permissions: 0777
  http_client:
    tls:
      insecure_skip_verify: true
      certificates: 
      # UPDATE certificate_file & key_file with actual file paths
        - certificate_file: crt.pem
          key_file:         key.pem
      min_version: 771 # 0x0303, the TLS 1.2 version uint16
identity:
  device_id: mac:1800deadbeef
  serial_number: 1800deadbeef
  hardware_model: fooModel
  hardware_manufacturer: barManufacturer
  firmware_version: v0.0.1
  partner_id: foobar
operational_state:
  last_reboot_reason: sleepy
  boot_time: "2024-02-28T01:04:27Z"
mock_tr_181:
  enabled: true
  file_path: mock_tr181.json

Hope this helps and let me know if I misunderstood anything or you need additional information!

@denopink
Copy link
Contributor

Can you also post your xmidt-agent logs (running in dev mode)?

Running your xmidt-agent with the --dev flag will actually show you whether the agent is successfully fetching themis a tokens as a log event (among other helpful information).

Here's an example of that event (successfully fetching a themis token):

2024-07-12T11: 52: 56-04: 00	DEBUG	credentials	xmidt-agent/credentials.go: 66	fetch	{
    "origin": "network",
    "at": "2024-07-12T11:52:42-04:00",
    "duration": "10.413915244s",
    "uuid": "ebae25f4-87be-4102-a9bc-26dab66140f4",
    "status_code": 200,
    "retry_in": "0s",
    "expiration": "2124-06-18T11:52:52-04:00"
}

@schmidtw
Copy link
Member

I merged the PR, but upon further review I'm not sure it's needed as @denopink has pointed out. https://github.com/golang/go/blob/master/src/net/http/client.go#L747 appears to copy everything that isn't cookie related.

@denopink
Copy link
Contributor

Sounds good, @schmidtw I setup a revert pr for this #190

@kcajmagic
Copy link
Member Author

kcajmagic commented Jul 12, 2024

@denopink I will need to do some more digging. I was weird, since I was seeing the convey header

example with curl

by adding --location-trusted I was able to see a different response

curl --location-trusted -L -i -H "X-Webpa-Device-Name:mac:112233445566" -H "Authorization: Bearer $TOKEN" https://petasos.example.com:8080/api/v2/device -v

xmidt-agent logs

2024-07-10T10:56:40-07:00       DEBUG   credentials     xmidt-agent/credentials.go:66   fetch   {"origin": "network", "at": "2024-07-10T10:56:40-07:00", "duration": "427.276598ms", "uuid": "60d81210-2e77-4c52-aead-19b0900e8ce0", "status_code": 200, "retry_in": "0s", "expiration": "2124-06-16T10:56:40-07:00"}
2024-07-10T10:56:40-07:00       INFO    fxevent/zap.go:51       OnStart hook executed   {"callee": "main.lifeCycle.onStart.func1()", "caller": "main.lifeCycle", "runtime": "427.504478ms"}
2024-07-10T10:56:40-07:00       INFO    fxevent/zap.go:51       started
2024-07-10T10:56:41-07:00       INFO    websocket       xmidt-agent/ws.go:106   connect listener        {"event": "Connect{\n  Started:    2024-07-10T10:56:40.49820387-07:00\n  At:         2024-07-10T10:56:41.113249097-07:00 (615.045227ms)\n  Mode:       IPv4\n  RetryingAt: 2024-07-10T10:56:42.299593351-07:00\n  Err:        failed to WebSocket dial: expected handshake response status code 101 but got 403\n}"}

xmidt-agent config?

nothing changed except using a custom domain

@denopink
Copy link
Contributor

Got it, sounds good!

@ilawjr if you have a chance, can you see whether a xmidt-agent (with a themis token) can connect to cd Talaria and the same Talaria is receiving the token, i.e. we don't see {"level":"error","ts":"2024-07-10T15:59:44Z","msg":"no authorization header", ...} in talaria's log during the xmidnt-agent->talaria request

I may beat you to it if I get a few things out of the way 🙂

@kcajmagic
Copy link
Member Author

@denopink some more info

  • if I change the url to the talaria url I do not see the issue.
  • if I use the pr change it works.
  • From the comments above, the following terrible test never breaks so something else is happening besides forwarding headers.
func TestForwardingHeaders(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)
	called := int32(0)
	socket := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		atomic.AddInt32(&called, 1)
		assert.Contains(r.Header, "Authorization")
		c, err := websocket.Accept(w, r, nil)
		if err != nil {
			log.Println(err)
			return
		}
		defer c.CloseNow()
		t.Log(r.Header)
		c.Close(websocket.StatusNormalClosure, "")
	})

	sockerServer := httptest.NewServer(socket)
	defer sockerServer.Close()

	redirect := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		atomic.AddInt32(&called, 1)
		assert.Contains(r.Header, "Authorization")
		t.Log(r.Header)
		http.Redirect(w, r, sockerServer.URL, http.StatusTemporaryRedirect)
	})

	redirectServer := httptest.NewServer(redirect)
	defer redirectServer.Close()
	got, err := New(
		URL(redirectServer.URL),
		DeviceID("mac:112233445566"),
		RetryPolicy(&retry.Config{
			Interval:    time.Second,
			Multiplier:  2.0,
			Jitter:      1.0 / 3.0,
			MaxInterval: 341*time.Second + 333*time.Millisecond,
		}),
		WithIPv4(),
		NowFunc(time.Now),
		FetchURLTimeout(30*time.Second),
		MaxMessageBytes(256*1024),
		CredentialsDecorator(func(h http.Header) error {
			h.Add("Authorization", "hello")
			return nil
		}),
		ConveyDecorator(func(h http.Header) error {
			return nil
		}),
		// Triggers inactivity timeouts
		InactivityTimeout(time.Hour),
	)
	require.NoError(err)
	require.NotNil(got)

	got.Start()
	time.Sleep(500 * time.Millisecond)
	got.shutdown()
	time.Sleep(500 * time.Millisecond)
	got.Stop()
	require.Equal(atomic.LoadInt32(&called), int32(2))
}

@ilawjr
Copy link

ilawjr commented Jul 12, 2024

Got it, sounds good!

@ilawjr if you have a chance, can you see whether a xmidt-agent (with a themis token) can connect to cd Talaria and the same Talaria is receiving the token, i.e. we don't see {"level":"error","ts":"2024-07-10T15:59:44Z","msg":"no authorization header", ...} in talaria's log during the xmidnt-agent->talaria request

I may beat you to it if I get a few things out of the way 🙂

@denopink I sent you the start up log directly, since it has some urls/ips in the log spam.

@denopink
Copy link
Contributor

@kcajmagic thanks for the extra details!

@ilawjr and I put aside some time today to reproduce this in our cd environment and we are seeing the same issue (using the old xmidt-agent pre-fix #189 ).

Asking @johnabass whether we're missing something simple or patch #189 is our best option.

cc: @schmidtw

@denopink
Copy link
Contributor

John confirmed that we need to copy over the headers manually using CheckRedirect.

thx @kcajmagic for contributing!

Closing.

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

No branches or pull requests

4 participants