Linux 家庭网络

作者:Preston F. Crow

我有一个相当复杂的家庭网络,它使用了 Linux 的许多不同功能。虽然我的网络设置可能比您在家中需要的更复杂,但您可能会发现您想使用一些相同的功能。在本文中,我将描述我的计算机是如何物理连接的,讨论我希望我的网络如何工作,然后解释我是如何使用 Linux 的各个方面来实现这些目标的。

物理层

我有三台台式电脑和一台笔记本电脑,通过有线调制解调器和 ISDN 线路提供互联网接入。其中一台台式电脑运行 Linux,负责互联网和内部网络之间的通信。

有线调制解调器是一个外部设备,可以将有线信号转换为以太网信号。我还使用一个外部 ISDN 调制解调器,其工作方式相同。它们都连接到我的中央 Linux 系统中的独立以太网卡。

这三台台式电脑使用带有集线器的以太网相互连接。然而,笔记本电脑没有以太网,因此它通过并行端口之间的电缆连接到我的中央 Linux 系统。

因此,中央计算机有三张以太网卡:一张用于有线调制解调器,一张用于 ISDN 调制解调器,一张用于连接其他机器的集线器。

它应该如何工作

首先,让我解释一下我的互联网连接是如何工作的。有线调制解调器提供一个动态 IP 地址和一个到通用互联网的快速连接。我的公司提供的 ISDN 线路连接到其内部网络,并为 ISDN 线路提供一个 16 个 IP 地址的子网。

我希望我的所有计算机都能相互通信,与我公司的内网和通用互联网通信。我想使用 ISDN 线路附带的 IP 地址作为我的内部网络。

子网和路由

我做的第一件事是将我的网络划分为子网。忘记您听到的关于不同类别的 IP 地址的任何信息;它们与家庭网络无关。这里的问题是子网划分。其思想是您拥有一系列连续的 IP 地址,并且您想将它们分成更小的独立块。唯一的限制是每个块上的地址数必须是 2 的幂。

在子网划分时,每个块的第一个地址称为“网络”地址。不要将其用于任何用途。块的最后一个地址是“广播”地址。同样,这也不用于任何特定机器。“子网掩码”为 255.255.255.x,其中 x 是 256 减去子网中的地址数。

IP 路由按网络或按地址进行处理。对于网络,您需要指定网络地址和子网掩码,而不仅仅是单个 IP 号码。在任何一种情况下,您都必须告诉它如何到达该地址。如果机器位于直接连接的网络上,您可以只指定一个网络接口;否则,您必须提供另一台将为您进行转发的机器的地址。

对于我的网络,我将 ISDN 调制解调器附带的 16 个 IP 地址分配如下:4 个用于连接 ISDN 调制解调器和我的主 Linux 系统的子网,4 个用于连接我的笔记本电脑的 PLIP 子网,8 个用于连接我的台式系统的以太网。有线调制解调器为其连接的以太网接口提供单个 IP 地址,而 ISDN 调制解调器充当具有自身 IP 地址的路由器。

它是如何工作的

我完全重写了用于初始化我的网络的启动脚本。理解我的网络的最好方法可能是逐步了解我的主 Linux 系统的初始化脚本并解释它的作用。与大多数系统一样,我的启动脚本是为 /bin/sh 编写的(实际上是 bash,但我没有使用任何花哨的 bash 功能)。

由于 Linux 2.2 的工具与 Linux 2.0 的工具不同,因此脚本会检查我正在运行的版本,允许我使用我选择引导的任何内核。

# Determine kernel version
KVERSION=`/usr/bin/awk '{printf("%3.3s\n,$3)}'\
/proc/version`

现在我将逐一设置每个网络接口。环回设备用于建立到我自己的机器的网络连接。每个 Linux 系统都应该已经配置了此设备。

