VPS Survival Guide

Running an unconstrained node on the public Internet is tricky and an invitation to pwnage.

Note

I would like to endorse a VPS hosting firm called TNA Hosting [1]. They are a small shop with really great deals, solid uptime, and no mandatory intrusion policy. As of this writing, my link below can lead to $25/year KVM nodes and other good stuff.

Email security

DKIM

A DKIM record authenticates messages originating from the domain.

  • Install opendkim.

# For Debian-alike
apt-get install opendkim opendkim-tools
# For modern RHEL-alike
dnf install opendkim
# For older RHEL-alike
yum install opendkim
  • Generate DKIM keys

    • The keys will be in /etc/opendkim/keys .

    • The mapping of keys should be correct in /etc/opendkim/keytable and /etc/opendkim/signingtable .

opendkim-default-keygen
  • Push the DKIM key to your DNS zone file as a TXT record.

Name

mail._domainkey

Type

TXT

TTL

<anything, usually 1 hour>

Value

v=DKIM; k=rsa256; p=<key_payload>

  • Check /etc/opendkim.conf

    • mode should be “sv”

    • note the port specified in the socket definition, such as inet:8891@localhost .

  • Activate opendkim

systemctl enable opendkim
systemctl restart opendkim
  • Configure your mail agent (Qmail/Postfix) to use DKIM (see below).

SPF

An SPF record lists who is allowed to send mail for your domain. It is a DNS record of type TXT.

  • A basic SPF record allowing anything in your MX list to send.

v=spf1 mx a -all
  • Letting Google do your dirty work.

v=spf1 include:_spf.google.com ~all
  • Same with Zoho.

v=spf1 include:zoho.com ~all

Postfix

  • Set opendkim as a mail filter

smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = inet:127.0.0.1:8891

Qmail

Network security

Openssh

  • Install Openssh.

# For Debian-alike
apt-get install openssh-server
# For modern RHEL-alike
dnf install openssh-server
# For older RHEL-alike
yum install openssh-server
# Your system will have SSH either as "ssh" or "sshd"
systemctl enable sshd ssh
systemctl start  sshd ssh
  • hosts.allow lists authorized TCP connection sources

# Local addresses
ALL: LOCAL
# Every host in your external domain
ALL: .mydomain.org
# Every host in your internal domain
ALL: .local.mydomain.org
# The host with IP x.x.x.x
ALL: x.x.x.x
  • hosts.deny lists forbidden TCP connection sources

# Ban everything not allowed in hosts.allow
ALL: ALL
# Replace it with this if you want to ban any IP-hostname mismatch
# ALL: PARANOID

Fail2ban and SSH

So, you installed fail2ban, which means your troubles are over, right?

The SSH state is off by default. Create /etc/fail2ban/jail.d/22-sshd.conf as follows…

1[sshd]
2enabled = true
3port = ssh
4maxretry = 2
5bantime = 864000
6banaction = nftables-allports
7# If using iptables, comment the previous line and uncomment the next.
8#banaction = iptables-allports

GEOIP ipsets and firewalld

This script will configure firewalld to block entire countries. This will only control your level of logspam, not your residual risk from technical controls!

Download blocknets.sh

 1#!/bin/bash 
 2  
 3cd `dirname ${0}`
 4[ ! -f zoneurls.txt ] && echo No zoneurls.txt && exit 255
 5
 6for zonefile in `cat zoneurls.txt`
 7do
 8    filename=`basename ${zonefile}`
 9    firewall-cmd --permanent --new-ipset=blacklist-${filename} --type=hash:net
10    firewall-cmd --add-rich-rule="rule source ipset=blacklist-${filename} log prefix=${filename} limit value=1/m drop" --permanent
11
12    [ ! -f ${filename} ] && curl ${zonefile} | sort -n | uniq > ${filename}
13    [ ! -f ${filename}.last ] && touch ${filename}.last
14    deletions=`comm -13 ${filename} ${filename}.last > ${filename}.deletions 2> /dev/null`
15
16    firewall-cmd --ipset=blacklist-${filename} --remove-entries-from-file=${filename}.deletions --permanent || exit 2
17    firewall-cmd --ipset=blacklist-${filename} --add-entries-from-file=${filename} --permanent || exit 2
18
19    /usr/bin/mv ${filename} ${filename}.last
20done
21
22firewall-cmd --reload

My zoneurls.txt contains the high-density sources for the bots in my logs. Add or subtract countries as you see fit.

Download zoneurls.txt

1https://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone
2https://www.ipdeny.com/ipblocks/data/countries/cn.zone
3https://www.ipdeny.com/ipblocks/data/countries/nl.zone
4https://www.ipdeny.com/ipblocks/data/aggregated/nl-aggregated.zone