Module: TrainPlugins::Juniper::BastionProxy

Includes:
SshAskpass, WindowsProxy
Included in:
Connection
Defined in:
lib/train-juniper/connection/bastion_proxy.rb

Overview

Handles bastion host proxy configuration and authentication

Instance Method Summary collapse

Instance Method Details

Build plink.exe proxy command for Windows bastion authentication

Parameters:

  • bastion_host (String)

    Bastion hostname

  • user (String)

    Username for bastion

  • port (Integer)

    Port for bastion

  • password (String)

    Password for bastion

Returns:

  • (String)

    Complete plink command string

#build_proxy_jump_string(bastion_user, bastion_port) ⇒ String (private)

Build proxy jump string from bastion options

Parameters:

  • bastion_user (String)

    Username for bastion

  • bastion_port (Integer)

    Port for bastion

Returns:

  • (String)

    Proxy jump string



70
71
72
73
74
75
76
# File 'lib/train-juniper/connection/bastion_proxy.rb', line 70

def build_proxy_jump_string(bastion_user, bastion_port)
  if bastion_port == Constants::DEFAULT_SSH_PORT
    "#{bastion_user}@#{@options[:bastion_host]}"
  else
    "#{bastion_user}@#{@options[:bastion_host]}:#{bastion_port}"
  end
end

#configure_bastion_proxy(ssh_options) ⇒ Object

Configure bastion proxy for SSH connection

Parameters:

  • ssh_options (Hash)

    SSH options to modify



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/train-juniper/connection/bastion_proxy.rb', line 16

def configure_bastion_proxy(ssh_options)
  bastion_user = @options[:bastion_user] || @options[:user]
  bastion_port = @options[:bastion_port]
  bastion_password = @options[:bastion_password] || @options[:password]

  # On Windows with password auth, use plink.exe if available
  if Gem.win_platform? && bastion_password && plink_available?
    configure_plink_proxy(ssh_options, bastion_user, bastion_port, bastion_password)
  else
    configure_standard_proxy(ssh_options, bastion_user, bastion_port)
  end
end

Configure plink.exe proxy for Windows password authentication

Parameters:

  • ssh_options (Hash)

    SSH options to modify

  • bastion_user (String)

    Username for bastion

  • bastion_port (Integer)

    Port for bastion

  • bastion_password (String)

    Password for bastion



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/train-juniper/connection/bastion_proxy.rb', line 52

def configure_plink_proxy(ssh_options, bastion_user, bastion_port, bastion_password)
  require 'net/ssh/proxy/command' unless defined?(Net::SSH::Proxy::Command)

  proxy_cmd = build_plink_proxy_command(
    @options[:bastion_host],
    bastion_user,
    bastion_port,
    bastion_password
  )

  @logger.debug('Using plink.exe for bastion proxy')
  ssh_options[:proxy] = Net::SSH::Proxy::Command.new(proxy_cmd)
end

#configure_standard_proxy(ssh_options, bastion_user, bastion_port) ⇒ Object (private)

Configure standard SSH proxy using Net::SSH::Proxy::Jump

Parameters:

  • ssh_options (Hash)

    SSH options to modify

  • bastion_user (String)

    Username for bastion

  • bastion_port (Integer)

    Port for bastion



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/train-juniper/connection/bastion_proxy.rb', line 35

def configure_standard_proxy(ssh_options, bastion_user, bastion_port)
  require 'net/ssh/proxy/jump' unless defined?(Net::SSH::Proxy::Jump)

  proxy_jump = build_proxy_jump_string(bastion_user, bastion_port)
  @logger.debug("Using bastion host: #{proxy_jump}")

  # Set up automated password authentication via SSH_ASKPASS
  setup_bastion_password_auth

  ssh_options[:proxy] = Net::SSH::Proxy::Jump.new(proxy_jump)
end

#create_ssh_askpass_script(password) ⇒ String Originally defined in module SshAskpass

Create temporary SSH_ASKPASS script for automated password authentication

Parameters:

  • password (String)

    The password to use

Returns:

  • (String)

    Path to the created script

#create_unix_askpass_script(password) ⇒ String (private) Originally defined in module SshAskpass

Create Unix shell script for SSH_ASKPASS

Parameters:

  • password (String)

    The password to use

Returns:

  • (String)

    Path to the created script

#create_windows_askpass_script(password) ⇒ String (private) Originally defined in module SshAskpass

Create Windows PowerShell script for SSH_ASKPASS

Parameters:

  • password (String)

    The password to use

Returns:

  • (String)

    Path to the wrapper batch file

#generate_bastion_proxy_command(bastion_user, bastion_port) ⇒ String (private)

Generate SSH proxy command for bastion host using ProxyJump (-J)

Parameters:

  • bastion_user (String)

    Username for bastion

  • bastion_port (Integer)

    Port for bastion

Returns:

  • (String)

    SSH command string



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/train-juniper/connection/bastion_proxy.rb', line 82

def generate_bastion_proxy_command(bastion_user, bastion_port)
  args = ['ssh']

  # SSH options for connection
  Constants::STANDARD_SSH_OPTIONS.each do |key, value|
    args += ['-o', "#{key}=#{value}"]
  end

  # Use ProxyJump (-J) which handles password authentication properly
  jump_host = build_proxy_jump_string(bastion_user, bastion_port)
  args += ['-J', jump_host]

  # Add SSH keys if specified
  if @options[:key_files]
    Array(@options[:key_files]).each do |key_file|
      args += ['-i', key_file]
    end
  end

  # Target connection - %h and %p will be replaced by Net::SSH
  args += ['%h', '-p', '%p']

  args.join(' ')
end

Check if plink.exe is available on Windows

Returns:

  • (Boolean)

    true if plink.exe is found in PATH

#setup_bastion_password_authObject Originally defined in module SshAskpass

Set up SSH_ASKPASS for bastion password authentication