# Attach the loopback device.
/sbin/ifconfig lo 127.0.0.1
/sbin/route add -net 127.0.0.0 lo
我将所有以太网驱动程序都构建为模块。这让我可以轻松控制哪个接口是 eth0,而不是 eth1。您会注意到我使用选项来指定我的 NE2000 卡的 I/O 地址。这是因为我有一个不寻常的 ISA 和 PCI NE2000 卡组合,它们使用单独的驱动程序。
# Set up the cable modem,
:echo setting up eth0
modprobe ne io=0x300,1,1,1
有线调制解调器使用 DHCP 来确定其 IP 地址,并且 2.2 有不同版本的 DHCP 客户端守护程序。
echo -n "starting dhcpcd"
[ $KVERSION = "2.0" ] && {
        /sbin/dhcpcd.old -r eth0
} || {
        /sbin/dhcpcd eth0
}
echo "
第二张以太网卡连接到 ISDN 调制解调器。ISDN 调制解调器充当路由器,因此它有自己的 IP 地址 (.209)。我为子网添加了一个路由以使用 eth1,并且我为我雇主的网络添加了另一个路由,以通过 ISDN 线路进行网关。
# Set up the ISDN line
echo setting up eth1
modprobe ne2k-pci
ifconfig eth1 inet 172.25.5.210 netmask 255.255.255.252 \ broadcast 172.25.5.211
route add -net 172.25.5.208 netmask 255.255.255.252 eth1
route add -net 168.159.0.0 netmask 255.255.0.0\
gw 172.25.5.209
第三个以太网接口用于我的内部网络。
# Set up the LAN
echo setting up eth2
modprobe tulip options=11
ifconfig eth2 inet 172.25.5.217 netmask 255.255.255.248 broadcast 172.25.5.223
route add -net 172.25.5.216 netmask\
255.255.255.248 eth2
对于我的笔记本电脑,设置 PLIP 就像设置另一个以太网端口一样。由于我有一个单独的并行端口连接了打印机,因此我对 PLIP 和 LP 都使用了模块,并指定选项到 modprobe,以便它为每个端口获得正确的端口。
# Set up PLIP
# see
# http://metalab.unc.edu/mdw/HOWTO/mini/PLIP.html
echo setting up plip0
[ $KVERSION = "2.2" ] && {
        modprobe lp parport=1
        echo 7 > /proc/parport/0/irq
        modprobe plip parport=0
} || {
        modprobe lp io=0x378
        modprobe plip io=0x3bc irq=7
}
/sbin/ifconfig plip0 172.25.5.213 netmask \
255.255.255.252 pointopoint 172.25.5.214 up
/sbin/route  add -net 172.25.5.212 netmask \
255.255.255.252 dev plip0
我们将使用 IP Masquerade 来共享有线调制解调器提供的单个 IP 地址,因此我们希望加载模块以提供对需要特殊帮助的伪装协议的支持。
# Load IP Masquerade modules
# Note that some of these only exist for 2.2
# kernels
modprobe ip_masq_ftp
modprobe ip_masq_irc
modprobe ip_masq_raudio
modprobe ip_masq_cuseeme
[ $KVERSION = "2.2" ] && {
        modprobe ip_masq_vdolive.o
        modprobe ip_masq_quake.o
}
现在是伪装、防火墙等。所有这些在 2.2 内核中都发生了变化,但思想是相同的。首先,我们设置我们的转发规则。这些规则告诉 Linux 当它从一台机器收到一个目标为另一台机器的 IP 数据包时该怎么做。来自内部机器且目标为互联网的任何内容都应该被伪装。我们还需要允许在不同接口之间转发数据包。我们不希望的是允许从通用互联网到转发或伪装的连接——从有线调制解调器进入的连接应该寻址到为该接口分配的 IP 号码。因此,我的默认策略是转发,并且我有特殊规则来伪装目标是发出有线调制解调器或从有线调制解调器进入的数据包。

请注意,转发规则的顺序很重要。内核必须在拒绝接口转发的规则之前看到伪装的规则。

# Set up IP Masquerading
# This has to be done carefully to only masquerade
# packets that originate from my network. Otherwise,
# someone on the outside could route through my
# system to hide their identity
echo Setting up IP Masquerade
[ $KVERSION = "2.2" ] && {
        echo 1 > /proc/sys/net/ipv4/ip_forward
        ipchains -P forward ACCEPT
        ipchains -A forward -i eth0 -s \
172.25.5.216/255.255.255.248 -j
        MASQ
        ipchains -A forward -i eth0 -s \
172.25.5.212/255.255.255.252 -j
        MASQ
        ipchains -A forward -i eth0 -j DENY
} || {
        /sbin/ipfwadm -F -p accept
        /sbin/ipfwadm -F -a m -S \
172.25.5.216/255.255.255.248 -D 0.0.0.0/0 -W
eth0
        /sbin/ipfwadm -F -a m -S \
172.25.5.212/255.255.255.252 -D 0.0.0.0/0 -W \
eth0
        /sbin/ipfwadm -F -a deny -W eth0
}

