• 10_libpcap以及libnet


    知识点1【飞秋欺骗】

    1、windwos安装飞秋 双击运行

    2、ubuntu安装飞秋 sudo apt-get install iptux

    ubuntu运行飞秋:iptux&

    3、飞秋的格式:

    版本:包编号:用户名:主机名:命令字:附加消息

    飞秋的端口是2425固定的

    1表示上线 32表示普通消息

    1_iptux_0#5#2:8:edu:edu:259:edu

    1. #include<stdio.h>
    2. #include<sys/socket.h>
    3. #include<netinet/ether.h>
    4. #include <sys/ioctl.h>//ioctl
    5. #include <net/if.h>//struct ifreq
    6. #include <netpacket/packet.h>//struct sockaddr_ll
    7. #include<unistd.h>//_exit
    8. #include<string.h>//strncpy
    9. #include <net/ethernet.h>//struct ether_header
    10. #include <net/if_arp.h>//struct arphdr
    11. #include <netinet/ip.h>//struct iphdr
    12. #include <netinet/udp.h>//struct udphdr
    13. void my_sendto(int sockfd, char *out, unsigned char *msg, int msg_len);
    14. typedef struct
    15. {
    16. u_int32_t saddr;//源IP
    17. u_int32_t daddr;//目的IP
    18. u_int8_t flag;//标记(0
    19. u_int8_t type;//udp协议 17
    20. u_int16_t len;//长度
    21. }WEIHDR;
    22. unsigned short checksum(unsigned short *buf, int len)
    23. {
    24. int nword = len/2;
    25. unsigned long sum;
    26. if(len%2 == 1)
    27. nword++;
    28. for(sum = 0; nword > 0; nword--)
    29. {
    30. sum += *buf;
    31. buf++;
    32. }
    33. sum = (sum>>16) + (sum&0xffff);
    34. sum += (sum>>16);
    35. return ~sum;
    36. }
    37. int main()
    38. {
    39. //1、创建原始套接字
    40. int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    41. if(sockfd < 0)
    42. {
    43. perror("socket");
    44. return 0;
    45. }
    46. //获取要发送的消息
    47. printf("请输入要发送的消息:");
    48. char data[128]="1_iptux_0#5#2:123:edu:edu:32:loveyou";
    49. int data_len = strlen(data);
    50. //如果data_len不是偶数 补0为偶数
    51. if(data_len%2 != 0)//奇数
    52. data_len++;
    53. /*目的mac地址 XPmac*/
    54. unsigned char dst_mac[6]={0x70,0x5A,0x0F,0x63,0xF5,0x9D};//win_mac
    55. unsigned char dst_ip[4]={192,168,0,110};//win_ip
    56. unsigned char src_mac[6]={0x00,0x0c,0x29,0x9a,0xeb,0x23};//伪装的mac!!!!
    57. unsigned char src_ip[4]={192,168,0,105};//伪装的IP !!!!!
    58. unsigned char msg[1024]="";
    59. //1、组mac头部
    60. struct ether_header *eth_addr = (struct ether_header *)msg;
    61. //赋值目的mac地址
    62. memcpy(eth_addr->ether_dhost, dst_mac, 6);
    63. //赋值源mac地址
    64. memcpy(eth_addr->ether_shost, src_mac, 6);
    65. //赋值帧类型
    66. eth_addr->ether_type = htons(0x0800);
    67. //2、组IP报文
    68. struct iphdr *ip_hdr = (struct iphdr *)(msg+14);
    69. ip_hdr->version = 4;//IPv4版本
    70. ip_hdr->ihl = 5;//IP头部长度 单位4B 所以赋值5其实就是5*4=20B
    71. ip_hdr->tos = 0;//服务类型
    72. ip_hdr->tot_len = htons(20+8+data_len);//总长度=IP首部长度+IP数据长度
    73. ip_hdr->id = htons(0);//标识
    74. ip_hdr->frag_off = htons(0);//标志 + 片偏移
    75. ip_hdr->ttl = 128;//64128都可以 生命周期
    76. ip_hdr->protocol = 17;//udp 17 tcp 6
    77. ip_hdr->check = htons(0);//首部校验???? 后续校验
    78. memcpy(&ip_hdr->saddr, src_ip, 4);//源IP
    79. memcpy(&ip_hdr->daddr, dst_ip, 4);//目的IP
    80. //ip报文头部校验
    81. ip_hdr->check = checksum(ip_hdr, 20);
    82. //3、udp头部
    83. struct udphdr *udp_hdr = (struct udphdr *)(msg+14+20);
    84. udp_hdr->source = htons(2425);//源端口 !!!!
    85. udp_hdr->dest = htons(2425);//目的端口 !!!!
    86. udp_hdr->len = htons(8+data_len);//udp总长度=udp报文头+数据长
    87. udp_hdr->check = htons(0);//???? udp校验
    88. //data拷贝到udp的数据部分
    89. memcpy(msg+14+20+8, data, data_len);
    90. //准备udp校验
    91. unsigned char wei_head[1024]="";
    92. WEIHDR *wei_hdr = (WEIHDR *)wei_head;
    93. memcpy(&wei_hdr->saddr, src_ip, 4);//源IP
    94. memcpy(&wei_hdr->daddr, dst_ip, 4);//目的IP
    95. wei_hdr->flag = 0;
    96. wei_hdr->type = 17;//协议
    97. wei_hdr->len = htons(8+data_len);//udp的总长度
    98. //将msg中的udp头部信息以及data数据 拷贝到为头部后方
    99. memcpy(wei_head+12, udp_hdr, 8+data_len);
    100. //校验udp: 为头部+udp头部+data部分
    101. udp_hdr->check = checksum(wei_head, 12+8+data_len);
    102. //发送arp请求帧数据
    103. my_sendto(sockfd, "eth0",msg, 14+20+8+data_len);
    104. sleep(5);
    105. close(sockfd);
    106. return 0;
    107. }
    108. void my_sendto(int sockfd, char *out, unsigned char *msg, int msg_len)
    109. {
    110. //通过ioctl得到网络接口
    111. struct ifreq ethreq;
    112. strncpy(ethreq.ifr_name, out, IFNAMSIZ);
    113. if(-1 == ioctl(sockfd, SIOCGIFINDEX, &ethreq))
    114. {
    115. perror("ioctl");
    116. close(sockfd);
    117. _exit(-1);
    118. }
    119. //帧数据 出去的本地接口
    120. struct sockaddr_ll sll;
    121. bzero(&sll,sizeof(sll));
    122. sll.sll_ifindex = ethreq.ifr_ifindex;
    123. //2、发送组好报文的帧数据
    124. sendto(sockfd, msg, msg_len, 0, (struct sockaddr *)&sll, sizeof(sll));
    125. }

    知识点2【libpcap】接受收原始套接字的数据

    1、Libpcap主要的作用

    Libpcap主要的作用如下:

    1、捕获各种数据包

    列如:网络流量统计

    2、过滤网络数据包

    列如:过滤掉本地上的一些数据,类似防火墙

    3、分析网络数据包

    列如:分析网络协议,数据的采集

    4、存储网络数据包

    列如:保存捕获的数据以为将来进行分析

    2、Libpcap的安装

    sudo apt-get install libpcap-dev

    需要的头文件:

    #include 

    编译的时候 -lpcap

    3、libpcap开发实例

    利用libpcap函数库开发应用程序的基本步骤:

    1、打开网络设备

    2、设置过滤规则(可选)

    3、捕获数据

    4、关闭网络设备

    捕获网络数据包常用函数

    1、pcap_lookupdev( )(可选) 查看设备名

    2、pcap_open_live( ) 打开设备

    3、pcap_lookupnet( )(可选) 获取的设备IP

    4、pcap_compile( )、 pcap_setfilter( ) (可选) 设置过滤规则

    5、pcap_next( 调用一次捕获一个报文 )、pcap_loop( 调用一次 不停捕获报文 ) 捕获数据

    6、pcap_close( )

    4、打开设备 获得设备的句柄

    1. pcap_t *pcap_open_live(const char *device,int snaplen,int promisc,
    2. int to_ms,char *ebuf)
    3. 功能:
    4. 打开一个用于捕获数据的网络接口
    5. 返回值:
    6. 返回一个Libpcap句柄
    7.  
    8. 参数:
    9. device:网络接口的名字
    10. snaplen:捕获数据包的长度
    11. promise:1代表混杂模式,其它非混杂模式
    12. to_ms:等待时间
    13. ebuf:存储错误信息

    5、关闭句柄

    void pcap_close(pcap_t *p)

    功能:

    关闭Libpcap操作,并销毁相应的资源

    参数

       p:需要关闭的Libpcap句柄

    返回值:

    例如

    1. const u_char *pcap_next(pcap_t *p,struct pcap_pkthdr *h)
    2. 功能:
    3. 捕获一个网络数据包
    4. 参数:
    5. p:Libpcap句柄
    6. h:数据包头
    7. 返回值:
    8. 捕获的数据包的地址

     struct pcap_pkthdr结构体信息:记录接受数据的时间以及报文的长度

     案例:

    1. #include<stdio.h>
    2. #include <pcap.h>
    3. int main()
    4. {
    5. //1、创建一个pcap句柄
    6. pcap_t *pcap_handle = NULL;
    7. pcap_handle = pcap_open_live("eth0",1500,0,0,NULL);
    8. //2、接受数据
    9. struct pcap_pkthdr pck_hdr;//记录收到数据的时间和报文长度
    10. unsigned char *msg = NULL;//存放接受到的帧数据
    11. msg = pcap_next(pcap_handle, &pck_hdr);
    12. printf("报文长度:%u\n", pck_hdr.caplen);
    13. //msg:mac ip udp/tcp data
    14. //msg的mac地址解析 和 原始套接字一样
    15. //解析msg的mac地址
    16. char src_mac[18]="";
    17. char dst_mac[18]="";
    18. sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \
    19. msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]);
    20. sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \
    21. msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]);
    22. printf("%s--->%s\n", src_mac, dst_mac);
    23. //关闭句柄
    24. pcap_close(pcap_handle);
    25. return 0;
    26. }

    运行结果:

    7、循环的接受网络数据pcap_loop

    1. int pcap_loop(pcap_t *p,int cnt,pcap_handler callback,u_char *user)
    2. 功能:
    3. 循环捕获网络数据包,直到遇到错误或者满足退出条件;
    4. 每次捕获一个数据包就会调用callback指示的回调函数,
    5. 所以,可以在回调函数中进行数据包的处理操作
    6. 返回值:
    7. 成功返回0,失败返回负数
    8. 参数:
    9. p:Libpcap句柄
    10. cnt:指定捕获数据包的个数,如果是-1,就会永无休止的捕获
    11. callback:回调函数
    12. user:向回调函数中传递的参数

    回调函数如何定义: 

    参数1:argument存放pcap_loop传递过来的user用户数据

    参数2:packet_heaher 存放接收到的报文的时间以及长度

    参数3:packet_content接收到的网络帧数据

    案例:

    1. #include<stdio.h>
    2. #include <pcap.h>
    3. //pcap_loop每收到一个报文 就会调用一次回调函数
    4. void callback(u_char *arg, const struct pcap_pkthdr *packet_header, \
    5. const u_char *packet_content)
    6. {
    7. unsigned char *msg = packet_content;
    8. printf("报文长度:%u\n", packet_header->caplen);
    9. //解析msg的mac地址
    10. char src_mac[18]="";
    11. char dst_mac[18]="";
    12. sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \
    13. msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]);
    14. sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \
    15. msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]);
    16. printf("%s--->%s\n", src_mac, dst_mac);
    17. }
    18. int main()
    19. {
    20. //1、创建一个pcap句柄
    21. pcap_t *pcap_handle = NULL;
    22. pcap_handle = pcap_open_live("eth0",1500,0,0,NULL);
    23. //2、接受数据 带阻塞
    24. pcap_loop(pcap_handle, 5, callback, NULL);
    25. //关闭句柄
    26. pcap_close(pcap_handle);
    27. return 0;
    28. }

     运行结果:

    8、设置过滤规则 下面两个函数配合使用

    pcap_compile: 将用户识别的规则 转换成 pcap识别的规则

    pcap_setfilter:将pcap识别的规则 设置到pcap结束数据的句柄中

    1. int pcap_compile(pcap_t *p,struct bpf_program *program,
    2. char *buf,int optimize,bpf_u_int32 mask)
    3. 功能:
    4. 编译BPF过滤规则
    5. 返回值:
    6. 成功返回0,失败返回-1
    7. 参数:
    8. p:Libpcap句柄
    9. program:bpf过滤规则(pcap识别的规则)
    10. buf:过滤规则字符串(用户识别的规则 重心)
    11. optimize:优化
    12. mask:掩码
    1. int pcap_setfilter(pcap *p,struct bpf_program*fp)
    2. 功能:
    3. 设置BPF过滤规则
    4. 返回值:
    5. 成功返回0,失败返回-1
    6. 参数:
    7. p:Libpcap句柄
    8. fp:BPF过滤规则

     过滤规则:

     

     案例:

    1. #include<stdio.h>
    2. #include <pcap.h>
    3. //pcap_loop每收到一个报文 就会调用一次回调函数
    4. void callback(u_char *arg, const struct pcap_pkthdr *packet_header, \
    5. const u_char *packet_content)
    6. {
    7. unsigned char *msg = packet_content;
    8. printf("报文长度:%u\n", packet_header->caplen);
    9. //解析msg的mac地址
    10. char src_mac[18]="";
    11. char dst_mac[18]="";
    12. sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \
    13. msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]);
    14. sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \
    15. msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]);
    16. printf("%s--->%s\n", src_mac, dst_mac);
    17. }
    18. int main()
    19. {
    20. //1、创建一个pcap句柄
    21. pcap_t *pcap_handle = NULL;
    22. pcap_handle = pcap_open_live("eth0",1500,0,0,NULL);
    23. //设置过滤规则
    24. struct bpf_program program;
    25. pcap_compile(pcap_handle,&program, "src port 9000", 0, 0xffffff00);
    26. pcap_setfilter(pcap_handle, &program);
    27. //2、接受数据 带阻塞
    28. pcap_loop(pcap_handle, 5, callback, NULL);
    29. //关闭句柄
    30. pcap_close(pcap_handle);
    31. return 0;
    32. }

     

    知识点3【libnet发送原始套接字数据】

    专业的构造和发送网络数据包的开发工具包

    是个高层次的API函数库,允许开发者自己构造和发送网络数据包

    头文件:include

    编译的是加:-lnet

    Libnet的安装

    Libnet开发流程

    利用libnet函数库开发应用程序的基本步骤:

    1、数据包内存初始化

    2、构造数据包

    3、发送数据

    4、释放资源

    1、内存管理相关函数

    1. libnet_t *libnet_init(int injection_type, char *device, char *err_buf)
    2. 功能:
    3. 数据包内存初始化及环境建立
    4. 参数:
    5. injection_type: 构造的类型
    6. (LIBNET_LINK,LIBNET_RAW4,LIBNET_LINK_ADV(推荐),LIBNET_RAW4_ADV)
    7. device:网络接口,如"eth0",或IP地址,亦可为NULL(自动查询搜索)
    8. err_buf: 存放出错的信息
    9. 返回值:
    10. 成功返回一个libnet句柄;失败返回NULL
    injection_type:构造的类型(LIBNET_LINK,LIBNET_RAW4,LIBNET_LINK_ADV,LIBNET_RAW4_ADV)

     

     2、释放资源

    1. void libnet_destroy(libnet_t *l);
    2. 功能:
    3. 释放资源
    4. 参数:
    5.   l: libnet句柄
    6. 返回值:

    3、构建udp报文 

    1. libnet_ptag_t libnet_build_udp(
    2. u_int16_t sp,u_int16_t dp,u_int16_t len,u_int16_t sum,
    3. u_int8_t *payload,u_int32_t payload_s,
    4. libnet_t *l,libnet_ptag_t ptag)
    5. 功能:
    6. 构造udp数据包
    7. 返回值:
    8. 成功返回协议标记;失败返回-1
    9. 参数:
    10. sp: 源端口号
    11. dp:目的端口号
    12. len:udp包总长度
    13. sum:校验和,设为0,libnet自动填充
    14. payload:负载,可设置为NULL
    15. payload_s:负载长度,或为0
    16. l: libnet句柄
    17. ptag:协议标记(其值为0创建一个新的协议数据,不为0,修改由ptag表示的协议数据)

     4、构造一个IPv4数据包

    1. libnet_ptag_t libnet_build_ipv4(
    2. u_int16_t ip_len,u_int8_t tos,
    3. u_int16_t id,u_int16_t flag,
    4. u_int8_t ttl,u_int8_t prot,
    5. u_int16 sum,u_int32_t src,
    6. u_int32_t dst,u_int8_t *payload,
    7. u_int32_t payload_s,
    8. libnet_t *l,libnet_ptag_t ptag)
    9. 功能:
    10. 构造一个IPv4数据包
    11. 参数:
    12. ip_len:ip包总长
    13. tos:服务类型
    14. id:ip标识
    15. flag:片偏移
    16. ttl:生存时间
    17. prot:上层协议
    18. sum:校验和,设为0,libnet自动填充
    19. src: 源ip地址
    20. dst:目的ip地址
    21. payload:负载,可设置为NULL
    22. payload_s:负载长度,或为0
    23. l: libnet句柄
    24. ptag:协议标记
    25.  
    26. 返回值:
    27. 成功返回协议标记;失败返回-1

    5、构造一个以太网数据包

    1. libnet_ptag_t libnet_build_ethernet(
    2. u_int8_t *dst,u_int8_t *src,
    3. u_int16_t type,
    4. u_int8_t *payload,
    5. u_int32_t payload_s,
    6. libnet_t *l,libnet_ptag_t ptag)
    7. 功能:
    8. 构造一个以太网数据包
    9.  
    10. 参数:
    11. dst:目的mac
    12. src:源mac
    13. type:上层协议类型
    14. payload:负载,即附带的数据
    15. payload_s:负载长度
    16. l:libnet句柄
    17. ptag:协议标记
    18.  
    19. 返回值:
    20. 成功返回协议标记;失败返回-1

    6、发送数据到网络

    1. int libnet_write(libnet_t * l)
    2. 功能:
    3. 发送数据到网络
    4. 参数:
    5.   l:libnet句柄
    6. 返回值:
    7. 失败返回-1,成功返回其他

    综合案例:发送udp数据

    1. #include<stdio.h>
    2. #include <libnet.h>
    3. #include<string.h>
    4. #include <sys/socket.h>
    5. #include <netinet/in.h>
    6. #include <arpa/inet.h>
    7. int main()
    8. {
    9. //1、初始化内存
    10. libnet_t *lib_handle = libnet_init(LIBNET_LINK_ADV,"eth0",NULL);
    11. char data[128]="";
    12. printf("请输入要发送的udp数据:");
    13. fgets(data,sizeof(data),stdin);
    14. data[strlen(data)-1]=0;
    15. int data_len = strlen(data)+strlen(data)%2;//长度为偶数
    16. //构建数据包:从应用层--->链路层
    17. //1、构建udp数据
    18. libnet_ptag_t ptag_udp = libnet_build_udp(8000,9000,8+data_len,\
    19. 0,data,data_len, lib_handle, 0);
    20. //2、构建IP报文
    21. libnet_ptag_t ptag_ip = libnet_build_ipv4(20+8+data_len,0,0,0,128,\
    22. 17,0,inet_addr("192.168.0.111"),inet_addr("192.168.0.110"),\
    23. NULL,0, lib_handle, 0);
    24. //3、构建mac数据报文
    25. unsigned char src_mac[6]={0x00,0x0c,0x29,0x79,0xf9,0x7f};
    26. unsigned char dst_mac[6]={0x70,0x5A,0x0F,0x63,0xF5,0x9D};
    27. libnet_ptag_t ptag_mac = libnet_build_ethernet(dst_mac, src_mac, 0x0800,\
    28. NULL,0, lib_handle, 0);
    29. //4、发送帧数据
    30. libnet_write(lib_handle);
    31. //循环的发送5
    32. int i=0;
    33. for(i=0;i<5;i++)
    34. {
    35. printf("请输入要发送的udp数据:");
    36. fgets(data,sizeof(data),stdin);
    37. data[strlen(data)-1]=0;
    38. data_len = strlen(data)+strlen(data)%2;//长度为偶数
    39. //重新构建udp报文
    40. ptag_udp = libnet_build_udp(8000,9000,8+data_len,\
    41. 0,data,data_len, lib_handle, ptag_udp);
    42. //重新构建IP报文
    43. ptag_ip = libnet_build_ipv4(20+8+data_len,0,0,0,128,\
    44. 17,0,inet_addr("192.168.0.111"),inet_addr("192.168.0.110"),\
    45. NULL,0, lib_handle, ptag_ip);
    46. //发送帧数据
    47. libnet_write(lib_handle);
    48. }
    49. //释放资源
    50. libnet_destroy(lib_handle);
    51. return 0;
    52. }

    知识点4【BS开发概述】浏览器和服务器开发

    HTML:超文本标记语言 静态的 显示网页

    CSS:层叠样式表 渲染网页

    XML:指可扩展标记语言 传输网页

    Javascript:脚本语言 和 网页交互 (局部刷新网页)

    AJAX:基于Javascript语言的技术 (将网页 和 服务器 交互)

    CGI:通用网关接口(服务器 借助 CGI 控制 外设(数据库、传感器设备、文件))

    2、B/S架构就是浏览器和服务器架构

    Browser/Server(浏览器/服务器结构),是随着Internet技术的兴起,是对C/S结构的一种变化或者改进的结构。

    用户界面完全通过www浏览器实现,一部分事物逻辑在前端实现,但是主要事务逻辑在服务器端实现。

    B/S架构 与 C/S架构对比

    角度

    C/S

    B/S

    硬件环境

    专用网络

    广域网

    安全要求

    面向相对固定的用户群

    信息安全的控制能力很强

    面向是不可知的用户群

    对安全的控制能力相对弱

    程序架构

    更加注重流程

    系统运行速度可较少考虑

    对安全以及访问速度要多重的考虑

    B/S结构的程序架构是发展的趋势

    软件重用

    系统维护

    升级难

    开销小、方便升级

    处理问题

    集中

    分散

    用户接口

    与操作系统关系密切

    跨平台,与浏览器相关

    信息流

    交互性低

    交互密集

    知识点5【ubuntu下的boa服务器搭建】

    boa-0.94.13-src.tar.gz

    1、将boa-0.94.13-src.tar.gz拷贝到ubuntu中 并解压到当前目录

    在ubuntu中解压:tar -xvf boa-0.94.13-src.tar.gz

    解压成功会生成:boa-0.94.13-src文件夹

    cd boa-0.94.13-src

     ls查看当前文件夹的内容 如下:

    进入src目录

    cd src

     ls查看目录内容:

     2、将来的boa服务器的目录结构分析

    创建boa目录:

    mkdir ~/share/boa/boa -p

    创建log目录

    mkdir ~/share/boa/log

    创建www以及cgi-bin目录

    mkdir ~/share/boa/www/cgi-bin -p

    3、将boa.conf服务器的配置文件以及mime.types 拷贝 到/home/edu/share/boa/boa目录中

    boa.conf在boa-0.94.13-src目录下:

    将boa.conf拷贝到/home/edu/share/boa/boa下

    cp boa.conf /home/edu/share/boa/boa

    将/etc/mime.types拷贝/home/edu/share/boa/boa下

    sudo cp /etc/mime.types /home/edu/share/boa/boa/

    4、配置boa服务器在启动的时候 去/home/edu/share/boa/boa下查找配置文件boa.conf

    注意上述路径配置在boa-0.94.13-src/src/defines.h中

    编辑defines.h文件 

    5、编译boa服务器的源码

    1、./configure 生成Makefile

    2、make编译源码

    make

    如果第一次make出现:make: bison:命令未找到。

    解决方法:sudo apt-get install bison

    如果第二次make出现:make: flex:命令未找到。

    解决方法:sudo apt-get install flex

    第三次make:就成功 就会在当前目录下 看到服务器boa可执行文件

    3、将当前路径下服务器boa拷贝到 /home/edu/share/boa/boa下:

    cp boa /home/edu/share/boa/boa/

    6、在log目录下添加error_log access_log两个文件

    touch /home/edu/share/boa/log/error_log

    touch /home/edu/share/boa/log/access_log

    成功如下图

    7、在www目录下创建一个index.html网页

    通过samba打开路径

     编辑网页:代码如下

    1. <html>
    2. <head>
    3. <title>NZ2001</title>
    4. </head>
    5. <body>
    6. NZ2001 good good good!!!!
    7. </body>
    8. </html

    8、修改/home/edu/share/boa/boa/boa.conf

    cd /home/edu/share/boa/boa/

     

     用notepad++打开:

     1、在48、49行将nobody、nogroup改成0

     2、在62行将ErrorLog /root/arm-boa/log/error_log改成ErrorLog /home/edu/share/boa/log/error_log

     3、在74行将AccessLog /root/arm-boa/log/access_log改成AccessLog /home/edu/share/boa/log/access_log

     4、在111行将DocumentRoot /root/arm-boa/www改成DocumentRoot /home/edu/share/boa/www

     5、在123行将DirectoryIndex homepage.html改成DirectoryIndex index.html

    6、在155行将MimeTypes /etc/mime.types改成MimeTypes /home/edu/share/boa/boa/mime.types 

     7、在193行将ScriptAlias /cgi-bin/ /root/arm-boa/www/cgi-bin/改成ScriptAlias /cgi-bin/ /home/edu/share/boa/www/cgi-bin/

    9、启动boa服务器 

    cd /home/edu/share/boa/boa

    sudo ./boa

    ps -A | grep boa 说明boa运行成功

    10、测试服务器是否好使

    打开windows打开浏览器输入ubuntu的ip

     

     

     

     

     

     

     

  • 相关阅读:
    【Java面试】Zookeeper中的Watch机制的原理?
    华为云API对话机器人CBS的魅力—实现简单的对话操作
    18.2 使用NPCAP库抓取数据包
    API接口对接电商平台,接入亚马逊国际站按关键字搜索商品API源数据采集示例
    归一化---学习笔记
    CMake 官方文档入门
    JavaScript之JS事件机制
    数据挖掘可视化+机器学习初探
    分析智能平台VMware Greenplum 7 正式发布!
    Vue——动态组件、缓存组件keep-alive、异步组件
  • 原文地址:https://blog.csdn.net/buhuidage/article/details/127956018