2009年3月11日星期三

Redesign of the pfsync Protocol, Part 3

Contributed by jason on Thu Feb 26 06:41:21 2009 (GMT)
from the mad-scientists-shouldn't-have-this-much-fun dept.

In this installment (see also Part 1 and Part 2), David Gwynne (dlg@) describes the approach and execution of his redesign of the pfsync protocol. He explains the limitations of pfsync version 4 and how he overcame these obstacles.

It was at about this point that it was decided that the code required significant surgery to avoid transmitting too many pfsync packets. Since the code was going to have to be heavily modified to fix it's behaviour, slipping an update to the wire protocol was also allowed, especially if it would help mitigate the number of packets pfsync intended to transmit.

Active-Active Firewall Cluster Support in OpenBSD (continued)
Approach and Execution

As described in detail above, the big problem with the current implementation is that it mitigates sending of pfsync packets too much, ie, in a firewall cluster with traffic split over two peers, updates aren't exchanged rapidly enough for the states on each firewall to move forward fast enough to keep up with the actual traffic. This is especially (or perhaps only) problematic with TCP traffic, which requires extremely current information from both sides of the connection to move the TCP sequence numbers forward.

Two attempts were made to try to solve the active-active problem in pfsync, firstly simple modifications to the existing implementation, and then as a result of that an almost full blown rewrite of the code.
Changes To The pfsync v4 Implementation

A large number of different approaches at dealing with states with traffic split over two peers in an active-active firewall cluster were evaluated and tested as part of the initial problem solving. This stage could be considered the exploratory surgery and was required so I could gain familiarity with the problem and the current implementation. However, all of the solutions except the final solution presented here were rejected as being unsuitable.

These solutions ranged from allowing packets for split TCP states to accept packets if the sequence numbers are on the edge of the window as stored in the state, to decreasing the maximum timeout on pfsync packets from 1 second down to small fractions of a second. All of these solutions either compromised the security provided by pf, or hurt the performance too much in existing use cases to be feasible.

Despite the long road to the changes made to the v4 code, the final changes were actually quite minimal. After a lot of trial and error it was decided that it was necessary for each firewall involved in a split path for TCP sessions to be notified of updates to that state as soon as possible. This in turn required the ability to detect when two peers were involved in a split path.

Detecting a split path turned out to be simple. Whenever an update to a state is received via the pfsync protocol, we record the time the update arrived at in the pf state structure. Then, when an update to the same state arrives via pf, we simply find the difference between the current time and the last time the state was updated via pf and assume the state is split if the difference is less than some arbitrary value, 4 in our case.

If we never get an update about a state via pfsync it means no other peer was involved in handling that state, therefore the timestamp in the state will always be 0 (the default value). The comparison between it and the current time will always be greater than 4. A peer that is handling packets for that session will send pfsync packets out about it though, so that comparison will evaluate to true and we know the state is split at that point.

The other feature of this mechanism is if the paths in both directions for this state merge onto a single firewall, that firewall will no longer receive updates for the state via pfsync. The timestamp on the state will no longer be updated, and the comparison between it and the system time will eventually fail as time moves forward. This means the same mechanism for detecting split states also allows us to detect when a state is no longer split.

With that mechanism in place it was trivial to modify the code to immediately send a pfsync state update about our own state changes to the peer.

These changes were successful, ie, if you had a pair of firewalls called A and B between two networks x and y, you could configure the route from hosts on network x to network y to go via firewall A, and the routes from hosts on network y to network x on firewall B, you could then successfully run pf as a fully stateful firewall with traffic for the same session split between those two firewalls.

The problem with these code changes is that they caused pfsync to become extremely chatty. Every single packet involved in a split session going through a firewall would generate a corresponding update from pfsync. Worse, for every single update for that split session we received from the firewall peers, we hit the merge state case in the pfsync update parsing code which cause us to send an update out again. Because of this the majority of the test we did with async paths for traffic through firewalls showed the pfsync traffic between two firewalls was several times the traffic of the actual traffic we were forwarding over the firewalls. Obviously causing more load than what we're attempting to filter is unacceptable.

One of the discoveries made during the tinkering with the v4 code was that there was a race between the forwarding of a packet that caused the creation of a state, the pfsync packet it generates, and when the reply from the host the packet was for is seen by a peer.

