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

Origin IP forwarding for security (e.g. geoblocking) #250

Open
Nexulo opened this issue May 14, 2023 · 32 comments
Open

Origin IP forwarding for security (e.g. geoblocking) #250

Nexulo opened this issue May 14, 2023 · 32 comments
Labels
enhancement New feature or request

Comments

@Nexulo
Copy link

Nexulo commented May 14, 2023

Feature Proposed
I have seen that there were already some posts here where the idea came up to forward and process the IP address of the users accessing a service through such rathole tunnels.

As far as I have seen this is not possible and every user/visitor of a rathole tunnel gets the local IP address 127.0.0.1 - Is this not dangerous from a security point of view? So you can no longer see or distinguish in the network where this access came from. So a firewall with geoblocking (e.g. also on a Synology NAS) is useless.

It goes without saying that the applications behind these tunnels should always be secured as well as possible. However, initial protection against this should not be neglected.

I would like to know if no one really thinks or worries about this or how appropriate solutions have perhaps already been implemented.

Use Case
Geoblocking
Security
Better monitoring

@Nexulo Nexulo added the enhancement New feature or request label May 14, 2023
@rapiz1
Copy link
Owner

rapiz1 commented May 14, 2023

Personally, I have not used a firewall with geoblocking. In the case of web applications on the client side, X-Forwarded-For can be used to pass on IP, which is the standard way for HTTP. Or you may want to apply firewall rules on the server side.

rathole tries to avoid overhead. Not everyone needs the original IPs, and for those in need, I bet the feature is already there in the upper protocol, e.g. HTTP.

@Nexulo
Copy link
Author

Nexulo commented May 14, 2023

Yes "X-Forwarded-For" is known to me but as far as I know this is not "safe" and can be manipulated.

So it seems that only a server side solution is possible. That is where rathole is active in "server" mode. I'm currently working with ufw but for example geoblocking is not easily possible.

I don't want to generate spam or an unnecessary post, but I think it would be good if the security aspect would be addressed here at the repository. Just for example that it is recommended to set up a server-side firewall.

Would be exciting to know if and how there are users here who have set up a server-side solution for geoblocking.

@rapiz1
Copy link
Owner

rapiz1 commented May 14, 2023

Yes "X-Forwarded-For" is known to me but as far as I know this is not "safe" and can be manipulated.

It's not safe when not configured appropriately. For most use cases, I think let the reverse proxy always removes any existing x-forwarded-for headers and always adds its own header is enough. It prevents visitors from bringing their own fake headers.

I'm currently working with ufw but for example geoblocking is not easily possible.

I have no experience with ufw and geoblocking. But I can't see how rathole server is different from other normal services with geoblocking. If you can set up a geoblocking rule with ufw for port 8000, at which some normal service is running, what blocks setting up a rule for port 9000, at which a service from rathole is running?

I think it would be good if the security aspect would be addressed here at the repository. Just for example that it is recommended to set up a server-side firewall.

Agree. examples/, docs/ can be further expanded for your use case, if you're interested.

In the future maybe a repo wiki is needed. README has grown a lot since the project launch.

@fernvenue
Copy link
Contributor

I don't think rathole should do anything with firewall, why not just use ufw with fail2ban? That's really simple to do these kind of things.

@Nexulo
Copy link
Author

Nexulo commented May 14, 2023

It's not about rathole doing anything with firewall for me either. I just think it is important that at least it is pointed out that you should pay attention to security and a firewall is recommended.

How would a solution with fail2ban be implemented, roughly? Assuming the service behind the tunnel is Plex, it would be very difficult to integrate fail2ban. How does Plex communicate on the private network with fail2ban on the Rathole server? Plex is very special because you have to log in with your Plex account.

@fernvenue
Copy link
Contributor

How does Plex communicate on the private network with fail2ban on the Rathole server? Plex is very special because you have to log in with your Plex account.

