Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ The following modules are currently available:

* [pfsense_haproxy_frontend](docs/modules/pfsense_haproxy_frontend.md) - Manage HAProxy frontends
* [pfsense_haproxy_frontend_server](docs/modules/pfsense_haproxy_frontend_server.md) - Manage HAProxy frontend bind addresses
* [pfsense_haproxy_frontend_acl](docs/modules/pfsense_haproxy_frontend_acl.md) - Manage HAProxy frontend ACLs for SNI-based routing
* [pfsense_haproxy_frontend_action](docs/modules/pfsense_haproxy_frontend_action.md) - Manage HAProxy frontend actions

The modules assume that you have already installed the haproxy pfSense package.

Expand Down
94 changes: 94 additions & 0 deletions docs/modules/pfsense_haproxy_frontend_acl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# pfsense_haproxy_frontend_acl

Manage pfSense HAProxy frontend ACLs

## Synopsis

- Manage pfSense HAProxy frontend Access Control Lists (ACLs) for SNI-based routing.
- ACLs define conditions that can be used with actions to route traffic to different backends.

## Notes

- SNI-based ACLs require the frontend to be configured in 'https' or 'tcp' mode, not 'http'.

## Parameters

| Parameter | Type | Required | Default | Choices | Description |
|-----------|------|----------|---------|---------|-------------|
| frontend | str | yes | - | - | The frontend name to add the ACL to. |
| name | str | yes | - | - | The ACL name. This name is used to reference the ACL in actions. ACLs with the same name are combined using OR logic. |
| expression | str | yes | - | ssl_sni_matches, ssl_sni_contains, ssl_sni_starts_with, ssl_sni_ends_with, ssl_sni_regex | The ACL expression type for SNI matching. |
| value | str | yes | - | - | The value to match against (hostname, pattern, or regex). |
| casesensitive | bool | no | false | - | Enable case-sensitive matching. |
| negate | bool | no | false | - | Negate the match (match if condition is NOT met). |
| state | str | no | present | present, absent | State in which to leave the ACL. |

## Expression Types

| Expression | Description |
|------------|-------------|
| ssl_sni_matches | Exact match of the SNI hostname |
| ssl_sni_contains | SNI hostname contains the specified string |
| ssl_sni_starts_with | SNI hostname starts with the specified string |
| ssl_sni_ends_with | SNI hostname ends with the specified string |
| ssl_sni_regex | SNI hostname matches the specified regex pattern |

## Examples

```yaml
- name: Add ACL for exact SNI match
pfsensible.haproxy.pfsense_haproxy_frontend_acl:
frontend: sni-frontend
name: is_api
expression: ssl_sni_matches
value: api.example.com
state: present

- name: Add ACL for SNI ending with domain
pfsensible.haproxy.pfsense_haproxy_frontend_acl:
frontend: sni-frontend
name: is_example_domain
expression: ssl_sni_ends_with
value: .example.com
state: present

- name: Add case-sensitive ACL with regex
pfsensible.haproxy.pfsense_haproxy_frontend_acl:
frontend: sni-frontend
name: is_versioned_api
expression: ssl_sni_regex
value: "api-v[0-9]+\\.example\\.com"
casesensitive: true
state: present

- name: Add negated ACL (match if NOT internal)
pfsensible.haproxy.pfsense_haproxy_frontend_acl:
frontend: sni-frontend
name: not_internal
expression: ssl_sni_ends_with
value: .internal.local
negate: true
state: present

- name: Remove ACL
pfsensible.haproxy.pfsense_haproxy_frontend_acl:
frontend: sni-frontend
name: is_api
expression: ssl_sni_matches
value: api.example.com
state: absent
```

## Return Values

| Key | Type | Returned | Description | Sample |
|-----|------|----------|-------------|--------|
| commands | list | always | the set of commands that would be pushed to the remote device (if pfSense had a CLI) | `["create haproxy_frontend_acl 'is_api' on 'sni-frontend', expression='ssl_sni_matches', value='api.example.com'", "delete haproxy_frontend_acl 'is_api' on 'sni-frontend'"]` |

## Author

- Nicholas Morey (@morey-tech)

## Version

Added in version 0.3.0
143 changes: 143 additions & 0 deletions docs/modules/pfsense_haproxy_frontend_action.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# pfsense_haproxy_frontend_action

