3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-10 22:19:31 +01:00

restore PROXY protocol support

support for PROXY was removed in 43e28e2fef. After discussion,
it's worth keeping around in case of client compatibility issues,
and until /rehash support is more mature.
This commit is contained in:
Shivaram Lingamneni 2017-09-11 01:04:08 -04:00 committed by Daniel Oaks
parent 8cd016e4c0
commit 99f02ede20
6 changed files with 46 additions and 1 deletions

View File

@ -66,6 +66,7 @@ type Client struct {
nickMaskCasefolded string nickMaskCasefolded string
nickMaskString string // cache for nickmask string since it's used with lots of replies nickMaskString string // cache for nickmask string since it's used with lots of replies
operName string operName string
proxiedIP string // actual remote IP if using the PROXY protocol
quitMessageSent bool quitMessageSent bool
quitMutex sync.Mutex quitMutex sync.Mutex
quitTimer *time.Timer quitTimer *time.Timer
@ -147,11 +148,19 @@ func NewClient(server *Server, conn net.Conn, isTLS bool) *Client {
// IP returns the IP address of this client. // IP returns the IP address of this client.
func (client *Client) IP() net.IP { func (client *Client) IP() net.IP {
if client.proxiedIP != "" {
return net.ParseIP(client.proxiedIP)
}
return net.ParseIP(IPString(client.socket.conn.RemoteAddr())) return net.ParseIP(IPString(client.socket.conn.RemoteAddr()))
} }
// IPString returns the IP address of this client as a string. // IPString returns the IP address of this client as a string.
func (client *Client) IPString() string { func (client *Client) IPString() string {
if client.proxiedIP != "" {
return client.proxiedIP
}
ip := client.IP().String() ip := client.IP().String()
if 0 < len(ip) && ip[0] == ':' { if 0 < len(ip) && ip[0] == ':' {
ip = "0" + ip ip = "0" + ip
@ -185,6 +194,7 @@ func (client *Client) run() {
var msg ircmsg.IrcMessage var msg ircmsg.IrcMessage
// Set the hostname for this client // Set the hostname for this client
// (may be overridden by a later PROXY command from stunnel)
client.rawHostname = AddrLookupHostname(client.socket.conn.RemoteAddr()) client.rawHostname = AddrLookupHostname(client.socket.conn.RemoteAddr())
for { for {

View File

@ -207,6 +207,11 @@ var Commands = map[string]Command{
handler: privmsgHandler, handler: privmsgHandler,
minParams: 2, minParams: 2,
}, },
"PROXY": {
handler: proxyHandler,
usablePreReg: true,
minParams: 5,
},
"RENAME": { "RENAME": {
handler: renameHandler, handler: renameHandler,
minParams: 2, minParams: 2,

View File

@ -202,7 +202,8 @@ type Config struct {
RestAPI RestAPIConfig `yaml:"rest-api"` RestAPI RestAPIConfig `yaml:"rest-api"`
CheckIdent bool `yaml:"check-ident"` CheckIdent bool `yaml:"check-ident"`
MOTD string MOTD string
MaxSendQString string `yaml:"max-sendq"` ProxyAllowedFrom []string `yaml:"proxy-allowed-from"`
MaxSendQString string `yaml:"max-sendq"`
MaxSendQBytes uint64 MaxSendQBytes uint64
ConnectionLimits ConnectionLimitsConfig `yaml:"connection-limits"` ConnectionLimits ConnectionLimitsConfig `yaml:"connection-limits"`
ConnectionThrottle ConnectionThrottleConfig `yaml:"connection-throttling"` ConnectionThrottle ConnectionThrottleConfig `yaml:"connection-throttling"`

View File

@ -356,6 +356,13 @@ Replies to a PING. Used to check link connectivity.`,
text: `PRIVMSG <target>{,<target>} <text to be sent> text: `PRIVMSG <target>{,<target>} <text to be sent>
Sends the text to the given targets as a PRIVMSG.`, Sends the text to the given targets as a PRIVMSG.`,
},
"proxy": {
oper: true, // not really, but it's restricted anyways
text: `PROXY TCP4/6 <sourceip> <destip> <sourceport> <destport>
Used by haproxy's PROXY protocol, to allow for alternate TLS support:
http://www.haproxy.org/download/1.7/doc/proxy-protocol.txt`,
}, },
"rename": { "rename": {
text: `RENAME <channel> <newname> [<reason>] text: `RENAME <channel> <newname> [<reason>]

View File

@ -109,6 +109,7 @@ type Server struct {
rehashMutex sync.Mutex rehashMutex sync.Mutex
rehashSignal chan os.Signal rehashSignal chan os.Signal
restAPI *RestAPIConfig restAPI *RestAPIConfig
proxyAllowedFrom []string
signals chan os.Signal signals chan os.Signal
snomasks *SnoManager snomasks *SnoManager
store *buntdb.DB store *buntdb.DB
@ -217,6 +218,7 @@ func NewServer(configFilename string, config *Config, logger *logger.Manager) (*
newConns: make(chan clientConn), newConns: make(chan clientConn),
operators: opers, operators: opers,
operclasses: *operClasses, operclasses: *operClasses,
proxyAllowedFrom: config.Server.ProxyAllowedFrom,
registeredChannels: make(map[string]*RegisteredChannel), registeredChannels: make(map[string]*RegisteredChannel),
rehashSignal: make(chan os.Signal, 1), rehashSignal: make(chan os.Signal, 1),
restAPI: &config.Server.RestAPI, restAPI: &config.Server.RestAPI,
@ -2224,3 +2226,19 @@ func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool
return false return false
} }
// PROXY TCP4/6 SOURCEIP DESTIP SOURCEPORT DESTPORT
// http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
func proxyHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
clientAddress := IPString(client.socket.conn.RemoteAddr())
clientHostname := client.hostname
for _, address := range server.proxyAllowedFrom {
if clientHostname == address || clientAddress == address {
client.proxiedIP = msg.Params[1]
client.hostname = LookupHostname(msg.Params[1])
return false
}
}
client.Quit("PROXY command is not usable from your address")
return true
}

View File

@ -65,6 +65,10 @@ server:
# if you change the motd, you should move it to ircd.motd # if you change the motd, you should move it to ircd.motd
motd: oragono.motd motd: oragono.motd
# addresses/hostnames the PROXY command can be used from
# this should be restricted to 127.0.0.1 and localhost at most
proxy-allowed-from: []
# maximum length of clients' sendQ in bytes # maximum length of clients' sendQ in bytes
# this should be big enough to hold /LIST and HELP replies # this should be big enough to hold /LIST and HELP replies
max-sendq: 16k max-sendq: 16k