nerves-project / nerves_ssh Goto Github PK
View Code? Open in Web Editor NEWNerves SSH support
License: Apache License 2.0
Nerves SSH support
License: Apache License 2.0
Currently the server key is hardcoded.
The logic for doing this was that nerves_ssh
was only useful for development and behind-a-firewall deployments where MITM attacks are less of a concern. It also was convenient since key generation takes some time on first boot and dealing with ssh complaining about server signatures changing was annoying.
The hard coded server key rightfully looks highly suspicious to anyone reviewing the code. I think that it's time to generate the key on first boot to get past this.
Hello there,
this is a continuation of a discussion from #83. I think it would be a great feature to allow connecting to nerves devices using SSH into a unix shell, separate to the existing IEx / Erlang shells. Therefore, I've written :nerves_ssh_shell
and this issue discusses possible ways to maybe integrate this feature into :nerves_ssh
in the future.
Some thoughts:
The only problem I see is that currently nerves_ssh_shell depends on erlexec, as this is the only way I found to actually run a process inside a pseudoterminal from the BEAM world and it currently does not compile for musl based systems.
I've seen jjcarstens/extty#8, but this does not create a "real" pseudoterminal for running interactive shell commands. nerves.system.shell
works around this by wrapping commands with the script
utility, but this is not a good solution as there seems to be no way to handle resizing terminals properly. Also, depending on tools like script
and stty
on nerves would require changing the base systems.
So with all that, using erlexec works great and I've already contributed a change that makes using interactive terminals much easier. So maybe the way forward is:
:nerves_ssh
and clarify what needs to be configured for Unix shell supportssh_server_channel
s from :nerves_ssh_shell
for using the shells, either as SSH subsystem (with reduced features) or using a separate daemonStill, I feel like I this is maybe not the best solution, as the configuration needed for erlexec is global and might interfere with users that already use erlexec with other settings. Maybe there could be a very small wrapper around Port
or a nif that allows spawning a command in a pty (https://man7.org/linux/man-pages/man7/pty.7.html) and setting possible pty options (modes, window size, ...), but I'm not proficient enough in C / Rust / Zig to write anything like this.
NervesSSH got into a restart loop when after failing to create a host key, but couldn't due to /data
not being writable. The problem is the system_dir
parameter below needs to be adjusted when this happens. I got this when I forgot to enable f2fs
support in the Linux kernel options. I could imagine this is possible to get many other ways, but disabling or misspelling the data partition filesystem type seems the easiest way to reproduce at the moment.
00:00:00.129 [warn] [NervesSSH] Failed to write generated SSH host key to /data/nerves_ssh/ssh_host_ed25519_key - {:error, :erofs}
The SSH daemon wil continue to run and use the generated key, but a new host key
will be generated the next time the daemon is started.
00:00:00.134 [error] [NervesSSH] :ssd.daemon failed: {:error, {:eoptions, {{:system_dir, '/data/nerves_ssh'}, :enoent}}}
00:00:00.636 [error] [NervesSSH] terminating with reason: {:ssh_daemon_error, {:error, {:eoptions, {{:system_dir, '/data/nerves_ssh'}, :enoent}}}}
00:00:00.637 [error] GenServer NervesSSH terminating
** (stop) {:ssh_daemon_error, {:error, {:eoptions, {{:system_dir, '/data/nerves_ssh'}, :enoent}}}}
Last message: {:continue, :start_daemon}
State: %NervesSSH.State{opts: %NervesSSH.Options{authorized_keys: [], daemon_option_overrides: [pwdfun: &CircuitsQuickstart.ssh_check_pass/2, auth_method_kb_interactive_data: &CircuitsQuickstart.ssh_show_prompt/3], decoded_authorized_keys: [], exec: :elixir, iex_opts: [dot_iex_path: "/etc/iex.exs"], port: 22, shell: :elixir, subsystems: [{'fwup', {SSHSubsystemFwup, [devpath: "/dev/mmcblk0"]}}, {'sftp', {:ssh_sftpd, [cwd: '/']}}], system_dir: "/data/nerves_ssh", user_dir: "/data/nerves_ssh/default_user", user_passwords: []}, sshd: nil, sshd_ref: nil}
00:00:00.661 [warn] [NervesSSH] Failed to save authorized_keys file: {:error, :enoent}
00:00:00.679 [warn] [NervesSSH] Failed to write generated SSH host key to /data/nerves_ssh/ssh_host_ed25519_key - {:error, :erofs}
The SSH daemon wil continue to run and use the generated key, but a new host key
will be generated the next time the daemon is started.
00:00:00.682 [error] [NervesSSH] :ssd.daemon failed: {:error, {:eoptions, {{:system_dir, '/data/nerves_ssh'}, :enoent}}}
Frank and I discovered that even if you have an ipv6 address, you can't access a device via ssh. After a quick search it should be as easy as adding :inet6
to this line
The current method for authentication is to specify passwords and ssh public keys in the application environment. This is good for first time setup, but sometimes you don't want the default credentials longer term. For example, if you don't want everyone to be able to log into your nerves_livebook
device, it would be great to replace the default password.
This can slightly be done via runtime.exs
, but you have to get it right on the first try or you can't log into the device. It would be better if you could keep a IEx prompt logged in that runs the change, and then be able to test the new auth by connecting in another terminal window.
It would be nice to be able to upload ssh public keys at runtime. This would especially be useful for the pre-built firmware images like circuits_quickstart
and nerves_livebook
. Both use password authentication, but it would be more convenient to be able to upload public keys and skip that step.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.