Manage pfSense HAProxy frontend actions

## Synopsis

- Manage pfSense HAProxy frontend actions for routing traffic based on ACL conditions.
- Actions define what happens when ACL conditions are met (e.g., route to a specific backend).

## Notes

- Actions reference ACLs by name. Create ACLs first using pfsense_haproxy_frontend_acl.
- Multiple ACL names can be specified (space-separated) to combine conditions with AND logic.

## Parameters

| Parameter | Type | Required | Default | Choices | Description |
|-----------|------|----------|---------|---------|-------------|
| frontend | str | yes | - | - | The frontend name to add the action to. |
| action | str | yes | - | use_backend, custom | The action type to perform. |
| backend | str | no* | - | - | The backend pool name to route traffic to. Required when action=use_backend. |
| acl | str | no | - | - | Space-separated list of ACL names that must match for this action to execute. Multiple ACLs are combined with AND logic. Leave empty for unconditional action (default route). |
| custom_action | str | no* | - | - | Custom HAProxy directive to execute. Required when action=custom. |
| state | str | no | present | present, absent | State in which to leave the action. |

## Action Types

| Action | Description |
|--------|-------------|
| use_backend | Route traffic to a specific backend pool |
| custom | Execute a custom HAProxy directive |

## Examples

```yaml
- name: Route traffic to api-backend when is_api ACL matches
pfsensible.haproxy.pfsense_haproxy_frontend_action:
frontend: sni-frontend
action: use_backend
backend: api-backend
acl: is_api
state: present

- name: Route traffic to web-backend when multiple ACLs match (AND logic)
pfsensible.haproxy.pfsense_haproxy_frontend_action:
frontend: sni-frontend
action: use_backend
backend: web-backend
acl: "is_web is_authenticated"
state: present

- name: Set default backend (no ACL condition)
pfsensible.haproxy.pfsense_haproxy_frontend_action:
frontend: sni-frontend
action: use_backend
backend: default-backend
state: present

- name: Add custom action
pfsensible.haproxy.pfsense_haproxy_frontend_action:
frontend: sni-frontend
action: custom
custom_action: "tcp-request content reject"
acl: is_blocked
state: present

- name: Remove action
pfsensible.haproxy.pfsense_haproxy_frontend_action:
frontend: sni-frontend
action: use_backend
backend: api-backend
acl: is_api
state: absent
```

## Complete SNI Routing Example

```yaml
# 1. Create HTTPS frontend (TCP mode for SNI routing)
- name: Create HTTPS frontend
pfsensible.haproxy.pfsense_haproxy_frontend:
name: sni-frontend
type: https
state: present

# 2. Add listener
- name: Add HTTPS listener
pfsensible.haproxy.pfsense_haproxy_frontend_server:
frontend: sni-frontend
extaddr: 0.0.0.0
extaddr_port: 443
state: present

# 3. Add ACL for api.example.com
- name: ACL for api domain
pfsensible.haproxy.pfsense_haproxy_frontend_acl:
frontend: sni-frontend
name: is_api
expression: ssl_sni_matches
value: api.example.com
state: present

# 4. Add ACL for web.example.com
- name: ACL for web domain
pfsensible.haproxy.pfsense_haproxy_frontend_acl:
frontend: sni-frontend
name: is_web
expression: ssl_sni_matches
value: web.example.com
state: present

# 5. Route api to api-backend
- name: Route api traffic
pfsensible.haproxy.pfsense_haproxy_frontend_action:
frontend: sni-frontend
action: use_backend
backend: api-backend
acl: is_api
state: present

# 6. Route web to web-backend
- name: Route web traffic
pfsensible.haproxy.pfsense_haproxy_frontend_action:
frontend: sni-frontend
action: use_backend
backend: web-backend
acl: is_web
state: present
```

## Return Values

| Key | Type | Returned | Description | Sample |
|-----|------|----------|-------------|--------|
| commands | list | always | the set of commands that would be pushed to the remote device (if pfSense had a CLI) | `["create haproxy_frontend_action 'is_api' -> 'api-backend' on 'sni-frontend', action='use_backend', backend='api-backend', acl='is_api'", "delete haproxy_frontend_action 'is_api' -> 'api-backend' on 'sni-frontend'"]` |

## Author

- Nicholas Morey (@morey-tech)

## Version

Added in version 0.3.0
Loading