> 文章列表 > 从零开始云服务器网卡抓包

从零开始云服务器网卡抓包

从零开始云服务器网卡抓包

从零开始云服务器网卡抓包

  • 一. 服务器上新增自己的用户
  • 二. 添加组件libpcap
  • 四. 安装测试环境
  • 六. 编写demo代码
  • 七. 正式项目代码编译
  • 八. 结果展示

一. 服务器上新增自己的用户

我这边是ubuntu服务器,其默认username为ubuntu,使用创建服务器时候的密码通过ssh登录进来

  1. 新增用户
adduser lsy

从零开始云服务器网卡抓包
2. 将用户lsy添加到root用户组
主要是需要在文件/etc/sudoers中加入用户信息

chmod 777 /etc/sudoers

编辑/etc/sudoers,插入下图内容,即可将用户加入root组
从零开始云服务器网卡抓包

chmod 440 /etc/sudoers

二. 添加组件libpcap

wget http://www.tcpdump.org/release/libpcap-1.4.0.tar.gz
sudo apt install bison m4 flex libpcap-dev -ycd ../libpcap-1.4.0
sudo ./configure 
sudo make
sudo make install

四. 安装测试环境

sudo apt install nginx

六. 编写demo代码

下例代码是测试代码,仅将访问日志打印出来

#include <pcap.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <iostream>
#include <cstring>#define HTTP_PORT 80using namespace std;
#define ETH_ADDR_LENGTH		6
struct ethhdr {unsigned char h_dst[ETH_ADDR_LENGTH];unsigned char h_src[ETH_ADDR_LENGTH];unsigned short h_proto;}; // 14struct ip_header {u_int8_t  	hdrlen : 4,ip_version : 4;          // 版本和首部长度u_int8_t  ip_tos;          // 服务类型u_int16_t ip_len;          // 总长度u_int16_t ip_id;           // 标识u_int16_t ip_off : 13,          // 片偏移flag : 3;u_int8_t  ip_ttl;          // 存活时间u_int8_t  ip_p;            // 协议类型u_int16_t ip_sum;          // 校验和struct in_addr ip_src, ip_dst; // 源地址和目的地址
};struct tcp_header {u_int16_t th_sport;        // 源端口号u_int16_t th_dport;        // 目的端口号u_int32_t th_seq;          // 序列号u_int32_t th_ack;          // 确认号u_int8_t  th_offx2;        // 数据偏移u_int8_t  th_flags;        // 控制标记u_int16_t th_win;          // 窗口大小u_int16_t th_sum;          // 校验和u_int16_t th_urp;          // 紧急指针
};void parse_http_header(char *data, int data_len) {char *start = strstr(data, "GET");if (start == NULL) {start = strstr(data, "POST");}if (start == NULL) {// 不是 HTTP 请求,不处理return;}// 解析出 PATHchar *end = strstr(start, " HTTP/1.");if (end == NULL) {// 不是 HTTP 请求,不处理return;}int path_len = end - start - 4;char path[1024];strncpy(path, start + 4, path_len);path[path_len] = '\\0';printf("PATH: %s\\n", path);
}void handle_packet(u_char *user, const struct pcap_pkthdr *header, const u_char *pkt_data) {// 解析 IP 头部struct ethhdr *ethhdr_info = (struct ethhdr*) pkt_data;struct ip_header *ip_hdr = (struct ip_header *) (pkt_data + sizeof(struct ethhdr));if (ip_hdr->ip_p != IPPROTO_TCP) {// 不是 TCP 协议,不处理
/*	int i;for(i=0;i<32;i++){printf("%02X ", pkt_data[i+sizeof(struct ethhdr)]);}*///printf("\\nherder:%x%x, ip_hdr->ip_p:%d\\n",ip_hdr->ip_version, ip_hdr->hdrlen, ip_hdr->ip_p);return;}// 解析 TCP 头部struct tcp_header *tcp_hdr = (struct tcp_header *) (pkt_data + sizeof(struct ip_header) + sizeof(struct ethhdr));if (ntohs(tcp_hdr->th_dport) != HTTP_PORT) {// 不是 HTTP 请求,不处理return;}{int i;// printf("off:%d, ip_len:%d \\n", tcp_hdr->th_offx2, ntohs(ip_hdr->ip_len));// for(i=0;i<ip_hdr->ip_len;i++)// {//     printf("%02X ", pkt_data[i+sizeof(struct ethhdr)]);// }}// printf("\\n");int data_len = ntohs(ip_hdr->ip_len) - sizeof(struct ip_header) - tcp_hdr->th_offx2/4;if (data_len <= 1) {// 没有数据,不处理return;}// 打印源地址、目的地址和printf("\\nSRC: %s:", inet_ntoa(ip_hdr->ip_src));{int i;for(i=0;i<6;i++){printf(" %02X", ethhdr_info->h_src[i]);}}printf("\\nDST: %s:",  inet_ntoa(ip_hdr->ip_dst));{int i;for(i=0;i<6;i++){printf(" %02X", ethhdr_info->h_dst[i]);}}putchar('\\n');// printf("SEQ: %u\\n", ntohl(tcp_hdr->th_seq));// 解析 HTTP 头部char *data = (char *) (pkt_data + sizeof(struct ip_header) + sizeof(struct ethhdr) + tcp_hdr->th_offx2/4);printf("data:%s\\n", data);// printf("ip_len:%d, ip_header:%ld, tcp_header:%ld, body_len:%ld\\n", ntohs(ip_hdr->ip_len), sizeof(struct ip_header), sizeof(struct tcp_header), strlen(data));parse_http_header(data, data_len);
}int main(int argc, char *argv[]) {char errbuf[PCAP_ERRBUF_SIZE];pcap_t *handle = pcap_open_live(argv[1], BUFSIZ, 1, 1000, errbuf);if (handle == NULL) {cerr << "Error opening device: " << errbuf << endl;return -1;}if (pcap_datalink(handle) != DLT_EN10MB) {cerr << "Device not Ethernet" << endl;return -1;}struct bpf_program fp;char filter_exp[] = "dst port 80";// char filter_exp[] = "";if (pcap_compile(handle, &fp, filter_exp, 0, PCAP_NETMASK_UNKNOWN) == -1) {cerr << "Error compiling filter" << endl;return -1;}if (pcap_setfilter(handle, &fp) == -1) {cerr << "Error setting filter" << endl;return -1;}pcap_loop(handle, -1, handle_packet, NULL);pcap_freecode(&fp);pcap_close(handle);return 0;
}

七. 正式项目代码编译

  1. 下载必要工具
sudo apt install make cmake
  1. 下载项目源码
git clone https://gitee.com/lovejj77/http_grab.git
  1. 编译源码
cd http_grab
cd log4cpp
./configure
make
make installcd http_grab
mkdir build
cd build
cmake ..
make
  1. 设置开机启动服务
vim /etc/rc.local
#在最后一行插入下述指令
/usr/local/sbin/http_grab eth0
#保存退出

八. 结果展示

注意:生产文件均位于/home/logs_file 目录下
从零开始云服务器网卡抓包
从零开始云服务器网卡抓包