If we forward that packet on to the host, and that host sends a reply through another firewall, it is likely that the 1 second timeout on the pfsync packet describing that state has not hit that second firewall yet. Because pf is stateful, it will probably reject or drop that reply rather than forward it on like it should.

In response to this problem a new pfsync message was created called PFSYNC_ACT_IACK. When a firewall creates a state, instead of forwarding the network packet that created the state on immediately, we delay transmission for a short period. While that first packet is delayed we immediately send a pfsync state insertion message. Peers that receive that state insertion message then send an insert acknowledgment message to the first firewall, which in turn uses that to trigger the transmission of the packet that was delayed. If no firewall is there to acknowledge the insert, a timeout on the packet fires and causes it to be transmitted anyway.

It was at about this point that it was decided that the code required significant surgery to avoid transmitting too many pfsync packets. Since the code was going to have to be heavily modified to fix it's behaviour, slipping an update to the wire protocol was also allowed, especially if it would help mitigate the number of packets pfsync intended to transmit.

To summarise, it was determined that not only does the pfsync code mitigate sending of pfsync packets too much, it also doesn't mitigate them enough.
pfsync v5

The only really major flaw with version 4 of the pfsync protocol was its inability to contain multiple types of messages within the same frame. It could only contain packets with state inserts, or updates, or deletions, or so on, but not a mix of those message types. This becomes a problem if you're trying to mitigate the number of packets sent, but needed to send a lot of messages of different types.

Therefore the only real change between pfsync v4 and pfsync v5 was the removal of the message type and counter fields in the pfsync header, and the introduction of a sub- header. Several different messages can now be placed in a pfsync packet, all prefixed by different sub-headers.

A new message type was added to the protocol as part of the new version too. To cope with the race between forwarding a packet that creates a state, and it's reply hitting a peer before the state was received by that peer, it was envisaged that the first peer forwarding the first packet would defer sending of that packet until it received an acknowledgment of the insert from a peer. That acknowledgment is represented by a new PFSYNC_ACT_IACK message type that simply contains the creator and state ids of the state that was just inserted.

To summarise, pfsync v5 is largely the same as pfsync v4, except for a new message type (IACK) and the ability to send multiple types of messages inside a single pfsync packet due to the addition of a sub-header in the frame format.

The following changes to the OpenBSD kernel were made to address the inadequacies discovered by the previous implementation.

Firstly, the pfsync packet parsing code in the kernel has been split up to avoid the use of switch statements to pick which code is used to parse which message types. Switch statements in C have an O(n) cost where n is the number of options you're switching between. Instead, the parser is picked by using the pfsync action in the sub-header id as an index into a table of function pointers. This moves the cost of picking a parser for a message to O(1) complexity.

Next, pfsync packet generation was moved from being done "on the fly" when pf notified us of updates, to being done only when a packet was ready to be transmitted. This in turn required that the state of a pf state with respect to pfsync be stored somewhere other than the packet currently being generated.

Previously the code determined if a state was already scheduled to be sent out on the wire by iterating over the packet in memory. This is another O(n) cost where n is the number of states scheduled in the current packet.

Because we also wanted to be able to send multiple types of messages in the same packet, it is now also necessary to mark what type of message the state had associated with it. Several queues for holding the states were created inside pfsync, one for each type of message that the state could appear in on the wire. The pf state structure was extended to record which of these queues it was currently held on. Now it is an O(1) cost to determine where a state is with respect to pfsync.

When the packet is eventually scheduled for transmission, the pfsync code walks all these queues and serialised the states into messages within the packet. As it does this iteration it simply marks the pf states as not being queued within pfsync anymore.

Another side effect of moving to queues of states was that it is now easy to move states between queues in response to pf notifications or requests from other peers. For example, pf itself could schedule a compressed update for a state which would leave it on the compressed update queue and marked as such. A peer can then request an uncompressed update for it. Where the previous implementation would have sent the previous message out immediately so it could begin a new packet with the uncompressed message type, the new code now can trivially figure out that it should simply remove the state from the compressed update queue and place it on the uncompressed update queue and mark it as such.

