端口触发使用NAT Firestarter防火墙和Ghost在Debian / Ubuntu
许多玩PC游戏的游戏,如battle.net,需要能够设置端口触发。 典型的“硬件”路由器可以通过在线菜单进行设置。 然而,使用Linux PC来执行路由器功能可以提供比通过“硬件”路由器实现的更多的控制和多功能性。 所有的NAT(网络地址转换),防火墙和端口转发功能都可以由iptables实现,Linux是2.4.x和2.6.x中的实际防火墙。
我在网上看了很多,试图找到一个基于linux或iptables的端口触发设置。 使用iptables的端口转发有很多,但在端口触发方面并不是什么。 本文提供了使用iptables,firestarter,ULOG,Spectre和少量bash脚本来实现简单端口触发的细节。 ULOG是可以添加到iptables上的用户空间记录功能,允许数据包的多播。 Spectre是一个运行守护进程的程序,允许您通过订阅ULOG流来启动操作。 Firestarter是iptables的防火墙GUI前端,可以轻松连接到您的防火墙。 虽然似乎没有最新的firestarter的开发活动,但它仍然是一个可行的,用户友好的,易于安装的软件包,一旦正确配置,实际上不需要升级。 您需要安装才能使用此方法实现端口触发的唯一软件是firestarter,Spectre和几个bash脚本。 我的配置使用运行Debian Linux的PC(尽管以下说明也适用于Ubuntu)作为我的家庭LAN的路由器/防火墙,并且我的LAN中的大多数PC都在运行Windows(游戏PC)。
我用作为battle.net的示例端口触发。 其主要原因是我的儿子喜欢为此举办游戏,所以我有一个体面的测试人员,他已经证明了这个设置了好几个月。 Battle.net主要使用tcp端口6112; 这里的概念是,当内部局域网上的PC(例如192.168.0.102)启动到battle.net服务器站点的tcp连接以开始托管游戏时,PC将在tcp目标端口6112上启动此操作“触发”一系列临时重新配置防火墙的命令:它使端口6112能够在防火墙上打开,并将针对此端口的连接转发到机器192.168.0.102(“触发”(主机))机器。 在合理的时间段之后,端口关闭并被窃取,丢弃任何路由到它的数据包,以阻止任何外部干扰或攻击(像往常一样)。
通过指定将涉及哪个端口来实现端口触发。 在OUTBOUND链中添加了两个iptables规则,在我的设置(firestarter)中,在LAN上的OUTPUT流量进行了一些筛选之后,它们是从OUTPUT链跳转到的一组规则。 规则执行ULOG日志记录输出到nlgroup 20(任意数字),只匹配在NEW状态的TCP数据包。 当这些数据包被输出时,Spectre会执行一个bash文件。 bash文件设置其他iptables规则,并创建锁定文件,以便我们确保不创建冗余iptables规则。 除了将入口连接的端口转发规则设置到LAN上的启动PC之外,新的iptables规则还添加了另一个ULOG输出ulog-nlgroup 21.这以非常有限的速率预订数据包,特别是仅1分钟。 这将检查以确保发起连接的出站流量仍然有效; 如果在一段指定的时间(15分钟)内处于非活动状态,则转发规则被消除,并且触发设置被放弃。 这将端口触发与端口转发区分开来; 在端口转发中,转发是无限期实现的,安全性较低。
在我们开始之前,有一些假设:- 您正在使用两个NIC作为路由器/防火墙,
- 一个通过有线/ DSL调制解调器连接到互联网(我假设它是eth1),
- 一个连接到你的LAN(我假设是eth0)。
您可以使用以下命令检查系统中哪个卡:
/sbin/ifconfig
在具有两个卡的典型设备上,该命令的输出应该标识一个具有诸如“192.168.0.255”或“10.0.0.255”等广播ID的卡。在这种情况下,该接口是您的LAN接口,您应该将这里假设(eth0)改变为命令输出给定的值。 另一个接口应该访问互联网,并具有广播地址,如“255.255.255.255”。 如果它不同于“eth1”,那么在这个howto中将eth1更改为适当的值。
按照以下链接的说明设置Firestarter:
http://www.debianadmin.com/secure-ubuntu-desktop-using-firestarter-firewall.html
使用其向导,Firestarter可以轻松地配置为用作互联网连接共享的路由器。 它本质上是Linux iptables的GUI界面。
Firestarter的一个功能是您可以将自己的自定义规则插入到iptables中。 在Firestarter的配置脚本已经运行后,我们将使用它来插入两个规则。 这是通过创建文件来完成的:
/ etc / firestarter / user-post
使用以下两行(使用您最喜欢的编辑器,如nano;或者如果您使用gnome,则可以将这些行复制并粘贴到图形编辑器中):
$IPT -I OUTBOUND 4 -s 192.168.0.0/24 -i eth0 -p tcp -m tcp --dport 6112 -j ULOG --ulog-prefix "trigger write" --ulog-nlgroup 20 -m hashlimit --hashlimit 1/minute --hashlimit-burst 2 --hashlimit-mode srcip,dstport --hashlimit-name w6112
$IPT -I OUTBOUND 5 -s 192.168.0.0/24 -i eth0 -p tcp -m state --state NEW --dport 6112 -j ULOG --ulog-nlgroup 21 --ulog-prefix "initial trigger" -m hashlimit --hashlimit 1/minute --hashlimit-burst 2 --hashlimit-mode srcip,dstport --hashlimit-name n6112
(用您的LAN地址范围替换192.168.0.0/24,并使用适当的接口名称替换eth0)。 为了创建文件,您需要以root或root权限创建它。
这两个iptables规则将目的端口为6112(battle.net网络端口)的出站数据包注册到局域网。 当它看到这些数据包时,有限数量的数据将通过netlink套接字记录到用户空间。 我们下面安装的一个名为“Spectre”的软件包订阅这些套接字并对其进行操作。 初始数据包被记录到nlgroup 21,并且通过设置端口转发到启动PC,使用脚本来发起battle.net会话。 持续的数据包(不管它们是否处于新状态)被记录到nlgroup 20,并且使用脚本来跟踪启动PC是否仍然存在活动。 由于端口转发到内部LAN客户端打开端口到互联网,当您不玩游戏时,它不是您应该离开的地方。 只要数据包已经在15分钟内从这台PC发送出来,端口就被打开并转发。 15分钟不活动后,端口转发停止,会话关闭,假设游戏结束。 然后可以立即启动新的会话。
要在Debian或Ubuntu中安装Spectre,请执行以下命令:
sudo apt-get install specter specter-mysql specter-pgsql
我们将需要编辑Spectre配置文件/etc/specter.conf
,以便能够对用户空间进行操作。 将以下行添加到此文件的末尾:
# nlgroup 20, write to file /tmp/forward.6112 if dest port 6112 is outbound from LAN
20 {
:BASE
:EXEC
command "/bin/echo %S %P %d > /tmp/forward.6112"
}
# nlgroup 21, run script initial_trigger_action if a new tcp connection to dest port 6112 is outbound from LAN
21 {
:BASE
:EXEC
command "/etc/firestarter/initial_trigger_action"
}
同样,您将需要root权限才能保存此文件。
Ghost的主页是: http : //joker.linuxstuff.pl/specter/
接下来,创建bash脚本文件(它还需要root所有权),并保存为:
/etc/firestarter/initial_trigger_action
该文件包含以下行:
#!/bin/bash
# file initial_trigger_action %S %P %d
# script for initial trigger activity - run from specter for ulog-nlgroup 20
# check to verify lock file does not yet exist, if not, then
# create a lock file, /tmp/trigger.port.lock (port=port number to trigger on)
# add iptables rules for forwarding port number to source ip by using firestarter
# set up "at" file to check for continued activity from source on port
#
# find forward(date) file
# forwardfile=`ls -t1 forward* | grep -m 1 f`
# Source IP address
# Wait long enough for tmp file to be created by nlgroup 21 process
sleep 0.5
if [ -f /tmp/forward.6112 ]; then
while read inputline
do
SourceIP="$(echo $inputline | cut -d' ' -f1)"
Protocl="$(echo $inputline | cut -d' ' -f2)"
dest_port="$(echo $inputline | cut -d' ' -f3)"
done < /tmp/forward.6112
if [ -f /tmp/trigger.6112.lock ]; then echo "lock file already exists!! Get rid of it"; exit 1;
else
#
# write lock file
#
echo "$SourceIP $dest_port $Protocl" > /tmp/trigger.6112.lock
#
# add forwarding rules
# using firestarter
# add line in /etc/firestarter/inbound/forward
# of format:
# name, port, destIP, port, comment
# first copy forward to forward.backup
cat /etc/firestarter/inbound/forward > /etc/firestarter/inbound/forward.backup
# now add line to end and save forward
echo "f$dest_port, $dest_port, $SourceIP, $dest_port, fwd$dest_port-$SourceIP" | cat /etc/firestarter/inbound/forward - > /etc/firestarter/inbound/forward.tmp
cp /etc/firestarter/inbound/forward.tmp /etc/firestarter/inbound/forward
#
# now restart firestarter to activate forwarding
/etc/init.d/firestarter force-reload
# next step: run at command
at -f /etc/firestarter/trigger_test_6112 now + 5 minutes
fi
fi
# done
创建后,您将需要使用以下命令使其可执行:
sudo chmod 755 /etc/firestarter/initial_trigger_action
接下来,创建以下bash脚本文件(它还需要root所有权)并将其保存为:
/etc/firestarter/trigger_test_6112
这是文件:
#!/bin/bash
# file trigger_test_6112
# script to test for continued trigger activity - run from at command
# lock file should be updated from specter ulog-nlgroup 21
# if tcp connections for game have not been established yet
# check to verify lock file exists, if not, then exit with error
# lock file is /tmp/trigger.6112.lock
# if lock file exists, check time of last modification (mod used touch)
# if less than 15 minutes, run another at command and exit, continuing chain
# if 15 minutes or more, remove iptables forwarding rules for forwarding port
# number to source ip, and remove iptables rulse for ulogging to nlgroup 21
#
# read lock file
# first step - check for lock file existence
if [ -f /tmp/trigger.6112.lock ]; then echo "OK, file exists"
else echo "lock file does not exist!!"; exit 1
fi
# second step - read variables from lock file
while read inputline
do
SourceIP="$(echo $inputline | cut -d' ' -f1)"
Protocl="$(echo $inputline | cut -d' ' -f2)"
dest_port="$(echo $inputline | cut -d' ' -f3)"
done < /tmp/forward.6112
# next step: check to see if outgoing port has been triggered recently
fwd_file_age=`ls -lt --time-style=+%s /tmp/forward.6112 | awk '{print $6}'`
now_time=`date +%s`
time_diff=$[$now_time-$fwd_file_age]
echo " time diff = $time_diff "
if [ "$time_diff" -ge "600" ]; then
# delete lock file
# else run at file and exit 0
# remove line of forward file containing $dest_port
# using sed
sed "/$dest_port/d" "/etc/firestarter/inbound/forward" > /etc/firestarter/inbound/forward.temp
cp /etc/firestarter/inbound/forward.temp /etc/firestarter/inbound/forward
#
# restart firestarter to de-activate forwarding
/etc/init.d/firestarter force-reload
rm /tmp/trigger.6112.lock
fi
# run at file to test whether forwarding should still be implemented
#
at -f /etc/firestarter/trigger_test_6112 now + 5 minutes
# done
创建后,您将需要使用以下命令使其可执行:
sudo chmod 755 /etc/firestarter/trigger_test_6112
这些脚本在/ tmp目录中创建一些文件以进行调试; 它们可以被忽略,除了锁定文件(或者您可以修改脚本,如果您希望防止它们被创建)。 默认情况下,当会话启动时,在会话期间,邮件将发送到根,宣布会话的状态。 Firestarter的一个有用功能是您可以从外界监控谁连接到LAN PC的用户; 当battle.net会话正常工作时,您将在端口6112上看到几个连接到LAN PC的IP地址(例如192.168.0.102)。
有关此设置的几个注意事项:与此同时,您可以在LAN上的防火墙后面有多个游戏参与者,同时您有与主机PC的外部连接。 关键问题是主机PC需要成为第一个联系battle.net网站(第一个实际发出6112端口的请求)的主机。 该PC在最后一次尝试联系网站后被识别为主机15分钟,如果该PC不跟随并成为主机,而是不同的LAN PC尝试成为主机,那么它将无法直到脚本中的计时器过期,防火墙再次关闭。 如果您在局域网上的热心游戏玩家不注意这一要求,这可能是一种沮丧的根源。 此设置不会启用(或禁用)来自互联网的ping。 这可以在Firestarter中单独完成。 对于battle.net而言,允许ping(ICMP)不是必需的; 然而,它有时用于故障排除。 当游戏没有活动时,我更喜欢使我的防火墙完全隐藏,而且我还没有去改变游戏中ICMP的行为。
另外,bash / sed的大师们也会注意到我没有先进的脚本 - 我的目标是要做一些工作并足够的记录,让别人知道我做了什么。 我欢迎改进设置的建议; 正如我所提到的,我发现没有设置(OpenWrt外部,它需要专门的硬件),这将允许您执行游戏所需的自动端口触发类型,并在游戏结束时关闭端口,以提高安全性。 虽然这个设置是为Debian / Ubuntu编写的,但是对于其他Linux版本,它应该同样适用(正确修改安装说明)。 除了需要2个NIC之外,路由器/防火墙PC的硬件要求是非常适中的。 我没有终端,它在衣柜里搭配电缆调制解调器; 我通过使用远程VNC软件和SSH(来自Windows PC的Putty和ultraVNC)完全控制它。