System Hardening Guidelines (A.14.2.5)
This document describes the general principles Breezy uses to harden its systems against malicious attacks. It is intended to provide broad guidance for system implementers with specific recommendations where appropriate.
This policy covers all public-facing systems and all critical internal systems used to facilitate product offerings from Breezy HR.
Amazon Web Services (AWS) is the only approved hosting provider for Breezy Software products within the scope of this policy. All sensitive customer data must remain on-premises in AWS data centers. AWS and Breezy have a Shared Responsibility Model of security, as explained by AWS in their online documentation. In summary, AWS is responsible for the security “of the cloud” (i.e., the services it provides) while Breezy is responsible for the security “in the cloud” (i.e., selecting and configuring AWS services, servers, etc.).
Systems should be defined using “Infrastructure as Code” tooling where practical. Specifically, AWS configuration should be defined in CloudFormation (legacy). Server configuration should be defined in Ansible, BASH Script, or Systems Manager State Manager. When appropriate, changes to this code should undergo peer review as per the change management policy before being applied.
Alerts from security monitoring services, such as Inspector, Shield, WAF, GuardDuty, or Config, are surfaced in an employee-visible manner. Depending on severity, alerts may be sent to email, IM (Slack), or by paging (SMS via SNS).
AWS access must be configured to require multi-factor authentication (MFA) both for the root account and any individual AWS IAM users.
Every AWS account must be joined into the LTG Enterprise AWS Organization. In addition, each account should have IAM roles allowing Enterprise Support and Billing Support to have limited read-only access for support purposes. Read-only access should be restricted to non-sensitive data. In particular, Support must not have the IAM permission s3:GetObject except for buckets specific to Support.
The following AWS services must be enabled in all relevant regions:
- CloudTrail, AWS’s audit logging service
- GuardDuty, which performs network intrusion detection and anomaly alerting for CloudTrail logs
- Config, which checks AWS configuration against known baselines
- Security Hub with the CIS Benchmark suite enabled, which allows us to measure CIS benchmark compliance
CloudTrail logs must be retained for at least two years, ideally in multiple regions.
Since customer data remains within AWS, the scope of networking guidelines is specific to AWS.
The security of the physical networking equipment is managed by AWS per the Shared Responsibility principle.
Changes made to networking configuration are recorded by AWS CloudTrail. These changes are archived for later analysis, if need be, in addition to being analyzed both by GuardDuty and Inspector for suspicious activity.
Where allowed by AWS, systems should reside in an AWS Virtual Private Cloud (VPC), which is a software-defined network with an associated RFC 1918 private IP address block. Each VPC has its private address block divided into subnets, which can conceptually be either public (have direct internet access) or private (having no internet access or having internet access only through a Network Address Translation (NAT) gateway).
Systems not intended for direct access from the internet should be placed into private subnets where possible. Those systems will, therefore, not have an associated public IP address, and communicating with them directly from the internet is not possible without an initial outbound connection (tracked by the NAT gateway). In addition to firewalls, this provides an effective layer of security.
AWS provides firewalls for systems through its “security group” feature, in addition to other offerings. Every system in a VPC can be associated with multiple security groups, with the default state (having no associated security groups) being “DENY ALL.” Each security group can open a port and protocol to a specific IP address range.
No firewalls may have a rule accepting all traffic from any port/protocol from a public IP address (i.e., the internet). In other words, rules allowing traffic from public addresses must specify particular protocols and ports needed for a service to function, and no more. Rules restricted to a VPC’s internal IP address block, however, may open entire port ranges. Access to VPC internal networks must be facilitated through Breezy Software’s VPN service.
If a firewall rule allows incoming traffic from 0.0.0.0/0, in other words, with no restriction on incoming IP addresses, it must restrict traffic to TCP port 80 (HTTP), TCP port 443 (HTTPS), or UDP port 1194 (OpenVPN). Only web services or VPN servers may be exposed to the public internet without restriction. Specifically note, general public SSH access is banned by this policy.
SSH access should be restricted to the VPC’s internal network, accessible via VPN. In rare cases, if necessary, firewall rules allowing SSH access from a specific public IP address, like an employee’s home network, may be temporarily added—for example, to allow initial configuration of a VPN server for later use. These rules should be labeled in a manner like “<name> Temp Home SSH” for easy identification.
Most servers should not be accessible directly from the internet. When possible, internet-facing traffic should be directed into AWS-managed services, like CloudFront or load balancers, instead of exposing Breezy servers to the internet itself, even if those AWS-managed services will subsequently communicate with Breezy-managed servers.
Network intrusion detection, including analysis of VPC flow logs and DNS requests, is performed by AWS GuardDuty.
All servers must be hosted in Amazon Web Services. In most cases, this means full VMs on Amazon EC2 instances. However, it’s also acceptable to use AWS’s other serverless managed offerings, such as Lambda.
Breezy’s operating system of choice is the Ubuntu distribution of Linux, specifically any of the Long-Term Support (LTS) releases still receiving public maintenance patches from Canonical. Operating system versions must be upgraded at least three months prior to public maintenance patches being discontinued for the version. Other operating systems may be used for internal testing but are banned from processing any sensitive data.
Systems should be configured to ship relevant log files to a central log service where possible. For EC2 servers, this includes the system journal, any application log files, and the operating system authentication log. For lambda functions, the default AWS setup (CloudWatch Logs) is considered sufficient by this document.
For cases where Breezy manages the underlying operating system (OS), for example for in-scope EC2 instances (servers), the following policies apply:
- The OS must have a baseline set of services configured:
- ~NTP to ensure servers have the correct date and time configured
- ~Inspector for vulnerability management and intrusion detection
- Direct access to the root account on the system must be disabled, typically achieved by letting the normal EC2 startup process randomize the password. As a result, “sudo” is the only mechanism available to elevate normal users to root.
- When possible, servers should be logically single purpose.
- SSH access for the root user must be disabled. SSH access for other users is allowable (so long as it’s not open to the public, per the networking policy above), but other users must not solely use password-based authentication. Purely key- or certificate-based SSH authentication is recommended.
- Unattended automatic upgrade services on critical production systems should be either configured to not automatically restart the machine or any of its attendant services, or the unattended upgrade daemon should be disabled. While unfortunate, automated restarts represent a threat to availability; restarts must be managed in a more intelligent fashion.
- As noted above, systems must ship relevant or important log files to a central location for storage and analysis.
- Any unnecessary OS services should be disabled. For example, if the server doesn’t need Apache httpd to perform whatever role it has, then Apache httpd should be disabled or ideally not installed at all.
- Per the guideline above, server configuration should be written as code in Ansible and follow the documented Change Management Policy.
System implementers are responsible for following these guidelines. Operations staff may implement technical controls to verify or check certain guidelines continuously or periodically.