关于http 压力测试工具

1. ab 、 webbench 、http_load的特点
这些测试工具都是单进程、非线程的程序,它的并发是通过异步实现的,虽然也实现的并发,就是说,同时确实存在着n个并发,但是需要注意的是,对于一个非常简单的接口来讲,客户端要做的事情和服务器端要做的事情差不太多;这时,一个单进程的程序去压一个多进程的程序,显然客户端可能一直忙于发请求,接受响应,而服务器端却很清闲,甚至n/3个httpd子进程就可以搞定n个并发了,这就是为什么n个并发,而服务器端的httpd子进程数却远小于n的可能的原因之一。

2. siege
siege 是一个单进程多线程的程序,只是测试结果数据太少,不太能说明问题

3. 尽管如此,我们还是可以用ab做多进程的并发的,如下:

for i in seq 1 50;do  nohup /data1/apache/bin/ab -n 10000 -c 1 "http://10.20.30.40/test.php" >ab.$i.txt &;done

这就是一个并发50,总数50万的ab压力测试

关于keep-alive

你的服务器是否打开了keep-alive 呢?看看httpd.conf 就知道了,但是也不是必须的,简单测试一下就知道了,用第三个请求比较稳妥一些,看看下面的几个请求,顺便理解一下HTTP/1.0  与 HTTP/1.1 的几个区别:

请求1:
———————————-
GET / HTTP/1.1
Host: phpor.net

返回结果的编码格式:Transfer-Encoding: chunked
没有立即关闭连接,说明:HTTP/1.1 默认支持(启用)keep-alive

———————————-

请求2:
———————————-
GET / HTTP/1.0
Host: pengyou.sina.com.cn
Connection: Keep-Alive

返回结果的编码格式:Content-Length: 5556       说明: HTTP/1.0 还不支持Transfer-Encoding: chunked的传输编码方式
没有立即关闭连接,说明:HTTP/1.0 也可以使用 keep-alive
———————————-

请求3:
———————————-
GET / HTTP/1.1
Host: phpor.net
Connection: Keep-Alive

这个就肯定keep-alive了
———————————-

请求4:
———————————-
GET / HTTP/1.0
Host: phpor.net

这个请求就;
1. 不能Transfer-Encoding: chunked
2. 不能keep-alive
———————————-

结论:
要了解某个server是否打开了keep-alive ,只需用telnet发一个类似于前三种的请求,看看是否立即关闭了就行了

全组合 之 PHP实现

<?php
$arr
= array(
array(
‘A1’,‘A2’
),
array(
‘B1’,‘B2’
),
array(
‘C1’,‘C2’
)
);

print_r(zuhe($arr,false));
// or
zuhe($arr,true
);

/**
* @param: $arr: array for deal
* @param: $echo: print at end or not
*/
function zuhe($arr, $echo = true
) {
$len = count($arr
);
if (
$len == 0
) return array();
if (
$len == 1
) {
if (
$echo
) {
foreach(
$arr[0] as $val
) {
echo
$val ."\n"
;
}
} else {
return
$arr[0
];
}
exit();
}
$tmparr
= array();
foreach(
$arr[0] as $val0
) {
foreach(
$arr[1] as $val1
) {
$tmparr[] = $val0 ."\t". $val1
;
}
}
array_shift($arr
);
array_shift($arr
);
array_unshift($arr, $tmparr
);
return
zuhe($arr, $echo
);
}
/**
* result:
* A1 B1 C1
* A1 B1 C2
* A1 B2 C1
* A1 B2 C2
* A2 B1 C1
* ….
* A2 B2 C2
*/
?>

实现2:

<?php

$arr = array(
    
‘gateway’=>array(‘set’,‘noset’
),
    
‘returntype’=>array(‘META’,‘TEXT’,‘TEXT2’
),
    
‘url’=>array(‘login.php’,‘set&not_login.php’,‘noset’
),
    
‘st’=>array(‘ok’,‘err’,‘no’
)
);

echo implode("\t\t\t\t",array_keys($arr))."\n"."\n";
//print_r(zuhe($arr,false));
// or
zuhe($arr,true, –20
);

