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

lack of information about the address of the connected node when exposing tcp #2

Open
jus7nyan opened this issue Jan 21, 2024 · 15 comments

Comments

@jus7nyan
Copy link

I would like to somehow find out the IP of the connected node. As far as I understand, yggstack simply connects locally from 127.0.0.1 to the listening port. in this case, information about the address of the connected person is lost

@jus7nyan
Copy link
Author

For example, you can not only connect yggstack to a port, but also send information about the public key of the connected node

@jus7nyan
Copy link
Author

jus7nyan commented Jan 21, 2024

or expand the functionality of socks proxy and add the bind feature. I'm not sure that the socks5 protocol is responsible for informing about the client's address but that would be nice

@basilgello
Copy link
Collaborator

AFAIK the x-forwarded-for header is HTTP header. I need to check how to pass this imfo to generic TCP socket.

@jus7nyan
Copy link
Author

jus7nyan commented Jan 21, 2024

The only thing I can think of is to simply send a package with the client's address. Doesn't look good, but I don't know how to do it better

@jus7nyan
Copy link
Author

jus7nyan commented Jan 21, 2024

I’m not good at Go and so far I’ve added c2.Write([]byte(c1.RemoteAddr().String())) to the ProxyTCP function in the file src/types/tcpproxy.go

@basilgello
Copy link
Collaborator

Well, the key issue here is that the listening application must know how to handle this additional info. However, there is IP_PKTINFO structure that can attach exactly what you want to the socket. This still needs the target application to support this functionality, but at least it is documented. Windows also supports this structure.

@jus7nyan
Copy link
Author

oh yeah of course I completely forgot. Is there really a sockopt field that can be used for this?

@basilgello
Copy link
Collaborator

Yup. https://man7.org/linux/man-pages/man7/ip.7.html states than PKTINFO is only for UDP sockets but IP_OPTIONS can be used for TCP or UDP. Not sure about Windows support of this header but 40 bytes can contain ipv6 address which you can map for the key.

@basilgello
Copy link
Collaborator

Also this gist shows how to set IP_OPTIONS before connect. We can use this approach with Yggdrasil or implement Proxy Protocol that Nginx, Apache etc do support.

@basilgello
Copy link
Collaborator

@basilgello
Copy link
Collaborator

@basilgello
Copy link
Collaborator

Or completely different single-binary SSH server implementation from GitLab; https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/sshd

@jus7nyan
Copy link
Author

jus7nyan commented Jan 22, 2024

what about socks proxy? If I'm not mistaken, the protocol describes the purpose (bind) of the TCP/IP port. but as I understand it, this is not implemented in yggstack. socks5 doesn't provide client ip either? and this might be more convenient than a command line argument. Is this necessary if the program cannot work through a proxy?

@basilgello
Copy link
Collaborator

From what I am reading about BIND SOCKS request, first the client sets primary SOCKS connection via CONNECT and then issues separate BIND request to make a second reverse tunnel. This is not equal to traditional bind/listen/accept used by server.

I think adding configurable Proxy Protocol support is best here. And the non-proxy aware apps can be made proxy-aware with library injection.

@basilgello
Copy link
Collaborator

The downside of the proxy protocol is that it does not allow re-using the same port for proxied and non-proxied connections simultaneously:

The receiver MUST NOT start processing the connection before it receives a
complete and valid PROXY protocol header. This is particularly important for
protocols where the receiver is expected to speak first (eg: SMTP, FTP or SSH).
The receiver may apply a short timeout and decide to abort the connection if
the protocol header is not seen within a few seconds (at least 3 seconds to
cover a TCP retransmit).

The receiver MUST be configured to only receive the protocol described in this
specification and MUST not try to guess whether the protocol header is present
or not. This means that the protocol explicitly prevents port sharing between
public and private access. Otherwise it would open a major security breach by
allowing untrusted parties to spoof their connection addresses. The receiver
SHOULD ensure proper access filtering so that only trusted proxies are allowed
to use this protocol.

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

2 participants