TCP Close 5 sec, Anti DDoS iptables

Setup of a Tor relay as a middle relay or guard relay, as an example:

### 1) Internet connection

Fiber-optic FTTH connection: 150 Mbit/s download / 150 Mbit/s upload.

### 2) UXG Pro + UniFi Network Application + UniFi Switch

UXG Pro (UniFi firmware version 5.1.26 minimum) + Raspberry Pi running Debian as an external UniFi Network Application, version 10.4.57 minimum (not used as a Tor relay) + UniFi Switch Flex Mini 2.5G.

#### 2a) IPv4 configuration

In the Network Controller window:

Click **Settings** → **Internet** → **Internet 1**.

A side panel opens.

Configure:

* VLAN ID: 7

* IPv4 configuration:

* Connection: PPPoE

* DNS server: Automatic

#### 2b) IPv6 configuration

Configure:

* IPv6: SLAAC

* Prefix Delegation: /56

(required because of `ORPort [::]:9001` in `torrc`)

* DNS server: Automatic

Click **Save**.

#### 2c) Automatic Firewall State Timeouts

In the Network Controller window:

Click **UniFi Devices** → **Gateway Pro**.

A side panel opens.

Go to:

**Settings** → **Advanced** → disable **Automatic Firewall State Timeouts** (mandatory).

Enter the following values manually:

* ICMP: 20 sec

* Other: 200 sec

* TCP Close: 5 sec

* TCP Close Wait: 10 sec

* TCP Established: 3600 sec

* TCP Fin Wait: 20 sec

* TCP Last ACK: 20 sec

* TCP Syn Recv: 5 sec

* TCP Syn Sent: 5 sec

* TCP Time Wait: 10 sec

* UDP Other: 600 sec

* UDP Stream: 600 sec

Click **Save**.

Target:

* Packet loss: 0%

* Latency: max. 10 ms

#### 2d) Optional: increase conntrack table size

```bash

sudo nano /etc/sysctl.d/XX-tor.conf

```

Add:

```text

net.netfilter.nf_conntrack_max=140000

```

#### 2e) Port forwarding for port 9001

In the Network Controller window:

Click **Settings** → **Port Forwarding** → **Create New Rule**.

Example configuration:

* Name: Port9001

* WAN: WAN1

* WAN Port: 9001

* From: Any

* Forward IP Address: 192.168.1.200

* Forward Port: 9001

* Protocol: TCP

Click **Save**.

#### 2f) Disable UniFi Threat Management / IDS/IPS depending on CPU load

The firewall is sufficient for this setup.

In the Network Controller window:

Click **Settings** → **CyberSecure** → set **Intrusion Prevention** to **Off**.

Click **Save**.

### 3) Raspberry Pi 5 as Tor relay

Raspberry Pi 5 with 4 GB RAM, or multiple devices, used as Tor relays.

Example name:

**Port9001**

Use a High Endurance SD card, or preferably an SSD.

Maximum relay bandwidth: approximately 30 Mbit/s.

Optionally install an ICE Tower cooler.

Power consumption: approximately 5 watts.

A Raspberry Pi 4 is not useful for this setup.

An Intel Core i5-12500T may be capable of approximately 80 Mbit/s (?).

#### 3a) Configure a fixed IP address on the UXG Pro

In the Network Controller window:

Click **Client Devices** → select the **Raspberry Pi**.

A side panel opens.

Go to **Settings**.

Configure:

* Name: Port9001

* IP Settings:

* Fixed IP Address: 192.168.1.200

Click **Save**.

Optional:

Create a separate VLAN and enable network isolation.

#### 3b) Raspberry Pi: install and configure Tor

Install Tor first.

Then open a terminal window and run:

```bash

sudo pcmanfm

```

Press Enter.

A new file manager window opens.

Open:

```text

/etc/tor/torrc

```

Insert the following configuration:

```text

SocksPort 0

Log notice file /var/log/tor/notices.log

ControlPort 9051

CookieAuthentication 1

ORPort 9001

ORPort [::]:9001

ExitPolicy reject *:*

ExitRelay 0

Nickname xx

RelayBandwidthRate 30 Mbits

RelayBandwidthBurst 31 Mbits

MaxMemInQueues 0

DisableDebuggerAttachment 1

AvoidDiskWrites 1

HeartbeatPeriod 3 hours

DataDirectory /var/lib/tor

ContactInfo xx@xx.com

MyFamily $xx, $xy # optional

FamilyID xxxx # optional

```

#### 3c) Increase the systemd file descriptor limit

Run:

```bash

sudo pcmanfm

```

Open:

```text

/lib/systemd/system/tor.service

```

Under `[Service]`, add:

```text

LimitNOFILE=65535

```

#### 3d) Kernel/network settings