/**
 * @param: $arr: array for deal
 * @param: $echo: print at end or not
 */
function zuhe($arr$echo true$width "\t"
) {
    
$len count($arr
);
    if (
$len == 
) return array();
    if (
$len == 1
) {
        if (
$echo
) {
            foreach( 
$arr[0] as $val
) {
                echo 
$val ."\n"
;
            }
        } else {
            return 
$arr[0
];
        }
        exit();
    }
    
$tmparr 
= array();
    
$arr0 array_shift($arr
);
    
$arr1 array_shift($arr
);
    foreach(
$arr0 as $val0
) {
        foreach(
$arr1 as $val1
) {
            if (
$width == "auto"
) {
                
// 希望能自动调整列宽,为实现
            
}else if ($width == "\t"
) {
                
$tmparr[] = $val0 ."\t"$val1
;
            } else {
                
$tmparr[] = sprintf("%${width}s",$val0) .sprintf("%${width}s",$val1
);
            }
        }
    }

    array_unshift($arr$tmparr);
    return 
zuhe($arr$echo$width
);
}
/**
 * result:
 * A1    B1    C1
 * A1     B1  C2
 * A1   B2  C1
 * A1   B2  C2
 * A2   B1  C1
 * ….
 * A2   B2  C2
 */

?>

利用openssl创建一个简单的CA

本文旨在利用开源openssl软件,在Linux(或UNIX/Cygwin)下创建一个简单的CA。我们可以利用这个CA进行PKI、数字证书相关的测试。比如,在测试用Tomcat或Apache构建HTTPS双向认证时,我们可以利用自己建立的测试CA来为服务器端颁发服务器数字证书,为客户端(浏览器)生成文件形式的数字证书(可以同时利用openssl生成客户端私钥)。

该简单的CA将建立在用户自己的目录下($HOME/testca),无需超级用户(root)权限。

一. 创建CA
1. 创建CA需要用到的目录和文件:
执行命令如下:
mkdir "$HOME/testca"
cd "$HOME/testca"
mkdir newcerts private conf
chmod g-rwx,o-rwx private
echo "01" > serial
touch index.txt

说明:
$HOME/testca为待建CA的主目录。其中newcerts子目录将存放CA签署(颁发)过的数字证书(证书备份目录)。而private目录用于存放CA的私钥。目录conf只是用于存放一些简化参数用的配置文件。

文件serial和index.txt分别用于存放下一个证书的序列号和证书信息数据库。
当然,偷懒起见,可以只用按照本文操作即可,不一定需要关心各个目录和文件的作用。

2. 生成CA的私钥和自签名证书(即根证书)
创建文件:
vi "$HOME/testca/conf/gentestca.conf"
文件内容如下:
####################################
[ req ]
default_keyfile = $ENV::HOME/testca/private/cakey.pem
default_md = md5
prompt = no
distinguished_name = ca_distinguished_name
x509_extensions = ca_extensions

[ ca_distinguished_name ]
organizationName = TestOrg
organizationalUnitName = TestDepartment
commonName = TestCA
emailAddress = ca_admin@testorg.com

[ ca_extensions ]
basicConstraints = CA:true
########################################

然后执行命令如下:
cd "$HOME/testca"
openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 2190 -config "$HOME/testca/conf/gentestca.conf"
执行过程中需要输入CA私钥的保护密码,假设我们输入密码: 888888

可以用如下命令查看一下CA自己证书的内容
openssl x509 -in cacert.pem -text -noout

3. 创建一个配置文件,以便后续CA日常操作中使用:
vi "$HOME/testca/conf/testca.conf"
文件内容如下:
####################################
[ ca ]
default_ca = testca # The default ca section

[ testca ]
dir = $ENV::HOME/testca # top dir
database = $dir/index.txt # index file.
new_certs_dir = $dir/newcerts # new certs dir

certificate = $dir/cacert.pem # The CA cert
serial = $dir/serial # serial no file
private_key = $dir/private/cakey.pem # CA private key
RANDFILE = $dir/private/.rand # random number file

