Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,8 @@ jdbc-bridge/target/

# Java build output
jdbc-bridge/target/

# SSH tunnel test stack — private keys stay local
docker/ssh-bastion/test_key
docker/ssh-bastion/test_key.pem
docker/ssh-bastion/test_key_with_passphrase
134 changes: 134 additions & 0 deletions docker-compose-ssh-tunnel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: ssh-tunnel-test

services:
# ── SSH Bastion (linuxserver/openssh-server) ──
# Exposes port 2222 to host. Password + key auth both enabled.
# All databases are on the same internal network, NOT exposed to host.
ssh-bastion:
image: linuxserver/openssh-server:latest
container_name: sqlkit-ssh-bastion
hostname: bastion
ports:
- '2223:2222'
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai
- PASSWORD_ACCESS=true
- USER_PASSWORD=testpass
- USER_NAME=tester
- SUDO_ACCESS=false
- PUBLIC_KEY_FILE=/config/.ssh/authorized_keys
volumes:
- ./docker/ssh-bastion/authorized_keys:/config/.ssh/authorized_keys:ro
- ./docker/ssh-bastion/sshd_config:/config/sshd/sshd_config
- ./docker/ssh-bastion/custom-cont-init.d:/custom-cont-init.d:ro
networks:
- ssh-tunnel
healthcheck:
test:
- CMD-SHELL
- 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -i /config/.ssh/authorized_keys tester@localhost -p 2222 echo ok 2>/dev/null || exit 1'
interval: 10s
timeout: 5s
retries: 30
start_period: 5s

# ── PostgreSQL 17 (behind bastion, internal network only) ──
# Reachable from bastion via: pg-test:5432
# tester / testpass / testdb
pg-test:
image: postgres:17
container_name: sqlkit-ssh-pg
environment:
- POSTGRES_USER=tester
- POSTGRES_PASSWORD=testpass
- POSTGRES_DB=testdb
volumes:
- ssh-test-pg-data:/var/lib/postgresql/data
networks:
- ssh-tunnel
healthcheck:
test: [CMD-SHELL, pg_isready -U tester -d testdb]
interval: 10s
timeout: 5s
retries: 30

# ── MySQL 8.4 (behind bastion, internal network only) ──
# Reachable from bastion via: mysql-test:3306
# tester / testpass / testdb (root / testpass also works)
mysql-test:
image: mysql:8.4
container_name: sqlkit-ssh-mysql
environment:
- MYSQL_ROOT_PASSWORD=testpass
- MYSQL_DATABASE=testdb
- MYSQL_USER=tester
- MYSQL_PASSWORD=testpass
command: --mysql-native-password=OFF
volumes:
- ssh-test-mysql-data:/var/lib/mysql
networks:
- ssh-tunnel
healthcheck:
test: [CMD, mysqladmin, ping, -h, localhost, -uroot, -ptestpass]
interval: 10s
timeout: 5s
retries: 30

# ── SQL Server 2022 (behind bastion, internal network only) ──
# Reachable from bastion via: sqlserver-test:1433
# sa / TestPass!2024 / master
# NOTE: needs ~2GB RAM. MSSQL_PID=Developer keeps it license-clean.
sqlserver-test:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: sqlkit-ssh-sqlserver
environment:
- ACCEPT_EULA=Y
- MSSQL_PID=Developer
- MSSQL_SA_PASSWORD=TestPass!2024
networks:
- ssh-tunnel
healthcheck:
test:
- CMD-SHELL
- "/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P 'TestPass!2024' -Q 'SELECT 1' || exit 1"

interval: 15s
timeout: 10s
retries: 30
start_period: 30s

# ── Oracle 23ai Free (behind bastion, internal network only) ──
# Reachable from bastion via: oracle-test:1521
# Service: FREEPDB1 — sqlkit / testpass (root DBA: system / admin)
# NOTE: needs ~2GB RAM and takes 1-3 minutes on first init.
oracle-test:
image: gvenzl/oracle-free:23-slim
container_name: sqlkit-ssh-oracle
environment:
- ORACLE_PASSWORD=admin
- APP_USER=sqlkit
- APP_USER_PASSWORD=testpass
volumes:
- ssh-test-oracle-data:/opt/oracle/oradata
networks:
- ssh-tunnel
healthcheck:
test:
- CMD-SHELL
- healthcheck.sh

interval: 15s
timeout: 10s
retries: 40
start_period: 180s

volumes:
ssh-test-pg-data:
ssh-test-mysql-data:
ssh-test-oracle-data:

networks:
ssh-tunnel:
name: sqlkit-ssh-tunnel
56 changes: 56 additions & 0 deletions docker/ssh-bastion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# SSH Bastion Test Keys

Test keys for the SSH tunnel test stack (`docker-compose-ssh-tunnel.yml`).
Pattern mirrors DocKit's `event-search/docker/ssh-bastion/` setup.

## Files

| File | Purpose | Git Tracked |
|------|---------|-------------|
| `test_key` | ED25519 private key (no passphrase) | ❌ gitignored |
| `test_key.pub` | ED25519 public key | ✅ committed |
| `test_key.pem` | RSA-2048 PEM private key (no passphrase) | ❌ gitignored |
| `test_key.pem.pub` | RSA-2048 PEM public key | ✅ committed |
| `test_key_with_passphrase` | ED25519 private key (**passphrase: `testphrase`**) | ❌ gitignored |
| `test_key_with_passphrase.pub` | matching public key | ✅ committed |
| `authorized_keys` | all three public keys for the bastion container | ✅ committed |

## Start the stack

```bash
docker compose -f docker-compose-ssh-tunnel.yml up -d
# Oracle initializes for 1-3 minutes on first run
```

