Support controller user attribution in audit logs (#15407)

* Support controller user attribution in audit logs

This PR supports associating audit logs with the controller user.

  ## Implementation:
  - Add `ControlledContext { conn_audit_token }` to `PunchHole`, `RequestRelay`, and `FetchLocalAddr`.
  - The server sends a controller-user identity snapshot to the controlled client through rendezvous messages.
  - The controlled client sends the token back to the server when posting the `on_open` conn audit or IP whitelist alarm audit.
  - This lets the server attach the controller user to audit logs.

  ## How the controlled client helps identify the controller user:
  - Conn audit: sends the token to the server in `on_open`; the server creates the audit log and caches the user snapshot.
  - File audit: sends `id` and `conn_id`; the server uses them to find the cached user snapshot.
  - Alarm audit: IP whitelist sends the token directly; other alarm logs send `id` and `conn_id`, and the server uses them to find the cached user
  snapshot.

  ## Compatibility:
  - Supported only for logs created with a new server and a new controlled client.
  - Does not require upgrading the controller client.

  ## Test

  - [x] New/old clients connected to new/old servers, and conn/file/alarm audit logs worked normally.
  - [x] New client connected to new server generated searchable conn/file/alarm audit logs.
  - [x] Punch hole, local addr, and relay paths worked with audit logs and control role on new/old servers.
  - [x] Direct IP connections produced audit logs, but do not support user audit.

Signed-off-by: 21pages <sunboeasy@gmail.com>

* rename conn_audit_token to conn_audit_ref

Signed-off-by: 21pages <sunboeasy@gmail.com>

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2026-06-26 15:07:27 +08:00
committed by GitHub
parent 78b5f47668
commit 989bf80fe8
4 changed files with 104 additions and 91 deletions

View File

@@ -81,6 +81,12 @@ pub mod printer_service;
pub type Childs = Arc<Mutex<Vec<std::process::Child>>>;
type ConnMap = HashMap<i32, ConnInner>;
#[derive(Clone, Default)]
pub struct ConnectionMeta {
pub control_permissions: Option<ControlPermissions>,
pub controlled_context: Option<ControlledContext>,
}
#[cfg(any(target_os = "macos", target_os = "linux"))]
const CONFIG_SYNC_INTERVAL_SECS: f32 = 0.3;
#[cfg(any(target_os = "macos", target_os = "linux"))]
@@ -163,7 +169,7 @@ async fn accept_connection_(
server: ServerPtr,
socket: Stream,
secure: bool,
control_permissions: Option<ControlPermissions>,
meta: ConnectionMeta,
) -> ResultType<()> {
let local_addr = socket.local_addr();
drop(socket);
@@ -180,7 +186,7 @@ async fn accept_connection_(
Stream::from(stream, stream_addr),
addr,
secure,
control_permissions,
meta,
)
.await?;
}
@@ -192,7 +198,7 @@ pub async fn create_tcp_connection(
stream: Stream,
addr: SocketAddr,
secure: bool,
control_permissions: Option<ControlPermissions>,
meta: ConnectionMeta,
) -> ResultType<()> {
let mut stream = stream;
let id = server.write().unwrap().get_new_id();
@@ -260,14 +266,7 @@ pub async fn create_tcp_connection(
}
log::info!("wake up macos");
}
Connection::start(
addr,
stream,
id,
Arc::downgrade(&server),
control_permissions,
)
.await;
Connection::start(addr, stream, id, Arc::downgrade(&server), meta).await;
Ok(())
}
@@ -276,9 +275,9 @@ pub async fn accept_connection(
socket: Stream,
peer_addr: SocketAddr,
secure: bool,
control_permissions: Option<ControlPermissions>,
meta: ConnectionMeta,
) {
if let Err(err) = accept_connection_(server, socket, secure, control_permissions).await {
if let Err(err) = accept_connection_(server, socket, secure, meta).await {
log::warn!("Failed to accept connection from {}: {}", peer_addr, err);
}
}
@@ -290,7 +289,7 @@ pub async fn create_relay_connection(
peer_addr: SocketAddr,
secure: bool,
ipv4: bool,
control_permissions: Option<ControlPermissions>,
meta: ConnectionMeta,
) {
if let Err(err) = create_relay_connection_(
server,
@@ -299,7 +298,7 @@ pub async fn create_relay_connection(
peer_addr,
secure,
ipv4,
control_permissions,
meta,
)
.await
{
@@ -319,7 +318,7 @@ async fn create_relay_connection_(
peer_addr: SocketAddr,
secure: bool,
ipv4: bool,
control_permissions: Option<ControlPermissions>,
meta: ConnectionMeta,
) -> ResultType<()> {
let mut stream = socket_client::connect_tcp(
socket_client::ipv4_to_ipv6(crate::check_port(relay_server, RELAY_PORT), ipv4),
@@ -334,7 +333,7 @@ async fn create_relay_connection_(
..Default::default()
});
stream.send(&msg_out).await?;
create_tcp_connection(server, stream, peer_addr, secure, control_permissions).await?;
create_tcp_connection(server, stream, peer_addr, secure, meta).await?;
Ok(())
}