Next, a mechanism to mitigate against having to send "immediate" packets out immediately was developed. Since there are no general high resolution timers available in the OpenBSD kernel, it was decided that a new softnet interrupt handler be created specifically to flush the pfsync message queues into a packet for transmission.

Because all the events in pfsync are generated by code that is running at softnet, ie, the pf tests for network packets on both the systems input and output queues and the processing of pfsync packets, it is possible to queue updates for all the states touched during that processing and schedule a softnet interrupt for the pfsync packet generator. Because that code is running at softnet it masks the pfsync packet generator scheduled at softnet and prevents from running until after all the current packet processing is finished.

Additionally, on systems with busy network interfaces it is typical that you process several dozen packets per call to the softnet interrupt handlers. Any updates requiring immediate transmission of a pfsync packet can bundle all those updates into a single update before the packet transmission code is run.

Finally, the features from the pfsync v4 reworking were brought over to the new pfsync v5 code. The time at which a pf state was last updated by a pfsync packet is stored in the pf state. If an update from pf for a state occurred within a second of the update from the pfsync system, it is determined that the traffic for that state is now split over two peers in the cluster and it is marked for "immediate" transmission by the softnet handler.

The IACK handling made against the pfsync v4 implementation was also brought over, however, instead of the pointer to the packet and its timeout being stored in the state, a separate queue for deferred packets was added to the pfsync code. This was done because the space required for the packet pointer and the timeout was considered excessively wasteful for every state to store when it was only to be used for an extremely short period of time. This was weighed against the extra cost in terms of CPU time of handling that separate queue, which was considered worth it for the memory savings.

Because of the changes to the wire protocol, tools outside the kernel that parsed pfsync packets must be updated to understand the new packet format. The only tool in the OpenBSD source tree that parses those packets is tcpdump. This program was updated to handle the new packet format as part of this work.

Overall the changes to the OpenBSD system resulted in a unified diff to the source tree touching 10 separate files and totaling over 4000 lines of changes.

OpenBSD使用PF实现策略路由(图

OpenBSD使用PF实现策略路由(图)
帖子 2007-10-08 21:10
此方案适用于可以使用PF做为防火墙的操作系统,包括FREEBSD/OPENBSD/NETBSD。所谓的策略路由就是在服务器同时连接了两个ISP线路,实现从那个网卡进来的数据包请求,返回给CLIENT时还是从那个网卡出去。
OpenBSD网络设置:
Fxp0: 192.168.0.100
Ne3: 192.168.1.100
Gateway: 192.168.0.1

PF规则:
# vi /etc/pf.conf
----------------------------------------------------------------------------
if_isp1="fxp0"
if_isp2="fxp1"
gw_isp1="电信网关"
gw_isp2="网通网关"

block all

pass quick on lo0 all

pass in quick on $if_isp1 reply-to ( $if_isp1 $gw_isp1 ) proto {tcp,udp,icmp} to any keep state
pass in quick on $if_isp2 reply-to ( $if_isp2 $gw_isp2 ) proto {tcp,udp,icmp} to any keep state

pass out keep state
---------------------------------------------------------------------------
pf启动脚本:

# vi /etc/rc.d/pf.sh
#!/bin/sh
# pf startup scripts
#

case "$1" in

start)
if [ -f /etc/pf.conf ]; then
/sbin/pfctl -e -f /etc/pf.conf
fi
;;

stop)
/sbin/pfctl -F all
/sbin/pfctl -d
;;
*)
echo "$0 start | stop"
;;

esac
exit 0

以上PF规则没有对TCP/UDP等协议的端口进行限制。在使用时可以根据自己的实际情况添加相应的规则。
------------------------------------------------------------------------------
1.试验拓扑,图中的『3接口路由器』可以用WIN2K或LINUX系统启动IP转发替代。
[img=375,225]http://www.i170.com/Attach/28CD8558-CDA4-4AF9-BAB1-F503F9AC203F[/img]
2.OpenBSD网络设置
[img=494,334]http://www.i170.com/Attach/46B6D9B2-51DC-41B8-A007-80542E16AAAE[/img]
3.试验效果图1
图片
4.试验效果图2
图片

openbsd+adsl+pf+qdns 配置过程

