Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1371287
  • 博文数量: 244
  • 博客积分: 10311
  • 博客等级: 上将
  • 技术积分: 3341
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-14 21:50
文章分类

全部博文(244)

文章存档

2013年(6)

2012年(5)

2011年(16)

2010年(11)

2009年(172)

2008年(34)

分类:

2009-03-23 14:15:05

 

    当您好不容易把 Linux 机器连上 Internet 之後,别以为就只有它一台机器能上网哦。下面教您的法子是如何用一台 Linux 机器让本地网路中所有的机器都能同时上网!

设定 Proxy

我们在“网路基础”中的“防火墙”那边已经知道,能做到以上要求的方法很多,之一是使用 proxy 。至於它的好处,前文已经说了许多,这里就不再重复了。假如您只想让其他机器到 Internet 上流览一下网页或透过 HTTP 下载档案,无疑 proxy 是个不错的主意,而且要设定这样一个 proxy 也是非常容易的,您只需确定 squid 套件有装好、并且能在开机的时候启动(执行 ntsysv 来选择)就行了。

然後,您要做的只是修改 /etc/squid/squid.conf 这个档案。虽然这个档案看上去很长,但是,如果仅是用来做 HTTP proxy 的话,您要修改的句子不超过两句:

# 在第 1163 行下面增加一行:
acl siyongc src 192.168.100.0/255.255.255.0 # 请修改为您自己的实际设定

# 然後在第 1197 行下面再增加一行:
http_access allow siyongc # 请修改为上一行定义的 acl 名称




然後重新跑 squid 就好了:

service squid restart


接下来,您将其他机器的流览器上之 proxy 功能打开,并将伺服器 IP 指向 squid 主机,同时将 port 设定为 3128 就可以了。如果您用 IE 的话,按‘工具’--> ‘Internet 选项’--> ‘连线’ --> ‘区域网路设定’ --> ‘使用 Proxy 伺服器’ --> 然後填好‘网址’与‘连接埠’:

这里只是最单纯的设定而已,事实上, squid 的设定非常多样和复杂,如果您有兴趣的话,可以参考‘ 优客笔记簿 ’中的文件。

正如您刚才发现的:在 Linux 上面设定一个简单的 proxy 看来是很容易的事情,但毕竟使用 proxy 是非常有限制的,例如,您要玩 ICQ、要使用 telnet、要上传 FTP 、要使用外面的 POP 信箱、要阅览新闻组或 BBS、等等,恐怕 proxy 就未必能全部应付得来了。不过,假如您使用 IP Masquerading ( IP 伪装 --- NAT 的一种)技术又如何呢?那情形几乎是:您在那台用来上网的 Linux 机器上所使用的 internet 功能,在其他机器也一样拥有!

前提准备

要设定 NAT ( Network Address Translation ) 就牵涉到防火墙装置了。老实说,要设定一个称职的防火墙并不是一件容易的事情,它要求您有非常丰富的 TCP/IP 基础、和严密的逻辑头脑、还得加上无以复加的细密测试。但是,我在这里教您的,并不是要真正的设定一个火墙,只是想让其他机器上网罢了。如果您真想设定防火墙,您可以看看 Firewall、IP Masquerade 和 IPchains 这几篇 HOWTO 文件,或许才会有些概念(但未必就设定得来)。而且,在阅读的时候,要注意文章引用的版本是否和您目前机器使用的相同,因为不同的版本所使用的工具和命令格式都相差很远,但基本的原理是不变的。

首先,您要知道,在 Linux 上面的防火墙程式都与核心版本非常密切:


如果您是用 2.0.x 的核心,那您只能使用 ipfwadm 程式;
如果是 2.2.x 的核心,则使用 ipchains 程式;
如果是 2.4.x 的核心,则使用 iptables 程式( ipchains 仍可以透过 modules 方式载入使用)。

