Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.0.9 #51

Merged
merged 12 commits into from
Dec 27, 2022
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
[![pydoc](https://github.com/devilbox/vhost-gen/workflows/pydoc/badge.svg)](https://github.com/devilbox/vhost-gen/actions?query=workflow%3Apydoc)


**[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.
**[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.

---

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

#### Supported Features

* Document serving vHost or Reverse Proxy
* Document serving vHost or Reverse Proxy (with or w/o websocket support)
* Custom server name
* Custom document root
* Custom access log name
Expand Down Expand Up @@ -248,8 +248,9 @@ in /etc/vhost-gen/conf.yml

Required arguments:
-p|r <str> You need to choose one of the mutually exclusive arguments.
-p: Path to document root/
-p: Path to document root.
-r: http(s)://Host:Port for reverse proxy.
-r: ws(s)://Host:Port for reverse proxy with websocket support.
Depening on the choice, it will either generate a document serving
vhost or a reverse proxy vhost.
Note, when using -p, this can also have a suffix directory to be set
Expand Down
59 changes: 38 additions & 21 deletions bin/vhost-gen
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ if os.environ.get("MYPY_CHECK", False):
# --------------------------------------------------------------------------------------------------
APPNAME = "vhost-gen"
APPREPO = "https://github.com/devilbox/vhost-gen"
VERSION = "1.0.8"
RELDATE = "2022-12-22"
VERSION = "1.0.9"
RELDATE = "2022-12-27"

# Default paths
CONFIG_PATH = "/etc/vhost-gen/conf.yml"
Expand Down Expand Up @@ -115,8 +115,9 @@ in /etc/vhost-gen/conf.yml

Required arguments:
-p|r <str> You need to choose one of the mutually exclusive arguments.
-p: Path to document root/
-p: Path to document root.
-r: http(s)://Host:Port for reverse proxy.
-r: ws(s)://Host:Port for reverse proxy with websocket support.
Depening on the choice, it will either generate a document serving
vhost or a reverse proxy vhost.
Note, when using -p, this can also have a suffix directory to be set
Expand Down Expand Up @@ -349,15 +350,12 @@ def validate_args_req(name, docroot, proxy, mode, location, verbose):
sys.exit(1)

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

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

proxy_addr = match.group(1)
return str_replace(
template["vhost_type"]["rproxy"],
{
"__LOCATION__": location,
"__PROXY_PROTO__": re.sub("://.*$", "", proxy),
"__PROXY_ADDR__": proxy_addr,
"__PROXY_PORT__": re.sub("^.*:", "", proxy),
},
)
protocol = re.sub("://.*$", "", proxy) # Proxy protocol http(s) vs ws(s)

# ws == http and wss == https
proxy_prot = "http" if protocol in ("http", "ws") else "https"
wsock_prot = "ws" if protocol in ("http", "ws") else "wss"

# Websocket
if protocol in ("ws", "wss"):
return str_replace(
template["vhost_type"]["rproxy_ws"],
{
"__LOCATION__": location,
"__WS_PROTO__": wsock_prot,
"__PROXY_PROTO__": proxy_prot,
"__PROXY_ADDR__": proxy_addr,
"__PROXY_PORT__": re.sub("^.*:", "", proxy),
},
)
if protocol in ("http", "https"):
return str_replace(
template["vhost_type"]["rproxy"],
{
"__LOCATION__": location,
"__PROXY_PROTO__": proxy_prot,
"__PROXY_ADDR__": proxy_addr,
"__PROXY_PORT__": re.sub("^.*:", "", proxy),
},
)
return ""


Expand Down
59 changes: 48 additions & 11 deletions etc/templates/apache22.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,23 @@
# __PHP_PORT__
#

###
### Notes about Apache
###

#
# 1. Each same directive is checked in order of definition (last one wins)
# 2. Directives are ordered: Directory, DirectoryMatch, Files, and finally Location (last one wins)
# * Last match always takes precedence
#
# Exception: Directories, where shortest path is matched first
# Exception: ProxyPass and Alias first match and then stops

###
### Basic vHost skeleton
###
### Note: Reverse Proxy section must be last for Apache 2.2
###
vhost: |
<VirtualHost __DEFAULT_VHOST__:__PORT__>
ServerName __VHOST_NAME__
Expand All @@ -54,13 +67,13 @@ vhost: |
__REDIRECT__
__SSL__
__VHOST_DOCROOT__
__VHOST_RPROXY__
__PHP_FPM__
__ALIASES__
__DENIES__
__SERVER_STATUS__
# Custom directives
__CUSTOM__
__VHOST_RPROXY__
</VirtualHost>

###
Expand All @@ -84,15 +97,38 @@ vhost_type:
Allow from all
</Directory>

# Reverse Proxy (-r)
# Reverse Proxy (-r http(s)://ADDR:PORT)
rproxy: |
# Define the vhost to reverse proxy
ProxyRequests off
ProxyPass __LOCATION__ __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__
<location __LOCATION__>
ProxyPassReverse /
RequestHeader unset Accept-Encoding
</location>
# ProxyRequests: Disable "Forward Proxy"
# ProxyPreserveHost: Pass "Host" header to remote
# ProxyVia: Add "Via" header
ProxyRequests Off
ProxyPreserveHost On
ProxyVia On
<Location __LOCATION__>
# Reverse Proxy
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
</Location>

# Reverse Proxy with websocket support (-r ws(s)://ADDR:PORT)
rproxy_ws: |
# ProxyRequests: Disable "Forward Proxy"
# ProxyPreserveHost: Pass "Host" header to remote
# ProxyVia: Add "Via" header
ProxyRequests Off
ProxyPreserveHost On
ProxyVia On
<Location __LOCATION__>
# Websocket Rewrite Settings
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule ^/?(.*)$ __WS_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/$1 [P,L]
# Reverse Proxy
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
</Location>


###
Expand Down Expand Up @@ -122,6 +158,7 @@ features:
# Alias Definition
Alias "__ALIAS__" "__PATH____ALIAS__"
<Location "__ALIAS__">
ProxyPass !
__XDOMAIN_REQ__
</Location>
<Directory "__PATH____ALIAS__">
Expand All @@ -131,10 +168,10 @@ features:

deny: |
# Deny Definition
<FilesMatch "__REGEX__">
<LocationMatch "__REGEX__">
Order allow,deny
Deny from all
</FilesMatch>
</LocationMatch>

server_status: |
# Status Page
Expand Down
63 changes: 49 additions & 14 deletions etc/templates/apache24.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@
# __PHP_PORT__
#

###
### Notes about Apache
###

#
# 1. Each same directive is checked in order of definition (last one wins)
# 2. Directives are ordered: Directory, DirectoryMatch, Files, and finally Location (last one wins)
# * Last match always takes precedence
#
# Exception: Directories, where shortest path is matched first
# Exception: ProxyPass and Alias first match and then stops

###
### Basic vHost skeleton
Expand Down Expand Up @@ -86,19 +97,42 @@ vhost_type:
Require all granted
</Directory>

# Reverse Proxy (-r)
# Reverse Proxy (-r http(s)://ADDR:PORT)
rproxy: |
# Define the vhost to reverse proxy
ProxyRequests off
ProxyPass __LOCATION__ __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__
ProxyHTMLURLMap __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__ __LOCATION__
<location __LOCATION__>
ProxyPassReverse /
SetOutputFilter proxy-html
ProxyHTMLURLMap / __LOCATION__
ProxyHTMLURLMap __LOCATION__ __LOCATION__
RequestHeader unset Accept-Encoding
</location>
# ProxyRequests: Disable "Forward Proxy"
# ProxyPreserveHost: Pass "Host" header to remote
# ProxyAddHeaders: Add "X-Forward-*" headers
# ProxyVia: Add "Via" header
ProxyRequests Off
ProxyPreserveHost On
ProxyAddHeaders On
ProxyVia On
<Location __LOCATION__>
# Reverse Proxy
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
</Location>

# Reverse Proxy with websocket support (-r ws(s)://ADDR:PORT)
rproxy_ws: |
# ProxyRequests: Disable "Forward Proxy"
# ProxyPreserveHost: Pass "Host" header to remote
# ProxyAddHeaders: Add "X-Forward-*" headers
# ProxyVia: Add "Via" header
ProxyRequests Off
ProxyPreserveHost On
ProxyAddHeaders On
ProxyVia On
<Location __LOCATION__>
# Websocket Rewrite Settings
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule ^/?(.*)$ __WS_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/$1 [P,L]
# Reverse Proxy
ProxyPass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/ retry=0
ProxyPassReverse __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__/
</Location>


###
Expand Down Expand Up @@ -147,6 +181,7 @@ features:
# Alias Definition
Alias "__ALIAS__" "__PATH____ALIAS__"
<Location "__ALIAS__">
ProxyPass !
__XDOMAIN_REQ__
</Location>
<Directory "__PATH____ALIAS__">
Expand All @@ -157,10 +192,10 @@ features:

deny: |
# Deny Definition
<FilesMatch "__REGEX__">
<LocationMatch "__REGEX__">
Order allow,deny
Deny from all
</FilesMatch>
</LocationMatch>

server_status: |
# Status Page
Expand Down
27 changes: 23 additions & 4 deletions etc/templates/nginx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,31 @@ vhost_type:
root "__DOCUMENT_ROOT__";
index __INDEX__;

# Reverse Proxy (-r)
# Reverse Proxy (-r http(s)://ADDR:PORT)
rproxy: |
# Define the vhost to reverse proxy
# Define Reverse Proxy
location __LOCATION__ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# https://stackoverflow.com/a/72586833
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Proxy connection
proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__;
}

# Reverse Proxy with websocket support (-r ws(s)://ADDR:PORT)
rproxy_ws: |
# Define Reverse Proxy with Websock support
location __LOCATION__ {
# https://stackoverflow.com/a/72586833
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Websocket settings
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# Proxy connection
proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__;
}

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name="vhost-gen",
version="1.0.8",
version="1.0.9",
description="Configurable vHost generator for Apache 2.2, Apache 2.4 and Nginx.",
license="MIT",
long_description=long_description,
Expand Down