From 1fef6ba505cf383de2d4dc038e1aa7826b65cb36 Mon Sep 17 00:00:00 2001 From: Chris de Bruin Date: Fri, 27 Jan 2023 10:07:24 +0100 Subject: [PATCH 1/6] Allow use of bastion host --- README.md | 15 +++++++++++++-- lib/mrsk/configuration.rb | 27 +++++++++++++++++++++++++-- test/configuration_test.rb | 7 ++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 62941f54..e5783cb0 100644 --- a/README.md +++ b/README.md @@ -68,10 +68,21 @@ registry: ### Using a different SSH user than root -The default SSH user is root, but you can change it using `ssh_user`: +The default SSH user is root, but you can change it using `ssh/user`: ```yaml -ssh_user: app +ssh: + user: app +``` + +### Using a bastion/proxy/jump SSH host + +If you need to connect to server through a bastion host, you can use `ssh/proxy_host`: + +```yaml +ssh: + proxy_host: 192.168.0.1 + user_proxy_host: app # defaults to root ``` ### Using env variables diff --git a/lib/mrsk/configuration.rb b/lib/mrsk/configuration.rb index 23723214..71f9909f 100644 --- a/lib/mrsk/configuration.rb +++ b/lib/mrsk/configuration.rb @@ -4,6 +4,7 @@ require "active_support/core_ext/module/delegation" require "pathname" require "erb" require "mrsk/utils" +require "net/ssh/proxy/jump" class Mrsk::Configuration delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true @@ -104,11 +105,33 @@ class Mrsk::Configuration end def ssh_user - raw_config.ssh_user || "root" + if raw_config.ssh.present? + raw_config.ssh["user"] || "root" + else + "root" + end end def ssh_options - { user: ssh_user, auth_methods: [ "publickey" ] } + options = { user: ssh_user, auth_methods: [ "publickey" ] } + + options[:proxy] = ::Net::SSH::Proxy::Jump.new(ssh_proxy_host) if ssh_proxy_host + + options + end + + def ssh_proxy_host + if raw_config.ssh && raw_config.ssh["proxy_host"] + "#{ssh_user_proxy_host}@#{raw_config.ssh['proxy_host']}" + end + end + + def ssh_user_proxy_host + if raw_config.ssh.present? + raw_config.ssh["user_proxy_host"] || "root" + else + "root" + end end def master_key diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 1cd45fcb..64f81454 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -140,10 +140,15 @@ class ConfigurationTest < ActiveSupport::TestCase test "ssh options" do assert_equal "root", @config.ssh_options[:user] - config = Mrsk::Configuration.new(@deploy.tap { |c| c[:ssh_user] = "app" }) + config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "user" => "app" }) }) assert_equal "app", @config.ssh_options[:user] end + test "ssh options with proxy host" do + config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "proxy_host" => "1.2.3.4" }) }) + assert_equal "root@1.2.3.4", @config.ssh_options[:proxy].jump_proxies + end + test "master key" do assert_equal "456", @config.master_key end From 71681cb8be92fe623919b45c74a539ea9febff0b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 31 Jan 2023 13:59:19 +0100 Subject: [PATCH 2/6] Use single string-based proxy declaration --- README.md | 14 ++++++++++---- lib/mrsk/configuration.rb | 27 ++++++++------------------- test/configuration_test.rb | 7 ++++++- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index e5783cb0..d9110c0f 100644 --- a/README.md +++ b/README.md @@ -75,14 +75,20 @@ ssh: user: app ``` -### Using a bastion/proxy/jump SSH host +### Using a proxy SSH host -If you need to connect to server through a bastion host, you can use `ssh/proxy_host`: +If you need to connect to server through a proxy host, you can use `ssh/proxy`: ```yaml ssh: - proxy_host: 192.168.0.1 - user_proxy_host: app # defaults to root + proxy: "192.168.0.1" # defaults to root as the user +``` + +Or with specific user: + +```yaml +ssh: + proxy: "app@192.168.0.1" ``` ### Using env variables diff --git a/lib/mrsk/configuration.rb b/lib/mrsk/configuration.rb index 71f9909f..1f03d8f4 100644 --- a/lib/mrsk/configuration.rb +++ b/lib/mrsk/configuration.rb @@ -112,26 +112,15 @@ class Mrsk::Configuration end end + def ssh_proxy + if raw_config.ssh.present? && raw_config.ssh["proxy"] + Net::SSH::Proxy::Jump.new \ + raw_config.ssh["proxy"].include?("@") ? raw_config.ssh["proxy"] : "root@#{raw_config.ssh["proxy"]}" + end + end + def ssh_options - options = { user: ssh_user, auth_methods: [ "publickey" ] } - - options[:proxy] = ::Net::SSH::Proxy::Jump.new(ssh_proxy_host) if ssh_proxy_host - - options - end - - def ssh_proxy_host - if raw_config.ssh && raw_config.ssh["proxy_host"] - "#{ssh_user_proxy_host}@#{raw_config.ssh['proxy_host']}" - end - end - - def ssh_user_proxy_host - if raw_config.ssh.present? - raw_config.ssh["user_proxy_host"] || "root" - else - "root" - end + { user: ssh_user, proxy: ssh_proxy, auth_methods: [ "publickey" ] }.compact end def master_key diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 64f81454..937abed0 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -145,10 +145,15 @@ class ConfigurationTest < ActiveSupport::TestCase end test "ssh options with proxy host" do - config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "proxy_host" => "1.2.3.4" }) }) + config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "proxy" => "1.2.3.4" }) }) assert_equal "root@1.2.3.4", @config.ssh_options[:proxy].jump_proxies end + test "ssh options with proxy host and user" do + config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "proxy" => "app@1.2.3.4" }) }) + assert_equal "app@1.2.3.4", @config.ssh_options[:proxy].jump_proxies + end + test "master key" do assert_equal "456", @config.master_key end From 7d95472543991c9a57eab090ed5e76cf87f5276e Mon Sep 17 00:00:00 2001 From: Chris de Bruin Date: Fri, 3 Feb 2023 14:27:19 +0100 Subject: [PATCH 3/6] Added -J for ssh proxy --- lib/mrsk/commands/base.rb | 8 +++++++- test/commands/app_test.rb | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/mrsk/commands/base.rb b/lib/mrsk/commands/base.rb index 49a8bf81..5b50b745 100644 --- a/lib/mrsk/commands/base.rb +++ b/lib/mrsk/commands/base.rb @@ -9,7 +9,13 @@ module Mrsk::Commands end def run_over_ssh(command, host:) - "ssh -t #{config.ssh_user}@#{host} '#{command}'" + ssh_command = "ssh" + + if config.ssh_proxy + ssh_command << " -J #{config.ssh_proxy.jump_proxies}" + end + + ssh_command << " -t #{config.ssh_user}@#{host} '#{command}'" end private diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index 51ee7b3a..ca00e180 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -38,4 +38,14 @@ class CommandsAppTest < ActiveSupport::TestCase assert @app.run.exclude?("RAILS_MASTER_KEY=456") end + + test "exec_over_ssh" do + assert @app.exec_over_ssh("ls", host: '1.1.1.1').start_with?("ssh -t #{@app.config.ssh_user}@1.1.1.1") + end + + test "exec_over_ssh with proxy" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "proxy" => 'root@2.2.2.2' } }) + + assert @app.exec_over_ssh("ls", host: '1.1.1.1').start_with?("ssh -J root@2.2.2.2 -t #{@app.config.ssh_user}@1.1.1.1") + end end From 9cfb6fb0a9d49d9d83260aee4e65af52e49afbd1 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 4 Feb 2023 15:34:48 +0100 Subject: [PATCH 4/6] Merge issue --- lib/mrsk/configuration.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/mrsk/configuration.rb b/lib/mrsk/configuration.rb index 0a39f89d..f5fd2da5 100644 --- a/lib/mrsk/configuration.rb +++ b/lib/mrsk/configuration.rb @@ -1,3 +1,8 @@ +require "active_support/ordered_options" +require "active_support/core_ext/string/inquiry" +require "active_support/core_ext/module/delegation" +require "pathname" +require "erb" require "net/ssh/proxy/jump" class Mrsk::Configuration From bdff11e1fc53fc1523b05e6345bce9081c602c51 Mon Sep 17 00:00:00 2001 From: Chris de Bruin Date: Fri, 27 Jan 2023 10:07:24 +0100 Subject: [PATCH 5/6] Allow use of bastion host --- test/configuration_test.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 808b9c62..d4206dfe 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -153,15 +153,6 @@ class ConfigurationTest < ActiveSupport::TestCase assert_equal "app@1.2.3.4", @config.ssh_options[:proxy].jump_proxies end - test "master key" do - assert_equal "456", @config.master_key - end - - test "skip master key" do - config = Mrsk::Configuration.new(@deploy.tap { |c| c[:skip_master_key] = true }) - assert_nil @config.master_key - end - test "volume_args" do assert_equal ["--volume", "/local/path:/container/path"], @config.volume_args end From 0a293ae4d61225441a431cababb6ed295360d83c Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 4 Feb 2023 15:43:45 +0100 Subject: [PATCH 6/6] Fix and expand testing --- test/commands/app_test.rb | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index e668dc68..f38ca87f 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -110,6 +110,30 @@ class CommandsAppTest < ActiveSupport::TestCase end end + test "run over ssh" do + assert_equal "ssh -t root@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with custom user" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "user" => "app" } }) + assert_equal "ssh -t app@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with proxy" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "proxy" => "2.2.2.2" } }) + assert_equal "ssh -J root@2.2.2.2 -t root@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with proxy user" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "proxy" => "app@2.2.2.2" } }) + assert_equal "ssh -J app@2.2.2.2 -t root@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with custom user with proxy" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "user" => "app", "proxy" => "2.2.2.2" } }) + assert_equal "ssh -J root@2.2.2.2 -t app@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + test "current_container_id" do assert_equal \ @@ -134,14 +158,4 @@ class CommandsAppTest < ActiveSupport::TestCase "docker image ls --format \"{{.Tag}}\" dhh/app | head -n 1", @app.most_recent_version_from_available_images.join(" ") end - - test "exec_over_ssh" do - assert @app.exec_over_ssh("ls", host: '1.1.1.1').start_with?("ssh -t #{@app.config.ssh_user}@1.1.1.1") - end - - test "exec_over_ssh with proxy" do - @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "proxy" => 'root@2.2.2.2' } }) - - assert @app.exec_over_ssh("ls", host: '1.1.1.1').start_with?("ssh -J root@2.2.2.2 -t #{@app.config.ssh_user}@1.1.1.1") - end end