中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

一個(gè)公司設(shè)計(jì)網(wǎng)站怎么做/京東seo搜索優(yōu)化

一個(gè)公司設(shè)計(jì)網(wǎng)站怎么做,京東seo搜索優(yōu)化,網(wǎng)站開發(fā)培訓(xùn)哪里好,貴陽網(wǎng)站建設(shè) 設(shè)計(jì)可以嗎文章目錄 1 audit簡介2 auditctl的使用2 audit配置和規(guī)則3 工作原理4 audit接口調(diào)用4.1 獲取和修改配置4.2 獲取和修改規(guī)則4.3 獲取審計(jì)日志 5 audit存在的問題5.1 內(nèi)核版本5.2 審計(jì)日志過多造成的緩存隊(duì)列和磁盤問題5.2 容器環(huán)境下同一個(gè)命令的日志存在差異 6 參考文檔 1 audi…

文章目錄

      • 1 audit簡介
      • 2 auditctl的使用
      • 2 audit配置和規(guī)則
      • 3 工作原理
      • 4 audit接口調(diào)用
        • 4.1 獲取和修改配置
        • 4.2 獲取和修改規(guī)則
        • 4.3 獲取審計(jì)日志
      • 5 audit存在的問題
        • 5.1 內(nèi)核版本
        • 5.2 審計(jì)日志過多造成的緩存隊(duì)列和磁盤問題
        • 5.2 容器環(huán)境下同一個(gè)命令的日志存在差異
      • 6 參考文檔

1 audit簡介

audit是Linux內(nèi)核提供的一種審計(jì)機(jī)制,由于audit是內(nèi)核提供的,因此,在使用audit的過程中就包含內(nèi)核空間和用戶空間部分:

  • rules:審計(jì)規(guī)則,其中配置了審計(jì)系統(tǒng)需要審計(jì)的操作
  • auditctl:用戶態(tài)程序,用于審計(jì)規(guī)則配置和配置變更
  • kaudit:內(nèi)核空間程序,根據(jù)配置好的審計(jì)規(guī)則記錄發(fā)生的事件
  • auditd:用戶態(tài)程序,通過netlink獲取審計(jì)日志

通常的使用流程:

  • 用戶通過auditctl配置審計(jì)規(guī)則
  • 內(nèi)核的kauditd程序獲取到審計(jì)規(guī)則后,記錄對應(yīng)的審計(jì)日志
  • 用戶態(tài)的auditd獲取審計(jì)日志并寫入日志文件。

audit的主要應(yīng)用場景是安全審計(jì),通過對日志進(jìn)行分析發(fā)現(xiàn)異常行為。

2 auditctl的使用

auditctl是用戶態(tài)的控制程序,可以修改audit配置以及審計(jì)規(guī)則的操作。

auditctl的選項(xiàng)可以分成兩類。

配置類:

  • -b:配置buffer的大小
  • -e:設(shè)置enabled標(biāo)記
  • -f:設(shè)置failure標(biāo)記
  • -s:返回整體的狀態(tài)
  • –backlog_wait_time:設(shè)置backlog_wait_time

審計(jì)規(guī)則類:

  • -a & -A l,a:往某個(gè)規(guī)則表中增加需要記錄的行為
  • -d:從某個(gè)規(guī)則表中刪除規(guī)則
  • -D:刪除所有規(guī)則
  • -F f=v:設(shè)置更多監(jiān)控條件
  • -l:查看規(guī)則
  • -p:在文件監(jiān)控上設(shè)置權(quán)限過濾
  • -i:當(dāng)從文件中讀取規(guī)則時(shí)忽略錯(cuò)誤
  • -c:出錯(cuò)時(shí)繼續(xù)
  • -r:設(shè)置rate_limit,每秒多少條消息
  • -R:從文件中讀取規(guī)則
  • -S:設(shè)置要監(jiān)控的系統(tǒng)調(diào)用名或者系統(tǒng)調(diào)用號
  • -w:增加監(jiān)控點(diǎn)
  • -W:刪除監(jiān)控點(diǎn)