现在,我喜欢在多台机器上运行 X,从远程互联网主机上的帐户连接到它们。X 服务器接受端口 6000+n 上的连接,其中 n 是 DISPLAY 变量中冒号后面的数字。因此,我想将端口 6001 的连接转发到内部机器上的端口 6000,进行一种反向 IP 伪装。对于 2.2,我使用端口转发。对于 2.0,我使用用户空间守护程序,因为端口转发不是标准 2.0 内核的一部分。请注意,这是不安全的,因为内部机器认为所有转发的连接都来自我的另一台 Linux 机器。

列表 1

这变得有点复杂,因为进行端口转发的正常方式需要您指定数据包寻址到的 IP 地址。由于我的 IP 地址是动态分配的,因此我想让我的规则独立于我的 IP 地址。因此,我使用“防火墙标记”执行两步过程。我创建一个标记规则,为任何端口 6001 的传入数据包分配一个编号标记,然后我基于该标记进行端口转发。(请参阅列表 1。)

列表 2

最后一步是添加一些防火墙规则(请参阅列表 2)以阻止我不想要的通用互联网连接。例如,我运行 Sendmail,但仅用于发送邮件,因为我在其他地方接收邮件。与其关注有关 Sendmail 的所有安全问题,不如阻止任何从外部连接到它的尝试。您可以使用 DENYREJECT。区别在于 REJECT 将发回一个数据包,说明“连接被拒绝”,而 DENY 将完全忽略连接尝试。

现在我们遇到了 ISDN 调制解调器的问题,因为当它为我的各种机器发送数据包时,它认为它们都在一个大的子网上。它没有意识到它需要将所有内容发送到我的中央 Linux 系统,然后该系统将路由事物。由于我不想打扰配置调制解调器的人,因此我改用桥接来解决问题。桥接有点像路由,但在不同的级别。路由使用 IP 地址;桥接使用以太网地址。当桥接打开时,Linux 会找出每个接口上所有系统的以太网地址,如果它看到一个寻址到与该机器不同的接口上的机器的数据包,它会在正确的接口上重新传输该数据包。重要的是,网桥透明地连接以太网段。它在以太网级别工作,因此任何 IP 级别的东西(例如防火墙、伪装和子网划分)都被完全绕过。桥接时,您甚至不必为接口分配 IP 地址。为了使其工作,您必须将接口置于“混杂”模式,以便它们侦听未寻址到它们的以太网数据包。

# Set up bridging so that incoming ISDN packets
# that don't know that
# I'm acting as a router will be intercepted and
# passed on
ifconfig eth1 promisc
ifconfig eth2 promisc
brcfg -ena

列表 3

桥接在以太网级别工作,因此 PLIP(IP 级别接口)不能成为网桥的一部分。但是,我仍然想为我的笔记本电脑做同样的事情。解决方案是使用代理 ARP(请参阅列表 3)。其思想是使用“地址解析协议”(在 IP 地址和以太网地址之间进行映射),告诉 ISDN 调制解调器我的 Linux 网关应该接收为我分配给笔记本电脑的 IP 号码的数据包。将 ARP 视为将以太网连接到 IP 网络连接的粘合剂。

对于客户端系统,我以与上面配置相应接口相同的方式配置其网络接口,只是更改了 IP 地址。然后,我为子网添加一个路由,并将默认路由设置为我的 Linux 盒。如果客户端运行 MacOS 或 Windows,它也能正常工作。这是一个例子

# Configure network interface and routes
ifconfig eth0 inet 172.25.5.218 netmask \<\n>
255.255.255.248 broadcast 172.25.5.223
route add -net 172.25.5.216 netmask \<\n>
255.255.255.248 eth0
route add default gw 172.25.5.217

当然,我还必须重新编译我的内核,显式启用我使用的每个功能。其中一些功能被标记为“实验性”,但根据我的经验,它们非常稳定(尽管您确实需要在配置期间告诉内核允许“实验性”功能)。我唯一使用的网络内核补丁是 Tulip 卡驱动程序版本的更新,因为我的卡非常奇怪。

但请注意:即使是真正了解自己在做什么的人也可能会犯错误。如果您在我的网络中发现任何安全漏洞,请告知Linux Journal,以便其他人不会犯同样的错误。

Preston F. Crow (Preston.F.Crow@Dartmouth.edu) 与他美好的妻子住在他在马萨诸塞州阿什兰的新房子里。他在 EMC 工作,编写软件来运行多 TB 存储系统。

加载 Disqus 评论