偶在翻阅了大量网上文档(具体记不清在那里了)后,实验整理了一下OPENBSD环境中ADSL、PF、QDNS的配置过程。希望对OPENBSD的初学者有些帮助。下面我用的是OPENBSD 3.6

配置ADSL:
# vi /etc/ppp/ppp.conf
========================ppp.conf=======================
default:
set log Phase Chat IPCP CCP tun command
set redial 15 0
set reconnect 15 10000

pppoe:
set device "!/usr/sbin/pppoe -i rl0"
disable acfcomp protocomp
deny acfcomp
set mtu max 1492
set crtscts off
set speed sync
enable lqr
#set lqrperiod 5
#set cd 5
set dial
set login
#set timeout 0
set authname "sjz681a0156@adsl2"
set authkey 123456
add! default HISADDR
#enable dns
enable mssfixup
========================ppp.conf=======================

建立防火墙配置:
# vi /etc/pf.conf
=========================pf.conf=======================
# 设置一些变量
Ext = "tun0"
Int = "dc0"
IntNet = "192.168.0.0/24"
RouterIP = "192.168.0.1"
Loop = "lo0"

# 下面地址不被路由
NoRoute = "{ 127.0.0.1/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 255.255.255.255/32 }"

# 需要开放的端口
InServicesTCP = "{ ssh, ftp, auth,http }"

# 统计数据外网接口数据(pfctl -s info)
set loginterface $Ext

# 快速断开非活动状态的连接减少内存消耗
set optimization aggressive

# 重组IP碎片
scrub in on $Ext all fragment reassemble

# 启用NAT
nat on $Ext from $IntNet to any -> $Ext

### 下面是一些过滤规则 ###
# 首先挡住所有进出的数据包
block out on $Ext all
block in on $Ext all

block return-rst out log on $Ext proto tcp all
block return-rst in log on $Ext proto tcp all
block return-icmp out log on $Ext proto udp all
block return-icmp in log on $Ext proto udp all

# 禁用IPv6.0
block in quick inet6 all
block out quick inet6 all

# 允许本地环回通过
pass in quick on $Loop all
pass out quick on $Loop all

# 给nmap等扫描器来点难度
block in log quick on $Ext inet proto tcp from any to any flags FUP/FUP
block in log quick on $Ext inet proto tcp from any to any flags SF/SFRA
block in log quick on $Ext inet proto tcp from any to any flags /SFRA
block in log quick on $Ext os NMAP

# 防止IP欺骗
block in log quick on $Ext inet from $NoRoute to any
block in log quick on $Ext inet from any to $NoRoute

# 允许 FTP 主动模式
pass in quick on $Ext inet proto tcp from any to any port > 49151 user proxy flags S/SAFR keep state

# 允许被ping
#pass in quick on $Ext inet proto icmp all icmp-type 8 code 0 keep state

# 对外界开放的端口
pass in quick on $Ext inet proto tcp from any to any port $InServicesTCP flags S/SAFR keep state

# 允许通过由内向外的包
pass out quick on $Ext all keep state
=========================pf.conf=======================

启用IP转发:
# vi /etc/sysctl.conf
net.inet.ip.forwarding=1

设置开机启动ADSL拨号:
# vi /etc/rc.local
/usr/sbin/ppp -ddial pppoe

启用NAME服务器:
# vi /etc/resolv.conf
nameserver 202.99.160.68
nameserver 202.99.168.8

根据拨号需要加载和关闭防火墙:
# vi /etc/ppp/ppp.linkup
MYADDR:
! sh -c "/sbin/ifconfig pflog0 up"
! sh -c "/sbin/pflogd"
! sh -c "/sbin/pfctl -e -F all -f /etc/pf.conf"

# vi /etc/ppp/ppp.linkdown
MYADDR:
! sh -c "/sbin/pfctl -d -F all"
! sh -c "kill `cat /var/run/pflogd.pid`"
! sh -c "/sbin/ifconfig pflog0 down"
! sh -c "/sbin/route delete default"

配置动态域名更新:

# tar zxvf ez-ipupdate-3.0.10.tgz
# cd ez-ipupdate-3.0.10
# ./configure
# make
# make install

设置拨号后自动运行IP更新程序:

