Add support for Proxy Protocol V1 and V2 in streamproxy configuration

- Updated HTML form to allow selection of Proxy Protocol version.
- Backend and config struct now use ProxyProtocolVersion (int) instead of UseProxyProtocol (bool).
- UI and API now pass and display Proxy Protocol version.

TODO: UDP should only allow Proxy Protocol V2
This commit is contained in:
jemmy1794
2025-10-14 21:30:32 +08:00
parent 66572981b3
commit 8d29a929f7
6 changed files with 82 additions and 77 deletions

View File

@@ -47,19 +47,19 @@ func (m *Manager) HandleAddProxyConfig(w http.ResponseWriter, r *http.Request) {
useTCP, _ := utils.PostBool(r, "useTCP")
useUDP, _ := utils.PostBool(r, "useUDP")
useProxyProtocol, _ := utils.PostBool(r, "useProxyProtocol")
ProxyProtocolVersion, _ := utils.PostInt(r, "proxyProtocolVersion")
enableLogging, _ := utils.PostBool(r, "enableLogging")
//Create the target config
newConfigUUID := m.NewConfig(&ProxyRelayOptions{
Name: name,
ListeningAddr: strings.TrimSpace(listenAddr),
ProxyAddr: strings.TrimSpace(proxyAddr),
Timeout: timeout,
UseTCP: useTCP,
UseUDP: useUDP,
UseProxyProtocol: useProxyProtocol,
EnableLogging: enableLogging,
Name: name,
ListeningAddr: strings.TrimSpace(listenAddr),
ProxyAddr: strings.TrimSpace(proxyAddr),
Timeout: timeout,
UseTCP: useTCP,
UseUDP: useUDP,
ProxyProtocolVersion: ProxyProtocolVersion,
EnableLogging: enableLogging,
})
js, _ := json.Marshal(newConfigUUID)
@@ -79,7 +79,7 @@ func (m *Manager) HandleEditProxyConfigs(w http.ResponseWriter, r *http.Request)
proxyAddr, _ := utils.PostPara(r, "proxyAddr")
useTCP, _ := utils.PostBool(r, "useTCP")
useUDP, _ := utils.PostBool(r, "useUDP")
useProxyProtocol, _ := utils.PostBool(r, "useProxyProtocol")
proxyProtocolVersion, _ := utils.PostInt(r, "proxyProtocolVersion")
enableLogging, _ := utils.PostBool(r, "enableLogging")
newTimeoutStr, _ := utils.PostPara(r, "timeout")
@@ -94,15 +94,15 @@ func (m *Manager) HandleEditProxyConfigs(w http.ResponseWriter, r *http.Request)
// Create a new ProxyRuleUpdateConfig with the extracted parameters
newConfig := &ProxyRuleUpdateConfig{
InstanceUUID: configUUID,
NewName: newName,
NewListeningAddr: listenAddr,
NewProxyAddr: proxyAddr,
UseTCP: useTCP,
UseUDP: useUDP,
UseProxyProtocol: useProxyProtocol,
EnableLogging: enableLogging,
NewTimeout: newTimeout,
InstanceUUID: configUUID,
NewName: newName,
NewListeningAddr: listenAddr,
NewProxyAddr: proxyAddr,
UseTCP: useTCP,
UseUDP: useUDP,
ProxyProtocolVersion: proxyProtocolVersion,
EnableLogging: enableLogging,
NewTimeout: newTimeout,
}
// Call the EditConfig method to modify the configuration

View File

@@ -23,42 +23,42 @@ import (
*/
type ProxyRelayOptions struct {
Name string
ListeningAddr string
ProxyAddr string
Timeout int
UseTCP bool
UseUDP bool
UseProxyProtocol bool
EnableLogging bool
Name string
ListeningAddr string
ProxyAddr string
Timeout int
UseTCP bool
UseUDP bool
ProxyProtocolVersion int
EnableLogging bool
}
// ProxyRuleUpdateConfig is used to update the proxy rule config
type ProxyRuleUpdateConfig struct {
InstanceUUID string //The target instance UUID to update
NewName string //New name for the instance, leave empty for no change
NewListeningAddr string //New listening address, leave empty for no change
NewProxyAddr string //New proxy target address, leave empty for no change
UseTCP bool //Enable TCP proxy, default to false
UseUDP bool //Enable UDP proxy, default to false
UseProxyProtocol bool //Enable Proxy Protocol, default to false
EnableLogging bool //Enable Logging TCP/UDP Message, default to true
NewTimeout int //New timeout for the connection, leave -1 for no change
InstanceUUID string //The target instance UUID to update
NewName string //New name for the instance, leave empty for no change
NewListeningAddr string //New listening address, leave empty for no change
NewProxyAddr string //New proxy target address, leave empty for no change
UseTCP bool //Enable TCP proxy, default to false
UseUDP bool //Enable UDP proxy, default to false
ProxyProtocolVersion int //Enable Proxy Protocol v1/v2, default to disabled
EnableLogging bool //Enable Logging TCP/UDP Message, default to true
NewTimeout int //New timeout for the connection, leave -1 for no change
}
type ProxyRelayInstance struct {
/* Runtime Config */
UUID string //A UUIDv4 representing this config
Name string //Name of the config
Running bool //Status, read only
AutoStart bool //If the service suppose to started automatically
ListeningAddress string //Listening Address, usually 127.0.0.1:port
ProxyTargetAddr string //Proxy target address
UseTCP bool //Enable TCP proxy
UseUDP bool //Enable UDP proxy
UseProxyProtocol bool //Enable Proxy Protocol
EnableLogging bool //Enable logging for ProxyInstance
Timeout int //Timeout for connection in sec
UUID string //A UUIDv4 representing this config
Name string //Name of the config
Running bool //Status, read only
AutoStart bool //If the service suppose to started automatically
ListeningAddress string //Listening Address, usually 127.0.0.1:port
ProxyTargetAddr string //Proxy target address
UseTCP bool //Enable TCP proxy
UseUDP bool //Enable UDP proxy
ProxyProtocolVersion int //Proxy Protocol v1/v2
EnableLogging bool //Enable logging for ProxyInstance
Timeout int //Timeout for connection in sec
/* Internal */
tcpStopChan chan bool //Stop channel for TCP listener
@@ -178,7 +178,7 @@ func (m *Manager) NewConfig(config *ProxyRelayOptions) string {
ProxyTargetAddr: config.ProxyAddr,
UseTCP: config.UseTCP,
UseUDP: config.UseUDP,
UseProxyProtocol: config.UseProxyProtocol,
ProxyProtocolVersion: config.ProxyProtocolVersion,
EnableLogging: config.EnableLogging,
Timeout: config.Timeout,
tcpStopChan: nil,
@@ -224,7 +224,7 @@ func (m *Manager) EditConfig(newConfig *ProxyRuleUpdateConfig) error {
foundConfig.UseTCP = newConfig.UseTCP
foundConfig.UseUDP = newConfig.UseUDP
foundConfig.UseProxyProtocol = newConfig.UseProxyProtocol
foundConfig.ProxyProtocolVersion = newConfig.ProxyProtocolVersion
foundConfig.EnableLogging = newConfig.EnableLogging
if newConfig.NewTimeout != -1 {

View File

@@ -11,6 +11,8 @@ import (
"sync"
"sync/atomic"
"time"
proxyproto "github.com/pires/go-proxyproto"
)
func isValidIP(ip string) bool {
@@ -44,20 +46,22 @@ func (c *ProxyRelayInstance) connCopy(conn1 net.Conn, conn2 net.Conn, wg *sync.W
wg.Done()
}
func writeProxyProtocolHeaderV1(dst net.Conn, src net.Conn) error {
func WriteProxyProtocolHeader(dst net.Conn, src net.Conn, version int) error {
clientAddr, ok1 := src.RemoteAddr().(*net.TCPAddr)
proxyAddr, ok2 := src.LocalAddr().(*net.TCPAddr)
if !ok1 || !ok2 {
return errors.New("invalid TCP address for proxy protocol")
}
header := fmt.Sprintf("PROXY TCP4 %s %s %d %d\r\n",
clientAddr.IP.String(),
proxyAddr.IP.String(),
clientAddr.Port,
proxyAddr.Port)
header := proxyproto.Header{
Version: byte(version),
Command: proxyproto.PROXY,
TransportProtocol: proxyproto.TCPv4,
SourceAddr: clientAddr,
DestinationAddr: proxyAddr,
}
_, err := dst.Write([]byte(header))
_, err := header.WriteTo(dst)
return err
}
@@ -161,9 +165,9 @@ func (c *ProxyRelayInstance) Port2host(allowPort string, targetAddress string, s
}
c.LogMsg("[→] connect target address ["+targetAddress+"] success.", nil)
if c.UseProxyProtocol {
if c.ProxyProtocolVersion != 0 {
c.LogMsg("[+] write proxy protocol header to target address ["+targetAddress+"]", nil)
err = writeProxyProtocolHeaderV1(target, conn)
err = WriteProxyProtocolHeader(target, conn, c.ProxyProtocolVersion)
if err != nil {
c.LogMsg("[x] Write proxy protocol header failed: "+err.Error(), nil)
target.Close()