Skip to content

Forward non-http ports and non-localhost ips #5723

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

Open
4 tasks done
sibidharan opened this issue Oct 27, 2022 · 26 comments
Open
4 tasks done

Forward non-http ports and non-localhost ips #5723

sibidharan opened this issue Oct 27, 2022 · 26 comments
Labels
enhancement Some improvement that isn't a feature

Comments

@sibidharan
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

OS/Web Information

  • Web Browser: Safari
  • Local OS: MacOS
  • Remote OS: Linux
  • Remote Architecture: amd64
  • code-server --version: 4.8.0

Steps to Reproduce

  1. Spawn a service in a neighbour container
  2. Under ports, paste container-ip:host
  3. It tells remotehost:port is forwarded, but it is unable to do

When I open the forwarded URL proxy, it says

connect ECONNREFUSED 0.0.0.0:8080

Expected

The service running at remotehost:port should be forwarded via web proxy

Actual

Only locally running ports are being forwarded and remorehost:port is not being forwarded unlike VS Code Desktop. It is not even respecting the host part and just attempting to forward a locally running port.

Logs

No response

Screenshot/Video

No response

Does this issue happen in VS Code or GitHub Codespaces?

  • I cannot reproduce this in VS Code.
  • I cannot reproduce this in GitHub Codespaces.

Are you accessing code-server over HTTPS?

  • I am using HTTPS.

Notes

No response

@sibidharan sibidharan added bug Something isn't working triage This issue needs to be triaged by a maintainer labels Oct 27, 2022
@jsjoeio
Copy link
Contributor

jsjoeio commented Oct 27, 2022

Can you elaborate "Spawn a service in a neighbour container"? Then I can try and reproduce this locally.

@jsjoeio jsjoeio added waiting-for-info Waiting for more information from submitter and removed bug Something isn't working triage This issue needs to be triaged by a maintainer labels Oct 27, 2022
@aureliainnovatives
Copy link

I am facing relatively same problem. If I run a Node App on port 3000 via Code-Server container and NGinx Proxy module, it's not accessible via url/proxy/3000 port. How to get rid of proxy/ and allow it like URL:3000 ?

@jsjoeio
Copy link
Contributor

jsjoeio commented Oct 31, 2022

Hmm 🤔 @code-asher any ideas on how this should work behind nginx?

@sibidharan
Copy link
Author

sibidharan commented Nov 1, 2022

Can you elaborate "Spawn a service in a neighbour container"? Then I can try and reproduce this locally.

Sorry for late response @jsjoeio

Hi,

For example, in a docker compose, I spawn 3 containers, one is MySQL, another one is Adminer and another one is my Apache+PHP+Codeserver containers. When these 3 containers are spawned, they are reachable within themselves. If I forward container-ip:3306 in my desktop vs code over SSH, it forwards container-ip:3306 over SSH to my localhost:3306.

If my codeserver can see any host:IP, it should be able to forward it. For now, it is just looking in localhost and not for the hosts/servers running on the same/reachable network, even if I specify host/ip. But this works correctly in my Desktop VS Code.

In the below example, a MongoDB service is running on that IP:port and my desktop VS code is able to port forward that.

Screenshot 2022-11-01 at 5 28 17 AM

If not MongoDB, at least the code-server should be able to forward HTTP, like adminer.

@jsjoeio
Copy link
Contributor

jsjoeio commented Nov 1, 2022

Thanks for elaborating! I'm not sure how'd we implement this on the code-server side 🤔

@code-asher any ideas?

@code-asher
Copy link
Member

code-asher commented Nov 1, 2022 via email

@code-asher
Copy link
Member

Uh I might have misread the question. For implementing maybe we can leave the IP alone if it is 172.*?

@code-asher
Copy link
Member

Actually we should just always leave the IP alone I think and when it is missing then we default to localhost.

@jsjoeio jsjoeio added bug Something isn't working and removed waiting-for-info Waiting for more information from submitter labels Nov 1, 2022
@jsjoeio jsjoeio added this to the On Deck - High Priority milestone Nov 1, 2022
@code-asher
Copy link
Member

But that means we need to encode the IP into the proxy URL somehow. /proxy/3000?ip=[ip] or /proxy/[ip]/3000 for example.

@sibidharan
Copy link
Author

Uh I might have misread the question. For implementing maybe we can leave the IP alone if it is 172.*?

I don't think so.. If the IP is reachable, code-server should forward it. I don't know how protocols like MySQL or MongoDB work in HTTPS.. There should be some way!

@benz0li
Copy link
Contributor

benz0li commented Nov 3, 2022

But that means we need to encode the IP into the proxy URL somehow. /proxy/3000?ip=[ip] or /proxy/[ip]/3000 for example.

@code-asher Does this affect https://github.com/coder/code-server/blob/main/patches/proxy-uri.diff?

@code-asher
Copy link
Member

Ah yeah good point, I think we would need to add something like {{ip}} to VSCODE_PROXY_URI? But to prevent breakage maybe we can default to localhost when the endpoint is /proxy/{{ip}}/3000 or whatever format we settle on.

@benz0li
Copy link
Contributor

benz0li commented Nov 5, 2022

Ah yeah good point, I think we would need to add something like {{ip}} to VSCODE_PROXY_URI?

Only if format /proxy/{{ip}}/{{port}}/[path/to/page] is settled on.

But to prevent breakage maybe we can default to localhost when the endpoint is /proxy/{{ip}}/3000 or whatever format we settle on.

If format /proxy/{{port}}/[path/to/page]?ip=192.0.2.21 is settled on and query string parameter ip is unset I expect to default to localhost.

Footnotes

  1. https://datatracker.ietf.org/doc/html/rfc5737

@benz0li
Copy link
Contributor

benz0li commented Nov 5, 2022

@code-asher @jsjoeio Please make sure that proxying is restricted to the following ranges:

IPv4

  • 10.0.0.0/81
  • 172.16.0.0/121
  • 192.168.0.0/161

plus 127.0.0.12/localhost.

IPv6

  • fc00::/73

plus ::14/localhost.

Proxying to arbitrary IPs must be prevented.
👉 Otherwise, this opens up an incredible number of (undesirable) use cases.

Footnotes

  1. https://en.wikipedia.org/wiki/IPv4#Private_networks 2 3

  2. https://en.wikipedia.org/wiki/IPv4#Loopback

  3. https://en.wikipedia.org/wiki/IPv6_address#Unique_local_addresses

  4. https://en.wikipedia.org/wiki/IPv6_address#Local_addresses

@benz0li
Copy link
Contributor

benz0li commented Nov 5, 2022

I prefer format /proxy/{{port}}/[path/to/page]?ip=192.0.2.2.

@code-asher
Copy link
Member

code-asher commented Nov 7, 2022 via email

@benz0li
Copy link
Contributor

benz0li commented Nov 7, 2022

I prefer the query parameter as well but I am concerned that the application itself might use query parameters and have one called ip or maybe it is an app with multiple pages and navigating to a page drops the ip query parameter.

Understood.

If we embed it into the path on the other hand the application would not be able to mess it up.

True.

We could make it a requirement that applications running behind code-server's proxy specially treat the ip query variable if it exists but I could see that not going too well. XD

Agreed.

@benz0li
Copy link
Contributor

benz0li commented Nov 7, 2022

@code-asher I do not like to modify the VSCODE_PROXY_URI (again). Applications and/or extension making use of VSCODE_PROXY_URI are running on 127.0.0.1/localhost by definition.

It should be possible to differentiate between /proxy/{{port}}/[path/to/page] and /proxy/{{ip}}/{{port}}/[path/to/page] and proxy the former to 127.0.0.1/localhost and the latter to ip.
ℹ️ For IPv4: If the part after the second / does not contain a ., it is already the port – no ip set; thus forward to 127.0.0.1/localhost.

@sibidharan
Copy link
Author

sibidharan commented Nov 8, 2022

@code-asher @jsjoeio @benz0li

How we put the IP into the path is one thing, but I am not sure how protocols like MySQL, MongoDB can be forwarded. It will be very difficult indeed because of the encryption. Many protocols and simple TCP/UDP don't need SSL.

For example, in my setup, the code-server is running on port 1111 and we have a reverse proxy that opens the code-server via SSL over a domain name. To make a lot of features work, like Clipboard, we need SSL. But we don't need SSL for many other protocols. So when I forward a port, instead of proxying it over a URL, is it possible to open a port in the same server and forward it?

Since my code-server is running on 172.20.0.5:1111, if I forward a service running on 172.20.0.6:3306, make the port available on 172.20.0.5:3306 if the port 3306 is available on the server and change the port to some random port if the port is not available (Just like Desktop VS Code). This way, more protocols can be forwarded than just HTTP(S). And this doesn't affect code-server in any way, and the forward remains open as long as the code-server session is open.

