Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SSL-Passthrough functionality #3226

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/ingress/controller/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ func (n *NGINXController) setupSSLProxy() {
}

glog.V(3).Infof("Handling connection from remote address %s to local %s", conn.RemoteAddr(), conn.LocalAddr())
go n.Proxy.Handle(conn)
go n.Proxy.Handle(conn, n.runningConfig)
}
}()
}
Expand Down
36 changes: 34 additions & 2 deletions internal/ingress/controller/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/golang/glog"

"github.com/paultag/sniff/parser"
"k8s.io/ingress-nginx/internal/ingress"
)

// TCPServer describes a server that works in passthrough mode.
Expand Down Expand Up @@ -57,9 +58,10 @@ func (p *TCPProxy) Get(host string) *TCPServer {

// Handle reads enough information from the connection to extract the hostname
// and open a connection to the passthrough server.
func (p *TCPProxy) Handle(conn net.Conn) {
func (p *TCPProxy) Handle(conn net.Conn, config *ingress.Configuration) {
defer conn.Close()
data := make([]byte, 4096)
remoteAddr := conn.RemoteAddr().(*net.TCPAddr)

length, err := conn.Read(data)
if err != nil {
Expand All @@ -79,6 +81,36 @@ func (p *TCPProxy) Handle(conn net.Conn) {
return
}

for _, server := range config.Servers {
if server.Hostname != hostname {
continue
}

if !server.SSLPassthrough {
continue
}

check := false
for _, location := range server.Locations {
for _, CIDR := range location.Whitelist.CIDR {
_, network, err := net.ParseCIDR(CIDR)
if err != nil {
glog.Fatalf("%v", err)
}

if network.Contains(net.ParseIP(remoteAddr.IP.String())) {
check = true
break
}
}
}
if !check {
glog.V(4).Infof("Whitelisting is not allowing this connection.")
return
}
break
}

clientConn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", proxy.IP, proxy.Port))
if err != nil {
return
Expand All @@ -88,7 +120,7 @@ func (p *TCPProxy) Handle(conn net.Conn) {
if proxy.ProxyProtocol {
// write out the Proxy Protocol header
localAddr := conn.LocalAddr().(*net.TCPAddr)
remoteAddr := conn.RemoteAddr().(*net.TCPAddr)

protocol := "UNKNOWN"
if remoteAddr.IP.To4() != nil {
protocol = "TCP4"
Expand Down
5 changes: 4 additions & 1 deletion rootfs/etc/nginx/template/nginx.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,13 @@ http {

# The following is a sneaky way to do "set $the_real_ip $remote_addr"
# Needed because using set is not allowed outside server blocks.
map '' $the_real_ip {
map $scheme $the_real_ip {
{{ if $cfg.UseProxyProtocol }}
# Get IP address from Proxy Protocol
default $proxy_protocol_addr;
{{ else if $all.IsSSLPassthroughEnabled }}
https $proxy_protocol_addr;
default $remote_addr;
{{ else }}
default $remote_addr;
{{ end }}
Expand Down