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

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

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

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

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

  1. 新增用户
adduser lsy

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

chmod 777 /etc/sudoers

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

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 -y

cd ../libpcap-1.4.0
sudo ./configure 
sudo make
sudo make install

四. 安装测试环境

sudo apt install nginx

六. 编写demo代码

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

#include 
#include 
#include 
#include 
#include 
#include 

#define HTTP_PORT 80

using 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;
	
}; // 14

struct 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;
    }

    // 解析出 PATH
    char *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;iip_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 install

cd http_grab
mkdir build
cd build
cmake ..
make
  1. 设置开机启动服务
vim /etc/rc.local
#在最后一行插入下述指令
/usr/local/sbin/http_grab eth0
#保存退出

八. 结果展示

注意:生产文件均位于/home/logs_file 目录下
在这里插入图片描述
从零开始云服务器网卡抓包_第3张图片

你可能感兴趣的:(网络分析,网络)