From 62c058150f0045fd4bf97224857bfc9ce7dbad51 Mon Sep 17 00:00:00 2001 From: Max Claus Nunes Date: Sun, 21 Mar 2021 21:52:40 -0300 Subject: [PATCH] Support new ssh keys --- .github/workflows/test.yml | 4 ++ CONTRIBUTING.md | 7 ++ README.md | 3 +- docker-compose.yml | 32 +++++++-- package-lock.json | 16 ++--- package.json | 2 +- spec/databases/config.ts | 2 +- spec/db.spec.ts | 82 +++++++++++++++++++++++- spec/ssh_files/id_ecdsa | 12 ++++ spec/ssh_files/id_ed25519 | 7 ++ spec/ssh_files/id_rsa | 49 ++++++++++++++ spec/ssh_files/id_rsa_passphrase | 39 +++++++++++ spec/ssh_files/pub/id_ecdsa.pub | 1 + spec/ssh_files/pub/id_ed25519.pub | 1 + spec/ssh_files/pub/id_rsa.pub | 1 + spec/ssh_files/pub/id_rsa_passphrase.pub | 1 + src/server.ts | 1 + src/tunnel.ts | 14 ++-- 18 files changed, 249 insertions(+), 25 deletions(-) create mode 100644 spec/ssh_files/id_ecdsa create mode 100644 spec/ssh_files/id_ed25519 create mode 100644 spec/ssh_files/id_rsa create mode 100644 spec/ssh_files/id_rsa_passphrase create mode 100644 spec/ssh_files/pub/id_ecdsa.pub create mode 100644 spec/ssh_files/pub/id_ed25519.pub create mode 100644 spec/ssh_files/pub/id_rsa.pub create mode 100644 spec/ssh_files/pub/id_rsa_passphrase.pub diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 57cd356..c54b298 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,6 +12,7 @@ jobs: env: redshift-version: redshift + SSH_HOST: localhost strategy: matrix: @@ -56,6 +57,9 @@ jobs: - name: Create SQLServer Container run: docker run --rm -d --name sqlserver -p 1433:1433 -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Password12!" -e "MSSQL_COLLATION=${{ matrix.sqlserver-collation }}" -v ${GITHUB_WORKSPACE}/spec/databases/sqlserver/schema:/docker-entrypoint-initdb.d mcr.microsoft.com/mssql/server:2017-latest + - name: Create OpenSSH-Server Container + run: docker run --rm -d --name openssh-server -p 2222:2222 -e "DOCKER_MODS=linuxserver/mods:openssh-server-ssh-tunnel" -e "PASSWORD_ACCESS=true" -e "USER_PASSWORD=password" -e "PUBLIC_KEY_DIR=/ssh_files/pub" -v ${GITHUB_WORKSPACE}/spec/ssh_files:/ssh_files ghcr.io/linuxserver/openssh-server + - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 168babc..f915fcc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,13 @@ It will bring up some databases such as MySQL and PostgreSQL and run all the tes docker-compose run --rm test ``` +Or to start the container and run the test command manually from there: + +```shell +docker-compose run --rm test bash +npm test +``` + #### Without Docker You will need to bring up all the databases then run the tests through: diff --git a/README.md b/README.md index 823abae..61f09f4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ The common code used by all sqlectron clients. -> Requires node 10 or higher. +> Requires node v10 or higher. +> For ed25519 ssh support it requires node v12. ## How to pronounce diff --git a/docker-compose.yml b/docker-compose.yml index 6d05bb0..6cd0eae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -48,18 +48,40 @@ services: ports: - 7000 # cluster - 9042 # native + ports: + - 9042:9042 test: - image: node:10.15.0 + image: node:12.21.0 command: npm test working_dir: /usr/src/app environment: DB_ADAPTERS: mysql,postgresql,cassandra MYSQL_ENV_MYSQL_USER: root MYSQL_ENV_MYSQL_PASSWORD: password + MYSQL_HOST: mysql + SSH_HOST: openssh-server volumes: - .:/usr/src/app - links: - - mysql:mysql - - postgres:postgres - - cassandra:cassandra + - /usr/src/app/node_modules + depends_on: + - mysql + - postgres + - cassandra + - openssh-server + + openssh-server: + image: ghcr.io/linuxserver/openssh-server + environment: + DOCKER_MODS: linuxserver/mods:openssh-server-ssh-tunnel + PASSWORD_ACCESS: 'true' + USER_PASSWORD: password + USER_NAME: sqlectron + PUBLIC_KEY_DIR: /ssh_files/pub + ports: + - 2222:2222 + restart: unless-stopped + depends_on: + - mysql + volumes: + - ./spec/ssh_files:/ssh_files diff --git a/package-lock.json b/package-lock.json index 36858c9..97b33a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3595,20 +3595,20 @@ "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==" }, "ssh2": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.5.tgz", - "integrity": "sha1-x3gezS7OcwSiU89iD6taXCK7IjU=", + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.8.9.tgz", + "integrity": "sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==", "requires": { - "ssh2-streams": "~0.1.18" + "ssh2-streams": "~0.4.10" } }, "ssh2-streams": { - "version": "0.1.20", - "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.1.20.tgz", - "integrity": "sha1-URGNFUVV31Rp7h9n4M8efoosDjo=", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz", + "integrity": "sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==", "requires": { "asn1": "~0.2.0", - "semver": "^5.1.0", + "bcrypt-pbkdf": "^1.0.2", "streamsearch": "~0.1.2" } }, diff --git a/package.json b/package.json index bb9fc38..a37a6bd 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "portfinder": "^1.0.28", "sql-query-identifier": "^1.1.0", "sqlite3": "^5.0.1", - "ssh2": "^0.5.0" + "ssh2": "^0.8.9" }, "devDependencies": { "@masterodin/publisher": "^0.7.0", diff --git a/spec/databases/config.ts b/spec/databases/config.ts index 39a57ea..fdcecc6 100644 --- a/spec/databases/config.ts +++ b/spec/databases/config.ts @@ -20,7 +20,7 @@ const mysql = new ConnectionString(process.env.MYSQL_DSN, { user: 'root', password: 'Password12!', path: ['sqlectron'], - hosts: [{ name: 'localhost', port: 3306 }], + hosts: [{ name: process.env.MYSQL_HOST || 'localhost', port: 3306 }], }); const mariadb = new ConnectionString(process.env.MARIADB_DSN, { user: 'root', diff --git a/spec/db.spec.ts b/spec/db.spec.ts index ebac930..f3b94bb 100644 --- a/spec/db.spec.ts +++ b/spec/db.spec.ts @@ -1,3 +1,5 @@ +import path from 'path'; +import { execSync } from 'child_process'; import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; import config from './databases/config'; @@ -8,7 +10,7 @@ import { clearSelectLimit, setSelectLimit } from '../src/database'; import { versionCompare } from '../src/utils'; import type { Adapter } from '../src/adapters'; import type { Database } from '../src/database'; -import type { Server } from '../src/server'; +import type { Server, ServerConfig } from '../src/server'; chai.use(chaiAsPromised); @@ -54,6 +56,8 @@ describe('db', () => { const dbSchema = dbSchemas[dbAdapter]; describe(dbAdapter, () => { + const database = config[dbAdapter].database + describe('.connect', () => { it(`should connect into a ${dbAdapter} database`, () => { const serverInfo = { @@ -94,6 +98,82 @@ describe('db', () => { return expect(dbConn.connect()).to.not.be.rejected; }) + + describe('connect with ssh', () => { + const assertSSHConnection = async (dbConn: Database) => { + await dbConn.connect(); + + // assert beyond a simplly opening the connection, + // but also ensure it can run a query + const databases = await dbConn.listDatabases(); + expect(databases.length).to.be.above(0); + }; + + it('should connect into server using ssh with password', () => { + const serverInfo: ServerConfig = { + ...config[dbAdapter], + name: dbAdapter, + adapter: dbAdapter, + }; + + serverInfo.ssh = { + host: process.env.SSH_HOST, + port: 2222, + user: 'sqlectron', + password: 'password', + }; + + const serverSession = db.createServer(serverInfo); + const dbConn = serverSession.createConnection(database); + + return expect(assertSSHConnection(dbConn)).to.not.be.rejected; + }); + + const keyTypes = ['rsa', 'ecdsa', 'ed25519'] + + for (const keyType of keyTypes) { + it(`should connect into server using ssh with private key of type ${keyType}`, () => { + const serverInfo: ServerConfig = { + ...config[dbAdapter], + name: dbAdapter, + adapter: dbAdapter, + }; + + serverInfo.ssh = { + host: process.env.SSH_HOST, + port: 2222, + user: 'sqlectron', + privateKey: path.join(__dirname, 'ssh_files/id_' + keyType), + }; + + const serverSession = db.createServer(serverInfo); + const dbConn = serverSession.createConnection(database); + + return expect(assertSSHConnection(dbConn)).to.not.be.rejected; + }); + } + + it('should connect into server using ssh agent with passphrase', () => { + const serverInfo: ServerConfig = { + ...config[dbAdapter], + name: dbAdapter, + adapter: dbAdapter, + }; + + serverInfo.ssh = { + host: process.env.SSH_HOST, + port: 2222, + user: 'sqlectron', + passphrase: 'password', + privateKey: path.join(__dirname, 'ssh_files/id_rsa_passphrase'), + }; + + const serverSession = db.createServer(serverInfo); + const dbConn = serverSession.createConnection(database); + + return expect(assertSSHConnection(dbConn)).to.not.be.rejected; + }); + }) }); describe('given is already connected', () => { diff --git a/spec/ssh_files/id_ecdsa b/spec/ssh_files/id_ecdsa new file mode 100644 index 0000000..55669a5 --- /dev/null +++ b/spec/ssh_files/id_ecdsa @@ -0,0 +1,12 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS +1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBPacz4PEYvCTCR0dpnH98hDQtzv7X +yaW7XXK4mZJFbZS0zFjs+gp3zgvb3cAc2HYLGi8bX4sbGuC1M5zxDAt0dSQAIZiykwu5qt +x9oPfJkx/Pn9TOXM6tOlPbk1dRLEp2vRz6zemw/C3bkRv4LI+vMOKgze/T6z1r6D+6yYhF +3ECyaLkAAAEQxJ7wV8Se8FcAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ +AAAIUEAT2nM+DxGLwkwkdHaZx/fIQ0Lc7+18mlu11yuJmSRW2UtMxY7PoKd84L293AHNh2 +CxovG1+LGxrgtTOc8QwLdHUkACGYspMLuarcfaD3yZMfz5/UzlzOrTpT25NXUSxKdr0c+s +3psPwt25Eb+CyPrzDioM3v0+s9a+g/usmIRdxAsmi5AAAAQgFlSgF2BdwLFtoXVIyzg+K1 +ttU15zq3ltfF4KnAKm19FeLlevtk8za9ZLiGJGwReTXDHWQOPn6F1XTGSd6NAWCwugAAAB +Fyb290QGI5YzgxNmIwNmY5ZAE= +-----END OPENSSH PRIVATE KEY----- diff --git a/spec/ssh_files/id_ed25519 b/spec/ssh_files/id_ed25519 new file mode 100644 index 0000000..2acce05 --- /dev/null +++ b/spec/ssh_files/id_ed25519 @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDjMo8Cwwi2Sh3c9SRepKei3uC/CJMquktSmynF7CeoewAAAJjAYXafwGF2 +nwAAAAtzc2gtZWQyNTUxOQAAACDjMo8Cwwi2Sh3c9SRepKei3uC/CJMquktSmynF7Ceoew +AAAECbyICBKd7XbZRfIvcdzX3hw+0oEVuic9gzuYGIKyGPe+MyjwLDCLZKHdz1JF6kp6Le +4L8Ikyq6S1KbKcXsJ6h7AAAAEXJvb3RANWI2ODE4MTYyNTU3AQIDBA== +-----END OPENSSH PRIVATE KEY----- diff --git a/spec/ssh_files/id_rsa b/spec/ssh_files/id_rsa new file mode 100644 index 0000000..79cb69e --- /dev/null +++ b/spec/ssh_files/id_rsa @@ -0,0 +1,49 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +-----END OPENSSH PRIVATE KEY----- diff --git a/spec/ssh_files/id_rsa_passphrase b/spec/ssh_files/id_rsa_passphrase new file mode 100644 index 0000000..d53d2a5 --- /dev/null +++ b/spec/ssh_files/id_rsa_passphrase @@ -0,0 +1,39 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +ts1Ai/ZyhOuEMhPw/SREgP7YK1o= +-----END OPENSSH PRIVATE KEY----- diff --git a/spec/ssh_files/pub/id_ecdsa.pub b/spec/ssh_files/pub/id_ecdsa.pub new file mode 100644 index 0000000..375ee8a --- /dev/null +++ b/spec/ssh_files/pub/id_ecdsa.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAE9pzPg8Ri8JMJHR2mcf3yENC3O/tfJpbtdcriZkkVtlLTMWOz6CnfOC9vdwBzYdgsaLxtfixsa4LUznPEMC3R1JAAhmLKTC7mq3H2g98mTH8+f1M5czq06U9uTV1EsSna9HPrN6bD8LduRG/gsj68w4qDN79PrPWvoP7rJiEXcQLJouQ== sqlectron_ecdsa diff --git a/spec/ssh_files/pub/id_ed25519.pub b/spec/ssh_files/pub/id_ed25519.pub new file mode 100644 index 0000000..b4b9150 --- /dev/null +++ b/spec/ssh_files/pub/id_ed25519.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMyjwLDCLZKHdz1JF6kp6Le4L8Ikyq6S1KbKcXsJ6h7 sqlectron_ed25519 diff --git a/spec/ssh_files/pub/id_rsa.pub b/spec/ssh_files/pub/id_rsa.pub new file mode 100644 index 0000000..a0617a5 --- /dev/null +++ b/spec/ssh_files/pub/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCcUau1R24kaxBSTv/U6A2K3IlY2fE6Dgs+U+flImOzp+sSzsM4HlwA/dH1a9KAzH/3dVW7U5Oymnz6WiVG1NeUN0OARxYSa6sFZBQBElXf6CNh6emYYaENPFtUq8ckJR6+EDXbWPQV8XA63Q5GWzgai398pN+xcOdyQMp9R97GF7U5bGfpfRmT92lFpsRjsgziWSM0Ppp1BbfVUsd5W+YG0nX7Mhc23hSBVrrBsQYNRaS/nZ8WNjXfCa4DFg6vCY2nDGz+kfoKbF/j5OsgFDY4bjgUDQYItP3nrnxGqrKGOeB+O4KlwXFuu3ksuSGMPkL3N8kH6ksZw+M4XyP65dCtcSu4/Gt+dhYT+m9jXEtYHaEn2WkQCotcWh5Me4jXQWcNHFhtzPCWevn4Yvx8eLtxDRYaS5AXCh+b0YHuiMPXybDKUbSSskcbVNd9OeI2eL41EL7/CKLFJcqGzTyuPTabKu9zU08gnYyUwcXebYCsMw/YW6WVJ6XvuGMeBGCLr+5qcKMkcWKLak90NhQQycqUg14/vtyKJKcN/H7kkx+gFTI+PExNtMXEuRrNw5et5ZhaaubWhQkOmXJvi4AwRExLkUB3IQKKjDOxD6UbceZZ7EDc7Cr+lZi2OpfD2hX+V2vGFE7Mqr9GvAibZKmSw3zYj6h5ICIAl0+CBE7ElGTM7w== sqlectron_rsa diff --git a/spec/ssh_files/pub/id_rsa_passphrase.pub b/spec/ssh_files/pub/id_rsa_passphrase.pub new file mode 100644 index 0000000..658ba07 --- /dev/null +++ b/spec/ssh_files/pub/id_rsa_passphrase.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCzZ9kFYjg07ksVGLmQXLDbfJBuPDpFYEAJtenaYF0WBVUJEu7xRtnyFwKL+N0ATnNgSrs4FxVo2GxXhEGzhgdpJUdBF8G5yt3AFl6/ZOlMiLNHQYgUBsvSnqwHfU0A2N87ZvQ0/XReqTWJvQ4cZySNgMCMnkvcQN5QtYAR1FYtLiQ6VEXDIMzF/7Oq1LJ7Olp8itpjyF3SBkiSjW5j8C7KSuGwaGeq4cm5Dstfp3SIVzCJ1F8fiuNWduR69n9ztM5jKbs6FdPdKbMa916qsXHELyLY7cbd4UWrZCL4QoDPqFJctfBnbFTpmfG9W5v2ZkGg6r+dKb3G3qy1nmWczWxY2v/q6v0ViZ5BMNmXseUY6eh/zwPaPROasHbXQ6taAVTFfvNTuC6UNQyDtkYGkBXQlNDrJVGPVT45f9RkYUF4mza5ySu0Fr2X58WhTsplJP1BlmyfFk9XiTtcDrFeRfplwXZDnQz14Op58khppeRVxgd10zQOFlhTV2APiTkTIIU= sqlectron_rsa_passphrase diff --git a/src/server.ts b/src/server.ts index 4004c16..c820507 100644 --- a/src/server.ts +++ b/src/server.ts @@ -22,6 +22,7 @@ export interface LegacyServerConfig { privateKey?: string; host: string; port: number; + useAgent?: boolean; }; ssl?: { key?: string; diff --git a/src/tunnel.ts b/src/tunnel.ts index d4bfb56..3126d04 100644 --- a/src/tunnel.ts +++ b/src/tunnel.ts @@ -13,8 +13,6 @@ interface TunnelConfig extends ConnectConfig { dstHost: string; dstPort: number; sshPort: number; - localHost: string; - localPort: number; } export default function (serverInfo: ServerConfig): Promise { @@ -69,7 +67,9 @@ export default function (serverInfo: ServerConfig): Promise { }); logger().debug('connecting ssh tunnel server'); - server.listen(config.localPort, config.localHost, () => { + + // Grab an arbitrary unused port + server.listen(0, 'localhost', () => { logger().debug('connected ssh tunnel server'); resolve(server); }).on('error', (err) => { @@ -98,13 +98,11 @@ async function configTunnel(serverInfo: ServerConfig) { sshPort: 22, srcPort: 0, srcHost: 'localhost', - localHost: 'localhost', - localPort: await getPort(), }; + if (serverInfo.ssh.password) config.password = serverInfo.ssh.password; if (serverInfo.ssh.passphrase) config.passphrase = serverInfo.ssh.passphrase; - if (serverInfo.ssh.privateKey) { - config.privateKey = await readFile(serverInfo.ssh.privateKey); - } + if (serverInfo.ssh.privateKey) config.privateKey = await readFile(serverInfo.ssh.privateKey); + return config; }