ProxymanApp / Proxyman

Modern. Native. Delightful Web Debugging Proxy for macOS, iOS, and Android ⚡️
https://proxyman.io
5.49k stars 180 forks source link

Reverse proxy for development needs #941

Open lorddaedra opened 3 years ago

lorddaedra commented 3 years ago

I have Django&Ariadne (RESTful and GraphQL) backend server on 127.0.0.1:8000 (core.mycompany.com in production). Also I have Vite&Vue.js frontend server on 127.0.0.1:3000 (console.mycompany.com in production environment).

I edited /etc/hosts and included my dev domains and configured domain cookies to .mycompany.local for development environment.

127.0.0.1 core.mycompany.local console.mycompany.local

Now I would like to create some kind of reverse proxy and create certificates to make my dev environment closer to production environment (so I can use https://console.mycompany.local in my browser instead of http://console.mycompany.local:3000, use secure cookies etc.).

Related with issue https://github.com/ProxymanApp/Proxyman/issues/447

So I would like to use Proxyman as proxy. Is it possible to do with Proxyman?.. Or is anything with better UI/UX than just nginx in container as proxy for that task?..

NghiaTranUIT commented 3 years ago

Hey @lorddaedra, please try either following the Reverse Proxy Rule (Please enable one at a time) and test it.

You can use https://console.mycompany.local

Proxy to your real production (https)

Browser <--(HTTPS)--> Proxyman <--(HTTPS)--> Real production server

Screen Shot 2021-07-20 at 11 48 37

Proxy to your local server (http)

Browser <--(HTTPS)--> Proxyman <--(HTTP)--> local server at port 3000

Screen Shot 2021-07-20 at 11 47 40
lorddaedra commented 3 years ago

@NghiaTranUIT Thank you for answer!

Can I configure several subdomains (console.mycompany.local and core.mycompany.local) with same local port (443)?

Browser <--(HTTPS)--> Proxyman (console.mycompany.local:443) <--(HTTP)--> 127.0.0.1:3000 (or console.mycompany.local:3000) Browser <--(HTTPS)--> Proxyman (core.mycompany.local:443) <--(HTTP)--> 127.0.0.1:8000 (or core.mycompany.local:8000)

NghiaTranUIT commented 3 years ago

It's possible but we have to create two Reverse Proxy at two different Local Ports. One for the Console and One for the Core.


I suppose we can use Map Remote, which is easier @lorddaedra 😄

Please try to create two Map Remote Rules like the following screenshot

Screen Shot 2021-07-20 at 16 44 44 Screen Shot 2021-07-20 at 16 45 27

By doing this way,

  1. http://console.mycompany.local:3000 -> Will map to https://console.mycompany.com:443
    1. http://core.mycompany.local:5000 -> Will map to https://core.mycompany.com:443
lorddaedra commented 3 years ago

@NghiaTranUIT Thanks again for answer!

I think, I should say about 2 things here.

1.) About my task

Goal of that setup: check correct work of secure cross-subdomain sessions and auth between two dev local subdomains, only .local subdomains (127.0.0.1) used here.

You wrote:

http://console.mycompany.local:3000 -> Will map to https://console.mycompany.com:443 http://core.mycompany.local:8000 -> Will map to https://core.mycompany.com:443

But actually I need these rules:

https://console.mycompany.local:443 -> Will map to http://127.0.0.1:3000 (or http://console.mycompany.local:3000) https://core.mycompany.local:443 -> Will map to http://127.0.0.1:8000 (or http://core.mycompany.local:8000)

So,

  1. I open iTerm2, run Django devserver in first tab (it binds 127.0.0.1:8000) (or default Terminal or click Run dev server button in PyCharm IDE, there are many ways to run dev server),
  2. next run Vite dev server in second iTerm tab (it binds 127.0.0.1:3000).
  3. Now I can just use http://console.mycompany.local:3000 and http://core.mycompany.local:8000 in browser. But I would like to add TLS encryption and remove that ports to default 443. (Because of my goal: check correct work of secure cross-subdomain sessions).
  4. Next I do something with proxy (open Proxyman and configure somehow).
  5. After that (expected result) I can open browser, go to https://console.mycompany.local (with httpS and without :port at the end) and it should work (encrypt connection and proxy to local http dev server), next go to https://core.mycompany.local and it should work too (same thing, but another subdomain and another port).

2.) About possible bug

But I would like to ask question before: do I need execute some commands after reinstall of Proxyman (I ask not about root certificate, but anything else, may be related with network configuration)?

NghiaTranUIT commented 3 years ago

Thanks for getting back to me @lorddaedra

But I would like to ask question before: do I need execute some commands after reinstall of Proxyman (I ask not about root certificate, but anything else, may be related with network configuration)?

You don't need to execute any command after reinstalling the Proxyman app. For the network configuration, Proxyman automatically executes networksetup (if you haven't installed Helper Tool), or use Helper Tool to override the network config.

For the first question, I'm reading it and answer you soon 👍

lorddaedra commented 3 years ago

