Skip to content

Commit c1cf8ff

Browse files
authored
Merge pull request #675 from dpratt/master
Use proxy-protocol to pass through source IP to nginx
2 parents 317f222 + d56d8b7 commit c1cf8ff

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

controllers/nginx/pkg/cmd/controller/nginx.go

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func newNGINXController() ingress.Controller {
8888
Hostname: "localhost",
8989
IP: "127.0.0.1",
9090
Port: 442,
91+
ProxyProtocol: true,
9192
},
9293
},
9394
}
@@ -531,10 +532,12 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er
531532
}
532533
}
533534

535+
//TODO: Allow PassthroughBackends to specify they support proxy-protocol
534536
servers = append(servers, &server{
535537
Hostname: pb.Hostname,
536538
IP: svc.Spec.ClusterIP,
537539
Port: port,
540+
ProxyProtocol: false,
538541
})
539542
}
540543

controllers/nginx/pkg/cmd/controller/tcp.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type server struct {
1313
Hostname string
1414
IP string
1515
Port int
16+
ProxyProtocol bool
1617
}
1718

1819
type proxy struct {
@@ -61,10 +62,31 @@ func (p *proxy) Handle(conn net.Conn) {
6162
}
6263
defer clientConn.Close()
6364

64-
_, err = clientConn.Write(data[:length])
65+
if proxy.ProxyProtocol {
66+
//Write out the proxy-protocol header
67+
localAddr := conn.LocalAddr().(*net.TCPAddr)
68+
remoteAddr := conn.RemoteAddr().(*net.TCPAddr)
69+
protocol := "UNKNOWN"
70+
if remoteAddr.IP.To4() != nil {
71+
protocol = "TCP4"
72+
} else if remoteAddr.IP.To16() != nil {
73+
protocol = "TCP6"
74+
}
75+
proxyProtocolHeader := fmt.Sprintf("PROXY %s %s %s %d %d\r\n", protocol, remoteAddr.IP.String(), localAddr.IP.String(), remoteAddr.Port, localAddr.Port)
76+
glog.V(4).Infof("Writing proxy protocol header - %s", proxyProtocolHeader)
77+
_, err = fmt.Fprintf(clientConn, proxyProtocolHeader)
78+
}
6579
if err != nil {
80+
glog.Errorf("unexpected error writing proxy-protocol header: %s", err)
6681
clientConn.Close()
82+
} else {
83+
_, err = clientConn.Write(data[:length])
84+
if err != nil {
85+
glog.Errorf("unexpected error writing first 4k of proxy data: %s", err)
86+
clientConn.Close()
87+
}
6788
}
89+
6890
pipe(clientConn, conn)
6991
}
7092

controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl

+3-3
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,9 @@ http {
230230
{{ if $IsIPV6Enabled }}listen [::]:80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{ end }};{{ end }}
231231

232232
{{/* Listen on 442 because port 443 is used in the TLS sni server */}}
233-
{{/* This listen on port 442 cannot contains proxy_protocol directive because port 443 is in charge of decoding the protocol */}}
234-
{{ if not (empty $server.SSLCertificate) }}listen 442{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }};
235-
{{ if $IsIPV6Enabled }}{{ if not (empty $server.SSLCertificate) }}listen [::]:442{{ end }} {{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }};{{ end }}
233+
{{/* This listener must always have proxy_protocol enabled, because the SNI listener forwards on source IP info in it. */}}
234+
{{ if not (empty $server.SSLCertificate) }}listen 442 proxy_protocol{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }};
235+
{{ if $IsIPV6Enabled }}{{ if not (empty $server.SSLCertificate) }}listen [::]:442 proxy_protocol{{ end }} {{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }};{{ end }}
236236
{{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}}
237237
# PEM sha: {{ $server.SSLPemChecksum }}
238238
ssl_certificate {{ $server.SSLCertificate }};

0 commit comments

Comments
 (0)