diff --git a/internal/configs/version2/nginx-plus.virtualserver.tmpl b/internal/configs/version2/nginx-plus.virtualserver.tmpl
index 5349454303..a6ddb6de98 100644
--- a/internal/configs/version2/nginx-plus.virtualserver.tmpl
+++ b/internal/configs/version2/nginx-plus.virtualserver.tmpl
@@ -481,14 +481,33 @@ server {
         proxy_set_header Connection $vs_connection_header;
         proxy_pass_request_headers {{ if $l.ProxyPassRequestHeaders }}on{{ else }}off{{ end }};
             {{ end }}
+
+        {{- $custom_headers := $l.ProxySetHeaders | headerListToCIMap }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Real-IP") }}
         {{ $proxyOrGRPC }}_set_header X-Real-IP $remote_addr;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-For") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-Host") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-Host $host;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-Port") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-Port $server_port;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-Proto") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-Proto {{ with $s.TLSRedirect }}{{ .BasedOn }}{{ else }}$scheme{{ end }};
-            {{ range $h := $l.ProxySetHeaders }}
+        {{- end }}
+
+        {{- range $h := $l.ProxySetHeaders }}
         {{ $proxyOrGRPC }}_set_header {{ $h.Name }} "{{ $h.Value }}";
-            {{ end }}
+        {{- end }}
+
             {{ range $h := $l.ProxyHideHeaders }}
         {{ $proxyOrGRPC }}_hide_header {{ $h }};
             {{ end }}
diff --git a/internal/configs/version2/nginx.virtualserver.tmpl b/internal/configs/version2/nginx.virtualserver.tmpl
index b5c9a8b1c5..09576e965b 100644
--- a/internal/configs/version2/nginx.virtualserver.tmpl
+++ b/internal/configs/version2/nginx.virtualserver.tmpl
@@ -318,14 +318,33 @@ server {
         proxy_set_header Connection $vs_connection_header;
         proxy_pass_request_headers {{ if $l.ProxyPassRequestHeaders }}on{{ else }}off{{ end }};
             {{ end }}
+
+        {{- $custom_headers := $l.ProxySetHeaders | headerListToCIMap }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Real-IP") }}
         {{ $proxyOrGRPC }}_set_header X-Real-IP $remote_addr;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-For") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-Host") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-Host $host;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-Port") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-Port $server_port;
+        {{- end }}
+
+        {{- if not ($custom_headers | hasCIKey "X-Forwarded-Proto") }}
         {{ $proxyOrGRPC }}_set_header X-Forwarded-Proto {{ with $s.TLSRedirect }}{{ .BasedOn }}{{ else }}$scheme{{ end }};
-            {{ range $h := $l.ProxySetHeaders }}
+        {{- end }}
+
+        {{- range $h := $l.ProxySetHeaders }}
         {{ $proxyOrGRPC }}_set_header {{ $h.Name }} "{{ $h.Value }}";
-            {{ end }}
+        {{- end }}
+
             {{ range $h := $l.ProxyHideHeaders }}
         {{ $proxyOrGRPC }}_hide_header {{ $h }};
             {{ end }}
diff --git a/internal/configs/version2/template_executor.go b/internal/configs/version2/template_executor.go
index ea5d0af13a..f395118e09 100644
--- a/internal/configs/version2/template_executor.go
+++ b/internal/configs/version2/template_executor.go
@@ -24,7 +24,7 @@ type TemplateExecutor struct {
 func NewTemplateExecutor(virtualServerTemplatePath string, transportServerTemplatePath string) (*TemplateExecutor, error) {
 	// template names  must be the base name of the template file https://golang.org/pkg/text/template/#Template.ParseFiles
 
-	vsTemplate, err := template.New(path.Base(virtualServerTemplatePath)).ParseFiles(virtualServerTemplatePath)
+	vsTemplate, err := template.New(path.Base(virtualServerTemplatePath)).Funcs(helperFunctions).ParseFiles(virtualServerTemplatePath)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/configs/version2/template_helper.go b/internal/configs/version2/template_helper.go
new file mode 100644
index 0000000000..35c31a4f71
--- /dev/null
+++ b/internal/configs/version2/template_helper.go
@@ -0,0 +1,26 @@
+package version2
+
+import (
+	"strings"
+	"text/template"
+)
+
+func headerListToCIMap(headers []Header) map[string]string {
+	ret := make(map[string]string)
+
+	for _, header := range headers {
+		ret[strings.ToLower(header.Name)] = header.Value
+	}
+
+	return ret
+}
+
+func hasCIKey(key string, d map[string]string) bool {
+	_, ok := d[strings.ToLower(key)]
+	return ok
+}
+
+var helperFunctions = template.FuncMap{
+	"headerListToCIMap": headerListToCIMap,
+	"hasCIKey":          hasCIKey,
+}