Skip to content

Commit 5af86d4

Browse files
committed
更新文档
1 parent d5ed670 commit 5af86d4

12 files changed

Lines changed: 171 additions & 111 deletions

File tree

WechatAutoReply/.DS_Store

0 Bytes
Binary file not shown.
6 KB
Binary file not shown.
6 KB
Binary file not shown.

middlewareAgent/CA/cert/my.crt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
-----BEGIN CERTIFICATE-----
2-
MIIDeDCCAuGgAwIBAgIHAVUpYkKJczANBgkqhkiG9w0BAQsFADCBvzEiMCAGA1UE
2+
MIIDeDCCAuGgAwIBAgIHAVUwYjdQQjANBgkqhkiG9w0BAQsFADCBvzEiMCAGA1UE
33
AxMZaHR0cHMtbWl0bS1wcm94eS1oYW5kYm9vazELMAkGA1UEBhMCQ04xEjAQBgNV
44
BAgTCUd1YW5nRG9uZzERMA8GA1UEBxMIU2hlblpoZW4xIjAgBgNVBAoTGWh0dHBz
55
LW1pdG0tcHJveHktaGFuZGJvb2sxQTA/BgNVBAsTOGh0dHBzOi8vZ2l0aHViLmNv
6-
bS93dWNoYW5nbWluZy9odHRwcy1taXRtLXByb3h5LWhhbmRib29rMB4XDTE4MDMx
7-
OTAyMjcwOFoXDTIwMDMxOTAyMjcwOFowgbExEzARBgNVBAMTCmdpdGh1Yi5jb20x
6+
bS93dWNoYW5nbWluZy9odHRwcy1taXRtLXByb3h5LWhhbmRib29rMB4XDTE4MDMy
7+
MDA2MTI1NVoXDTIwMDMyMDA2MTI1NVowgbExEzARBgNVBAMTCmdpdGh1Yi5jb20x
88
CzAJBgNVBAYTAkNOMRIwEAYDVQQIEwlHdWFuZ0RvbmcxEjAQBgNVBAcTCVNoZW5n
99
WmhlbjEiMCAGA1UEChMZaHR0cHMtbWl0bS1wcm94eS1oYW5kYm9vazFBMD8GA1UE
1010
CxM4aHR0cHM6Ly9naXRodWIuY29tL3d1Y2hhbmdtaW5nL2h0dHBzLW1pdG0tcHJv
11-
eHktaGFuZGJvb2swgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANTLY5/uSFFD
12-
e94ZS7B685ba27mlfkRvAZgb0/POIcwxnyrNCIfz6PNRaGSwxxKSXhPhvoqH+KPv
13-
I5BmQJ0B7tpmjwfImq9cEZScoVUE0XI4K+6/HRVSiQpQwMdbnFAxzqqiy6vgnVyD
14-
CkV3sVviIZNSQSYsguttPL/gPELQk/XzAgMBAAGjgYkwgYYwDAYDVR0TAQH/BAIw
15-
ADAPBgNVHQ8BAf8EBQMDB7+AMB0GA1UdDgQWBBREDVp+5xCK4bbhlg9WZLjXSkJj
16-
hTA7BgNVHSUENDAyBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEF
17-
BQcDBAYIKwYBBQUHAwgwCQYDVR0jBAIwADANBgkqhkiG9w0BAQsFAAOBgQBgfAbs
18-
2X8YCBHKoP/xmWQw1ONNrJrRJciO0CZx94WC76dSmtNPvMZbishwCsUt66vPrBzG
19-
KDGZIg78hNQxAWWr0JnLzwytX9H41ZgF0Pj7iai+2WNl3MiDNQzRcAKRZs4f57Kn
20-
gZlGaWfm6oDTPnkwserV4zZiov3beje86jUu6g==
11+
eHktaGFuZGJvb2swgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALVQELtIusEk
12+
yQkLu8/UOxMh3AKidY3OubcZCslLtkS7PATii8oo6uUCU9rr1y2QFE394egT/4Xe
13+
mpPvJ4CNQXjIzkAU2VDnf+9HZJh/gka+NUUSbQGldfzzl212I54Qotay772uYIK/
14+
ELUxXu7iF05Qmbec9Dyt9ls/8qX2A9a5AgMBAAGjgYkwgYYwDAYDVR0TAQH/BAIw
15+
ADAPBgNVHQ8BAf8EBQMDB7+AMB0GA1UdDgQWBBTctQulm34JhovW0A/x4ohnxTDs
16+
njA7BgNVHSUENDAyBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEF
17+
BQcDBAYIKwYBBQUHAwgwCQYDVR0jBAIwADANBgkqhkiG9w0BAQsFAAOBgQAxR80b
18+
Hu2Otmw6X/H27SUPFjv5BMxbMxI91XAz6eHVNZNq0Y1Bas581+/HbsApzZ2VaJmV
19+
vrNbcrY111Ofk67eN5idRxJtQc695g8h+Pp5zGKK9J3DYS0DhUuajlORs9FWFQAG
20+
1aK6+U+dYoT48KhxOp97JXGp2cgON5qftyrOeA==
2121
-----END CERTIFICATE-----

