12

Currently I'm using the following iptables rules for my remote (server) geth node:

V4

*filter

# Allow all loopback (lo0) traffic and reject traffic
# to localhost that does not originate from lo0.
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT

# Allow ping.
-A INPUT -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT

# Allow SSH connections.
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# Allow TCP and UDP connections from anywhere
-A INPUT -p tcp --dport 30303 -m state --state NEW -j ACCEPT
-A INPUT -p udp --dport 30303 -m state --state NEW -j ACCEPT
-A INPUT -p udp --dport 30301 -m state --state NEW -j ACCEPT

# Allow inbound traffic from established connections.
# This includes ICMP error returns.
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Log what was incoming but denied.
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables_INPUT_denied: " --log-level 7

# Reject all other inbound.
-A INPUT -j REJECT

# Log any traffic that was sent to you
# for forwarding.
-A FORWARD -m limit --limit 5/min -j LOG --log-prefix "iptables_FORWARD_denied: " --log-level 7

# Reject all traffic forwarding.
-A FORWARD -j REJECT

COMMIT

V6

*filter

# Allow all loopback (lo0) traffic and reject traffic
# to localhost that does not originate from lo0.
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s ::1/128 -j REJECT

# Allow ping.
-A INPUT -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT

# Allow SSH connections.
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# Allow TCP and UDP connections from anywhere
-A INPUT -p tcp --dport 30303 -m state --state NEW -j ACCEPT
-A INPUT -p udp --dport 30303 -m state --state NEW -j ACCEPT
-A INPUT -p udp --dport 30301 -m state --state NEW -j ACCEPT

# Allow inbound traffic from established connections.
# This includes ICMP error returns.
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Log what was incoming but denied.
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "ip6tables_INPUT_denied: " --log-level 7


# Reject all other inbound.
-A INPUT -j REJECT

# Log any traffic that was sent to you
# for forwarding.
-A FORWARD -m limit --limit 5/min -j LOG --log-prefix "ip6tables_FORWARD_denied: " --log-level 7

# Reject all traffic forwarding.
-A FORWARD -j REJECT

COMMIT

Is there any way I can make the rules more secure. Also I would like to know if the same are good enough for a parity node.

  • 2
    +1, great question. I'd also like to know if this can be further restricted to the user running the geth client (say with something like the -m owner --uid-owner ... iptables rules). – Cedric Martin Oct 11 '16 at 1:15
5

Network security isn't my specialty, but I thought I'd give some feedback on what seems obvious to me.

  • It might be good to setup a VPN for yourself. In general it's best to just blindly reject any traffic from untrusted sources. If they can't connect to your server it's much harder to test for vulnerabilities. Once that is configured, you can make your SSH rule stricter with:

    sudo iptables -A INPUT -p tcp -s $vpn_connection --dport 80 -j ACCEPT # allow all tcp connections by $vpn_connection to port 80

  • This is just a general rule to protect you from yourself, you can choose to add it or not. This rule basically says that any new rule you add will not sever existing connections (ie. if you accidentally add a rule severing your own active SSH connection):

    sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # prevent added rules from severing existing connections

As far as general notes, I like that you ended your rule set with a drop command to all remaining requests. Other than that I cannot stress any more how important it is to setup a VPN to restrict SSH and other secure connections. Good luck and hopefully someone else can criticize me for anything I forgot (I'd appreciate it).

  • Hey, thanks for the answer, two questions regarding your suggestion. VPNs have the tendency to drop connections, though very unusual but possible. Is there any chance to be left isolated from my own instance if this is the case, that is, the server being incapable of reconnecting to the VPN. And second, the second rule if it were included where exactly would be a good place put with respect to the rest of rules, at the bottom? – wacax Nov 23 '16 at 3:35
3

There were many good answers and suggestions on this Reddit thread which I'll try to summarize.

Iptables rules on their own won't suffice in a large or organized attack, the datacenter must have some sort of proper DDoS protection in their network. This is of primary importance when dealing with DDoS attacks.

  • Drop all requests / Start with a default DROP policy

Begining with a default DROP policy and simply white list anything needed is a good strategy.

A good recommendation is to drop every request but those the server is expecting to receive or expecting to make. Another good idea is to explicitly drop port 0, some attacks were making use of that, because some DDoSers were able to still circumvent the attack onto that port. It is unsure if this is just an issue that plagued older iptables/OSes.

An example of such rules are as follows:

iptables -P INPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED, RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 30303 -j ACCEPT
iptables -A INPUT -p udp --dport 30303 -j ACCEPT

iptables -P FORWARD DROP

.. etc

  • Using netstat to see which ports are needed per service

In addition to a "DROP" policy, using netstat to include ports needed for whatever services you need and include them in the iptables rules is a good approach. In this example we include the daemons' ports of Bitcoin and Litecoin client in addition to Geth's

#!/bin/bash
IPT="/sbin/iptables"
# This is the iptables script that will be loaded through a cronjob, every time the system boots. 
# First we will flush old rules and then fill iptables with policies and rules specified below.
# Iptables on
systemctl start iptables
# Flush old rules, old custom tables
$IPT --flush
$IPT --delete-chain

### POLICIES ###
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

### INPUT RULES ###
# accept local port use, for example so you can use json-rpc on the    servers cli
$IPT -A INPUT -i lo -j ACCEPT
# accept other nodes data reply in case for example a peer request your Geth made to another node
$IPT -A INPUT -m state --state ESTABLISHED, RELATED -j ACCEPT
# ssh from your home
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# accept your local crypto daemons to receive connections
# Bitcoin
$IPT -A INPUT -p tcp --dport 18333 -s 0.0.0.0/0 -j ACCEPT
# Litecoin
$IPT -A INPUT -p tcp --dport 19333 -s 0.0.0.0/0 -j ACCEPT
# Go-Ethereum (Geth)
$IPT -A INPUT -p tcp --dport 30303 -s 0.0.0.0/0 -j ACCEPT
  • Accepting SSH only from your home IP address

Doing something similar to:

$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -s [your home ip]/32 -j ACCEPT

In order to limit access to anyone except a user using your home address may limit unwanted access. Warning ISPs may change your IP address without prior notification rendering your access to your remote server impossible. Consider using it only if you have a fixed IP address or if you can do this from the cpanel or console (ex. AWS).

  • Changing the default SSH port

Another recommendation is changing the default SSH port to something random, a lot of Chinese servers attempt to brute-force the default port. Making sure rate-limiting for the attempts are in place as well is a good idea.

  • Disallow ping

The host does not need to respond to pings, you don't need to allow ICMP echo's.

  • Add a VPN to SSH

It might be good to setup a VPN for yourself. One can make the SSH rule stricter with:

sudo iptables -A INPUT -p tcp -s $vpn_connection --dport 80 -j ACCEPT # allow all tcp connections by $vpn_connection to port 80
  • Add a rule to protect you from yourself

This is just a general rule to protect the host from yourself. This rule basically says that any new rule you add will not sever existing connections (ie. if you accidentally add a rule severing your own active SSH connection):

sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # prevent added rules from severing existing connections

Thanks to:

For their answers and to 5chdn for making the question public on Reddit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.