Run:

```bash

sudo pcmanfm

```

Open either:

```text

/etc/sysctl.conf

`

``

or preferably:

```text

/etc/sysctl.d/tor.conf

```

Add:

```text

net.core.rmem_max = 16777216

net.core.wmem_max = 16777216

net.ipv4.tcp_max_syn_backlog = 4096

net.ipv4.ip_local_port_range = 15000 64000

```

### 4) Ask ChatGPT


Anti DDoS strong (like toralf):

DDoS protection for IPv4 and IPv6 addresses per Tor relay:

```text

0.0.0.0:9001

[::]:9001

```

-–

## Objective

IPv4 > 3/min → block for 7 days

IPv4 > 7/h → block for 7 days

IPv6 > 3/min → block the /64 for 7 days

IPv6 > 7/h → block the /64 for 7 days

> 5 simultaneous connections from one source → DROP

> ESTABLISHED → never touch

ORPort → 9001

IPv4 → 0.0.0.0:9001

IPv6 → [::]:9001

-–

IPv4: `tor-ddos-v4`

IPv6: `tor-ddos-v6`

3/min

7/hour

7-day timeout

maximum 5 simultaneous connections per IPv4 address or IPv6 /64

persistent storage

restore at boot

automatic save every 5 minutes

-–

```bash

sudo -i

```

## 1. Stop Tor and install packages

```bash

systemctl status tor.service --no-pager

systemctl status tor@default.service --no-pager

sudo systemctl stop tor.service

sudo systemctl stop tor@default.service 2>/dev/null || true

sudo ss -lntp | grep ‘:9001’ || true

sudo apt update

sudo apt install -y jq ipset iptables

jq --version

ipset --version

iptables --version

ip6tables --version

```

-–

## 2. Create IPv4 and IPv6 blocklists

IPv4 blocks individual addresses. IPv6 stores the complete /64 network.

```bash

sudo ipset create tor-ddos-v4 hash:ip \

family inet timeout 604800 -exist

sudo ipset create tor-ddos-v6 hash:ip \

family inet6 netmask 64 timeout 604800 -exist

```

Check:

```bash

sudo ipset list tor-ddos-v4 | head -12

sudo ipset list tor-ddos-v6 | head -12

```

For IPv6, the following must appear:

```text

Type: hash:ip

Header: family inet6 … netmask 64 timeout 604800

```

-–

## 3. Create firewall chains

```bash

sudo iptables -N TOR-DDOS-V4

sudo ip6tables -N TOR-DDOS-V6

```

Always accept established connections:

```bash

sudo iptables -I INPUT 1 \

-m conntrack --ctstate ESTABLISHED,RELATED \

-j ACCEPT

sudo ip6tables -I INPUT 1 \

-m conntrack --ctstate ESTABLISHED,RELATED \

-j ACCEPT

```

Route new SYN connections to port 9001 into the protection chains:

```bash

sudo iptables -A INPUT \

-p tcp --dport 9001 --syn \

-m conntrack --ctstate NEW \

-j TOR-DDOS-V4

sudo ip6tables -A INPUT \

-p tcp --dport 9001 --syn \

-m conntrack --ctstate NEW \

-j TOR-DDOS-V6

```

-–

## 4. Drop sources that are already blocked

Add only one such DROP rule for each protocol:

```bash

sudo iptables -A TOR-DDOS-V4 \

-m set --match-set tor-ddos-v4 src \

-j DROP

sudo ip6tables -A TOR-DDOS-V6 \

-m set --match-set tor-ddos-v6 src \

-j DROP

```

-–

## 5. Block more than three new connections per minute

IPv4:

```bash

sudo iptables -A TOR-DDOS-V4 \

-p tcp --dport 9001 \

-m hashlimit \

--hashlimit-above 3/minute \

--hashlimit-burst 3 \

--hashlimit-mode srcip \

--hashlimit-name tor-ddos-v4-3m \

-j SET --add-set tor-ddos-v4 src --exist

```

IPv6, grouped by /64:

```bash

sudo ip6tables -A TOR-DDOS-V6 \

-p tcp --dport 9001 \

-m hashlimit \

--hashlimit-above 3/minute \

--hashlimit-burst 3 \

--hashlimit-mode srcip \

--hashlimit-srcmask 64 \

--hashlimit-name tor-ddos-v6-3m \

-j SET --add-set tor-ddos-v6 src --exist

```

-–

## 6. Block more than seven new connections per hour

IPv4:

```bash

sudo iptables -A TOR-DDOS-V4 \

-p tcp --dport 9001 \

-m hashlimit \

--hashlimit-above 7/hour \

--hashlimit-burst 7 \

--hashlimit-mode srcip \

--hashlimit-name tor-ddos-v4-7h \

-j SET --add-set tor-ddos-v4 src --exist

```

