Skip to content

Commit

Permalink
Some improvements
Browse files Browse the repository at this point in the history
- Add user IDs to admin interface
- Add snapshot testing to ConnectionMap
- Add auth_self_hosted_login_api test
  • Loading branch information
EpicEric committed Dec 15, 2024
1 parent d0d01f4 commit 54d64ec
Show file tree
Hide file tree
Showing 24 changed files with 483 additions and 156 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@

### Added

- **BREAKING**: Add `remote_address` field to API login request.
- Add user forwarding quotas via the `--quota-per-user` option.
- Add `remote_address` field to API login request.
- Add user IDs to admin interface.

### Fixed

- Better handling of initial value and windowing for telemetry counters.

### Changed

- Bump MSRV to 1.79.0.
- **BREAKING**: Bump MSRV to 1.79.0.
- Modify exports to live within `lib.rs`.
- Update `russh` dependency to version `0.50.0-beta.1`.
- Update `sysinfo` dependency to version `0.33.0`.
Expand Down
38 changes: 38 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exclude = [".github", "book", "docker-compose-example", "tests/data"]
[dependencies]
anyhow = "1.0.93"
async-trait = "0.1.83"
axum = "0.7.7"
axum = { version = "0.7.7", default-features = false }
bytes = "1.8.0"
chrono = "0.4.38"
clap = { version = "4.5.20", features = ["derive", "string"] }
Expand Down Expand Up @@ -58,6 +58,7 @@ trie-rs = "0.4.2"
[dev-dependencies]
axum = { version = "0.7.7", features = ["macros", "ws"] }
futures-util = "0.3.31"
insta = { version = "1.41.1", features = ["yaml"] }
mockall = "0.13.0"
regex = "1.11.1"
tokio-tungstenite = "0.24.0"
Expand Down
16 changes: 8 additions & 8 deletions book/src/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ Expose HTTP/SSH/TCP services through SSH port forwarding.

Possible values:
- <b>all</b>: Allow any hostnames unconditionally, including the
main domain
main domain
- <b>cname</b>: Allow any hostnames with a CNAME record pointing to
the main domain
the main domain
- <b>txt</b>: Allow any hostnames with a TXT record containing a
fingerprint, including the main domain
fingerprint, including the main domain
- <b>none</b>: Don&#39;t allow user-provided hostnames, enforce
subdomains
subdomains

<b>--load-balancing</b> &lt;STRATEGY&gt;
Strategy for load-balancing when multiple services request the same
Expand All @@ -133,9 +133,9 @@ Expose HTTP/SSH/TCP services through SSH port forwarding.
Possible values:
- <b>allow</b>: Load-balance with all available handlers
- <b>replace</b>: Don&#39;t load-balance; When adding a new handler,
replace the existing one
replace the existing one
- <b>deny</b>: Don&#39;t load-balance; Deny the new handler if
there&#39;s an existing one
there&#39;s an existing one

<b>--txt-record-prefix</b> &lt;PREFIX&gt;
Prefix for TXT DNS records containing key fingerprints, for
Expand Down Expand Up @@ -174,11 +174,11 @@ Expose HTTP/SSH/TCP services through SSH port forwarding.

Possible values:
- <b>ip-and-user</b>: From IP address, SSH user, and requested
address. Recommended if unsure
address. Recommended if unsure
- <b>user</b>: From SSH user and requested address
- <b>fingerprint</b>: From SSH key fingerprint and requested address
- <b>address</b>: From SSH connection socket (address + port) and
requested address
requested address

<b>--idle-connection-timeout</b> &lt;DURATION&gt;
Grace period for dangling/unauthenticated SSH connections before they
Expand Down
88 changes: 58 additions & 30 deletions src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ struct AdminState {
is_pty: bool,
tab: Tab,
table_state: TableState,
scroll_state: ScrollbarState,
vertical_scroll: ScrollbarState,
}

fn remove_user_namespace(user: &str) -> &str {
&user[2..]
}

