rsksmart / rskj

RSKj is a Java implementation of the Rootstock protocol.
https://rootstock.io
GNU Lesser General Public License v3.0
670 stars 268 forks source link

Disable `Host` header checks on RPC? #1439

Open dpc opened 3 years ago

dpc commented 3 years ago

Hi,

In certain scenarios the Host header check is really getting in a way. It seems like currently there's no way to disable it, is there?

patogallaiovlabs commented 3 years ago

Hi @dpc , you can disable CORS request checks by putting a wildcard in the property "rpc.providers.web.cors", is that what you want?

Ways of setting the property:

dpc commented 3 years ago

Hi @patogallaiovlabs . I'm talking about this check https://github.com/rsksmart/rskj/blob/08fc57d8b56c50e20ae9f5458ca3c054ce85390e/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3FilterHandler.java#L72 , which doesn't seem to be affected by these settings.

In certain scenarios - e.g. "fullnode farms" the exact hostname is impossible to predict upfront.

fedejinich commented 3 years ago

how can i reproduce this behaviour?

dpc commented 3 years ago

@fedejinich One way would be to set up some tcp-level proxy (eg. using nc or ssh -R), and call the proxied endpoint using an IP/hostname that rskj doesn't know about, which then get proxied to the rskj without rewriting Host header. The call will get rejected on the line I pasted above.

We're developing/using a smart load balancer/proxy for fullnodes where the fullnodes itself are running in kubernetes (and thus get randomly assigned IPs and ports), so the caller can't possibly know which end target node the request it hits, so can't predict the Host header to use. Right now our proxy is http-based, so we just rewrite Host header but we think about architectures with tcp-based load balancing in which case that would be impossible.

The current check also makes it impossible to use any sort of tcp-based tunneling, which is also useful sometimes.

COLUD4 commented 2 years ago

Hi @dpc , you can disable CORS request checks by putting a wildcard in the property "rpc.providers.web.cors", is that what you want?

Ways of setting the property:

  • "-Drpc.providers.web.cors=*" when starting the node.
  • Config file: rpc { providers { web { cors = "*" ...

I did that, but it didn't work. The outside mainframe was still inaccessible

lcgogo commented 2 years ago

Hi @dpc , you can disable CORS request checks by putting a wildcard in the property "rpc.providers.web.cors", is that what you want? Ways of setting the property:

  • "-Drpc.providers.web.cors=*" when starting the node.
  • Config file: rpc { providers { web { cors = "*" ...

I did that, but it didn't work. The outside mainframe was still inaccessible

met the same issue, the rpc { providers { web { cors = "*" ... is not working for me

lcgogo commented 2 years ago

@patogallaiovlabs Can you help to trouble shooting?

lcgogo commented 2 years ago

Hi @dpc , you can disable CORS request checks by putting a wildcard in the property "rpc.providers.web.cors", is that what you want? Ways of setting the property:

  • "-Drpc.providers.web.cors=*" when starting the node.
  • Config file: rpc { providers { web { cors = "*" ...

I did that, but it didn't work. The outside mainframe was still inaccessible

@COLUD4 Do you find any solution for that?

dpc commented 2 years ago

https://github.com/rsksmart/rskj/blob/08fc57d8b56c50e20ae9f5458ca3c054ce85390e/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3FilterHandler.java#L72 is the root cause of the issue.

AFAICT the whole check is pointless. The caller is free to provide any Host header as they desire, so they can as well put localhost value in it, which we use as a workaround for this issue.

lcgogo commented 2 years ago

@dpc Many thanks for figuring out the code.

do you remove the ! in if() or comment out the whole if block to bypass the issue?