Skip to content

Commit 813402d

Browse files
bjorn3djc
authored andcommitted
Store the generated host key on the disk
Instead of generating one on every connection. This avoids having to either remove the host key again after every test or having to tell the ssh client to not store host fingerprints.
1 parent 1a622c1 commit 813402d

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/target
2+
ssh_host_ed25519_key

src/main.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use core::net::{Ipv4Addr, SocketAddr};
2-
use std::sync::Arc;
2+
use std::{
3+
fs::{self, File},
4+
io::{self, Write},
5+
sync::Arc,
6+
};
37

48
use aws_lc_rs::signature::Ed25519KeyPair;
59
use clap::Parser;
@@ -16,6 +20,25 @@ async fn main() -> anyhow::Result<()> {
1620

1721
let args = Args::parse();
1822

23+
let host_key = Arc::new(if args.generate_host_key {
24+
match File::create_new(&args.host_key_file) {
25+
Ok(mut host_key_file) => {
26+
let Ok(host_key) = Ed25519KeyPair::generate() else {
27+
anyhow::bail!("failed to generate host key");
28+
};
29+
// FIXME ensure the host key is only readable by the ssh server user
30+
host_key_file.write_all(host_key.to_pkcs8v1()?.as_ref())?;
31+
host_key
32+
}
33+
Err(err) if err.kind() == io::ErrorKind::AlreadyExists => {
34+
anyhow::bail!("host key file `{}` already exists", &args.host_key_file);
35+
}
36+
Err(err) => return Err(err.into()),
37+
}
38+
} else {
39+
Ed25519KeyPair::from_pkcs8(&fs::read(args.host_key_file)?)?
40+
});
41+
1942
let listener = match (ListenFd::from_env().take_tcp_listener(0)?, args.port) {
2043
(Some(listener), None) => {
2144
listener.set_nonblocking(true)?;
@@ -30,11 +53,6 @@ async fn main() -> anyhow::Result<()> {
3053
};
3154
info!(addr = %listener.local_addr()?, "listening for connections");
3255

33-
let Ok(host_key) = Ed25519KeyPair::generate() else {
34-
anyhow::bail!("failed to generate host key");
35-
};
36-
let host_key = Arc::new(host_key);
37-
3856
loop {
3957
match listener.accept().await {
4058
Ok((stream, addr)) => {
@@ -54,4 +72,8 @@ async fn main() -> anyhow::Result<()> {
5472
struct Args {
5573
#[clap(short, long)]
5674
port: Option<u16>,
75+
#[clap(long, default_value = "ssh_host_ed25519_key")]
76+
host_key_file: String,
77+
#[clap(long)]
78+
generate_host_key: bool,
5779
}

0 commit comments

Comments
 (0)