ntopng、nprobe和ndpi基础

ntopng、nprobe和ndpi环境搭建及基础运用

一、环境搭建

1.1 ndpi安装

从github下载ndpi源码,编译顺序为:
apt-get install libpcap-dev
./autogen.sh
./configure
make install

或者直接

apt-get install ndpi

1.2 ntopng、nprobe安装

apt-get install software-properties-common wget
add-apt-repository universe
wget https://packages.ntop.org/apt/20.04/all/apt-ntop.deb

apt install ./apt-ntop.deb

apt update
apt install ntopng nprobe

注意此处的虚拟机环境为ubuntu20.4TLS ,如果为其他版本,请访问参考网站找其对应命令。

参考网站:https://packages.ntop.org/apt/

二、配置测试

2.1 nprobe简介

ntopng可用于可视化nProbe生成或收集的交通数据。在几种情况下,将ntopng与nProbe一起使用很方便,包括:
通常由路由器,交换机和网络设备产生的NetFlow / sFlow数据的可视化。在这种情况下,nProbe从设备收集并解析NetFlow / sFlow流量,并将结果流发送到ntopng以进行可视化。
监视连接到远程系统的物理网络接口。在这种情况下,ntopng无法直接监视网络接口,也无法看到其数据包。一个或多个nProbe可用于捕获远程网络接口流量并将结果流发送到中央ntopng,以进行分析和可视化。
下图总结了上面突出显示的两种情况,并说明了它们也可以组合在一起。

在这里插入图片描述

2.2 多个nProbe到一个ntopng

使用单个ntopng从多个nProbe收集流对于单个位置负责可视化和存档交通数据可能很有用。
在这里插入图片描述

要从多个nProbe收集流,ntopng必须以额外的开始 C(为收集器)在ZMQ端点的末尾,而每个nProbe都需要选择–zmq-probe-mode。在这种配置中,nProbes会启动与充当服务器的ntopng的连接,反之亦然。因此,您必须确保ntopng正在侦听ANY地址(即通配符)* 在ZMQ端点地址中)或在各种nProbe可以访问的另一个地址上。
以下是这种配置的示例

ntopng -i tcp://*:1234c 
nprobe --zmq "tcp://<ip address of ntopng>:1234" --zmq-probe-mode -i eth1 -n none -T "@NTOPNG@" 
nprobe --zmq "tcp://<ip address of ntopng>:1234" --zmq-probe-mode -i none -n none --collector-port 2055 -T "@NTOPNG@" 
nprobe --zmq "tcp://<ip address of ntopng>:1234" --zmq-probe-mode -i none -n none --collector-port 6343 -T "@NTOPNG@"

2.3 NAT

nProbe和ntopng的IP可达性不能总是被认为是理所当然的。有时,ntopng可能有必要从单独网络中的nProbe收集流,该网络可能位于NAT之后,甚至被防火墙屏蔽。同样,NAT后的ntopng可能有必要从另一个网络中的nProbe收集流。幸运的是,要处理这些情况,可以将ntopng(和nProbe)配置为可互换地充当JSON-Over-ZMQ通信的客户端或服务器。 这样就避免了在网络设备中插入冗长,耗时且可能不安全的规则,因为这足以确保客户端可以访问服务器,而NAT将自动处理通信中返回的服务器到客户端部分。
当nProbe和ntopng都在同一网络上,或者当ntopng在另一个网络中但可以到达nProbe时,应使用以下配置
在这里插入图片描述

ntopng -i tcp://<nProbe的IP地址>:1234 nprobe --zmq "tcp:// *:1234" -i eth1 -n none -T "@NTOPNG@"

上述是最简单nprobe和ntopng 的示例如:

ntopng -i tcp://127.0.0.1:1234 nprobe --zmq "tcp://*:1234" -i eth1 -n none -T "@ NTOPNG@"

当ntopng无法达到nProbe,但nProbe可以达到ntopng时,应使用的配置为:
在这里插入图片描述