# vi /etc/ppp/ppp.linkup
MYADDR:
! sh -c "/sbin/ifconfig pflog0 up"
! sh -c "/sbin/pflogd"
! sh -c "/sbin/pfctl -e -F all -f /etc/pf.conf"
!bg /usr/local/bin/ez-ipupdate -i tun0 -h nero.3322.org -S qdns -u yourname:yourpw

完成上面的配置后reboot机器就可以了。

openbsd+pf配置

openbsd+pf配置

  初学openbsd+pf,见笑了,不对的请指正

  qq:35907960

  mail:yanypunix@yahoo.com.cn

  openbsd服务器3块网卡

  rl0 61.131.58.x 接公网

  rl1 192.168.1.0/24 接内网段1

  rl2 131.107.3.0/24 接内网段2

  有些ip要24小时上网,有些ip限定8小时上网

  写了两个脚本

  shellpf1+pf1.conf(24小时上网)

  shellpf2+pf2.conf(8小时上网)

  shellpf1,shellpf2,pf1.conf,pf2.conf四个文件放在/etc/pf目录下

  在crontab里定时执行,

  文件/etc/pf/pf1.conf的配置如下:

  ext_if="rl0" #接公网
192_if="rl1" #接内网段1
131_if="rl2" #接内网段2
192net="{
192.168.1.222/32,
192.168.1.5/32,
192.168.1.132/32,
192.168.1.77/32,
192.168.1.2/32,
192.168.1.8/32,
192.168.1.4/32,
192.168.1.6/32,
192.168.1.28/32,
192.168.1.177/32,
192.168.1.195/32,
192.168.1.45/32,
192.168.1.47/32,
192.168.1.16/32,
192.168.1.249/32,
}"
131net="{
131.107.3.215/32,
131.107.3.216/32,
131.107.3.217/32,
131.107.3.218/32,
131.107.3.219/32,
131.107.3.220/32,
131.107.3.211/32,
131.107.3.43/32,
131.107.3.47/32,
131.107.3.48/32,
131.107.3.174/32,
131.107.3.175/32,
131.107.3.181/32,
131.107.3.194/32,
131.107.3.123/32,
131.107.3.252/32,
131.107.3.253/32,
131.107.3.216/32,
131.107.3.198/32,
131.107.3.17/32
}"
tcp_services="{22,113}"
icmp_types="echoreq"
priv_nets="{127.0.0.0/8,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8}"
set optimization aggressive
scrub in all
nat on rl0 from 192.168.1.0/24 to any -> 61.131.58.x/32
nat on rl0 from 131.107.3.0/24 to any -> 61.131.58.x/32
block all
pass quick on lo0 all
block drop in quick on $ext_if from $priv_nets to any
block drop out quick on $ext_if from any to $priv_nets
#pass in inet proto icmp all icmp-type $icmp_types keep states
block in quick on $192_if from 131.107.3.0/24 to any
block out quick on $192_if from any to 131.107.3.0/24
block in quick on $131_if from 192.168.1.0/24 to any
block out quick on $131_if from any to 192.168.1.0/24
pass in on $192_if from $192net to any keep state
pass out on $192_if from any to $192net keep state
pass in on $131_if from $131net to any keep state
pass out on $131_if from any to $131net keep state
pass out on $ext_if proto tcp all modulate state flags S/SA
pass out on $ext_if proto udp all keep state

