Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions agent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions agent/crates/public/src/l7_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub enum L7Protocol {
MySQL = 60,
PostgreSQL = 61,
Oracle = 62,
SqlServer = 63,

// NoSQL
Redis = 80,
Expand Down Expand Up @@ -144,6 +145,7 @@ impl From<String> for L7Protocol {
"webspheremq" => Self::WebSphereMq,
"dns" => Self::DNS,
"oracle" => Self::Oracle,
"sqlserver" => Self::SqlServer,
"iso8583" | "iso-8583" => Self::Iso8583,
"triple" => Self::Triple,
"tls" => Self::TLS,
Expand Down
2 changes: 2 additions & 0 deletions agent/plugins/l7/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ edition = "2021"

[dependencies]
bitflags = "1.3.2"
bytes = "1.10"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

把多个 crate 都在用的依赖放到 agent/Cargo.toml 的 workspace 依赖里

chrono = "0.4"
serde = { version = "1.0", features = ["derive"] }
1 change: 1 addition & 0 deletions agent/plugins/l7/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
*/

pub mod some_ip;
pub mod sql_server;
pub mod tls;
63 changes: 63 additions & 0 deletions agent/plugins/l7/src/sql_server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2024 Yunshan Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#[derive(Debug, Default)]
pub struct TdsParser {
pub sql: Option<String>,
pub status_code: Option<i32>,
pub error_message: Option<String>,
pub affected_row: Option<u64>,
}

impl TdsParser {
pub fn new(_: &[u8]) -> Self {
TdsParser::default()
}

pub fn parse(&mut self) -> Result<(), ParserError> {
Err(ParserError::InvalidData)
}
}

#[derive(Debug)]
pub enum ParserError {
IoError(std::io::Error),
UnknownToken(u8),
UnknownEnvType(u8),
InvalidData,
InsufficientData,
Utf8Error(std::string::FromUtf8Error),
Utf16Error(std::string::FromUtf16Error),
UnsupportedDataType,
}

impl From<std::io::Error> for ParserError {
fn from(err: std::io::Error) -> Self {
ParserError::IoError(err)
}
}

impl From<std::string::FromUtf8Error> for ParserError {
fn from(err: std::string::FromUtf8Error) -> Self {
ParserError::Utf8Error(err)
}
}

impl From<std::string::FromUtf16Error> for ParserError {
fn from(err: std::string::FromUtf16Error) -> Self {
ParserError::Utf16Error(err)
}
}
4 changes: 3 additions & 1 deletion agent/src/common/l7_protocol_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use crate::{
fastcgi::FastCGIInfo, pb_adapter::L7ProtocolSendLog, AmqpInfo, BrpcInfo, DnsInfo,
DubboInfo, HttpInfo, KafkaInfo, MemcachedInfo, MongoDBInfo, MqttInfo, MysqlInfo,
NatsInfo, OpenWireInfo, PingInfo, PostgreInfo, PulsarInfo, RedisInfo, RocketmqInfo,
SofaRpcInfo, TarsInfo, ZmtpInfo,
SofaRpcInfo, SqlServerInfo, TarsInfo, ZmtpInfo,
},
AppProtoHead, Result,
},
Expand Down Expand Up @@ -100,6 +100,7 @@ cfg_if::cfg_if! {
SofaRpcInfo(SofaRpcInfo),
PingInfo(PingInfo),
CustomInfo(CustomInfo),
SqlServerInfo(SqlServerInfo),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这边不用加

// add new protocol info below
);
} else {
Expand Down Expand Up @@ -131,6 +132,7 @@ cfg_if::cfg_if! {
PingInfo(PingInfo),
CustomInfo(CustomInfo),
Iso8583Info(crate::flow_generator::protocol_logs::rpc::Iso8583Info),
SqlServerInfo(SqlServerInfo),
// add new protocol info below
);
}
Expand Down
4 changes: 3 additions & 1 deletion agent/src/common/l7_protocol_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use crate::flow_generator::protocol_logs::{
sql::ObfuscateCache,
AmqpLog, BrpcLog, DnsLog, DubboLog, HttpLog, KafkaLog, L7ResponseStatus, MemcachedLog,
MongoDBLog, MqttLog, MysqlLog, NatsLog, OpenWireLog, PingLog, PostgresqlLog, PulsarLog,
RedisLog, RocketmqLog, SofaRpcLog, TarsLog, ZmtpLog,
RedisLog, RocketmqLog, SofaRpcLog, SqlServerLog, TarsLog, ZmtpLog,
};