default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # message digest method to use
unique_subject = no # Set to ‘no’ to allow creation of
# several ctificates with same subject.
policy = policy_any # default policy

[ policy_any ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

########################################

二. CA的日常操作
1. 根据证书申请请求签发证书
假设收到一个证书请求文件名为req.pem,文件格式应该是PKCS#10格式(标准证书请求格式)。

首先可以查看一下证书请求的内容,执行命令:
openssl req -in req.pem -text -noout
将看到证书请求的内容,包括请求者唯一的名字(DN)、公钥信息(可能还有一组扩展的可选属性)。

执行签发命令:
openssl ca -in req.pem -out cert.pem -config "$HOME/testca/conf/testca.conf"
执行过程中会要求输入访问CA的私钥密码(刚才设置的888888)。

完成上一步后,签发好的证书就是cert.pem,另外$HOME/testca/newcerts里也会有一个相同的证书副本(文件名为证书序列号)。
你可以执行以下语句来查看生成的证书的内容:
openssl x509 -in cert.pem -text -noout

2. 吊销证书(作废证书)
一般由于用户私钥泄露等情况才需要吊销一个未过期的证书。(当然我们用本测试CA时其时很少用到该命令,除非专门用于测试吊销证书的情况)
假设需要被吊销的证书文件为cert.pem,则执行以下命令吊销证书:
openssl ca -revoke cert.pem -config "$HOME/testca/conf/testca.conf"

3. 生成证书吊销列表文件(CRL)
准备公开被吊销的证书列表时,可以生成证书吊销列表(CRL),执行命令如下:
openssl ca -gencrl -out testca.crl -config "$HOME/testca/conf/testca.conf"
还可以添加-crldays和-crlhours参数来说明下一个吊销列表将在多少天后(或多少小时候)发布。

可以用以下命令检查testca.crl的内容:
openssl crl -in testca.crl -text -noout

三. 自己生成公钥密钥,并用测试CA签发数字证书
我们在平时测试时,可以自己用openssl为服务器或用户生成公钥密钥,并用上面创建的CA签发对应私钥(密钥)的数字证书。
假设,我们就用刚才创建CA的操作系统用户为名为testuser的用户创建数字证书,我们要把待创建的私钥、证书等都放在目录$HOME/testuser下:

1. 创建密钥和证书请求(证书请求里包含了公钥)
创建$HOME/testuser目录并执行命令:
mkdir $HOME/testuser
cd $HOME/testuser
openssl req -newkey rsa:1024 -keyout testkey.pem -keyform PEM -out testreq.pem -outform PEM -subj "/O=TestCom/OU=TestOU/CN=testuser"
执行过程中需要输入私钥的保护密码,假设我们输入密码: 222222

执行完后,testkey.pem即为用户的密钥,而testreq.pem即为证书请求。
可以用openssl req -in testreq.pem -text -noout查看证书请求的内容。

2. 用测试CA为testuser签发证书
同样还在$HOME/testuser目录下执行命令:
openssl ca -in testreq.pem -out testcert.pem -config "$HOME/testca/conf/testca.conf"
执行过程中需要输入CA的密钥保护密码(刚才设置的888888),并且最后询问你是否要给该用户签发证书时要选y。

执行完后,testcert.pem即为证书,
可以用命令openssl x509 -in testcert.pem -text -noout查看证书内容。

3. 制作一个PKCS12格式的文档(个人数字证书)
我们制作的这个PKCS#12文件将包含密钥、证书和颁发该证书的CA证书。该文件可以直接用于服务器数字证书或个人数字证书。
把前几步生成的密钥和证书制作成一个pkcs12文件的方法执行命令:
openssl pkcs12 -export -in testcert.pem -inkey testkey.pem -out testuser.p12 -name testuser -chain -CAfile "$HOME/testca/cacert.pem"
执行过程中需要输入保护密钥的密码(222222),以及新的保护pkcs12文件的密码。

执行完后,testuser.p12即为pkcs12文件。你可以直接拷贝到windows下,作为个人数字证书,双击导入IE后就可以使用了。该文件也可以直接用于tomcat作为服务器证书使用(我尽量在近期再写一篇关于如何自己用tomcat建立HTTPS双向认证测试环境的文章)。

若要查看testuser.p12的内容可以用命令openssl pkcs12 -in testuser.p12

说明:
– 本文中名词“个人数字证书”意识为包含私钥和证书的实体,而不是单指只保护公钥的数字证书。
– openssl版本OpenSSL 0.9.8g 19

JAVA 双向SSL,SOCKET客户端/服务端

实现技术:
JSSE(Java Security Socket Extension)
Server需要:
1)KeyStore: 其中保存服务端的私钥
2)Trust KeyStore:其中保存客户端的授权证书
Client需要:
1)KeyStore:其中保存客户端的私钥
2)Trust KeyStore:其中保存服务端的授权证书