## Verify the bastion directly

```bash
ssh -i docker/ssh-bastion/test_key -p 2223 tester@localhost echo ok
# password auth also works: tester / testpass
```

## Databases behind the bastion (internal network only)

| Database | Host (as seen from the bastion) | Port | Credentials | Database/Service |
|---|---|---|---|---|
| PostgreSQL 17 | `pg-test` | 5432 | `tester` / `testpass` | `testdb` |
| MySQL 8.4 | `mysql-test` | 3306 | `tester` / `testpass` (root: `testpass`) | `testdb` |
| SQL Server 2022 | `sqlserver-test` | 1433 | `sa` / `TestPass!2024` | `master` |
| Oracle 23ai Free | `oracle-test` | 1521 | `sqlkit` / `testpass` | service `FREEPDB1` |

## SqlKit connection settings

**SSH Tunnel** (Advanced section, or an SSH profile):
- Host: `localhost`, Port: `2223`, Username: `tester`
- Auth: password `testpass` — or Private Key `./docker/ssh-bastion/test_key`
(ED25519), `./docker/ssh-bastion/test_key.pem` (RSA PEM), or
`./docker/ssh-bastion/test_key_with_passphrase` (passphrase `testphrase`)

**Database target** (host/port stay internal — the tunnel reaches them):
- PostgreSQL: `pg-test:5432`, tester / testpass, database `testdb`
- MySQL: `mysql-test:3306`, tester / testpass, database `testdb`
- SQL Server: `sqlserver-test:1433`, sa / TestPass!2024
- Oracle: `oracle-test:1521`, service `FREEPDB1`, sqlkit / testpass

⚠️ The database hosts are NOT `localhost` — inside the tunnel they resolve
from the bastion's network (`pg-test`, `mysql-test`, …).
3 changes: 3 additions & 0 deletions docker/ssh-bastion/authorized_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkPxVONClrcQRFdo91In/tY17Ljj/lLgmGSYBNkzZdm sqlkit-ssh-test
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWt/1OztSrJkoA3XQnJggQTL+Xt9llK7QvcJUEMOgp6S1u4AggciYBHgth9OEwvDsiMa4SvfKYx1WXgo4dfnTyQiOatfNnQ4AwjvfZFtqj+dpdHbmRquRBovuXqZrKsiXJdvFhCmTGB3y6onCmqittBXn1ixF0E4TErpRwFwxiyNyHL3Ta1vGxu8P4yMJZyrs/aZ/0xQ9OeapezqRdr69mn8+gLmMBPvCI0XSSNQGWNCN63u+Mspoz/SDgzes0yqbviYonxddRlUWRs7P6a/NZgKgbvlw3n8y0pEd8uVOEmikO37LYa3lRQOV7OArINz4/+DNMY01zvmYhb2jmfJvZ sqlkit-ssh-test-pem
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIInM1wahDl/gUVupvwzhLqrZoLsbICR5Bl97QyiF+9Z2 sqlkit-ssh-test-passphrase
3 changes: 3 additions & 0 deletions docker/ssh-bastion/custom-cont-init.d/fix-tcp-forward.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
sed -i 's/AllowTcpForwarding no/AllowTcpForwarding yes/' /config/sshd/sshd_config
echo "TCP forwarding enabled in /config/sshd/sshd_config"
123 changes: 123 additions & 0 deletions docker/ssh-bastion/sshd_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# $OpenBSD: sshd_config,v 1.105 2024/12/03 14:12:47 dtucker Exp $

# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.

# Include configuration snippets before processing this file to allow the
# snippets to override directives set in this file.
#Include /etc/ssh/sshd_config.d/*.conf

Port 2222
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to "no" here!
PasswordAuthentication yes
#PermitEmptyPasswords no

# Change to "no" to disable keyboard-interactive authentication. Depending on
# the system's configuration, this may involve passwords, challenge-response,
# one-time passwords or some combination of these and other methods.
#KbdInteractiveAuthentication yes

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin prohibit-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
#UsePAM no

#AllowAgentForwarding yes
# Feel free to re-enable these if your use case requires them.
AllowTcpForwarding yes
GatewayPorts no
X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
PidFile /config/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# override default of no subsystems
Subsystem sftp internal-sftp

# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding yes
# PermitTTY no
# ForceCommand cvs server
1 change: 1 addition & 0 deletions docker/ssh-bastion/test_key.pem.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWt/1OztSrJkoA3XQnJggQTL+Xt9llK7QvcJUEMOgp6S1u4AggciYBHgth9OEwvDsiMa4SvfKYx1WXgo4dfnTyQiOatfNnQ4AwjvfZFtqj+dpdHbmRquRBovuXqZrKsiXJdvFhCmTGB3y6onCmqittBXn1ixF0E4TErpRwFwxiyNyHL3Ta1vGxu8P4yMJZyrs/aZ/0xQ9OeapezqRdr69mn8+gLmMBPvCI0XSSNQGWNCN63u+Mspoz/SDgzes0yqbviYonxddRlUWRs7P6a/NZgKgbvlw3n8y0pEd8uVOEmikO37LYa3lRQOV7OArINz4/+DNMY01zvmYhb2jmfJvZ sqlkit-ssh-test-pem
1 change: 1 addition & 0 deletions docker/ssh-bastion/test_key.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkPxVONClrcQRFdo91In/tY17Ljj/lLgmGSYBNkzZdm sqlkit-ssh-test
1 change: 1 addition & 0 deletions docker/ssh-bastion/test_key_with_passphrase.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIInM1wahDl/gUVupvwzhLqrZoLsbICR5Bl97QyiF+9Z2 sqlkit-ssh-test-passphrase
Loading
Loading