OpenBSD 之PF 基本防火牆啟動及 /etc/pf.conf 設定檔範例研究(转) From: 百度空间 Author: netnolimit

 Description:

  OpenBSD 之PF 基本防火牆啟動及 /etc/pf.conf 設定檔範例研究,我在想 OpenBSD 是不是天生開發出來,就是要擔任防火牆的角色,裝完 OpenBSD 後即可啟用 NAT 及 firewall 的能力,並不需要再去編譯 Kernel 即可使用。

  Setp 1.

  開機自動啟動:

  #vi /etc/rc.conf

  pf=YES

  #vi /etc/sysctl.conf

  #net.inet.ip.forwarding=1 # 將最前面的 # 號拿掉

  手動立即啟動:

  #pfctl -e

  #sysctl -w net.inet.ip.forwarding=1

  開啟 ftp-proxy 讓內部可以對外使用 FTP 的服務:

  #vi /etc/inetd.conf

  #127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy ftp-proxy # 將"# "號拿掉開通 127.0.0.1 的 ftp-proxy

  127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy ftp-proxy#kill -HUP `cat /var/run/inetd.pid`

  Setp 2.

  基本 PF 的 /etc/pf.conf 設定範例:

  # macros

  int_if = "de0" # 定義對內的網介面

  ext_if = "fxp0" # 定義對外的網路介面

  tcp_services = "{ 22, 113 }" # 定義 port 22, 113 服務

  icmp_types = "echoreq" # 定義 tcmp 回應狀態

  priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }" # 定義符合 RFC 1918 私有IP 部份

  comp3 = "10.10.10.3" # 定義內部的一台電腦代號 comp3 對應 10.10.10.3 這個 IP

  # options

  set block-policy return

  set loginterface $ext_if

  # scrub

  scrub in all # 修整進入 NAT 的封包

  # nat/rdr

  nat on $ext_if from $int_if:network to any -> ($ext_if) # NAT 設定讓內部的 IP 可轉換出去

  rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021 # 讓內部可使用 ftp client 軟體連出去

  rdr on $ext_if proto tcp from any to any port 80 -> $comp3 # 內部電腦 comp3 的 80 port 服務對應到外面

  # filter rules

  block all # 所有封包都擋掉

  pass quick on lo0 all # 允許 localhost 封包通行

  block drop in quick on $ext_if from $priv_nets to any # 拒絕所有 priv_nets 定義的私有 IP 進入 ext_if 介面

  block drop out quick on $ext_if from any to $priv_nets # 拒絕所有 priv_nets 定義的私有 IP 出去 ext_if 介面pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state # 允許 tcp_services 定義之 port 進入 ext_if 介面

  pass in on $ext_if proto tcp from any to $comp3 port 80 flags S/SA synproxy state # 讓內部 comp3 的 80 port 服務由 ext_if 介面出去

  pass in inet proto icmp all icmp-type $icmp_types keep state # 允許 icmp 封包進入通行

  pass in on $int_if from $int_if:network to any keep state # 允許封包由 de0 進到 10.10.10.0/24 暢通

  pass out on $int_if from any to $int_if:network keep state # 允許封包由 de0 出去 10.10.10.0/24 暢通pass out on $ext_if proto tcp all modulate state flags S/SA # 允許 tcp 封包由 fxp0 出去

  pass out on $ext_if proto { udp, icmp } all keep state # 允許 udp , icmp 封包由 fxp0 出去

  Setp 3.

  pfctl 的控制指令:

  #pfctl -f /etc/pf.conf # 重新載入pf.conf 設定檔

  #pfctl -nf /etc/pf.conf # 確認語法有無符合,但不載入

  #pfctl -Nf /etc/pf.conf # 只載入 NAT 的設定檔

  #pfctl -Rf /etc/pf.conf # 只載入防火牆的過濾設定檔

  #pfctl -sn # 顯示現階段 NAT 的規則

  #pfctl -sr # 顯示現階段過濾的規則

  #pfctl -ss # 顯示現階段封包運作狀態

  #pfctl -si # 顯示現階段過濾封包的統計資料

  #pfctl -sa # 顯示現階段所有統計的資料net.inet.ip.forwarding=1

理解VMware虚拟机下网络连接的三种模式