例如,假如我們想要獲取調(diào)用execve系統(tǒng)調(diào)用的事件,可以增加下列的規(guī)則:

auditctl -a always,exit -S execve -F key=123456

然后就可以通過ausearch查找該日志:

ausearch -k 123456

如果想要獲取執(zhí)行tail命令的事件,可以增加規(guī)則:

auditctl -w /usr/bin/tail -p x -k 123456

然后使用tail命令查看通過ausearch命令查看日志:

time->Sun Apr 23 15:47:36 2023
type=PROCTITLE msg=audit(1682236056.128:4318964): proctitle=7461696C002D6E0032006C756F2E7368
type=PATH msg=audit(1682236056.128:4318964): item=1 name="/lib64/ld-linux-x86-64.so.2" inode=36969 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:ld_so_t:s0 objtype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PATH msg=audit(1682236056.128:4318964): item=0 name="/usr/bin/tail" inode=100666597 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:bin_t:s0 objtype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=CWD msg=audit(1682236056.128:4318964):  cwd="/root"
type=EXECVE msg=audit(1682236056.128:4318964): argc=4 a0="tail" a1="-n" a2="2" a3="luo.sh"
type=SYSCALL msg=audit(1682236056.128:4318964): arch=c000003e syscall=59 success=yes exit=0 a0=20749e0 a1=218ecd0 a2=2179ee0 a3=7fffa4a99460 items=2 ppid=58219 pid=59519 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=956 comm="tail" exe="/usr/bin/tail" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="123456"

可以看到,開頭一行是事件發(fā)生的事件,后面的若干行是執(zhí)行tail命令產(chǎn)生的事件日志,有些日志很簡單,例如CWD,表示操作的當(dāng)前路徑,而有些日志很復(fù)雜,例如SYSCALL,有接近30個(gè)字段。每行日志都有type字段和msg字段(冒號前面是時(shí)間戳,可以通過date命令轉(zhuǎn)換,冒號后面是事件ID,同一條規(guī)則產(chǎn)生的事件的事件ID是一樣的,因此,如果不使用ausearch查找某條規(guī)則產(chǎn)生的日志,就需要先用key進(jìn)行查找,找到對應(yīng)的事件ID,然后再通過事件ID查找產(chǎn)生的所有日志)。

這里的tail命令的監(jiān)控,我們只關(guān)注上面的2個(gè)事件:

  • EXECVE:這里給出了調(diào)用的參數(shù),argc和argv
  • SYSCALL:arch(架構(gòu)),syscall(系統(tǒng)調(diào)用號,可以通過ausyscall --dump查看),success(調(diào)用是否成功),exit(返回碼),a0~a3為系統(tǒng)調(diào)用前4個(gè)參數(shù),ppid(父進(jìn)程ID),pid(進(jìn)程ID),comm(執(zhí)行的命令),exe(執(zhí)行execve的可執(zhí)行文件)

2 audit配置和規(guī)則

通過auditctl -s命令可以看到當(dāng)前audit的一些屬性和配置:

  • enabled:表明audit是否會記錄事件,可以通過auditctl -e設(shè)置
  • failure:表明audit是否會記錄失敗事件,設(shè)置為1,才會記錄失敗事件
  • pid:占用audit的進(jìn)程的pid
  • rate_limit:內(nèi)核每秒發(fā)送的最大消息數(shù),如果是0,表示不限制
  • backlog_limit:緩存隊(duì)列長度限制
  • lost:由于緩存隊(duì)列超過限制而導(dǎo)致的丟失的記錄數(shù)
  • backlog:當(dāng)前緩存隊(duì)列中等待讀取的記錄數(shù)
  • backlog_wait_time:緩存隊(duì)列滿時(shí)的等待時(shí)間

其中backlog_wait_time是后面的版本提供的。

3 工作原理

除了上述的使用外,audit還有一個(gè)特點(diǎn):獨(dú)占性。實(shí)際的審計(jì)操作是由內(nèi)核中的kauditd完成的,auditd再通過netlink讀取審計(jì)日志。而kauditd是只允許與一個(gè)用戶態(tài)進(jìn)程連接,因此,如果系統(tǒng)上已經(jīng)有auditd進(jìn)程與kauditd建立連接,后續(xù)其他進(jìn)程進(jìn)行了搶占,auditd則會斷開。那么,如果判斷當(dāng)前是哪個(gè)進(jìn)程與kautid建立了連接呢?可以通過auditctl -s中的pid進(jìn)行判斷。

另一個(gè)重要的地方是kaudit如何去應(yīng)用配置的規(guī)則。在auditctl的-a <l,a>選項(xiàng)中,給出的選項(xiàng)含義是:將規(guī)則和對應(yīng)的action加入到list后面。list有4種:task、exit、user、exclude,action有2種:never、always。

task、exit、user分別表示審計(jì)事件的三種類型:user事件是指與用戶相關(guān)的事件,例如用戶登錄、注銷、切換等。task是指與進(jìn)程相關(guān)的事件,例如進(jìn)程創(chuàng)建、退出、切換等。exit是指與系統(tǒng)調(diào)用相關(guān)的事件。exclude只是一個(gè)關(guān)鍵字,用于排除不需要審計(jì)的文件或者目錄。因此,這里面的事件類型與其他的某些選項(xiàng)有強(qiáng)相關(guān):

  • -a用于增加規(guī)則,-w用于監(jiān)視文件,兩者不能同時(shí)使用,說明在實(shí)現(xiàn)上,分別維護(hù)了以事件類型進(jìn)行分類的4個(gè)列表,同時(shí)還維護(hù)了需要監(jiān)視的文件列表
  • -S指定系統(tǒng)調(diào)用號,因此,只能用于-a exit

配置和規(guī)則的變更:

當(dāng)通過auditctl操作配置或者規(guī)則時(shí),會通過netlink將規(guī)則發(fā)送到內(nèi)核,內(nèi)核接收到到配置后會對內(nèi)部的配置或者規(guī)則進(jìn)行更新
對于規(guī)則來說,內(nèi)核(4.19.281)內(nèi)部會維護(hù)7個(gè)鏈表:

  • AUDIT_FILTER_USER:用戶生成的日志
  • AUDIT_FILTER_TASK:進(jìn)程創(chuàng)建
  • AUDIT_FILTER_ENTRY:系統(tǒng)調(diào)用入口
  • AUDIT_FILTER_WATCH:文件系統(tǒng)監(jiān)控
  • AUDIT_FILTER_EXIT:系統(tǒng)調(diào)用退出
  • AUDIT_FILTER_EXCLUDE:審計(jì)日志排除
  • AUDIT_FILTER_FS

請?zhí)砑訄D片描述

4 audit接口調(diào)用

auditctl使用netlink與內(nèi)核進(jìn)行交互,因此,要想實(shí)現(xiàn)audit的一些能力,就需要采用netlink實(shí)現(xiàn)一套交互接口,幸運(yùn)的是,已經(jīng)有庫可以完成這項(xiàng)工作:yum install -y audit-libs-devel,然后編譯時(shí)帶上-laudit。

安裝完成后,可以查看頭文件/usr/include/libaudit.h看下提供的方法。

4.1 獲取和修改配置
#include <iostream>
#include <libaudit.h>using namespace std;int main() {int fd = audit_open();audit_request_status(fd);struct audit_reply reply;audit_get_reply(fd, &reply, GET_REPLY_BLOCKING, 0);struct audit_status *status;status = reply.status;cout <<"auditctl -s return:" <<endl;cout << "enabled=" << status->enabled << endl;cout << "failure=" << status->failure << endl;cout << "pid=" << status->pid << endl;cout << "rate_limit=" << status->rate_limit << endl;cout << "backlog_limit=" << status->backlog_limit << endl;cout << "lost=" << status->lost << endl;cout << "backlog=" << status->backlog << endl;return 0;
}

先試用audit_request_status()向內(nèi)核發(fā)送請求,表明要獲取配置信息,然后再通過audit_get_reply()接收數(shù)據(jù),數(shù)據(jù)放在struct audit_reply的結(jié)構(gòu)體:

// /usr/src/libaudit.h
struct audit_reply {int                      type;int                      len;struct nlmsghdr         *nlh;struct audit_message     msg;/* Using a union to compress this structure since only one of* the following should be valid for any packet. */union {struct audit_status     *status;struct audit_rule_data  *ruledata;struct audit_login      *login;char                    *message;struct nlmsgerr         *error;struct audit_sig_info   *signal_info;struct daemon_conf      *conf;
#ifdef AUDIT_FEATURE_BITMAP_ALLstruct audit_features   *features;
#endif};
};

如果是獲取配置信息,此時(shí)數(shù)據(jù)放在status中:

// include/uapi/linux/audit.h
struct audit_status {__u32           mask;           /* Bit mask for valid entries */__u32           enabled;        /* 1 = enabled, 0 = disabled */__u32           failure;        /* Failure-to-log action */__u32           pid;            /* pid of auditd process */__u32           rate_limit;     /* messages rate limit (per second) */__u32           backlog_limit;  /* waiting messages limit */__u32           lost;           /* messages lost */__u32           backlog;        /* messages waiting in queue */union {__u32   version;        /* deprecated: audit api version num */__u32   feature_bitmap; /* bitmap of kernel audit features */};
};

因此,只要讀取返回的audit_reply中的status中的上述字段即可。需要注意的是,如果audit_get_reply()中的第3個(gè)參數(shù)設(shè)置為GET_REPLY_NONBLOCKING,可能拿不到數(shù)據(jù),因?yàn)閒d可能還沒有可讀的數(shù)據(jù),所以,這里要么設(shè)置為GET_REPLY_BLOCKING,要么使用select:

#include <iostream>
#include <libaudit.h>using namespace std;int main() {struct timeval t = {.tv_sec = 0, .tv_usec = 500000};int fd = audit_open();audit_request_status(fd);fd_set read_mask;FD_ZERO(&read_mask);FD_SET(fd, &read_mask);select(fd+1, &read_mask, NULL, NULL, &t);struct audit_reply reply;audit_get_reply(fd, &reply, GET_REPLY_NONBLOCKING, 0);struct audit_status *status;status = reply.status;cout <<"auditctl -s return:" <<endl;cout << "enabled=" << status->enabled << endl;cout << "failure=" << status->failure << endl;cout << "pid=" << status->pid << endl;cout << "rate_limit=" << status->rate_limit << endl;cout << "backlog_limit=" << status->backlog_limit << endl;cout << "lost=" << status->lost << endl;cout << "backlog=" << status->backlog << endl;return 0;
}

對于修改配置的操作,libaudit直接提供了對應(yīng)的api函數(shù),例如,設(shè)置backlog_limit,可以直接調(diào)用audit_set_backlog_limit()。

4.2 獲取和修改規(guī)則
#include <iostream>
#include <libaudit.h>using namespace std;int main() {struct timeval t = {.tv_sec = 0, .tv_usec = 500000};int fd = audit_open();do {audit_request_rules_list_data(fd);fd_set read_mask;FD_ZERO(&read_mask);FD_SET(fd, &read_mask);select(fd+1, &read_mask, NULL, NULL, &t);struct audit_reply reply;audit_get_reply(fd, &reply, GET_REPLY_NONBLOCKING, 0);if(reply.type == NLMSG_DONE) {break;}struct audit_rule_data *rules;rules = reply.ruledata;cout <<"auditctl -l return:" <<endl;cout << audit_flag_to_name(rules->flags) << endl;cout << audit_action_to_name(rules->action) << endl;} while(true);return 0;
}

獲取規(guī)則跟獲取配置的區(qū)別只是發(fā)起操作的函數(shù)和數(shù)據(jù)解析不同,獲取規(guī)則使用audit_request_rules_list_data()發(fā)起操作,解析數(shù)據(jù)時(shí)則需要解析struct audit_rule_data的數(shù)組。

#include <iostream>
#include <libaudit.h>
#include <linux/audit.h>using namespace std;int main() {int fd = audit_open();struct audit_rule_data *rule = new(struct audit_rule_data);audit_rule_syscall_data(rule, 57);audit_add_rule_data(fd, rule, AUDIT_FILTER_EXIT, AUDIT_NEVER);return 0;
}

上面的代碼相當(dāng)于auditctl -a exit,never -S execve

#include <iostream>
#include <libaudit.h>
#include <linux/audit.h>using namespace std;int main() {int fd = audit_open();struct audit_rule_data *rule = new(struct audit_rule_data);audit_add_watch(&rule, "/etc/passwd");audit_add_rule_data(fd, rule, AUDIT_FILTER_EXIT, AUDIT_ALWAYS);return 0;
}

上面的代碼相當(dāng)于auditctl -w /etc/passwd -p rwxa。

4.3 獲取審計(jì)日志

獲取升級日志還是使用netlink的方式讀取:

#include <iostream>
#include <libaudit.h>
#include <string.h>
#include <unistd.h>using namespace std;int main() {int audit_fd = audit_open();if (audit_fd < 0) {cout << "open audit fail:" << strerror(errno) << endl;return -1;}audit_set_enabled(audit_fd, 1);struct audit_reply audit_rep;int ret;struct timeval t = {.tv_sec = 5, .tv_usec = 0};pid_t cur_pid = getpid();ret = audit_set_pid(audit_fd, static_cast<uint32_t>(cur_pid),WAIT_NO);if (ret <= 0) {cout << "audit_set_pid fail:" << strerror(errno) << endl;return -1;}do {fd_set read_mask;FD_ZERO(&read_mask);FD_SET(audit_fd, &read_mask);ret = select(audit_fd + 1, &read_mask, nullptr, nullptr, &t);if (ret <= 0) {cout << "select fail:" << strerror(errno) << endl;continue;}ret = audit_get_reply(audit_fd, &audit_rep,GET_REPLY_NONBLOCKING, 0);if (ret <= 0) {cout << "open audit fail:" << strerror(errno) << endl;}printf("%s %s", __FUNCTION__, audit_rep.msg.data);cout << audit_rep.msg.data << endl;} while(true);return 0;
}

5 audit存在的問題

如果只是正常使用audit:配置audit規(guī)則,查看審計(jì)日志,也沒啥問題,但是,實(shí)際使用過程中,還是存在一些問題。

5.1 內(nèi)核版本

不同版本的內(nèi)核在實(shí)現(xiàn)機(jī)制上有所不同,因此,運(yùn)行表現(xiàn)和參數(shù)控制上也有所不同:

  • 小于3.14的內(nèi)核沒有提供設(shè)置backlog_wait_time的接口
5.2 審計(jì)日志過多造成的緩存隊(duì)列和磁盤問題

audit_log_end將審計(jì)日志放到audit_queue的隊(duì)尾,如果審計(jì)日志較多,可能會導(dǎo)致隊(duì)列很長,占用的資源增多,因此,內(nèi)核也提供了一些參數(shù)進(jìn)行控制:

  • backlog_limit:緩存隊(duì)列長度限制
  • backlog_wait_time:緩存隊(duì)列滿的等待時(shí)間
// audit_log_start(linux-4.19.281)// auditd_test_task:檢查當(dāng)前進(jìn)程是否是audit daemon進(jìn)程// audit_ctl_owner_current:檢查當(dāng)前進(jìn)程是否持有audit_cmd_mutex鎖// 因此,這里進(jìn)入if的條件是:當(dāng)前進(jìn)程不是audit daemon進(jìn)程,并且沒有持有鎖if (!(auditd_test_task(current) || audit_ctl_owner_current())) {// 獲取audit_backlog_wait_time,就是auditctl -s中的backlog_wait_timelong stime = audit_backlog_wait_time;// audit_backlog_limit就是auditctl -s中的backlog_limit,默認(rèn)值是64// 因此,這里進(jìn)入while的條件是:設(shè)置了backlog_limit,并且當(dāng)前緩存隊(duì)列的長度大于backlog_limitwhile (audit_backlog_limit &&(skb_queue_len(&audit_queue) > audit_backlog_limit)) {// 喚醒kauditd處理隊(duì)列中的日志wake_up_interruptible(&kauditd_wait);/* sleep if we are allowed and we haven't exhausted our* backlog wait limit */// 如果當(dāng)前進(jìn)程允許休眠,并且backlog_wait_time大于0,則進(jìn)入if,backlog_wait_time默認(rèn)是60sif (gfpflags_allow_blocking(gfp_mask) && (stime > 0)) {// 創(chuàng)建等待隊(duì)列的節(jié)點(diǎn)DECLARE_WAITQUEUE(wait, current);// 將剛才創(chuàng)建的等待隊(duì)列的節(jié)點(diǎn)wait加入到隊(duì)列audit_backlog_wait中add_wait_queue_exclusive(&audit_backlog_wait,&wait);set_current_state(TASK_UNINTERRUPTIBLE);// 讓當(dāng)前進(jìn)程休眠一段時(shí)間stime = schedule_timeout(stime);// 將wait從audit_backlog_wait隊(duì)列中移除remove_wait_queue(&audit_backlog_wait, &wait);} else {// 如果當(dāng)前進(jìn)程沒有休眠,則先檢查審計(jì)日志的生成速度是否超過rate_limitif (audit_rate_check() && printk_ratelimit())pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",skb_queue_len(&audit_queue),audit_backlog_limit);// lost自增1,并在審計(jì)日志中打印緩存隊(duì)列超過限制audit_log_lost("backlog limit exceeded");return NULL;}}}

從上面的代碼可以看出,當(dāng)隊(duì)列長度超過backlog_limit時(shí),內(nèi)核會休眠一段時(shí)間backlog_wait_time(默認(rèn)60秒),如果backlog_limit為0,則不會休眠,而是會打印backlog limit exceeded日志。

因此,如果backlog_wait_time不為0,而日志太多時(shí),可能導(dǎo)致內(nèi)核頻繁休眠,極端情況下,系統(tǒng)直接卡死。

如果要解決這個(gè)問題,可以從幾個(gè)方面入手:

  • 審計(jì)規(guī)則盡可能只配置必要的,防止生成大量無用的審計(jì)日志
  • 根據(jù)機(jī)器配置增加backlog_limit,例如,將backlog_limit可以設(shè)置為8193或者更大
  • backlog_wait_time設(shè)置為0,當(dāng)日志過多時(shí)直接丟棄,防止影響日常的使用
  • 審計(jì)日志的消費(fèi)者盡可能快速消費(fèi)日志,可能的情況下,可以增加丟棄策略,防止審計(jì)日志堆積

當(dāng)審計(jì)日志過多,還會造成磁盤占用率的問題:當(dāng)審計(jì)日志太多,可能會占用大量磁盤空間。

需要注意的是,即使沒有配置審計(jì)規(guī)則,日志中也可能有審計(jì)日志,pam認(rèn)證、服務(wù)啟動等,在沒有規(guī)則的情況下內(nèi)核也會生成審計(jì)日志。

同時(shí),從3.16.0開始,內(nèi)核增加了多消費(fèi)者,允許多個(gè)進(jìn)程同時(shí)讀取審計(jì)日志,那么,如果存在其他進(jìn)程也讀取審計(jì)然后寫到日志文件的話,磁盤占用的問題又會放大,因此,對于磁盤占用的問題,可以從以下幾個(gè)方面入手:

  • 是否有其他進(jìn)程也讀取了審計(jì)日志
  • 在沒有配置審計(jì)規(guī)則的情況下是否也會產(chǎn)生大量日志
5.2 容器環(huán)境下同一個(gè)命令的日志存在差異

在容器環(huán)境下,同一個(gè)命令的日志可能存在差異,因?yàn)槊畹膶?shí)現(xiàn)有所不同,比較典型的是,有些鏡像的vi是重定向到busybox,有些則是跟主機(jī)一樣的二進(jìn)制文件,那么他們產(chǎn)生的日志就不同,就會造成分析上的困難。

6 參考文檔

  • RHEL Audit System Reference
  • 讀懂a(chǎn)udit日志
  • Audit framework
http://www.risenshineclean.com/news/746.html

相關(guān)文章:

  • wordpress在線音樂/seo狂人
  • 上海最好的網(wǎng)站建設(shè)公司/百度競價(jià)推廣方案
  • 做網(wǎng)站哪個(gè)語言強(qiáng)/好項(xiàng)目推薦平臺
  • 網(wǎng)絡(luò)營銷與傳統(tǒng)營銷有哪些區(qū)別/windows優(yōu)化大師可以卸載嗎
  • 鶴壁做網(wǎng)站優(yōu)化/aso優(yōu)化榜單
  • 如何做企業(yè)網(wǎng)站推廣產(chǎn)品/iis搭建網(wǎng)站
  • 網(wǎng)絡(luò)營銷方式和平臺推廣/搜索引擎優(yōu)化的目的是
  • 天津武清做網(wǎng)站tjniu/產(chǎn)品互聯(lián)網(wǎng)營銷推廣
  • 海報(bào)設(shè)計(jì)網(wǎng)站官網(wǎng)/百度怎么做廣告
  • 石家莊有哪些做網(wǎng)站的公司/百度保障中心人工電話
  • 門戶網(wǎng)站建設(shè)工作會議/國外引流推廣軟件
  • 網(wǎng)站頁面類型/正規(guī)網(wǎng)站優(yōu)化哪個(gè)公司好
  • 推廣網(wǎng)站最有效方法/自己有貨源怎么找客戶
  • 重慶網(wǎng)站建設(shè)設(shè)計(jì)/怎么去推廣一個(gè)app
  • 網(wǎng)站微營銷公司哪家好/鄭州疫情最新動態(tài)
  • 品牌logo設(shè)計(jì)說明/百度seo優(yōu)化公司
  • 有什么做任務(wù)得傭金的網(wǎng)站/站長之家app
  • 做淘寶有哪些推廣網(wǎng)站/seo外鏈友情鏈接
  • 開發(fā)公司取名字大全免費(fèi)查詢/貴陽網(wǎng)站優(yōu)化公司
  • 代碼判斷網(wǎng)站/上海百度競價(jià)托管
  • 運(yùn)動網(wǎng)站建設(shè)教程/上海網(wǎng)站排名優(yōu)化公司
  • 濟(jì)南做網(wǎng)站xywlcn/百度用戶服務(wù)中心官網(wǎng)
  • 南海區(qū)住房和城鄉(xiāng)建設(shè)部網(wǎng)站/提高網(wǎng)站排名軟件
  • 河南那家公司做家具行業(yè)網(wǎng)站好/電商培訓(xùn)有用嗎
  • 中山品牌網(wǎng)站建設(shè)推廣/軟件培訓(xùn)機(jī)構(gòu)有哪些?哪個(gè)比較好
  • 東莞工信部網(wǎng)站/公司排名seo
  • java做網(wǎng)站pdf/網(wǎng)絡(luò)營銷成功案例ppt
  • 學(xué)生怎樣做網(wǎng)站/模板建站哪里有
  • 免費(fèi)網(wǎng)站制作公司/長春網(wǎng)站關(guān)鍵詞推廣
  • 網(wǎng)站產(chǎn)品頁面/注冊安全工程師