or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-sshtunnel

Pure python SSH tunnels for creating secure connections through intermediate servers

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/sshtunnel@0.4.x

To install, run

npx @tessl/cli install tessl/pypi-sshtunnel@0.4.0

0

# SSH Tunnel

1

2

Pure python SSH tunnels for creating secure connections through intermediate servers. This library enables both local and remote port forwarding via SSH, supporting applications that need reliable SSH tunnel functionality without external dependencies beyond paramiko.

3

4

## Package Information

5

6

- **Package Name**: sshtunnel

7

- **Language**: Python

8

- **Installation**: `pip install sshtunnel`

9

10

## Core Imports

11

12

```python

13

import sshtunnel

14

```

15

16

Common patterns:

17

18

```python

19

from sshtunnel import SSHTunnelForwarder, open_tunnel

20

```

21

22

## Basic Usage

23

24

```python

25

from sshtunnel import SSHTunnelForwarder

26

27

# Create and start SSH tunnel

28

server = SSHTunnelForwarder(

29

ssh_address_or_host='ssh.example.com',

30

ssh_username='user',

31

ssh_password='secret',

32

remote_bind_address=('127.0.0.1', 3306),

33

local_bind_address=('127.0.0.1', 3307)

34

)

35

36

server.start()

37

print(f"Server connected via local port: {server.local_bind_port}")

38

39

# Use your tunnel connection here

40

# Connect to localhost:3307 to reach 127.0.0.1:3306 on remote server

41

42

server.stop()

43

```

44

45

Context manager usage:

46

47

```python

48

from sshtunnel import open_tunnel

49

50

with open_tunnel(

51

('ssh.example.com', 22),

52

ssh_username='user',

53

ssh_password='secret',

54

remote_bind_address=('127.0.0.1', 3306),

55

local_bind_address=('127.0.0.1', 3307)

56

) as tunnel:

57

print(f"Tunnel opened on local port: {tunnel.local_bind_port}")

58

# Use tunnel connection here

59

# Tunnel automatically closed when exiting context

60

```

61

62

## Architecture

63

64

The sshtunnel package is built around a few key components:

65

66

- **SSHTunnelForwarder**: Main class managing SSH connections and tunnel forwarding

67

- **Forward servers**: Background TCP/UNIX socket servers handling tunnel connections

68

- **Handler threads**: Individual connection handlers for concurrent tunnel usage

69

- **Transport layer**: Paramiko-based SSH transport with keepalive and authentication

70

71

## Capabilities

72

73

### SSH Tunnel Management

74

75

Main functionality for creating and managing SSH tunnels with full lifecycle control.

76

77

```python { .api }

78

class SSHTunnelForwarder:

79

def __init__(

80

self,

81

ssh_address_or_host=None,

82

ssh_config_file=SSH_CONFIG_FILE,

83

ssh_host_key=None,

84

ssh_password=None,

85

ssh_pkey=None,

86

ssh_private_key_password=None,

87

ssh_proxy=None,

88

ssh_proxy_enabled=True,

89

ssh_username=None,

90

local_bind_address=None,

91

local_bind_addresses=None,

92

logger=None,

93

mute_exceptions=False,

94

remote_bind_address=None,

95

remote_bind_addresses=None,

96

set_keepalive=5.0,

97

threaded=True,

98

compression=None,

99

allow_agent=True,

100

host_pkey_directories=None

101

): ...

102

103

def start(self): ...

104

def stop(self, force=False): ...

105

def close(self): ...

106

def restart(self): ...

107

```

108

109

### Tunnel Status and Properties

110

111

Access tunnel connection information and status.

112

113

```python { .api }

114

class SSHTunnelForwarder:

115

@property

116

def local_bind_port(self) -> int: ...

117

118

@property

119

def local_bind_ports(self) -> list[int]: ...

120

121

@property

122

def local_bind_host(self) -> str: ...

123

124

@property

125

def local_bind_hosts(self) -> list[str]: ...

126

127

@property

128

def local_bind_address(self) -> tuple: ...

129

130

@property

131

def local_bind_addresses(self) -> list[tuple]: ...

132

133

@property

134

def tunnel_bindings(self) -> dict: ...

135

136

tunnel_is_up: dict # Instance attribute - tunnel status mapping

137

138

@property

139

def is_active(self) -> bool: ...

140

141

is_alive: bool # Instance attribute - whether tunnels are alive

142

143

def check_tunnels(self): ...

144

def local_is_up(self, target: tuple) -> bool: ... # deprecated

145

```

146

147

### Simplified Tunnel Interface

148

149

Convenience function for common tunnel use cases with context manager support.

150

151

```python { .api }

152

def open_tunnel(*args, **kwargs) -> SSHTunnelForwarder:

153

"""

154

Open an SSH Tunnel, wrapper for SSHTunnelForwarder.

155

156

Parameters:

157

- ssh_address_or_host: SSH server address/hostname

158

- ssh_username: SSH username

159

- ssh_password: SSH password

160

- ssh_pkey: Private key file path or paramiko.PKey object

161

- ssh_port: SSH port (default: 22)

162

- remote_bind_address: Remote (host, port) tuple

163

- remote_bind_addresses: List of remote bind addresses

164

- local_bind_address: Local (host, port) tuple

165

- local_bind_addresses: List of local bind addresses

166

- debug_level: Log level for debugging

167

- skip_tunnel_checkup: Disable tunnel status checking

168

- Additional SSHTunnelForwarder parameters supported

169

170

Returns:

171

SSHTunnelForwarder instance configured as context manager

172

"""

173

```

174

175

### SSH Key Management

176

177

Utilities for loading SSH keys from various sources.

178

179

```python { .api }

180

class SSHTunnelForwarder:

181

@staticmethod

182

def get_agent_keys(logger=None) -> list:

183

"""Load public keys from SSH agent."""

184

185

@staticmethod

186

def get_keys(

187

logger=None,

188

host_pkey_directories=None,

189

allow_agent=False

190

) -> list:

191

"""Load keys from SSH agent or local directories."""

192

193

@staticmethod

194

def read_private_key_file(

195

pkey_file: str,

196

pkey_password=None,

197

key_type=None,

198

logger=None

199

):

200

"""Read private key file and return paramiko.PKey object."""

201

```

202

203

### Validation and Logging

204

205

Utility functions for address validation and logger configuration.

206

207

```python { .api }

208

def check_host(host: str): ...

209

def check_port(port: int): ...

210

def check_address(address): ...

211

def check_addresses(address_list: list, is_remote=False): ...

212

213

def create_logger(

214

logger=None,

215

loglevel=None,

216

capture_warnings=True,

217

add_paramiko_handler=True

218

) -> logging.Logger:

219

"""Create or configure logger with console handler."""

220

221

def address_to_str(address) -> str:

222

"""Convert address to string representation."""

223

224

def get_connection_id() -> int:

225

"""Generate unique connection ID for tunnel connections."""

226

```

227

228

## Exception Classes

229

230

```python { .api }

231

class BaseSSHTunnelForwarderError(Exception):

232

"""Base exception for SSHTunnelForwarder errors."""

233

234

class HandlerSSHTunnelForwarderError(BaseSSHTunnelForwarderError):

235

"""Exception for tunnel forwarder errors."""

236

```

237

238

## Constants

239

240

```python { .api }

241

__version__: str = '0.4.0'

242

__author__: str = 'pahaz'

243

244

SSH_TIMEOUT: float = 0.1 # Transport socket timeout

245

TUNNEL_TIMEOUT: float = 10.0 # Tunnel connection timeout

246

DEFAULT_LOGLEVEL: int = logging.ERROR # Default log level

247

TRACE_LEVEL: int = 1 # Trace log level

248

DEFAULT_SSH_DIRECTORY: str = '~/.ssh' # Default SSH directory

249

SSH_CONFIG_FILE: str # Path to SSH config file

250

```

251

252

## Usage Examples

253

254

### Multiple Tunnels

255

256

```python

257

from sshtunnel import SSHTunnelForwarder

258

259

# Create multiple tunnels at once

260

server = SSHTunnelForwarder(

261

ssh_address_or_host='ssh.example.com',

262

ssh_username='user',

263

ssh_password='secret',

264

remote_bind_addresses=[('127.0.0.1', 3306), ('127.0.0.1', 5432)],

265

local_bind_addresses=[('127.0.0.1', 3307), ('127.0.0.1', 5433)]

266

)

267

268

server.start()

269

print(f"MySQL tunnel: localhost:{server.local_bind_ports[0]}")

270

print(f"PostgreSQL tunnel: localhost:{server.local_bind_ports[1]}")

271

server.stop()

272

```

273

274

### SSH Key Authentication

275

276

```python

277

from sshtunnel import SSHTunnelForwarder

278

279

# Using SSH key file

280

server = SSHTunnelForwarder(

281

ssh_address_or_host='example.com',

282

ssh_username='user',

283

ssh_pkey='/home/user/.ssh/id_rsa',

284

ssh_private_key_password='key_password', # if key is encrypted

285

remote_bind_address=('192.168.1.100', 22),

286

local_bind_address=('127.0.0.1', 2222)

287

)

288

289

# Using SSH agent keys

290

server = SSHTunnelForwarder(

291

ssh_address_or_host='example.com',

292

ssh_username='user',

293

allow_agent=True,

294

remote_bind_address=('192.168.1.100', 22)

295

)

296

```

297

298

### Custom Logger Configuration

299

300

```python

301

import logging

302

from sshtunnel import SSHTunnelForwarder, create_logger

303

304

# Create custom logger

305

logger = create_logger(loglevel=logging.DEBUG)

306

307

server = SSHTunnelForwarder(

308

ssh_address_or_host='example.com',

309

ssh_username='user',

310

ssh_password='secret',

311

remote_bind_address=('127.0.0.1', 3306),

312

logger=logger

313

)

314

```

315

316

### Error Handling

317

318

```python

319

from sshtunnel import (

320

SSHTunnelForwarder,

321

BaseSSHTunnelForwarderError,

322

HandlerSSHTunnelForwarderError

323

)

324

325

try:

326

server = SSHTunnelForwarder(

327

ssh_address_or_host='example.com',

328

ssh_username='user',

329

ssh_password='wrong_password',

330

remote_bind_address=('127.0.0.1', 3306),

331

mute_exceptions=False # Enable exception raising

332

)

333

server.start()

334

except BaseSSHTunnelForwarderError as e:

335

print(f"SSH tunnel error: {e}")

336

except HandlerSSHTunnelForwarderError as e:

337

print(f"Tunnel handler error: {e}")

338

```

339

340

### Proxy Support

341

342

```python

343

from sshtunnel import SSHTunnelForwarder

344

345

# Using HTTP proxy

346

server = SSHTunnelForwarder(

347

ssh_address_or_host='target.example.com',

348

ssh_username='user',

349

ssh_password='secret',

350

ssh_proxy=('proxy.example.com', 8080),

351

remote_bind_address=('127.0.0.1', 3306)

352

)

353

354

# Using ProxyCommand from SSH config

355

server = SSHTunnelForwarder(

356

ssh_address_or_host='target.example.com',

357

ssh_username='user',

358

ssh_config_file='~/.ssh/config', # Contains ProxyCommand

359

ssh_proxy_enabled=True,

360

remote_bind_address=('127.0.0.1', 3306)

361

)

362

```