服务端的抓包

如果不会在Linux命令行方式下抓包,永远不会成为服务端开发的高手;
当一个技术系统变得越来越庞大复杂的时候,用抓包的方式来掌握和理解其中的网络交互,就变得尤为重要;
抓包是掌握生产系统的一种方式,这种方式不依赖于具体的业务逻辑

最近发现身边很多Java程序员和PHP程序员不会在服务器上抓包,还是蛮吃惊的,这里结合多年的经验,讲解如何在服务器上抓包

1. Problem

这里列举几个典型的技术问题,这些问题使用其他方法比较难以解决,或者解决的效率比较低,但是使用抓包的方式就可以很好的处理。

1.1 后端系统间的通讯可靠性

假设两个后端系统A和B,A发了一个请求给B,但是B没有收到。A系统的业务日志显示已经发送请求,但是B系统的业务日志却没有收到相关请求的日志,如何定位问题

假如这个问题不是必现,而是偶尔出现,又该如何解决

1.2 如何确定请求方

有的时候,一个技术系统会突然收到很多莫名的请求,这些请求占用了蛮多的服务器资源,如何确定请求来自于哪里

2. Solution

在服务器上抓包,观察网络流可以解决上述问题,常用的抓包命令如下:

root@:~# tcpdump -iany -Xn -s0 port 443
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes

17:04:11.888152 IP 36.24.158.122.27603 > 10.133.206.234.https: Flags [S], seq 608876073, win 65535, options [mss 1412,nop,wscale 6,nop,nop,TS val 286050563 ecr 0,sackOK,eol], length 0
    0x0000:  4500 0040 0000 4000 3306 abb6 2418 9e7a  E..@..@.3...$..z
    0x0010:  0a85 ceea 6bd3 01bb 244a b629 0000 0000  ....k...$J.)....
    0x0020:  b002 ffff 7918 0000 0204 0584 0103 0306  ....y...........
    0x0030:  0101 080a 110c c903 0000 0000 0402 0000  ................
    0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