Actually, fail2ban can read the log, you can just set logpath in jail, and the failregex in aggressive, so that fail2ban can ban anyone who login failed, and yea there're maxretry, ignoreip or some other useful features, you can do that on your private network. By the way, on the rathole server, fail2ban can also do something, such as geoblocking as you guys said above.

@Nexulo
Copy link
Author

Nexulo commented May 14, 2023

Yes fail2ban is known to me. But how exactly should this work if all requests via the rathole tunnel have the LOCAL ip address 127.0.0.1? That is the problem and 127.0.0.1 can not be blocked. You have the same problem with a Synology NAS with active geoblocking and active tunneling.

Maybe I'm misunderstanding something, but a fail2ban solution is not possible in the private network. Not as long as each user simply has the IP address 127.0.0.1 which I can see at least in the Synology logs when a user uses incorrect login data.

@fernvenue
Copy link
Contributor

That is the problem and 127.0.0.1 can not be blocked.

Ah, I see your doubts, what do you think about action part in fail2ban configuration? Maybe you can do something here to make your rathole client server send a message to tell the rathole server to ban this IP address?

@Nexulo
Copy link
Author

Nexulo commented May 14, 2023

The logic does not work, because all accesses to my private network, which run over the tunnel, have the local IP 127.0.0.1. Every incorrect login attempt has the IP address 127.0.0.1 stored and I can not block this, because then the tunnel is blocked and this is a local IP address.

@fernvenue
Copy link
Contributor

The logic does not work, because all accesses to my private network, which run over the tunnel, have the local IP 127.0.0.1.

What if you put a reverse proxy like NGINX to use proxy protocol? Not like X-Forwarded-For, it is based on TCP stream.

@Nexulo
Copy link
Author

Nexulo commented May 14, 2023

I will look at this as soon as I have time. Thanks for your help :)

@fernvenue
Copy link
Contributor

I will look at this as soon as I have time. Thanks for your help :)

Glad to help :)

@Nexulo
Copy link
Author

Nexulo commented Oct 22, 2023

So I have now partially implemented a solution.

  • Set up and started a Nginx Proxy Manager (=NPM) with docker-compose.
  • Opened with ufw only specific ports (e.g. 443 for NPM)
  • Depending on which subdomain is called, NPM redirects the traffic to the respective port of Rathole and thus to the Rathole client.

Thanks to NPM the correct IP of the visitor is added as header and my devices (e.g. Synology NAS) can block P addresses after x failed login attempts.

Now I would just have to find a solution to send the failed login attempts from Plex to my Rathole server so that fail2ban takes this into account. Maybe I will do this one day.

Important to mention:

Docker sets rules in the iptables by default. Therefore, ufw rules would then be ignored.
So you have to change the docker systemd service file to run docker without changing iptables.

For me it was the file:
/lib/systemd/system/docker.service

And I had to add "--iptables=false" to the ExecStart command:
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=false

@cromulus
Copy link

cromulus commented Dec 16, 2023

Is there a chance perhaps the rathole client could forward the TCP stream to a unix domain socket, rather than an IP and a port? Would that help?

i.e. "unix:/tmp/sock" or "unix:/var/run/nginx.sock"

@archont00
Copy link