因为 RedHat 7.1 预设是使用 2.4.2 核心,所以我们这里打算以 iptables 来做范例。如果您的核心参考 system 系列之‘ 编译核心 ’文章编的,那就已经具备防火墙功能了。如果您目前的版本是使用 2.2.x 核心的话,请参考 RH6.2 版本的 旧文章 ,这里将不再以 ipchains 来作说明了。


Tips:如果您对 ipchains 比较熟识、而决定继续在 2.4.x 核心上面使用 ipchains 的话,那也可以执行 modprobe ipchains 将 ipchains 的模组载入(但无论如何,ipchains 与 iptables 模组不能同时载入)。不过,2.2.x 核心原来提供的一些模组(如 ip_masq_*.o )就没办法使用了,这点请您留意。

另外,您还可以执行 ntsysv 将 ipchains 选择起来,并将 ipchains 的设定写进 /etc/sysconfig/ipchains 档案中(可执行 setup 选择 ‘Firewall Configuration’来设定这个档),那麽在开机的时候就会将 ipchains 跑起来了。

不过,我们这里只打算使用 iptables ,所以,以上方法仅供已有 ipchains 经验的朋友们参考,请勿和下面的说明搞混了。


好了,下面我跟大家说说如何在 RedHat7.1 上面用 iptables 来做一些防火墙和 NAT 的功能。但我必须再一次指出:设定防火墙需要您具备非常丰富的 TCP/IP 基础。最起码,您能理解如下的概念:


IP subneting 与 IP routing 的概念;
TCP 与 IP 封包 header 的各个栏位之名称与意义;
Socket Pair (Source Socket 与 Destination Socket) 的定义;
TCP 封包之 Sequence Number 与 Acknowledgement Number 的关系;
IP fragment 与 MTU/MRU 的关系;
ICMP 协定的 type & error code 之名称与意义;
Three-way Handshake 的过程与 SYNC 封包的意义;
TCP/IP 连线的不同连线状态(例如 NEW、WAITED、ESTABLISEHED、等)
各种服务的连线特征(尤以 FTP 服务为代表)。

假如您弄不懂以上所说的概念而硬要设定防火墙,那将是一件非常痛苦的事情(呵,我可把话说在前面了哦~~)。如果您真的决心弄明白这些概念,那您可以参考如下文章所列的书目清单:请推荐有关网路的书.... ,花点时间了解 TCP/IP 这对宝贝。要不然,当问题发生的时候,就算您要上来和大家请教和讨论,人家也不知道如何帮您解释才好、或是人家说了您却听不懂,因为都必须要牵涉到底层的 TCP/IP 基础知识。

好吧,我假设您已经补习好基础了哦~~ 然则的话,Let's go!

设定 IP Masquerading

我们这里的网路环境基本上与第一章所介绍的环境一样:

" target=_blank>

=780) window.open('');" src="" onload="javascript:if(this.width>'780')this.width='780';setTimeout('if(document.getElementById(\'\').height>\'700\')document.getElementById(\'\').height=\'700\';',500);" border=0>


这里,作为 NAT 机器的主机就是 RH71 ,它目前有三张网路卡,而我这里是将 adsl 接到 eth1 上面去,并且完成了 adsl-setup 、也已经顺利连上 Internet 了;执行 ipconfig 确定 ppp0 界面已经起来。


注:我们在接下来的叙述中,都一律以 ppp0 作为对外界面;如果您不是使用拨接连接,或是拨接界面不是 ppp0 的话,请您自行以该界面代替 ppp0 。

Tips:如果您使用拨接式 ADSL ,并向内部网路提供 NAT 服务的话,用一张网路卡就够了,反正 adsl 会使用 ppp0 而非 eth0 作为对外界面。但如果您是使用固接式 ADSL, 并且不是以 ppp 而是实体网路卡( ethX 界面)的话,那我建议您最好使用多片网路卡,分别用来连接外部和内部网路(甚至 DMZ 网路)。如果您用一张网路,然後以 IP Alias 方式同时连接外部和内部网路,单纯提供 IP 伪装服务而不设定封包过滤的话,那是可以的,但我还是不鼓励如此做法。


