Hardening your MAAS installation
As a MAAS administrator, you have the important responsibilty of hardening your installation to help repudiate attacks and malicious actors. While there are too many variables to make meaningful suggestions for your deployed machines, there are a number of steps you can take to improve the overall security of your MASS setup. This article provides a few suggestions.
Quick questions you may have:
- How do I setup a firewall for MAAS?
- How do I configure a TLS-terminating load balancer (and what’s the impact on my MAAS setup?)
- How do I use logs to identify security issues?
- How do I implement PostgreSQL security?
- What else can I do to harden MAAS?
- Whom do I contact for MAAS security consulting?
Use a firewall
Each rack controller must be able to initiate TCP connections on the following ports:
||HTTP communication with each region controller. Note that port
||Reserved for internal MAAS services.|
||Reserved for rack HTTP communication.|
||Reserved for region workers (RPC).|
Consider setting your firewall (external link) on your rack and region controllers to disallow communication on all ports except those used by MAAS. For example, assuming you have installed
ufw, you could execute:
sudo ufw enable sudo ufw default deny incoming
You could then follow that with commands similar to these:
sudo ufw allow 5240 sudo ufw allow 5248 sudo ufw allow 5241:5247/tcp sudo ufw allow 5241:5247/udp sudo ufw allow 5250:5270/tcp sudo ufw allow 5250:5270/udp
Recognize that your particular configuration and version may vary, so consult the appropriate firewall manual pages for your specific MAAS host system.
Configure a TLS-terminating load balancer
One of the best steps you can take to improve both security and availability of your MAAS installation is to install TLS-terminating load balancer. For MAAS, we recommend using HAProxy (external link). This section explains how to set one up.
What is a TLS-terminated load balancer?
In the context of MAAS, a load balancer (external link) distributes the incoming Web UI and API requests across multiple region controllers. This reduces both load on MAAS and wait times for user requests. Typically, this is known as a high-availability (HA) configuration, although there are two other HA configurations that can be enabled for MAAS: one for BMC access (for powering on machines), and one for DHCP, which enables primary and secondary DHCP instances that manage the same VLAN.
A TLS-terminated load balancer is a load balancer that carries encryption and decryption as far down the pipe as possible, in this case, all the way to the load balancer itself. Note that, even though the “SSL” keyword may be used to enable operation, the term SSL is considered obsolete. Hence we choose to use the term “TLS” instead, referring to Transport Layer Security.
TLS is meant to provide privacy and data integrity between two or more applications. Privacy is provided by symmetric cryptography (external link), based on a shared secret and uniquely-generated keys negotiated at the start of a session (during the TLS handshake (external link)). Identity of each app can be authenticated, though this feature can be optional. Authenticity of messages is ensured by using message authentication codes (external link) to detect tampering.
As a first step, you’ll need an SSL certificate (
mysite.com.crt) with a key pair (
mysite.com.key), combined into a PEM file:
cat mysite.com.crt mysite.com.key > mysite.com.pem sudo cp mysite.com.pem /etc/ssl/private/
Depending upon your chosen certificate authority, you may also need to copy your CA root certificate and one or more intermediate CA certificates into the same PEM file.
Install and configure HA proxy
To install HAProxy, execute the following commands:
sudo apt-get update sudo apt-get install haproxy
/etc/haproxy/haproxy.cfg as follows. In the
global section of the file, add this line:
maxconn <number of concurrent connections>
Be aware that there’s a balance between accepting many connections and overloading the API by trying to serve too many requests. Also, you should consider adding a line like this one to the same section:
This parameter configures the maximum size of temporary DHE keys that are generated.
Next, in the
defaults section, add the following lines under
option forwardfor option http-server-close
forwardfor tells HAProxy to add X-Forward-For headers to each request. The
http-server-close option reduces latency between HAProxy and your users by closing connections but maintaining a keep-alive.
Finally, you’ll set the frontend and backend parameters that define the connections between HAProxy and MAAS. For the frontend, you can set parameters this way:
frontend maas bind *:443 ssl crt /etc/ssl/private/mysite.com.pem reqadd X-Forwarded-Proto:\ https retries 3 option redispatch default_backend maas
This stanza defines a frontend name
maas; tells HAProxy to handle incoming traffic to port 443, providing SSL encryption, enabled by the certificates and keys you earlier concatenated into your PEM file; allows three retries and redispatch; and forwards these requests to
maas as the backend server, which is defined something like this:
backend maas timeout server 90s balance source hash-type consistent server localhost localhost:5240 check server maas-api-1 <ip-address-of-a-region-controller>:5240 check server maas-api-2 <ip-address-of-another-region-controller>:5240 check
This stanza defines a backend server group named
maas; sets consistent hashing, 90 second timeout, and balanced sources; sets the server address and port (
localhost:5240); and engages two region controllers, named
maas-api-2. Note that the “1” and “2” designations are completely arbitrary, as there is no sense of “primary” or “secondary” associated with this configuration.
Finally, restart the (already-running) load balancer so that these changes can take effect and the HAProxy will begin to forward requests:
sudo systemctl restart haproxy
Note that you can also enable HAProxy logging (external link) if desired. This logging is an optional feature of the HAProxy tool and is thus left to your discretion.
Use logs to identify security issues
There are four categories of log files that you can use to help identify security issues:
- firewall logs
- Web server logs
- MAAS log files
- system log files
This section will offer some advice, as well as links to more detailed infromation on these categories.
The Ubuntu firewall, UFW (external link), is a front-end for iptables (external link), so the UFW log output is very similar to what you’ll encounter in iptables itself. If you want to secure your MAAS installation, it’s very important to periodically review your UFW logs, found in
Learning to recognize issues in the UFW/iptables log is an art form, so we’re not going to give an extended tutorial here. Still, there are some key indicators that might help you spot security issues.
You might look for something probing a port that’s not supporting an application service. Attackers use port scanners to look for openings. You might see entries like these:
blocked incoming tcp connection request from 184.108.40.206:8240 to 220.127.116.11:6002 blocked incoming tcp connection request from 18.104.22.168:8240 to 22.214.171.124:6003 blocked incoming tcp connection request from 126.96.36.199:8240 to 188.8.131.52:6004
You can also compare attempts on unusual port numbers against well-known hacker tools (external link). For instance, repeated attempts against port 12361 might mean that someone is attempting to attack with the Whack-a-mole exploit.
Also suspicious are repeated, unsuccessful access attempts, against the same port or service, from the same domain, IP address, or subnet. These attempts may be spread out in time (
grep is your friend, here). For example, a group of login attempts that look like this may indicate that an attacker is trying to disguise port scans by switching IP addresses within a block of addresses available to them:
blocked incoming tcp connection request from 184.108.40.206:49343 to 220.127.116.11:31337 blocked incoming tcp connection request from 18.104.22.168:49343 to 22.214.171.124:31337 blocked incoming tcp connection request from 126.96.36.199:49343 to 188.8.131.52:31337 blocked incoming tcp connection request from 184.108.40.206:49343 to 220.127.116.11:31337 . . . blocked incoming tcp connection request from 18.104.22.168:49343 to 22.214.171.124:31337
Watch out for suspicious messages or connections originating inside your network, which may indicate that you have a Trojan residing inside your UFW:
blocked outgoing tcp packet from 192.168.23.100:5240 to 126.96.36.199:443 as FIN:ACK received, but there is no active connection.
This message will usually be repeated a number of times, since Trojans are fairly persistent.
Look for source-routed packets, that is, packets with a source address internal to your network, but which originate from outside your network, indicating that someone is trying to spoof one of your internal addresses.
Review the IP addresses that are being rejected and dropped. Try to identify them with a
ping -a <IP address>. Spoofed addresses won’t have an owner (and you can block them). Real addresses have a whois (external link) entry, so it’s possible you can contact the ISP to report and resolve this issue.
There are many other firewall log analysis techniques, and a number of good open-source and commercial log analysis programs. If you decide to analyze directly, though, you’re basically looking for blocked connection issues, connections to (potentially) open ports you’re not using, and suspicious-looking outbound connections.
Web server logs
Detecting malicious activity directed toward your Web server is best done with a log analysis tool. If you want to review the raw logs directly, you can look for them in:
/var/log/apache2(in the case of Apache), or
the path given in
/etc/nginx/nginx.confor given in your site configuration file, which itself is found at the path
/etc/nginx/sites-available(in the case of nginx – look for the
Web server log analysis is also an art form, so we don’t plan to offer a comprehensive tutorial here, but here are few examples of things to look for in your logs:
multiple requests in less than one second, or some other appropriate timeframe.
multiple secure/login page accesses in a one-minute window, especially when they fail.
attempts to access non-existent pages using different paths or query parameters (e.g.,
look out for SQL injection attacks, for example:
188.8.131.52- - [14/Apr/2016:08:22:13 0100]
AND (SELECT 6810 FROM(SELECT COUNT(*),CONCAT(0x7171787671,(SELECT
INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) HTTP/1.1” 200 166 “-” “Mozilla/5.0
(Windows; U; Windows NT 6.1; ru; rv:184.108.40.206) Gecko/20100401 Firefox/4.0 (.NET CLR
attempts to run a Web shell, for instance:
192.168.1.102 29/Oct/2018:14:52:16 GET /b374k.php HTTP/1.1 200 2125 Mozilla/5.0
As mentioned above, there are a large number of Web server exploits, and this document does not propose to enumerate them all. If you want to ensure secure operation, though, it’s useful to familiarise yourself with these kinds of Web server attacks.
MAAS log files
Presently, your primary use of MAAS log files to improve security is to periodically check log files for login failures. You can check for this activity in the
regiond.log file. For reference, a valid login request looks like this entry:
2020-03-31 21:17:56 regiond: [info] 10.132.172.1 GET /MAAS/accounts/login/ HTTP/1.1 --> 200 OK (referrer: http://10.132.172.231:5240/MAAS/r/; agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36)````
If a login fails due to bad input (username/password), the regiond log will contain an entry something like this one:
2020-03-31 21:18:08 regiond: [info] 10.132.172.1 POST /MAAS/accounts/login/ HTTP/1.1 --> 400 BAD_REQUEST (referrer: http://10.132.172.231:5240/MAAS/r/; agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36)````
An entry like this one would also be suspect, since it involves omitting username/password entries at the login prompt:
2020-03-31 21:18:45 regiond: [info] 10.132.172.1 POST /MAAS/accounts/login/ HTTP/1.1 --> 204 NO_CONTENT (referrer: http://10.132.172.231:5240/MAAS/r/; agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36)````
The key differentiator to distinguish problems from routine failures is the frequency. If you notice a lot of these last two entries in a given period of time, you may want to investigate more thoroughly.
System log files
You can also use the standard system logs to detect malicious activity, though this subject is largely beyond the scope of this document. As a simple example, consider using
journalctl to detect and source an SSH brute force attack:
[root@maasserver ~]# journalctl -u sshd | grep "Failed password" Jun 06 13:45:19 router sshd: Failed password for root from 220.127.116.11 port 42258 ssh2 Jun 06 13:45:24 router sshd: Failed password for root from 18.104.22.168 port 42258 ssh2 Jun 06 13:45:35 router sshd: Failed password for root from 22.214.171.124 port 38834 ssh2 Jun 06 13:45:48 router sshd: Failed password for root from 126.96.36.199 port 35444 ssh2
From here, you can either use
whois to locate the attacker and work with the ISP to block them, or simply use your UFW firewall to block them directly.
As mentioned, this subject is far too complex for a detailed tutorial in this section. For more information, try the Ubuntu journalctl manpage (external link) or another, similar source (external link).
Implement PostgreSQL security
PostgreSQL contains secrets, and should be encrypted for maximum protection. You should consider full disk encryption (external link). Also recommended is TLS encryption between MAAS and PostgreSQL (external link).
Other things you can do to harden MAAS
In addition to the items mentioned above, you should be aware of a few other points about hardening MAAS.
You should pick good passwords and store them securely (e.g. in a KeePassX password database). Perform user administration only via the web UI. Only share the
root user passwords with administrators.
MAAS configuration files should be set to have permission
640: readable by logins belonging to the
maas group and writeable only by the
root user. Currently, the
regiond.conf file contains the login credentials for the PostgreSQL database used by MAAS to keep track of all machines, networks, and configuration.
chmod 640 /etc/maas/rackd.conf chmod 640 /etc/maas/regiond.conf
-rw-r----- 1 root maas 90 Sep 27 14:13 rackd.conf -rw-r----- 1 root maas 157 Sep 27 14:14 regiond.conf
When you add a new rack or region controller, MAAS asks for a shared secret it will use to communicate with the rest of MAAS. This secret is also exposed in the web UI when you click the ‘Add rack controller’ button on the Controllers page. MAAS automatically generates this secret when your first region controller installed, and stores the secret in a plain text file. This file is automatically protected with the correct permissions, so there is no need for any action on your part.
About snap security
Since snaps are fully confined or “sandboxed,” they bring a lot of inherent security to the contained application. More detailed information can be found in this snap blog (external link).
Whom to contact about MAAS security consulting
If you need help implementing MAAS security, please contact us (external link). We will be happy to assist you in arranging security consulting appropriate to your needs.