很多朋友都用vmware来测试不同的系统,我结合自己的经验谈一下对网络设置的理解,不对的地方请指正.
  bridge:这种方式最简单,直接将虚拟网卡桥接到一个物理网卡上面,和linux下一个网卡 绑定两个不同地址类似,实际上是将网卡设置为混杂模式,从而达到侦听多个IP的能力.
  在此种模式下,虚拟机内部的网卡(例如linux下的eth0)直接连到了物理网卡所在的网络上,可以想象为虚拟机和host机处于对等的地位,在网络关系上是平等的,没有谁在谁后面的问题.
  使用这种方式很简单,前提是你可以得到1个以上的地址.对于想进行种种网络实验的朋友不太适合,因为你无法对虚拟机的网络进行控制,它直接出去了.
  nat方式:这种方式下host内部出现了一个虚拟的网卡vmnet8(默认情况下),如果你有过做nat服务器的经验,这里的vmnet8就相当于连接到内网的网卡,而虚拟机本身则相当于运行在内网上的机器,虚拟机内的网卡(eth0)则独立于vmnet8.
  你会发现在这种方式下,vmware自带的dhcp会默认地加载到vmnet8界面上,这样虚拟机就可以使用dhcp服务.更为重要的是,vmware自带了nat服务,提供了从vmnet8到外网的地址转换,所以这种情况是一个实实在在的nat服务器在运行,只不过是供虚拟机用的.很显然,如果你只有一个外网地址,此种方式很合适.
  hostonly:
  这应该是最为灵活的方式,有兴趣的话可以进行各种网络实验.和nat唯一的不同的是,此种方式下,没有地址转换服务,因此,默认情况下,虚拟机只能到主机访问,这也是hostonly的名字的意义.
  默认情况下,也会有一个dhcp服务加载到vmnet1上.这样连接到vmnet8上的虚拟机仍然可以设置成dhcp,方便系统的配置.
  是不是这种方式就没有办法连接到外网呢,当然不是,事实上,这种方式更为灵活,你可以使用自己的方式,从而达到最理想的配置,例如:
a.使用自己dhcp服务:首先停掉vmware自带的dhcp服务,使dhcp服务更为统一.
  b.使用自己的nat,方便加入防火墙.windows host可以做nat的方法很多,简单的如windows xp的internet共享,复杂的如windows server里的nat服务.
  c. 使用自己的防火墙.因为你可以完全控制vmnet1,你可以加入(或试验)防火墙在vmnet1和外网的网卡间.
  从以上可以看出,hostonly这种模式和普通的nat server带整个内网上网的情形类似,因此你可以方便的进行与之有关的实验,比如防火强的设置等
  1、Bridge模式(一切都跟host一样,只有ip不能与host相同)
  ip 192.168.39.222
  netmask:255.255.252.0
  gateway:192.168.39.254
  Primary nameserve:192.168.39.252
  2、NAT模式
  首先在host中查看VMnet8的IP(e.g. 192.168.255.1).
  启动VMware,点Edit下Virtual Network Setting… ,弹出Virtual network Editor对话框;
  产看NAT选项卡,记录NAT的Gateway IP address:192.168.255.2
  在config中,填写:
  ip:192.168.255.5(与192.168.255.1在同一个网段的不同地址)
  netmask:255.255.255.0(与192.168.255.1的隐码相同)
  Gateway IP:填写VMware中的NAT网关192.168.255.2
  Primary nameserver:填写与主机中一样的网关192.168.39.252,这样就可以上网冲浪了.
  如果填写192.168.255.1,则不能连上外网.这里也可以不停,总之不能写错误的地址
  3、hostonly模式
  (1)查看你的连接外网的网卡的属性,选择“高级”标签,设置成允许共享,并设定允许的网络接口为VMNET1
  (2)再插看一下你的VMnet1 的属性,看一下TCP/IP协议的设置,你发现已经被自动设置为
192.168.0.1/255.255.255.0,
  (3)windows下的设置完成,转入到跑linux的虚拟机.将你的eth0的ip地址设置为静态的(如果安装时没有选静态的话)
  按红帽子图标->系统设置->网络(或其它你了解的方法)
  ip: 192.168.0.2(或其它在此网段上的地址)
  netmask: 255.255.255.0
  default gateway: 192.168.0.1 (VMnet1的地址)
  dns:输入你自己的DNS (host中用的DNS)
  保存设置.如果你还没有设置好主机名称:
  cd /etc/sysconfig