middlewareAgent/CA/cert/my.key.pem

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
-----BEGIN RSA PRIVATE KEY-----
2-
MIICXgIBAAKBgQDUy2Of7khRQ3veGUuwevOW2tu5pX5EbwGYG9PzziHMMZ8qzQiH
3-
8+jzUWhksMcSkl4T4b6Kh/ij7yOQZkCdAe7aZo8HyJqvXBGUnKFVBNFyOCvuvx0V
4-
UokKUMDHW5xQMc6qosur4J1cgwpFd7Fb4iGTUkEmLILrbTy/4DxC0JP18wIDAQAB
5-
AoGBAKm6+WHtvD0laL3Ey3ye9YDUXQJ9IHQRXuInAC6tsoOe6OhI1o8qXBsISg5W
6-
etMzcFrHayYwQoDwFBvvk4YoroyNG/RtJK9H6J8FMN1o1xl4ZpvizXrbIRGiCrbO
7-
6gwsqDtmE069ZeDugzs99RH5J4XjSQk02Jl9X7I9uzQg0XThAkEA9ExUkTTerXci
8-
Vl+LGFCHmIPBVRAHxd6f9/iNdnEgpnN11UD6uJFyIxt9evaiYEQi+j4HcCPLJ05V
9-
riaWNf4vGQJBAN78v+yhabMFaHYTE11iGfGMeh5Dj61DJdacZrUBNfTSalafbE6f
10-
zT5swAI2eqKPyFgEeCQYxSybSli6E4tdyusCQQCkSNB19b/plzwYKZg4ea81+SSC
11-
N42CmvuonhVDmUADr5GGH3R7uhOvWEVB86muYyPCdQQ7fVaY0Cz+OCS7mnvBAkBE
12-
p6kn4CK9HcMl54Wk0NmQB2JqAv8vp2b1Br6QqEjGkipvdTJRmt4EhFMx2zgy6PYU
13-
M3wSERZUP5PKcbAmzr/1AkEA1YyAOUkSEqB64ccqeCwnndVFZtvZqNfAf+StqQU7
14-
borHEmqwnQEH749z9Hh0+ioo1y69KWgIOWuIuJ2l+VKesw==
2+
MIICXAIBAAKBgQC1UBC7SLrBJMkJC7vP1DsTIdwConWNzrm3GQrJS7ZEuzwE4ovK
3+
KOrlAlPa69ctkBRN/eHoE/+F3pqT7yeAjUF4yM5AFNlQ53/vR2SYf4JGvjVFEm0B
4+
pXX885dtdiOeEKLWsu+9rmCCvxC1MV7u4hdOUJm3nPQ8rfZbP/Kl9gPWuQIDAQAB
5+
AoGAJuA39jAt+uPMRyhA6Nr0n7GO3vG+it1cbKnt6iNVvX7364Q3vOzxEJFjMXmH
6+
9bkC4YYiPgSrsSR9uGJ68dFXzBWxosTVZ/TUX2ECbsh2ldwArRt34iWGcxrRlijP
7+
TH6Lt20kPLqljSmCo8IXOpQtUH8v7WSCHK70KqOuPJo4oEECQQDer7Za7fe5t4U2
8+
+XJlqOOqYOVgdkTVzYW0HuTYZ7AbiOFuebqn/pjqj+7hRE1EPFKhpTx/6Vv9rthQ
9+
n1QzAW1FAkEA0G/a3GJ64MA/s0FASD5rHn7f3+2ZXp9YZl86rBA4COs2CQDfQ9hV
10+
jWIlLd9fwEDF96x4/gIJ14q+VBd8dN445QJAWiHIr1kuMW9EbhHc6aTIMUfyz25P
11+
QjJjcZoniie9sgdfJzYCBMkZ36bOS0M3+uxnjaGxsRwk7bL9PvSeQd7L+QJASUPH
12+
7kc/Ydixi1SYP8yQ4ns+PfvKORRRgkpe2TQqPhhPOgLwd2yHRdcFsoYdpfoem9wn
13+
+0DELNs741sOCBZEcQJBAIjKXEWSSxScF7P3hVV43tmt/X38STD/ai7seVOTa2ri
14+
4aF9ofT/A7Vcn9z6ZMOd0Dlczi43DBGEoQYyKaOvdGE=
1515
-----END RSA PRIVATE KEY-----
0 Bytes
Binary file not shown.

