Added custom type for Proxy Protocol Version

- Changed enum type for proxy protocol
- Added warning for proxy protocol 1 on UDP selection in UI
This commit is contained in:
Toby Chui
2025-10-15 07:40:48 +08:00
parent 0e78f3af65
commit 824972a1e2
5 changed files with 71 additions and 20 deletions

View File

@@ -58,7 +58,7 @@ func (m *Manager) HandleAddProxyConfig(w http.ResponseWriter, r *http.Request) {
Timeout: timeout, Timeout: timeout,
UseTCP: useTCP, UseTCP: useTCP,
UseUDP: useUDP, UseUDP: useUDP,
ProxyProtocolVersion: ProxyProtocolVersion, ProxyProtocolVersion: convertIntToProxyProtocolVersion(ProxyProtocolVersion),
EnableLogging: enableLogging, EnableLogging: enableLogging,
}) })

View File

@@ -15,13 +15,22 @@ import (
) )
/* /*
TCP Proxy Stream Proxy
Forward port from one port to another Forward port from one port to another
Also accept active connection and passive Also accept active connection and passive
connection connection
*/ */
// ProxyProtocolVersion enum type
type ProxyProtocolVersion int
const (
ProxyProtocolDisabled ProxyProtocolVersion = 0
ProxyProtocolV1 ProxyProtocolVersion = 1
ProxyProtocolV2 ProxyProtocolVersion = 2
)
type ProxyRelayOptions struct { type ProxyRelayOptions struct {
Name string Name string
ListeningAddr string ListeningAddr string
@@ -29,7 +38,7 @@ type ProxyRelayOptions struct {
Timeout int Timeout int
UseTCP bool UseTCP bool
UseUDP bool UseUDP bool
ProxyProtocolVersion int ProxyProtocolVersion ProxyProtocolVersion
EnableLogging bool EnableLogging bool
} }
@@ -56,7 +65,7 @@ type ProxyRelayInstance struct {
ProxyTargetAddr string //Proxy target address ProxyTargetAddr string //Proxy target address
UseTCP bool //Enable TCP proxy UseTCP bool //Enable TCP proxy
UseUDP bool //Enable UDP proxy UseUDP bool //Enable UDP proxy
ProxyProtocolVersion int //Proxy Protocol v1/v2 ProxyProtocolVersion ProxyProtocolVersion //Proxy Protocol v1/v2
EnableLogging bool //Enable logging for ProxyInstance EnableLogging bool //Enable logging for ProxyInstance
Timeout int //Timeout for connection in sec Timeout int //Timeout for connection in sec
@@ -203,6 +212,30 @@ func (m *Manager) GetConfigByUUID(configUUID string) (*ProxyRelayInstance, error
return nil, errors.New("config not found") return nil, errors.New("config not found")
} }
// ConvertIntToProxyProtocolVersion converts an int to ProxyProtocolVersion type
func convertIntToProxyProtocolVersion(v int) ProxyProtocolVersion {
switch v {
case 1:
return ProxyProtocolV1
case 2:
return ProxyProtocolV2
default:
return ProxyProtocolDisabled
}
}
// convertProxyProtocolVersionToInt converts ProxyProtocolVersion type back to int
func convertProxyProtocolVersionToInt(v ProxyProtocolVersion) int {
switch v {
case ProxyProtocolV1:
return 1
case ProxyProtocolV2:
return 2
default:
return 0
}
}
// Edit the config based on config UUID, leave empty for unchange fields // Edit the config based on config UUID, leave empty for unchange fields
func (m *Manager) EditConfig(newConfig *ProxyRuleUpdateConfig) error { func (m *Manager) EditConfig(newConfig *ProxyRuleUpdateConfig) error {
// Find the config with the specified UUID // Find the config with the specified UUID
@@ -224,7 +257,7 @@ func (m *Manager) EditConfig(newConfig *ProxyRuleUpdateConfig) error {
foundConfig.UseTCP = newConfig.UseTCP foundConfig.UseTCP = newConfig.UseTCP
foundConfig.UseUDP = newConfig.UseUDP foundConfig.UseUDP = newConfig.UseUDP
foundConfig.ProxyProtocolVersion = newConfig.ProxyProtocolVersion foundConfig.ProxyProtocolVersion = convertIntToProxyProtocolVersion(newConfig.ProxyProtocolVersion)
foundConfig.EnableLogging = newConfig.EnableLogging foundConfig.EnableLogging = newConfig.EnableLogging
if newConfig.NewTimeout != -1 { if newConfig.NewTimeout != -1 {

View File

@@ -46,7 +46,7 @@ func (c *ProxyRelayInstance) connCopy(conn1 net.Conn, conn2 net.Conn, wg *sync.W
wg.Done() wg.Done()
} }
func WriteProxyProtocolHeader(dst net.Conn, src net.Conn, version int) error { func WriteProxyProtocolHeader(dst net.Conn, src net.Conn, version ProxyProtocolVersion) error {
clientAddr, ok1 := src.RemoteAddr().(*net.TCPAddr) clientAddr, ok1 := src.RemoteAddr().(*net.TCPAddr)
proxyAddr, ok2 := src.LocalAddr().(*net.TCPAddr) proxyAddr, ok2 := src.LocalAddr().(*net.TCPAddr)
if !ok1 || !ok2 { if !ok1 || !ok2 {
@@ -54,7 +54,7 @@ func WriteProxyProtocolHeader(dst net.Conn, src net.Conn, version int) error {
} }
header := proxyproto.Header{ header := proxyproto.Header{
Version: byte(version), Version: byte(convertProxyProtocolVersionToInt(version)),
Command: proxyproto.PROXY, Command: proxyproto.PROXY,
TransportProtocol: proxyproto.TCPv4, TransportProtocol: proxyproto.TCPv4,
SourceAddr: clientAddr, SourceAddr: clientAddr,
@@ -165,7 +165,7 @@ func (c *ProxyRelayInstance) Port2host(allowPort string, targetAddress string, s
} }
c.LogMsg("[→] connect target address ["+targetAddress+"] success.", nil) c.LogMsg("[→] connect target address ["+targetAddress+"] success.", nil)
if c.ProxyProtocolVersion != 0 { if c.ProxyProtocolVersion != ProxyProtocolDisabled {
c.LogMsg("[+] write proxy protocol header to target address ["+targetAddress+"]", nil) c.LogMsg("[+] write proxy protocol header to target address ["+targetAddress+"]", nil)
err = WriteProxyProtocolHeader(target, conn, c.ProxyProtocolVersion) err = WriteProxyProtocolHeader(target, conn, c.ProxyProtocolVersion)
if err != nil { if err != nil {

View File

@@ -88,7 +88,7 @@ func (c *ProxyRelayInstance) CloseAllUDPConnections() {
// Write Proxy Protocol v2 header to UDP connection // Write Proxy Protocol v2 header to UDP connection
func WriteProxyProtocolHeaderUDP(conn *net.UDPConn, srcAddr, dstAddr *net.UDPAddr) error { func WriteProxyProtocolHeaderUDP(conn *net.UDPConn, srcAddr, dstAddr *net.UDPAddr) error {
header := proxyproto.Header{ header := proxyproto.Header{
Version: 2, Version: byte(ProxyProtocolV2),
Command: proxyproto.PROXY, Command: proxyproto.PROXY,
TransportProtocol: proxyproto.UDPv4, TransportProtocol: proxyproto.UDPv4,
SourceAddr: srcAddr, SourceAddr: srcAddr,
@@ -164,7 +164,7 @@ func (c *ProxyRelayInstance) ForwardUDP(address1, address2 string, stopChan chan
go c.RunUDPConnectionRelay(conn, lisener) go c.RunUDPConnectionRelay(conn, lisener)
// Send Proxy Protocol header if enabled // Send Proxy Protocol header if enabled
if c.ProxyProtocolVersion == 2 { if c.ProxyProtocolVersion == ProxyProtocolV2 {
_ = WriteProxyProtocolHeaderUDP(conn.ServerConn, cliaddr, targetAddr) _ = WriteProxyProtocolHeaderUDP(conn.ServerConn, cliaddr, targetAddr)
} }
} else { } else {

View File

@@ -90,6 +90,9 @@
<option value="2">Proxy Protocol V2</option> <option value="2">Proxy Protocol V2</option>
</select> </select>
<small>Select Proxy Protocol v1 / v2 to use (if any)</small> <small>Select Proxy Protocol v1 / v2 to use (if any)</small>
<div id="proxyProtocolUdpWarning" style="display:none; color:#bd7100; margin-top:0.5em;">
<i class="exclamation triangle icon"></i> Proxy Protocol V1 is not supported for UDP. The proxy protocol header will not be included in UDP packets if selected.
</div>
</div> </div>
<button id="addStreamProxyButton" class="ui basic button" type="submit"><i class="ui green add icon"></i> Create</button> <button id="addStreamProxyButton" class="ui basic button" type="submit"><i class="ui green add icon"></i> Create</button>
<button id="editStreamProxyButton" class="ui basic button" onclick="confirmEditTCPProxyConfig(event, this);" style="display:none;"><i class="ui green check icon"></i> Update</button> <button id="editStreamProxyButton" class="ui basic button" onclick="confirmEditTCPProxyConfig(event, this);" style="display:none;"><i class="ui green check icon"></i> Update</button>
@@ -100,6 +103,21 @@
<script> <script>
let editingStreamProxyConfigUUID = ""; //The current editing TCP Proxy config UUID let editingStreamProxyConfigUUID = ""; //The current editing TCP Proxy config UUID
// Show/hide warning for Proxy Protocol V1 + UDP
function updateProxyProtocolUdpWarning() {
const proxyProtocolVersion = $("#streamProxyForm select[name=proxyProtocolVersion]").val();
const useUDP = $("#streamProxyForm input[name=useUDP]")[0].checked;
if (proxyProtocolVersion === "1" && useUDP) {
$("#proxyProtocolUdpWarning").show();
} else {
$("#proxyProtocolUdpWarning").hide();
}
}
$("#streamProxyForm select[name=proxyProtocolVersion]").on("change", updateProxyProtocolUdpWarning);
$("#streamProxyForm input[name=useUDP]").on("change", updateProxyProtocolUdpWarning);
$(document).ready(updateProxyProtocolUdpWarning);
$("#streamProxyForm .dropdown").dropdown(); $("#streamProxyForm .dropdown").dropdown();
$('#streamProxyForm').on('submit', function(event) { $('#streamProxyForm').on('submit', function(event) {
event.preventDefault(); event.preventDefault();