17:04:11.888235 IP 10.133.206.234.https > 36.24.158.122.27603: Flags [S.], seq 539909370, ack 608876074, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
    0x0000:  4500 0034 0000 4000 4006 9ec2 0a85 ceea  E..4..@.@.......
    0x0010:  2418 9e7a 01bb 6bd3 202e 5cfa 244a b62a  $..z..k...\.$J.*
    0x0020:  8012 7210 9c28 0000 0204 05b4 0101 0402  ..r..(..........
    0x0030:  0103 0307 0000 0000 0000 0000 0000 0000  ................
    0x0040:  0000 0000                                ....

2.1 tcpdump的工作原理

当网卡收到一个网络报文后,会将该报文发给所有能处理该报文的网络协议模块来进行解析处理。tcpdump通过注册一种虚拟的底层网络协议来获得对相关报文的处理权,同时将报文完整的复制一份,根据用户的过滤条件和展示选项进行报文的处理。

2.2 tcpdump常用选项

  1. -i: 选定网卡的interface进行抓包,可取值为any(所有接口)、eth0(eth0接口)等
  2. -n: 不要对主机名进行解析,即直接显示IP地址
  3. -nn: 不要对主机名和端口进行解析,即直接显示IP地址和数字形式的端口号
  4. -X: 抓到的包展示内容的时候,既包括Hex的样式,也包括ASCII码的样式
  5. -s: 对每一个抓到的包,限制包的大小(以字节为单位):-s0表示不限制大小,全部抓取和展示,-s 128 表示展示128个字节

2.3 tcpdump常用的过滤表达式

在一个繁忙的服务器上抓包的时候,会有大量的traffic,为了过滤出来你关心的报文,经常使用Expression进行过滤。

  1. host: 对主机进行过滤,host后面跟服务器的IP,比如host 192.168.100.1表示只抓取源IP或者目的IP为192.168.100.1的报文
  2. port: 对端口进行过滤,port后面跟服务器的端口号,比如port 80表示只抓取源端口号或者目的端口号为80的报文
  3. srcdst: 这两个用户控制网络流的方向过滤,比如dst port 80表示只抓取目的端口号为80的报文,src ip 192.168.100.1表示只抓取源IP为192.168.100.1的报文
  4. 将过滤条件进行组合
    可以使用and or not和小括号(需要\来转义)来组合过滤条件,如下所示:
tcpdump -iany -Xn -s0 port 443 and \( not host 192.168.100.1 or host 192.168.100.2 \)

2.4 将tcpdump抓到的包保存到文件上

可以将tcpdump抓到的包保存到文件上,格式可以是二进制的(PCAP格式,可以下载到Windows用wireshark打卡),也可以是文本格式。

举例A. 将tcpdump抓到的包以二进制形式保存到文件上,使用-w选项

tcpdump -iany -Xn -s0 port 443 -w /tmp/aaa.pcap

举例B. 将tcpdump抓到的包以文本形式保存到文件上,使用重定向

tcpdump -iany -Xn -s0 port 443 > /tmp/aaa.txt 2>&1

3. Discussion

3.1 TCP的连接建立

TCP的连接建立是通过收发双方的三次握手进行的

每个packet第一行里的Flags [S]中表示握手阶段(S为synchronize的缩写),双方握手主要是在交换收发双方当前的序列号、窗口大小和其他TCP的选项;每个packet第一行里的ack 2335101116表示接收方对发送方内容的ack,以序列号为标志。

14:26:52.511678 IP 10.133.206.234.36018 > 10.66.149.55.3306: Flags [S.], seq 2335101115, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
    0x0000:  4500 0034 e5e4 4000 4006 dbf6 0a85 ceea  E..4..@.@.......
    0x0010:  0a42 9537 8cb2 0cea 8b2e d0bb 0000 0000  .B.7............
    0x0020:  8002 7210 790f 0000 0204 05b4 0101 0402  ..r.y...........
    0x0030:  0103 0307 0000 0000 6f6d 2060 745f 7573  ........om.`t_us
    0x0040:  725f 7072                                r_pr
14:26:52.511960 IP 10.66.149.55.3306 > 10.133.206.234.36018: Flags [S.], seq 3990271169, ack 2335101116, win 5760, options [mss 1404,nop,nop,sackOK,nop,wscale 7], length 0
    0x0000:  4500 0034 0000 4000 3f06 c2db 0a42 9537  E..4..@.?....B.7
    0x0010:  0a85 ceea 0cea 8cb2 edd6 b4c1 8b2e d0bc  ................
    0x0020:  8012 1680 47b0 0000 0204 057c 0101 0402  ....G......|....
    0x0030:  0103 0307 7369 6f6e 2073 716c 5f6d 6f64  ....sion.sql_mod
    0x0040:  653d 274f                                e='O
14:26:52.511991 IP 10.133.206.234.36018 > 10.66.149.55.3306: Flags [.], ack 1, win 229, length 0
    0x0000:  4500 0028 e5e5 4000 4006 dc01 0a85 ceea  E..(..@.@.......
    0x0010:  0a42 9537 8cb2 0cea 8b2e d0bc edd6 b4c2  .B.7............
    0x0020:  5010 00e5 7903 0000 0100 0001 1944 0000  P...y........D..
    0x0030:  0203 6465 6608 6175                      ..def.au

3.2 TCP的连接释放

TCP的连接释放是通过收发双方的四次释放完成的

每个packet第一行里的Flags [F]中表示开始释放(F表示Finish)。

下述抓包是端口为20103的进程,主动关闭MySQL(端口号为3306):

  1. 20103的进程首先发送Fin包给MySQL
  2. MySQL对此Fin包进行ack
  3. MySQL再对20103的进程发Fin包
  4. 20103的进程对MySQL的Fin包进行确认
10:10:06.468550 IP 10.133.206.234.20103 > 10.66.149.55.3306: Flags [F.], seq 604, ack 4107, win 318, length 0
    0x0000:  4500 0028 db7d 4000 4006 e669 0a85 ceea  E..(.}@.@..i....
    0x0010:  0a42 9537 4e87 0cea 35e7 a877 21a4 a45e  .B.7N...5..w!..^
    0x0020:  5011 013e 7903 0000 0204 057c 0101 0402  P..>y......|....
    0x0030:  0103 0307 0000 0072                      .......r
10:10:06.468853 IP 10.66.149.55.3306 > 10.133.206.234.20103: Flags [.], ack 604, win 62, length 0
    0x0000:  4508 0028 b918 4000 3f06 09c7 0a42 9537  E..(..@.?....B.7
    0x0010:  0a85 ceea 0cea 4e87 21a4 a45e 35e7 a877  ......N.!..^5..w
    0x0020:  5010 003e 36db 0000 1000 0000 0375 7365  P..>6........use
    0x0030:  2060 6175 6374 696f                      .`auctio
10:10:06.468856 IP 10.66.149.55.3306 > 10.133.206.234.20103: Flags [F.], seq 4107, ack 604, win 62, length 0
    0x0000:  4508 0028 b919 4000 3f06 09c6 0a42 9537  E..(..@.?....B.7
    0x0010:  0a85 ceea 0cea 4e87 21a4 a45e 35e7 a877  ......N.!..^5..w
    0x0020:  5011 003e 36da 0000 5800 0000 0a35 2e35  P..>6...X....5.5
    0x0030:  2e32 342d 4344 422d                      .24-CDB-
10:10:06.468886 IP 10.133.206.234.20103 > 10.66.149.55.3306: Flags [.], ack 4108, win 318, length 0
    0x0000:  4500 0028 db7e 4000 4006 e668 0a85 ceea  E..(.~@.@..h....
    0x0010:  0a42 9537 4e87 0cea 35e7 a878 21a4 a45f  .B.7N...5..x!.._
    0x0020:  5010 013e 7903 0000 3100 0000 1673 6574  P..>y...1....set
    0x0030:  206e 616d 6573 2027                      .names.'

3.3 TCP的数据传输

一般而言,TCP建立连接后开始进行数据传输,第一行里的length字段表示传输的payload的长度。

Flags [P.]表示发送方已经将当前发送buffer里的所有数据发给接收方,接收方需要尽快将此数据上报给顶层应用,P表示Push。如果没有Flags [P.],则表示此packet发完之后,发送buffer里还有待发送的数据。

示例A:MySQL应答了1424字节的数据,但是MySQL对应的tcp里的发送buffer,还有数据。

10:10:06.458574 IP 10.66.149.55.3306 > 10.133.206.234.20103: Flags [.], seq 169:1593, ack 522, win 62, length 1424
    0x0000:  4508 05b8 b914 4000 3f06 043b 0a42 9537  E.....@.?..;.B.7
    0x0010:  0a85 ceea 0cea 4e87 21a4 94fc 35e7 a825  ......N.!...5..%
......

示例B:MySQL应答了618字节的数据,MySQL对应的tcp里的发送buffer里已经没有数据,接收方需要尽快将此数据上浮给高层应用。

10:10:06.458574 IP 10.66.149.55.3306 > 10.133.206.234.20103: Flags [P.], seq 1593:2211, ack 522, win 62, length 618
    0x0000:  4508 0292 b915 4000 3f06 0760 0a42 9537  E.....@.?..`.B.7
    0x0010:  0a85 ceea 0cea 4e87 21a4 9a8c 35e7 a825  ......N.!...5..%
    0x0020:  5018 003e 4bc7 0000 725f 6e61 6d65 0e64  P..>K...r_name.d
    0x0030:  6561 6c5f 6164 6472 5f6e 616d 650c e000  eal_addr_name...

3.4 TCP的包头格式

1530845376699.jpg

常见标记:

  1. S ( SYN synchronize ):Synchronize sequence numbers to initiate a connection
  2. A ( ACK acknowledgement ): Acknowledge sender packet with sequence number
  3. F ( FIN finish ):The sender of the segment is finished sending data to its peer
  4. R ( RST reset ): Reset the connection (connection abort, usually because of an error)
  5. P ( PSH push ): The receiver should pass this data to the application as soon as possible

备注:R标记的包,在网络排故的时候很有用,如果tcpdump抓出来的包有大量的reset标记,大概率意味着连接请求被防火墙或者其他安全措施挡住啦。

3.5 二进制协议

TCP/IP协议族中的大部分协议,其Header都组织为二进制格式,即每个bit或者bit串需要当成数值直接定义;另外很多Application也将自己的协议(例如PC QQ)组织为二进制的格式,二进制协议不易读,但是占用空间小,因而传输效率高。

下图为一个应用程序发起连接MySQL的请求,报文里0x0012字节的值为0x4e87 = 20103,即为发送方的端口号;报文里0x0013字节的值为0x0cea = 3306,即为服务方的端口号。

WechatIMG642.jpeg

对于二进制协议,经常接合包里某个偏移位置上的内容进行抓包,比如下边的命令可以抓取所有和MySQL交互的报文:

root@:~# tcpdump -iany -Xn -nn -s0 ip[0x0014:2] = 0x0cea or ip[0x0016:2] = 0x0cea

3.6 字符串协议

包括MySQL、RabbitMQ在内,很多Application也会将自己的协议组织为字符串的格式,字符串格式的协议比较human-readable,可以对抓到的报文做很多二次操作。

对SQL(select * from t_usr_profile where mobile_phone = '13155668877')的抓包结果如下:

11:34:38.933455 IP 10.133.206.234.33166 > 10.66.149.55.3306: Flags [P.], seq 2397:2488, ack 148577, win 1475, length 91
    0x0000:  4500 0083 bdf5 4000 4006 0397 0a85 ceea  E.....@.@.......
    0x0010:  0a42 9537 818e 0cea daa3 0567 8b16 d9f5  .B.7.......g....
    0x0020:  5018 05c3 795e 0000 5400 0000 0000 0050  P...y^..T......P
    0x0030:  0000 0003 5345 4c45 4354 202a 2046 524f  ....SELECT.*.FRO
    0x0040:  4d20 6074 5f75 7372 5f70 726f 6669 6c65  M.`t_usr_profile
    0x0050:  6020 5748 4552 4520 606d 6f62 696c 655f  `.WHERE.`mobile_
    0x0060:  7068 6f6e 6560 203d 2027 3133 3135 3536  phone`.=.'131556
    0x0070:  3638 3837 3727 204c 494d 4954 2030 2c31  68877'.LIMIT.0,1
    0x0080:  3030 3041 5445 2c45 5252 4f52 5f46 4f52  000ATE,ERROR_FOR
    0x0090:  5f44 49                                  _DI

我们可以把这类抓包保存到文本文件上,结合Linux的搜索命令,快速定位出操作手机号131556的请求(主要是搜索抓包结果最右侧的文本内容,因此注意折行)

3.7 其他方式的抓包

HTTPS的抓包:HTTPS因为加密的缘由,已经无法查看抓到的包的内容啦,如果大伙有高招(服务端),请告诉我。

另外,tcpdump的兄弟工具,wireshark以插件的形式对外提供了很多parse包的定制化能力,结合Lua语言可以构建出强大的二次分析能力。

4. Answer

4.1 请求的不可达(必现)

假设两个后端系统A和B,A发了一个请求给B,但是B没有收到。A系统的业务日志显示已经发送请求,但是B系统的业务日志却没有收到相关请求的日志,如何定位问题

在B的服务器上抓包,过滤主机A的IP,观察相关的报文是否达到服务器B上

tcpdump -iany -Xn -s0 host 192.168.100.1

4.2 请求的不可达(不是必现)

假如4.1的问题不是必现,而是偶尔出现,又该如何解决

在后台抓一段时间的包,之后再分析抓包的结果(特别注意:如果抓包量比较大的话,一定要避免把磁盘打满,此时需要增加更多的过滤表达式

//将抓到的包输出到/tmp/1里,并且在后台运行
root@:~# nohup tcpdump -iany -Xn -nn -s0 host 10.66.149.55 > /tmp/1 2>&1 &

//可以看到存储包的文件大小在不断的涨
root@:~# ls -lh /tmp/1
-rw-r--r-- 1 root root 2.4M 7月   6 17:05 /tmp/1

//查看后台运行的job
root@:~# jobs
[2]+  运行中               nohup tcpdump -iany -Xn -nn -s0 host 10.66.149.55 > /tmp/1 2>&1 &

//将后台运行的job切换到前台
root@:~# fg 2
nohup tcpdump -iany -Xn -nn -s0 host 10.66.149.55 > /tmp/1 2>&1

//结束抓包 Ctrl + C

//用其他命令来分析抓包结果,进而判断究竟是包没有达到B,还是A没有发出,还是被防火墙拦住啦
root@:~# ls -lh /tmp/1
-rw-r--r-- 1 root root 11M 7月   6 17:08 /tmp/1

4.3 确定请求方

有的时候,一个技术系统会突然收到很多莫名的请求,这些请求占用了蛮多的服务器资源,如何确定请求来自于哪里。

假设这个请求有固定的特征,比如说有固定的订单号或其他标识串,这个特征可以在抓包结果的最右侧捕获到。

解决这类问题的总思路是分析请求方服务器IP的分布,根据IP分布确定原因,一般而言原因分为几类:

  1. 服务方系统自身的bug,导致了ping-pang(A系统发请求给B,B请求了C,C又请求了A,也就是说同一个请求在系统间不停的路由转发而不总结),ping-pang是最为严重的bug,很容易把系统压瘫痪
  2. 系统配置有误,导致请求方不断在重试该请求
  3. 请求方底层依赖的框架或组件有bug(重发策略或路由分发策略等),导致不断重发一些过期的请求

下面以MySQL不断收到如下SQL的查询为例,列举一些思路和使用到的命令,这里的核心是熟练掌握Linux的常用命令

select * from `t_usr_profile` where `mobile_phone` = '13155668877'
  1. 在服务方的机器上根据服务端口抓一段时间包,假设服务端是MySQL,则使用dst port 3306来过滤抓到的包,将抓到的包重定向到临时文件上(aaa),形如:
nohup tcpdump -iany -Xn -s0 dst port 3306 > /tmp/aaa 2>&1 &

; /tmp/aaa内容如下:
11:34:38.933455 IP 10.133.206.234.33166 > 10.66.149.55.3306: Flags [P.], seq 2397:2488, ack 148577, win 1475, length 91
    0x0000:  4500 0083 bdf5 4000 4006 0397 0a85 ceea  E.....@.@.......
    0x0010:  0a42 9537 818e 0cea daa3 0567 8b16 d9f5  .B.7.......g....
    0x0020:  5018 05c3 795e 0000 5400 0000 0000 0050  P...y^..T......P
    0x0030:  0000 0003 5345 4c45 4354 202a 2046 524f  ....SELECT.*.FRO
    0x0040:  4d20 6074 5f75 7372 5f70 726f 6669 6c65  M.`t_usr_profile
    0x0050:  6020 5748 4552 4520 606d 6f62 696c 655f  `.WHERE.`mobile_
    0x0060:  7068 6f6e 6560 203d 2027 3133 3135 3536  phone`.=.'131556
    0x0070:  3638 3837 3727 204c 494d 4954 2030 2c31  68877'.LIMIT.0,1
    0x0080:  3030 3041 5445 2c45 5252 4f52 5f46 4f52  000ATE,ERROR_FOR
    0x0090:  5f44 49                                  _DI
  1. 搜索标识串(标识串为131556),并将所抓包的摘要行一起展示。注意grep命令的-B选项
root@:/tmp# grep "131556" aaa -B7 

aaa-10:44:03.460160 IP 10.133.206.234.62790 > 10.66.149.55.mysql: Flags [P.], seq 514:580, ack 329, win 237, length 66
aaa-    0x0000:  4500 006a 3705 4000 4006 8aa0 0a85 ceea  E..j7.@.@.......
aaa-    0x0010:  0a42 9537 f546 0cea f4ed dac4 03dc 4e32  .B.7.F........N2
aaa-    0x0020:  5018 00ed 7945 0000 3e00 0000 1703 0000  P...yE..>.......
aaa-    0x0030:  0000 0100 0000 0001 0800 0800 0800 0800  ................
aaa-    0x0040:  0800 0200 0000 0000 0000 f328 405b 0000  ...........(@[..
aaa-    0x0050:  0000 0092 3f5b 0000 0000 f328 405b 0000  ....?[.....(@[..
aaa:    0x0060:  0000 0000 0000 0000 0000 3133 3135 3536  ..........131556
--
  1. 将抓到的包的首行grep出来:grep " > "
root@:/tmp# grep "131556" aaa -B7 | grep " >" 
10:43:17.476791 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2208:2286, ack 10677, win 1030, length 78
10:43:17.642296 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2286:2364, ack 11057, win 1052, length 78
10:43:17.808716 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2364:2442, ack 11437, win 1074, length 78
10:43:17.935525 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2442:2520, ack 11817, win 1096, length 78
10:43:18.077713 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2520:2598, ack 12197, win 1119, length 78
10:43:18.264376 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2598:2676, ack 12577, win 1141, length 78
10:43:18.396421 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2676:2754, ack 12957, win 1163, length 78
10:43:18.555735 IP 10.133.206.234.62672 > 10.66.149.55.mysql: Flags [P.], seq 2754:2832, ack 13337, win 1185, length 78
  1. 将请求方IP列出来: awk '{print $3}'
root@:/tmp# grep "131556" aaa -B7 | grep " >" | awk '{print $3}'
10.133.206.234.62672
10.133.206.234.62672
10.133.206.234.62672
10.133.206.234.62672
10.133.206.234.62672
10.133.206.234.62672
10.133.206.234.62672
10.133.206.234.62672
10.133.206.234.62672
  1. 去掉端口号:使用cut命令,-d .标识以.进行分割,-f 1,2,3,4表示显示1 2 3 4四列
root@:/tmp# grep "131556" aaa -B7 | grep " >" | awk '{print $3}' |  cut -d . -f 1,2,3,4

10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
  1. 将请求方IP的排序: sort
root@:/tmp# grep "131556" aaa -B7 | grep " >" | awk '{print $3}' |  cut -d . -f 1,2,3,4 | sort

10.133.206.234
10.133.206.234
10.133.206.234
10.133.206.234
  1. 统计请求方IP的出现次数: uniq -c
root@:/tmp# grep "131556" aaa -B7 | grep " >" | awk '{print $3}' |  cut -d . -f 1,2,3,4 | sort | uniq -c
     61 10.133.206.234

说明10.133.206.234请求了61次

  1. 依据出现次数排序: sort -n
root@:/tmp# grep "131556" aaa -B7 | grep " >" | awk '{print $3}' |  cut -d . -f 1,2,3,4 | sort | uniq -c | sort -n
     61 10.133.206.234
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容