Skip to content

Commit d0adee3

Browse files
committed
(maint) add ed25519 support
rubygems has compiled versions of bcrypt_pbkdf 1.1.0 for windows addresses #1986 #1987
1 parent 2b0d943 commit d0adee3

File tree

8 files changed

+50
-53
lines changed

8 files changed

+50
-53
lines changed

Diff for: bolt.gemspec

+2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ Gem::Specification.new do |spec|
4545

4646
spec.add_dependency "addressable", '~> 2.5'
4747
spec.add_dependency "aws-sdk-ec2", '~> 1'
48+
spec.add_dependency "bcrypt_pbkdf", ">= 1.1", "< 2.0"
4849
spec.add_dependency "CFPropertyList", ">= 2.2"
4950
spec.add_dependency "concurrent-ruby", "~> 1.0", "< 1.2.0"
51+
spec.add_dependency "ed25519", ">= 1.3", "< 2.0"
5052
spec.add_dependency "ffi", ">= 1.9.25", "< 2.0.0"
5153
spec.add_dependency "hiera-eyaml", "~> 3"
5254
spec.add_dependency "jwt", "~> 2.2"

Diff for: documentation/bolt_known_issues.md

-36
Original file line numberDiff line numberDiff line change
@@ -68,42 +68,6 @@ such as [`bolt-defaults.yaml`](bolt_defaults_reference.md) or
6868
[inventory file](bolt_inventory_reference.md), or passing the password on the
6969
command line with the `--password` option.
7070