vi network
  编辑HOSTNAME
  cd /etc
  vi hosts
  加入:
  192.168.0.2 yourhostname
  重新启动服务
  su
  /sbin/service network restart
  (4)测试一下
  网关: ping 192.168.0.1
  dns: ping dnsserver
  =============================
  (1)Bridged方式
  用这种方式,虚拟系统的IP可设置成与本机系统在同一网段,虚拟系统相当于网络内的一台独立的机器,与本机共同插在一个Hub上,网络内其他机器可访问虚拟系统,虚拟系统也可访问网络内其他机器,当然与本机系统的双向访问也不
  成问题.
  (2)NAT方式
  这种方式也可以实现本机系统与虚拟系统的双向访问.但网络内其他机器不能访问虚拟系统,虚拟系统可通过本机系统用NAT协议访问网络内其他机器.
  NAT方式的IP地址配置方法:虚拟系统先用DHCP自动获得IP地址,本机系统里的VMware services会为虚拟系统分配一个IP,之后如果想每次启动都用固定IP的话,在虚拟系统里直接设定这个IP即可.
  (3)host-only方式
  顾名思义这种方式只能进行虚拟机和主机之间的网络通信,既网络内其他机器不能访问虚拟系统,虚拟系统也不能访问其他机器.
  (4)not use方式
  既是不使用网络,虚拟系统为一个单机.
  一般来说,Bridged方式最方便好用.但如果本机系统是win2000而网线没插(或者根本没有网卡),网络很可能不可用(大部分用PCI网卡的机器都如此),此时就只能用NAT方式或host-only,之前所说的那两块虚拟网卡就是适应这两种网络准备的.

vmware三种网络连接实例
vmware有三种网络连接方式:bridge ,NAT, host-only,我在三种连接上花了不少时间研究,并将研究结果写成此bokee.
三个名词,vmware的使用,电脑基础等基础知识请看书,在此不再解释。
实例1
bridge连接 虚拟机可和宿主机通信,可上外网如[url]www.baidu.com[/url],会和宿主机局域网同IP地址的机器冲突。
宿主机:
ip: 192.168.10.153
submask:255.255.255.0
gateway:192.168.10.1
DNS: 192.168.10.7
VMNET1网卡host-only
ip: 192.168.0.111
submask:255.255.255.0
gateway:192.168.0.111 or null
DNS: null
VMNET8网卡NAT
ip: 192.168.100.1
submask:255.255.255.0
gateway:192.168.100.2 or null
DNS: null
虚拟机:
ip: 192.168.10.154
submask:255.255.255.0
gateway:192.168.10.1
DNS: 192.168.10.7
实例2
NAT连接 虚拟机可和宿主机通信,可上外网如[url]www.baidu.com[/url],不会和宿主机局域网同IP地址的机器冲突。(VMNET8)
宿主机:
ip: 192.168.10.153
submask:255.255.255.0
gateway:192.168.10.1
DNS: 192.168.10.7
VMNET1网卡host-only
ip: 192.168.0.111
submask:255.255.255.0
gateway:192.168.0.111 or null
DNS: null
VMNET8网卡NAT
ip: 192.168.100.1
submask:255.255.255.0
gateway:192.168.100.2 or null
DNS: null
虚拟机:
ip: 192.168.100.3
submask:255.255.255.0
gateway:192.168.100.2 important!!!(VMware中NAT的网关)
DNS: 192.168.10.7(host的DNS)
实例3
host-only连接 虚拟机只能和宿主机通信,外网屏蔽。(VMNET1)
宿主机:
ip: 192.168.10.153
submask:255.255.255.0
gateway:192.168.10.1
DNS: 192.168.10.7
VMNET1网卡host-only
ip: 192.168.0.111
submask:255.255.255.0
gateway:192.168.0.111 or null
DNS: null
VMNET8网卡NAT
ip: 192.168.100.1
submask:255.255.255.0
gateway:192.168.100.2 or null
DNS: null
虚拟机:
ip: 192.168.0.113
submask:255.255.255.0
gateway:null or 192.168.0.111(VMNET1的地址)
DNS: null or 192.168.10.7(host的DNS)

2009年3月10日星期二

Linux上的文本“浏览器”

花开,没有声音……
从elinks开始,回想了一下Linux下基于ncurses库的“浏览器”,有如下几种:

lynx :最经典的,不用说了

w3m :用的和知道的人好像比较少。

elinks :昨天刚看到的,据说是替代lynx的程序。

links :指向elinks的软链接。

htmlview :一个shell角本,不能算是文件浏览器,他是一个探测程序,使用探测到的程序打开URL,在文本终端上,总是使用文件浏览器打开URL。

你还知道哪些?