Compare commits

..

35 Commits

Author SHA1 Message Date
671817d640 Add docs on how to test the code 2024-03-10 11:39:13 +01:00
c39e580e81 Fix cypress integration tests 2024-03-10 11:20:57 +01:00
da29cd2e0e Add support for PROXY protocol on streams 2024-03-10 11:03:06 +01:00
72abe50799 Adjust ProxyHostObject in api.swagger.json 2024-03-10 10:08:58 +01:00
a92624d086 Fix eslint errors in migrations 2024-03-10 10:03:58 +01:00
c6465a5090 Enable PROXY procotol for proxy hosts 2024-03-10 09:49:34 +01:00
d40f9e06fc Merge pull request #3479 from NginxProxyManager/dependabot/npm_and_yarn/docs/vite-5.0.12
Bump vite from 5.0.11 to 5.0.12 in /docs
2024-02-27 11:44:04 +10:00
69ec017a53 Merge pull request #3513 from setrin/websupport-fix
Updated certbot-dns-websupport plugin to 2.0.1 #3447
2024-02-27 11:43:47 +10:00
fa67f257ef Merge pull request #3526 from eltociear/patch-1
Update README.md
2024-02-27 11:43:24 +10:00
0dcd648c9d Merge pull request #3531 from hywax/develop
Add DNS Provider TimeWeb Cloud
2024-02-27 11:41:56 +10:00
c989a282e3 Merge pull request #3532 from Habbie/jwt-not-gpg
the generated keys appear to be for JWT, not GPG
2024-02-27 11:41:28 +10:00
5aff969c04 Merge pull request #3554 from bricas/develop
Add FreeDNS certbot plugin
2024-02-27 11:38:12 +10:00
bfbf7519ec Merge pull request #3560 from drachul/develop
Adding easyDNS provider.
2024-02-27 11:37:51 +10:00
bf36c7966a Merge pull request #3570 from NginxProxyManager/dependabot/npm_and_yarn/frontend/ip-2.0.1
Bump ip from 2.0.0 to 2.0.1 in /frontend
2024-02-27 11:36:18 +10:00
63cd9ba08f Merge pull request #3581 from davidindra/increase-max-domains-count
Fix: increase max number of domains to 100 (match with Let's Encrypt)
2024-02-27 11:36:04 +10:00
e3d4882c3d Merge pull request #3583 from michto01/patch-1
Update README.md to support Podman
2024-02-27 11:35:23 +10:00
3e1b73143e Merge pull request #3584 from timob/develop
Access-List fix so that nginx config is loaded after configuration happens
2024-02-27 11:34:52 +10:00
10ece3548d Fixing "the map directive is not allowed here" at the validation stage (see https://github.com/NginxProxyManager/nginx-proxy-manager/pull/3478) 2024-02-27 00:42:58 +01:00
Tim
0503a6af75 Fix so that nginx config is loaded after configuration happens
M	backend/internal/access-list.js
2024-02-26 10:04:25 +11:00
55d765e785 Update README.md to support Podman
Podman by default doesn't except the not fully qualified image urls. This commit adds the domain (docker.io) in order to resolve this issue.
2024-02-25 22:38:50 +01:00
1fb9a75a33 Fix: increase max number of domains to 100 2024-02-23 15:37:32 +01:00
9c2e838d61 Bump ip from 2.0.0 to 2.0.1 in /frontend
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-21 03:12:49 +00:00
40d81d6e44 Adding easyDNS provider. 2024-02-17 12:32:05 -08:00
1c84eaac02 Add FreeDNS certbot plugin
Info from #2352 and https://github.com/schleuss/certbot_dns_freedns
2024-02-15 23:43:53 -04:00
577954ef8c Bump version DNS Provider TimeWeb Cloud 2024-02-08 03:20:53 +05:00
f0c75641d8 the generated keys appear to be for JWT, not GPG 2024-02-07 12:44:37 +01:00
e42e2acf12 Add DNS Provider TimeWeb Cloud 2024-02-07 13:12:20 +05:00
eaa11fe460 Update README.md
a -> an
2024-02-04 18:50:50 +09:00
5b53825ccb Fixed certbot-dns-websupport plugin name 2024-01-30 22:46:05 +01:00
a94660120f Renamed certbot-dns-websupportsk plugin to certbot-dns-websupport & updatedcredentials 2024-01-30 22:17:33 +01:00
39f4836485 Updated certbot-dns-webstorm plugin to 2.0.1 2024-01-30 20:57:19 +01:00
209c1b3334 Merge branch 'master' into develop 2024-01-21 21:16:30 +10:00
58138fbac4 Bump version 2024-01-21 21:13:03 +10:00
da820db4e1 Fix startup hang due to unresolved promise
Affects instances where there are certs but none
of them are dns validated
2024-01-21 20:48:53 +10:00
47b868bfc6 Bump vite from 5.0.11 to 5.0.12 in /docs
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.11 to 5.0.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.0.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.0.12/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-19 22:36:30 +00:00
36 changed files with 356 additions and 56 deletions

View File

@ -1 +1 @@
2.11.0
2.11.1

View File

@ -1,7 +1,7 @@
<p align="center">
<img src="https://nginxproxymanager.com/github.png">
<br><br>
<img src="https://img.shields.io/badge/version-2.11.0-green.svg?style=for-the-badge">
<img src="https://img.shields.io/badge/version-2.11.1-green.svg?style=for-the-badge">
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a>
@ -19,7 +19,7 @@ running at home or otherwise, including free SSL, without having to know too muc
## Project Goal
I created this project to fill a personal need to provide users with a easy way to accomplish reverse
I created this project to fill a personal need to provide users with an easy way to accomplish reverse
proxying hosts with SSL termination and it had to be so easy that a monkey could do it. This goal hasn't changed.
While there might be advanced options they are optional and the project should be as simple as possible
so that the barrier for entry here is low.
@ -59,7 +59,7 @@ I won't go in to too much detail here but here are the basics for someone new to
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
image: 'docker.io/jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
@ -102,6 +102,11 @@ Immediately after logging in with this default user you will be asked to modify
All are welcome to create pull requests for this project, against the `develop` branch. Official releases are created from the `master` branch.
Run the following commands to test locally:
- `cd backend && npm i && node_modules/eslint/bin/eslint.js .`
- `cd test && npm i && npm run cypress`
CI is used in this project. All PR's must pass before being considered. After passing,
docker builds for PR's are available on dockerhub for manual verifications.

View File

@ -90,6 +90,8 @@
"nginx_err": "Command failed: /usr/sbin/nginx -t -g \"error_log off;\"\nnginx: [emerg] unknown directive \"sdfsdfsdf\" in /data/nginx/proxy_host/1.conf:37\nnginx: configuration file /etc/nginx/nginx.conf test failed\n"
},
"allow_websocket_upgrade": 0,
"enable_proxy_protocol": 0,
"load_balancer_ip": "",
"http2_support": 0,
"forward_scheme": "http",
"enabled": 1,
@ -210,6 +212,8 @@
"dns_challenge": false
},
"allow_websocket_upgrade": 0,
"enable_proxy_protocol": 0,
"load_balancer_ip": "",
"http2_support": 0,
"forward_scheme": "http",
"enabled": 1,
@ -1120,6 +1124,8 @@
"advanced_config",
"meta",
"allow_websocket_upgrade",
"enable_proxy_protocol",
"load_balancer_ip",
"http2_support",
"forward_scheme",
"enabled",
@ -1193,6 +1199,12 @@
"allow_websocket_upgrade": {
"type": "integer"
},
"enable_proxy_protocol": {
"type": "integer"
},
"load_balancer_ip": {
"type": "string"
},
"http2_support": {
"type": "integer"
},

View File

@ -204,7 +204,6 @@ const internalAccessList = {
});
}
})
.then(internalNginx.reload)
.then(() => {
// Add to audit log
return internalAuditLog.add(access, {
@ -227,7 +226,7 @@ const internalAccessList = {
if (row.proxy_host_count) {
return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts);
}
})
}).then(internalNginx.reload)
.then(() => {
return internalAccessList.maskItems(row);
});

View File

@ -155,6 +155,7 @@ const internalNginx = {
let locationCopy = Object.assign({}, {access_list_id: host.access_list_id}, {certificate_id: host.certificate_id},
{ssl_forced: host.ssl_forced}, {caching_enabled: host.caching_enabled}, {block_exploits: host.block_exploits},
{allow_websocket_upgrade: host.allow_websocket_upgrade}, {http2_support: host.http2_support},
{enable_proxy_protocol: host.enable_proxy_protocol}, {load_balancer_ip: host.load_balancer_ip},
{hsts_enabled: host.hsts_enabled}, {hsts_subdomains: host.hsts_subdomains}, {access_list: host.access_list},
{certificate: host.certificate}, host.locations[i]);

View File

@ -16,6 +16,7 @@ const certbot = {
return new Promise((resolve, reject) => {
if (pluginKeys.length === 0) {
resolve();
return;
}

View File

@ -0,0 +1,41 @@
const migrate_name = 'proxy_protocol';
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('proxy_host', function (proxy_host) {
proxy_host.integer('enable_proxy_protocol').notNull().unsigned().defaultTo(0);
proxy_host.string('load_balancer_ip').notNull().defaultTo('');
})
.then(() => {
logger.info('[' + migrate_name + '] proxy_host Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
return knex.schema.table('proxy_host', function (proxy_host) {
proxy_host.dropColumn('enable_proxy_protocol');
proxy_host.dropColumn('load_balancer_ip');
})
.then(function () {
logger.info('[' + migrate_name + '] proxy_host Table altered');
});
};

View 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');
});
};

View File

@ -172,7 +172,7 @@
"description": "Domain Names separated by a comma",
"example": "*.jc21.com,blog.jc21.com",
"type": "array",
"maxItems": 30,
"maxItems": 100,
"uniqueItems": true,
"items": {
"type": "string",

View File

@ -58,6 +58,16 @@
"example": true,
"type": "boolean"
},
"enable_proxy_protocol": {
"description": "Enable PROXY Protocol support",
"example": true,
"type": "boolean"
},
"load_balancer_ip": {
"type": "string",
"minLength": 0,
"maxLength": 255
},
"access_list_id": {
"$ref": "../definitions.json#/definitions/access_list_id"
},
@ -155,6 +165,12 @@
"allow_websocket_upgrade": {
"$ref": "#/definitions/allow_websocket_upgrade"
},
"enable_proxy_protocol": {
"$ref": "#/definitions/enable_proxy_protocol"
},
"load_balancer_ip": {
"$ref": "#/definitions/load_balancer_ip"
},
"access_list_id": {
"$ref": "#/definitions/access_list_id"
},
@ -245,6 +261,12 @@
"allow_websocket_upgrade": {
"$ref": "#/definitions/allow_websocket_upgrade"
},
"enable_proxy_protocol": {
"$ref": "#/definitions/enable_proxy_protocol"
},
"load_balancer_ip": {
"$ref": "#/definitions/load_balancer_ip"
},
"access_list_id": {
"$ref": "#/definitions/access_list_id"
},
@ -318,6 +340,12 @@
"allow_websocket_upgrade": {
"$ref": "#/definitions/allow_websocket_upgrade"
},
"enable_proxy_protocol": {
"$ref": "#/definitions/enable_proxy_protocol"
},
"load_balancer_ip": {
"$ref": "#/definitions/load_balancer_ip"
},
"access_list_id": {
"$ref": "#/definitions/access_list_id"
},

View File

@ -46,6 +46,16 @@
"udp_forwarding": {
"type": "boolean"
},
"enable_proxy_protocol": {
"description": "Enable PROXY Protocol support",
"example": true,
"type": "boolean"
},
"load_balancer_ip": {
"type": "string",
"minLength": 0,
"maxLength": 255
},
"enabled": {
"$ref": "../definitions.json#/definitions/enabled"
},
@ -78,6 +88,12 @@
"udp_forwarding": {
"$ref": "#/definitions/udp_forwarding"
},
"enable_proxy_protocol": {
"$ref": "#/definitions/enable_proxy_protocol"
},
"load_balancer_ip": {
"$ref": "#/definitions/load_balancer_ip"
},
"enabled": {
"$ref": "#/definitions/enabled"
},
@ -137,6 +153,12 @@
"udp_forwarding": {
"$ref": "#/definitions/udp_forwarding"
},
"enable_proxy_protocol": {
"$ref": "#/definitions/enable_proxy_protocol"
},
"load_balancer_ip": {
"$ref": "#/definitions/load_balancer_ip"
},
"meta": {
"$ref": "#/definitions/meta"
}
@ -177,6 +199,12 @@
"udp_forwarding": {
"$ref": "#/definitions/udp_forwarding"
},
"enable_proxy_protocol": {
"$ref": "#/definitions/enable_proxy_protocol"
},
"load_balancer_ip": {
"$ref": "#/definitions/load_balancer_ip"
},
"meta": {
"$ref": "#/definitions/meta"
}

View File

@ -1,15 +1,24 @@
listen 80;
{% if ipv6 -%}
listen [::]:80;
{% if enable_proxy_protocol == 1 or enable_proxy_protocol == true -%}
{% assign port_number_http = "88" -%}
{% assign port_number_https = "444" -%}
{% assign listen_extra_args = "proxy_protocol" -%}
{% else -%}
#listen [::]:80;
{% endif %}
{% assign port_number_http = "80" -%}
{% assign port_number_https = "443" -%}
{% assign listen_extra_args = "" -%}
{% endif -%}
listen {{ port_number_http }} {{ listen_extra_args }};
{% if ipv6 -%}
listen [::]:{{ port_number_http }} {{ listen_extra_args }};
{% endif -%}
{% if certificate -%}
listen 443 ssl{% if http2_support == 1 or http2_support == true %} http2{% endif %};
{% capture listen_extra_args_https %}ssl{% if http2_support %} http2{% endif %} {{ listen_extra_args }}{% endcapture -%}
listen {{ port_number_https }} {{ listen_extra_args_https }};
{% if ipv6 -%}
listen [::]:443 ssl{% if http2_support == 1 or http2_support == true %} http2{% endif %};
{% else -%}
#listen [::]:443;
{% endif %}
{% endif %}
listen [::]:{{ port_number_https }} {{ listen_extra_args_https }};
{% endif -%}
{% endif -%}
server_name {{ domain_names | join: " " }};

View File

@ -1,5 +1,3 @@
{% include "_hsts_map.conf" %}
location {{ path }} {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;

View File

@ -0,0 +1,6 @@
{% if enable_proxy_protocol == 1 or enable_proxy_protocol == true %}
{% if load_balancer_ip != '' %}
set_real_ip_from {{ load_balancer_ip }};
real_ip_header proxy_protocol;
{% endif %}
{% endif %}

View File

@ -15,6 +15,7 @@ server {
{% include "_exploits.conf" %}
{% include "_hsts.conf" %}
{% include "_forced_ssl.conf" %}
{% include "_proxy_protocol.conf" %}
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
proxy_set_header Upgrade $http_upgrade;

View File

@ -1,31 +1,38 @@
# ------------------------------------------------------------
# {{ 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 tcp_forwarding == 1 or tcp_forwarding == true -%}
server {
listen {{ incoming_port }};
listen {{ incoming_port }} {{ listen_extra_args }};
{% if ipv6 -%}
listen [::]:{{ incoming_port }};
listen [::]:{{ incoming_port }} {{ listen_extra_args }};
{% else -%}
#listen [::]:{{ incoming_port }};
#listen [::]:{{ incoming_port }} {{ listen_extra_args }};
{% endif %}
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
{% include '_proxy_protocol.conf' %}
# Custom
include /data/nginx/custom/server_stream[.]conf;
include /data/nginx/custom/server_stream_tcp[.]conf;
}
{% endif %}
{% if udp_forwarding == 1 or udp_forwarding == true %}
{% # Proxy Protocol is not supported for UDP %}
{% assign listen_extra_args = "" %}
server {
listen {{ incoming_port }} udp;
listen {{ incoming_port }} udp {{ listen_extra_args }};
{% if ipv6 -%}
listen [::]:{{ incoming_port }} udp;
listen [::]:{{ incoming_port }} udp {{ listen_extra_args }};
{% else -%}
#listen [::]:{{ incoming_port }} udp;
#listen [::]:{{ incoming_port }} udp {{ listen_extra_args }};
{% endif %}
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};

View File

@ -33,7 +33,7 @@ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
COPY docker/scripts/install-s6 /tmp/install-s6
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
EXPOSE 80 81 443
EXPOSE 80 81 88 443 444
COPY backend /app
COPY frontend/dist /app/frontend

View File

@ -29,5 +29,5 @@ RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
COPY scripts/install-s6 /tmp/install-s6
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
EXPOSE 80 81 443
EXPOSE 80 81 88 443 444
ENTRYPOINT [ "/init" ]

View File

@ -19,7 +19,9 @@ services:
expose:
- 81
- 80
- 88
- 443
- 444
depends_on:
- db
healthcheck:
@ -43,7 +45,9 @@ services:
expose:
- 81
- 80
- 88
- 443
- 444
healthcheck:
test: ["CMD", "/usr/bin/check-health"]
interval: 10s

View File

@ -11,7 +11,9 @@ services:
ports:
- 3080:80
- 3081:81
- 3088:88
- 3443:443
- 3444:444
networks:
- nginx_proxy_manager
environment:

View File

@ -208,3 +208,27 @@ 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).
## 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 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:
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
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

View File

@ -61,6 +61,8 @@ services:
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# - '88:88' # Public HTTP Port with proxy_protocol enabled
# - '444:444' # Public HTTPS Port with proxy_protocol enabled
# Add any other Stream port you want to expose
# - '21:21' # FTP
environment:
@ -120,7 +122,7 @@ Please note that the `jc21/mariadb-aria:latest` image might have some problems o
After the app is running for the first time, the following will happen:
1. GPG keys will be generated and saved in the data folder
1. JWT keys will be generated and saved in the data folder
2. The database will initialize with table structures
3. A default admin user will be created

View File

@ -3086,8 +3086,8 @@ __metadata:
linkType: hard
"vite@npm:~5.0.0":
version: 5.0.11
resolution: "vite@npm:5.0.11"
version: 5.0.12
resolution: "vite@npm:5.0.12"
dependencies:
esbuild: "npm:^0.19.3"
fsevents: "npm:~2.3.3"
@ -3121,7 +3121,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 74a3ddc6d43cf19cb6f827a53d77c481a07517a72b7d82a178df082012ad81ab5231a287a6dcc5471c0b2a5c8dd7e6ea8e1d62d268803057d0315729f09c5e33
checksum: c51b8e458851943c903fddde6973e720099ef8a5f364fb107cddade59c9e90f6d9ad98b61a7419cdfa0c6374236e10bff965d0c2d9e7b1790c68b874e5e7950c
languageName: node
linkType: hard

View File

@ -265,7 +265,7 @@ module.exports = Mn.View.extend({
this.ui.domain_names.selectize({
delimiter: ',',
persist: false,
maxOptions: 30,
maxOptions: 100,
create: function (input) {
return {
value: input,

View File

@ -233,7 +233,7 @@ module.exports = Mn.View.extend({
this.ui.domain_names.selectize({
delimiter: ',',
persist: false,
maxOptions: 30,
maxOptions: 100,
create: function (input) {
return {
value: input,

View File

@ -72,7 +72,7 @@
</label>
</div>
</div>
<div class="col-sm-12 col-md-12">
<div class="col-sm-6 col-md-6">
<div class="form-group">
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="allow_websocket_upgrade" value="1"<%- allow_websocket_upgrade ? ' checked' : '' %>>
@ -81,6 +81,22 @@
</label>
</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('proxy-hosts', '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('proxy-hosts', '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="form-group">

View File

@ -43,6 +43,8 @@ module.exports = Mn.View.extend({
dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]',
propagation_seconds: 'input[name="meta[propagation_seconds]"]',
forward_scheme: 'select[name="forward_scheme"]',
enable_proxy_protocol: 'input[name="enable_proxy_protocol"]',
load_balancer_ip: 'input[name="load_balancer_ip"]',
letsencrypt: '.letsencrypt'
},
@ -51,6 +53,13 @@ module.exports = Mn.View.extend({
},
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.certificate_select': function () {
let id = this.ui.certificate_select.val();
if (id === 'new') {
@ -163,6 +172,7 @@ module.exports = Mn.View.extend({
data.block_exploits = !!data.block_exploits;
data.caching_enabled = !!data.caching_enabled;
data.allow_websocket_upgrade = !!data.allow_websocket_upgrade;
data.enable_proxy_protocol = !!data.enable_proxy_protocol;
data.http2_support = !!data.http2_support;
data.hsts_enabled = !!data.hsts_enabled;
data.hsts_subdomains = !!data.hsts_subdomains;
@ -264,6 +274,7 @@ module.exports = Mn.View.extend({
onRender: function () {
let view = this;
this.ui.enable_proxy_protocol.trigger('change');
this.ui.ssl_forced.trigger('change');
this.ui.hsts_enabled.trigger('change');
@ -271,7 +282,7 @@ module.exports = Mn.View.extend({
this.ui.domain_names.selectize({
delimiter: ',',
persist: false,
maxOptions: 30,
maxOptions: 100,
create: function (input) {
return {
value: input,

View File

@ -235,7 +235,7 @@ module.exports = Mn.View.extend({
this.ui.domain_names.selectize({
delimiter: ',',
persist: false,
maxOptions: 30,
maxOptions: 100,
create: function (input) {
return {
value: input,

View File

@ -42,6 +42,22 @@
</label>
</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="forward-type-error invalid-feedback"><%- i18n('streams', 'forward-type-error') %></div>
</div>

View File

@ -14,6 +14,8 @@ module.exports = Mn.View.extend({
ui: {
form: 'form',
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',
buttons: '.modal-footer button',
switches: '.custom-switch-input',
@ -22,6 +24,13 @@ module.exports = Mn.View.extend({
},
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 () {
this.ui.type_error.hide();
},
@ -47,6 +56,7 @@ module.exports = Mn.View.extend({
data.forwarding_port = parseInt(data.forwarding_port, 10);
data.tcp_forwarding = !!data.tcp_forwarding;
data.udp_forwarding = !!data.udp_forwarding;
data.enable_proxy_protocol = !!data.enable_proxy_protocol;
let method = App.Api.Nginx.Streams.create;
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) {
if (typeof options.model === 'undefined' || !options.model) {
this.model = new StreamModel.Model();

View File

@ -131,6 +131,8 @@
"help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional SSL termination for your service that might not have SSL support built in.\nProxy Hosts are the most common use for the Nginx Proxy Manager.",
"access-list": "Access List",
"allow-websocket-upgrade": "Websockets Support",
"enable-proxy-protocol": "Enable Proxy Protocol",
"load-balancer-ip": "Load balancer or TCP proxy IP / CIDR range",
"ignore-invalid-upstream-ssl": "Ignore Invalid SSL",
"custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path/",
"search": "Search Host…"
@ -175,6 +177,8 @@
"protocol": "Protocol",
"tcp": "TCP",
"udp": "UDP",
"enable-proxy-protocol": "Enable Proxy Protocol",
"load-balancer-ip": "Load balancer or TCP proxy IP / CIDR range",
"delete": "Delete Stream",
"delete-confirm": "Are you sure you want to delete this Stream?",
"help-title": "What is a Stream?",

View File

@ -19,6 +19,8 @@ const model = Backbone.Model.extend({
hsts_subdomains: false,
caching_enabled: false,
allow_websocket_upgrade: false,
enable_proxy_protocol: false,
load_balancer_ip: '',
block_exploits: false,
http2_support: false,
advanced_config: '',

View File

@ -13,6 +13,8 @@ const model = Backbone.Model.extend({
forwarding_port: null,
tcp_forwarding: true,
udp_forwarding: false,
enable_proxy_protocol: false,
load_balancer_ip: "",
enabled: true,
meta: {},
// The following are expansions:

View File

@ -3809,9 +3809,9 @@ invariant@^2.2.2:
loose-envify "^1.0.0"
ip@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
is-accessor-descriptor@^0.1.6:
version "0.1.6"

View File

@ -159,6 +159,14 @@
"credentials": "dns_dynu_auth_token = YOUR_DYNU_AUTH_TOKEN",
"full_plugin_name": "dns-dynu"
},
"easydns": {
"name": "easyDNS",
"package_name": "certbot-dns-easydns",
"version": "~=0.1.2",
"dependencies": "",
"credentials": "dns_easydns_usertoken = YOUR_EASYDNS_USERTOKEN\ndns_easydns_userkey = YOUR_EASYDNS_USERKEY\ndns_easydns_endpoint = https://rest.easydns.net",
"full_plugin_name": "dns-easydns"
},
"eurodns": {
"name": "EuroDNS",
"package_name": "certbot-dns-eurodns",
@ -167,6 +175,14 @@
"credentials": "dns_eurodns_applicationId = myuser\ndns_eurodns_apiKey = mysecretpassword\ndns_eurodns_endpoint = https://rest-api.eurodns.com/user-api-gateway/proxy",
"full_plugin_name": "dns-eurodns"
},
"freedns": {
"name": "FreeDNS",
"package_name": "certbot-dns-freedns",
"version": "~=0.1.0",
"dependencies": "",
"credentials": "dns_freedns_username = myremoteuser\ndns_freedns_password = verysecureremoteuserpassword",
"full_plugin_name": "dns-freedns"
},
"gandi": {
"name": "Gandi Live DNS",
"package_name": "certbot_plugin_gandi",
@ -391,6 +407,14 @@
"credentials": "dns_strato_username = user\ndns_strato_password = pass\n# uncomment if youre using two factor authentication:\n# dns_strato_totp_devicename = 2fa_device\n# dns_strato_totp_secret = 2fa_secret\n#\n# uncomment if domain name contains special characters\n# insert domain display name as seen on your account page here\n# dns_strato_domain_display_name = my-punicode-url.de\n#\n# if youre not using strato.de or another special endpoint you can customise it below\n# you will probably only need to adjust the host, but you can also change the complete endpoint url\n# dns_strato_custom_api_scheme = https\n# dns_strato_custom_api_host = www.strato.de\n# dns_strato_custom_api_port = 443\n# dns_strato_custom_api_path = \"/apps/CustomerService\"",
"full_plugin_name": "dns-strato"
},
"timeweb": {
"name": "Timeweb Cloud",
"package_name": "certbot-dns-timeweb",
"version": "~=1.0.1",
"dependencies": "",
"credentials": "dns_timeweb_api_key = XXXXXXXXXXXXXXXXXXX",
"full_plugin_name": "dns-timeweb"
},
"transip": {
"name": "TransIP",
"package_name": "certbot-dns-transip",
@ -415,12 +439,12 @@
"credentials": "dns_vultr_key = YOUR_VULTR_API_KEY",
"full_plugin_name": "dns-vultr"
},
"websupportsk": {
"websupport": {
"name": "Websupport.sk",
"package_name": "certbot-dns-websupportsk",
"version": "~=0.1.6",
"package_name": "certbot-dns-websupport",
"version": "~=2.0.1",
"dependencies": "",
"credentials": "dns_websupportsk_api_key = <api_key>\ndns_websupportsk_secret = <secret>\ndns_websupportsk_domain = example.com",
"full_plugin_name": "dns-websupportsk"
"credentials": "dns_websupport_identifier = <api_key>\ndns_websupport_secret_key = <secret>",
"full_plugin_name": "dns-websupport"
}
}

View File

@ -29,6 +29,8 @@ describe('Hosts endpoints', () => {
block_exploits: false,
caching_enabled: false,
allow_websocket_upgrade: false,
enable_proxy_protocol: false,
load_balancer_ip: '',
http2_support: false,
hsts_enabled: false,
hsts_subdomains: false,