这时候在内部网路准备一台测试主机(跑 client 端程式),并确定它能够连上 RH71 主机、而且 default gw 也指向 RH71 的内部界面。

当我们的环境准备好之後,接下来就可以开始 NAT 的设定了:


无论如何,第一件事情要做的是确定您的系统上有安装 iptables 套件,否则请用 RPM 从 CD 里面安装(RH7.1 CD1)。


然後,您必须将 Firewall 功能编进核心里面去。如果您的核心是按照‘ 编译核心 ’文章的例子编的,应该就不成问题了:


Networking options --->[*] Network packet filtering (replaces ipchains)[*] TCP/IP networking
IP: Netfilter Configuration --->
Connection tracking (required for masq/NAT) (NEW)
FTP protocol support (NEW)
IP tables support (required for filtering/masq/NAT) (NEW)
limit match support (NEW)
MAC address match support (NEW)
netfilter MARK match support (NEW)
Multiple port match support (NEW)
TOS match support (NEW)
tcpmss match support (NEW)
Connection state match support (NEW)
Packet filtering (NEW)
REJECT target support (NEW)
Full NAT (NEW)
MASQUERADE target support (NEW)
REDIRECT target support (NEW)
Packet mangling (NEW)
TOS target support (NEW)
MARK target support (NEW)
LOG target support (NEW)
TCPMSS target support (NEW)
ipchains (2.2-style) support (NEW)
< > ipfwadm (2.0-style) support (NEW)


提示:假如您的系统并没作过任何的核心修改,换句话说:您一直都是使用系统安装时所准备的预设核心,那麽这个步骤可以省略了。除非您发现某些模组确实需要重编才有。


然後,检查一下 /etc/sysctl.conf 这个档案,看看 ‘net.ipv4.ip_forward=’是否为‘1’。如果是,跳到下一步;如果不是,将之改成‘1’,存档,然後执行 :

sysctl -w net.ipv4.ip_forward=1



Tips:上面这步骤是将 ip_forward 功能打开,您也可以用如下句子来完成:

echo "1" > /proc/sys/net/ipv4/ip_forward




执行 ntsysv 将 iptalbes 选择起来,并且确定 ipchains 没有选择。


检查一下 ipchains 的模组是否被‘意外’载入了:

lsmod | grep ipchains


如果输出结果没有发现 ipchains 的话,跳到下一步骤;如果有发现,则执行:

service ipchains stop
rmmod ipchains


并重复执行 lsmod 确定 ipchains 模组已经移除。


检查 iptables 的模组是否已经载入:

lsmod | grep ip_tables


如果有请跳到下一步骤;否则执行:

modprobe ip_tables


并再次执行 lsmod 确定 iptables 模组已经成功载入。


如果您不考虑任何安全性,现在执行:

iptables -t nat -A POSTROUTING -o ppp0 \
-s 192.168.100.0/24 -j MASQUERADE



就这样,您就可以让 NAT 後面的内部网路的机器连上 Internet 了!现在,您可以取消 proxy 设定并尝试一下 web 连线,或用邮件程式上网收发信件看看?甚至还可以打开 ICQ 和外面的朋友聊天呢!当然了,什麽 BBS 或新闻群组这些也都可以啦~~ ^_^

设定 Transparent Proxy

您或许会觉得继续使用 proxy 仍不失为一个好主意,尤其是当您考量到频宽问题的时候,甚至您还可以在使用者在不知情的情况下用 proxy 来浏漤 www 网站。这时候,您就可以考虑建立一个 Transparent Proxy 了:


首先,修改 /etc/squid/squid.conf,找到下面几行,并修改为如下样子:

