Skip to content

TCP/UDP Stream Proxying

Protocol mappings add TCP or UDP listening ports for non-HTTP services such as SSH, databases, and DNS. They do not inspect a domain Host or URL path; each rule forwards the byte stream on one external port to a host:port.

This feature is available only as an addition to direct public Subdomain mode. Continue to use Subdomain Routing for web services, or see Path-based Reverse Proxy (Compatibility Mode) for legacy path rules.

Requirements

Protocol mappings appears in the sidebar only when both conditions are met:

  1. System settings → Mode is set to Subdomain mode.
  2. System settings → Features → Protocol mapping is enabled.

Turning off the feature switch stops the Protocol mapping listeners and hides the menu, but preserves the saved rules. Enabling it again restores the previous configuration. Leaving Subdomain mode also disables the feature and stops its listeners while preserving the rules.

Although Reverse proxy mode → Subdomain mapping also uses Host-based routing, it does not provide Protocol mappings. To carry another protocol through FRP or Cloudflare, configure it separately on that platform; you cannot reuse fn-knock's HTTP Host entry point.

Routing Model

text
TCP :2222 -> 192.168.1.20:22
TCP :3306 -> 127.0.0.1:3306
UDP :53   -> 127.0.0.1:53

A domain only resolves to the entry-point address and does not participate in protocol dispatch. A client can connect to nas.example.com:2222, but the selected rule depends only on the transport protocol and port.

Rule Fields

FieldDescription
Transport protocolTCP, UDP, or both; selecting both creates two rules when saved
External portThe port used by the client, from 1-65535
CommentOptional context for distinguishing and searching similar mappings
Target addressPlain host:port, without http:// or a path
Require authChecks fn-knock source-IP authorization before accepting the connection

The same port can have separate TCP and UDP rules, such as 53/tcp and 53/udp. A protocol-and-port pair cannot be duplicated.

The Target must be reachable from the fn-knock runtime environment. In Docker, 127.0.0.1 refers to the container itself; use an address reachable from the container for a host or LAN target.

The list search matches protocol, External port, Comment, Target address, and authentication state. You can edit a Comment directly in the list; use the mapping editor for protocol, port, Target, or authentication changes.

Authentication Checks Source IP and Credential Scope

Clients such as SSH, MySQL, and Redis do not open an fn-knock sign-in page. With Require auth enabled, use this flow:

  1. Open the fn-knock web entry point in a browser and sign in.
  2. If System settings → Sessions → Post-login IP authorization is not disabled, sign-in creates protocol access for the current public egress IP; otherwise, add the IP/CIDR manually.
  3. Connect to the external port from a protocol client using that same egress IP.

With All scopes, protocol access applies to every protocol mapping that requires authentication. With Custom scopes, select the exact TCP/UDP + external port under Auth → Permission. The system authorizes the current source IP only for the selected mapping; an unselected protocol or port is still denied. Changing the credential scope also reconciles protocol access for existing sessions.

If the egress IP changes, authorization expires, post-login IP authorization is disabled, or the protocol client uses another network, the connection is rejected immediately. Sign in again or update the manual authorization. A browser Cookie is not sent with a TCP or UDP connection; the protocol entry point checks source IP, protocol, and external port. Manual IP/CIDR authorization remains an independent allow path. See Sessions, Source-IP Authorization, and IP Changes for sessions and IP changes, and Authentication, Sessions, and Service Scopes for custom scopes.

Protocol clients have no browser Cookie, so the gateway associates the source IP confirmed by the current session with the protocol grant. While the session remains valid, its current source IP stays eligible for the full lifetime of that protocol grant. Additional IPs observed through mobile-network drift are valid only within the configured mobility window. Once the session or protocol grant expires, connections are denied; an IP is not retained permanently merely because it was used for an earlier sign-in.

Disabling Require auth makes the listening port a public forward. You must still configure the target service's own SSH keys, database password, TLS, and least-privilege access.

local_exempt

The authentication service classifies loopback, private, and link-local sources identified by the gateway as local_exempt. Connections from these sources to an authenticated Protocol mapping are treated as local-network access and do not require a prior web sign-in.

Therefore:

  • A successful LAN connection does not prove that public authentication works.
  • If another NAT or proxy sits in front of the port, confirm that the gateway does not see the proxy's private address.
  • Test from a genuine external network and compare its source IP with the session record.

Save, Synchronize, and Open the Firewall

Create, edit, delete, and Comment updates are saved in sequence so consecutive actions do not overwrite each other. Rule changes that affect listeners refresh the gateway and open the port on supported deployments. Comments are used only for management and search and do not affect forwarding. Sync gateway explicitly replays the complete configuration; you normally do not need to select it after every edit.

Platform boundaries:

  • The native fnOS FPK and an OpenWrt runtime with root-level host capability can synchronize protocol ports when automatic firewall management is enabled.
  • Docker neither publishes a new host port nor modifies the host firewall. Explicitly publish fixed ports in the container startup configuration and manage host and router rules manually. Adding a port only in the admin console cannot expose it publicly from an already-running Compose deployment.
  • If you manage the gateway runtime yourself, opening ports remains the system administrator's responsibility. Do not assume that fn-knock modifies the host firewall.

Regardless of automatic firewall support, the router's port forwarding, cloud security group, and upstream network policy must also allow the port.

Verification and Troubleshooting

  1. Confirm that the current mode is Subdomain mode with direct public ingress and that the feature switch remains enabled.
  2. Check that the protocol and External port match the client.
  3. Connect to the Target directly from the fn-knock runtime environment.
  4. Check container port publishing, the host firewall, router forwarding, and cloud security group.
  5. With authentication enabled, confirm that the browser sign-in and protocol client use the same public egress IP, post-login IP authorization is enabled, and a custom credential includes the current protocol and external port.
  6. If the listener is still absent after saving, select Sync gateway, then review status and logs.

See System Settings and Maintenance for the related feature switch.

Community QQ group: 1081609274