我想运行一个开放的托尔路由器。
我的退出政策将类似于减少退出政策。
但我也想让 Tor 网络很难滥用我的资源。
我想阻止客户通过 Tor 进行的情况:
- 用大量数据包攻击一个站点。
- 对整个 IP 块进行积极的网络扫描
我不想阻止客户通过 Tor 进行的情况:
- 将数百个图像文件上传到云端
- 播种种子
我的问题是,这是否可以做到,以及如何做到?
我的第一个想法是一些防火墙(Linux/iptables 或 *BSD/ipfw/pf) - 但由于洋葱路由器的固有属性,这可能毫无用处。
是否有关于此主题的正在进行的 torproject 团队开发?
我还要求获得有关保护 Tor 出口节点的一般提示。
更新(2012 年 9 月)
根据有用的答案和一些其他研究,我认为这是无法做到的。
要阻止人们滥用出口节点在 DDOS 中做出贡献,您能做的最好的事情就是检测定向到一个 IP 的非常频繁的数据包。
“非常频繁”的阈值取决于总节点带宽……如果错误,就会出现误报,从而阻止实时 TCP 应用程序的合法流量以及从大量客户端发送到一个目的地的流量。
更新(2014 年 12 月)
我的预测显然是正确的 - 我收到了几起来自我的互联网提供商的网络滥用投诉。
为了避免服务关闭,我必须采用以下一组iptables
规则(ONEW
是传出 TCP SYN(又名新)数据包的链:
我不确定这是否足够,但它是:
-A ONEW -o lo -j ACCEPT
-A ONEW -p udp --dport 53 -m limit --limit 2/sec --limit-burst 5 -j ACCEPT
-A ONEW -m hashlimit --hashlimit-upto 1/second --hashlimit-mode dstip --hashlimit-dstmask 24 --hashlimit-name ONEW -j ACCEPT
-A ONEW -m limit --limit 1/sec -j LOG --log-prefix "REJECTED: "
-A ONEW -j REJECT --reject-with icmp-admin-prohibited
答案1
请记住:
根据我目前的理解,Tor 客户端每 10 分钟左右就会切换一次虚拟电路。这意味着源 IP 在该时间范围内发生变化。您不可能阻止任何您认为恶意的行为超过该持续时间。
请注意,Tor 仅代理 TCP 流量而不代理任何其他协议这一事实在很大程度上限制了滥用的可能性。
iptables
可以让您以不同于现有连接的方式对待新的传出 TCP 连接。任何东西都ESTABLISHED,RELATED
应该ACCEPTED
通过“现有的 TCP 连接”链,并且不被该链捕获的传出 TCP 可能会受到速率限制。任何传出的 Tor 流量都应遵守此规定。
我相信在上述内容和使用“减少退出政策”之间将是您能做的最好的事情。
理想情况下,不要在 Tor 盒子上运行任何其他东西,除了:
- 您可能至少会启动 SSH,并将其放在与 22 不同的端口上。
- 您可能需要运行一个简单的网络服务器来显示这一页。 chroot
mini-httpd
实例应该可以。不要使用inetd
.
不要在正在用于其他用途的机器上运行 Tor。确保您已阅读《退出继电器》部分Tor 法律常见问题解答并充分理解其含义。还阅读并完成所有这些。
答案2
由于源 IP 不是恒定的,因此阻止这些攻击将比平常更困难。然而,据我所知,tor 的路线每隔几分钟左右就会改变一次。
因此,您仍然可以部署一些标准限制/过滤规则,但具有更高的阈值,因为您必须假设源 IP 背后有一个完整的网络。
您可以过滤:
- 错误或典型的指纹/扫描数据包(错误的 TCP/IP 标志、XMAS、大多数 ICMP 类型等)
- 不适合正在进行的或新的连接的无效数据包(-m 状态)
- 新连接以相当高的阈值开始
但是,请注意,此类操作通常是在入站流量上完成的。您不知道您的“客户”将运行哪种协议,并且您可能会以令人烦恼/不清楚的方式限制它们。
另外,对于速率限制的新(或无状态)数据包,您可能需要考虑一些更复杂的方案,其中被拒绝的(永远不会丢弃,除非它明显是攻击!)数据包是随机的。这样,即使总体速率当前处于限制,普通用户也可以尝试重新加载并获得幸运,而并发端口扫描器将无法绕过您的速率限制。
另外在 Tor 邮件列表上询问,您可能不是第一个有这样想法的人:https://lists.torproject.org/cgi-bin/mailman/listinfo
答案3
首先,我不建议 iptables 来解决所有这些问题,实际上,理想的出口 Tor 节点会通过一些 VPN 隧道加载平衡流量,以使 ISP 的视线远离数据包和真实目的地和/或利用缓存代理来保留出站重复请求流行静止的内容最少......在研究这些选项时,这里有一个创可贴对于滥用投诉问题;
使用的信息来源
http://www.ossramblings.com/using_iptables_rate_limiting_to_prevent_portscans
将两个源链接组合成规则,可用于挫败尝试使用 Tor 出口节点进行端口扫描的机器人。请注意,这可能会让使用您的退出节点的黑客非常不高兴,因为这些规则会导致 nmap 挂起时间。
#!/bin/bash
## Network interface used by Tor exit daemon
_tor_iface="eth1"
## Ports that Tor exit daemon binds to, maybe comma or space sepperated.
_tor_ports="9050,9051"
## Time to ban connections out in secconds, default equates to 10 minutes, same as default Tor cercut.
_ban_time="600"
## How long to monitor conections in seconds, default equates to 10 minutes.
_outgoing_tcp_update_seconds="600"
## How many new connections can be placed to a server in aloted update time limits. May nead to increes this depending on exit node usage and remote servers usages.
_outgoing_tcp_hitcount="8"
## How long to monitor connections for in minuets, default is 15 minutes but could be lessoned.
_outgoing_tcp_burst_minute="15"
## Hom many connections to accept untill un-matched
_outgoing_tcp_burst_limit="1000"
iptables -N out_temp_ban -m comment --comment "Make custom chain for tracking ban time limits" || exit 1
iptables -A out_temp_ban -m recent --set --name temp_tcp_ban -p TCP -j DROP -m comment --comment "Ban any TCP packet coming to this chain" || exit 1
iptables -N out_vuln_scan -m comment --comment "Make custom chain for mitigating port scans originating from ${_tor_iface}" || exit 1
for _tor_port in ${_tor_ports//,/ }; do
iptables -A out_vuln_scan -p TCP -o ${_tor_iface} --sport ${_tor_port} -m recent --name temp_tcp_ban --update --seconds ${_ban_time} -j DROP -m comment --comment "Update ban time if IP address is found in temp_tcp_ban list" || exit 1
iptables -A out_vuln_scan -p TCP -o ${_tor_iface} --sport ${_tor_port} -m state --state NEW -m recent --set -m comment --comment "Monitor number of new conncetions to ${_server_iface}" || exit 1
iptables -A out_vuln_scan -p TCP -o ${_tor_iface} --sport ${_tor_port} -m state --state NEW -m recent --update --seconds 30 --hitcout 10 -j out_temp_ban -m comment --comment "Ban address when to many new connections are attempted on ${_tor_iface}" || exit 1
done
iptables -A out_vuln_scan -j RETURN -m comment --comment "Return un-matched packets for further processing" || exit 1
## Add rules to accept/allow outbound packets
iptables -N tor_out -m comment --comment "Make custom chain for allowing Tor exit node services" || exit 1
for _tor_port in ${_tor_ports//,/ }; do
iptables -A tor_out -p TCP -o ${_tor_iface} --sport ${_tor_port} -m state --state NEW -m recent --set --name limit_${_tor_port} -m comment --comment "Track out-going tcp connections from port ${_tor_port}" || exit 1
iptables -A tor_out -p TCP -o ${_tor_iface} --sport ${_tor_port} -m state --state NEW -m recent --update --seconds ${_outgoing_tcp_update_seconds:-60} --hitcount ${_outgoing_tcp_hitcount:-8} --rttl --name limit_${_tor_port} -j LOG --log-prefix "TCP flooding port ${_tor_port}" -m comment --comment "Log atempts to flood port ${_tor_port} from your server" || exit 1
iptables -A tor_out -p TCP -o ${_tor_iface} --sport ${_tor_port} -m state --state NEW -m recent --update --seconds ${_outgoing_tcp_update_seconds:-60} --hitcount ${_outgoing_tcp_hitcount:-8} --rttl --name limit_${_tor_port} -j DROP -m comment --comment "Drop attempts to flood port ${_tor_port} from your server" || exit 1
iptables -A tor_out -p TCP -o ${_tor_iface} --sport ${_tor_port} -m limit --limit ${_outgoing_tcp_burst_minute:-15}/minute --limit-burst ${_outgoing_tcp_burst_limit:-1000} -j ACCEPT -m comment --comment "Accept with conditions new connections from port ${_tor_port} from your server" || exit 1
done
iptables -A tor_out -j RETURN -m comment ---comment "Reurn un-matched packets for further filtering or default polices to take effect." || exit 1
## Activate jumps from default output chain to new custom filtering chains
iptables -A OUTPUT -p TCP -o ${_tor_iface} -j out_vuln_scan -m comment --comment "Jump outbound packets through vulnerability scaning mitigation" || exit 1
iptables -A OUTPUT -p TCP -o ${_tor_iface} -j tor_out -m comment --comment "Jump outbound packets through conditional acceptance" || exit 1
运行上面的 withbash
来对带有 cammas 的变量执行魔法,,
即;
user@host~# bash iptables_limit_tor.sh
这又是变量列表
_tor_iface="eth1"
_tor_ports="9050,9051"
_ban_time="600"
_outgoing_tcp_update_seconds="600"
_outgoing_tcp_hitcount="8"
_outgoing_tcp_burst_minute="15"
_outgoing_tcp_burst_limit="1000"
请注意,您可能还希望过滤新的出站连接以查找-m state NEW ! --syn
各种类型的连接有趣的一些机器人使用业务来查找可利用的服务器,这是一个示例链,您可以使用上面的两个链来进一步过滤此类格式错误的聊天内容
iptables -N out_bad_packets -m comment --comment "Make new chain for filtering malformed packets" || exit 1
iptables -A out_bad_packets -p TCP --fragment -j out_temp_ban -m comment --comment "Drop all fragmented packets" || exit 1
iptables -A out_bad_packets -p TCP -m state --state INVALID -j out_temp_ban -m comment --comment "Drop all invalid packets" || exit 1
iptables -A out_bad_packets -p TCP ! --syn -m state --state NEW -j out_temp_ban -m comment --comment "Drop new non-syn packets" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL NONE -j out_temp_ban -m comment --comment "Drop NULL scan" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL ALL -j out_temp_ban -m comment --comment "Drop XMAS scan"|| exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL FIN,URG,PSH -j out_temp_ban -m comment --comment "Drop stealth scan 1" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL SYN,RST,ACK,FIN,URG -j out_temp_ban -m comment --comment "Drop pscan 1"|| exit 1
iptables -A out_bad_packets -p TCP --tcp-flags SYN,FIN SYN,FIN -j out_temp_ban -m comment --comment "Drop pscan 2" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags FIN,RST FIN,RST -j out_temp_ban -m comment --comment "Drop pscan 3" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags SYN,RST SYN,RST -j out_temp_ban -m comment --comment "Drop SYN-RST scan" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ACK,URG URG -j out_temp_ban -m comment --comment "Drop URG scans" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL SYN,FIN -j out_temp_ban -m comment --comment "Drop SYNFIN scan" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL URG,PSH,FIN -j out_temp_ban -m comment --comment "Drop nmap Xmas scan" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL FIN -j out_temp_ban -m comment --comment "Drop FIN scan" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags ALL URG,PSH,SYN,FIN -j out_temp_ban -m comment --comment "Drop nmap-id scan" || exit 1
iptables -A out_bad_packets -p TCP --tcp-flags RST RST -o ${_tor_iface} --sport ${_tor_port} -m limit --limit 2/second --limit-burst 3 -j out_temp_ban -m comment --comment "Mitigate Smurf attacks from excesive RST packets"
iptables -A out_bad_packets -p TCP --tcp-flags RST RST -o ${_tor_iface} --sport ${_tor_port} -m limit --limit 2/second --limit-burst 2 -j RETURN -m comment --comment "Ban Smurf attacks using excesive RST packets"
iptables -A out_bad_packets -j RETURN -m comment --comment "Return un-matched packets for further processing." || exit 1
然而,上述链将受到非常严格的限制,因为任何匹配的数据包都将禁止该 IP(可能更改-j out_temp_ban
为-j DROP
或-j REJECT
用于测试),无论该链的规则中选择多少秒。当客户端上编码错误的应用程序通过新的 Tor cercut 重新连接时,这组规则还可能导致误报。
~~~~~~
用于进一步调整流量的软件 Checkout firejail
for Linux,源代码在 Github 和 Source forge 上,手册页可以在旧主页(wordpress 子域)上找到,DigitalOcean 有一个使用 PHP 和 Firejail 的 Nginx 指南,稍加修改就可以让您更加了解应该在哪里限制网络。还有其他工具,例如KVM
太,可用于将特殊服务保持在操作边界内,以便店铺找到最适合您的系统的一个。
还有一种选择是以这样的方式运行fail2ban
:当疯狂的系统管理员尝试通过 http 或 ssl 连接到您的 IP 时,会添加一条规则来删除-m state --state NEW
与那些请求退出通知页面的连接。如果与合理的解除禁令时间限制相结合,可能会允许远程服务器在系统管理员抱怨日志污染时休息;-)但是,这超出了当前答案的范围,并且取决于您使用的服务软件退出通知页面;提示如果现在请求 URL,nginx 和 apache 都将为您的配置中的第一个虚拟主机或服务器块提供服务。如果使用 apache 或 nginx 以外的其他东西,您需要查阅手册页,但对我来说,这就像将第一个虚拟主机设置为登录到不同的文件一样简单,并让fail2ban将该日志中的任何 IP 添加到临时禁止列表中;这对于禁止公共服务器上的机器人也非常有效,因为它们通常使用 IP 地址,并且不提供域请求会导致服务器提供机器人陷阱,或者在本例中为退出通知。
我倾向于运行受限制的 Tor 退出策略(看起来您已经处理了该策略),然后通过 VPN 隧道推送流量,为多个隧道之间的负载平衡提供额外的信用点。因为这会减少对 Tor 网络流量的干扰,并使您的 ISP 无法察觉到您正在运行出口节点……除非他们愿意承认嗅探和破解您的 VPN 流量。这是因为运行临时禁止或允许远程主机自我禁止的规则可能会导致节点客户端的隐私受到侵犯,而将流量推送到 VPN(或少数)将有助于保护客户端的隐私并保留您的信息。 ISP免遭追捕要求任何有能力运行的政府都会记录您的网络流量日志whois www.some.domain
。
~~~
编辑/更新
~~~
我查阅了详细的笔记并提取了我使用的公共服务器的配置
这是fail2banjail.local
斯坦萨
[apache-ipscan]
enabled = true
port = http,https
filter = apache-ipscan
logpath = /var/log/apache*/*error_ip*
action = iptables-repeater[name=ipscan]
maxretry = 1
这是过滤器apache-ipscan.conf
文件
[DEFAULT]
_apache_error_msg = \[[^]]*\] \[\S*:error\] \[pid \d+\] \[client <HOST>(:\d{1,5})?\]
[Definition]
failregex = \[client <HOST>\] client denied by server .*(?i)/.*
#^<HOST>.*GET*.*(?!)/.*
# ^%(_apache_error_msg)s (AH0\d+: )?client denied by server configuration: (uri )?.*$
# ^%(_apache_error_msg)s script '\S+' not found or unable to stat(, referer: \S+)?\s*$
ignoreregex =
# DEV Notes:
# the web server only responds to clients with a valid Host:
# header. anyone who tries using IP only will get shunted into
# the dummy-error.log and get a client-denied message
#
# the second regex catches folks with otherwise valid CGI paths but no good Host: header
#
# Author: Paul Heinlein
这是操作iptables-repeater.conf
文件
# Fail2Ban configuration file
#
# Author: Phil Hagen <[email protected]>
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning and Lukas Camenzind for persistent banning
# Modified by S0AndS0 to combine features of previous Authors and Modders
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = iptables -N fail2ban-BADIPS-<name>
iptables -A fail2ban-BADIPS-<name> -j RETURN
iptables -I INPUT -j fail2ban-BADIPS-<name>
## Comment above line and uncomment bello line to use multiport and protocol in addition to named jails
#iptables -I INPUT -p <protocol> -m multiport --dports <port> -j fail2ban-BADIPS-<name>
# set up from the static file
#cat /etc/fail2ban/ip.blocklist.<name> |grep -v ^\s*#|awk '{print $1}' | while read IP; do iptables -I fail2ban-BADIPS-<name> 1 -s $IP -j DROP; done
cat /etc/fail2ban/ip.blocklist.<name> |grep -v ^\s*#|awk '{print $1}' | while read IP; do iptables -I fail2ban-BADIPS-<name> 1 -d $IP -j DROP; done
## Comment above line and uncomment bellow line to check if there are blacklist files to load before attempting to load them
# if [ -f /etc/fail2ban/ip.blacklist.<name> ]; then cat /etc/fail2ban/ip.blacklist.<name> | grep -e <name>$ | cut -d "," -s -f 1 | while read IP; do iptables -I fail2ban-BADIPS-<name> 1 -s $IP -j DROP; done; fi
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -j fail2ban-BADIPS-<name>
iptables -F fail2ban-BADIPS-<name>
iptables -X fail2ban-BADIPS-<name>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
#actioncheck = iptables -n -L INPUT | grep -q fail2ban-BADIPS-<name>
actioncheck = iptables -n -L OUTPUT | grep -q fail2ban-BADIPS-<name>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
#actionban = if ! iptables -C fail2ban-BADIPS-<name> -s <ip> -j DROP; then iptables -I fail2ban-BADIPS-<name> 1 -s <ip> -j DROP; fi
actionban = if ! iptables -C fail2ban-BADIPS-<name> -d <ip> -j DROP; then iptables -I fail2ban-BADIPS-<name> 1 -d <ip> -j DROP; fi
# Add offenders to local blacklist, if not already there
if ! grep -Fxq '<ip>,<name>' /etc/fail2ban/ip.blocklist.<name>; then echo "<ip>,<name> # fail2ban/$( date '+%%Y-%%m-%%d %%T' ): auto-add for BadIP offender" >> /etc/fail2ban/ip.blocklist.<name>; fi
# Report offenders to badips.com
# wget -q -O /dev/null www.badips.com/add/<name>/<ip>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
#actionunban = iptables -D fail2ban-REPEAT-<name> -s <ip> -j DROP
actionunban = iptables -D fail2ban-REPEAT-<name> -d <ip> -j DROP
# Disabled clearing out entry from ip.blacklist (somehow happens after each stop of fail2ban)
#sed --in-place '/<ip>,<name>/d' /etc/fail2ban/ip.blacklist.<name>
[Init]
# Defaut name of the chain
#
# Defaut name of the chain
name = BADIPS
# Option: port
# Notes.: specifies port to monitor
# Values: [ NUM | STRING ] Default:
#
#port = ssh
# Option: protocol
# Notes.: internally used by config reader for interpolations.
# Values: [ tcp | udp | icmp | all ] Default: tcp
请注意,上面的过滤器已被编辑为阻止OUTPUT
启动/停止操作,但您仍然需要将-p TCP -m state --state NEW
配置添加到每一行,以便仅禁止来自记录的 IP 地址的新出站连接。
最后是设置一个 Apache vHost 配置,将那些不请求域的内容路由到特定的访问和错误日志,并设置允许与拒绝的访问,以便它总是出错,甚至环回也不能在不弹出错误的情况下拉出页面。最后但并非最不重要的是将 Apache 的错误页面设置为 Tor 的默认退出通知,以便提供该通知而不是503
平淡404
的消息。或者,如果您已将状态行添加到fail2ban 的 iptables 操作中,您可以轻松地指向退出通知所使用的同一日志文件。结果将是您的服务器将无法与检查您的 IP 地址的服务器的 IP 建立新连接,但已建立的相关连接仍将被允许,即它们仍然可以浏览您的其他页面,但您无法浏览这些页面。
答案4
我有一个更好的解决方案:squid 缓存服务器。 Squid 缓存服务器可用于配置定义acl
和您deny
或accept
每个acl
.非常有趣的是,鱿鱼团队在您的问题发现的维基中定义了一组规则那里 iptables,PF
否则其他人无法完成您的工作,因为您只是在另一层工作。