fn to_socket_addr_string(addr: SocketAddr) -> String {
Expand Down Expand Up @@ -151,23 +155,29 @@ impl AdminState {
let table = match self.tab {
Tab::Http => {
let data = self.server.http_data.read().unwrap().clone();
self.scroll_state = self.scroll_state.content_length(data.len());
let rows = data.into_iter().map(|(host, (peers, req_per_min))| {
let len = peers.len() as u16;
self.vertical_scroll = self.vertical_scroll.content_length(data.len());
let rows = data.into_iter().map(|(host, (connections, req_per_min))| {
let len = connections.len() as u16;
let (peers, users): (Vec<_>, Vec<_>) = connections.into_iter().unzip();
Row::new(vec![
host,
peers.into_iter().map(to_socket_addr_string).join("\n"),
req_per_min.to_string(),
users
.iter()
.map(|user| remove_user_namespace(user))
.join("\n"),
peers.into_iter().map(to_socket_addr_string).join("\n"),
])
.height(len)
});
let constraints = [
Constraint::Min(25),
Constraint::Length(47),
Constraint::Min(7),
Constraint::Length(50),
Constraint::Length(47),
];
let header =
Row::new(["Host", "Peer(s)", "Req/min"]).add_modifier(Modifier::UNDERLINED);
let header = Row::new(["Host", "Req/min", "User(s)", "Peer(s)"])
.add_modifier(Modifier::UNDERLINED);
let title =
Block::new().title(Line::from("HTTP services".fg(color).bold()).centered());
Table::new(rows, constraints)
Expand All @@ -178,17 +188,27 @@ impl AdminState {
}
Tab::Ssh => {
let data = self.server.ssh_data.read().unwrap().clone();
self.scroll_state = self.scroll_state.content_length(data.len());
let rows = data.into_iter().map(|(host, peers)| {
let len = peers.len() as u16;
self.vertical_scroll = self.vertical_scroll.content_length(data.len());
let rows = data.into_iter().map(|(host, connections)| {
let len = connections.len() as u16;
let (peers, users): (Vec<_>, Vec<_>) = connections.into_iter().unzip();
Row::new(vec![
host,
users
.iter()
.map(|user| remove_user_namespace(user))
.join("\n"),
peers.into_iter().map(to_socket_addr_string).join("\n"),
])
.height(len)
});
let constraints = [Constraint::Min(25), Constraint::Length(47)];
let header = Row::new(["Host", "Peer(s)"]).add_modifier(Modifier::UNDERLINED);
let constraints = [
Constraint::Min(25),
Constraint::Length(50),
Constraint::Length(47),
];
let header =
Row::new(["Host", "User(s)", "Peer(s)"]).add_modifier(Modifier::UNDERLINED);
let title =
Block::new().title(Line::from("SSH services".fg(color).bold()).centered());
Table::new(rows, constraints)
Expand All @@ -199,19 +219,27 @@ impl AdminState {
}
Tab::Tcp => {
let data = self.server.tcp_data.read().unwrap().clone();
self.scroll_state = self.scroll_state.content_length(data.len());
let rows = data.into_iter().map(|(TcpAlias(alias, port), peers)| {
let len = peers.len() as u16;
Row::new(vec![
alias,
port.to_string(),
peers.into_iter().map(to_socket_addr_string).join("\n"),
])
.height(len)
});
self.vertical_scroll = self.vertical_scroll.content_length(data.len());
let rows = data
.into_iter()
.map(|(TcpAlias(alias, port), connections)| {
let len = connections.len() as u16;
let (peers, users): (Vec<_>, Vec<_>) = connections.into_iter().unzip();
Row::new(vec![
alias,
port.to_string(),
users
.iter()
.map(|user| remove_user_namespace(user))
.join("\n"),
peers.into_iter().map(to_socket_addr_string).join("\n"),
])
.height(len)
});
let constraints = [
Constraint::Min(25),
Constraint::Length(5),
Constraint::Length(50),
Constraint::Length(47),
];
let header =
Expand All @@ -228,9 +256,9 @@ impl AdminState {
StatefulWidget::render(table, area, buf, &mut self.table_state);
StatefulWidget::render(
Scrollbar::default().orientation(ScrollbarOrientation::VerticalRight),
area.inner(Margin::new(0, 1)),
area.inner(Margin::new(0, 2)),
buf,
&mut self.scroll_state,
&mut self.vertical_scroll,
);
}

Expand Down Expand Up @@ -309,7 +337,7 @@ impl AdminInterface {
tab: Tab::Http,
is_pty: false,
table_state: Default::default(),
scroll_state: Default::default(),
vertical_scroll: Default::default(),
},
}));
let interface_clone = Arc::clone(&interface);
Expand Down Expand Up @@ -376,7 +404,7 @@ impl AdminInterface {
}
}
interface.state.table_state = Default::default();
interface.state.scroll_state = Default::default();
interface.state.vertical_scroll = Default::default();
drop(interface);
}
let _ = self.change_notifier.send(());
Expand All @@ -398,7 +426,7 @@ impl AdminInterface {
}
}
interface.state.table_state = Default::default();
interface.state.scroll_state = Default::default();
interface.state.vertical_scroll = Default::default();
drop(interface);
}
let _ = self.change_notifier.send(());
Expand All @@ -409,7 +437,7 @@ impl AdminInterface {
{
let mut interface = self.interface.lock().unwrap();
interface.state.table_state.select_next();
interface.state.scroll_state.next();
interface.state.vertical_scroll.next();
drop(interface);
}
let _ = self.change_notifier.send(());
Expand All @@ -420,7 +448,7 @@ impl AdminInterface {
{
let mut interface = self.interface.lock().unwrap();
interface.state.table_state.select_previous();
interface.state.scroll_state.prev();
interface.state.vertical_scroll.prev();
drop(interface);
}
let _ = self.change_notifier.send(());
Expand Down
Loading

0 comments on commit 54d64ec

Please sign in to comment.