From b892da1b8998be1a6e79e4d25e322177928d0c6b Mon Sep 17 00:00:00 2001 From: uumas Date: Sun, 28 Jul 2024 17:45:50 +0300 Subject: [PATCH] vhost: support proxying to unix sockets --- roles/vhost/defaults/main.yaml | 1 + roles/vhost/meta/argument_specs.yaml | 75 +++++++++++++++++++++------- roles/vhost/tasks/caddy.yaml | 12 ++++- roles/vhost/tasks/main.yaml | 10 ++-- 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/roles/vhost/defaults/main.yaml b/roles/vhost/defaults/main.yaml index f372af1..14b0ea7 100644 --- a/roles/vhost/defaults/main.yaml +++ b/roles/vhost/defaults/main.yaml @@ -12,6 +12,7 @@ vhost_delete_headers: [] vhost_basicauth: false vhost_basicauth_users: {} +vhost_proxy_target_netproto: tcp vhost_proxy_target_protocol: http vhost_proxy_target_host: localhost vhost_proxy_delete_headers: [] diff --git a/roles/vhost/meta/argument_specs.yaml b/roles/vhost/meta/argument_specs.yaml index 46b5927..a060c44 100644 --- a/roles/vhost/meta/argument_specs.yaml +++ b/roles/vhost/meta/argument_specs.yaml @@ -62,23 +62,45 @@ argument_specs: required: false default: {} - vhost_proxy_target_port: - description: Port where to proxy requests to. Only applicable if vhost_type is reverse_proxy - type: int - required: "{{ vhost_state == 'present' and vhost_type == 'reverse_proxy' }}" - vhost_proxy_target_host: - description: Host where to proxy requests to. Only applicable if vhost_type is reverse_proxy + vhost_proxy_target_netproto: + description: + - Network protocol to use for proxy requests. + - Only applicable if vhost_type is reverse_proxy. type: str required: false - default: localhost + default: tcp + choices: + - tcp + - unix vhost_proxy_target_protocol: - description: Protocol to use for proxy requests. Only applicable if vhost_type is reverse_proxy + description: + - Transport protocol (scheme) to use for proxy requests. + - Only applicable if vhost_type is reverse_proxy. type: str required: false default: http choices: - http - https + vhost_proxy_target_host: + description: + - Host where to proxy requests to. + - Only applicable if vhost_type is reverse_proxy and vhost_proxy_target_netproto is tcp. + type: str + required: false + default: localhost + vhost_proxy_target_port: + description: + - Port where to proxy requests to. + - Only applicable if vhost_type is reverse_proxy and vhost_proxy_target_netproto is tcp. + type: int + required: "{{ vhost_state == 'present' and vhost_type == 'reverse_proxy' and vhost_proxy_target_netproto == 'tcp' }}" + vhost_proxy_target_socket: + description: + - Unix socket path to proxy requests to. + - Only applicable if vhost_type is reverse_proxy and vhost_proxy_target_netproto is unix. + type: str + required: "{{ vhost_state == 'present' and vhost_type == 'reverse_proxy' and vhost_proxy_target_netproto == 'unix' }}" vhost_proxy_delete_headers: description: List of headers to delete from proxied requests type: list @@ -158,24 +180,43 @@ argument_specs: type: dict default: "{{ vhost_basicauth_users }}" - proxy_target_port: - description: Port where to proxy requests to. Only applicable if type is reverse_proxy. - type: int - required: false - default: "{{ vhost_proxy_target_port if vhost_type == 'reverse_proxy' else 0 }}" - proxy_target_host: - description: Host where to proxy requests to. Only applicable if type is reverse_proxy + proxy_target_netproto: + description: + - Network protocol to use for proxy requests. + - Only applicable if type is reverse_proxy. type: str required: false - default: "{{ vhost_proxy_target_host }}" + default: "{{ vhost_proxy_target_netproto }}" + choices: + - tcp + - unix proxy_target_protocol: - description: Protocol to use for proxy requests. Only applicable if type is reverse_proxy + description: + - Transport protocol (scheme) to use for proxy requests. + - Only applicable if type is reverse_proxy. type: str required: false default: "{{ vhost_proxy_target_protocol }}" choices: - http - https + proxy_target_host: + description: Host where to proxy requests to. Only applicable if type is reverse_proxy + type: str + required: false + default: "{{ vhost_proxy_target_host }}" + proxy_target_port: + description: Port where to proxy requests to. Only applicable if type is reverse_proxy. + type: int + required: false + default: "{{ vhost_proxy_target_port if vhost_type == 'reverse_proxy' and vhost_proxy_target_netproto == 'tcp' else 0 }}" + proxy_target_socket: + description: + - Unix socket path to proxy requests to. + - Only applicable if type is reverse_proxy and proxy_target_netproto is unix. + type: str + required: false + default: "{{ vhost_proxy_target_socket if vhost_type == 'reverse_proxy' and vhost_proxy_target_netproto == 'unix' else '' }}" proxy_delete_headers: description: List of request headers to delete from proxied requests type: list diff --git a/roles/vhost/tasks/caddy.yaml b/roles/vhost/tasks/caddy.yaml index b08c390..01ce24c 100644 --- a/roles/vhost/tasks/caddy.yaml +++ b/roles/vhost/tasks/caddy.yaml @@ -22,10 +22,18 @@ } {% endif %} {% if location.type == 'reverse_proxy' %} - reverse_proxy {{ location.proxy_target_protocol }}://{{ location.proxy_target_host }}:{{ location.proxy_target_port }} { - {% if location.proxy_target_protocol == 'https' and location.proxy_target_host == 'localhost' %} + reverse_proxy { + {% if location.proxy_target_netproto == 'tcp' %} + to tcp/{{ location.proxy_target_host }}:{{ location.proxy_target_port }} + {% else %} + to unix/{{ location.proxy_target_socket }} + {% endif %} + {% if location.proxy_target_protocol == 'https' %} transport http { + tls + {% if location.proxy_target_host == 'localhost' %} tls_insecure_skip_verify + {% endif %} } {% endif %} } diff --git a/roles/vhost/tasks/main.yaml b/roles/vhost/tasks/main.yaml index 9078eea..fe4c3ad 100644 --- a/roles/vhost/tasks/main.yaml +++ b/roles/vhost/tasks/main.yaml @@ -30,9 +30,13 @@ 'basicauth': item.basicauth | default(vhost_basicauth), 'basicauth_users': item.basicauth_users | default(vhost_basicauth_users), - 'proxy_target_port': item.proxy_target_port | default(vhost_proxy_target_port if vhost_type == 'reverse_proxy' else ''), - 'proxy_target_host': item.proxy_target_host | default(vhost_proxy_target_host), + 'proxy_target_netproto': item.proxy_target_netproto | default(vhost_proxy_target_netproto), 'proxy_target_protocol': item.proxy_target_protocol | default(vhost_proxy_target_protocol), + 'proxy_target_host': item.proxy_target_host | default(vhost_proxy_target_host), + 'proxy_target_port': item.proxy_target_port | default(vhost_proxy_target_port if + vhost_type == 'reverse_proxy' and vhost_proxy_target_netproto == 'tcp' else ''), + 'proxy_target_socket': item.proxy_target_socket | default(vhost_proxy_target_socket if + vhost_type == 'reverse_proxy' and vhost_proxy_target_netproto == 'unix' else ''), 'proxy_delete_headers': item.proxy_delete_headers | default(vhost_proxy_delete_headers), 'redirect_target': item.redirect_target | default(vhost_redirect_target if vhost_type == 'redirect' else ''), @@ -45,5 +49,5 @@ loop: "{{ vhost_locations + [{'path': ''}] }}" - name: "Setup {{ vhost_id + ' vhost on ' + vhost_web_server }}" - ansible.builtin.include_tasks: "{{ vhost_web_server }}.yml" + ansible.builtin.include_tasks: "{{ vhost_web_server }}.yaml" when: vhost_web_server != 'none'