使用Java自带的keytool命令,去生成这样信息文件:

1)生成服务端私钥,并且导入到服务端KeyStore文件中

2)根据私钥,导出服务端证书

3)将服务端证书,导入到客户端的Trust KeyStore中

采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的Trust KeyStore中
1)keytool -genkey -alias clientkey -keystore kclient.keystore
2)keytool -export -alias clientkey -keystore kclient.keystore -file client.crt
3)keytool -import -alias clientkey -file client.crt -keystore tserver.keystore

Server:
Java代码
public class Server implements Runnable{   
  
    private static final int     DEFAULT_PORT                     = 7777;   
  
    private static final String SERVER_KEY_STORE_PASSWORD        = "123456";   
    private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";   
  
    private SSLServerSocket      serverSocket;   
  
    /**
      * 启动程序
      *
      * @param args
      */  
    public static void main(String[] args) {   
         Server server = new Server();   
         server.init();   
         Thread thread = new Thread(server);   
         thread.start();   
     }   
  
    public synchronized void start() {   
        if (serverSocket == null) {   
             System.out.println("ERROR");   
            return;   
         }   
        while (true) {   
            try {   
                 Socket s = serverSocket.accept();   
                 InputStream input = s.getInputStream();   
                 OutputStream output = s.getOutputStream();   
  
                 BufferedInputStream bis = new BufferedInputStream(input);   
                 BufferedOutputStream bos = new BufferedOutputStream(output);   
  
                byte[] buffer = new byte[20];   
                 bis.read(buffer);   
                 System.out.println("——receive:——–"+new String(buffer).toString());   
  
                 bos.write("yes".getBytes());   
                 bos.flush();   
  
                 s.close();   
             } catch (Exception e) {   
                 System.out.println(e);   
             }   
         }   
     }   
    public void init() {   
        try {   
             SSLContext ctx = SSLContext.getInstance("SSL");   
  
             KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");   
             TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");   
  
             KeyStore ks = KeyStore.getInstance("JKS");   
             KeyStore tks = KeyStore.getInstance("JKS");   
  
             ks.load(new FileInputStream("src/ssl/kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray());   
             tks.load(new FileInputStream("src/ssl/tserver.keystore"), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());   
  
             kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());   
             tmf.init(tks);   
  
             ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);   
  
             serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);   
             serverSocket.setNeedClientAuth(true);   
         } catch (Exception e) {   
             System.out.println(e);   
         }   
     }   
  
    public void run() {   
        // TODO Auto-generated method stub   
         start();   
     }   
}  

Client:
Java代码
package ssl;   
  
import java.io.BufferedInputStream;   
import java.io.BufferedOutputStream;   
import java.io.FileInputStream;   
import java.io.IOException;   
import java.io.InputStream;   
import java.io.OutputStream;   
import java.security.KeyStore;   
  
import javax.net.ssl.KeyManagerFactory;   
import javax.net.ssl.SSLContext;   
import javax.net.ssl.SSLSocket;   
import javax.net.ssl.TrustManagerFactory;   
  
/**
* SSL Client
*
* @author Leo
*/  
public class Client {   
  
    private static final String DEFAULT_HOST                     = "127.0.0.1";   
    private static final int     DEFAULT_PORT                     = 7777;   
  
    private static final String CLIENT_KEY_STORE_PASSWORD        = "123456";   
    private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";   
  
