Wednesday, September 24, 2014

Unprivileged servers over standard ports on the Raspberry Pi

Sometimes you want to be able to run network services on standard ports, but as unprivileged users. I encountered this while attempting to configure my Raspberry Pi as an easy-to-use checkers game server. The following describes how I used port forwarding via iptables to achieve this.

I wanted users to be able to access a HTML5 checkers game client simply by entering just the host name of the server into a web browser, and not hostname:port-number. This meant I needed my nodejs server to accept and serve connections on TCP port 80. However, code running as unprivileged users can only bind to ports above 1024. Rather than running the nodejs server as a privileged user, and opening the server up to more security vulnerabilities, I decided to use iptables to redirect traffic from the standard port (80) to my non-standard one (3000).

To do this on the pi, you need to:
  • Add the following to the bottom of /etc/network/interfaces:
  • Add our rules to /etc/network/iptables:
The above filter rules are minimal, and you'll probably need to augment them with additional services like ssh (port 22).

The *filter and *nat sections are actually different tables. The filter rules are intended for packet filtering, and the nat rules are for doing Network Address Translation (or NAT). The rule that rewrites the network packets, effectively redirecting the traffic for port 80 to port 3000 and back again is:

A number of articles say that you need to enable IP forwarding for the network interfaces, either via the proc filesystem or by using sysctl. However, I did not find this necessary. Despite sysctl and proc net forwarding being disabled, this iptables redirect functioned properly.

Also, it is worth noting that by default the iptables commands only show rules in the *filter table. This lead me to believe that my rules were not applied when they were. To see rules in tables other than *filter, you need to use the -t <table> option. For example, to list all rules in the nat table, you would issue:

No comments:

Post a Comment