I use my private server setup notes as a cheatsheet occasionally, but below is a simplified version of that, the way I adjusted it to set with a temporary free domain name (from afraid.org, without DNSSEC, so did not set DANE, either), without a secondary DNS server, without mailing lists, with uacme instead of certbot, and without mail submission via Postfix, since mail can be handled either completely over SSH, or Dovecot can handle both IMAP and submission. XMPP is also configured, for textual chats only: without a TURN server, a web interface, or file upload. A private IRC server is set to be accessible via a private network without TLS (by both clients and other servers) and client authentication, or from the Internet over TLS and with authentication. Using multiple domain names for the services.
In this section we update the system, add users, configure SSH access, optionally set a text editor.
# Check /etc/apt/sources.list apt update apt upgrade apt install sudo emacs-nox # Add a user adduser defanor adduser defanor sudo su defanor # The text editor setup is optional echo 'EDITOR="emacsclient -a emacs -t"' >> .profile source .profile echo 'alias em="emacsclient -a emacs -t"' >> .bashrc source .bashrc systemctl --user enable --now emacs # Enable linger to achieve persistent Emacs sessions sudo loginctl enable-linger $USER # Add SSH keys, configure sshd mkdir .ssh $EDITOR .ssh/authorized_keys sudo -e /etc/ssh/sshd_config # Ensure "PermitRootLogin no" and "PasswordAuthentication no" sudo systemctl reload sshd # Check that logging in as a user and sudo work, lock the root password sudo passwd -l root # Set time zone to UTC, locale to C.UTF-8 sudo dpkg-reconfigure tzdata sudo -e /etc/default/locale
We will set knot for authoritative DNS. This can be used for an ACME challenge afterwards, though a web server is also usable for that. It is convenient to host authoritative DNS servers, though some hosting companies may disable UDP while under DDoS attacks, which leads to lookup failures (even when TCP is supported, as in this case). Often one may use registrar-provided nameservers, or free ones, like those provided by Cloudflare.
apt install knot knot-dnsutils sudo -e /etc/knot/knot.conf # A knot.conf example is in the next listing sudo -e /var/lib/knot/steady.mooo.com.zone sudo -e /var/lib/knot/beep.boop.ip-dynamic.org.zone # A zone file example is below
/etc/knot/knot.conf
changes:
--- original_configs/knot.conf 2024-08-29 18:41:48.485534350 +0000 +++ /etc/knot/knot.conf 2024-09-29 12:20:50.446108496 +0000 @@ -5,7 +5,7 @@ rundir: "/run/knot" user: knot:knot automatic-acl: on - listen: [ 127.0.0.1@53, ::1@53 ] + listen: [ 127.0.0.1@53, ::1@53, 89.110.126.39@53 ] log: - target: syslog @@ -26,7 +26,26 @@ storage: "/var/lib/knot" file: "%s.zone" +key: + - id: uacme + algorithm: hmac-sha512 + secret: SECRET_TSIG_KEY + +acl: + - id: uacme_acl + address: [127.0.0.1, ::1] + action: update + key: uacme + zone: + - domain: steady.mooo.com + acl: uacme_acl + semantic-checks: on + + - domain: beep.boop.ip-dynamic.org + acl: uacme_acl + semantic-checks: on + # # Primary zone # - domain: example.com # notify: secondary
A zone file
example, /var/lib/knot/steady.mooo.com.zone
:
@ 10800 SOA steady.mooo.com. hostmaster.steady.mooo.com. 726 43200 7200 2419200 86400 @ 10800 A 89.110.126.39 @ 10800 NS steady.mooo.com. @ 10800 TXT "v=spf1 a mx ~all" @ 10800 CAA 0 issue "letsencrypt.org" @ 10800 MX 10 steady.mooo.com. _dmarc 10800 TXT "v=DMARC1; p=quarantine" _adsp._domainkey 10800 TXT "dkim=all" strudel2024._domainkey 10800 TXT "v=DKIM1; h=sha256; k=rsa; p=KEY_HERE" _xmpp-client._tcp 10800 SRV 10 5 5222 steady.mooo.com. _xmpp-server._tcp 10800 SRV 10 5 5269 steady.mooo.com. _xmpp-server._tcp.chat 10800 SRV 10 5 5269 steady.mooo.com.
The zone file for beep.boop.ip-dynamic.org is similar. Had to use the fourth level domain for it, since cloudns.net serves SOA records itself (not allowing to override those on free plans), so third-level domain name delegation does not quite work.
A web server is easy to set now:
sudo apt install nginx sudo -e /etc/nginx/sites-available/general.conf sudo ln -s /etc/nginx/sites-available/general.conf /etc/nginx/sites-enabled/
And sample site configuration, general.conf
:
server { listen 80; listen 443 ssl; server_name steady.mooo.com beep.boop.ip-dynamic.org; ssl_certificate /etc/ssl/uacme/steady.mooo.com/cert.pem; ssl_certificate_key /etc/ssl/uacme/private/steady.mooo.com/key.pem; index index.xhtml index.html index.txt; location / { root /var/www/general; } # User directories location ~ ^/~([^/]+)(.*)$ { alias /home/$1/public_html/$2; } }
Listing two setups for X.509 certificate retrieval using the
ACME protocol, the uacme client. In either case, apt
install uacme
, and do general configuration to run it
under a dedicated user:
sudo adduser --system uacme sudo mkdir /etc/ssl/uacme sudo chown uacme /etc/ssl/uacme sudo -u uacme uacme -v new # A DNS- or HTTP-specific "uacme issue" command here, see below. # Set the same uacme command on cron.daily, followed by "systemctl reload ..." sudo -e /etc/cron.daily/uacme-cert-update sudo chmod +x /etc/cron.daily/uacme-cert-update
sudo keymgr -t uacme hmac-sha512 sudo cp /usr/share/uacme/nsupdate.sh /usr/local/bin/uacme-nsupdate.sh sudo -e /usr/local/bin/uacme-nsupdate.sh # An uacme-nsupdate.sh adjusted for knot is below sudo -u uacme -e /etc/ssl/uacme/private/uacme.tsig # uacme.tsig contains the key produced by keymgr above sudo chmod 600 /etc/ssl/uacme/private/uacme.tsig sudo -u uacme uacme -h /usr/local/bin/uacme-nsupdate.sh issue \ steady.mooo.com '*.steady.mooo.com' \ beep.boop.ip-dynamic.org '*.beep.boop.ip-dynamic.org'
The uacme-nsupdate.sh
hook script adjustments
(though it is not suitable for a separate zone for
_acme-challenge
: the sample
script's ns_getdomain
procedure would fail to
retrieve the domain):
--- /usr/share/uacme/nsupdate.sh 2023-02-15 20:31:43.000000000 +0000 +++ /usr/local/bin/uacme-nsupdate.sh 2025-02-06 10:49:50.890262287 +0000 @@ -21 +21 @@ -NSUPDATE=nsupdate +NSUPDATE=knsupdate @@ -29 +29 @@ -RNDC_KEY_NSUPDATE= +RNDC_KEY_NSUPDATE=/etc/ssl/uacme/private/uacme.tsig @@ -92 +92 @@ - local ttl=600 + local ttl=1 @@ -106 +106,2 @@ - server ${nameserver} + zone ${IDENT}. + origin ${IDENT}. @@ -109,0 +111,4 @@ + + # Wait a little, since otherwise somehow Let's Encrypt sees old + # records. + sleep 10
The CAA DNS RR can be set to 0 issue
"letsencrypt.org;validationmethods=dns-01"
then.
sudo mkdir -p /var/www/general/.well-known/acme-challenge sudo chown uacme /var/www/general/.well-known/acme-challenge sudo -u uacme \ UACME_CHALLENGE_PATH=/var/www/general/.well-known/acme-challenge/ \ uacme -h /usr/share/uacme/uacme.sh issue \ steady.mooo.com beep.boop.ip-dynamic.org
Setting Postfix with OpenDKIM and SPF Engine first, for a basic mail server.
sudo apt install postfix postfix-policyd-spf-python opendkim opendkim-tools sudo -u opendkim opendkim-genkey -D /etc/dkimkeys -d steady.mooo.com -s strudel2024 sudo -e /etc/opendkim.conf # opendkim.conf adjustments are listed below # Aiming multiple domains, so using keytable and signingtable sudo tee /etc/dkimkeys/keytable <<EOF steady steady.mooo.com:strudel2024:/etc/dkimkeys/strudel2024.private beepboop beep.boop.ip-dynamic.org:strudel2024:/etc/dkimkeys/strudel2024.private EOF sudo tee /etc/dkimkeys/signingtable <<EOF *@steady.mooo.com steady *@beep.boop.ip-dynamic.org beepboop EOF sudo mkdir /var/spool/postfix/opendkim sudo chown opendkim:opendkim /var/spool/postfix/opendkim sudo systemctl restart opendkim sudo adduser postfix opendkim sudo -e /etc/postfix/master.cf sudo -e /etc/postfix/main.cf # master.cf and main.cf adjustments are listed below # Adjust access rules and mail aliases sudo -e /etc/postfix/postscreen_access.cidr sudo -e /etc/postfix/client_checks sudo postmap /etc/postfix/client_checks sudo -e /etc/postfix/sender_checks sudo postmap /etc/postfix/sender_checks sudo -e /etc/aliases sudo postalias /etc/aliases sudo systemctl restart postfix
opendkim.conf
edits:
--- original_configs/opendkim.conf 2024-08-30 06:36:30.982553576 +0000 +++ /etc/opendkim.conf 2024-08-30 06:38:37.435019550 +0000 @@ -24,0 +25,2 @@ +KeyTable file:/etc/dkimkeys/keytable +SigningTable refile:/etc/dkimkeys/signingtable @@ -37 +39 @@ -Socket local:/run/opendkim/opendkim.sock +#Socket local:/run/opendkim/opendkim.sock @@ -40 +42 @@ -#Socket local:/var/spool/postfix/opendkim/opendkim.sock +Socket local:/var/spool/postfix/opendkim/opendkim.sock
The Postfix's master.cf
:
--- original_configs/master.cf 2024-08-30 06:48:45.213250773 +0000 +++ /etc/postfix/master.cf 2024-08-30 07:01:25.308043639 +0000 @@ -12,5 +12,5 @@ -smtp inet n - y - - smtpd -#smtp inet n - y - 1 postscreen -#smtpd pass - - y - - smtpd -#dnsblog unix - - y - 0 dnsblog -#tlsproxy unix - - y - 0 tlsproxy +#smtp inet n - y - - smtpd +smtp inet n - y - 1 postscreen +smtpd pass - - y - - smtpd +dnsblog unix - - y - 0 dnsblog +tlsproxy unix - - y - 0 tlsproxy @@ -137,0 +138,4 @@ + +# SPF with postfix-policyd-spf-python +policyd-spf unix - n n - 0 spawn + user=policyd-spf argv=/usr/bin/policyd-spf
And main.cf
:
--- original_configs/main.cf 2024-08-30 07:24:12.265070083 +0000 +++ /etc/postfix/main.cf 2024-09-01 16:10:52.553840094 +0000 @@ -27,2 +27,2 @@ -smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem -smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key +smtpd_tls_cert_file=/etc/ssl/uacme/steady.mooo.com/cert.pem +smtpd_tls_key_file=/etc/ssl/uacme/private/steady.mooo.com/key.pem @@ -37 +37 @@ -myhostname = strudel.uberspace.net +myhostname = steady.mooo.com @@ -41 +41 @@ -mydestination = $myhostname, steady.mooo.com, strudel.uberspace.net, localhost.uberspace.net, localhost +mydestination = $myhostname, steady.mooo.com, beep.boop.ip-dynamic.org, strudel.uberspace.net, localhost @@ -44 +44,2 @@ -message_size_limit = 0 +message_size_limit = 20971520 +mailbox_size_limit = 1073741824 @@ -48,0 +50,53 @@ +# Store messages in ~/Maildir/ +home_mailbox = Maildir/ + +# OpenDKIM +smtpd_milters = unix:opendkim/opendkim.sock +non_smtpd_milters = $smtpd_milters +milter_default_action = accept +internal_mail_filter_classes = bounce + +# Postscreen +postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr +postscreen_blacklist_action = drop +postscreen_greet_action = drop +postscreen_pipelining_enable = yes +postscreen_non_smtp_command_enable = yes +postscreen_bare_newline_enable = yes +postscreen_bare_newline_action = enforce +postscreen_dnsbl_action = enforce +postscreen_dnsbl_sites = zen.spamhaus.org*3 + b.barracudacentral.org*2 + bl.spameatingmonkey.net*2 + bl.spamcop.net + dnsbl.sorbs.net + psbl.surriel.com + bl.mailspike.net + list.dnswl.org=127.0.[2..14;16..255].0*-2 + list.dnswl.org=127.0.[2..14;16..255].1*-3 + list.dnswl.org=127.0.[2..9;11..14;16..255].[2..3]*-4 +postscreen_dnsbl_threshold = 3 +postscreen_dnsbl_whitelist_threshold = -1 + +# Other anti-UCE +smtpd_helo_required = yes +disable_vrfy_command = yes +smtpd_recipient_restrictions = + reject_invalid_hostname, + reject_non_fqdn_hostname, + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + permit_mynetworks, + reject_unauth_destination, + check_sender_access hash:/etc/postfix/sender_checks, + check_client_access hash:/etc/postfix/client_checks, + reject_rbl_client bl.spamcop.net, + reject_rbl_client cbl.abuseat.org, + check_policy_service unix:private/policyd-spf, + permit +smtpd_data_restrictions = + reject_unauth_pipelining, + permit
At this point, the mail server's core is configured. It can be
used with sendmail(1)
, mail(1)
from
GNU mailutils (installed with Emacs), or Emacs clients, on the
server itself. For instance, with mu4e:
sudo apt install mu4e mu init --maildir=~/Maildir --my-address=defanor@steady.mooo.com --my-address=defanor@beep.boop.ip-dynamic.org
Then M-x mu4e
in Emacs, and it is works for mail
reading and composition, without additional configuration. But
for external IMAP and SMTP clients, we could set Dovecot.
Now to set IMAP access and submission over SMTP, with
Dovecot: sudo apt install dovecot-imapd
dovecot-submissiond
, then adjust the following three
configuration files:
--- original_configs/10-mail.conf 2024-08-30 17:37:12.441632067 +0000 +++ /etc/dovecot/conf.d/10-mail.conf 2024-08-30 16:51:40.139684081 +0000 @@ -29,3 +29,3 @@ # -mail_location = mbox:~/mail:INBOX=/var/mail/%u +mail_location = maildir:~/Maildir:LAYOUT=fs
This makes Dovecot to write files into ~/Maildir
,
and to use the regular hierarchical directory layout, compatible
with mu4e and other MUAs, as opposed to the Maildir++ directory
layout, which prefixes mail folders with a dot. That way,
maildirs on servers and clients are interchangeable, and MUAs
ran on mail servers behave the same as those on personal
computers.
--- original_configs/10-ssl.conf 2024-08-30 17:37:51.361773007 +0000 +++ /etc/dovecot/conf.d/10-ssl.conf 2024-08-30 16:53:20.508051171 +0000 @@ -6 +6 @@ -ssl = yes +ssl = required @@ -12,2 +12,2 @@ -ssl_cert = </etc/dovecot/private/dovecot.pem -ssl_key = </etc/dovecot/private/dovecot.key +ssl_cert = </etc/ssl/uacme/steady.mooo.com/cert.pem +ssl_key = </etc/ssl/uacme/private/steady.mooo.com/key.pem
--- original_configs/20-submission.conf 2024-08-30 17:31:46.480451752 +0000 +++ /etc/dovecot/conf.d/20-submission.conf 2024-08-30 18:01:07.070829241 +0000 @@ -45 +45 @@ -#submission_relay_host = +submission_relay_host = localhost @@ -52 +52 @@ -#submission_relay_trusted = no +submission_relay_trusted = yes
Reload the service, and it should work. Can be set with Emacs
mail clients, but here is a basic mutt configuration
(~/.muttrc
) that works with this setup:
set folder=imaps://defanor@steady.mooo.com/ set spoolfile=+inbox mailboxes +inbox set record = +sent set realname=defanor set from=defanor@steady.mooo.com set smtp_url=smtp://defanor@steady.mooo.com:587/ set ssl_starttls=yes unset smtp_pass
When I had to migrate the maildir to a new server, I have
ultimately moved it with rsync, after attempting to simply
synchronize with mbsync, removing its .uidvalidity
and .mbsyncstate
files, running into duplicated
messages due to mbsync's X-TUID headers. Fortunately I backed up
the maildir (made a tar archive) before the manipulations, so it
was safe and easy to restore, did not have to clean up the
duplicates. One may also employ doveadm
for
synchronization.
A basic XMPP setup here, just for textual chats.
sudo apt install prosody sudo rm /etc/prosody/conf.d/localhost.cfg.lua sudo -e /etc/prosody/prosody.cfg.lua sudo chgrp ssl-cert /etc/ssl/uacme/private/{,steady.mooo.com/{,key.pem}} sudo chmod g+r /etc/ssl/uacme/private/steady.mooo.com/key.pem sudo chmod g+rx /etc/ssl/uacme/private/{,steady.mooo.com/} sudo adduser prosody ssl-cert sudo prosodyctl restart sudo prosodyctl adduser defanor@steady.mooo.com
And the configuration adjustments:
--- original_configs/prosody.cfg.lua 2024-08-31 19:47:49.024239057 +0000 +++ /etc/prosody/prosody.cfg.lua 2024-08-31 21:02:37.783514208 +0000 @@ -24 +24 @@ -admins = { } +admins = { "defanor@steady.mooo.com" } @@ -65 +65 @@ - --"mam"; -- Store recent messages to allow multi-device synchronization + "mam"; -- Store recent messages to allow multi-device synchronization @@ -199,2 +199,2 @@ - info = "/var/log/prosody/prosody.log"; - error = "/var/log/prosody/prosody.err"; + -- info = "/var/log/prosody/prosody.log"; + -- error = "/var/log/prosody/prosody.err"; @@ -202 +202 @@ - { levels = { "error" }; to = "syslog"; }; + { levels = { "info" }; to = "syslog"; }; @@ -233,3 +233,5 @@ -VirtualHost "localhost" --- Prosody requires at least one enabled VirtualHost to function. You can --- safely remove or disable 'localhost' once you have added another. +VirtualHost "steady.mooo.com" +ssl = { + certificate = "/etc/ssl/uacme/steady.mooo.com/cert.pem"; + key = "/etc/ssl/uacme/private/steady.mooo.com/key.pem"; +} @@ -245,2 +247,2 @@ ----Set up a MUC (multi-user chat) room server on conference.example.com: ---Component "conference.example.com" "muc" +---Set up a MUC (multi-user chat) room server on chat.steady.mooo.com: +Component "chat.steady.mooo.com" "muc" @@ -248 +250 @@ ---modules_enabled = { "muc_mam" } +modules_enabled = { "muc_mam" }
This server is a part of a small private IRC network, using InspIRCd without IRC services; it is open to both virtual private network addresses (without TLS or client authentication) and via the Internet (with TLS and a password). It also binds a websocket on 127.0.0.1, to connect via a reverse proxy set with nginx (which is awkward and hides user IP addresses, but the KiwiIRC web interface does not support regular PASS authentication, so HTTP basic authentication with a secret websocket path is a hacky workaround). The setup is done as follows:
sudo apt install inspircd sudo adduser irc ssl-cert sudo -e /etc/inspircd/inspircd.conf sudo systemctl reload inspircd
The relevant configuration changes for this particular setup are:
--- original_configs/inspircd.conf 2024-12-08 13:28:17.188260631 +0000 +++ /etc/inspircd//inspircd.conf 2024-11-30 14:18:19.958889434 +0000 @@ -6,15 +6,42 @@ -<server name="irc.local" - description="Local IRC Server" - network="Localnet"> +<server name="10.0.255.62" + description="The 0xa00ff3e IRC Server" + network="Womblenet"> -<admin name="Root Penguin" - nick="Nick" - email="root@localhost"> +<admin name="defanor" + nick="defanor" + email="defanor@steady.mooo.com"> -<bind address="127.0.0.1" port="6667" type="clients"> +<bind address="10.0.255.62" port="6667" type="clients"> -<power diepass="3456" restartpass="7890"> +<power diepass="PASSWORD" restartpass="PASSWORD"> -<connect allow="*" +<module name="ssl_gnutls"> + +<gnutls onrehash="yes"> + +<sslprofile name="Clients" + provider="gnutls" + certfile="/etc/ssl/uacme/steady.mooo.com/cert.pem" + keyfile="/etc/ssl/uacme/private/steady.mooo.com/key.pem"> + +<bind address="89.110.126.39" port="6697" sslprofile="Clients" type="clients"> + +<connect name="Secure" + parent="Main" + allow="*" + port="6697" + password="PASSWORD"> + +<connect name="Plain" + parent="Main" + allow="*" + port="6667"> + +<connect name="Websocket" + parent="Main" + allow="*" + port="6687"> + +<connect name="Main" timeout="60" @@ -26,3 +53,4 @@ localmax="3" - globalmax="3"> + globalmax="3" + resolvehostnames="no"> @@ -40,14 +68,11 @@ <type name="NetAdmin" - classes="OperChat BanControl HostCloak Shutdown ServerLink" - host="netadmin.omega.org.za"> + classes="OperChat BanControl HostCloak Shutdown ServerLink"> <type name="GlobalOp" - classes="OperChat BanControl HostCloak ServerLink" - host="ircop.omega.org.za"> + classes="OperChat BanControl HostCloak ServerLink"> <type name="Helper" - classes="HostCloak" - host="helper.omega.org.za"> + classes="HostCloak"> -<oper name="root" - password="12345" - host="*@localhost" +<oper name="defanor" + password="PASSWORD" + host="*@10.0.255.66/30 *@10.0.255.62/30" type="NetAdmin"> @@ -59,3 +84,3 @@ -<dns server="127.0.0.1" timeout="5"> +<dns enabled="no" server="127.0.0.1" timeout="5"> @@ -93 +118,19 @@ <badnick nick="MemoServ" reason="Reserved For Services"> + +<module name="spanningtree"> +<bind address="10.0.255.62" port="7000" type="servers" defer="5s"> +<link name="10.0.255.66" + ipaddr="10.0.255.66" + port="7000" + allowmask="10.0.255.66/32" + sendpass="PASSWORD" + recvpass="PASSWORD"> + + +<module name="sha1"> +<module name="websocket"> +<wsorigin allow="*"> +<bind address="127.0.0.1" + port="6687" + type="clients" + hook="websocket">
To reduce spam in the logs:
apt install fail2ban sudo -e /etc/fail2ban/jail.local sudo systemctl restart fail2ban
A jail.local example from the old notes works, but
with backend = systemd
in the DEFAULT section, now
that there are no traditional textual log files by default.
Likewise with nftables: I took the old nftables configuration, though also adjusted it over time, including additional filtering for SMTP connections from China, due to the persistent network abuse. An attempted setup with nftables-geoip ran out of memory when trying to load the tables here, so this is more custom and lightweight:
curl https://download.db-ip.com/free/dbip-country-lite-2025-02.csv.gz | \ zcat | grep CN | grep -v : | \ sed -E 's/([0-9\.]+),([0-9\.]+),CN/\1-\2,/g' > china.nft $EDITOR china.nft sudo mv china.nft /etc/ sudo chown root /etc/china.nft
With an editor, china.nft is adjusted a little more, to wrap the list of addresses into an nftables set, which is then included into the main nftables configuration:
#!/usr/sbin/nft -f flush ruleset table inet filter { include "/etc/china.nft" # Large networks from which registered users don't connect: APNIC, # AFRNIC, LACNIC. Also subnets of ISPs that seem to ignore abuse # reports: Centurylink, AS209605, AS133398 (serveroffer.lt), # AS133398 (tele-asia.net), AS34665 (pindc.ru), AS33915 (ziggo.nl), # AS200391 (fastvps.biz), AS212370/AS213371 (peenq.nl), AS51395 # (privacyfirst.{sh,digital}), AS20978 (ttnet.com.tr), AS12876 # (online.net), AS35807 (sknt.ru), AS44493 (profitserver.ru). set not-users { type ipv4_addr flags interval elements = { 1.0.0.0/8, 14.0.0.0/8, 27.0.0.0/8, 36.0.0.0/8, 39.0.0.0/8, 41.0.0.0-43.255.255.255, 49.0.0.0/8, 58.0.0.0-61.255.255.255, 101.0.0.0-103.255.255.255, 105.0.0.0-106.255.255.255, 110.0.0.0-126.255.255.255, 133.0.0.0/8, 150.0.0.0/8, 153.0.0.0-154.255.255.255, 163.0.0.0/8, 171.0.0.0/8, 175.0.0.0/8, 177.0.0.0/8, 179.0.0.0-183.255.255.255, 186.0.0.0/7, 189.0.0.0-191.255.255.255, 196.0.0.0/7, 200.0.0.0/6, 210.0.0.0/7, 218.0.0.0-223.255.255.255, 63.152.0.0/13, 63.224.0.0/13, 64.91.0.0/17, 67.0.0.0/13, 67.232.0.0/13, 69.29.0.0/16, 69.68.0.0/15, 69.179.0.0/16, 70.56.0.0/14, 71.0.0.0/14, 71.32.0.0/13, 71.48.0.0/13, 71.208.0.0/12, 75.160.0.0/12, 76.0.0.0/13, 97.112.0.0/12, 98.125.0.0/16, 168.103.0.0/16, 173.202.0.0/16, 174.16.0.0/12, 184.96.0.0/13, 184.156.0.0/14, 207.118.0.0/15, 141.98.10.0/24, 185.36.81.0/24, 45.125.64.0/22, 31.184.192.0/20, 5.188.210.0/24, 37.139.53.0/24, 82.74.0.0/15, 5.188.206.0/24, 77.247.110.0/24, 37.49.225.0/24, 91.192.100.0/22, 37.154.0.0/15, 51.15.0.0/16, 188.243.192.0/18, 88.201.204.0/22, 31.192.232.0/21 } } # Trusted hosts. set trusted { type ipv4_addr flags interval elements = {} } # Known spammers. These will be updated dynamically. set spammers { type ipv4_addr flags interval } # Known persistent spammers from ISPs ignoring abuse reports, and # aiming services where even little server-to-server spam is # annoying (XMPP, email); a manually edited list. Currently in it: # sknt.ru. set s2s-spammers { type ipv4_addr flags interval elements = { 188.243.192.232 } } # Same, for IPv6. Contents: sknt.ru. set s2s-spammers-v6 { type ipv6_addr flags interval elements = { 2a05:3580:cd00::/40 } } chain input { type filter hook input priority 0; policy drop; # Allow traffic from established and related packets. ct state established,related accept # Drop invalid packets. ct state invalid drop # Allow loopback traffic. iifname lo accept # Allow traffic from trusted hosts. ip saddr @trusted accept # Allow all ICMP and IGMP traffic, but enforce a rate limit to # help prevent some types of flood attacks. ip protocol icmp limit rate 4/second accept ip6 nexthdr ipv6-icmp limit rate 4/second accept ip protocol igmp limit rate 4/second accept # Restrict connections from likely spammers. ip saddr @spammers limit rate over 4/hour drop # Block connections from known spammers. ip saddr @s2s-spammers drop ip6 saddr @s2s-spammers-v6 drop # Block SMTP connections from China, since there is a lot of spam # and no ham. Block a few more ports as well, to reduce spam in # the logs. tcp dport {22, 25, 143, 587, 993} ip saddr @china drop # Allow non-users to access public services, just limit the rate. tcp dport {25, 53, 70, 443, 5269} ip saddr @not-users limit rate 1/minute accept udp dport {53} ip saddr @not-users limit rate 1/minute accept # That's it for non-users. ip saddr @not-users drop # Allow SSH, SMTP, DNS, Gopher, HTTP, IMAP, HTTPS, SMTP # submission, IMAPS, ZNC, IRC, and XMPP-related ports: file # transfer proxy, client connections, server connections, # TURN/STUN. tcp dport { 22, 25, 53, 70, 80, 143, 443, 587, 993, 1500, 5000, 6697, 5222, 5269, 3478, 3479, 5349, 5350, 49152-65535 } accept # Also allow UDP ports: 53 for DNS, 68 for DHCP, 3478 for # TURN/STUN (along with 5349 for TLS, port+1 as alternatives, # 49152-65535 for relaying). udp dport {53, 68, 3478, 3479, 5349, 5350, 49152-65535} accept # Private network ports ip daddr 10.0.255.62 tcp dport {80,6667} accept; ip daddr 10.0.255.62 ip saddr 10.0.255.66 tcp dport {7000} accept; } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }