SSH
Local Port Forwarding
Open a tunnel from the client to a server. AKA trying to point your web browser at a private web server.
Format:
ssh -L <local_port>:<remote_addr>:<remote_port> <server>
If you want to access something on the remote server itself, use localhost as the remote_addr
Examples
Port forward a postgres database running on the remote:
ssh -L 5432:localhost:5432 myuser@myserver
Access a private database from an admin host:
ssh -L 5432:database.rds.amazonaws.com:5432 myuser@admin-host
Remote Port Forwarding
Format:
ssh -R <remote_port>:<local_addr>:<local_port> <server>
Open a tunnel from the server to a client. AKA trying to share a local database with an application on the server
!> [!NOTE]
sshd must be configured with
GatewayPorts yesin order to accept incoming connections.
Examples
Port forward a local database instance to the server:
ssh -R 5432:localhost:5432 myuser@myserver
Allow access to an internal website using your computer as a proxy:
ssh -R 8080:jira.mycorp.com:80 myuser@myserver
Dynamic Port Forwarding
Creates a SOCKS compatible proxy that operates on Layer 7, meaning it is not constrained by protocols
Format:
ssh -D <local_port> <server>
Using a SOCKS proxy depends on your application configuration. E.g. Firefox has proxy settings.
Linux/macOS support setting these environment variables:
ssh -D 8080 myuser@myserver
export http_proxy="socks5://127.0.0.1:8080"
export https_proxy="socks5://127.0.0.1:8080"
.ssh/config
Local Forwarding
Format:
LocalForward <local_port> <remote_addr>:<remote_port>
Examples:
Host server01
HostName myserver01.internal.company.com
User user
LocalForward 5432 localhost:5432
LocalForward 8080 privateserver.internal.company.com:80
Remote Forwarding
Format:
RemoteForward <remote_port> <local_addr>:<local_port>
Examples:
Host server01
HostName myserver01.internal.company.com
User user
RemoteForward 5432 localhost:5432
RemoteForward 8080 jira.internal.company.com:80
Dynamic Forwarding
Host my-proxy
HostName my-proxy.internal.company.com
User user
DynamicForward 8080
Kubernetes
AWS Session Manager
socat
Socket concatenation. Allows making pipes between addresses.
Addresses
Addresses in socat have three components:
- address type
- zero or more required address parameters
- zero or more address options
Types
TCP4
Format:
TCP4:<addr>:<port>
UDP_RECVFROM
Sets up a UDP listener to receive traffic and potentially respond.
Format:
UDP_RECVFROM:<port>
TCP4-LISTEN
Sets up a TCP4 listener to receive traffic and potentially respond.
Format:
TCP4-LISTEN:localhost:8080
GOPEN
Generic open of a file. If an address has a slash in it and no type specified, it is assumed to be this type.
Format:
GOPEN:/tmp/readdata
- CREATE
- EXEC
- STDIN
- STDOUT
- STDIO - also aliased to
- - PIPE
- PTY
- UDP4
Option Groups
The options available to the different address types are dependent on what option groups that type is in.
Sockets
Includes TCP4, TCP4-LISTEN, UDP, UDP_RECVFROM, GOPEN
Open
Includes GOPEN, PIPE
Single vs Dual Addresses
Single Addresses
Single addresses are the more common type of address. In them, the address is both the source and the sink for that part of the socat command.
For example, the following command listens on port 8080 and sends all traffic received to www.example.com
socat TCP4-LISTEN:8080 TCP4:www.example.com:80
flowchart LR
TCP4-LISTEN
TCP4
TCP4-LISTEN <--> TCP4
Unidirectional Mode
You can enable unidirectional channels with the -u cli option:
socat -u GOPEN:/usr/share/example.txt STDOUT
flowchart LR
GOPEN
STDOUT
GOPEN --> STDOUT
To reverse the direction, use -U
socat -U GOPEN:/usr/share/example.txt STDIN
flowchart RL
GOPEN
STDIN
STDIN --> GOPEN
Dual Addresses
Dual addresses contain two separate address definitions: one for reading and the other for writing.
Dual addresses are denoted by double exclamation points, which may require escaping in terminals:
<read_addr>\!\!<write_addr>
The following example uses the readline utility to consume some text from the user, transform it using a shell command, and then write the results to a file:
socat -d -d READLINE\!\!OPEN:file.txt,creat,trunc SYSTEM:'read stdin; echo $stdin'
---
config:
flowchart:
curve: cardinal
---
flowchart TB
subgraph ADDR1
direction TB
READLINE
OPEN
READLINE ~~~~ OPEN
end
direction TB
subgraph ADDR2
SYSTEM
end
READLINE --> SYSTEM
SYSTEM --> OPEN
Lifecycle
- Initialization - parses CLI options and sets up logging
- Opening - opens address 1 and then address 2. Opening addresses is usually a blocking operation and might require authentication.
- Transfer - reads and writes from one end to the other (using Linux
select) - Closing - when one bytestream sends an EOF, socat will try to close the write part of the other bytestream. After some delay socat will forcibly close ones that don’t close gracefully.