Security Considerations
Introduction
This section covers topics related to protecting L7|ESP from accidental or malicious access and provides recommendations on overall security.
Ports and Protocols
The following ports should be opened between hardware and/or software firewalls between load balancer, application and database servers. (For example, security group rules and/or network ACLs in an AWS cloud-hosted environment, or firewalld
software firewall on RedHat VMs, etc).
L7|ESP Required Ports and Protocols
Protocol | Port Range | Purpose | Used By |
---|---|---|---|
TCP | 443 | Between Users and Load Balancer | HTTPS |
TCP | 8002 | Between Application and Load Balancer | L7|ESP |
TCP | 5432 | Between Application and Database Server | PostgreSQL |
Key-based SSH access should also be configured for remote system administration on a port of your choosing (default is TCP 22). This will be required for initial software installation and occasional content deployments, but is not otherwise required for a functional L7|ESP system.
Accepting HTTPS traffic
To accept secure traffic, it is expected that the L7|ESP application will sit behind a TLS termination proxy. L7|ESP itself does not perform SSL offloading but provides some common configuration options you might expect from a typical web application in this regard.
There many are software options for performing SSL offloading, most advertise themselves as web servers, reverse proxies, load balancers, HTTPS front-ends, and similar terms. Popular options include HAProxy, Nginx, Apache but there are countless others such as, Caddy, Varnish, Pound, etc.
In a cloud setting, such as AWS, it is recommended to use one of the provided services if possible so you have one less component to maintain. For example, Amazon can perform SSL offloading on their load balancers (ELB/ALB) using certificates stored in ACM.
Referencing the illustration above, the load balancer would listen for HTTP traffic on ports 8002 and 443, and would have a DNS record associated with it so that users have a nice URL to use when visiting. In the following paragraphs, we will presume the DNS record is: l7esp.example.com.
Port 8002 is for HTTP traffic (ie. http://l7esp.example.com maps to l7esp.example.com:8002)
Port 443 is for HTTPS traffic (ie. https://l7esp.example.com maps to l7esp.example.com:443)
The HTTP endpoint should be configured to immediately redirect traffic to the HTTPS endpoint such that any insecure connections are converted to secure connections before the application may be accessed and users visiting l7esp.example.com without specifying the protocol will get the secure padlock icon.
Traffic to the HTTPS should be proxied to the L7|ESP application server behind the scenes. Assuming the DNS name of the L7|ESP application server is L7ESPAPPSRV, the proxy communication/HTTP traffic between l7esp.example.com:443 and L7ESPAPPSRV:8002 will be transparent and therefore unnoticed by the user.
While it is normally desirable to perform SSL offloading on another machine to alleviate the application server for the overhead of encrypting/decrypting HTTP traffic and security implications of store secure SSL certificates, it is certainly possible to install SSL offloading software directly to the application server.
Since L7|ESP is installed in Linux user-space and listens on user/registered ports, instead of system/well-known ports below 1024 that require root privileges, there is no chance of collision with HTTP software installed at the system-level (for example, using sudo apt-get/yum install haproxy).
This gives the administrator full ability to configure to surrounding system to their specific needs, if that includes installing SSL offloading or other software(s) onto the L7|ESP application server itself. Of course, this comes with extra maintenance overhead as that software will need configured separately from ESP.
If the administrator chooses this path, there will need to be some mechanism for providing the SSL offloading software with the required secure SSL certificates, but the L7|ESP listening port 8002 will no longer need exposed to the outside world as all traffic between that software and L7|ESP will be internal.
That said, it is still our suggestion that the activity of SSL offloading is performed outside the L7|ESP application where possible as it reduces the overall complexity of maintaining the L7|ESP application server.
L7|ESP Configuration
L7|ESP provides a number of configuration options that can be used to harden the application to your specific needs. The following sections will cover the most common security configuration options.
Web Server
-
web_server.blacklist
A list of strings that, when sent in POST requests to L7|ESP, will be rejected by the server and result in 500 errors. This is to prevent XSS (cross-site scripting) attacks. The default list is: [ ">", "<", "&", "`", "%3Cscript%3E"]. Normally, you won’t need to change this, however it has been known to block valid requests so you may find it is necessary to add or remove items to tune it accordingly.
-
web_server.domain
Used to configure the domain name where L7|ESP is hosted. You should set this to the DNS name of the server (e.g. esp.example.com) rather than localhost. If not set, the application will use localhost and http:// as the base URL. This is used for generating links in emails and other places where the application needs to refer to itself. See the web_server.high_security setting if you are using https:// (recommended).
-
web_server.https
Used to configure the Secure attribute of cookies set by the L7|ESP server. When set to true, the Secure attribute will be set on cookies, which will prevent the browser from sending them over HTTP. This is useful if you are running L7|ESP behind a proxy that terminates SSL connections. If you are running L7|ESP without encryption, you should set this to false (default).
-
web_server.log_level
While not specifically security-related, this setting can be used to tune the verbosity of the L7|ESP application logs. The default is INFO. Valid values are: DEBUG, INFO, WARN, ERROR, FATAL.
-
web_server.origin_whitelist
Used to whitelist the only allowed origin of requests to the L7|ESP application. If this list is non-empty, the L7|ESP application will reject any requests that do not have an Origin header that matches one of the entries in the list.
-
web_server.use_high_security
If set to true, this will prepend https:// to the web_server.domain to form the base URL for the application. This is useful if you are running L7|ESP behind a proxy that terminates SSL connections. If you are running L7|ESP without encryption, you should set this to false (default).
-
web_server.ip_address_validation
This setting is used to control whether or not L7|ESP will validate the IP address of the user when they log in. Not supported when users are logging in via SSO solution such as Keycloak.
-
web_server.ipware_header_precedence_order
The IP address of a user is detected by checking the following HTTP request headers by default: ['HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR' 'HTTP_CLIENT_IP' 'HTTP_X_REAL_IP' 'HTTP_X_FORWARDED' 'HTTP_X_CLUSTER_CLIENT_IP' 'HTTP_FORWARDED_FOR' 'HTTP_FORWARDED' 'HTTP_VIA' 'REMOTE_ADDR']. This setting allows you to define a different list of headers and the order to check them for the IP address of the user. L7|ESP will use the first matching header.
-
web_server.ipware_private_ip_prefix
You may customize the prefixes to indicate an IP address is private. IP addresses matching a predefined list of prefixes are considered private & are not publicly routable.
System
-
system.concurrent_gui_user_sessions
The maximum number of sessions a single user can have at a given time. This is to prevent a single user from logging into L7|ESP from multiple computers at the same time. The default is -1 which is unlimited.
-
system.concurrent_client_user_sessions
Same as above, however this is for non-GUI traffic - ie. Python scripts that use the L7|ESP API. The default is -1 which is unlimited.
-
system.concurrent_session_handling
How to handle sessions that exceed the above limits. Possible values reject to reject the new session with a “Too many sessions” message, or kick to log out the old session automatically. The default is reject.
Passwords
The following settings are available for configuring password requirements:
-
password.bcrypt_rounds
The number of rounds to use when hashing passwords. The default is 13. Increasing this number will make password cracking more difficult, but will also make login slower. The recommended value is 13.
-
password.disallow_overlap
Whether or not the password can contain you username or email address domain. The default is false.
-
password.expire_days
The number of days after which a user’s password will expire. The default is 0 which is never.
-
password.min_length
The minimum length of a password. Set to 0 (default) to disable.
-
password.require_digits
Whether or not to require digits in passwords. The default is false.
-
password.require_mixed_case
Wheter or not to require mixed case in passwords. The default is false.
-
password.require_special
Whether or not to require special characters in passwords. The default is false.
-
password.user_change_ok
Whether or not the user can change their own password. Possible values: never, notsso, always.
Brute force protection
-
customize.max_login_failures
The maximum number of failed login attempts before the user is locked out. The default is 3.
-
customize.max_login_failures_timeframe
The number of minutes to keep track of failed login attempts. The default is 5.
-
login_failures_notify.enabled
Whether to send notifications if brute force is detected. The default is false.
-
login_failures_notify.failure_threshold
The number of failed login attempts before a notification is sent. The default is 6.
-
login_failures_notify.notify_method
The method to use for sending notifications. The default is email. Possible values are email for SMTP, notification for L7|ESP system notification, or both.
OpenID (SSO)
-
openid.verify_ssl_server
This setting is used to control whether or not L7|ESP will verify the SSL certificate of the OpenID provider. This is useful if you are using a self-signed certificate for your OpenID provider. However, it is not recommended to disable this setting in production environments.