Previous blog posts demonstrated how remote control of Cumulus Linux ACLs can be used for DDoS mitigation and Large "Elephant" flow marking.
A more advanced version of the script is now available on GitHub:
https://github.com/pphaal/acl_server/
The new script adds the following features:
- It now runs as a daemon.
- Exceptions generated by cl-acltool are caught and handled
- Rules are compiled asynchronously, reducing response time of REST calls
- Updates are batched, supporting hundreds of operations per second
Fortunately, Cumulus Linux is a open Linux distribution that allows additional software components to be installed. Rather than being forced to add authentication and encryption to the script, it is possible to install additional software and leverage the capabilities of a mature web server such as Apache. The operational steps needed to secure access to Apache are well understood and the large Apache community ensures that security issues are quickly identified and addressed.
This article will demonstrate how Apache can be used to proxy REST operations for the acl_server script, allowing familiar Apache features to be applied to secure access to the ACL service.
Download the acl_server script from GitHub
wget https://raw.githubusercontent.com/pphaal/acl_server/master/acl_serverChange the following line to limit access to requests made by other processes on the switch:
server = HTTPServer(('',8080), ACLRequestHandler)Limiting access to localhost, 127.0.0.1:
server = HTTPServer(('127.0.0.1',8080), ACLRequestHandler)Next, install the script on the switch:
sudo mv acl_server /etc/init.d/ sudo chown root:root /etc/init.d/acl_server sudo chmod 755 /etc/init.d/acl_server sudo service acl_server start sudo update-rc.d acl_server startNow install Apache:
sudo sh -c "echo 'deb http://ftp.us.debian.org/debian wheezy main contrib' \ >>/etc/apt/sources.list.d/deb.list" sudo apt-get update sudo apt-get install apache2Next enable the Apache proxy module:
sudo a2enmod proxy proxy_httpCreate an Apache configuration file /etc/apache2/conf.d/acl_server with the following contents:
<ifmodule mod_proxy.c> ProxyRequests off ProxyVia off ProxyPass /acl/ http://127.0.0.1:8080/acl/ ProxyPassReverse /acl/ http://127.0.0.1:8080/acl/ </ifmodule>Make any additional changes to the Apache configuration to encrypt and authenticate requests.
Finally, restart Apache:
sudo service apache2 restartThese above steps are easily automated using tools like Puppet or Ansible that are available for Cumulus Linux.
The following examples demonstrate the REST API.
Create an ACL
curl -H "Content-Type:application/json" -X PUT --data '["[iptables]","-A FORWARD --in-interface swp+ -d 10.10.100.10 -p udp --sport 53 -j DROP"]' http://10.0.0.233/acl/ddos1ACLs are sent as a JSON encoded array of strings. Each string will be written as a line in a file stored under /etc/cumulus/acl/policy.d/ - See Cumulus Linux: Netfilter - ACLs. For example, the rule above will be written to the file 50rest-ddos1.rules with the following content:
[iptables] -A FORWARD --in-interface swp+ -d 10.10.100.10 -p udp --sport 53 -j DROPThis iptables rule blocks all traffic from UDP port 53 (DNS) to host 10.10.100.10. This is the type of rule that might be inserted to block a DNS amplification attack.
Retrieve an ACL
curl http://10.0.0.233/acl/ddos1Returns the result:
["[iptables]", "-A FORWARD --in-interface swp+ -d 10.10.100.10 -p udp --sport 53 -j DROP"]
List ACLs
curl http://10.0.0.233/acl/Returns the result:
["ddos1"]
Delete an ACL
curl -X DELETE http://10.0.0.233/acl/ddos1
Delete all ACLs
curl -X DELETE http://10.0.0.233/acl/Note this doesn't delete all the ACLs, just the ones created using the REST API. All default ACLs or manually created ACLs are inaccessible through the REST API.
The acl_server batches and compiles changes after the HTTP requests complete. Batching has the benefit of increasing throughput and reducing request latency, but makes it difficult to track compilation errors since they are reported later. The acl_server catches the output and status when running cl-acltool and attaches an HTTP Warning header to subsequent requests to indicate that the last compilation failed:
HTTP/1.0 204 No Content Server: BaseHTTP/0.3 Python/2.7.3 Date: Thu, 12 Feb 2015 05:31:06 GMT Accept: application/json Content-Type: application/json Warning: 199 - "check lasterror"The output of cl-acltool can be retrieved:
curl http://10.0.0.233/acl/lasterrorreturns the result:
{"returncode": 255, "lines": [...]}The REST API is intended to be used by automation systems and so syntax problems with the ACLs they generate should be rare and are the result of a software bug. A controller using this API should check responses for the presence of the last error Warning, log the lasterror information so that the problem can be debugged, and finally delete all the rules created through the REST API to restore the system to its default state.
While this REST API could be used as a convenient way to manually push an ACL to a switch, the API is intended to be part of automation solutions that combine real-time traffic analytics with automated control. Cumulus Linux includes standard sFlow measurement support, delivering real-time network wide visibility to drive solutions that include: DDoS mitigation, enforcing black lists, marking large flows, ECMP load balancing, packet brokers etc.
Awesome work as usual Peter. Happy Holidays!
ReplyDelete