mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-06-18 10:06:26 +00:00
Add support for PROXY protocol on streams
This commit is contained in:
41
backend/migrations/20240310100432_proxy_protocol_streams.js
Normal file
41
backend/migrations/20240310100432_proxy_protocol_streams.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
const migrate_name = 'proxy_protocol_streams';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('stream', function (stream) {
|
||||||
|
stream.integer('enable_proxy_protocol').notNull().unsigned().defaultTo(0);
|
||||||
|
stream.string('load_balancer_ip').notNull().defaultTo('');
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] stream Table altered');
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex/*, Promise*/) {
|
||||||
|
return knex.schema.table('stream', function (stream) {
|
||||||
|
stream.dropColumn('enable_proxy_protocol');
|
||||||
|
stream.dropColumn('load_balancer_ip');
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
logger.info('[' + migrate_name + '] stream Table altered');
|
||||||
|
});
|
||||||
|
};
|
@ -46,6 +46,16 @@
|
|||||||
"udp_forwarding": {
|
"udp_forwarding": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"enable_proxy_protocol": {
|
||||||
|
"description": "Enable PROXY Protocol support",
|
||||||
|
"example": true,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"load_balancer_ip": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 0,
|
||||||
|
"maxLength": 255
|
||||||
|
},
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"$ref": "../definitions.json#/definitions/enabled"
|
"$ref": "../definitions.json#/definitions/enabled"
|
||||||
},
|
},
|
||||||
@ -78,6 +88,12 @@
|
|||||||
"udp_forwarding": {
|
"udp_forwarding": {
|
||||||
"$ref": "#/definitions/udp_forwarding"
|
"$ref": "#/definitions/udp_forwarding"
|
||||||
},
|
},
|
||||||
|
"enable_proxy_protocol": {
|
||||||
|
"$ref": "#/definitions/enable_proxy_protocol"
|
||||||
|
},
|
||||||
|
"load_balancer_ip": {
|
||||||
|
"$ref": "#/definitions/load_balancer_ip"
|
||||||
|
},
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"$ref": "#/definitions/enabled"
|
"$ref": "#/definitions/enabled"
|
||||||
},
|
},
|
||||||
@ -137,6 +153,12 @@
|
|||||||
"udp_forwarding": {
|
"udp_forwarding": {
|
||||||
"$ref": "#/definitions/udp_forwarding"
|
"$ref": "#/definitions/udp_forwarding"
|
||||||
},
|
},
|
||||||
|
"enable_proxy_protocol": {
|
||||||
|
"$ref": "#/definitions/enable_proxy_protocol"
|
||||||
|
},
|
||||||
|
"load_balancer_ip": {
|
||||||
|
"$ref": "#/definitions/load_balancer_ip"
|
||||||
|
},
|
||||||
"meta": {
|
"meta": {
|
||||||
"$ref": "#/definitions/meta"
|
"$ref": "#/definitions/meta"
|
||||||
}
|
}
|
||||||
@ -177,6 +199,12 @@
|
|||||||
"udp_forwarding": {
|
"udp_forwarding": {
|
||||||
"$ref": "#/definitions/udp_forwarding"
|
"$ref": "#/definitions/udp_forwarding"
|
||||||
},
|
},
|
||||||
|
"enable_proxy_protocol": {
|
||||||
|
"$ref": "#/definitions/enable_proxy_protocol"
|
||||||
|
},
|
||||||
|
"load_balancer_ip": {
|
||||||
|
"$ref": "#/definitions/load_balancer_ip"
|
||||||
|
},
|
||||||
"meta": {
|
"meta": {
|
||||||
"$ref": "#/definitions/meta"
|
"$ref": "#/definitions/meta"
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,38 @@
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# {{ incoming_port }} TCP: {{ tcp_forwarding }} UDP: {{ udp_forwarding }}
|
# {{ incoming_port }} TCP: {{ tcp_forwarding }} UDP: {{ udp_forwarding }}
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
{% if enable_proxy_protocol == 1 or enable_proxy_protocol == true -%}
|
||||||
|
{% capture listen_extra_args %}proxy_protocol{% endcapture -%}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
{% if enabled %}
|
{% if enabled %}
|
||||||
{% if tcp_forwarding == 1 or tcp_forwarding == true -%}
|
{% if tcp_forwarding == 1 or tcp_forwarding == true -%}
|
||||||
server {
|
server {
|
||||||
listen {{ incoming_port }};
|
listen {{ incoming_port }} {{ listen_extra_args }};
|
||||||
{% if ipv6 -%}
|
{% if ipv6 -%}
|
||||||
listen [::]:{{ incoming_port }};
|
listen [::]:{{ incoming_port }} {{ listen_extra_args }};
|
||||||
{% else -%}
|
{% else -%}
|
||||||
#listen [::]:{{ incoming_port }};
|
#listen [::]:{{ incoming_port }} {{ listen_extra_args }};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
|
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
|
||||||
|
|
||||||
|
{% include '_proxy_protocol.conf' %}
|
||||||
|
|
||||||
# Custom
|
# Custom
|
||||||
include /data/nginx/custom/server_stream[.]conf;
|
include /data/nginx/custom/server_stream[.]conf;
|
||||||
include /data/nginx/custom/server_stream_tcp[.]conf;
|
include /data/nginx/custom/server_stream_tcp[.]conf;
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if udp_forwarding == 1 or udp_forwarding == true %}
|
{% if udp_forwarding == 1 or udp_forwarding == true %}
|
||||||
|
{% # Proxy Protocol is not supported for UDP %}
|
||||||
|
{% assign listen_extra_args = "" %}
|
||||||
server {
|
server {
|
||||||
listen {{ incoming_port }} udp;
|
listen {{ incoming_port }} udp {{ listen_extra_args }};
|
||||||
{% if ipv6 -%}
|
{% if ipv6 -%}
|
||||||
listen [::]:{{ incoming_port }} udp;
|
listen [::]:{{ incoming_port }} udp {{ listen_extra_args }};
|
||||||
{% else -%}
|
{% else -%}
|
||||||
#listen [::]:{{ incoming_port }} udp;
|
#listen [::]:{{ incoming_port }} udp {{ listen_extra_args }};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
|
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
|
||||||
|
|
||||||
|
@ -209,14 +209,26 @@ You can customise the logrotate configuration through a mount (if your custom co
|
|||||||
|
|
||||||
For reference, the default configuration can be found [here](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/rootfs/etc/logrotate.d/nginx-proxy-manager).
|
For reference, the default configuration can be found [here](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/rootfs/etc/logrotate.d/nginx-proxy-manager).
|
||||||
|
|
||||||
## Enabling Proxy Protocol for Proxy Hosts
|
## Enabling PROXY protocol for Proxy Hosts
|
||||||
|
|
||||||
When running NPM behind a load balancer, you might want to use the [PROXY procotol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) to receive client information such as the source IP address (useful for banning IPs).
|
When running NPM behind a load balancer, you might want to use the [PROXY procotol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) to receive client information such as the source IP address (useful for banning IPs).
|
||||||
|
|
||||||
When configuring the PROXY protocol for proxy hosts, NPM uses the ports 88 for http and 444 for https traffic to allow you to decide on a per host basis whether to use the PROSY protocol.
|
When configuring the PROXY protocol for proxy hosts, NPM uses the ports 88 for http and 444 for https traffic to allow you to decide on a per host basis whether to use the PROSY protocol.
|
||||||
|
|
||||||
To enable the Proxy Protocol for your hosts you need to perform the following steps:
|
To enable the PROXY protocol for your hosts you need to perform the following steps:
|
||||||
|
|
||||||
1. Expose the ports `88` (and `444` is applicable) by adjusting your `docker-compose.yml`
|
1. Expose the ports `88` (and `444` is applicable) by adjusting your `docker-compose.yml`
|
||||||
2. Edit your proxy hosts to enable the PROXY protocol
|
2. Edit your proxy hosts to enable the PROXY protocol
|
||||||
3. Edit your upstream load balancer to redirect traffic to the port `88`/`444` and enable the PROXY protocol
|
3. Edit your upstream load balancer to redirect traffic to the port `88`/`444` and enable the PROXY protocol
|
||||||
|
|
||||||
|
## Enabling PROXY protocol for Streams
|
||||||
|
|
||||||
|
When running NPM behind a load balancer, you might want to use the [PROXY procotol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) to receive client information such as the source IP address (useful for banning IPs).
|
||||||
|
|
||||||
|
Keep in mind that the PROXY procotol cannot be enabled for udp endpoints.
|
||||||
|
|
||||||
|
To enable the PROXY protocol for streams:
|
||||||
|
|
||||||
|
1. Expose the desired port by adjusting you `docker-compose.yml`
|
||||||
|
2. Edit the Stream to enable the PROXY protocol
|
||||||
|
3. Edit your upstream load balancer to enable the PROXY protocol
|
||||||
|
@ -42,6 +42,22 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="custom-switch">
|
||||||
|
<input type="checkbox" class="custom-switch-input" name="enable_proxy_protocol" value="1"<%- enable_proxy_protocol ? ' checked' : '' %>>
|
||||||
|
<span class="custom-switch-indicator"></span>
|
||||||
|
<span class="custom-switch-description"><%- i18n('streams', 'enable-proxy-protocol') %><a href="https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/#introduction" target="_blank"><i class="fe fe-help-circle"></i></a></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('streams', 'load-balancer-ip') %><a href="https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/#changing-the-load-balancers-ip-address-to-the-client-ip-address" target="_blank"><i class="fe fe-help-circle"></i></a></label>
|
||||||
|
<input type="text" name="load_balancer_ip" class="form-control text-monospace" placeholder="" value="<%- load_balancer_ip %>" autocomplete="off" maxlength="255" <%- enable_proxy_protocol ? '' : ' disabled' %>>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-12 col-md-12">
|
||||||
<div class="forward-type-error invalid-feedback"><%- i18n('streams', 'forward-type-error') %></div>
|
<div class="forward-type-error invalid-feedback"><%- i18n('streams', 'forward-type-error') %></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,6 +14,8 @@ module.exports = Mn.View.extend({
|
|||||||
ui: {
|
ui: {
|
||||||
form: 'form',
|
form: 'form',
|
||||||
forwarding_host: 'input[name="forwarding_host"]',
|
forwarding_host: 'input[name="forwarding_host"]',
|
||||||
|
enable_proxy_protocol: 'input[name="enable_proxy_protocol"]',
|
||||||
|
load_balancer_ip: 'input[name="load_balancer_ip"]',
|
||||||
type_error: '.forward-type-error',
|
type_error: '.forward-type-error',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
switches: '.custom-switch-input',
|
switches: '.custom-switch-input',
|
||||||
@ -22,6 +24,13 @@ module.exports = Mn.View.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
|
'change @ui.enable_proxy_protocol': function () {
|
||||||
|
let checked = this.ui.enable_proxy_protocol.prop('checked');
|
||||||
|
this.ui.load_balancer_ip
|
||||||
|
.prop('disabled', !checked)
|
||||||
|
.parents('.form-group')
|
||||||
|
.css('opacity', checked ? 1 : 0.5);
|
||||||
|
},
|
||||||
'change @ui.switches': function () {
|
'change @ui.switches': function () {
|
||||||
this.ui.type_error.hide();
|
this.ui.type_error.hide();
|
||||||
},
|
},
|
||||||
@ -47,6 +56,7 @@ module.exports = Mn.View.extend({
|
|||||||
data.forwarding_port = parseInt(data.forwarding_port, 10);
|
data.forwarding_port = parseInt(data.forwarding_port, 10);
|
||||||
data.tcp_forwarding = !!data.tcp_forwarding;
|
data.tcp_forwarding = !!data.tcp_forwarding;
|
||||||
data.udp_forwarding = !!data.udp_forwarding;
|
data.udp_forwarding = !!data.udp_forwarding;
|
||||||
|
data.enable_proxy_protocol = !!data.enable_proxy_protocol;
|
||||||
|
|
||||||
let method = App.Api.Nginx.Streams.create;
|
let method = App.Api.Nginx.Streams.create;
|
||||||
let is_new = true;
|
let is_new = true;
|
||||||
@ -76,6 +86,10 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onRender: function () {
|
||||||
|
this.ui.enable_proxy_protocol.trigger('change');
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function (options) {
|
initialize: function (options) {
|
||||||
if (typeof options.model === 'undefined' || !options.model) {
|
if (typeof options.model === 'undefined' || !options.model) {
|
||||||
this.model = new StreamModel.Model();
|
this.model = new StreamModel.Model();
|
||||||
|
@ -177,6 +177,8 @@
|
|||||||
"protocol": "Protocol",
|
"protocol": "Protocol",
|
||||||
"tcp": "TCP",
|
"tcp": "TCP",
|
||||||
"udp": "UDP",
|
"udp": "UDP",
|
||||||
|
"enable-proxy-protocol": "Enable Proxy Protocol",
|
||||||
|
"load-balancer-ip": "Load balancer or TCP proxy IP / CIDR range",
|
||||||
"delete": "Delete Stream",
|
"delete": "Delete Stream",
|
||||||
"delete-confirm": "Are you sure you want to delete this Stream?",
|
"delete-confirm": "Are you sure you want to delete this Stream?",
|
||||||
"help-title": "What is a Stream?",
|
"help-title": "What is a Stream?",
|
||||||
|
@ -5,18 +5,20 @@ const model = Backbone.Model.extend({
|
|||||||
|
|
||||||
defaults: function () {
|
defaults: function () {
|
||||||
return {
|
return {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
created_on: null,
|
created_on: null,
|
||||||
modified_on: null,
|
modified_on: null,
|
||||||
incoming_port: null,
|
incoming_port: null,
|
||||||
forwarding_host: null,
|
forwarding_host: null,
|
||||||
forwarding_port: null,
|
forwarding_port: null,
|
||||||
tcp_forwarding: true,
|
tcp_forwarding: true,
|
||||||
udp_forwarding: false,
|
udp_forwarding: false,
|
||||||
enabled: true,
|
enable_proxy_protocol: false,
|
||||||
meta: {},
|
load_balancer_ip: "",
|
||||||
|
enabled: true,
|
||||||
|
meta: {},
|
||||||
// The following are expansions:
|
// The following are expansions:
|
||||||
owner: null
|
owner: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user