httpd_accel_host rh71.siyongc.domain # 请修改为您的 squid 主机名称
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on




并重新启动 squid 服务:

service squid restart



然後执行:

iptables -t nat -A PREROUTING -i eth0 -p tcp \
-s 192.168.100.0/24 \
--dport 80 -j REDIRECT --to-ports 3128



这时候,您的 Transparent Proxy 就起来了!如果您要测试它,可以取消 client 端的 proxy 设定,并将 squid 关闭,然後测试是否不能连线(建议用一个未曾浏览过的网址来测试)?然则,再将 squid 打开,如果能这样又能恢复连线的话,那就已经成功了!这样有一个好处是:以後您再也不必跑到 client 那边设定 proxy;而且,更好的地方在於:重复性的连线再也无需占用宝贵的对外频宽,速递当然也能‘假性’的获得提高。

工作原理

然而,以目前的设定来说,可以说是完全开放的,毫无安全性可言的。虽然我在这里并不想设定一个真正火墙,但起码的安全也是应该考虑的。当我们提到防火墙的时候,大部份都是指 Packet Filtering (封包过滤),这和前面提到的封包伪装(也就是 NAT 的一种技术)可不是一样的。这里面,我们不妨先了解一下封包过滤的工作原理,这对於我们日後的防火墙管理非常重要!

让我们回到 TCP/IP 的基础知识吧(顺便检查一下您是否能够正确理解我在前面列出的概念):


Socket Pair


首先,让我们了解一下什麽是 Socket Pair 。所谓 socket 就是一个‘ IP 位址’加上一个‘ TCP/UDP Port ’,代表了一个连线与哪台机器( IP 位址)、及与机器上那一苹程式( Port ) 相连的。我们同时也知道:一个连线必须有两个端点:来源地( Source ) 和 目的地( Destination ) 。换句话说,我们一个连线就是与一对 socket 相连著:分别是 Source Socket ( Source Address & Source Port) 与 Destination Socket ( Destination Address & Destination Port ) ,合起来我们称之为 Socket Pair :
" target=_blank>
=780) window.open('');" src="" onload="javascript:if(this.width>'780')this.width='780';setTimeout('if(document.getElementById(\'\').height>\'700\')document.getElementById(\'\').height=\'700\';',500);" border=0>
Tips:如果您了解 TCP 与 IP 封包 header 结构的话,都非常容易找到上述提到的栏位。一般而言,防火墙程式大都会检查这些栏位来进行判断,然後根据您的设计要求来处理封包。当然,事实上,防火墙程式除了根据 Socket 资讯来判决封包命运之外,几乎封包的每一个栏位都可以作为判断依据。这也就是防火墙(或封包过滤)程式能耐之处了。

事实上, Socket 的功能就是让网路程式存取网路使用的,对程式而言,关键是它所被分配的 Port 数值。而 port 也有分两种: TCP 和 UDP ;至於哪些服务用哪种 port,端视服务程式的要求(您都可以在 /etc/services 这个档案中找到)。一般而言,单一的机器最多能使用的 port 范围是在 1 到 65535 之间。其中的 1 ~ 1023 这段范围只能由 root 权限的服务程式使用,通常是一些常用的服务程式,如 HTTP、FTP、SMTP、等。我们称这些常用的 port 为 Well-known Port,基本上大家都会采用相同的数值,如 80、21、25 等(事实上是未必的,只要能让 client 找到就好,如地下网站就通常使用不为人知的 port 数值)。但是,作为 client 端程式所使用的 port ,我们没办法事先知道它会用哪一个 port 。因为 client 程式所使用的 port 会随机的从 1024 ~ 65535 之间挑选,只要那个 port 没被其它程式使用就行。

请您记住这些 port 的使用特征,我们在防火墙设计中常会用到。


连线方向


我们已经知道 Socket Pair 事实上就是两个 socket :一个是 Source、另一个是 Destination。但,这是相对而言的,为什麽这麽说?