In my case of using a reverse-proxy to access code-server over domain name, it will be meaningful to make the proxy forward it over IP instead of a domain name (because reverse-proxy doesn't forward all ports, and it works with domain name). I guess instead of displaying domain name in Local Address column, use the IP of any chosen interface, and this can be set over the command line like --forwarder-iface=eth0 and so code-server knows where to forward, and display the IP in Local Address column effortlessly.

I am facing relatively same problem. If I run a Node App on port 3000 via Code-Server container and NGinx Proxy module, it's not accessible via url/proxy/3000 port. How to get rid of proxy/ and allow it like URL:3000 ?

And I believe this is what this comment is trying to tell.

@sibidharan
Copy link
Author

sibidharan commented Nov 8, 2022

Proxying to arbitrary IPs must be prevented.
👉 Otherwise, this opens up an incredible number of (undesirable) use cases.

IPv4

  • 10.0.0.0/81
  • 172.16.0.0/121
  • 192.168.0.0/161

plus 127.0.0.12/localhost.

IPv6

  • fc00::/73

plus ::14/localhost.

We cannot limit only to this range - lemme tell you why.

In the below image, I have forwarded icanhazip.com:80 (which just displays the end user IP address) and it is forwarded to localhost:52955

Screenshot 2022-11-08 at 8 44 37 PM

My current public IP is 49.206.9.41 and if I open https://icanhazip.com, it says the same.

Since this https://icanhazip.com (also works on http) is hosted behind Cloudflare proxy, my VS Code Desktop resolve the host:port to IP:port and trying to forward the IP only and so it says the following error.

Screenshot 2022-11-08 at 8 50 40 PM

This is because the Cloudflare IP has many servers running behind it and only reachable with a proper domain name. Forward won't work behind proxies that need domain name mandatorily. If I setup a proper forward proxy, I am able to forward this (no time for this now, so I am setting up my own server without any reverse-proxy)

...

I have hosted my own server that tells my IP and hosted it in http://whatismyip.selfmade.ninja and it doesn't work behind any proxy.

When I open it directly:

Screenshot 2022-11-08 at 9 02 44 PM

Look below, I have forwarded it from a server that I have access over wireguard:

Screenshot 2022-11-08 at 8 58 14 PM

When I open the forwarded one:

Screenshot 2022-11-08 at 9 03 35 PM

It says the server's public IP (95.111.198.224) of my 172.0.0.5 (that's on wireguard), because VS Code Desktop is able to forward any arbitrary IP - and this is like I am opening http://whatismyip.selfmade.ninja from 95.111.198.224

This opens up a lot of opportunities for developers, and I don't understand what undesirable things will happen by forwarding arbitrary IPs. Why not code-server do the same?

@benz0li
Copy link
Contributor

benz0li commented Nov 8, 2022

It says the server's public IP (95.111.198.224) of my 172.0.0.5 (that's on wireguard), because VS Code Desktop is able to forward any arbitrary IP) - and this is like I am opening http://whatismyip.selfmade.ninja from 95.111.198.224

Since VS Code Desktop [and the computer it runs on] is under your control, that is fine.

This opens up a lot of opportunities for developers, and I don't understand what undesirable things will happen by forwarding arbitrary IPs.

Because if code-server is deployed as SaaS, users would be able to use your server as a proxy for pretty much anything.
ℹ️ For this reason this functionality should be restricted to private subnets.

@sibidharan
Copy link
Author

Because if code-server is deployed as SaaS, users would be able to use your server as a proxy for pretty much anything.
ℹ️ For this reason this functionality should be restricted to private subnets.

This is a potential security risk, agreed.

But a user can do this whatsoever if he has a shell, by doing an SSH port forward. So why don't we let the admins decide if the code-server can allow forward on all IP ranges or only private IP with a configuration like allowed-ips as an array that takes CIDR - and it can default to Class A,B&C, so unless modified, it won't allow forwarding.?

@code-asher
Copy link
Member

code-asher commented Nov 10, 2022 via email

@Toskies
Copy link

Toskies commented Oct 11, 2023

The service I deployed is in Kubernetes' pod, and the localaddress provided by the codeserver auto forward port is https:///notebook/northstar-team/test-isaacsim/proxy/8211/
When I use this link to access, I reported an error not found.
My normal link to access the service is http:// ip :8211/streaming/client
I tried https:///notebook/northstar-team/test-isaacsim/proxy/8211/streaming/client , But it's not the interface I want
codeserver

@code-asher
Copy link
Member

@Toskies Do you have the same problem if you use /absproxy/8211/ instead?

You might need to log the requests in your app to see if it is getting what it expects. Unless the 404 comes from code-server and not your app?

@sibidharan
Copy link
Author

sibidharan commented Nov 10, 2023

You could spin up or write your own proxy, access it through code-server's proxy, then access whatever you want anyway.

Yes, I am able to do this using socat and its forwarding anything I want. For example,

socat TCP-LISTEN:8081,reuseaddr,fork TCP:adminer.selfmade.ninja:8080

this command could forward adminer.selfmade.ninja:8080 to my localhost's 8081 and I am able to view it via my --proxy-domain like https://8081.proxy.domain

I have setup a container with dynamic proxy, and its working like a charm. So adding this as a feature is much appreciated with whitelist feature.

image

And the feature doesn't do what the placeholder says! Please fix it, let us forward remote host ports also.

@code-asher code-asher changed the title [Bug]: Unable to forward remotehost:port Forward non-http ports and non-localhost ips Jul 13, 2024
@code-asher code-asher added enhancement Some improvement that isn't a feature and removed bug Something isn't working labels Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Some improvement that isn't a feature
Projects
None yet
Development

No branches or pull requests

6 participants