IPv6, grouped by /64:

```bash

sudo ip6tables -A TOR-DDOS-V6 \

-p tcp --dport 9001 \

-m hashlimit \

--hashlimit-above 7/hour \

--hashlimit-burst 7 \

--hashlimit-mode srcip \

--hashlimit-srcmask 64 \

--hashlimit-name tor-ddos-v6-7h \

-j SET --add-set tor-ddos-v6 src --exist

```

-–

## 7. Maximum of five simultaneous connections

IPv4 per individual address:

```bash

sudo iptables -A TOR-DDOS-V4 \

-p tcp --dport 9001 \

-m connlimit \

--connlimit-above 5 \

--connlimit-mask 32 \

--connlimit-saddr \

-j DROP

```

IPv6 grouped by /64:

```bash

sudo ip6tables -A TOR-DDOS-V6 \

-p tcp --dport 9001 \

-m connlimit \

--connlimit-above 5 \

--connlimit-mask 64 \

--connlimit-saddr \

-j DROP

```

Accept all remaining new Tor connections:

```bash

sudo iptables -A TOR-DDOS-V4 \

-p tcp --dport 9001 \

-j ACCEPT

sudo ip6tables -A TOR-DDOS-V6 \

-p tcp --dport 9001 \

-j ACCEPT

```

Check:

```bash

sudo iptables -L TOR-DDOS-V4 -n -v --line-numbers

sudo ip6tables -L TOR-DDOS-V6 -n -v --line-numbers

```

Expected order:

```text

1 DROP match-set

2 SET above 3/min burst 3

3 SET above 7/hour burst 7

4 DROP connlimit above 5

5 ACCEPT tcp dpt:9001

```

-–

## 8. Save the firewall state for the first time

```bash

sudo mkdir -p /var/lib/tor-ddos

sudo chmod 700 /var/lib/tor-ddos

```

The redirection must also be performed with root privileges:

```bash

sudo sh -c \

‘/usr/sbin/iptables-save > /var/lib/tor-ddos/rules.v4’

sudo sh -c \

‘/usr/sbin/ip6tables-save > /var/lib/tor-ddos/rules.v6’

sudo sh -c \

‘/usr/sbin/ipset save tor-ddos-v4 > /var/lib/tor-ddos/tor-ddos-v4.ipset’

sudo sh -c \

‘/usr/sbin/ipset save tor-ddos-v6 > /var/lib/tor-ddos/tor-ddos-v6.ipset’

```

Check:

```bash

sudo ls -lh /var/lib/tor-ddos

```

Four files must exist and each must be larger than zero bytes.

-–

## 9. Create the restore script

```bash

sudo tee /root/tor-ddos-restore.sh >/dev/null <<‘EOF’

#!/bin/bash

set -e

/usr/sbin/ipset restore -exist \

< /var/lib/tor-ddos/tor-ddos-v4.ipset

/usr/sbin/ipset restore -exist \

< /var/lib/tor-ddos/tor-ddos-v6.ipset

/usr/sbin/iptables-restore \

< /var/lib/tor-ddos/rules.v4

/usr/sbin/ip6tables-restore \

< /var/lib/tor-ddos/rules.v6

EOF

sudo chmod 700 /root/tor-ddos-restore.sh

```

-–

## 10. Create the restore service

```bash

sudo tee /etc/systemd/system/tor-ddos-restore.service >/dev/null <<‘EOF’

[Unit]

Description=Restore Tor DDoS firewall rules

Before=tor.service tor@default.service

After=network-pre.target

Wants=network-pre.target

[Service]

Type=oneshot

ExecStart=/root/tor-ddos-restore.sh

RemainAfterExit=yes

[Install]

WantedBy=multi-user.target

EOF

```

-–

## 11. Create the save script

```bash

sudo tee /root/tor-ddos-save.sh >/dev/null <<‘EOF’

#!/bin/bash

set -e

/usr/sbin/iptables-save \

> /var/lib/tor-ddos/rules.v4

/usr/sbin/ip6tables-save \

> /var/lib/tor-ddos/rules.v6

/usr/sbin/ipset save tor-ddos-v4 \

> /var/lib/tor-ddos/tor-ddos-v4.ipset

/usr/sbin/ipset save tor-ddos-v6 \

> /var/lib/tor-ddos/tor-ddos-v6.ipset

EOF

sudo chmod 700 /root/tor-ddos-save.sh

```

-–

## 12. Create the save service

```bash

sudo tee /etc/systemd/system/tor-ddos-save.service >/dev/null <<‘EOF’

[Unit]

Description=Save Tor DDoS firewall state

After=tor-ddos-restore.service

[Service]

Type=oneshot

ExecStart=/root/tor-ddos-save.sh

EOF

```