middlewareAgent/browserAgent/README.md

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ httpMitmProxy.on('request', (req, res) => {
6363
})
6464
})
6565
```
66+
具体源代码请看[这里](https://github.com/Wscats/node-tutorial/blob/master/middlewareAgent/browserAgent/http/http.js)
6667

6768
# HTTPS代理实现
6869

@@ -147,20 +148,25 @@ httpTunnel.on('connect', (req, cltSocket, head) => {
147148
});
148149
});
149150
```
150-
不获取明文的代理,这种方式就是利用`http`得到请求信息然后借助`net`模块模拟客户端的`TCP`请求
151+
具体源代码请看[这里](https://github.com/Wscats/node-tutorial/blob/master/middlewareAgent/browserAgent/https/https.js)
152+
153+
154+
不获取明文的代理,这种方式就是利用`http`得到请求信息然后借助`net`模块模拟客户端的`TCP`请求,这个实现方式跟Node官方文档的[connect事件例子](http://nodejs.cn/api/http.html#http_event_connect)非常相似
151155
```js
152-
// node.js 中基于express 实现简单http代理服务
153156
const url = require('url');
154157
const http = require('http');
155158
const net = require('net');
156-
const config = {
157-
port: 6789
158-
};
159159
const {
160160
port
161-
} = config;
162-
163-
const server = http.createServer();
161+
} = config = {
162+
port: 6789
163+
};
164+
const server = http.createServer((req, res) => {
165+
// 代理HTTP
166+
const ip = res.socket.remoteAddress;
167+
const port = res.socket.remotePort;
168+
res.end(`您的 IP 地址是 ${ip},您的源端口是 ${port}`);
169+
});
164170

165171
// HTTP 隧道 代理HTTPS 流量 但由于加密 不能处理
166172
server.on('connect', (req, socket) => {
@@ -185,11 +191,9 @@ server.on('connect', (req, socket) => {
185191
socket.pipe(clientSocket);
186192

187193
});
188-
189194
// 开启server 监听指定端口
190195
server.listen(port, () => {
191-
// 打印当前ip 地址和port
192-
console.log(`address: ${server.address()}:${server.port}`);
196+
console.log('server start');
193197
});
194198
server.on('error', (e) => {
195199
if (e.code == 'EADDRINUSE') {
@@ -202,6 +206,53 @@ server.on('error', (e) => {
202206
}
203207
});
204208
```
209+
具体源代码请看[这里](https://github.com/Wscats/node-tutorial/blob/master/middlewareAgent/browserAgent/https/https4.js)
210+
211+
# 生成CA证书
212+
213+
## 根证书
214+
215+
具体代码请看:[生成根证书](https://github.com/Wscats/node-tutorial/blob/master/middlewareAgent/CA/createRootCA.js)
216+
217+
执行完`npm run createRootCA`后,CA根证书的公私钥会生成到项目根路径的rootCA文件夹下
218+
219+
|||
220+
|-|-|
221+
|公钥文件|rootCA/rootCA.crt|
222+
|私钥文件|rootCA/rootCA.key.pem|
223+
224+
## 安装CA根证书
225+
226+
⚠️注意:
227+
228+
- 1.必须要按照上面步骤先生成CA证书相关文件
229+
- 2.每一次生成的证书和密钥都是独一无二的。
230+
231+
在MAC系统下找到**钥匙串访问**,然后双击打开证书文件`rootCA/rootCA.crt`完成安装,并且有可能需要在**信任-使用此证书时**里面设置**始终信任**
232+
233+
<img src="./assets/mac-proxy4.png">
234+
235+
或者在项目根路径下执行下面命令,然后输入用户密码或者指纹后即可安装成功。
236+
237+
```bash
238+
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain rootCA/rootCA.crt
239+
```
240+
241+
## 子证书
242+
243+
执行完`npm run createCertByRootCA`后,CA子证书的公私钥会生成到项目根路径的cert文件夹下
244+
245+
|||
246+
|-|-|
247+
|公钥文件|cert/my.crt|
248+
|私钥文件|cert/my.key.pem|
249+
250+
另外和CA根证书最大的不同是,该子证书是用CA根证书的私钥签名,而CA根证书是用自己的私钥自签名。这也从代码的角度认识到了证书链的原理
251+
```js
252+
// 用CA根证书私钥签名
253+
cert.sign(caKey, forge.md.sha256.create());
254+
```
255+
配合HTTP隧道和证书实现HTTPS代理,具体源代码请看[https.js](https://github.com/Wscats/node-tutorial/blob/master/middlewareAgent/browserAgent/https/https.js)[createFakeHttpsWebSite.js](https://github.com/Wscats/node-tutorial/blob/master/middlewareAgent/browserAgent/https/createFakeHttpsWebSite.js)
205256

206257
# 设置代理
207258

666 KB
Loading

middlewareAgent/browserAgent/https/createFakeHttpsWebSite.js

Lines changed: 63 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ const http = require('http');
77
const https = require('https');
88
const fs = require('fs');
99

10-
11-
1210
const caCertPath = path.join(__dirname, '../../CA/rootCA/rootCA.crt');
1311
const caKeyPath = path.join(__dirname, '../../CA/rootCA/rootCA.key.pem');
1412

@@ -36,12 +34,14 @@ const caKey = forge.pki.privateKeyFromPem(caKeyPem);
3634
* @return {[type]} [description]
3735
*/
3836
function createFakeHttpsWebSite(domain, successFun) {
39-
const fakeCertObj = createFakeCertificateByDomain(caKey, caCert, domain)
37+
// 针对域名生成公钥和私钥
38+
const fakeCertObj = createFakeCertificateByDomain(caKey, caCert, domain);
39+
// 构建一个https服务器
4040
var fakeServer = new https.Server({
41-
key: fakeCertObj.key,
42-
cert: fakeCertObj.cert,
41+
key: pki.privateKeyToPem(fakeCertObj.key),
42+
cert: pki.certificateToPem(fakeCertObj.cert),
4343
SNICallback: (hostname, done) => {
44-
let certObj = createFakeCertificateByDomain(caKey, caCert, hostname)
44+
let certObj = createFakeCertificateByDomain(caKey, caCert, hostname);
4545
done(null, tls.createSecureContext({
4646
key: pki.privateKeyToPem(certObj.key),
4747
cert: pki.certificateToPem(certObj.cert)
@@ -54,25 +54,25 @@ function createFakeHttpsWebSite(domain, successFun) {
5454
successFun(address.port);
5555
});
5656
fakeServer.on('request', (req, res) => {
57-
5857
// 解析客户端请求
5958
var urlObject = url.parse(req.url);
60-
let options = {
59+
let options = {
6160
protocol: 'https:',
6261
hostname: req.headers.host.split(':')[0],
6362
method: req.method,
6463
port: req.headers.host.split(':')[1] || 80,
6564
path: urlObject.path,
6665
headers: req.headers
6766
};
68-
res.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8'});
69-
res.write(`<html><body>我是伪造的: ${options.protocol}//${options.hostname} 站点</body></html>`)
67+
res.writeHead(200, {
68+
'Content-Type': 'text/html;charset=utf-8'
69+
});
70+
res.write(`<html><body>我是伪造的: ${options.protocol}//${options.hostname} 站点</body></html>`);
7071
res.end();
7172
});
7273
fakeServer.on('error', (e) => {
7374
console.error(e);
7475
});
75-
7676
}
7777

7878
/**
@@ -87,73 +87,74 @@ function createFakeCertificateByDomain(caKey, caCert, domain) {
8787
var cert = pki.createCertificate();
8888
cert.publicKey = keys.publicKey;
8989

90-
cert.serialNumber = (new Date()).getTime()+'';
90+
cert.serialNumber = (new Date()).getTime() + '';
9191
cert.validity.notBefore = new Date();
9292
cert.validity.notBefore.setFullYear(cert.validity.notBefore.getFullYear() - 1);
9393
cert.validity.notAfter = new Date();
9494
cert.validity.notAfter.setFullYear(cert.validity.notAfter.getFullYear() + 1);
9595
var attrs = [{
96-
name: 'commonName',
97-
value: domain
96+
name: 'commonName',
97+
value: domain
9898
}, {
99-
name: 'countryName',
100-
value: 'CN'
99+
name: 'countryName',
100+
value: 'CN'
101101
}, {
102-
shortName: 'ST',
103-
value: 'GuangDong'
102+
shortName: 'ST',
103+
value: 'GuangDong'
104104
}, {
105-
name: 'localityName',
106-
value: 'ShengZhen'
105+
name: 'localityName',
106+
value: 'ShengZhen'
107107
}, {
108-
name: 'organizationName',
109-
value: 'https-mitm-proxy-handbook'
108+
name: 'organizationName',
109+
value: 'https-mitm-proxy-handbook'
110110
}, {
111-
shortName: 'OU',
112-
value: 'https://github.com/wuchangming/https-mitm-proxy-handbook'
111+
shortName: 'OU',
112+
value: 'https://github.com/wuchangming/https-mitm-proxy-handbook'
113113
}];
114114

115115
cert.setIssuer(caCert.subject.attributes);
116116
cert.setSubject(attrs);
117117

118118
cert.setExtensions([{
119-
name: 'basicConstraints',
120-
critical: true,
121-
cA: false
122-
},
123-
{
124-
name: 'keyUsage',
125-
critical: true,
126-
digitalSignature: true,
127-
contentCommitment: true,
128-
keyEncipherment: true,
129-
dataEncipherment: true,
130-
keyAgreement: true,
131-
keyCertSign: true,
132-
cRLSign: true,
133-
encipherOnly: true,
134-
decipherOnly: true
135-
},
136-
{
137-
name: 'subjectAltName',
138-
altNames: [{
139-
type: 2,
140-
value: domain
141-
}]
142-
},
143-
{
144-
name: 'subjectKeyIdentifier'
145-
},
146-
{
147-
name: 'extKeyUsage',
148-
serverAuth: true,
149-
clientAuth: true,
150-
codeSigning: true,
151-
emailProtection: true,
152-
timeStamping: true
153-
},
154-
{
155-
name:'authorityKeyIdentifier'
156-
}]);
119+
name: 'basicConstraints',
120+
critical: true,
121+
cA: false
122+
},
123+
{
124+
name: 'keyUsage',
125+
critical: true,
126+
digitalSignature: true,
127+
contentCommitment: true,
128+
keyEncipherment: true,
129+
dataEncipherment: true,
130+
keyAgreement: true,
131+
keyCertSign: true,
132+
cRLSign: true,
133+
encipherOnly: true,
134+
decipherOnly: true
135+
},
136+
{
137+
name: 'subjectAltName',
138+
altNames: [{
139+
type: 2,
140+
value: domain
141+
}]
142+
},
143+
{
144+
name: 'subjectKeyIdentifier'
145+
},
146+
{
147+
name: 'extKeyUsage',
148+
serverAuth: true,
149+
clientAuth: true,
150+
codeSigning: true,
151+
emailProtection: true,
152+
timeStamping: true
153+
},
154+
{
155+
name: 'authorityKeyIdentifier'
156+
}
157+
]);
157158
cert.sign(caKey, forge.md.sha256.create());
158159

159160
return {

middlewareAgent/browserAgent/https/https.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ httpTunnel.on('error', (e) => {
2828
httpTunnel.on('connect', (req, cltSocket, head) => {
2929
// connect to an origin server
3030
var srvUrl = url.parse(`http://${req.url}`);
31-
3231
console.log(`CONNECT ${srvUrl.hostname}:${srvUrl.port}`);
33-
3432
createFakeHttpsWebSite(srvUrl.hostname, (port) => {
3533
var srvSocket = net.connect(port, '127.0.0.1', () => {
3634
cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
3735
'Proxy-agent: MITM-proxy\r\n' +
3836
'\r\n');
37+
cltSocket.on('error', (e) => {
38+
console.error(e);
39+
})
40+
cltSocket.on('data', (data) => {
41+
// console.log(data.toString());
42+
});
3943
srvSocket.write(head);
4044
srvSocket.pipe(cltSocket);
4145
cltSocket.pipe(srvSocket);

0 commit comments

Comments
 (0)