rapiz1 / rathole

A lightweight and high-performance reverse proxy for NAT traversal, written in Rust. An alternative to frp and ngrok.
Apache License 2.0
9.47k stars 475 forks source link

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

Open Nexulo opened 1 year ago

Nexulo commented 1 year ago

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

rapiz1 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

fernvenue commented 1 year ago

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

Glad to help :)

Nexulo commented 11 months ago

So I have now partially implemented a solution.

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 commented 9 months ago

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 commented 9 months ago

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

So:

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 4 months ago

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 commented 4 months ago

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 commented 4 months ago

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

nando2301 commented 4 months ago

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 commented 3 months ago

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 commented 3 months ago

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

https://github.com/rapiz1/rathole/compare/main...pkarc:rathole:proxy-protocol