Tarsnap / spiped

Spiped is a utility for creating symmetrically encrypted and authenticated pipes between socket addresses.
http://www.tarsnap.com/spiped.html
Other
858 stars 56 forks source link

local interface for outgoing connections #351

Closed nerijus closed 2 years ago

nerijus commented 2 years ago

I need to use non default interface for outgoing connections. telnet has -b option for it:

$ telnet 10.10.10.63 8080
Trying 10.10.10.63...

telnet: connect to address 10.10.10.63: Connection timed out

$ telnet -b 10.15.0.2 10.10.10.63 8080
Trying 10.10.10.63...

Connected to 10.10.10.63.

Is it possible when using spiped?

nerijus commented 2 years ago

I was able to find a workaround using iptables:

iptables -t nat -A POSTROUTING --destination 10.10.10.63/32 -j SNAT --to-source 10.15.0.2

but it would still be nice if spiped supported it :)

cperciva commented 2 years ago

There is no support for this yet, but it should be easy to add. Are you interested in writing a patch?

nerijus commented 2 years ago

I could try if you guide me where in the code (I took a look at the code already).

cperciva commented 2 years ago

Ok, there's unfortunately a lot of plumbing to get the bind address where it needs to go, but it's reasonably straightforward despite being annoying how many places need to be touched.

You'll want to add an option (-b sounds good to me) to the getopt loop in spiped's main.c. Pass it to sock_resolve and then the struct sock_addr * needs to be:

  1. Passed as a new parameter to dispatch_accept;
  2. Stored as a new field in struct accept_state;
  3. Passed as a new parameter to proto_conn_create;
  4. Passed as a parameter to network_connect_bind which is the same as network_connect except with an added argument;
  5. Stored as a new field in struct connect_cookie;
  6. Passed as a parameter to sock_connect_bind_nb which is the same as sock_connect_nb except with an added argument;

and finally that function can call bind after creating a socket.

Once you've done this, you can also add it to spipe with far less work: Just add the option to the getopt loop and pass it to proto_conn_create.

nerijus commented 2 years ago

Thank you for the guide!

  1. As -b is optional, can I pass NULL as struct sock_addr ** sas_b (a new parameter) to dispatch_accept when -b is not used?
cperciva commented 2 years ago

I would pass NULL to indicate that we don't want to bind to any specific address.

Also, pass in a struct sock_addr *, not a ** -- you'll get back a ** (which is a list of addresses) from sock_resolve but we can only bind to one address so just ignore any extras (possibly with a warning message).

nerijus commented 2 years ago

Thank you for easy to follow and complete guide. I created PR https://github.com/Tarsnap/spiped/pull/353 What is missing - did not touch the man files, and spiped -b 127.0.0.1 does not work - spiped: Address must contain port number: 127.0.0.1. spiped -b 127.0.0.1:2222 works.

cperciva commented 2 years ago

Thanks! I've left some comments on the patch, but at first glance it looks like it's all fairly minor fixes needed.

Good catch about the port number. We could probably add :0 to the bind address if it doesn't have a port number specified, to tell the OS to pick any port number it likes.

gperciva commented 2 years ago

Merged in #364.