ntopng -i tcp://*:1234c nprobe --zmq "tcp://<ip address of ntopng>:1234" --zmq-probe-mode -i eth1 -n none -T "@NTOPNG@"

请注意,更改ntopng和nProbe的客户端/服务器角色不会影响后续的流收集,因此两种配置可以互换使用。

2.4 在同一个设备上监视某个接口流量示例

配置ntopng:

sudo ntopng -i tcp://*:1234c

配置nprobe:

sudo nprobe --zmq "tcp://*:1234" -i ens33 -n none -T "@NTOPNG@"

配置完成后即可打开web界面:

在这里插入图片描述

打开Web GUI界面以后可以看见此时的接口变为tcp://*:1234c
在这里插入图片描述

2.5 大流量监控

在监控大型网络时,流量过大,不能直接使用 ntopng 进行收集原始数据流量,而是使用 pfring ZC 和nProbe 配合使用。

2.5.1 RRS 负载均衡

当流量较大时我们无法一次性完成流量的处理,这是需要的使用负载均衡的方法进行多线程的流量处理,最好的方法是使用 RSS,几乎所有英特尔(和其他供应商)NIC 都具有 RSS 支持,这意味着它们能够对硬件中的数据包进行哈希处理,以便将负载分配到多个 RX 队列中。

RSS 配置方法参考:https://www.ntop.org/guides/pf_ring/rss.html

2.5.2 nProbe 和 ntopng 配置

完成 RSS 配置后,使用 nProbe 在 ZC 的模式下处理流量。假设 nProbe 和 ntopng 在同一台设备上,

nProbe

配置示例如下:

#################################
#假设配置了两个 RSS 队列
-i=zc:ens33@0
-i=zc:ens33@1
-n=none
--zmq="tcp://*:5556"
--zmq-probe-mode=
-T="@NTOPNG@" 
##################################

ntopng 配置示例如下:

###################################
-i=tcp://127.0.0.1:5556
-m=192.168.0.0/24,192.168.1.0/24
#最大活动流
-X=1000000
最大活动主机
-x=200000
-F=nindex
-G=/var/run/ntopng.pid
###################################

ntopng与nprobe都既可采用**“命令 + 配置”的方式启动,也可以采用“命令+config文件”**的方式

三、交互数据格式

3.1 环境与配置

环境拓扑:ubuntu18.04 (probe) <------> ubuntu20.4(ntopng)

nprobe配置:

ntopng -i tcp://*:1234c -m -q -s --disable-login=1 -d /home/server/bin/ntop/bin/data -2 /usr/share/ntopng/scripts -1 /usr/share/ntopng/httpdocs --ndpi

ntopng配置:

nprobe -i ens33 -n none --zmq tcp://192.168.206.90:1234 --agent-mode --zmq-probe-mode --zmq-disable-compression --zmq-format j

3.2 zmq消息字段格式

字段1

..event..................8...=.........
{ "iface": { "name": "ens33", "speed": 1000, "ip": "192.168.206.108" }, 
  "probe": { "version": "10.5.231130", "osname": "Ubuntu 18.04.6 LTS", "license": "Time-limited license", "edition": "Pro",                  "maintenance": "-", "ip": "192.168.206.108", "public_ip": "" }, 
   "time" : 1701394961, "bytes": 3743, "packets": 27, 
   "avg": { "bps": 2199, "pps": 1 }, 
   "sampling": { "pkt_rate": 1, "collection_rate": 1, "flow_export_rate": 1 }, 
   "drops" : { "export_queue_too_long": 0, "too_many_flows": 0, "elk_flow_drops": 0, "sflow_pkt_sample_drops": 0,                              "flow_collection_drops": 0, "flow_collection_udp_socket_drops": 0 }, 
   "timeout": { "lifetime": 120, "idle": 60, "collected_lifetime": 0 },  
   "flow_collection": { "nf_ipfix_flows": 0, "sflow_samples": 0 },  
   "zmq": { "num_flow_exports": 0, "num_exporters": 1 } 
}

iface:probe探测的接口名、速率以及地址信息

probe:probe版本已经运行probe的系统版本等信息

time:抓包时间信息

avg: bps(比特率)是指网络传输速率,表示每秒传输的比特数。比特率可以用来衡量网络链路的带宽,即单位时间内传输的数据量。常见的比特率单位有bps(每秒比特)、Kbps(每秒千比特)、Mbps(每秒兆比特)和Gbps(每秒千兆比特)等。 pps(数据包速率)是指每秒传输的数据包数量。数据包速率可以用来衡量网络设备或应用程序处理数据包的能力。通常,较高的数据包速率表示设备或应用程序能够更快地处理网络流量。数据包速率通常以每秒数据包数(pps)为单位进行计量。

sampling:抽样率

timeout:字面意思

zmq:导出流的数量、出口数

字段2

..listening-ports....5...<...=........5
{"ip-addresses":["192.168.206.108"],
 "listening-ports":{
	"tcp4":[{"port":139,"proc":"\/usr\/sbin\/smbd","pkg":"samba"},
		{"port":53,"proc":"\/lib\/systemd\/systemd-resolved","pkg":"systemd"},
		{"port":445,"proc":"\/usr\/sbin\/smbd","pkg":"samba"},
		{"port":22,"proc":"\/usr\/sbin\/sshd","pkg":"openssh-server"}],
	"tcp6":[{"port":139,"proc":"\/usr\/sbin\/smbd","pkg":"samba"},
		{"port":445,"proc":"\/usr\/sbin\/smbd","pkg":"samba"},
		{"port":22,"proc":"\/usr\/sbin\/sshd","pkg":"openssh-server"}],
	"udp4":[{"port":138,"proc":"\/usr\/sbin\/nmbd","pkg":"samba"},
		{"port":68,"proc":"\/lib\/systemd\/systemd-networkd","pkg":"systemd"},
		{"port":137,"proc":"\/usr\/sbin\/nmbd","pkg":"samba"},
		{"port":53,"proc":"\/lib\/systemd\/systemd-resolved","pkg":"systemd"}],
	"udp6":[{"port":546,"proc":"\/lib\/systemd\/systemd-networkd","pkg":"systemd"}]
   }
}

链路层协议、监听端口号以及关联进程。

字段3:

..template...............=...=.........[{"PEN":0,"field":1,"len":4,"format":"formatted_uint","name":"IN_BYTES","descr":"Incoming flow bytes (src->dst)"},{"PEN":0,"field":2,"len":4,"format":"formatted_uint","name":"IN_PKTS","descr":"Incoming flow packets (src->dst)"},{"PEN":0,"field":4,"len":1,"format":"uint","name":"PROTOCOL","descr":"IP protocol byte"},{"PEN":0,"field":5,"len":1,"format":"uint","name":"SRC_TOS","descr":"TOS/DSCP (src->dst)"},{"PEN":0,"field":7,"len":2,"format":"uint","name":"L4_SRC_PORT","descr":"IPv4 source port"},{"PEN":0,"field":8,"len":4,"format":"ipv4_address","name":"IPV4_SRC_ADDR","descr":"IPv4 source address"},{"PEN":0,"field":10,"len":4,"format":"uint","name":"INPUT_SNMP","descr":"Input interface SNMP idx"},{"PEN":0,"field":11,"len":2,"format":"uint","name":"L4_DST_PORT","descr":"IPv4 destination port"},{"PEN":0,"field":12,"len":4,"format":"ipv4_address","name":"IPV4_DST_ADDR","descr":"IPv4 destination address"},{"PEN":0,"field":14,"len":4,"format":"uint","name":"OUTPUT_SNMP","descr":"Output interface SNMP idx"},{"PEN":0,"field":21,"len":4,"format":"epoch","name":"LAST_SWITCHED","descr":"SysUptime (msec) of the last flow pkt"},{"PEN":0,"field":22,"len":4,"format":"epoch","name":"FIRST_SWITCHED","descr":"SysUptime (msec) of the first flow pkt"},{"PEN":0,"field":23,"len":4,"format":"formatted_uint","name":"OUT_BYTES","descr":"Outgoing flow bytes (dst->src)"},{"PEN":0,"field":24,"len":4,"format":"formatted_uint","name":"OUT_PKTS","descr":"Outgoing flow packets (dst->src)"},{"PEN":0,"field":34,"len":4,"format":"uint","name":"SAMPLING_INTERVAL","descr":"Sampling rate"},{"PEN":0,"field":42,"len":4,"format":"formatted_uint","name":"TOTAL_FLOWS_EXP","descr":"Total number of exported flows"},{"PEN":0,"field":55,"len":1,"format":"uint","name":"DST_TOS","descr":"TOS/DSCP (dst->src)"},{"PEN":0,"field":58,"len":2,"format":"uint","name":"SRC_VLAN","descr":"Source VLAN (inner VLAN in QinQ)"},{"PEN":0,"field":56,"len":6,"format":"mac_address","name":"IN_SRC_MAC","descr":"Source MAC Address"},{"PEN":0,"field":57,"len":6,"format":"mac_address","name":"OUT_DST_MAC","descr":"Post Destination MAC Address"},{"PEN":0,"field":60,"len":1,"format":"uint","name":"IP_PROTOCOL_VERSION","descr":"[4=IPv4][6=IPv6]"},{"PEN":0,"field":61,"len":1,"format":"uint","name":"DIRECTION","descr":"Flow direction [0=RX, 1=TX]"},{"PEN":0,"field":57640,"len":4,"format":"uint","name":"SRC_PROC_PID","descr":"Flow source proc PID"},{"PEN":0,"field":57641,"len":16,"format":"ascii","name":"SRC_PROC_NAME","descr":"Flow source proc name"},{"PEN":0,"field":57897,"len":4,"format":"uint","name":"SRC_PROC_UID","descr":"Flow source proc userId"},{"PEN":0,"field":57844,"len":16,"format":"ascii","name":"SRC_PROC_USER_NAME","descr":"Flow source proc user name"},{"PEN":0,"field":58012,"len":16,"format":"ascii","name":"SRC_PROC_PKG_NAME","descr":"Flow source proc package name"},{"PEN":0,"field":58028,"len":32,"format":"ascii","name":"SRC_PROC_CMDLINE","descr":"Flow source proc cmdline args"},{"PEN":0,"field":58030,"len":16,"format":"ascii","name":"SRC_PROC_CONTAINER_ID","descr":"Flow source proc containerId"},{"PEN":0,"field":57846,"len":16,"format":"ascii","name":"SRC_FATHER_PROC_NAME","descr":"Flow src father proc name"},{"PEN":0,"field":58036,"len":4,"format":"uint","name":"SRC_FATHER_PROC_UID","descr":"Flow src father proc UID"},{"PEN":0,"field":58037,"len":16,"format":"ascii","name":"SRC_FATHER_PROC_USER_NAME","descr":"Flow src father proc UID name"},{"PEN":0,"field":58033,"len":16,"format":"ascii","name":"SRC_FATHER_PROC_PKG_NAME","descr":"Flow src father proc package name"},{"PEN":0,"field":57847,"len":4,"format":"uint","name":"DST_PROC_PID","descr":"Flow dest proc PID"},{"PEN":0,"field":57848,"len":16,"format":"ascii","name":"DST_PROC_NAME","descr":"Flow dest proc name"},{"PEN":0,"field":57898,"len":4,"format":"uint","name":"DST_PROC_UID","descr":"Flow dest proc userId"},{"PEN":0,"field":57849,"len":16,"format":"ascii","name":"DST_PROC_USER_NAME","descr":"Flow dest proc user name"},{"PEN":0,"field":58013,"len":16,"format":"ascii","name":"DST_PROC_PKG_NAME","descr":"Flow dest proc package name"},{"PEN":0,"field":58029,"len":32,"format":"ascii","name":"DST_PROC_CMDLINE","descr":"Flow dest proc cmdline args"},{"PEN":0,"field":58031,"len":16,"format":"ascii","name":"DST_PROC_CONTAINER_ID","descr":"Flow dest proc containerId"},{"PEN":0,"field":57851,"len":16,"format":"ascii","name":"DST_FATHER_PROC_NAME","descr":"Flow dest father proc name"},{"PEN":0,"field":58039,"len":4,"format":"uint","name":"DST_FATHER_PROC_UID","descr":"Flow dst father proc UID"},{"PEN":0,"field":58040,"len":16,"format":"ascii","name":"DST_FATHER_PROC_USER_NAME","descr":"Flow dst father proc UID name"},{"PEN":0,"field":58035,"len":16,"format":"ascii","name":"DST_FATHER_PROC_PKG_NAME","descr":"Flow dst father proc package name"},{"PEN":0,"field":130,"len":4,"format":"uint","name":"EXPORTER_IPV4_ADDRESS","descr":"Flow exporter IPv4 Address"},{"PEN":35632,"field":57552,"len":2,"format":"uint","name":"SRC_FRAGMENTS","descr":"Num fragmented packets src->dst"},{"PEN":35632,"field":57553,"len":2,"format":"uint","name":"DST_FRAGMENTS","descr":"Num fragmented packets dst->src"},{"PEN":35632,"field":57595,"len":4,"format":"uint","name":"CLIENT_NW_LATENCY_MS","descr":"Network TCP 3WH RTT/2 client <-> nprobe (msec)"},{"PEN":35632,"field":57596,"len":4,"format":"uint","name":"SERVER_NW_LATENCY_MS","descr":"Network TCP 3WH RTT/2 nprobe <-> server (msec)"},{"PEN":35632,"field":57550,"len":1,"format":"uint","name":"CLIENT_TCP_FLAGS","descr":"Cumulative of all client TCP flags"},{"PEN":35632,"field":57551,"len":1,"format":"uint","name":"SERVER_TCP_FLAGS","descr":"Cumulative of all server TCP flags"},{"PEN":35632,"field":57597,"len":4,"format":"uint","name":"APPL_LATENCY_MS","descr":"Application latency (msec), a.k.a. server response time"},{"PEN":35632,"field":57943,"len":4,"format":"ipv4_address","name":"NPROBE_IPV4_ADDRESS","descr":"IPv4 address of the host were nProbe runs"},{"PEN":35632,"field":57581,"len":4,"format":"uint","name":"RETRANSMITTED_IN_PKTS","descr":"Number of retransmitted TCP flow packets (src->dst)"},{"PEN":35632,"field":57582,"len":4,"format":"uint","name":"RETRANSMITTED_OUT_PKTS","descr":"Number of retransmitted TCP flow packets (dst->src)"},{"PEN":35632,"field":57583,"len":4,"format":"uint","name":"OOORDER_IN_PKTS","descr":"Number of out of order TCP flow packets (dst->src)"},{"PEN":35632,"field":57584,"len":4,"format":"uint","name":"OOORDER_OUT_PKTS","descr":"Number of out of order TCP flow packets (src->dst)"},{"PEN":35632,"field":57590,"len":2,"format":"uint","name":"L7_PROTO","descr":"Layer 7 Protocol (numeric)"},{"PEN":35632,"field":58032,"len":1,"format":"uint","name":"L7_CONFIDENCE","descr":"nDPI confidence"},{"PEN":35632,"field":58011,"len":24,"format":"ascii","name":"L7_INFO","descr":"Layer 7 Flow Information"},{"PEN":35632,"field":57660,"len":48,"format":"ascii","name":"TLS_SERVER_NAME","descr":"TLS server name"},{"PEN":35632,"field":57661,"len":40,"format":"ascii","name":"BITTORRENT_HASH","descr":"BITTORRENT hash"},{"PEN":35632,"field":57594,"len":32,"format":"ascii","name":"NPROBE_INSTANCE_NAME","descr":"nprobe instance name"},{"PEN":35632,"field":57888,"len":2,"format":"uint","name":"TCP_WIN_MAX_IN","descr":"Max TCP Window (src->dst)"},{"PEN":35632,"field":57892,"len":2,"format":"uint","name":"TCP_WIN_MAX_OUT","descr":"Max TCP Window (dst->src)"},{"PEN":35632,"field":57981,"len":8,"format":"uint","name":"L7_PROTO_RISK","descr":"Layer 7 protocol risk (bitmap)"},{"PEN":35632,"field":57999,"len":2,"format":"uint","name":"L7_RISK_SCORE","descr":"Layer 7 flow Risk Score"},{"PEN":35632,"field":57994,"len":2,"format":"uint","name":"FLOW_VERDICT","descr":"Flow verdict marker (0 = unknown, 1=pass, 2=drop...)"},{"PEN":35632,"field":58027,"len":48,"format":"ascii","name":"L7_RISK_INFO","descr":"L7 Risk Information"}]

共74个字段,定义流的模板格式。此处指定了各个字段所代表的含义以及名称长度编码格式等。

字段4:

..flow...................C...=.........[{"56":"00:0C:29:F4:02:34","57":"1C:69:7A:54:DD:E0","10":0,"14":0,"58":0,"8":"192.168.206.108","12":"192.168.206.164","7":22,"11":64668,"27":"::","28":"::","60":4,"4":6,"35632.118":"92","35632.560":1,"1":1400,"2":6,"23":208,"24":4,"22":1701394902,"21":1701394903,"35632.78":24,"35632.79":16,"35632.509":0,"35632.527":0,"130":"0.0.0.0","61":1,"34":1,"42":1,"35632.471":"192.168.206.108","35632.122":"","35632.123":0.708,"35632.124":0.348,"35632.125":0.000,"35632.416":501,"35632.420":8235,"35632.111":0,"35632.112":0,"35632.109":0,"35632.110":0,"35632.80":0,"35632.81":0,"35632.539":"","35632.205":"","35632.207":0,"35632.208":0,"35632.180":"","35632.361":"","35632.360":"","35632.181":0,"35632.188":"","35632.189":"","5":16,"55":0,"35632.183":"","35632.555":"","57641":"","57640":0,"58028":"","58030":"","57848":"","57847":0,"58029":"","58031":"","35632.522":0,"57897":0,"57844":"","58012":"","57846":"","58036":0,"58037":"","58033":"","57898":0,"57849":"","58013":"","57851":"","58039":0,"58040":"","58035":""}]

按照template字段指定的格式罗列的流详细信息。

flow 字段包含了实际的流量数据,包括源和目的地址、端口、协议、流量统计信息等等。这些信息描述了单个流量记录的各个方面。

template 字段描述了数据的模板,其中包含了每个字段的名称、类型、长度和格式。模板定义了如何解析和解释流量数据中的各个字段。 这两个字段之间的关联是, template 字段定义了如何解析 flow 字段中的数据。通过使用模板,ntopng能够正确地解析和显示来自nProbe的流量数据。 因此, template 字段是用于解释和解析 flow 字段中的数据的重要组成部分。它确保ntopng能够正确理解和显示来自nProbe的数据。

由于nprobe并不提供免费版本,因此如果需要完成2.3中的拓扑方式,就需要我们在设备内依据probe的消息格式封装消息并发送到对应的Collector并提供相应支持。

3.3 nprobe替代需求

由于nprobe并不免费,假如我们需要在系统中运用这种探测–显示的模式,就需要在协议栈上加以修改,一般来说主要包含下面几个方面(部分,待补充)

1.支持配置zmq 采集者配置
2.支持与ntopng的消息交互,并根据接收到的报文完成3.2中消息的组装
3.支持zmq。传统socket是无法满足如此大的流量要求的。
4.其余暂未想到

四、ntopng源码编译

源码下载:

git clone https://github.com/ntop/ntopng.git

编译详情参考 ntopng-dev/doc/README.compilation,因为版本更新较快,这里不再列出具体编译命令,以README中为准。

依赖库安装完成后

cd <compilation directory>
git clone https://github.com/ntop/nDPI.git
cd nDPI; ./autogen.sh; ./configure; make; cd ..
git clone https://github.com/ntop/ntopng.git
cd ntopng
./autogen.sh
./configure
make

这里需要注意,从git下载下来的nDPI可能它的目录名称会是nDPI-dev,这里需要手动进行修改,否则可能在ntopng的./configure会提示找不到nDPI的错误。原因是ntopng编译过程中需要引用nDPI的头文件,因此这里的名称和位置不符合就会导致找不到文件,编译失败退出。

启动命令:

./ ntopng -i ens33 -m -q -s --disable-login=1 -2 /usr/share/ntopng/scripts -1 /usr/share/ntopng/httpdocs

这里和apt安装的不同在于启动时必须去指定script和httpdocs目录,否则web的显示会有问题。
在这里插入图片描述
在这里插入图片描述
不再枚举其它web页面,感兴趣可以去搭建一个看看。

makefile中make install标签的行为如下:

install: ntopng
	@echo "While we provide you an install make target, we encourage you"
	@echo "to create a package and install that"
	@echo "rpm - do 'make build-rpm'"
	@echo "deb - do 'cd packages/ubuntu;./configure;make"
	mkdir -p $(INSTALL_DIR)/share/ntopng $(MAN_DIR)/man8 $(INSTALL_DIR)/bin
	cp ntopng $(INSTALL_DIR)/bin
	cp ./ntopng.8 $(MAN_DIR)/man8
	cp -r ./httpdocs $(INSTALL_DIR)/share/ntopng
	cp -LR ./scripts $(INSTALL_DIR)/share/ntopng # L dereference symlinks
	find $(INSTALL_DIR)/share/ntopng -name "*~"   | xargs /bin/rm -f
	find $(INSTALL_DIR)/share/ntopng -name ".git" | xargs /bin/rm -rf

- install: :这是一个目标标签,用于指定安装操作。

  • @echo :这是一个命令,用于在终端输出一条消息。

  • mkdir -p $(INSTALL_DIR)/share/ntopng $(MAN_DIR)/man8 $(INSTALL_DIR)/bin :这个命令用于创建目录, $(INSTALL_DIR)/share/ntopng$(MAN_DIR)/man8$(INSTALL_DIR)/bin 是变量,表示安装目录中的不同子目录。

  • cp ntopng $(INSTALL_DIR)/bin :这个命令将 ntopng 文件复制到安装目录的 bin 子目录中。

  • cp ./ntopng.8 $(MAN_DIR)/man8 :这个命令将 ntopng.8 文件复制到安装目录的 man8 子目录中。

  • cp -r ./httpdocs$(INSTALL_DIR)/share/ntopng:这个命令将httpdocs目录及其内容递归地复制到安装目录的 share/ntopng子目录中。

  • cp -LR ./scripts $(INSTALL_DIR)/share/ntopng :这个命令将 scripts 目录及其内容递归地复制到安装目录的 share/ntopng 子目录中。 -L 选项用于解除符号链接。

  • find $(INSTALL_DIR)/share/ntopng -name “*~” | xargs /bin/rm -f:这个命令用于删除安装目录中以~ 结尾的临时文件。

  • find $(INSTALL_DIR)/share/ntopng -name “.git” | xargs /bin/rm -rf:这个命令用于删除安装目录中的.git` 目录,即Git版本控制的相关文件。

    通过执行Makefile中的 install 标签,可以将ntopng软件及其相关文件复制到指定的安装目录中。

例如这里需要将它移植到某个系统中,做交叉编译的时候就需要考虑到例如script、httpdocs等页面相关文件的操作,否则可能会出现问题。

五、参考链接

https://blog.csdn.net/HongkeTraining/article/details/121562157

全网仅此一篇!万字详解ZeroMQ的zmq_msg_t消息处理、多部分消息、及消息接口-CSDN博客

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值