2.) Looks like there are several bugs:

a.) Open apple.com in Safari handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435613 error:1000009d:SSL routines:OPENSSL_internal:INAPPROPRIATE_FALLBACK])), but In Brave Browser (Chromium based browser) it works...

b.) Need disable and exit from ProtonVPN app. Even if Kill switch is Off in ProtonVPN settings, requests not logged in Proxyman. Sometimes need restart Proxyman after that.

ifconfig results (if it helps): https://dpaste.org/TbGj

NghiaTranUIT commented 3 years ago

a.) Open apple.com in Safari handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435613 error:1000009d:SSL routines:OPENSSL_internal:INAPPROPRIATE_FALLBACK])), but In Brave Browser (Chromium based browser) it works...

It's because of the SSL-Pinning if we try to intercept apple.com traffic from Safari. Chrome, Firefox, and Brave work fine. This issue occurs on other Web debugging proxy apps too, such as Charles, Fiddler, and Burp Suite.

From what I know so far, there is no way to bypass the SSL-Pinning.

b.) Need disable and exit from ProtonVPN app. Even if Kill switch is Off in ProtonVPN settings, requests not logged in Proxyman. Sometimes need restart Proxyman after that.

If you could not see traffic on Proxyman when using ProtonVPN, please go to Network Preference -> Wifi -> Advanced... -> Proxies tab -> And see if HTTP/HTTPS checkbox is enabled. If it's enabled it must be 127.0.0.1:9090 (or a different Proxyman port)

I suppose that ProtonVPN might override the HTTP/HTTPS Proxy, so Proxyman could not capture the traffic.

lorddaedra commented 3 years ago

If you could not see traffic on Proxyman when using ProtonVPN, please go to Network Preference -> Wifi -> Advanced... -> Proxies tab -> And see if HTTP/HTTPS checkbox is enabled. If it's enabled it must be 127.0.0.1:9090 (or a different Proxyman port)

  1. I connect to ProtonVPN server. Now sites works in browser, traffic not logged in Proxyman. I checked proxy, 127.0.0.1:9090 enabled for http and https traffic for both Ethernet and Wi-Fi.
  2. I disconnect. Now nothing works, I do not see anything in browser.
  3. I restart Proxyman. Now I get a big list of requests and it works fine.
NghiaTranUIT commented 3 years ago

Thanks for the hint @lorddaedra. Basically, Proxyman and other web debugging proxy apps might conflict with VPN apps. Some might work, some might not 😢

I collect all VPN feedback here https://docs.proxyman.io/troubleshooting/proxyman-does-not-work-with-vpn-apps

Meanwhile, I will try to reproduce it on my end and see if I can fix it.

lorddaedra commented 3 years ago

It's okay for me to disable ProtonVPN during development. But it's nice to have feature to make them compatible to each other (of course, if Kill switch is Off in ProtonVPN connection settings, this is expected behaviour in that case).

I will try to reproduce it on my end and see if I can fix it.

I also suggest to install Docker for Mac too during testing. https://docs.docker.com/docker-for-mac/install/ It could affect or not because of it add some rules to network configuration. Other things on my side looks standard (network topology is simple too: Mac mini -> MikroTik router -> Internet Provider).

lorddaedra commented 3 years ago

For the first question, I'm reading it and answer you soon 👍

This is how I solved it (I did it without Proxyman but I think it looks as good feature for Proxyman):

So

  1. Add 127.0.0.1 core.mycompany.local console.mycompany.local to the end of /etc/hosts
  2. brew install caddy nss
  3. caddy trust
  4. vim /usr/local/etc/Caddyfile
    
    core.mycompany.local {
    tls internal
    reverse_proxy http://127.0.0.1:8000
    }

console.mycompany.local { tls internal reverse_proxy http://127.0.0.1:3000 }


4. ```brew services start caddy```

If it's possible to do somehow via Proxyman in current version, please, tell me.
Proxyman has GUI, I like it, users will prefer Proxyman over Caddy I guess...
eirenik0 commented 5 months ago

Would be great to have such feature that shows @lorddaedra

NghiaTranUIT commented 5 months ago

@eirenik0 If your python server uses one of these libraries: http, https, aiohttp, or requests. There is a simple solution by using the Automatic Setup: https://docs.proxyman.io/automatic-setup/automatic-setup

This tool will open the pre-configured Terminal -> Start your local Python server here -> Proxyman will automatically capture these traffic and handle the self-singed SSL (no need to trust Proxyman certificate in your codebase) 👍

eirenik0 commented 5 months ago

@NghiaTranUIT thanks for answer!

But it won't cover my need. Look, I have app that make some request to remote servers. For some reason, I can add to this app only domain that is not equal remote domain. But the request should be send to the actual remote domain.

If app allows to add domain with port I could add just https://proxyman.debug:7878/ and redirect inside app. But, app allows to add only domain names without port. So, I need to add intermediate reverse proxy like Caddy which will convert mydomain.local -> proxyman.debug:7878 -> Proxyman -> remote.domain.com