(Let's have a VPS with public IP; home LAN server behind CGNAT providing various services).

So:

  • Setting up a reverse proxy for HTTP(s) on VPS before rathole server would allow passing the original ip address to services on client's side. That should be good for built-in brute force protection used e.g. by Nextcloud, Home Assistant, Wordpress and alike. Alternatively, the info about original IP address could be passed to VPS for banning by iptables as well.
  • Use of SSH jumping (from VPS via Proxy Jump to client's SSH service) and fail2ban on VPS might provide some protection for SSH.
  • Not sure about other stuff (imap, smtp, ldap, ...). As the rathole client always provides local IP address, fail2ban on cleint's side of tunnel makes no sense.

This actually makes me re-consider the WireGuard tunnel between VPS and LAN server (with port fowarding without masquerade/snat to keep the external source ip address). The down-side of this approach is that the route for replying packets from LAN server must go via VPS and not via my local internet connection.

Not sure at the moment, if this means a default home LAN server's route for every out-going packets to go via VPS (which would consume VPS's bandwidth unnecessarily) or some kind of dynamic routing for selected packets (Use of iptables connmark for anything coming via tunnel? Would this also work for dockerised services?).

@shshekhar93
Copy link

I had the similar use case (open access on local network, but fail2ban + lower ratelimits per IP + client certs for external connections) . However, the nginx and sshd access logs indicated all requests to have been coming from the local machine. Setting up haproxy / nginx on the VPS (rathole server) side to add the proxy protocol header would have worked, but it seemed like an overkill.

Reading up the Proxy Protocol specification, the V1 implementation seemed simple enough. So, I added the logic in rathole server to natively emit the proxy protocol v1 header. That way no additional setup is required on the VPS / rathole server side. Its available in my fork and this diff. Hope it helps someone else.

@linnuxx
Copy link

linnuxx commented Apr 16, 2024

I had the similar use case (open access on local network, but fail2ban + lower ratelimits per IP + client certs for external connections) . However, the nginx and sshd access logs indicated all requests to have been coming from the local machine. Setting up haproxy / nginx on the VPS (rathole server) side to add the proxy protocol header would have worked, but it seemed like an overkill.

Reading up the Proxy Protocol specification, the V1 implementation seemed simple enough. So, I added the logic in rathole server to natively emit the proxy protocol v1 header. That way no additional setup is required on the VPS / rathole server side. Its available in my fork and this diff. Hope it helps someone else.

Should the game server also have the "Proxy Protocolhaproxy-protocol"?
https://docs.papermc.io/velocity/configuration

@Appel-flappen
Copy link

I wanted to add that PROXY protocol is the standard solution for this, which can be found in many reverse proxies. I know rathole is not trying to be a reverse proxy per se, but it is proxying the TCP/UDP traffic. This is the PROXY protocol spec:
https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt

I have seen in many other issues that there seems to be some confusion about application layers and http. This proxy protocol we are talking about does not work on the application layer, it works on the transport layer (TCP). Since rathole proxies our traffic, I think it would be very useful for it to support PROXY protocol , which is defined for the purpose of allowing downstream servers to know the original requesting IP. This would make it work transparently with security systems like geoblocking, Fail2Ban, crowdsec etc.

@shshekhar93 already did some great work implementing v1, if that could be merged and potentially v2 added (v2 is just faster because it uses less bytes to represent the data) I think that would be a great feature.

I know we can use nginx to add the proxy protocol data, but then what is the point of using rathole? I can just tell nginx to send the TCP down a wireguard tunnel to my server. Rathole could be a brilliant all in one solution, (it already is) but for me the proxy protocol is a really important part. I use it to restrict access to certain internal services.

@linnuxx
Copy link

linnuxx commented Apr 29, 2024

I had the similar use case (open access on local network, but fail2ban + lower ratelimits per IP + client certs for external connections) . However, the nginx and sshd access logs indicated all requests to have been coming from the local machine. Setting up haproxy / nginx on the VPS (rathole server) side to add the proxy protocol header would have worked, but it seemed like an overkill.

Reading up the Proxy Protocol specification, the V1 implementation seemed simple enough. So, I added the logic in rathole server to natively emit the proxy protocol v1 header. That way no additional setup is required on the VPS / rathole server side. Its available in my fork and this diff. Hope it helps someone else.

how to build your project?
https://github.com/shshekhar93/rathole/tree/main

@shshekhar93
Copy link

how to build your project?
https://github.com/shshekhar93/rathole/tree/main

@linnuxx, The build process is same as the original project. cargo build --release should do the trick. You'd need cargo / rust to be installed. Take a look at the docs/build-guide.md in the repo for more details about the build process.

@nando2301
Copy link

nando2301 commented May 5, 2024

I had the similar use case (open access on local network, but fail2ban + lower ratelimits per IP + client certs for external connections) . However, the nginx and sshd access logs indicated all requests to have been coming from the local machine. Setting up haproxy / nginx on the VPS (rathole server) side to add the proxy protocol header would have worked, but it seemed like an overkill.

Reading up the Proxy Protocol specification, the V1 implementation seemed simple enough. So, I added the logic in rathole server to natively emit the proxy protocol v1 header. That way no additional setup is required on the VPS / rathole server side. Its available in my fork and this diff. Hope it helps someone else.

Hi @

I had the similar use case (open access on local network, but fail2ban + lower ratelimits per IP + client certs for external connections) . However, the nginx and sshd access logs indicated all requests to have been coming from the local machine. Setting up haproxy / nginx on the VPS (rathole server) side to add the proxy protocol header would have worked, but it seemed like an overkill.
Reading up the Proxy Protocol specification, the V1 implementation seemed simple enough. So, I added the logic in rathole server to natively emit the proxy protocol v1 header. That way no additional setup is required on the VPS / rathole server side. Its available in my fork and this diff. Hope it helps someone else.

how to build your project? https://github.com/shshekhar93/rathole/tree/main

Hi @shshekhar93 , I tried to compile your project and didn't succeed, would you be so kind to provide the instructions, I compiled default, rustls and minimal, to no avail.

Error:

   Compiling rathole v0.5.0 (/opt/apps/src/rathole)
error: could not compile `rathole` (bin "rathole")

Caused by:
  process didn't exit successfully: `/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name rathole --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=202 --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C codegen-units=1 --cfg 'feature="base64"' --cfg 'feature="client"' --cfg 'feature="default"' --cfg 'feature="futures-core"' --cfg 'feature="futures-sink"' --cfg 'feature="hot-reload"' --cfg 'feature="native-tls"' --cfg 'feature="noise"' --cfg 'feature="notify"' --cfg 'feature="server"' --cfg 'feature="snowstorm"' --cfg 'feature="tokio-native-tls"' --cfg 'feature="tokio-tungstenite"' --cfg 'feature="tokio-util"' --cfg 'feature="websocket-native-tls"' -C metadata=6cbb8e45d5e5b7c1 -C extra-filename=-6cbb8e45d5e5b7c1 --out-dir /opt/apps/src/rathole/target/release/deps -C strip=symbols -L dependency=/opt/apps/src/rathole/target/release/deps --extern anyhow=/opt/apps/src/rathole/target/release/deps/libanyhow-2b1ecd8117f9e2da.rlib --extern async_http_proxy=/opt/apps/src/rathole/target/release/deps/libasync_http_proxy-8888ff3f909e405e.rlib --extern async_socks5=/opt/apps/src/rathole/target/release/deps/libasync_socks5-9371eae0d117e9f8.rlib --extern async_trait=/opt/apps/src/rathole/target/release/deps/libasync_trait-2694b15c6fca31f7.so --extern atty=/opt/apps/src/rathole/target/release/deps/libatty-254c695d8dd15faa.rlib --extern backoff=/opt/apps/src/rathole/target/release/deps/libbackoff-49849c6efe805e7e.rlib --extern base64=/opt/apps/src/rathole/target/release/deps/libbase64-bb283772eeb122ec.rlib --extern bincode=/opt/apps/src/rathole/target/release/deps/libbincode-31cd06593c45f0ff.rlib --extern bytes=/opt/apps/src/rathole/target/release/deps/libbytes-52e01dbae5e68909.rlib --extern clap=/opt/apps/src/rathole/target/release/deps/libclap-aa1d8b0d25bae098.rlib --extern fdlimit=/opt/apps/src/rathole/target/release/deps/libfdlimit-5c69d33903a97d2d.rlib --extern futures_core=/opt/apps/src/rathole/target/release/deps/libfutures_core-7a90f975f04f1fb2.rlib --extern futures_sink=/opt/apps/src/rathole/target/release/deps/libfutures_sink-e94bf929770deb9d.rlib --extern hex=/opt/apps/src/rathole/target/release/deps/libhex-9c3ec43297ec6ef0.rlib --extern lazy_static=/opt/apps/src/rathole/target/release/deps/liblazy_static-eed76de70908220b.rlib --extern notify=/opt/apps/src/rathole/target/release/deps/libnotify-aed9fcacd6089dae.rlib --extern rand=/opt/apps/src/rathole/target/release/deps/librand-b4962b846cd6bf0c.rlib --extern rathole=/opt/apps/src/rathole/target/release/deps/librathole-3f649ffb42327366.rlib --extern serde=/opt/apps/src/rathole/target/release/deps/libserde-d5eb45ba00db1df4.rlib --extern sha2=/opt/apps/src/rathole/target/release/deps/libsha2-3811d8bfb064d37b.rlib --extern snowstorm=/opt/apps/src/rathole/target/release/deps/libsnowstorm-752d76252520e007.rlib --extern socket2=/opt/apps/src/rathole/target/release/deps/libsocket2-a89db7efb6f9abe2.rlib --extern tokio=/opt/apps/src/rathole/target/release/deps/libtokio-4af81d401efd0327.rlib --extern tokio_native_tls=/opt/apps/src/rathole/target/release/deps/libtokio_native_tls-07c1d7c2174dedbd.rlib --extern tokio_tungstenite=/opt/apps/src/rathole/target/release/deps/libtokio_tungstenite-45867ee738de20d6.rlib --extern tokio_util=/opt/apps/src/rathole/target/release/deps/libtokio_util-12ec4ec49c22bab7.rlib --extern toml=/opt/apps/src/rathole/target/release/deps/libtoml-9df61b00a11efb25.rlib --extern tracing=/opt/apps/src/rathole/target/release/deps/libtracing-164088329d860329.rlib --extern tracing_subscriber=/opt/apps/src/rathole/target/release/deps/libtracing_subscriber-8962beaad0fbc583.rlib --extern url=/opt/apps/src/rathole/target/release/deps/liburl-abc5f3feeafd8ec5.rlib` (signal: 9, SIGKILL: kill)

With rustls:

INFO connection{addr=189.216.170.87:42496}:handle{service=nas_https}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:50>
INFO connection{addr=189.216.170.87:42524}: rathole::server: Try to handshake a control channel

Please provide more detail, Thanks, this software is great.

@nando2301
Copy link

I had the similar use case (open access on local network, but fail2ban + lower ratelimits per IP + client certs for external connections) . However, the nginx and sshd access logs indicated all requests to have been coming from the local machine. Setting up haproxy / nginx on the VPS (rathole server) side to add the proxy protocol header would have worked, but it seemed like an overkill.

Reading up the Proxy Protocol specification, the V1 implementation seemed simple enough. So, I added the logic in rathole server to natively emit the proxy protocol v1 header. That way no additional setup is required on the VPS / rathole server side. Its available in my fork and this diff. Hope it helps someone else.

Hi, please provide linux binary versions, I have Ubuntu 22.04 LTS x86_64 but trying to compile your version with proxy protocol fails. Thanks

@nando2301
Copy link

nando2301 commented May 19, 2024

how to build your project?
https://github.com/shshekhar93/rathole/tree/main

@linnuxx, The build process is same as the original project. cargo build --release should do the trick. You'd need cargo / rust to be installed. Take a look at the docs/build-guide.md in the repo for more details about the build process.

Hi @shshekhar93 , thanks for you help, I compiled it successfully in a new Ubuntu 22.04 VM and the option, enable_proxy_protocol = true is accepted but this error is broke my HTTPS ports

Browser: PR_END_OF_FILE_ERROR or SSL_ERROR_RX_RECORD_TOO_LONG

Note: I copied your compiled version on both machines.

Client:

rathole
Build Timestamp:     2024-05-18T16:10:36.177057154Z
Build Version:       0.5.0
Commit SHA:          Some("c013a20e52f092fd87c47f54015fa282567ef6ad")
Commit Date:         Some("2024-04-10T18:37:06Z")
Commit Branch:       Some("main")
cargo Target Triple: x86_64-unknown-linux-gnu
cargo Profile:       release
cargo Features:      base64,client,default,futures_core,futures_sink,hot_reload,native_tls,noise,notify,server,snowstorm,tokio_native_tls,tokio_tungstenite,tokio_util,websocket_native_tls
[client.services.haproxy_https]
token = "_"
local_addr = "127.0.0.1:8443"

[client.services.nas_https]
token = "_"
local_addr = "192.168.0.150:5001"
May 18 22:46:04 pop-os systemd[1]: Stopping Rathole Client Service...
May 18 22:46:04 pop-os systemd[1]: rathole.service: Deactivated successfully.
May 18 22:46:04 pop-os systemd[1]: Stopped Rathole Client Service.
May 18 22:46:04 pop-os systemd[1]: Started Rathole Client Service.
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053162Z  INFO handle{service=haproxy_https}: rathole::client: Starting 8aedf3651353b130bf182715d39b14cf919026aa5962215c98778de6358907bf
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053185Z  INFO handle{service=nas_http}: rathole::client: Starting 2a542886e28301f4fd0f67a4f7cb0900d04abb2c2d203b5f43228eee25559dc6
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053193Z  INFO handle{service=drawio_https}: rathole::client: Starting 9a989463103ffce692a01bc0f1127d941dc2be43f5c697100228ff25c72f43ad
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053199Z  INFO handle{service=plex_https}: rathole::client: Starting 6027d52f985aa47c9d4e7b9ef6bc03623e5d4ca18e4576963b8f35a067786c05
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053203Z  INFO handle{service=nas_drive}: rathole::client: Starting 3e5c068951ff7c871d715d655e4b7cde077eadaaab845c0a69649abf8eb65926
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053208Z  INFO handle{service=immich_https}: rathole::client: Starting d0c414d497e89c79a7570d86c1e9ffca72e9a035b3101b5b417ca0ec4997967d
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053212Z  INFO handle{service=nas_http_5000}: rathole::client: Starting 8c1cf36c85e41cb53e3b4bd69b8c72d57b4457049d75a9b82e77ade84e273c37
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053217Z  INFO handle{service=nas_ssh}: rathole::client: Starting d718f852b153490651fffc30a3eca6be98d117ca673f8013541d1f397384949d
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053222Z  INFO handle{service=nas_https}: rathole::client: Starting b5c7fafb565d71e2ac3c66cc4e75597cfc97fe8572c3b6e77dd3cd34acf89850
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.053241Z  INFO config_watcher{path="/opt/apps/rathole/client.toml"}: rathole::config_watcher: Start watching the config
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.264314Z  INFO handle{service=plex_https}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.265366Z  INFO handle{service=nas_http}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.265833Z  INFO handle{service=nas_drive}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.267723Z  INFO handle{service=nas_http_5000}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.267906Z  INFO handle{service=drawio_https}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.268213Z  INFO handle{service=immich_https}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.268677Z  INFO handle{service=nas_https}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.268977Z  INFO handle{service=haproxy_https}:run: rathole::client: Control channel established
May 18 22:46:04 pop-os rathole[18105]: 2024-05-19T04:46:04.269499Z  INFO handle{service=nas_ssh}:run: rathole::client: Control channel established

Server:

rathole
Build Timestamp:     2024-05-18T16:10:36.177057154Z
Build Version:       0.5.0
Commit SHA:          Some("c013a20e52f092fd87c47f54015fa282567ef6ad")
Commit Date:         Some("2024-04-10T18:37:06Z")
Commit Branch:       Some("main")
cargo Target Triple: x86_64-unknown-linux-gnu
cargo Profile:       release
cargo Features:      base64,client,default,futures_core,futures_sink,hot_reload,native_tls,noise,notify,server,snowstorm,tokio_native_tls,tokio_tungstenite,tokio_util,websocket_native_tls
[server.services.haproxy_https]
token = "_" 
bind_addr = "0.0.0.0:443"
enable_proxy_protocol = true

[server.services.nas_https]
token = "_" #
bind_addr = "0.0.0.0:5001"
enable_proxy_protocol = true
May 18 22:44:09 ubuntu systemd[1]: Stopping Rathole Server Service...
May 18 22:44:09 ubuntu systemd[1]: rathole.service: Deactivated successfully.
May 18 22:44:09 ubuntu systemd[1]: Stopped Rathole Server Service.
May 18 22:44:09 ubuntu systemd[1]: Started Rathole Server Service.
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.291304Z  INFO config_watcher{path="/opt/apps/rathole/server.toml"}: rathole::config_watcher: Start watching the config
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.291777Z  INFO rathole::server: Listening at 0.0.0.0:2333
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.893460Z  INFO connection{addr=189.216.170.87:39520}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.893876Z  INFO connection{addr=189.216.170.87:39536}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.913043Z  INFO connection{addr=189.216.170.87:39546}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.919004Z  INFO connection{addr=189.216.170.87:39548}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.935956Z  INFO connection{addr=189.216.170.87:39550}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.954016Z  INFO connection{addr=189.216.170.87:39560}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.956881Z  INFO connection{addr=189.216.170.87:39576}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.963588Z  INFO connection{addr=189.216.170.87:39520}: rathole::server: Control channel established service=plex_https
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.963952Z  INFO connection{addr=189.216.170.87:39520}:handle{service=plex_https}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:32401
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.964214Z  INFO connection{addr=189.216.170.87:39536}: rathole::server: Control channel established service=haproxy_https
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.964467Z  INFO connection{addr=189.216.170.87:39536}:handle{service=haproxy_https}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:443
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.980461Z  INFO connection{addr=189.216.170.87:39582}: rathole::server: Try to handshake a control channel
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.982936Z  INFO connection{addr=189.216.170.87:39546}: rathole::server: Control channel established service=nas_drive
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.983145Z  INFO connection{addr=189.216.170.87:39546}:handle{service=nas_drive}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:6690
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.988850Z  INFO connection{addr=189.216.170.87:39548}: rathole::server: Control channel established service=immich_https
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.989070Z  INFO connection{addr=189.216.170.87:39548}:handle{service=immich_https}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:2284
May 18 22:44:09 ubuntu rathole[329637]: 2024-05-19T04:44:09.995490Z  INFO connection{addr=189.216.170.87:39592}: rathole::server: Try to handshake a control channel
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.005591Z  INFO connection{addr=189.216.170.87:39550}: rathole::server: Control channel established service=nas_http
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.005858Z  INFO connection{addr=189.216.170.87:39550}:handle{service=nas_http}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:80
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.023588Z  INFO connection{addr=189.216.170.87:39560}: rathole::server: Control channel established service=nas_https
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.023995Z  INFO connection{addr=189.216.170.87:39560}:handle{service=nas_https}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:5001
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.026599Z  INFO connection{addr=189.216.170.87:39576}: rathole::server: Control channel established service=nas_http_5000
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.026829Z  INFO connection{addr=189.216.170.87:39576}:handle{service=nas_http_5000}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:5000
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.050007Z  INFO connection{addr=189.216.170.87:39582}: rathole::server: Control channel established service=nas_ssh
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.050547Z  INFO connection{addr=189.216.170.87:39582}:handle{service=nas_ssh}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:2028
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.065187Z  INFO connection{addr=189.216.170.87:39592}: rathole::server: Control channel established service=drawio_https
May 18 22:44:10 ubuntu rathole[329637]: 2024-05-19T04:44:10.065544Z  INFO connection{addr=189.216.170.87:39592}:handle{service=drawio_https}:run_tcp_connection_pool: rathole::server: Listening at 0.0.0.0:8081

Thanks for your help.

@mydoomfr
Copy link

Hello! Thank you so much for the PR, @shshekhar93; I hope it will get accepted soon. 👍

@nando2301, Proxy Protocol v1 is working fine on my side. I believe your issue is on the backend, which needs to be configured as well to accept the proxy protocol. In my case, I'm using Traefik v3.0.0.

If you want to make sure it's not related to the rathole build, you can test with this image: https://hub.docker.com/r/mydoomfr/rathole

@nando2301
Copy link

Thanks for the comment, I have HAProxy in front of my services, I will check that you comment. Thanks.

@nando2301
Copy link

Thanks @mydoomfr

Ready!

Now the IP Blocking is Working

Attack (IP received on HAProxy due to proxy protocol v1 is enabled):

May 27 22:44:46 pop-os haproxy[79812]: 60.190.204.30:45300 [27/May/2024:22:44:41.985] synology~ synology_backend/synology TLSv1.3 TLS_AES_128_GCM_SHA256 0/0/2/4777/4779 200 629 - - ---- 4/3/1/1/0 0/0 "GET //webapi/auth.cgi?api=SYNO.API.Auth&version=3&method=login&account=mr&passwd=mr HTTP/1.1"

HAProxy Config (I just added accept-proxy) on frontend:

frontend synology
    bind *:5001 ssl crt /cert/path alpn h2,http/1.1 accept-proxy
    mode http
    default_backend synology_backend

backend synology_backend
    mode http
    option forwardfor
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    http-request add-header X-Forwarded-For %[src]
    server synology 192.168.0.150:5001 check ssl verify none

Synology Blocked IPs:

image

Thanks for all information and guidance, This project is great!

@pkarc
Copy link

pkarc commented Jun 26, 2024

I can confirm that the @shshekhar93 branch work pretty well, also supporting v2 binary would be very useful as rathole tries its bets to avoid overhead. cheers @shshekhar93 and thank you.

BTW the PR(#352 ) is stuck on linting

@pkarc
Copy link

pkarc commented Jul 4, 2024

Follow up this issue I end up doing some work on the proxy protocol support suggest by @shshekhar93 now supporting v2 as well, I'm using this right now without any issue

Any feedback is really appreciated, as its my first time using RUST

main...pkarc:rathole:proxy-protocol

@hendrikbl
Copy link

I'm using rathole to forward ssh connections to a local sftp server, wich works great. But I have no experience with ssh proxies or anything like that. Is it possible to get the original ip when using ssh so I can use fail2ban? I can't use X-Forwarded there or can I?

@fernvenue
Copy link
Contributor

I'm using rathole to forward ssh connections to a local sftp server, wich works great. But I have no experience with ssh proxies or anything like that. Is it possible to get the original ip when using ssh so I can use fail2ban? I can't use X-Forwarded there or can I?

Try use proxy protocol. Since Rathole does not work at the application layer, you need to use an application that supports the proxy protocol.

@hendrikbl
Copy link

Try use proxy protocol. Since Rathole does not work at the application layer, you need to use an application that supports the proxy protocol.

How would I go about doing that? I currently only use a proxy (caddy) for my http/https webservices wich usually understand the X-Forwarded headers.
If I understand correctly I would need something that adds the proxy haeder for proxy protocol in front of my rathole server and then behind my rathole client to expose the real ip to my sftp service.

@fernvenue
Copy link
Contributor

How would I go about doing that?

@hendrikbl As I said above, you have to use third-party applications, such as gost/proxy-protocol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests