Skip to content

Commit 64de096

Browse files
committed
Added support for redirection and 404 hosts
1 parent 6182084 commit 64de096

22 files changed

+453
-31
lines changed

README.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
# Nginx Proxy Manager
44

5-
![Version](https://img.shields.io/badge/version-1.0.0-green.svg)
5+
![Version](https://img.shields.io/badge/version-1.0.1-green.svg)
66
![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg)
77
![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg)
88

99
![Build Status](http://bamboo.jc21.com/plugins/servlet/wittified/build-status/AB-NPM)
1010

11-
This NPM comes as a pre-built docker image that enables you to easily forward to your websites
11+
This project comes as a pre-built docker image that enables you to easily forward to your websites
1212
running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt.
1313

1414

@@ -19,6 +19,10 @@ running at home or otherwise, including free SSL, without having to know too muc
1919
- Secure your sites with SSL and optionally force SSL
2020
- Secure your sites with Basic HTTP Authentication Access Lists
2121
- Advanced Nginx config option for super users
22+
- 3 domain uses:
23+
- Proxy requests to upstream server
24+
- Redirect requests to another domain
25+
- Return immediate 404's
2226

2327

2428
## Getting started
@@ -84,7 +88,7 @@ I won't go in to too much detail here but here are the basics for someone new to
8488
1. Your home router will have a Port Forwarding section somewhere. Log in and find it
8589
2. Add port forwarding for port 80 and 443 to the server hosting this project
8690
3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS
87-
4. Use the NPM here as your gateway to forward to your other web based services
91+
4. Use the Nginx Proxy Manager here as your gateway to forward to your other web based services
8892

8993

9094
## Screenshots
@@ -98,8 +102,8 @@ I won't go in to too much detail here but here are the basics for someone new to
98102

99103
- Pass on human readable ssl cert errors to the ui
100104
- Allow a host to be a redirection to another domain
101-
- Allow a host to return immediate 404's
102105
- UI: Allow column sorting on tables
103106
- UI: Allow filtering hosts by types
104107
- Advanced option to overwrite the default location block (or regex to do it automatically)
105-
- Change the renew ssl process to use the letsencrypt renew procedure so as to avoid rate limits
108+
- Add nice upstream error pages
109+

manager/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nginx-proxy-manager",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "Nginx proxt with built in Web based management",
55
"main": "src/backend/index.js",
66
"dependencies": {

manager/src/backend/internal/host.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,14 @@ const internalHost = {
155155
*
156156
* @param {Object} host
157157
* @param {Boolean} [reload_nginx]
158-
* @param {Boolean} [force_ssl_renew]
159158
* @returns {Promise}
160159
*/
161-
configure: (host, reload_nginx, force_ssl_renew) => {
160+
configure: (host, reload_nginx) => {
162161
return new Promise((resolve/*, reject*/) => {
163162
resolve(internalNginx.deleteConfig(host));
164163
})
165164
.then(() => {
166-
if (host.ssl && (force_ssl_renew || !internalSsl.hasValidSslCerts(host))) {
165+
if (host.ssl && !internalSsl.hasValidSslCerts(host)) {
167166
return internalSsl.configureSsl(host);
168167
}
169168
})
@@ -248,7 +247,7 @@ const internalHost = {
248247
reject(new error.ValidationError('Host does not have SSL enabled'));
249248
} else {
250249
// 3. Fire the ssl and config generation for this host, forcing ssl
251-
internalHost.configure(host, true, true)
250+
internalSsl.renewSsl(host)
252251
.then((/*result*/) => {
253252
resolve(host);
254253
})

manager/src/backend/internal/nginx.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ const internalNginx = {
4545
let filename = internalNginx.getConfigName(host);
4646

4747
try {
48-
template = fs.readFileSync(__dirname + '/../templates/host.conf.ejs', {encoding: 'utf8'});
48+
if (typeof host.type === 'undefined' || !host.type) {
49+
host.type = 'proxy';
50+
}
51+
52+
template = fs.readFileSync(__dirname + '/../templates/' + host.type + '.conf.ejs', {encoding: 'utf8'});
4953
let config_text = ejs.render(template, host);
5054
fs.writeFileSync(filename, config_text, {encoding: 'utf8'});
5155
resolve(true);

manager/src/backend/schema/endpoints/hosts.json

+24-3
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,20 @@
1010
"type": "string",
1111
"readonly": true
1212
},
13+
"type": {
14+
"type": "string",
15+
"pattern": "^(proxy|redirection|404)$"
16+
},
1317
"hostname": {
1418
"$ref": "../definitions.json#/definitions/hostname"
1519
},
1620
"forward_server": {
1721
"type": "string",
1822
"format": "ipv4"
1923
},
24+
"forward_host": {
25+
"type": "string"
26+
},
2027
"forward_port": {
2128
"type": "integer",
2229
"minumum": 1,
@@ -79,14 +86,19 @@
7986
"schema": {
8087
"type": "object",
8188
"required": [
82-
"hostname",
83-
"forward_server",
84-
"forward_port"
89+
"type",
90+
"hostname"
8591
],
8692
"properties": {
93+
"type": {
94+
"$ref": "#/definitions/type"
95+
},
8796
"hostname": {
8897
"$ref": "#/definitions/hostname"
8998
},
99+
"forward_host": {
100+
"$ref": "#/definitions/forward_host"
101+
},
90102
"forward_server": {
91103
"$ref": "#/definitions/forward_server"
92104
},
@@ -137,6 +149,9 @@
137149
"hostname": {
138150
"$ref": "#/definitions/hostname"
139151
},
152+
"forward_host": {
153+
"$ref": "#/definitions/forward_host"
154+
},
140155
"forward_server": {
141156
"$ref": "#/definitions/forward_server"
142157
},
@@ -188,9 +203,15 @@
188203
"_id": {
189204
"$ref": "#/definitions/_id"
190205
},
206+
"type": {
207+
"$ref": "#/definitions/type"
208+
},
191209
"hostname": {
192210
"$ref": "#/definitions/hostname"
193211
},
212+
"forward_host": {
213+
"$ref": "#/definitions/forward_host"
214+
},
194215
"forward_server": {
195216
"$ref": "#/definitions/forward_server"
196217
},
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# <%- hostname %>
2+
server {
3+
listen 80;
4+
<%- typeof ssl !== 'undefined' && ssl ? 'listen 443 ssl;' : '' %>
5+
6+
server_name <%- hostname %>;
7+
8+
access_log /config/logs/<%- hostname %>.log proxy;
9+
10+
<% if (typeof ssl !== 'undefined' && ssl) { -%>
11+
include conf.d/include/ssl-ciphers.conf;
12+
ssl_certificate /etc/letsencrypt/live/<%- hostname %>/fullchain.pem;
13+
ssl_certificate_key /etc/letsencrypt/live/<%- hostname %>/privkey.pem;
14+
<% } -%>
15+
16+
<%- typeof advanced !== 'undefined' && advanced ? advanced : '' %>
17+
18+
return 404;
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# <%- hostname %>
2+
server {
3+
listen 80;
4+
<%- typeof ssl !== 'undefined' && ssl ? 'listen 443 ssl;' : '' %>
5+
6+
server_name <%- hostname %>;
7+
8+
access_log /config/logs/<%- hostname %>.log proxy;
9+
10+
<%- typeof asset_caching !== 'undefined' && asset_caching ? 'include conf.d/include/assets.conf;' : '' %>
11+
<%- typeof block_exploits !== 'undefined' && block_exploits ? 'include conf.d/include/block-exploits.conf;' : '' %>
12+
13+
<% if (typeof ssl !== 'undefined' && ssl) { -%>
14+
include conf.d/include/ssl-ciphers.conf;
15+
ssl_certificate /etc/letsencrypt/live/<%- hostname %>/fullchain.pem;
16+
ssl_certificate_key /etc/letsencrypt/live/<%- hostname %>/privkey.pem;
17+
<% } -%>
18+
19+
<%- typeof advanced !== 'undefined' && advanced ? advanced : '' %>
20+
21+
return 301 $scheme://<%- forward_host %>$request_uri;
22+
}

manager/src/frontend/js/app/controller.js

+25-3
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,34 @@ module.exports = {
5454
},
5555

5656
/**
57-
* Show Host Form
57+
* Show Proxy Host Form
5858
*
5959
* @param model
6060
*/
61-
showHostForm: function (model) {
62-
require(['./main', './host/form'], function (App, View) {
61+
showProxyHostForm: function (model) {
62+
require(['./main', './host/proxy_form'], function (App, View) {
63+
App.UI.showModalDialog(new View({model: model}));
64+
});
65+
},
66+
67+
/**
68+
* Show Redirection Host Form
69+
*
70+
* @param model
71+
*/
72+
showRedirectionHostForm: function (model) {
73+
require(['./main', './host/redirection_form'], function (App, View) {
74+
App.UI.showModalDialog(new View({model: model}));
75+
});
76+
},
77+
78+
/**
79+
* Show 404 Host Form
80+
*
81+
* @param model
82+
*/
83+
show404HostForm: function (model) {
84+
require(['./main', './host/404_form'], function (App, View) {
6385
App.UI.showModalDialog(new View({model: model}));
6486
});
6587
},
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<td colspan="10" class="text-center">
22
<br><br>
33
<p>It looks like there are no hosts configured.</p>
4-
<p><button type="button" class="btn btn-sm btn-success">Create your first Host</button></p>
4+
<p>
5+
<button type="button" class="btn btn-sm btn-success proxy">Create Proxy Host</button>
6+
<button type="button" class="btn btn-sm btn-success redirection">Create Redirection Host</button>
7+
<button type="button" class="btn btn-sm btn-success 404">Create 404 Host</button>
8+
</p>
59
</td>

manager/src/frontend/js/app/dashboard/empty.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,25 @@ module.exports = Mn.View.extend({
1111
tagName: 'tr',
1212

1313
ui: {
14-
create: 'button'
14+
proxy: 'button.proxy',
15+
redirection: 'button.redirection',
16+
'404': 'button.404'
1517
},
1618

1719
events: {
18-
'click @ui.create': function (e) {
20+
'click @ui.proxy': function (e) {
1921
e.preventDefault();
20-
Controller.showHostForm(new HostModel.Model);
22+
Controller.showProxyHostForm(new HostModel.Model);
23+
},
24+
25+
'click @ui.redirection': function (e) {
26+
e.preventDefault();
27+
Controller.showRedirectionHostForm(new HostModel.Model);
28+
},
29+
30+
'click @ui.404': function (e) {
31+
e.preventDefault();
32+
Controller.show404HostForm(new HostModel.Model);
2133
}
2234
}
2335
});

manager/src/frontend/js/app/dashboard/main.ejs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
<table class="table table-condensed table-striped">
22
<thead>
33
<th>Hostname</th>
4-
<th>Forward</th>
4+
<th>Destination</th>
55
<th>SSL</th>
66
<th>Access List</th>
7-
<th class="text-right"><button type="button" class="btn btn-xs btn-info">Create Host</button></th>
7+
<th class="text-right">
8+
<div class="btn-group">
9+
<button type="button" class="btn btn-xs btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
10+
Create Host <span class="caret"></span>
11+
</button>
12+
<ul class="dropdown-menu">
13+
<li><a href="#" class="new-proxy">Proxy Host</a></li>
14+
<li><a href="#" class="new-redirection">Redirection Host</a></li>
15+
<li><a href="#" class="new-404">404 Host</a></li>
16+
</ul>
17+
</div>
18+
</th>
819
</thead>
920
<tbody>
1021
<!-- items -->

manager/src/frontend/js/app/dashboard/main.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,25 @@ module.exports = Mn.View.extend({
2626
},
2727

2828
ui: {
29-
'create': 'th button'
29+
new_proxy: 'th .new-proxy',
30+
new_redirection: 'th .new-redirection',
31+
new_404: 'th .new-404'
3032
},
3133

3234
events: {
33-
'click @ui.create': function (e) {
35+
'click @ui.new_proxy': function (e) {
3436
e.preventDefault();
35-
Controller.showHostForm(new HostModel.Model);
37+
Controller.showProxyHostForm(new HostModel.Model);
38+
},
39+
40+
'click @ui.new_redirection': function (e) {
41+
e.preventDefault();
42+
Controller.showRedirectionHostForm(new HostModel.Model);
43+
},
44+
45+
'click @ui.new_404': function (e) {
46+
e.preventDefault();
47+
Controller.show404HostForm(new HostModel.Model);
3648
}
3749
},
3850

manager/src/frontend/js/app/dashboard/row.ejs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<td><a href="<%- ssl ? 'https' : 'http' %>://<%- hostname %>" target="_blank"><%- hostname %></a></td>
2-
<td><span class="monospace"><%- forward_server %>:<%- forward_port %></span></td>
2+
<td>
3+
<span class="monospace">
4+
<% if (type === 'proxy') { %>
5+
<%- forward_server %>:<%- forward_port %>
6+
<% } else if (type === 'redirection') { %>
7+
<%- forward_host %>
8+
<% } else if (type === '404') { %>
9+
404
10+
<% } %>
11+
</span>
12+
</td>
313
<td>
414
<% if (ssl && force_ssl) { %>
515
Forced

manager/src/frontend/js/app/dashboard/row.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,17 @@ module.exports = Mn.View.extend({
2222
events: {
2323
'click @ui.edit': function (e) {
2424
e.preventDefault();
25-
Controller.showHostForm(this.model);
25+
switch (this.model.get('type')) {
26+
case 'proxy':
27+
Controller.showProxyHostForm(this.model);
28+
break;
29+
case 'redirection':
30+
Controller.showRedirectionHostForm(this.model);
31+
break;
32+
case '404':
33+
Controller.show404HostForm(this.model);
34+
break;
35+
}
2636
},
2737

2838
'click @ui.delete': function (e) {

0 commit comments

Comments
 (0)