Skip to content

Commit

Permalink
Add --use-remote-address flag to set X-Forwarded-For headers (#59)
Browse files Browse the repository at this point in the history
Signed-off-by: Laurent Marchaud <[email protected]>
  • Loading branch information
Aluxima authored Jan 18, 2022
1 parent 0b078cc commit 759282a
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,5 @@ The Yggdrasil-specific metrics which are available from the API are:
--upstream-healthcheck-timeout duration timeout of the upstream healthchecks (default 5s)
--upstream-healthcheck-unhealthy uint32 number of failed healthchecks before the backend is considered unhealthy (default 3)
--upstream-port uint32 port used to connect to the upstream ingresses (default 443)
--use-remote-address populates the X-Forwarded-For header with the client address. Set to true when used as edge proxy - [documentation](https://www.envoyproxy.io/docs/envoy/v1.19.0/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-use-remote-address) (default false)
```
4 changes: 4 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type config struct {
MaxEjectionPercentage uint32 `json:"maxEjectionPercentage"`
HostSelectionRetryAttempts int64 `json:"hostSelectionRetryAttempts"`
UpstreamHealthCheck envoy.UpstreamHealthCheck `json:"upstreamHealthCheck"`
UseRemoteAddress bool `json:"useRemoteAddress"`
}

// Hasher returns node ID as an ID
Expand Down Expand Up @@ -89,6 +90,7 @@ func init() {
rootCmd.PersistentFlags().Duration("upstream-healthcheck-timeout", 5*time.Second, "timeout of the upstream healthchecks")
rootCmd.PersistentFlags().Uint32("upstream-healthcheck-healthy", 3, "number of successful healthchecks before the backend is considered healthy")
rootCmd.PersistentFlags().Uint32("upstream-healthcheck-unhealthy", 3, "number of failed healthchecks before the backend is considered unhealthy")
rootCmd.PersistentFlags().Bool("use-remote-address", false, "populates the X-Forwarded-For header with the client address. Set to true when used as edge proxy")
viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug"))
viper.BindPFlag("address", rootCmd.PersistentFlags().Lookup("address"))
viper.BindPFlag("healthAddress", rootCmd.PersistentFlags().Lookup("health-address"))
Expand All @@ -106,6 +108,7 @@ func init() {
viper.BindPFlag("upstreamHealthCheck.timeout", rootCmd.PersistentFlags().Lookup("upstream-healthcheck-timeout"))
viper.BindPFlag("upstreamHealthCheck.healthyThreshold", rootCmd.PersistentFlags().Lookup("upstream-healthcheck-healthy"))
viper.BindPFlag("upstreamHealthCheck.unhealthyThreshold", rootCmd.PersistentFlags().Lookup("upstream-healthcheck-unhealthy"))
viper.BindPFlag("useRemoteAddress", rootCmd.PersistentFlags().Lookup("use-remote-address"))
}

func initConfig() {
Expand Down Expand Up @@ -194,6 +197,7 @@ func main(*cobra.Command, []string) error {
envoy.WithOutlierPercentage(viper.GetInt32("maxEjectionPercentage")),
envoy.WithHostSelectionRetryAttempts(viper.GetInt64("hostSelectionRetryAttempts")),
envoy.WithUpstreamHealthCheck(c.UpstreamHealthCheck),
envoy.WithUseRemoteAddress(c.UseRemoteAddress),
)
snapshotter := envoy.NewSnapshotter(envoyCache, configurator, lister)

Expand Down
8 changes: 5 additions & 3 deletions pkg/envoy/boilerplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/golang/protobuf/ptypes/duration"
"github.com/golang/protobuf/ptypes/wrappers"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/wrapperspb"
)

var (
Expand Down Expand Up @@ -108,7 +109,7 @@ func makeHealthConfig() *hcfg.HealthCheck {
}
}

func makeConnectionManager(virtualHosts []*route.VirtualHost) *hcm.HttpConnectionManager {
func (c *KubernetesConfigurator) makeConnectionManager(virtualHosts []*route.VirtualHost) *hcm.HttpConnectionManager {
accessLogConfig, err := util.MessageToStruct(
&eal.FileAccessLog{
Path: "/var/log/envoy/access.log",
Expand Down Expand Up @@ -166,11 +167,12 @@ func makeConnectionManager(virtualHosts []*route.VirtualHost) *hcm.HttpConnectio
ConfigType: &cal.AccessLog_TypedConfig{TypedConfig: anyAccessLogConfig},
},
},
UseRemoteAddress: &wrapperspb.BoolValue{Value: c.useRemoteAddress},
}
}

func makeFilterChain(certificate Certificate, virtualHosts []*route.VirtualHost) (listener.FilterChain, error) {
httpConnectionManager := makeConnectionManager(virtualHosts)
func (c *KubernetesConfigurator) makeFilterChain(certificate Certificate, virtualHosts []*route.VirtualHost) (listener.FilterChain, error) {
httpConnectionManager := c.makeConnectionManager(virtualHosts)
httpConfig, err := util.MessageToStruct(httpConnectionManager)
if err != nil {
return listener.FilterChain{}, fmt.Errorf("failed to convert virtualHost to envoy control plane struct: %s", err)
Expand Down
5 changes: 3 additions & 2 deletions pkg/envoy/configurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type KubernetesConfigurator struct {
outlierPercentage int32
hostSelectionRetryAttempts int64
upstreamHealthCheck UpstreamHealthCheck
useRemoteAddress bool

previousConfig *envoyConfiguration
listenerVersion string
Expand Down Expand Up @@ -145,7 +146,7 @@ func (c *KubernetesConfigurator) generateHTTPFilterChain(config *envoyConfigurat
virtualHosts = append(virtualHosts, makeVirtualHost(virtualHost, c.hostSelectionRetryAttempts))
}

httpConnectionManager := makeConnectionManager(virtualHosts)
httpConnectionManager := c.makeConnectionManager(virtualHosts)
httpConfig, err := util.MessageToStruct(httpConnectionManager)
if err != nil {
log.Fatalf("failed to convert virtualHost to envoy control plane struct: %s", err)
Expand Down Expand Up @@ -188,7 +189,7 @@ func (c *KubernetesConfigurator) generateTLSFilterChains(config *envoyConfigurat
continue
}

filterChain, err := makeFilterChain(certificate, virtualHosts)
filterChain, err := c.makeFilterChain(certificate, virtualHosts)
if err != nil {
log.Printf("Error making filter chain: %v", err)
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/envoy/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,10 @@ func WithUpstreamHealthCheck(config UpstreamHealthCheck) option {
c.upstreamHealthCheck = config
}
}

// WithUseRemoteAddress configures the useRemoteAddress option into the KubernetesConfigurator
func WithUseRemoteAddress(useRemoteAddress bool) option {
return func(c *KubernetesConfigurator) {
c.useRemoteAddress = useRemoteAddress
}
}
2 changes: 1 addition & 1 deletion pkg/k8s/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (i *IngressAggregator) Events() chan interface{} {
}

//Run starts all the ingress informers. Will block until all controllers
//have sycned. Shouldn't be called in go routine
//have synced. Shouldn't be called in go routine
func (i *IngressAggregator) Run(ctx context.Context) error {
for _, c := range i.controllers {
logrus.Debugf("starting cache controller: %+v", c)
Expand Down

0 comments on commit 759282a

Please sign in to comment.