-–

## 13. Create a repeating five-minute timer

```bash

sudo tee /etc/systemd/system/tor-ddos-save.timer >/dev/null <<‘EOF’

[Unit]

Description=Periodic Tor DDoS firewall state save

[Timer]

OnBootSec=5min

OnUnitActiveSec=5min

AccuracySec=30s

Unit=tor-ddos-save.service

[Install]

WantedBy=timers.target

EOF

```

-–

## 14. Create a dedicated real tor.service

```bash

sudo tee /etc/systemd/system/tor.service >/dev/null <<‘EOF’

[Unit]

Description=Tor relay

After=network-online.target tor-ddos-restore.service

Wants=network-online.target tor-ddos-restore.service

[Service]

Type=notify

NotifyAccess=all

User=debian-tor

Group=debian-tor

ExecStartPre=/usr/bin/tor --verify-config -f /etc/tor/torrc

ExecStart=/usr/bin/tor --RunAsDaemon 0 -f /etc/tor/torrc

ExecReload=/bin/kill -HUP $MAINPID

KillSignal=SIGINT

Restart=on-failure

RestartSec=5

TimeoutStartSec=300

TimeoutStopSec=60

LimitNOFILE=65535

[Install]

WantedBy=multi-user.target

EOF

```

Check the configuration:

```bash

sudo -u debian-tor /usr/bin/tor \

--RunAsDaemon 0 \

-f /etc/tor/torrc \

--verify-config

```

Expected:

```text

Configuration was valid

```

-–

## 15. Enable the services

```bash

sudo systemctl daemon-reload

sudo systemctl enable tor-ddos-restore.service

sudo systemctl enable --now tor-ddos-save.timer

sudo systemctl enable tor.service

```

Disable and mask the default instance:

```bash

sudo systemctl disable --now tor@default.service 2>/dev/null || true

sudo systemctl mask tor@default.service

sudo systemctl reset-failed tor@default.service

```

-–

## 16. Save once and test the restore

```bash

sudo systemctl start tor-ddos-save.service

sudo systemctl restart tor-ddos-restore.service

```

Check:

```bash

systemctl status tor-ddos-save.service --no-pager -l

systemctl status tor-ddos-restore.service --no-pager -l

```

After successful execution, the save service will return to:

```text

inactive (dead)

```

This is normal for `Type=oneshot` without `RemainAfterExit`.

The restore service must show:

```text

Active: active (exited)

status=0/SUCCESS

```

-–

## 17. Start Tor

```bash

sudo systemctl restart tor.service

```

Check:

```bash

systemctl status tor.service --no-pager -l

systemctl is-enabled tor.service

systemctl is-enabled tor@default.service

systemctl is-active tor.service

systemctl is-active tor@default.service

sudo ss -lntp |

grep -E ‘:(9001|9050|9051)\b’ || true

```

Expected:

```text

tor.service: enabled and active

tor@default.service: masked and inactive

```

The following ports may be open:

```text

127.0.0.1:9051

0.0.0.0:9001

[::]:9001

```

Port 9050 must not appear.

-–

## 18. Check the firewall

```bash

sudo ipset list tor-ddos-v4 |

grep -E ‘Type:|Header:|References:|Number of entries’

sudo ipset list tor-ddos-v6 |

grep -E ‘Type:|Header:|References:|Number of entries’

sudo iptables -L INPUT -n -v --line-numbers

sudo ip6tables -L INPUT -n -v --line-numbers

sudo iptables -L TOR-DDOS-V4 -n -v --line-numbers

sudo ip6tables -L TOR-DDOS-V6 -n -v --line-numbers

systemctl list-timers --all tor-ddos-save.timer

```

-–

## 19. Reboot

```bash

sudo systemctl start tor-ddos-save.service

sudo reboot

```

-–

## 20. Check everything after reboot

```bash

systemctl status tor-ddos-restore.service --no-pager -l

systemctl status tor-ddos-save.timer –

no-pager -l

systemctl status tor.service --no-pager -l

systemctl is-enabled tor.service

systemctl is-enabled tor@default.service

sudo ss -lntp | grep ‘:9001’

sudo ipset list tor-ddos-v4 |

grep -E ‘Type:|Header:|References:|Number of entries’

sudo ipset list tor-ddos-v6 |

grep -E ‘Type:|Header:|References:|Number of entries’

sudo iptables -L INPUT -n -v --line-numbers

sudo ip6tables -L INPUT -n -v --line-numbers

sudo iptables -L TOR-DDOS-V4 -n -v --line-numbers

sudo ip6tables -L TOR-DDOS-V6 -n -v --line-numbers

systemctl list-timers --all tor-ddos-save.timer

```