use crate::flow_generator::Result;
Expand Down Expand Up @@ -180,6 +180,7 @@ cfg_if::cfg_if! {
RocketMQ(RocketmqLog),
OpenWire(OpenWireLog),
Ping(PingLog),
SqlServer(SqlServerLog),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里也不用

// add protocol below
}
}
Expand Down Expand Up @@ -213,6 +214,7 @@ cfg_if::cfg_if! {
TLS(crate::flow_generator::protocol_logs::TlsLog),
SomeIp(crate::flow_generator::protocol_logs::SomeIpLog),
Ping(PingLog),
SqlServer(SqlServerLog),
// add protocol below
}
}
Expand Down
2 changes: 2 additions & 0 deletions agent/src/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1891,6 +1891,7 @@ impl Default for Filters {
("MySQL".to_string(), "1-65535".to_string()),
("PostgreSQL".to_string(), "1-65535".to_string()),
("Oracle".to_string(), "1521".to_string()),
("SqlServer".to_string(), "1433".to_string()),
("Redis".to_string(), "1-65535".to_string()),
("MongoDB".to_string(), "1-65535".to_string()),
("Memcached".to_string(), "11211".to_string()),
Expand Down Expand Up @@ -1923,6 +1924,7 @@ impl Default for Filters {
("MySQL".to_string(), vec![]),
("PostgreSQL".to_string(), vec![]),
("Oracle".to_string(), vec![]),
("SqlServer".to_string(), vec![]),
("Redis".to_string(), vec![]),
("MongoDB".to_string(), vec![]),
("Memcached".to_string(), vec![]),
Expand Down
21 changes: 11 additions & 10 deletions agent/src/ebpf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The following protocols are currently probed:
- TLS(handshake)
- MONGO
- ORACLE
- SqlServer
- FASTCGI
- ROCKETMQ

Expand Down Expand Up @@ -104,13 +105,13 @@ end
style bpf_tracer_init-2 stroke-width:2px
style bpf_tracer_init-3 stroke-width:2px
start[tracer start]
start --> enable_ebpf_protocol(1 enable_ebpf_protocol) -.- enable_ebpf_protocol-i([ebable application layer protocols])
start --> enable_ebpf_protocol(1 enable_ebpf_protocol) -.- enable_ebpf_protocol-i([ebable application layer protocols])
start --> FEATUER(2 set_feature_regex) -.- FEATUER-i([Uprobe OPENSSL/GOLANG filter])
start --> bpf_tracer_init(3 bpf_tracer_init)

start --> running_socket_tracer(4 running_socket_tracer)
start --> bpf_tracer_finish(5 bpf_tracer_finish)-.-bpf_tracer_finish-i([Indicates that all probes have been set])

bpf_tracer_init --> bpf_tracer_init-1(3.1 set bpf_jit_enable,sys_boot_time,max_locked_memory)
bpf_tracer_init --> bpf_tracer_init-2(3.2 set log)
bpf_tracer_init --> bpf_tracer_init-3(3.3 new thread - ctrl_main)
Expand All @@ -125,12 +126,12 @@ end
running_socket_tracer --> running_socket_tracer-6(4.4 setup_bpf_tracer)

running_socket_tracer --> running_socket_tracer-4(4.5 maps_config)-.-running_socket_tracer-4-i([set socket/trace map entries count])
running_socket_tracer --> running_socket_tracer-5(4.6 set perf buffer reader callback)
running_socket_tracer --> running_socket_tracer-7(4.7 set socket_map_max_reclaim value)
running_socket_tracer --> running_socket_tracer-5(4.6 set perf buffer reader callback)
running_socket_tracer --> running_socket_tracer-7(4.7 set socket_map_max_reclaim value)
running_socket_tracer --> running_socket_tracer-8(4.8 tracer_bpf_load)-.-running_socket_tracer-8-i([load ebpf progs and create maps])
running_socket_tracer --> running_socket_tracer-9(4.9 tracer_probes_init)-.-running_socket_tracer-9-i([Call create_probe, prepare all probes before attach/detach])
running_socket_tracer --> running_socket_tracer-10(4.10 update_offset_map_from_btf_vmlinux)-.-running_socket_tracer-10-i([Get the offsets from the BTF files, these offsets are used by the eBPF programs])
running_socket_tracer-10 -.-> |store member offset to map |members_offset_map[(members_offset map)]
running_socket_tracer-10 -.-> |store member offset to map |members_offset_map[(members_offset map)]
running_socket_tracer --> running_socket_tracer-11(4.11 update_proc_info_to_map) -.- running_socket_tracer-11-i([set go/ssl uprobe offsets])
running_socket_tracer-11-.->|store uprobe offsets for the executable file|proc_info_map[(proc_info_map)]
running_socket_tracer --> running_socket_tracer-12(4.12 update_protocol_filter_array)
Expand Down Expand Up @@ -309,7 +310,7 @@ end
style collect_ssl_uprobe_syms_from_procfs fill:#ccff,color:#000, stroke-width:2px
style IFGETVER stroke-width:2px
style collect_ssl_detail stroke-width:2px
style RET fill:#fff,color:#000,stroke:#000,stroke-width:2px
style RET fill:#fff,color:#000,stroke:#000,stroke-width:2px
style resolve_bin_file fill:#ccff,color:#000, stroke-width:2px
style resolve_and_gen_uprobe_symbol fill:#ccff,color:#000, stroke-width:2px
style bcc_elf_foreach_sym fill:#ccff,color:#000, stroke-width:2px
Expand Down Expand Up @@ -389,7 +390,7 @@ graph LR
perf_buffer-.-> Buffer-Reader(Buffer-Reader)
subgraph user
Buffer-Reader---perf_buffer_read(3 perf_buffer_read)-->reader_event_read(4 reader_event_read)-->reader_raw_cb(5 reader_raw_cb)
end
end
```

```mermaid
Expand Down Expand Up @@ -452,7 +453,7 @@ graph LR

**Explanation:**

- 7 process_event
- 7 process_event
- According to the event_type is EVENT_TYPE_PROC_EXEC or EVENT_TYPE_PROC_EXIT to determine the final call interface. EVENT_TYPE_PROC_EXEC(call go_process_exec(), ssl_process_exec),EVENT_TYPE_PROC_EXIT(call go_process_exit(), ssl_process_exit()).
- 8 rust extra events callback
- We provide a function that the user can register a callback interface for a specific event. e.g. Use rust function process these events.
Expand All @@ -478,11 +479,11 @@ graph LR
- 4.16.x
- 4.16.0, 4.16.1, 4.16.10, 4.16.11, 4.16.12,4.16.13, 4.16.2, 4.16.3, 4.16.4, 4.16.5, 4.16.6, 4.16.7, 4.16.8, 4.16.9
- 4.17.x
- 4.17.0, 4.17.1, 4.17.10, 4.17.11,4.17.12, 4.17.13, 4.17.14, 4.17.2, 4.17.3, 4.17.4, 4.17.5, 4.17.6, 4.17.8, 4.17.9
- 4.17.0, 4.17.1, 4.17.10, 4.17.11,4.17.12, 4.17.13, 4.17.14, 4.17.2, 4.17.3, 4.17.4, 4.17.5, 4.17.6, 4.17.8, 4.17.9
- 4.18.x
- 4.18.0, 4.18.1, 4.18.10,4.18.11, 4.18.12, 4.18.13, 4.18.14, 4.18.15, 4.18.16, 4.18.3, 4.18.4, 4.18.5, 4.18.6, 4.18.7, 4.18.8, 4.18.9
- 4.19.x
- 4.19.0, 4.19.1, 4.19.10, 4.19.11, 4.19.12, 4.19.2, 4.19.3, 4.19.4, 4.19.5, 4.19.6, 4.19.7, 4.19.8, 4.19.9
- 4.19.0, 4.19.1, 4.19.10, 4.19.11, 4.19.12, 4.19.2, 4.19.3, 4.19.4, 4.19.5, 4.19.6, 4.19.7, 4.19.8, 4.19.9
- 4.20.x
- 4.20.0,4.20.1, 4.20.10, 4.20.11, 4.20.12, 4.20.13, 4.20.2, 4.20.3, 4.20.4, 4.20.5, 4.20.6, 4.20.7, 4.20.8
- 5.0.x
Expand Down
1 change: 1 addition & 0 deletions agent/src/ebpf/kernel/include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ enum traffic_protocol {
PROTO_MYSQL = 60,
PROTO_POSTGRESQL = 61,
PROTO_ORACLE = 62,
PROTO_SQL_SERVER = 63,
PROTO_REDIS = 80,
PROTO_MONGO = 81,
PROTO_MEMCACHED = 82,
Expand Down
83 changes: 71 additions & 12 deletions agent/src/ebpf/kernel/include/protocol_inference.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,10 +791,10 @@ static __inline enum message_type infer_mysql_message(const char *buf,
if (is_socket_info_valid(conn_info->socket_info_ptr)) {
/*
* Ensure the authentication response packet is captured
* and distinguish it based on the 5th byte (Payload start):
* and distinguish it based on the 5th byte (Payload start):
*
* - **Authentication Success (OK Packet):** `0x00`
* - **Authentication Failure (ERR Packet):** `0xFF`
* - **Authentication Success (OK Packet):** `0x00`
* - **Authentication Failure (ERR Packet):** `0xFF`
* - **Authentication Switch Request (Auth Switch Request):** `0xFE`
*/
if (seq <= 1 || (seq == 2 && (com == 0x0 || com == 0xFF || com == 0xFE)))
Expand Down Expand Up @@ -835,14 +835,14 @@ static __inline enum message_type infer_mysql_message(const char *buf,

/*
* After establishing a connection, the MySQL server sends a handshake packet.
* The process is as follows:
* - **Server > Client (Handshake Packet)**
* The process is as follows:
* - **Server > Client (Handshake Packet)**
* The server sends this handshake packet, which includes the MySQL version,
* thread ID, authentication method, and other information.
* - **Client > Server (Login Request Packet)**
* thread ID, authentication method, and other information.
* - **Client > Server (Login Request Packet)**
* The client computes the encrypted password based on `auth-plugin-data` and
* sends it back to the server for verification.
* - **Server > Client (Login Success or Failure)**
* sends it back to the server for verification.
* - **Server > Client (Login Success or Failure)**
* The server verifies the client's identity and returns either an **OK Packet** or an **ERR Packet**.
*
* The handshake packet sent by the server is used for identification.
Expand Down Expand Up @@ -1228,6 +1228,48 @@ static __inline enum message_type infer_oracle_tns_message(const char *buf,
}
}

static __inline enum message_type infer_sql_server_message(const char *buf,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注释下sql_server推断的参考链接?

size_t count,
struct conn_info_s
*conn_info)
{
#define HEADER_SIZE 8
#define MESSAGE_TYPE_OFFSET 0
#define LENGTH_OFFSET 1
#define WINDOWS_OFFSET 7
#define MESSAGE_TYPE_SQL_BATCH 1
#define MESSAGE_TYPE_RPC 3
#define MESSAGE_TYPE_RESPONSE 4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面这些宏在当前推断完之后undef了吧,确保这些宏定义不会污染到当前函数之外的代码中。
参考: pulsar_check_basecommand() 这个接口写法

if (!protocol_port_check_1(PROTO_SQL_SERVER, conn_info))
return MSG_UNKNOWN;
if (conn_info->tuple.l4_protocol != IPPROTO_TCP || count < HEADER_SIZE) {
return MSG_UNKNOWN;
}

if (is_infer_socket_valid(conn_info->socket_info_ptr)) {
if (conn_info->socket_info_ptr->l7_proto != PROTO_SQL_SERVER)
return MSG_UNKNOWN;
}

__u8 pkt_type = buf[MESSAGE_TYPE_OFFSET];
__u16 pkt_length = __bpf_ntohs(*(__u16 *) & buf[LENGTH_OFFSET]);
__u8 windows = buf[WINDOWS_OFFSET];
if (pkt_length < HEADER_SIZE || windows != 0) {
return MSG_UNKNOWN;
}

if (pkt_type == MESSAGE_TYPE_RESPONSE) {
return MSG_RESPONSE;
}
if (pkt_type == MESSAGE_TYPE_SQL_BATCH) {
return MSG_REQUEST;
}
if (pkt_type == MESSAGE_TYPE_RPC) {
return MSG_REQUEST;
}
return MSG_UNKNOWN;
}

// https://en.wikipedia.org/wiki/ISO_8583
static __inline enum message_type infer_iso8583_message(const char *buf,
size_t count,
Expand Down Expand Up @@ -1581,11 +1623,11 @@ static __inline enum message_type infer_dns_message(const char *buf,

bool update_tcp_dns_prev_count = false;
struct dns_header *dns = (struct dns_header *)buf;

/*
* Note that TCP DNS adds two length bytes at the beginning of the protocol,
* whereas UDP DNS does not. We need to handle this properly to ensure that
* these two length bytes are not sent to the upper layer.
* these two length bytes are not sent to the upper layer.
*
* When receiving data, the client does not first receive two bytes but instead
* receives everything at once; whereas the server receives two bytes (length) first
Expand Down Expand Up @@ -4286,7 +4328,7 @@ infer_protocol_1(struct ctx_info_s *ctx,
* encrypted data can be discarded to prevent it from being involved
* in subsequent protocol inference, thereby avoiding performance
* degradation.
*/
*/
if (is_socket_info_valid(conn_info->socket_info_ptr)) {
if (conn_info->socket_info_ptr->is_tls &&
!skip_http2_kprobe())
Expand Down Expand Up @@ -4483,6 +4525,15 @@ infer_protocol_1(struct ctx_info_s *ctx,
return inferred_message;
}
break;
case PROTO_SQL_SERVER:
if ((inferred_message.type =
infer_sql_server_message(infer_buf, count,
conn_info)) !=
MSG_UNKNOWN) {
inferred_message.protocol = PROTO_SQL_SERVER;
return inferred_message;
}
break;
case PROTO_ISO8583:
if ((inferred_message.type =
infer_iso8583_message(infer_buf, count,
Expand Down Expand Up @@ -4633,6 +4684,14 @@ infer_protocol_1(struct ctx_info_s *ctx,
if (inferred_message.type == MSG_PRESTORE)
return inferred_message;
inferred_message.protocol = PROTO_MYSQL;
#if defined(LINUX_VER_KFUNC) || defined(LINUX_VER_5_2_PLUS)
} else if (skip_proto != PROTO_SQL_SERVER && (inferred_message.type =
#else
} else if ((inferred_message.type =
#endif
infer_sql_server_message(infer_buf, count,
conn_info)) != MSG_UNKNOWN) {
inferred_message.protocol = PROTO_SQL_SERVER;
#if defined(LINUX_VER_KFUNC) || defined(LINUX_VER_5_2_PLUS)
} else if (skip_proto != PROTO_FASTCGI && (inferred_message.type =
#else
Expand Down
Loading
Loading