Skip to content

Commit 1d15ead

Browse files
docs: add docs page on security hardening
1 parent fe83725 commit 1d15ead

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

docs/SECURING_API_ACCESS.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Securing API Access
2+
3+
In the age of network automation, APIs on network appliances unlocks incredible efficiency and potential, but it also
4+
can also create a high-stakes attack vector. Unlike standard web applications, a compromised firewall doesn't just leak
5+
data; it can grant attackers administrative control over your network's perimeter, allowing them to rewrite traffic rules
6+
and bypass your defenses entirely. The REST API package includes several built-in security features to help protect
7+
API access and ensure that only authorized users and systems can interact with your pfSense instances.
8+
9+
## Step 1: Follow Netgate's Best Practices for Remote Access
10+
11+
If you need access to the pfSense REST API from outside your local network, it is critical that you follow Netgate's
12+
[Allowing Remote Access to the GUI¶](https://docs.netgate.com/pfsense/en/latest/recipes/remote-firewall-administration.html)
13+
guide to ensure that your pfSense instance is properly secured against unauthorized access. This includes:
14+
15+
- Enabling HTTPS for the web GUI to encrypt traffic between clients and the pfSense instance.
16+
- Using a VPN to connect to your pfSense instance remotely, rather than exposing the web GUI directly to the internet.
17+
- Configuring strong firewall rules to restrict access to the webConfigurator.
18+
19+
## Step 2: Choose an Appropriate Authentication Method
20+
21+
The authentication method you choose for API access will depend on your specific use case and security requirements
22+
for your environment. The pfSense REST API package supports several different authentication methods, and allows
23+
multiple methods to be enabled simultaneously. The three main authentication methods supported are:
24+
25+
### Basic Authentication (Local Database)
26+
27+
[Basic authentication](AUTHENTICATION_AND_AUTHORIZATION.md#basic-authentication-local-database) allows you to authenticate
28+
with the same username and password you use to log into the pfSense web GUI. This method is the default authentication
29+
method for the REST API package as it allows for out-of-the-box functionality without any additional configuration.
30+
However, basic authentication is less secure than other methods and should only be used in trusted environments and
31+
over secure connections (e.g., HTTPS or VPN).
32+
33+
**Pros**:
34+
35+
- Easy to set up and use.
36+
- No additional configuration required.
37+
38+
**Cons**:
39+
40+
- Less secure than other methods.
41+
- Credentials are sent with each request, increasing the risk of interception, especially if not using HTTPS.
42+
- Credentials may also allow web GUI and/or SSH access, which may not be desirable for API-only users.
43+
44+
### JWT Authentication
45+
46+
[JWT authentication](AUTHENTICATION_AND_AUTHORIZATION.md#json-web-token-jwt-authentication) allows you to authenticate
47+
using JSON Web Tokens. These are short-lived, digitially signed tokens that can be used to authenticate API requests without
48+
sending a username and password with each request. JWT authentication is more secure than basic authentication and is
49+
recommended for production environments who need session-based or short-lived authentication. This is especially useful
50+
for front-end applications or scripts that need to make multiple API requests over a short period of time.
51+
52+
**Pros**:
53+
54+
- More secure than basic authentication.
55+
- Tokens can be short-lived, reducing the risk of compromise.
56+
- Tokens do not expose pfSense user credentials with each request.
57+
58+
**Cons**:
59+
60+
- Requires additional configuration to set up.
61+
- Tokens need to be refreshed before they expire.
62+
63+
### Key Authentication
64+
65+
[Key authentication](AUTHENTICATION_AND_AUTHORIZATION.md#api-key-authentication) allows you to authenticate using
66+
dedicated API keys. These keys are created specifically for API access and never require a username or password to
67+
be sent with requests. Key authentication is the most secure method and is recommended for production environments
68+
where security is a top priority. This method is especially useful for automated systems or services that need to
69+
make API requests without human intervention.
70+
71+
**Pros**:
72+
73+
- Most secure authentication method.
74+
- API keys can be easily revoked or rotated without affecting user accounts.
75+
- Does not expose pfSense user credentials with requests.
76+
- Supports configurable key-lengths and hashing algorithms for purpose-specific security needs.
77+
78+
**Cons**:
79+
80+
- Requires additional configuration to set up.
81+
- API keys need to be securely stored and managed.
82+
83+
## Step 4: Use API-specific user accounts
84+
85+
Regardless of the authentication method you choose, the REST API package uses pfSense's built-in privilege system to
86+
control access to API endpoints. This means that all credentials used for API access must belong to a pfSense user account
87+
who has been granted the appropriate API privileges. Each endpoint has its own privileges for each HTTP method supported
88+
by that endpoint. It is highly recommended that you create dedicated user accounts specifically for API access, rather
89+
than using existing user accounts that may have broader access. This helps to limit the potential impact of a
90+
compromised account and allows for better tracking of API activity. It is also highly recommended to follow the principle
91+
of least privilege when assigning API privileges to user accounts. Only grant the minimum privileges necessary for the
92+
intended use case.
93+
94+
!!! Warning
95+
The `page-all` privilege grants unrestricted access to all API endpoints and methods. Avoid assigning this privilege
96+
to user accounts unless absolutely necessary, as it significantly increases the risk of unauthorized access and
97+
potential misuse of the API.
98+
99+
## Step 4: Restrict API access to specific interfaces
100+
101+
By default, the pfSense REST API package allows requests received on any interface IP to respond to API requests. However,
102+
you can restrict the API to only respond to requests received on specific interfaces if desired. This can help limit the
103+
exposure of the API to only trusted networks or systems beyond just setting firewall rules. To configure which
104+
interfaces the API will respond to, navigate to `System` > `REST API` > `Settings` > `Allowed Interfaces` and select
105+
the desired interfaces.
106+
107+
!!! Warning
108+
This setting is not a replacement for proper firewall rules. This setting should be used in addition to firewall rules
109+
to provide a layered approach to security. Ensure that you have proper firewall rules in place to restrict access to the API
110+
to only trusted networks or systems, then ensure the API is configured to only respond on those same interfaces.
111+
112+
## Step 5: Configure API access lists
113+
114+
The REST API package includes an API access list feature that allows you to restrict API access based on source IP,
115+
network, time-of-day, and/or user. This provides an additional layer of security by allowing you to define specific rules for who
116+
can access the API, when they can access it, and from where. To configure API access lists, navigate to `System` > `REST API` >
117+
`Access Lists` and create the desired access list rules. When designing your access list rules, consider the following best practices:
118+
119+
- Only allow IPs you trust and have a legitimate use case for accessing the API.
120+
- Only allow the relevant users to access the API from their respective IPs or networks.
121+
- If possible, configure and apply a schedule to apply to the access list rules to limit access to only when necessary.
122+
123+
!!! Warning
124+
This access control list is not a replacement for proper firewall rules. This setting should be used in addition to
125+
firewall rules to provide a layered approach to security. Ensure that you have proper firewall rules in place to
126+
restrict access to the API to only trusted networks or systems, then use the access list to further restrict access
127+
based on your specific requirements.
128+
129+
## Step 6: Update Regularly
130+
131+
Ensure that you are running the latest version of the pfSense REST API package to benefit from the latest security
132+
patches and features. Regularly check for updates and apply them as soon as possible to minimize the risk of vulnerabilities.
133+
134+
!!! Tip
135+
If you are using Prometheus for monitoring in your environment, consider using the [official pfREST Prometheus exporter](https://github.com/pfrest/pfsense_exporter)
136+
to monitor for outdated pfSense REST API package versions across your fleet of pfSense instances!

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ nav:
1313
- Working with HATEOAS: WORKING_WITH_HATEOAS.md
1414
- Common Control Parameters: COMMON_CONTROL_PARAMETERS.md
1515
- GraphQL: GRAPHQL.md
16+
- Securing API Access: SECURING_API_ACCESS.md
1617
- Limitations & FAQs: LIMITATIONS_AND_FAQS.md
1718
- API Reference: https://pfrest.org/api-docs/
1819
- Advanced Topics:

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/RESTAPIAccessListEntry.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class RESTAPIAccessListEntry extends Model {
5959
allow_empty: true,
6060
many: true,
6161
many_minimum: 0,
62-
help_text: 'The users that this entry applies to. Only users in this list will be affected by this entry.',
62+
help_text: 'The users that this entry applies to. Only users in this list will be affected by this ' .
63+
'entry. Leave empty if this entry should apply to all users.',
6364
);
6465
$this->sched = new ForeignModelField(
6566
model_name: 'FirewallSchedule',

0 commit comments

Comments
 (0)