Created
September 27, 2024 20:11
-
-
Save Eugeny/9eb1c607ffa64b17453c8006e252ae45 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::net::SocketAddr; | |
use std::sync::Arc; | |
use russh::client; | |
use tokio::net::TcpListener; | |
struct Client {} | |
#[async_trait::async_trait] | |
impl client::Handler for Client { | |
type Error = russh::Error; | |
async fn check_server_key( | |
&mut self, | |
_server_public_key: &russh_keys::key::PublicKey, | |
) -> Result<bool, Self::Error> { | |
Ok(true) | |
} | |
} | |
#[tokio::main] | |
async fn main() -> anyhow::Result<()> { | |
env_logger::init(); | |
let listener = TcpListener::bind("0.0.0.0:50000").await?; | |
log::info!("Listening on port 50000"); | |
loop { | |
// Accept incoming connections | |
let (mut socket, addr) = listener.accept().await?; | |
log::info!("Accepted connection from {:?}", addr); | |
let jump_host = "192.168.78.233"; | |
let target_host = "192.168.77.254"; | |
let jump_host_user = "root"; | |
let jump_host_pwd = std::env::args().collect::<Vec<_>>()[1].clone(); | |
// Spawn a new task to handle the connection | |
tokio::spawn(async move { | |
// Configure the SSH client | |
let mut config = client::Config::default(); | |
config.inactivity_timeout = Some(std::time::Duration::from_secs(3600 * 60)); | |
let config = Arc::new(config); | |
// Connect to the SSH server | |
let addr: Vec<SocketAddr> = tokio::net::lookup_host(format!("{}:{}", jump_host, 22)) | |
.await? | |
.collect(); | |
let mut jump_handle = | |
client::connect(config.clone(), addr.as_slice(), Client {}).await?; | |
// Authenticate | |
let is_authenticated = jump_handle | |
.authenticate_password(jump_host_user, jump_host_pwd) | |
.await?; | |
if !is_authenticated { | |
anyhow::bail!("failed to authenticate"); | |
} else { | |
log::info!("authenticated"); | |
} | |
let (mut reader, mut writer) = socket.split(); | |
let mut channel = jump_handle | |
.channel_open_direct_tcpip(target_host, 22, "localhost", 12345) | |
.await?; | |
let mut ch_writer = channel.make_writer(); | |
let mut ch_reader = channel.make_reader(); | |
let read_fut = async move { | |
let _ = tokio::io::copy(&mut reader, &mut ch_writer).await; | |
log::info!("Channel writer loop ended, channel will send EOF"); | |
}; | |
let write_fut = async move { | |
let _ = tokio::io::copy(&mut ch_reader, &mut writer).await; | |
log::info!("Channel reader loop ended, channel received EOF"); | |
}; | |
let _ = tokio::join!(read_fut, write_fut); | |
log::info!("Both copy loops ended"); | |
Ok(()) | |
}); | |
} | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment