xrdp and the ulimits / nofile issue

You might have noticed for xrdp on Debian (but quite possibly with a lot of other Linux tools and other Linux distributions) the user limits (described in /etc/security/limits.conf) are not enforced. Which meant in my case that any session open with xrdp was opened with a max number of open files (nofile) set to 1024.

To fix this, edit the file /etc/pam.d/common-session and add the following line:

session    required   pam_limits.so

Limiting number of connections per IP with ufw

This is a personal reminder post.

The easiest attack one can perform on a web server is opening all the connections and do nothing with it. iptables fortunately has a “connlimit” module to avoid this. If you’re using ufw like me you will want to keep your good integration with it.

In the /etc/ufw/before.rules file, after these lines:

1
2
3
4
5
6
7
# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines

You can add this to limit the number of concurrent connections:

1
2
# Limit to 10 concurrent connections on port 80 per IP
-A ufw-before-input -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 -j DROP

And this to limit the number of connections:

1
2
3
# Limit to 20 connections on port 80 per 2 seconds per IP
-A ufw-before-input -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set
-A ufw-before-input -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 2 --hitcount 20 -j DROP

This second rules might create some issues with http clients that don’t support keep-alive (is there any?).
If you want to do some benchmarks (with ApacheBench for example), you need to enable the keep-alive and set the max number of keep-alive requests per connection very high (or unlimited).
In apache config it is set with:

1
MaxKeepAliveRequests 0

Cassandra as registry

One of the biggest issue with distributed database is to find the right model to store your data. On a recent project, I decided to use a registry model.

The registry idea

The idea behind writing a registry is to have an easy way to both store and view data.

For a given device that has a {UUID} id:

  • I will access “/device/{UUID}/”.
  • Any properties will be stored in “/device/{UUID}/properties/“.
  • Deletion of the device will delete all the contents this device contains.

Classical column-families to index data

The problem comes with the data we need to index. We can store everything in a registry manner like having a path “/device/by-owner/{UUID}”:[“{UUID1}”,”{UUID2}”]. But it’s just easier to use cassandra secondary indexes have each property of each entity written to the indexed columns of the column family.

Sample use case: file storage

So you get the basic “Registry” model. Storing file on top of that is quite easy. Then what I did is I just said files are chunks of data. So if I want to store a picture for a user, I could store like this:

  • “/user/{UUID}/picture/” becomes the path of the picture.
  • “/user/{UUID}/picture/type” describes the type of this file (“file” or “directory”)
  • “/user/{UUID}/picture/filetype” describes the content of this tile (“text/plain” per example)
  • “/user/{UUID}/picture/size” describes the size of the file
  • “/user/{UUID}/picture/chunk-size” describes the size of each chunk that we will save
  • Then we will save each chunk from “/user/{UUID}/picture/0” to /user/{UUID}/picture/X.

Hector object mapper

I have to say I didn’t know this project existed not that long ago.

I think HOM is a much better option in pretty much all the cases. Still having a simple tree view of your data can be a very interesting feature to analyze what you are working on.