Introduction
Port Forwarding Helper helps you reach Screen Sharing on a Mac inside a private network through encrypted SSH tunnels. Manage local (-L) and reverse (-R) port forwarding from your menu bar, using your own SSH server.
Keep multiple tunnels in one place, check their connection status, and reconnect automatically when a connection drops. Private keys are stored encrypted on your Mac, and password-encrypted configuration import and export lets you move your tunnel setup between Macs.
Reach Screen Sharing from another Mac
For this example, Mac A is the Mac you want to control, and Mac B is the Mac you connect from. Install Port Forwarding Helper on both Macs. Both connect to the same trusted SSH server.
How the configuration form works
Click Add to open the configuration form. The tables below use the app’s actual English field labels. Select -R or -L using the two forwarding options. Enter host addresses and port numbers in separate fields: for example, 127.0.0.1:5900 means Target Host = 127.0.0.1 and Target Port = 5900. Access Port takes only a number.
In every table, replace ssh.example.com with your server’s real address, alice with your SSH username, and 22 with your server’s SSH port if different. Select a supported private key authorized for that user. Each Mac can use its own SSH user and private key, provided the server permits the required connections. The example names are just labels you can change.
On Mac A: share the screen through a reverse tunnel
Enable Screen Sharing in macOS on Mac A. In Port Forwarding Helper, click Add and fill in:
| Form field | Value | What it means |
|---|---|---|
| Name | Screen Sharing — Share |
A label for this tunnel. |
| -L / -R | -R | Create the access port on the SSH server. |
| SSH Host | ssh.example.com |
Your trusted SSH server. |
| User | alice |
Your SSH login user on that server. |
| SSH Port | 22 |
The server’s SSH login port. |
| Private Key | Select your private key file | The key authorized for this SSH user. |
| Target Host | 127.0.0.1 |
In -R, this refers to Mac A itself. |
| Target Port | 5900 |
Screen Sharing on Mac A. |
| Access Port | 15900 |
The port to create on the SSH server. |
Click Save. New tunnels start switched off; turn this tunnel on in the list. If prompted, verify the server fingerprint against a trusted source before accepting it, and unlock your private key if needed. Wait for the tunnel to show connected.
On Mac B: reach that server port through a local tunnel
In Port Forwarding Helper on Mac B, click Add and fill in:
| Form field | Value | What it means |
|---|---|---|
| Name | Screen Sharing — Connect |
A label for this tunnel. |
| -L / -R | -L | Create the access port on Mac B. |
| SSH Host | ssh.example.com |
The same SSH server Mac A uses. |
| User | alice |
Your SSH login user on that server. |
| SSH Port | 22 |
The server’s SSH login port. |
| Private Key | Select your private key file | The key authorized for this SSH user. |
| Target Host | 127.0.0.1 |
In -L, this refers to the SSH server itself. |
| Target Port | 15900 |
Must match Mac A’s Access Port. |
| Access Port | 15901 |
The port your client will use on Mac B. |
Click Save, turn the tunnel on, and complete any fingerprint confirmation or private key unlock. With both tunnels connected, open Screen Sharing on Mac B and connect to vnc://127.0.0.1:15901. Use the credentials permitted by Mac A’s Screen Sharing settings.
Here, 127.0.0.1 in the Screen Sharing client refers to Mac B. The two Target Host fields contain the same address but refer to different machines because -R connects to its target from Mac A, while -L connects to its target from the SSH server.
These are example ports; choose available ports for your setup. A tunnel’s ready status confirms the forwarding setup, not that Screen Sharing is reachable or that its login will succeed.
Configure access on both ends. Restrict the reverse port to the server’s loopback interface through your SSH server configuration, and verify its actual listening addresses. The app does not enforce a loopback-only reverse listener. Do not open the mapped port to the public internet in your server firewall or cloud security group. The connecting Mac’s local tunnel listens on all IPv4 interfaces (0.0.0.0), so restrict inbound access to that port on untrusted networks as well.
Each SSH connection is encrypted, but the server is a trusted relay that may access traffic after SSH decryption. Two SSH tunnels alone do not provide end-to-end encryption between the Macs.
Reach SubWin from another Mac
SubWin keeps Windows 11 running in the background on your Apple Silicon Mac. Port Forwarding Helper lets you reach that Windows desktop from another Mac through your own SSH server—even when the two Macs are on different networks. Use Microsoft’s Windows App to view and control the desktop.
For this example, Mac A runs SubWin and Mac B is the Mac you connect from. Install Port Forwarding Helper on both Macs and configure them to use the same trusted SSH server.
On Mac A: forward SubWin’s RDP service
Start SubWin and finish Windows setup. First confirm that Windows App on Mac A can connect to localhost:3389. Keep the Windows username and password you created in SubWin handy.
In Port Forwarding Helper on Mac A, click Add. Use the same form workflow and placeholder replacement rules described above:
| Form field | Value | What it means |
|---|---|---|
| Name | SubWin — Share |
A label for this tunnel. |
| -L / -R | -R | Create the access port on the SSH server. |
| SSH Host | ssh.example.com |
Your trusted SSH server. |
| User | alice |
Your SSH login user on that server. |
| SSH Port | 22 |
The server’s SSH login port. |
| Private Key | Select your private key file | The key authorized for this SSH user. |
| Target Host | 127.0.0.1 |
Mac A, where SubWin provides its RDP entrance. |
| Target Port | 3389 |
SubWin’s local RDP port. |
| Access Port | 13389 |
The port to create on the SSH server. |
Click Save, turn this tunnel on, and complete any fingerprint confirmation or private key unlock. Wait for it to show connected.
On Mac B: create the local entrance for Windows App
In Port Forwarding Helper on Mac B, click Add and fill in:
| Form field | Value | What it means |
|---|---|---|
| Name | SubWin — Connect |
A label for this tunnel. |
| -L / -R | -L | Create the access port on Mac B. |
| SSH Host | ssh.example.com |
The same SSH server Mac A uses. |
| User | alice |
Your SSH login user on that server. |
| SSH Port | 22 |
The server’s SSH login port. |
| Private Key | Select your private key file | The key authorized for this SSH user. |
| Target Host | 127.0.0.1 |
The SSH server itself, as seen from its side of -L. |
| Target Port | 13389 |
Must match Mac A’s Access Port. |
| Access Port | 13390 |
The port Windows App will use on Mac B. |
Click Save, turn this tunnel on, and complete any fingerprint confirmation or private key unlock. With both tunnels connected, open Windows App on Mac B and add a PC with PC name set to 127.0.0.1:13390. Use the Windows username and password created in SubWin, rather than your Mac login or SSH credentials. This client address uses Mac B’s Access Port, not the server’s 13389 or SubWin’s 3389.
The connection follows this path:
Windows App on Mac B → local tunnel → SSH server → reverse tunnel on Mac A → SubWin
Keep both Macs awake, SubWin running, and both tunnels connected. The ports 13389 and 13390 are examples; choose available ports and keep the corresponding settings consistent. If SubWin uses a different local RDP port, replace 3389 with that port.
Apply the same server-loopback and local-port access restrictions described above. You do not need to forward port 3389 on Mac A’s router or expose the server’s mapped RDP port to the public internet. The SSH server remains a trusted relay; the two tunnels alone do not provide end-to-end encryption between the Macs.
Port Forwarding Helper carries TCP traffic, including this RDP connection; it does not carry RDP’s optional UDP transport. SubWin provides the Windows environment, Port Forwarding Helper provides the tunnels, and Windows App provides the remote desktop interface.
What you need
- Your own trusted SSH server.
- An OpenSSH-format Ed25519 or ECDSA private key, with or without a passphrase. RSA keys and SSH account password authentication are not supported.
Port Forwarding Helper does not include an SSH server or a remote desktop client.
Privacy
The app does not require an app account or include advertising, analytics, tracking, or automatic crash-reporting SDKs. Your tunnel settings and credentials stay on your Mac; connections go to the servers and services you configure. Diagnostic logs are not automatically uploaded. Read our Privacy Policy.
Frequently Asked Questions
How do I choose between local (-L) and reverse (-R) forwarding?
Choose based on where the service is reachable:
- -L: Access a service that your SSH server can reach. The app opens an Access Port on your Mac, and the SSH server connects to Target Host / Target Port.
- -R: Let your SSH server reach a service accessible from your Mac. The server opens an Access Port, and your Mac connects to Target Host / Target Port.
In both examples above, Mac A uses -R to share its service through the server, and Mac B uses -L to access it. See the field-by-field setup for Screen Sharing or SubWin.
Access Port takes only a port number. Target Host / Target Port identify the service you want to reach. SSH Port is the port used to log in to the SSH server; it is separate from both forwarding ports.
Why is the switch on when the tunnel is not connected?
The switch means “keep this tunnel connected,” not “the connection has succeeded.” First read the message below that tunnel; hover over it for the full explanation.
- If it is waiting for the network or retrying automatically, you can leave it enabled and wait.
- If it asks you to confirm a server fingerprint, unlock a private key, or fix authentication or configuration, complete that action first. Use Retry when offered after resolving the issue.
Check the status indicator to see whether the tunnel is ready. Turning the switch off stops the connection and further retries.
The tunnel is connected. Why won’t Screen Sharing or RDP open?
The app has established the tunnel, but it has not verified that your screen or Windows desktop can open. First check the client address on Mac B:
- For the Screen Sharing example, connect to
vnc://127.0.0.1:15901. - For the SubWin example, enter
127.0.0.1:13390as PC name in Windows App.
If you changed Mac B’s Access Port, use that number instead. Then check:
- Both tunnels show connected. These examples require Mac A’s -R tunnel and Mac B’s -L tunnel.
- Mac B’s Target Port matches Mac A’s Access Port. The example values are
15900for Screen Sharing and13389for SubWin; both use127.0.0.1as Target Host. - The service works on Mac A. Check that Screen Sharing is enabled, or that Windows App on Mac A can reach SubWin at
localhost:3389. Use the service’s login credentials, not your SSH credentials. - The server and firewalls allow the connections. A server can accept the SSH login but still restrict particular forwarding destinations.
- Read the error below the tunnel and open the diagnostic log for the specific failure reason.
For other setups, remember that -L reaches Target Host from the SSH server, while -R reaches it from the Mac running that tunnel. In the examples above, the reverse port should listen only on the server’s loopback interface, so connect through Mac B’s local tunnel rather than the server’s public address.
Which ports need to be reachable from the internet?
For the two-tunnel examples on this page, both Macs must be able to connect to your server’s SSH Port, usually 22 or your custom port.
- On the SSH server: Do not add public inbound firewall or cloud security group rules for the mapped port (
15900for Screen Sharing or13389for SubWin). Mac B reaches it from inside its SSH connection. - On Mac A’s router: You do not need to forward Screen Sharing port
5900or SubWin’s RDP entrance3389to the internet. - On Mac B’s router: You do not need to forward the local Access Port (
15901or13390) to the internet.
Keep Screen Sharing or Windows login authentication enabled. Restrict the server’s reverse listener to loopback as described in the examples.
Can other devices connect to my local forwarding port?
The app currently does not restrict a local forwarding port to access from this Mac alone. Its -L listener uses 0.0.0.0, meaning all IPv4 interfaces. Connecting to it from 127.0.0.1 does not make the listener private to your Mac. Other devices may reach it depending on routing and firewalls. If you only need access from this Mac, restrict inbound access with a host firewall and do not forward that port through your router. The app currently has no separate setting to choose a local listening address.
Why is my reverse (-R) tunnel’s Access Port still in use after a disconnect?
An old SSH session may still be holding the tunnel’s Access Port on the SSH server. After a network interruption, sleep, or a VPN disconnect, the server may not receive the old connection’s closing message. Its reverse listener can remain open, preventing the reconnecting -R tunnel from using the same port. The app may describe this as a possible half-open forwarding session.
This is one possible cause of a rejected forwarding request. Another service or an active tunnel using the same port, or a server forwarding restriction, can also cause rejection.
Restore the connection now
The app cannot close another SSH session’s listener. Ask the server administrator to identify the listener and its owning session before deciding whether to end it, or temporarily choose a different Access Port for Mac A’s -R tunnel. If you change it in either example above, also change Mac B’s Target Port to match, save both configurations, and retry. Do not terminate a process based only on its port number.
Reduce the chance of it happening again
To reduce Access Port conflicts caused by unresponsive old sessions, the server administrator can enable client liveness checks in the SSH server’s effective sshd_config or included configuration, for example:
ClientAliveInterval 15
ClientAliveCountMax 3
These must be active settings, without a leading #. With these values, an unresponsive client is typically detected after about 45 seconds; this is not a guarantee that a port will be released within 45 seconds of switching off a tunnel. Healthy idle connections that answer the checks remain connected. When the server ends an unresponsive session, it also releases the reverse forwarding port held by that session. These checks do not free ports used by other services or healthy active tunnels, or change server forwarding permissions. The app’s own heartbeat cannot replace the server’s checks.
Validate the server configuration with sudo sshd -t, then inspect the effective values with sudo sshd -T. If the server uses Match rules, the administrator should check the relevant connection using sshd -T -C with its actual connection parameters. Apply configuration changes using the server’s normal procedure; restarting the whole SSH service should not be the default troubleshooting step.
Changes normally apply to new connections, so existing stale sessions may still need separate attention. See the OpenSSH documentation for ClientAliveInterval and ClientAliveCountMax.
Will tunnels reconnect after I restart my Mac?
Yes, tunnels can restore automatically after you log in to macOS. Enable both of these:
- Open the settings menu (the gear button) and enable Launch at Login so the app starts when you log in.
- Leave each tunnel you want restored switched on so the app knows to reconnect it.
This does not establish tunnels before anyone logs in. After login, the app waits for an available network and retries temporary failures. A changed server fingerprint or a private key that needs unlocking can still require your attention. Closing the app’s window keeps it running; quitting the app disconnects its tunnels.
Can I move my tunnel configurations to another Mac?
Use Export… and Import… in the settings menu. The password-encrypted .pfhconfig file includes tunnel settings and private key contents. Keep it protected and remember its export password—the app does not save that password and cannot recover it.
Import adds new tunnels without overwriting existing ones. Imported tunnels start switched off, and server fingerprints must be confirmed again.
There may be two different passwords involved:
- Export password: Opens the
.pfhconfigfile during import. You choose it when exporting. - Private key passphrase: Unlocks an encrypted SSH private key when connecting. This is the original key’s passphrase; remembered passphrases are not included in the export.
Neither is the Windows or Screen Sharing login password.
Where can I find details to help troubleshoot a connection?
Click the log button in the title bar, just to the left of the settings gear. It shows up to 200 recent events recorded since you last opened the app. Search for your tunnel name or an error, then use Save to export the matching records as a text file. You can also clear the log.
Logs are not automatically uploaded. Quitting the app clears its in-app log; any text files you saved remain where you saved them. Saved logs may include host addresses, ports, tunnel names, and error details; review them before sharing because exports are not automatically redacted or encrypted.
Support
Still stuck? Share this page with your AI assistant, describe your setup, and provide the tunnel status and exact error message. Say which example you are following, which Mac runs each tunnel, and the values of -L / -R, Target Host, Target Port, and Access Port on each Mac. To protect your privacy, replace real server addresses and usernames with placeholders, using the same placeholder wherever the same value appears. Never share private keys or passwords, or upload a .pfhconfig export. Review logs and screenshots before sharing them.
For setup questions, bug reports, or feature ideas, email support@lonefondness.com. Do not include private keys, passphrases, or configuration export passwords. Review diagnostic logs before sharing them.