    private SSLSocket            sslSocket;   
  
    /**
      * 启动客户端程序
      *
      * @param args
      */  
    public static void main(String[] args) {   
        Client client = new Client();   
         client.init();   
         client.process();   
     }   
  
  
    public void process() {   
        if (sslSocket == null) {   
             System.out.println("ERROR");   
            return;   
         }   
        try {   
             InputStream input = sslSocket.getInputStream();   
             OutputStream output = sslSocket.getOutputStream();   
  
             BufferedInputStream bis = new BufferedInputStream(input);   
             BufferedOutputStream bos = new BufferedOutputStream(output);   
  
             bos.write("1234567890".getBytes());   
             bos.flush();   
  
            byte[] buffer = new byte[20];   
             bis.read(buffer);   
             System.out.println(new String(buffer));   
  
             sslSocket.close();   
         } catch (IOException e) {   
             System.out.println(e);   
         }   
     }   
  
  
    public void init() {   
        try {   
             SSLContext ctx = SSLContext.getInstance("SSL");   
  
             KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");   
             TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");   
  
             KeyStore ks = KeyStore.getInstance("JKS");   
             KeyStore tks = KeyStore.getInstance("JKS");   
  
             ks.load(new FileInputStream("src/ssl/kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray());   
             tks.load(new FileInputStream("src/ssl/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());   
  
             kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());   
             tmf.init(tks);   
  
             ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);   
  
             sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);   
         } catch (Exception e) {   
             System.out.println(e);   
         }   
     }   
  
}  

启动Server

启动Client,发送信息。

Server接收如下:正确解密
返回Client信息,

如此,就完成了服务端和客户端之间的基于身份认证的交互。

client采用kclient.keystore中的clientkey私钥进行数据加密,发送给server。
server采用tserver.keystore中的client.crt证书(包含了clientkey的公钥)对数据解密,如果解密成功,证明消息来自client,进行逻辑处理。

server采用kserver.keystore中的serverkey私钥进行数据加密,发送给client。
client采用tclient.keystore中的server.crt证书(包含了serverkey的公钥)对数据解密,如果解密成功,证明消息来自server,进行逻辑处理。

如果过程中,解密失败,那么证明消息来源错误。不进行逻辑处理。这样就完成了双向的身份认证。

keytools简介

keytool JAVA是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据 完整性以及认证服务。它还允许用户储存他们的通信对等者的公钥(以证书形式)。通过keytool –help查看其用法;

创建证书Java 中的 keytool.exe (位于 JDK/Bin 目录下)可以用来创建数字证书,所有的数字证书是以一条一条(采用别名区别)的形式存入证书库的中,证书库中的一条证书包含该条证书的私钥,公钥和对应的 数字证书的信息。证书库中的一条证书可以导出数字证书文件,数字证书文件只包括主体信息和对应的公钥。
每一个证书库是一个文件组成,它有访问密码,在首次创建时,它会自动生成证书库,并要求指定访问证书库的密码。
在创建证书的的时候,需要填写证书的一些信息和证书对应的私钥密码。这些信息包括 CN=xx,OU=xx,O=xx,L=xx,ST=xx,C=xx,它们的意思是:
Ø CN(Common Name – 名字与姓氏):其实这个“名字与姓氏”应该是域名,比如说localhost或是blog.devep.net之类的。输成了姓名,和真正运行的时候域名 不符,会出问题。浏览器访问时,弹出一个对话框,提示“安全证书上的名称无效,或者与站点名称不匹配”,用户选择继续还是可以浏览网页。但是用http client写程序访问的时候,会抛出类似于“javax.servlet.ServletException: HTTPS hostname wrong: should be ”的异常。
Ø OU(Organization Unit – 组织单位名称)
Ø O(Organization – 组织名称)
Ø L(Locality – 城市或区域名称)
Ø ST(State – 州或省份名称)
Ø C(Country – 国家名称)
可以采用交互式让工具提示输入以上信息,也可以采用参数,如:-dname “CN=xx,OU=xx,O=xx,L=xx,ST=xx,C=xx”来自动创建。

创建一个证书
指定证书库为 D:/keystore/test,创建别名为 Tomcat 的一条证书,它指定用 RSA 算法生成,且指定密钥长度为 1024,证书有效期为 1 年:
keytool -genkey -alias Tomcat -keyalg RSA -keysize 1024 -keystore C:/keystore/test -validity 365
显示证书库中的证书使用如下命令: keytool -list -keystore C:/keystore/test 将显示 C:/keystore/test 证书库的的所有证书列表

导出到证书文件
使用命令:keytool -export -alias Tomcat -file C:/keystore/TC.cer -keystore C:/keystore/test 将把证书库C:/keystore/test 中的别名为 Tomcat 的证书导出到 TC.cer 证书文件中,它包含证书主体的信息及证书的公钥,不包括私钥,可以公开。
导出的证书文件是以二进制编码文件,无法用文本编辑器正确显示,可以加上 -rfc参数以一种可打印的编者编码输出。 如:
keytool -export -alias Tomcat -file C:/keystore/TC.cer -keystore C:/keystore/test –rfc

查看证书的信息
通过命令: keytool -printcert -file D:/keystore/TC.cer 可以查看证书文件的信息。 也可以在 Windows 资源管理器中双击产生的证书文件直接查看。

删除密钥库中的条目

keytool -delete -alias Tomcat -keystore C:/keystore/test
这条命令将 C:/keystore/test 库中的 Tomcat 这一条证书删除了。

修改证书条目口令
keytool -keypasswd -alias Tomcat -keystore C:/keystore/test,可以以交互的方式修改 C:/keystore/test 证书库中的条目为 Tomcat 的证书。
Keytool -keypasswd -alias Tomcat -keypass oldpasswd -new newpasswd -storepass storepasswd -keystore C:/keystore/test

这一行命令以非交互式的方式修改库中别名为 Tomcat 的证书的密码为新密码 newpasswd,行中的 oldpasswd 是指该条证书的原密码, storepasswd 是指证书库的密码。

德兰修女语录

人们经常是不讲道理的、没有逻辑的和以自我为中心的
不管怎样,你要原谅他们

即使你是友善的,人们可能还是会说你自私和动机不良
不管怎样,你还是要友善

当你功成名就,你会有一些虚假的朋友
和一些真实的敌人
不管怎样,你还是要取得成功
 
即使你是诚实的和率直的,人们可能还是会欺骗你
不管怎样,你还是要诚实和率直

你多年来营造的东西
有人在一夜之间把它摧毁
不管怎样,你还是要去营造
 
如果你找到了平静和幸福,他们可能会嫉妒你
不管怎样,你还是要快乐
 
你今天做的善事,人们往往明天就会忘记
不管怎样,你还是要做善事
 
即使把你最好的东西给了这个世界
也许这些东西永远都不够
不管怎样,把你最好的东西给这个世界

你看,说到底,它是你和上帝之间的事
而决不是你和他人之间的事

家用路由器设置实战

关于如何设置路由器,其实说明书里已经讲的很明白了,这里我只说几个安全配置方面的问题

1、 根据mac地址限制访问

我这里有两台pc,一个虚拟的pc,一个iphone,虚拟的pc是通过桥接的方式上网的,虽然也是从路由器那里动态获取ip地址的,但是,并不需要将虚拟pc的mac地址加入到允许的mac地址列表里,因为走的是桥接模式(什么是桥接模式,我也不清楚了),所以最后允许的mac地址只有三个就可以了,就是两个pc的无线网卡的物理地址,和iphone的wifi的物理地址。

注意:

1. mac地址一定要加在: . 安全设置=》mac地址过滤 里面,而不是: 无线参数=>mac 地址过滤 里面

2. 一定要打开 安全设置=》防火墙设置 里面的 “开启防火墙” 这个总的开关

 

2、端口转发的配置

   如果LAN里的一个机器想提供服务,如:sshd  httpd,那么从
        转发规则=》虚拟服务器  里添加指定的端口转发到提供服务的ip就行了;然后使用该路由器的wan口的ip和配置的port,就可以访问到私网ip的指定服务了;  这就是路由器的nat模式