this post was submitted on 14 Aug 2024
117 points (99.2% liked)

Linux

48338 readers
451 users here now

From Wikipedia, the free encyclopedia

Linux is a family of open source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991 by Linus Torvalds. Linux is typically packaged in a Linux distribution (or distro for short).

Distributions include the Linux kernel and supporting system software and libraries, many of which are provided by the GNU Project. Many Linux distributions use the word "Linux" in their name, but the Free Software Foundation uses the name GNU/Linux to emphasize the importance of GNU software, causing some controversy.

Rules

Related Communities

Community icon by Alpár-Etele Méder, licensed under CC BY 3.0

founded 5 years ago
MODERATORS
 

I have my own ssh server (on raspberry pi 5, Ubuntu Server 23) but when I try to connect from my PC using key authentication (having password disabled), I get a blank screen. A blinking cursor.

However, once I enter the command eval "$(ssh-agent -s)" and try ssh again, I successfully login after entering my passphrase. I don't want to issue this command every time. Is that possible?

This does not occur when I have password enabled on the ssh server. Also, ideally, I want to enter my passphrase EVERYTIME I connect to my server, so ideally I don't want it to be stored in cache or something. I want the passphrase to be a lil' password so that other people can't accidentally connect to my server when they use my PC.

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 1 points 3 months ago* (last edited 3 months ago)

I was unclear: I did not mean to imply that it will work with it.

It's OT, but I'll clarify since it might be useful for people who find Bash cryptic.

Thing is, roughly speaking:

  • eval will evaluate its first argument as Bash code
  • eval "$(any_command really)" will run run any_command really, take its output and then use it as first argument for eval. So the assumption is that any_command really must output a valid Bash code snippet.

So what eval "$(ssh-agent -s)" really means is, "run ssh-agent -s, collect the output and run it right here, where we are calling eval. Compare to ssh-agent -s | bash -- this would also run ssh-agent output but it would run it in a new process--a child process of the current process---so the whatever the snippet would be, it would have no way of affecting state of the parent program, which is why it's safer.

Aside: The reason we need eval in this case is that we actually need to affect state of the program: that's the whole point. We need to set several environment variables to values that ssh-agent "knows". Without eval we would have to "ask" ssh-agent separately for each value (I'm assuming it's not even supported) and then set all these envvars using eg. export keyword. Using eval we let ssh-agent dictate the whole process: which variables are going to be set to what values, with the caveat that if compromised, it could do "evil" stuff like setting PATH to override common commands with compromised code. etc.

So what's the problem with the quotes? The Shell syntax, foo "$(bar baz)" will make sure that the thing between quotes is

  • kept verbatim
  • treated as a single argument, even if it contains newlines (with some ugly exceptions to this regarding the final newline)

Now without quotes, Bash (as well as POSIX shell) actually have several things they can do with the output (read man bash for full list, but keep it for a long rainy evening). Some of it involves substituting eg. values like * with matching filenames, some of it may involve actually splitting the output to separate arguments based on spaces or other special characters (which can even be different characters depending on current state, see IFS and the likes).

You can see the difference, if you run eg. printf '[%s]\n' instead of eval. This printf syntax will simply print all of following arguments on a separate line, adding braces before and after. You can compare

printf '|%s|\n' $(ssh-agent -s)      # printf will probably receive multiple extra arguments
printf '|%s|\n' "$(ssh-agent -s)"    # printf will receive just one extra argument (and print it as specified)

(both of these commands should be safe as long as ssh-agent is not compromised and as long I have not made any terrible typo)