mirror of
https://github.com/ekzhang/bore.git
synced 2024-12-22 16:15:21 +07:00
Add a configuration to allow forward to a different local host (#15)
* Add a configuration to allow forward to a different local host * Minor documentation / formatting change Co-authored-by: Eric Zhang <ekzhang1@gmail.com>
This commit is contained in:
parent
634af3f6af
commit
99fc4f7ddb
15
README.md
15
README.md
@ -47,7 +47,7 @@ You can forward a port on your local machine by using the `bore local` command.
|
||||
bore local 5000 --to bore.pub
|
||||
```
|
||||
|
||||
You can optionally pass in a `--port` option to pick a specific port on the remote to expose, although the command will fail if this port is not available.
|
||||
You can optionally pass in a `--port` option to pick a specific port on the remote to expose, although the command will fail if this port is not available. Also, passing `--local-host` allows you to expose a different host on your local area network besides the loopback address `localhost`.
|
||||
|
||||
The full options are shown below.
|
||||
|
||||
@ -59,14 +59,15 @@ USAGE:
|
||||
bore local [OPTIONS] --to <TO> <LOCAL_PORT>
|
||||
|
||||
ARGS:
|
||||
<LOCAL_PORT> The local port to listen on
|
||||
<LOCAL_PORT> The local port to expose
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-p, --port <PORT> Optional port on the remote server to select [default: 0]
|
||||
-s, --secret <SECRET> Optional secret for authentication
|
||||
-t, --to <TO> Address of the remote server to expose local ports to
|
||||
-V, --version Print version information
|
||||
-h, --help Print help information
|
||||
-l, --local-host <HOST> The local host to expose [default: localhost]
|
||||
-p, --port <PORT> Optional port on the remote server to select [default: 0]
|
||||
-s, --secret <SECRET> Optional secret for authentication
|
||||
-t, --to <TO> Address of the remote server to expose local ports to
|
||||
-V, --version Print version information
|
||||
```
|
||||
|
||||
### Self-Hosting
|
||||
|
@ -21,6 +21,9 @@ pub struct Client {
|
||||
/// Destination address of the server.
|
||||
to: String,
|
||||
|
||||
// Local host that is forwarded.
|
||||
local_host: String,
|
||||
|
||||
/// Local port that is forwarded.
|
||||
local_port: u16,
|
||||
|
||||
@ -33,7 +36,13 @@ pub struct Client {
|
||||
|
||||
impl Client {
|
||||
/// Create a new client.
|
||||
pub async fn new(local_port: u16, to: &str, port: u16, secret: Option<&str>) -> Result<Self> {
|
||||
pub async fn new(
|
||||
local_host: &str,
|
||||
local_port: u16,
|
||||
to: &str,
|
||||
port: u16,
|
||||
secret: Option<&str>,
|
||||
) -> Result<Self> {
|
||||
let mut stream = BufReader::new(connect_with_timeout(to, CONTROL_PORT).await?);
|
||||
|
||||
let auth = secret.map(Authenticator::new);
|
||||
@ -57,6 +66,7 @@ impl Client {
|
||||
Ok(Client {
|
||||
conn: Some(stream),
|
||||
to: to.to_string(),
|
||||
local_host: local_host.to_string(),
|
||||
local_port,
|
||||
remote_port,
|
||||
auth,
|
||||
@ -106,7 +116,7 @@ impl Client {
|
||||
}
|
||||
send_json(&mut remote_conn, ClientMessage::Accept(id)).await?;
|
||||
|
||||
let local_conn = connect_with_timeout("localhost", self.local_port).await?;
|
||||
let local_conn = connect_with_timeout(&self.local_host, self.local_port).await?;
|
||||
proxy(local_conn, remote_conn).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -14,9 +14,13 @@ struct Args {
|
||||
enum Command {
|
||||
/// Starts a local proxy to the remote server.
|
||||
Local {
|
||||
/// The local port to listen on.
|
||||
/// The local port to expose.
|
||||
local_port: u16,
|
||||
|
||||
/// The local host to expose.
|
||||
#[clap(short, long, value_name = "HOST", default_value = "localhost")]
|
||||
local_host: String,
|
||||
|
||||
/// Address of the remote server to expose local ports to.
|
||||
#[clap(short, long)]
|
||||
to: String,
|
||||
@ -49,12 +53,13 @@ async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
match args.command {
|
||||
Command::Local {
|
||||
local_host,
|
||||
local_port,
|
||||
to,
|
||||
port,
|
||||
secret,
|
||||
} => {
|
||||
let client = Client::new(local_port, &to, port, secret.as_deref()).await?;
|
||||
let client = Client::new(&local_host, local_port, &to, port, secret.as_deref()).await?;
|
||||
client.listen().await?;
|
||||
}
|
||||
Command::Server { min_port, secret } => {
|
||||
|
@ -24,7 +24,8 @@ async fn spawn_server(secret: Option<&str>) {
|
||||
/// Spawns a client with randomly assigned ports, returning the listener and remote address.
|
||||
async fn spawn_client(secret: Option<&str>) -> Result<(TcpListener, SocketAddr)> {
|
||||
let listener = TcpListener::bind("localhost:0").await?;
|
||||
let client = Client::new(listener.local_addr()?.port(), "localhost", 0, secret).await?;
|
||||
let local_port = listener.local_addr()?.port();
|
||||
let client = Client::new("localhost", local_port, "localhost", 0, secret).await?;
|
||||
let remote_addr = ([0, 0, 0, 0], client.remote_port()).into();
|
||||
tokio::spawn(client.listen());
|
||||
Ok((listener, remote_addr))
|
||||
@ -83,7 +84,7 @@ async fn mismatched_secret(
|
||||
async fn invalid_address() -> Result<()> {
|
||||
// We don't need the serial guard for this test because it doesn't create a server.
|
||||
async fn check_address(to: &str, use_secret: bool) -> Result<()> {
|
||||
match Client::new(5000, to, 0, use_secret.then(|| "a secret")).await {
|
||||
match Client::new("localhost", 5000, to, 0, use_secret.then(|| "a secret")).await {
|
||||
Ok(_) => Err(anyhow!("expected error for {to}, use_secret={use_secret}")),
|
||||
Err(_) => Ok(()),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user