diff --git a/src/Commands/DatabaseTunnelCommand.php b/src/Commands/DatabaseTunnelCommand.php
new file mode 100644
index 00000000..894ff147
--- /dev/null
+++ b/src/Commands/DatabaseTunnelCommand.php
@@ -0,0 +1,100 @@
+setName('database:tunnel')
+ ->addArgument('database', InputArgument::REQUIRED, 'The name of the database')
+ ->addArgument('port', InputArgument::OPTIONAL, 'The local port to serve connections on')
+ ->setDescription('Create a secure tunnel to a database, allowing local connections');
+ }
+
+ /**
+ * Execute the command.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ Helpers::ensure_api_token_is_available();
+
+ $databases = $this->vapor->databases();
+
+ if (! is_numeric($databaseId = $this->argument('database'))) {
+ $databaseId = $this->findIdByName($databases, $databaseId);
+ }
+
+ if (is_null($databaseId)) {
+ Helpers::abort('Unable to find a database with that name / ID.');
+ }
+
+ $jumpBox = $this->findCompatibleJumpBox(
+ $database = collect($databases)->firstWhere('id', $databaseId)
+ );
+
+ $localPort = $this->argument('port') ?? ($database['port'] - 1);
+
+ Helpers::line('Establishing secure tunnel to ['.$database['name'].'] on [localhost:'.$localPort.']...');
+
+ passthru(sprintf('ssh ec2-user@%s -i %s -o LogLevel=error -L %d:%s:%d -N',
+ $jumpBox['endpoint'],
+ $this->storeJumpBoxKey($jumpBox),
+ $localPort,
+ $database['endpoint'],
+ $database['port']
+ ));
+ }
+
+ /**
+ * Find a jump-box compatible with the database.
+ *
+ * @param array $database
+ * @return array
+ */
+ protected function findCompatibleJumpBox(array $database)
+ {
+ $jumpBoxes = collect($this->vapor->jumpBoxes())->filter(function ($jumpBox) use ($database) {
+ return $jumpBox['network_id'] == $database['network_id'];
+ });
+
+ $jumpBox = in_array($database['type'], ['rds', 'aurora-serverless'])
+ ? $jumpBoxes->first()
+ : $jumpBoxes->firstWhere('version', '>', 1);
+
+ if (is_null($jumpBox)) {
+ Helpers::abort('A compatible jumpbox is required in order to create a tunnel.');
+ }
+
+ return $jumpBox;
+ }
+
+ /**
+ * Store the private SSH key for the jump-box.
+ *
+ * @param array $jumpBox
+ * @return string
+ */
+ protected function storeJumpBoxKey(array $jumpBox)
+ {
+ file_put_contents(
+ $path = Helpers::home().'/.ssh/vapor-database-shell',
+ $this->vapor->jumpBoxKey($jumpBox['id'])['private_key']
+ );
+
+ chmod($path, 0600);
+
+ return $path;
+ }
+}
diff --git a/vapor b/vapor
index 4737a821..0ce0269c 100755
--- a/vapor
+++ b/vapor
@@ -109,6 +109,7 @@ $app->add(new Commands\DatabaseUsersCommand);
$app->add(new Commands\DatabaseUserCommand);
$app->add(new Commands\DatabaseDropUserCommand);
$app->add(new Commands\DatabaseShellCommand);
+$app->add(new Commands\DatabaseTunnelCommand);
$app->add(new Commands\DatabaseDeleteCommand);
// Caches...