因为,我们要成功的建立一个 TCP/IP 连线,其连线必须是双向的:假设连线是 A 与 B 之间的两台机器。当封包从 A 送往 B 的时候,A 的 Scocket 是 Source Socket、而 B 则是 Destination Socket ;反过来,当封包从 B 送回 A 的时候,那麽 A 的 Socket 就变成 Destination、而 B 则变成 Source 。
" target=_blank>
=780) window.open('');" src="" onload="javascript:if(this.width>'780')this.width='780';setTimeout('if(document.getElementById(\'\').height>\'700\')document.getElementById(\'\').height=\'700\';',500);" border=0>
请您务必搞懂这对 Socket 於连线方向时所使用的名称。这样,当您在防火墙墙上处理这些封包的时候,才知道哪边是 Source 、哪边是 Destination 。


连线界面


与刚才提到的连线方向相关的,就是连线界面了。一般情况下,防火墙都是处於内部网路与外部网路之间的位置,换句话说:它通常有不同的界面来连接不同的网路。

让我们再以图三为例:当封包从 A 送往 B 的时候,在防火墙左边的界面属於 incoming 界面(在 iptables 中以 -i 表示)、而右边的界面则是 outgoing 界面(在 iptables 以 -o 表示);但是,当封包从 B 送回 A 的时候,右边界面则成为 incoming 界面、左边的则成为 outgoing 界面。


Tips:请那些习惯了 ipchains 语法的朋友务必注意:在 ipchains 里面不管界面是属於 incoming 还是 outgoing ,一律以 -i 表示;但在 iptables 中,-i 只能代表传入界面、传出界面只能以 -o 表示。所以,在 iptables 中的 INPUT 不可能使用 -o 来指定界面;相反,-i 界面也不可能出现在 OUTPUT 中。


封包於防火墙中的流向


当您搞懂了 Source Socket 与 Destination Socket 、以及各界面之间的关系之後,接下来,再让我们仔细看看封包在防火墙中的流向。

当一个封包抵达防火墙的时候,必须从一个界面进入,然後经过路由判断之後,再从路由判断所指定的界面送出去。您或许很容易的认为:从界面传入的封包就是 INPUT ;从界面从出去的封包就是 OUTPUT;而从一个界面送到另一个界面就是 FORWARD :

" target=_blank>
=780) window.open('');" src="" onload="javascript:if(this.width>'780')this.width='780';setTimeout('if(document.getElementById(\'\').height>\'700\')document.getElementById(\'\').height=\'700\';',500);" border=0>
事实上是否如此呢?

哈,如果您对 ipchains 程式够了解的话,您肯定会认为如此。但,到了 iptables 的时候,却未必哦~~ ^_^ 在 iptables 中,所谓的 INPUT 与 OUTPUT,只对那些与本机 Local Process 相关的封包而言才是成立的(这也是 iptables 与 ipchains 最大分别之一)。也就是说:对於一个从界面传入的封包,如果它是送给在本机的,那才算是 INPUT,否则不算;至於将从一个界面送出的封包,如果这个封包是从本机产生的,才算 OUTPUT,否则不算;那些传入与传出都与本机无关的封包,则属於 FORWARD 了(注意:既不是 INPUT 也不是 OUTPUT 哦):

" target=_blank>

=780) window.open('');" src="" onload="javascript:if(this.width>'780')this.width='780';setTimeout('if(document.getElementById(\'\').height>\'700\')document.getElementById(\'\').height=\'700\';',500);" border=0>


事实上,图五中的三个圆角方块( INPUT、OUTPUT、FORWARD ), 分别是在 iptables 程式里面的三个内建防火链( Built-in Chains,我们後面再说明) 。


NAT 的原理


阅读(1052) | 评论(0) | 转发(0) |
0

上一篇:大端\小端模式

下一篇:iptables之类NAT篇

给主人留下些什么吧!~~