71-
📖 **Related issues**
72-
73-
- [#1986 - Commands fail if in a remote session to
74-
Windows](https://github.com/puppetlabs/bolt/issues/1986)
75-
76-
## Unable to authenticate with ed25519 keys over SSH transport on Windows
77-
78-
By default, Bolt uses the `net-ssh` Ruby libary to connect to targets over SSH.
79-
The `net-ssh` library requires the `ed25519` and `bcrypt_pbkdf` gems as
80-
dependencies, which are not supported in Bolt's packaging process due to issues
81-
with compiling native extensions.
82-
83-
Attempting to authenticate with ed25519 keys over SSH on Windows will result
84-
in an error message similar to this:
85-
86-
```
87-
unsupported key type `ssh-ed25519'
88-
net-ssh requires the following gems for ed25519 support:
89-
* ed25519 (>= 1.2, < 2.0)
90-
* bcrypt_pbkdf (>= 1.0, < 2.0)
91-
```
92-
93-
A workaround is to use native SSH when you need to authenticate with ed25519
94-
keys. When native SSH is enabled, Bolt will use a specified SSH client to
95-
connect to targets instead of the `net-ssh` Ruby library. To learn more about
96-
native SSH, see [native SSH
97-
transport](experimental_features.md#native-ssh-transport).
98-
99-
🧪 Native SSH is
100-
experimental and might change in future minor (y) releases.
101-
102-
📖 **Related issues**
103-
104-
- [#1987 - Unable to authenticate with ed25519 keys over SSH transport
105-
on Windows](https://github.com/puppetlabs/bolt/issues/1987)
106-
10771
## 🧪 Limited Kerberos support over WinRM
10872

10973
🧪 Authenticating with Kerberos over WinRM is considered experimental and is

Diff for: spec/Dockerfile

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ RUN adduser bolt sudo
2828

2929
RUN mkdir -p /home/bolt/.ssh
3030
COPY fixtures/keys/id_rsa.pub /home/bolt/.ssh/id_rsa.pub
31-
COPY fixtures/keys/id_rsa.pub /home/bolt/.ssh/authorized_keys
31+
COPY fixtures/keys/id_ed25519.pub /home/bolt/.ssh/id_ed25519.pub
32+
RUN cat /home/bolt/.ssh/*.pub > /home/bolt/.ssh/authorized_keys
3233
RUN chmod 700 /home/bolt/.ssh
3334
RUN chmod 600 /home/bolt/.ssh/authorized_keys
3435
RUN chown -R bolt:sudo /home/bolt
@@ -41,7 +42,8 @@ RUN echo test | chsh -s /bin/bash test
4142

4243
RUN mkdir -p /home/test/.ssh
4344
COPY fixtures/keys/id_rsa.pub /home/test/.ssh/id_rsa.pub
44-
COPY fixtures/keys/id_rsa.pub /home/test/.ssh/authorized_keys
45+
COPY fixtures/keys/id_ed25519.pub /home/test/.ssh/id_ed25519.pub
46+
RUN cat /home/test/.ssh/*.pub > /home/test/.ssh/authorized_keys
4547
RUN chmod 700 /home/test/.ssh
4648
RUN chmod 600 /home/test/.ssh/authorized_keys
4749
RUN chown -R test:sudo /home/test

Diff for: spec/bolt_server/app_integration_spec.rb

+24-13
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,31 @@ def app
4444
expect(result['value']['_output'].chomp).to match(/\w+ got passed the message: Hello!/)
4545
end
4646

47-
it 'runs an echo task using a private key' do
48-
private_key = ENV['BOLT_SSH_KEY'] || Dir["spec/fixtures/keys/id_rsa"][0]
49-
private_key_content = File.read(private_key)
50-
target = conn_target('ssh', options: { 'private-key' => { 'key-data' => private_key_content } })
51-
body = build_task_request('sample::echo',
52-
target,
53-
message: "Hello!")
47+
%w[env rsa ed25519].each do |key_type|
48+
next if key_type == 'env' && ENV['BOLT_SSH_KEY'].nil?
49+
50+
context "runs an echo task using an #{key_type} private key" do
51+
let(:private_key) do
52+
key_type == 'env' ? ENV['BOLT_SSH_KEY'] : Dir["spec/fixtures/keys/id_#{key_type}"][0]
53+
end
54+
55+
it do
56+
private_key_content = File.read(private_key)
57+
target = conn_target('ssh', options: { 'private-key' => { 'key-data' => private_key_content } })
58+
body = build_task_request('sample::echo',
59+
target,
60+
message: "Hello!")
61+
62+
post path, JSON.generate(body), 'CONTENT_TYPE' => 'text/json'
63+
expect(last_response).to be_ok
64+
expect(last_response.status).to eq(200)
65+
result = JSON.parse(last_response.body)
66+
expect(result).to include('status' => 'success')
67+
expect(result['value']['_output'].chomp).to match(/\w+ got passed the message: Hello!/)
68+
end
69+
end
5470

55-
post path, JSON.generate(body), 'CONTENT_TYPE' => 'text/json'
56-
expect(last_response).to be_ok
57-
expect(last_response.status).to eq(200)
58-
result = JSON.parse(last_response.body)
59-
expect(result).to include('status' => 'success')
60-
expect(result['value']['_output'].chomp).to match(/\w+ got passed the message: Hello!/)
71+
break if key_type == 'env'
6172
end
6273

6374
it 'runs a shareable task' do

Diff for: spec/fixtures/keys/id_ed25519

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-----BEGIN OPENSSH PRIVATE KEY-----
2+
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
3+
QyNTUxOQAAACDuFK/VaW7prqpNVY0H+bUTXsbDSeYg5XKlo0AitRXSmAAAALjUlsWQ1JbF
4+
kAAAAAtzc2gtZWQyNTUxOQAAACDuFK/VaW7prqpNVY0H+bUTXsbDSeYg5XKlo0AitRXSmA
5+
AAAECU+JslSRRf+EDh1yWFP6Hue8DrT0M8CGLp1UDKycZnfu4Ur9Vpbumuqk1VjQf5tRNe
6+
xsNJ5iDlcqWjQCK1FdKYAAAAMWplZmZyZXkuY2xhcmtAamVmZnJleWNsYXJrcy1WaXJ0dW
7+
FsLU1hY2hpbmUubG9jYWwBAgME
8+
-----END OPENSSH PRIVATE KEY-----

Diff for: spec/fixtures/keys/id_ed25519.pub

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO4Ur9Vpbumuqk1VjQf5tRNexsNJ5iDlcqWjQCK1FdKY [email protected]

Diff for: spec/integration/transport/ssh_spec.rb

+9
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
let(:bash_user) { 'test' }
3333
let(:bash_password) { 'test' }
3434
let(:key) { conn_info('ssh')[:key] }
35+
let(:ed25519_key) { File.expand_path(File.join(__dir__, '..', '..', 'fixtures/keys/id_ed25519')) }
3536
let(:command) { "pwd" }
3637

3738
let(:no_host_key_check) { { 'host-key-check' => false, user: user, password: password } }
@@ -208,6 +209,14 @@ def make_target(host_: hostname, port_: port)
208209
).to eq(true)
209210
end
210211
end
212+
213+
context "with ed25519 private key" do
214+
let(:transport_config) { super().merge({ 'private-key' => ed25519_key }) }
215+
216+
it "executes a command on a host" do
217+
expect(ssh.run_command(target, command).value['stdout']).to eq("/home/#{user}\n")
218+
end
219+
end
211220
end
212221

213222
context "when executing with private key data" do

Diff for: spec/unit/executor_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ def mock_node_results
571571
expect(ssh)
572572
.to receive(:with_connection)
573573
.and_raise(
574-
NotImplementedError.new('ed25519 is not supported')
574+
NotImplementedError.new('something is not supported')
575575
)
576576
end
577577

@@ -580,7 +580,7 @@ def mock_node_results
580580

581581
results.each do |result|
582582
expect(result.error_hash['kind']).to eq('puppetlabs.tasks/exception-error')
583-
expect(result.error_hash['msg']).to eq('ed25519 is not supported')
583+
expect(result.error_hash['msg']).to eq('something is not supported')
584584
end
585585

586586
expect(collector.events.count).to eq(10)

0 commit comments

Comments
 (0)