dumbpipe

repository·main·Indexed 20 days ago

https://github.com/n0-computer/dumbpipe

A CLI tool for piping data over the network with NAT hole punching, built on the iroh library. It creates encrypted, location-transparent QUIC connections and serves as a modern, TLS-encrypted alternative to netcat. dumbpipe supports bidirectional data streams via stdin/stdout, TCP forwarding, and Unix socket tunneling, using endpoint tickets for secure connection establishment regardless of IP addresses.

Tokens
2.8K
Snippets
15
Records
17
Agent score
71%

What's inside dumbpipe

  1. Forward a development web server via TCP

    main

    To share a local web server (e.g., running on localhost:3000) with a remote colleague:

    1. On the host (Listener): Run dumbpipe listen-tcp pointing to the local web server port. This outputs a <ticket>.
    2. On the client (Connector): Run dumbpipe connect-tcp specifying a local port to listen on and the <ticket> from the host.
    3. Access: The client can now access the remote web server by browsing their own local port.
    # 1. The web server (e.g., npm run dev on port 3000)
    
    # 2. The dumbpipe listener (on the host)
    dumbpipe listen-tcp --host localhost:3000
    
    # 3. The dumbpipe connector (on the client)
    dumbpipe connect-tcp --addr 0.0.0.0:3001 <ticket>
    
    # 4. Access via http://localhost:3001
  2. Forward a Unix Socket application (e.g., Zellij)

    main

    You can tunnel applications that communicate over Unix sockets (like Zellij) across the internet.

    1. On the remote host: Identify the socket path (e.g., /tmp/zellij-0/<VERSION>/<session-name>) and run dumbpipe listen-unix --socket-path <path> to get a <ticket>.
    2. On the local machine: Create the local directory structure matching the remote version, then run dumbpipe connect-unix --socket-path <local-path> <ticket>.
    3. Attach: Set the ZELLIJ_SOCKET_DIR environment variable to your local directory and run zellij attach <session-name>.
    # 1. Remote host
    dumbpipe listen-unix --socket-path /tmp/zellij-0/0.42.2/remote-task-1234
    
    # 2. Local machine
    mkdir -p /tmp/zj-remote/0.42.1
    dumbpipe connect-unix --socket-path /tmp/zj-remote/0.42.1/remote-task-1234 <ticket>
    
    # 3. Attach
    ZELLIJ_SOCKET_DIR=/tmp/zj-remote zellij attach remote-task-1234
  3. Use the dumbpipe CLI to create a data pipe

    main

    The dumbpipe CLI allows you to create bidirectional data streams between two machines using an Iroh endpoint. One side acts as a listener and the other as a connector. Connections are established using a 32-byte endpoint ticket, which is independent of IP addresses and works through NATs and firewalls (falling back to relay servers if necessary).

    Key Concepts

    • Endpoint Ticket: A string containing the endpoint ID and necessary relay information used to connect.
    • Secret Key: You can specify a persistent secret key using the IROH_SECRET environment variable. If not provided, a random one is generated and printed to stderr.
    • Handshake: By default, dumbpipe performs a handshake to verify the connection. This can be bypassed using a custom ALPN.
  4. Understand the dumbpipe handshake mechanism

    main

    To ensure a stream is correctly created, dumbpipe uses a fixed-size handshake.

    • The side that initiates the connection (calling open_bi()) must first send the HANDSHAKE bytes.
    • The side that accepts the connection (calling accept_bi()) must consume these bytes to complete the handshake.
    /// The handshake to send when connecting.
    ///
    /// The side that calls open_bi() first must send this handshake, the side that
    /// calls accept_bi() must consume it.
    pub const HANDSHAKE: [u8; 5] = *b"hello";
  5. Share a terminal session with tty-share

    main

    To provide an end-to-end encrypted terminal sharing experience using tty-share, use dumbpipe to tunnel the connection.

    # On the server:
    $ dumbpipe listen-tcp --host localhost:8000 &
    $ tty-share
    
    # On the client(s):
    $ dumbpipe connect-tcp --addr localhost:8000 <ticket> &
    $ tty-share http://localhost:8000/s/local/
  6. Combine different listener and connector types

    main

    Dumbpipe allows mixing and matching different protocols. For example, you can listen on a remote Unix socket and connect to it via a local TCP port.

    # Machine A: Listen on a Unix socket
    dumbpipe listen-unix --socket-path /var/run/my-app.sock
    
    # Machine B: Connect to it via a local TCP port
    dumbpipe connect-tcp --addr 127.0.0.1:8080 <ticket>
  7. Stream video using ffmpeg and dumbpipe

    main

    You can stream video from one machine to another by piping ffmpeg output into dumbpipe listen and piping dumbpipe connect output into ffplay.

    Note: You must use the ticket generated by the sender side to connect on the receiver side.

    # --- SENDER SIDE ---
    # On Mac OS:
    ffmpeg -f avfoundation -r 30 -i "0" -pix_fmt yuv420p -f mpegts - | dumbpipe listen
    
    # On Linux:
    ffmpeg -f v4l2 -i /dev/video0 -r 30 -preset ultrafast -vcodec libx264 -tune zerolatency -f mpegts - | dumbpipe listen
    
    # --- RECEIVER SIDE ---
    # Use the ticket from the sender:
    # dumbpipe connect <ticket> | ffplay -f mpegts -fflags nobuffer -framedrop -
  8. Use custom ALPNs for iroh services

    main

    Expert users can specify a custom Application-Layer Protocol Negotiation (ALPN) string to interact with existing iroh services, such as the iroh-blobs protocol.

    # Interacting with iroh-blobs protocol
    echo request1.bin | dumbpipe connect <ticket> --custom-alpn utf8:/iroh-bytes/2 > response1.bin
  9. Configure common endpoint arguments

    main

    The following arguments are available to most dumbpipe commands:

    • --ipv4-addr <ADDR>: The IPv4 address the endpoint will listen on. Defaults to a random free port.
    • --ipv6-addr <ADDR>: The IPv6 address the endpoint will listen on. Defaults to a random free port.
    • --custom-alpn <ALPN>: An expert feature to use a custom ALPN.
      • To specify a UTF-8 string, prefix it with utf8: (e.g., utf8:my-protocol).
      • Otherwise, it is parsed as a hex string.
      • Note: Both sides must use the same ALPN. When using custom ALPN, the standard dumbpipe handshake is skipped.
    • -v, --verbose: Increase verbosity level.
  10. Use the DUMBPIPEV0 ALPN for protocol negotiation

    main

    When using dumbpipe over protocols that support ALPN (Application-Layer Protocol Negotiation), such as QUIC, use the constant ALPN to ensure the connecting sides agree on the dumbpipe protocol version.

    /// The ALPN for dumbpipe.
    pub const ALPN: &[u8] = b"DUMBPIPEV0";
  11. Generate an endpoint ticket

    main

    If you have a specific secret key (set via IROH_SECRET), you can generate a ticket that corresponds to that key without actually starting a listener. This is useful for pre-calculating connection strings.

    dumbpipe generate-ticket