Skip to content

Commit 98cdbd3

Browse files
authored
Merge pull request #51 from devilbox/release-1.0.9
Release 1.0.9
2 parents d4a5fa2 + 1c9277d commit 98cdbd3

File tree

6 files changed

+163
-54
lines changed

6 files changed

+163
-54
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
[![pydoc](https://github.com/devilbox/vhost-gen/workflows/pydoc/badge.svg)](https://github.com/devilbox/vhost-gen/actions?query=workflow%3Apydoc)
2222

2323

24-
**[vhost-gen](bin/vhost-gen)** will dynamically generate **vhost** or **reverse proxy** configuration files for Apache 2.2, Apache 2.4 and Nginx depending on what you have set in [conf.yml](etc/conf.yml). This makes it easy to switch between different web servers while keeping the exact same functionality.
24+
**[vhost-gen](bin/vhost-gen)** will dynamically generate **vhost** or **reverse proxy** (with or without **websocket support**) configuration files for Apache 2.2, Apache 2.4 and Nginx depending on what you have set in [conf.yml](etc/conf.yml). This makes it easy to switch between different web servers while keeping the exact same functionality.
2525

2626
---
2727

@@ -138,7 +138,7 @@ If you are not satisfied with the default definitions for the webserver configur
138138

139139
#### Supported Features
140140

141-
* Document serving vHost or Reverse Proxy
141+
* Document serving vHost or Reverse Proxy (with or w/o websocket support)
142142
* Custom server name
143143
* Custom document root
144144
* Custom access log name
@@ -248,8 +248,9 @@ in /etc/vhost-gen/conf.yml
248248
249249
Required arguments:
250250
-p|r <str> You need to choose one of the mutually exclusive arguments.
251-
-p: Path to document root/
251+
-p: Path to document root.
252252
-r: http(s)://Host:Port for reverse proxy.
253+
-r: ws(s)://Host:Port for reverse proxy with websocket support.
253254
Depening on the choice, it will either generate a document serving
254255
vhost or a reverse proxy vhost.
255256
Note, when using -p, this can also have a suffix directory to be set

bin/vhost-gen

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ if os.environ.get("MYPY_CHECK", False):
2929
# --------------------------------------------------------------------------------------------------
3030
APPNAME = "vhost-gen"
3131
APPREPO = "https://github.com/devilbox/vhost-gen"
32-
VERSION = "1.0.8"
33-
RELDATE = "2022-12-22"
32+
VERSION = "1.0.9"
33+
RELDATE = "2022-12-27"
3434

3535
# Default paths
3636
CONFIG_PATH = "/etc/vhost-gen/conf.yml"
@@ -115,8 +115,9 @@ in /etc/vhost-gen/conf.yml
115115
116116
Required arguments:
117117
-p|r <str> You need to choose one of the mutually exclusive arguments.
118-
-p: Path to document root/
118+
-p: Path to document root.
119119
-r: http(s)://Host:Port for reverse proxy.
120+
-r: ws(s)://Host:Port for reverse proxy with websocket support.
120121
Depening on the choice, it will either generate a document serving
121122
vhost or a reverse proxy vhost.
122123
Note, when using -p, this can also have a suffix directory to be set
@@ -349,15 +350,12 @@ def validate_args_req(name, docroot, proxy, mode, location, verbose):
349350
sys.exit(1)
350351

351352
# Regex: HOSTNAME/IP:PORT
352-
regex = re.compile("(^http(s)?://[-_.a-zA-Z0-9]+:[0-9]+$)", re.IGNORECASE)
353-
if not regex.match(proxy):
354-
log(
355-
0,
356-
"Invalid proxy argument string: '{}', should be {} or {}.".format(
357-
proxy, "http(s)://HOST:PORT", "http(s)://IP:PORT"
358-
),
359-
verbose,
360-
)
353+
regex_http = re.compile("(^http(s)?://[-_.a-zA-Z0-9]+:[0-9]+$)", re.IGNORECASE)
354+
regex_webs = re.compile("(^ws(s)?://[-_.a-zA-Z0-9]+:[0-9]+$)", re.IGNORECASE)
355+
if not regex_http.match(proxy) and not regex_webs.match(proxy):
356+
log(0, "Invalid proxy argument string: '{}', should be:".format(proxy), verbose)
357+
log(0, " http(s)://HOST:PORT or http(s)://IP:PORT", verbose)
358+
log(0, " ws(s)://HOST:PORT or ws(s)://IP:PORT", verbose)
361359
log(0, "Type --help for help", verbose)
362360
sys.exit(1)
363361

@@ -570,15 +568,34 @@ def vhost_get_vhost_rproxy(template, proxy, location, verbose):
570568
sys.exit(1)
571569

572570
proxy_addr = match.group(1)
573-
return str_replace(
574-
template["vhost_type"]["rproxy"],
575-
{
576-
"__LOCATION__": location,
577-
"__PROXY_PROTO__": re.sub("://.*$", "", proxy),
578-
"__PROXY_ADDR__": proxy_addr,
579-
"__PROXY_PORT__": re.sub("^.*:", "", proxy),
580-
},
581-
)
571+
protocol = re.sub("://.*$", "", proxy) # Proxy protocol http(s) vs ws(s)
572+
573+
# ws == http and wss == https
574+
proxy_prot = "http" if protocol in ("http", "ws") else "https"
575+
wsock_prot = "ws" if protocol in ("http", "ws") else "wss"
576+
577+
# Websocket
578+
if protocol in ("ws", "wss"):
579+
return str_replace(
580+
template["vhost_type"]["rproxy_ws"],
581+
{
582+
"__LOCATION__": location,
583+
"__WS_PROTO__": wsock_prot,
584+
"__PROXY_PROTO__": proxy_prot,
585+
"__PROXY_ADDR__": proxy_addr,
586+
"__PROXY_PORT__": re.sub("^.*:", "", proxy),
587+
},
588+
)
589+
if protocol in ("http", "https"):
590+
return str_replace(
591+
template["vhost_type"]["rproxy"],
592+
{
593+
"__LOCATION__": location,
594+
"__PROXY_PROTO__": proxy_prot,
595+
"__PROXY_ADDR__": proxy_addr,
596+
"__PROXY_PORT__": re.sub("^.*:", "", proxy),
597+
},
598+
)
582599
return ""
583600

584601

etc/templates/apache22.yml

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,23 @@
4040
# __PHP_PORT__
4141
#
4242

43+
###
44+
### Notes about Apache
45+
###
46+
47+
#
48+
# 1. Each same directive is checked in order of definition (last one wins)
49+
# 2. Directives are ordered: Directory, DirectoryMatch, Files, and finally Location (last one wins)
50+
# * Last match always takes precedence
51+
#
52+
# Exception: Directories, where shortest path is matched first
53+
# Exception: ProxyPass and Alias first match and then stops
4354

4455
###
4556
### Basic vHost skeleton
4657
###
58+
### Note: Reverse Proxy section must be last for Apache 2.2
59+
###
4760
vhost: |
4861
<VirtualHost __DEFAULT_VHOST__:__PORT__>
4962
ServerName __VHOST_NAME__
@@ -54,13 +67,13 @@ vhost: |
5467
__REDIRECT__
5568
__SSL__
5669
__VHOST_DOCROOT__
57-
__VHOST_RPROXY__
5870
__PHP_FPM__
5971
__ALIASES__
6072
__DENIES__
6173
__SERVER_STATUS__
6274
# Custom directives
6375
__CUSTOM__
76+
__VHOST_RPROXY__
6477
</VirtualHost>
6578
6679
###
@@ -84,15 +97,38 @@ vhost_type:
8497
Allow from all
8598
</Directory>
8699
87-
# Reverse Proxy (-r)
100+
# Reverse Proxy (-r http(s)://ADDR:PORT)
88101
rproxy: |
89-
# Define the vhost to reverse proxy
90-
ProxyRequests off
91-
ProxyPass __LOCATION__ __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__
92-
<location __LOCATION__>
93-
ProxyPassReverse /
94-
RequestHeader unset Accept-Encoding
95-
</location>
102+
# ProxyRequests: Disable "Forward Proxy"
103+
# ProxyPreserveHost: Pass "Host" header to remote
104+
# ProxyVia: Add "Via" header
105+
ProxyRequests Off
106+
ProxyPreserveHost On
107+
ProxyVia On
108+
<Location __LOCATION__>
109+
# Reverse Proxy
110+
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
111+
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
112+
</Location>
113+
114+
# Reverse Proxy with websocket support (-r ws(s)://ADDR:PORT)
115+
rproxy_ws: |
116+
# ProxyRequests: Disable "Forward Proxy"
117+
# ProxyPreserveHost: Pass "Host" header to remote
118+
# ProxyVia: Add "Via" header
119+
ProxyRequests Off
120+
ProxyPreserveHost On
121+
ProxyVia On
122+
<Location __LOCATION__>
123+
# Websocket Rewrite Settings
124+
RewriteEngine On
125+
RewriteCond %{HTTP:Connection} Upgrade [NC]
126+
RewriteCond %{HTTP:Upgrade} websocket [NC]
127+
RewriteRule ^/?(.*)$ __WS_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/$1 [P,L]
128+
# Reverse Proxy
129+
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
130+
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
131+
</Location>
96132
97133
98134
###
@@ -122,6 +158,7 @@ features:
122158
# Alias Definition
123159
Alias "__ALIAS__" "__PATH____ALIAS__"
124160
<Location "__ALIAS__">
161+
ProxyPass !
125162
__XDOMAIN_REQ__
126163
</Location>
127164
<Directory "__PATH____ALIAS__">
@@ -131,10 +168,10 @@ features:
131168
132169
deny: |
133170
# Deny Definition
134-
<FilesMatch "__REGEX__">
171+
<LocationMatch "__REGEX__">
135172
Order allow,deny
136173
Deny from all
137-
</FilesMatch>
174+
</LocationMatch>
138175
139176
server_status: |
140177
# Status Page

etc/templates/apache24.yml

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@
4040
# __PHP_PORT__
4141
#
4242

43+
###
44+
### Notes about Apache
45+
###
46+
47+
#
48+
# 1. Each same directive is checked in order of definition (last one wins)
49+
# 2. Directives are ordered: Directory, DirectoryMatch, Files, and finally Location (last one wins)
50+
# * Last match always takes precedence
51+
#
52+
# Exception: Directories, where shortest path is matched first
53+
# Exception: ProxyPass and Alias first match and then stops
4354

4455
###
4556
### Basic vHost skeleton
@@ -86,19 +97,42 @@ vhost_type:
8697
Require all granted
8798
</Directory>
8899
89-
# Reverse Proxy (-r)
100+
# Reverse Proxy (-r http(s)://ADDR:PORT)
90101
rproxy: |
91-
# Define the vhost to reverse proxy
92-
ProxyRequests off
93-
ProxyPass __LOCATION__ __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__
94-
ProxyHTMLURLMap __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__ __LOCATION__
95-
<location __LOCATION__>
96-
ProxyPassReverse /
97-
SetOutputFilter proxy-html
98-
ProxyHTMLURLMap / __LOCATION__
99-
ProxyHTMLURLMap __LOCATION__ __LOCATION__
100-
RequestHeader unset Accept-Encoding
101-
</location>
102+
# ProxyRequests: Disable "Forward Proxy"
103+
# ProxyPreserveHost: Pass "Host" header to remote
104+
# ProxyAddHeaders: Add "X-Forward-*" headers
105+
# ProxyVia: Add "Via" header
106+
ProxyRequests Off
107+
ProxyPreserveHost On
108+
ProxyAddHeaders On
109+
ProxyVia On
110+
<Location __LOCATION__>
111+
# Reverse Proxy
112+
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
113+
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
114+
</Location>
115+
116+
# Reverse Proxy with websocket support (-r ws(s)://ADDR:PORT)
117+
rproxy_ws: |
118+
# ProxyRequests: Disable "Forward Proxy"
119+
# ProxyPreserveHost: Pass "Host" header to remote
120+
# ProxyAddHeaders: Add "X-Forward-*" headers
121+
# ProxyVia: Add "Via" header
122+
ProxyRequests Off
123+
ProxyPreserveHost On
124+
ProxyAddHeaders On
125+
ProxyVia On
126+
<Location __LOCATION__>
127+
# Websocket Rewrite Settings
128+
RewriteEngine On
129+
RewriteCond %{HTTP:Connection} Upgrade [NC]
130+
RewriteCond %{HTTP:Upgrade} websocket [NC]
131+
RewriteRule ^/?(.*)$ __WS_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/$1 [P,L]
132+
# Reverse Proxy
133+
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
134+
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
135+
</Location>
102136
103137
104138
###
@@ -147,6 +181,7 @@ features:
147181
# Alias Definition
148182
Alias "__ALIAS__" "__PATH____ALIAS__"
149183
<Location "__ALIAS__">
184+
ProxyPass !
150185
__XDOMAIN_REQ__
151186
</Location>
152187
<Directory "__PATH____ALIAS__">
@@ -157,10 +192,10 @@ features:
157192
158193
deny: |
159194
# Deny Definition
160-
<FilesMatch "__REGEX__">
195+
<LocationMatch "__REGEX__">
161196
Order allow,deny
162197
Deny from all
163-
</FilesMatch>
198+
</LocationMatch>
164199
165200
server_status: |
166201
# Status Page

etc/templates/nginx.yml

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,31 @@ vhost_type:
7575
root "__DOCUMENT_ROOT__";
7676
index __INDEX__;
7777
78-
# Reverse Proxy (-r)
78+
# Reverse Proxy (-r http(s)://ADDR:PORT)
7979
rproxy: |
80-
# Define the vhost to reverse proxy
80+
# Define Reverse Proxy
8181
location __LOCATION__ {
82-
proxy_set_header Host $host;
83-
proxy_set_header X-Real-IP $remote_addr;
82+
# https://stackoverflow.com/a/72586833
83+
proxy_set_header Host $host;
84+
proxy_set_header X-Real-IP $remote_addr;
85+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
86+
# Proxy connection
87+
proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__;
88+
}
89+
90+
# Reverse Proxy with websocket support (-r ws(s)://ADDR:PORT)
91+
rproxy_ws: |
92+
# Define Reverse Proxy with Websock support
93+
location __LOCATION__ {
94+
# https://stackoverflow.com/a/72586833
95+
proxy_set_header Host $host;
96+
proxy_set_header X-Real-IP $remote_addr;
97+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
98+
# Websocket settings
99+
proxy_http_version 1.1;
100+
proxy_set_header Upgrade $http_upgrade;
101+
proxy_set_header Connection "Upgrade";
102+
# Proxy connection
84103
proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__;
85104
}
86105

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
setup(
88
name="vhost-gen",
9-
version="1.0.8",
9+
version="1.0.9",
1010
description="Configurable vHost generator for Apache 2.2, Apache 2.4 and Nginx.",
1111
license="MIT",
1212
long_description=long_description,

0 commit comments

Comments
 (0)