NHacker Next
  • new
  • past
  • show
  • ask
  • show
  • jobs
  • submit
Unix shells are generally not viable access control mechanisms any more (utcc.utoronto.ca)
chatmasta 12 hours ago [-]
When you SSH into GitLab, you get a "shell," which at one point was a locked-down Unix shell where you could only run Git commands. That's a workable solution, but they (rightly) migrated off it [0], so now it's just a Go program [1] that runs an SSH server and interprets a small list of valid commands. This basically inverts the security model. The Unix shell approach is leaky, because you never know if you've plugged all the holes while only allowing the commands you want. Whereas the Go program is only capable of executing a narrow range of commands, which it interprets itself, in its own fake shell, while exposing an SSH server.

Fun fact: one of the commands [2] the shell implements is `personal_access_token`, so you can programmatically mint a new PAT, since you've already authenticated via your SSH key:

    ssh git@gitlab.com personal_access_token someTokenName api,read_repository,read_api,read_user,read_registry 90

[0] https://about.gitlab.com/blog/2022/08/17/why-we-have-impleme...

[1] https://gitlab.com/gitlab-org/gitlab-shell

[2] https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/inter...

kccqzy 11 hours ago [-]
How is that different from writing your own shell that implements a tiny subset of the functionality with support for a small number of commands? You can even write it in Go if that's your preferred language.
chatmasta 11 hours ago [-]
That's exactly what it is, but the point is that it's not a Unix shell, and it's not running as a subcommand of SSH (which you could also do with a custom shell). There's no tty involved, and so the attack surface is reduced - if you exploit a logic error in the Go code (e.g. parameter pollution), you won't be able to do more than run one of the commands that it already runs. But if you exploit a logic error in a Unix shell with parameter pollution, then the attack surface is much greater. That said, of course if an attacker finds a bug in the Go code that enables arbitrary code execution, then the attack surface is just as wide as any other binary on the system, including a Unix shell, so you still need to lock down the privileges of the process itself.
jolmg 9 hours ago [-]
I think the point is: how is bundling a custom ssh server into the same executable that interprets the commands, a reduced surface as opposed to using standard openssh's sshd, and defining a simple shell like so:


  cmd_foo() {
    printf "called foo with %s\n" "$*"

  cmd_bar() {
    printf "called bar with %s\n" "$*"

  run_cmd_call() {
    local cmd="$1"; shift
    local cmd_args=("$@")

    case "$cmd" in
      foo) cmd_foo "${cmd_args[@]}" ;;
      bar) cmd_bar "${cmd_args[@]}" ;;
      *) printf "%s: unknown command\n" "$cmd" >&2

  while (( $# )); do
    case "$1" in
        read -ra cmd_call <<< "$2"

        printf "%s: unknown argument\n" "$1" >&2
        exit 1

  if [[ "$cmd_call" ]]; then
    run_cmd_call "${cmd_call[@]}"
      printf "> "
      read -ra cmd_call
      run_cmd_call "${cmd_call[@]}"
(then, of course,)

  sudo useradd -ms /path/to/custom-shell.sh userfoo
  sudo -u userfoo bash -c 'mkdir ~/.ssh; printf "%s\n" "$your_pubkey" >> ~/.ssh/authorized_keys'
How would you "do more than run one of the commands that it already runs" with this from a `ssh userfoo@localhost` call?
garblegarble 8 hours ago [-]
Don't forget to disable sftp in your sshd_config. and ssh port forwarding. and hopefully there's no sneaky way that an attacker can push an environment variable to break something like with LD_PRELOAD, and are you sure there are no directly/indirectly exploitable bugs/omissions in your script logic for invoking complex commands like git, and that your distributed filesystem works quickly across a few million home folders for your authorized_keys files, ...
jolmg 8 hours ago [-]
EDIT: Crap. You're right. Port forwarding worked... So there's that. `ssh -J userfoo@localhost other-place` also worked... I would imagine that's all able to be disabled, but I see that the user is not fundamentally limited to what the shell allows. That's disappointing. I thought it would wrap everything in `custom-shell.sh -c` calls like it does with the sftp and scp servers. I imagine/hope that under a default configuration one is still not able to touch the contents of the server if the shell doesn't permit it, but being able to use it as a proxy or listen on its ports is not what I expected.


> Don't forget to disable sftp in your sshd_config

Doing `strace -fp $(pgrep sshd)` then `sftp userfoo@localhost` in another terminal, I see:

  $ sftp userfoo@localhost
  Connection closed.  
  Connection closed
then in the `strace` output:

  [pid 408173] execve("/tmp/custom-shell.sh", ["custom-shell.sh", "-c", "/usr/lib/ssh/sftp-server"], 0x55c5f3bae0d0 /* 14 vars */) = 0
  [pid 408173] write(1, "/usr/lib/ssh/sftp-server: unknown command\n", 42) = 42
As far as I understand, SSH's security of what a user can do is completely based on what the shell permits the user to do.

> are you sure there are no directly/indirectly exploitable bugs/omissions in your script logic for invoking complex commands like git

Including a ssh server in the same executable doesn't save you from such bugs.

> and that your distributed filesystem works quickly across a few million home folders for your authorized_keys files

OpenSSH's sshd seems quite flexible in ways to authenticate users. I don't think having a home folder per user is necessary if you don't want it.

> and hopefully there's no sneaky way that an attacker can push an environment variable to break something like with LD_PRELOAD

SSH's default is to not accept the client's environment, and this shell itself provides no way to manipulate them. They can be nonexistent in the shell's interface if you don't want them.

I put the script so someone can offer some concrete way (as in show me some code) to bypass it in a way that having a custom integrated SSH server would prevent it. I'd love to see a `ssh/sftp userfoo@localhost` call that does something other than call cmd_foo, cmd_bar, or erring out.

Jenda_ 7 hours ago [-]
There was another hole if the target command was executed using /bin/bash in a certain way: https://en.wikipedia.org/wiki/Shellshock_(software_bug) It's probably not the case when the command is the user's shell, but it was exploitable when it was the command= in authorized_keys.

Additionally, maybe they are using a custom server because they don't want to fork a new instance of the handler on every login.

Here is a stackoverflow topic on limiting the SSH user: https://serverfault.com/questions/152726/how-can-ssh-allowed.... They suggest a few more options, probably not relevant for a gitlab-like use-case.

> SSH's default is to not accept the client's environment

sshd accepts environment variables specified by AcceptEnv in /etc/ssh/sshd_config. By default, they are mostly related to locales.

  $ LC_ALL=en_US.UTF8 ssh x date
  Tue Sep 19 01:14:41 AM UTC 2023
  $ LC_ALL=cs_CZ.UTF8 ssh x date
  Út 19. září 2023, 01:14:46 UTC
jolmg 7 hours ago [-]
> There was another hole if the target command was executed using /bin/bash in a certain way: https://en.wikipedia.org/wiki/Shellshock_(software_bug)

I agree bash is not the best choice security-wise, but language choice is a bit beside the point with regards to whether or not to bundle a server.

> Additionally, maybe they are using a custom server because they don't want to fork a new instance of the handler on every login.

That's very valid, though the discussion was about having a reduced attack surface from adding a custom server.

> Here is a stackoverflow topic on limiting the SSH user: https://serverfault.com/questions/152726/how-can-ssh-allowed.... They suggest a few more options, probably not relevant for a gitlab-like use-case.

Thanks for that.

> sshd accepts environment variables specified by AcceptEnv in /etc/ssh/sshd_config. By default, they are mostly related to locales.

That seems to be a Debian-specific patch. Upstream doesn't include AcceptEnv in the default config file and there seems to be no default value. Your example commands fail to set LC_ALL on my system. `ssh -o SetEnv=LC_ALL=...` also fails.

Too 4 hours ago [-]
Bash actually has this feature built in. Restricted shell they call it. Start it as rbash or bash -r.

It will lock down the shell to not allow cd, setting envvars, launching commands outside working directory and a lot more.

If you look at the full list of things they disable you realize how many obscure holes are available you never would have thought about.

Not that I would ever trust it enough to expose on a shared box. Likewise with a tailor made shellscript. I’d take a bespoke server in go any day.

jart 3 hours ago [-]
What difference does it being a subcommand make? Just use a seccomp filter. It'll apply to all descendent processes.
tedunangst 7 hours ago [-]
Attackers cannot get access to features which don't exist even if you forget to configure them off.
11 hours ago [-]
fooblat 21 hours ago [-]
This article could have been published 30 years ago. In professional unix admin circles this was already well known back them. Although I could be misreading it as the article is not very clear. I think this are the points it is trying to make:

1. Once upon a time you could rely on the passwd file and shell behavior as an effective means of authentication and access control.

2. It has been a very long time since that was an effective approach, for a variety of reasons, and you should not do this on modern production systems.

tremon 18 hours ago [-]
Even 30 years ago, the core argument would have been nonsensical.

1. They introduce their argument as if it is solely about shell access (the conclusion also only mentions "login access control"), but then the first example/statement they make is about non-shell access (Samba, IMAP, Apache).

2. The second argument conflates authentication and authorization, and concludes that to implement shell authorization properly, your only choice is to provide multiple authentication systems.

Zero effort is spent on explaining why existing/historic shell authorization systems (such as simple DAC groups or rbash) are inadequate, and it's not clear to me what threat model they are using to arrive at their conclusion.

edit: rethinking this, I think TFA is just lacking a clear problem statement. They seem to be talking specifically about non-shell services that (ab)use the user's shell field in /etc/passwd as authorization information, and then complaining that many services did not follow suit.

hinkley 18 hours ago [-]
Few contractions foment confusion as much as “auth”. Don’t do it.
AceJohnny2 13 hours ago [-]
authn vs authz: Authentication vs Authorization

authn/authentication: user proves who they are, with username/password or otherwise

authz/authorization: based on who the user is, system determines what they are allowed to do, via group membership or otherwise

AndrewDavis 12 hours ago [-]
authz may be confusing to non USA English speakers. I wouldn't make the connection without it spelled out to me. Unfortunately I don't have a better suggestion because auths as short for authorisation is probably worse.
Affric 9 hours ago [-]
If you work with computers (rather than using them) and don't default to USA English when discussing and using them you are likely in for a bad time.
raxxorraxor 2 hours ago [-]
I think it is less confusion than just calling it auth. I have read many articles about basic auth vs oauth. But the auth here isn't the same.
matttproud 3 hours ago [-]
TBH, we'd be better if without any of the contracted forms.
hinkley 12 hours ago [-]
You can't pronounce authn and authz very well, but to be perfectly honest I'm not sure if that falls under the 'pro' or 'con' column.
fragmede 11 hours ago [-]
I think it's a pro. in saying auth-enn and auth-zee (zed), it's clear which of the two you're talking about.
PH95VuimJjqBqy 13 hours ago [-]
the only exception is if you mean both, but even that's confusing if the context isn't clear.

spell them out or use authn/authz.

bigbuppo 10 hours ago [-]
You're not thinking like a thought leader.
1vuio0pswjnm7 12 hours ago [-]
This blog of generally gibberish hits the HN front page with an astounding frequency. IMHO, there are many interesting blogs on "system administration" topics that are submitted to HN every week that never reach the front page while there are a handful of familiar, low-quality ones that routinely appear on page one.
itsanaccount 11 hours ago [-]
Much of tech is a theatre, a jobs program that keeps people employed in a middle class salary so long as they diligently pretend to be engineers. This theatre serves as a prop for a higher level theatre in our virtual economy for investors and their game of financialization.

Its expected that as tech grows in number of workers clutching to that middle-class life-raft that the baseline of knowledge discussed in tech spheres (like this site) will sink lower.

fragmede 11 hours ago [-]
Is it September already?
type0 9 hours ago [-]
it has been for 30 years
wang_li 18 hours ago [-]
I think the point being made is that the fact that a user has rksh as their shell means nothing to samba, ftp, some features of ssh, httpd, cron, and etc. Fundamentally unix has pretty simple permissions, you're either root or you're not. The existence of a user account on a system is often enough to enable SMB and SSH access even if the only purpose of the account is to own files and an application process and is never intended to have interactive logins or to transfer data to and from the server.
nightpool 17 hours ago [-]
> I think the point being made is that the fact that a user has rksh as their shell means nothing to samba, ftp, some features of ssh, httpd, cron, and etc

Which has been true for...... 30 years? If not longer?

Attummm 21 hours ago [-]
Would be possible to share those reasons?
crabbone 20 hours ago [-]
Here are some:

* Doesn't scale. Having passwords in a plain text file is not a scalable solution for users directory. Can probably go up to a hundred users, but not much more.

* In computer clusters you want user identity to "stick" to the user when they use multiple machines, containers etc. That's why you have LDAP... but it doesn't help all that much because user id is encoded into the file system (huge mistake...) which makes it very difficult to contain users to things they should control. If your only mechanism was the /etc/passwd, it would mean you'd have to constantly synchronize this file across all those machines and containers you have.

Attummm 19 hours ago [-]
It may be old and not particularly appealing, but LDAP has been serving that role effectively at many companies.[0]

Using a terminal remains standard practice for sysadmins and devops.[1]

I believe there's some confusion in both the article and the comment between authentication and authorization. LDAP is fully equipped to handle both tasks.



crabbone 18 hours ago [-]
hiAndrewQuinn 19 hours ago [-]
To anyone reading this and thinking "yeah dummy, of course it doesn't scale because you're not supposed to store passwords in plain text in the first place" I'll direct you to Chapter 7ish of The Linux Programming Interface.

If you look in your /etc/passwd right now, you'll almost certainly see a single "x" where the (EDIT: no, it was still encrypted!) password originally was - nowadays that single "x" is an instruction to go look in /etc/shadow instead, for the salted hash of the password you're trying to check.

I think this minimizes the number of users who need read permissions to /etc/shadow, and the amount of time they need it for.

This has been your seemingly useless bit of Linux trivia for today. :)

vajrabum 19 hours ago [-]
/etc/shadow was born not because /etc/passwd had a plain text password but because the hashes became crackable and /etc/passwd is a public read file. Linux has never had them. Here's the man page indicating encrypted passwords for Unix v7 /etc/passwd release in 1979: https://man.cat-v.org/unix_7th/5/passwd
hiAndrewQuinn 19 hours ago [-]
Whoops! My bad, this is an even better bit of trivia.

My mistaken memory really sells the underlying point that everything old is new again.

hinkley 18 hours ago [-]
I have a vague recollection of my 20 floppy of Slackware already having /etc/shadow. That would have been fall of 92 or winter 93, based on where I was living at the time.
fuzztester 9 hours ago [-]
Shadow file was definitely from quite a while ago.

Can't remember exact date, but might have been around time of SVR4 intro.

I know because I remember going "ugh", but without investigating the reason why it (shadow) was introduced :) - which was of course wrong on my part.

mmcgaha 17 hours ago [-]
I have a vague recollection of being given the choice on a 90s vintage distribution with some warning about security and password length if I did not use shadow passwords. At some point in the early 2000s we started authenticating regular users against AD but the shadow file was still there for root.
hinkley 14 hours ago [-]
We had a couple of labs of sparcstations that just went away a couple of times a year because something bad would happen with all of the NFS mounted partitions and they'd have to turn the cluster on one box at a time to prevent thundering herd issues with NFS.

I think they may have been mounting parts of /etc as well. People get the idea that managing accounts for a cluster of boxes should be centralized. It's all fun and games until the network mount disappears.

chasil 19 hours ago [-]
That was not a "plaintext password," it was a DES hash (from 7th edition onwards).

This is the same format used by the classic htpasswd utility.


dsr_ 19 hours ago [-]
plaintext vs plain text

unencrypted vs unstructured

Of course, unstructured is also incorrect; the passwd and shadow files have structured records, one per line.

thwarted 16 hours ago [-]
…and being structured, the passwd file content should be accessed with the getpwent family of functions.
bhawks 8 hours ago [-]
Which unfortunately are not thread safe.
neuromanser 15 hours ago [-]
"unencrypted" is normally written as "cleartext". "plaintext" means "(readable / intended to be read) without a special viewer". Your.ssh /id_rsa is plaintext but not cleartext.
hinkley 18 hours ago [-]
My school had 30k students, including grad and doctoral students. When they gave students shell accounts, they tried to put them all onto a single Sequent box. They got my incoming class, the following, and anyone previous who asked for one onto that box. I’m pretty sure it had an /etc/password file, and would have had about 8-10k people on it.

After that they gave up. Even with aggressive ulimits it was too hard, and each new class was apportioned to a separate Sparc. Which was a shame because we learned an awful lot about Unix administration from users pranking each other, figuring out what they did and how they did it, protecting yourself and retaliating (some people would prank others without first protecting themselves).

Made it a lot harder chatting with people from other classes as well. For electives and humanities you weren’t always in classes with people your exact age. They could be ahead of you or behind.

naasking 18 hours ago [-]
> Doesn't scale. Having passwords in a plain text file is not a scalable solution for users directory. Can probably go up to a hundred users, but not much more.

This simply cannot be true. A users directory that is frequently read will be in cache. The file is also fairly simple to parse. Even on old hardware you should be able to parse thousands of users.

wang_li 18 hours ago [-]
It's more of a problem of the number of nodes your users will be accessing than the number of users. It's a PITA to make mechanisms for password changes, for adding and removing users, for unlocking accounts, etc. when you have a distinct file on each server that needs to be changed. As well as adding new nodes to the environment and bringing them up to date on the list of users and etc.
naasking 17 hours ago [-]
Fair point, networking always makes things more complicated. I'm not sure it's really that much more complicated though. Like any concurrency problem with shared state, a single-writer and multiple readers keeps things simple, eg. a single host is authoritative and any changes are made there, and any file changes trigger automated scripts that distribute the changed file over NFS, FTP, etc.

As long as new nodes start with the same base configuration/image this seems manageable. Simple to do with inotify, but even prior to that some simple C programs to broadcast that a change is available and listen for a change broadcast and pull the changed file is totally within the realm of a classic sysadmin's skillset.

crabbone 18 hours ago [-]
You would have to lock the file, or guarantee consistency in some other way. Right now, I don't believe Linux does anything about consistency of reads / writes to that file... which is bad, but we pretend not to notice.

So... the system is kind of broken to begin with, and it's kind of pointless to try to assess its performance.

Also, it would obviously make a lot of difference if you had a hundred of users with only a handful being active users, or if you had a hundred of active users. I meant active users. Running programs all the time.

NB. You might have heard about this language called Python. Upon starting the interpreter it reads /etc/passwd (because it needs to populate some "static" data in os module). Bet a bunch of similar tools do the same thing. If you have a bunch of users all running Python scripts while there are some changes to the user directory... things are going to get interesting.

naasking 18 hours ago [-]
> You would have to lock the file, or guarantee consistency in some other way.

I think the standard approach to atomicity is to copy, change the copy, then move that copy overwriting the original (edit: file moves are sorta atomic). Not perfect but generally works.

I agree that this approach is not good for a users directory, I'm just disagreeing that the reason it's not good is performance-related.

fragmede 10 hours ago [-]
Moves are atomic. During the move, at no time is it possible to get the contents of file 1 and file 2 confused when reading from the file descriptors. (Confusion by the human operating things is eminently possible.)
pjc50 17 hours ago [-]
Most systems come with "vipw" which does the atomic-rename dance to avoid problems with /etc/password. In practice this works fine. Things get more complicated when you have alternate PAM arrangements.

A whole bunch of standard functions like getpwents() are defined to read /etc/password, so that can't be changed.

codys 12 hours ago [-]
`getpwents()` is not defined to only read `/etc/passwd`. There is only a requirement that there is some abstract "user database" or "password database" (depending on if you're reading the linux man pages or the Single Unix Specification man pages).

In practice, `getpwent` on linux uses the nsswitch mechanism to provide return values from `getpwent`. One can probably disable using `/etc/passwd` entirely when using glibc if: all users do use `getpwent`, and you remove `files` from the `passwd` entry in `/etc/nsswitch.conf`.

pseudostem 18 hours ago [-]
Exactly, even large textfile based DNS servers have capability to "compile" the textfile to a db file for faster access.
crabbone 18 hours ago [-]
So what if they do?

This file is a public interface exposed by Linux to other programs. So what if Linux caches its contents when eg. Python interpreter on launch will read this file. And it's not coming from some "fake" filesystem like procfs or sysfs. It's an actual physical file most of the time.

pjc50 17 hours ago [-]
> user id is encoded into the file system

This is kind of unavoidable, but you do have 32 bits to play with. Windows did it slightly better with the SID: https://learn.microsoft.com/en-us/windows-server/identity/ad...

> which makes it very difficult to contain users to things they should control

It's not the file system that's the problem here, it's that "everything is a file" is not true for a whole bunch of important stuff that you might want to apply access control to on a UNIX system. Such as the right to initiate TCP connections. This sort of thing is why containers are so popular.

NIS and LDAP do let you have a large number of users. Heck, we managed a few thousand users in /etc/password back when I was running https://www.srcf.net/ .. in 2000.

TFortunato 17 hours ago [-]
> it's not the file system that's the problem here, it's that "everything is a file" is not true for a whole bunch of important stuff that you might want to apply access control to on a UNIX system

I wonder if there has ever been an attempt to really lean into, and push the limits of sticking with the "everything is a file" philosophy in this realm.

I.e. how far could you get with having special files for fine grained permissions like "right to initiate a TCP connection", and making access control management be, essentially, managing which groups a user belonged to?

jampekka 15 hours ago [-]
Plan 9 probably took this the furthest. Sad it didn't take off. https://en.m.wikipedia.org/wiki/Plan_9_from_Bell_Labs
generalizations 15 hours ago [-]
I think that was Plan 9.
tenebrisalietum 15 hours ago [-]
I think Hurd and Plan 9 take the EIAF further.
zare_st 11 hours ago [-]
Plan9 tried to "remedy this".

But in reality a file is not a good abstraction for an internet socket. The ACLs would in essence spell out firewall rules. Because the bigger question is where can it connect to than "user" that is connecting.

That's why this is done on the level of kernel networking, where kernel knows what process is trying to open a socket and can firewall it.

dizhn 19 hours ago [-]
This sounds like a completely unrelated thing and you are not constrained by the plain text password/shadow file for scale. NIS existed for many decades. You can even use Active Directory (or samba) for authentication and user management.

But the article is not about this at all.

crabbone 18 hours ago [-]
This shows you either didn't read what you replied to or don't understand the subject.

This file is the public interface of the Linux system to everyone who wants to get information about users on the system. It doesn't matter that alternative tools exist: they were already mentioned in the post you replied to. It's not the point...

dizhn 17 hours ago [-]
If I didn't understand I'd be grateful if you could explain it.

As far as I know that file does not get referenced for the users in an external directory server. That's how the systems scale without needing to put the users in the file. Aren't we talking about a high number of users (and their authorization levels) when talking about scalibility in this case?

Phrodo_00 11 hours ago [-]
> This file is the public interface of the Linux system to everyone who wants to get information about users on the system

No it isn't. PAM is. The password file is only one of the places where users might be defined.

marginalia_nu 12 hours ago [-]
> * Doesn't scale. Having passwords in a plain text file is not a scalable solution for users directory. Can probably go up to a hundred users, but not much more.

Why not? A file 100,000 line file will only take a moment to scan.

generalizations 15 hours ago [-]
I've wondered why we don't have a passwd.d folder, the way we do with other things in the UNIX filesystem, with individual user accounts represented by individual files. Could even retain the same line-oriented format, just stored separately.
eternityforest 11 hours ago [-]
That's the first understandable explanation I've ever heard of what exactly LDAP is and what it's for!
fanf2 20 hours ago [-]
Several are outlined in TFA
no_time 20 hours ago [-]
Tangent, I can't find what "TFA" stands for. My gut tells me it's "The Fucking Article". Am I correct?
InvaderFizz 20 hours ago [-]

TFA = The Fucking Article.

Much like:

RTFM = Read The Fucking Manual.

mannykannot 19 hours ago [-]
As I said to my mother-in-law, the 'F' is silent.
dotancohen 17 hours ago [-]
When Gwen Shotwell was asked about the acronym BFR on international television, she replied "Big Falcon Rocket". Lovely response, quite dependent on context!
pxc 17 hours ago [-]
This is like how I use 'ofc' to abbreviate 'of course'. Once upon a time the 'f' may have stood for something, but I never use it that way. For me, 'the F is silent'.
qazxcvbnm 19 hours ago [-]
I pretend its The Forementioned Article
codetrotter 18 hours ago [-]
I like to read it as The Featured Article
NavinF 20 hours ago [-]
Yes, but in polite company you can pretend it means "The Freaking Article"
BLKNSLVR 19 hours ago [-]
In polite company you say "The article" or "read the manual" and patiently await your reward, which is their asking "what does the 'F' stand for?", to which you reply only with a condescending look and raised eyebrow(s).

That look of realisation is precious.

I've manufactured this experience once or twice, and it's wonderful.

klibertp 19 hours ago [-]
I think "Friendly" was/is popular explanation where devs tried to translate their subculture into something generally digestible.
evilduck 18 hours ago [-]
Digestible maybe, but swapping "friendly" in for "fucking" changes the tone and intent of someone's statement. At least "freaking" expresses similar, if muted, exclamation.

A recipient who is being not-so-subtly reproached with an F-bomb acronym might misunderstand what is being implied.

hinkley 18 hours ago [-]
But when the person asking was management, and asking for the tenth time, there was a decided advantage to changing the tone.

All of that is now wrapped up in the initialism.

tremon 19 hours ago [-]
Fine instead of Freaking is much nicer.
dotancohen 17 hours ago [-]
Or the fine article.
worble 20 hours ago [-]
edgyquant 19 hours ago [-]
I really hate this acronym and this comment is no different from saying “read the article” which is against the guidelines here
codetrotter 18 hours ago [-]
> saying “read the article” which is against the guidelines here

The guidelines say that you should not accuse someone of not having read the article. However, as the guidelines say it is fine to point out that something is mentioned in the article.

There is a subtle difference.

From the guidelines:

> Please don't comment on whether someone read an article. "Did you even read the article? It mentions that" can be shortened to "The article mentions that".

Parent comment was in line with the guidelines IMO.

And as for “TFA” as an acronym I like to read it as meaning “The Featured Article”. Then it seems nice and friendly.

taneq 20 hours ago [-]
I'd assume any code in a non-memorysafe language that parses any freeform data entered by the user is a potentially exploitable security vulnerability, so an interactive shell is a huge surface area for attacks?
dsr_ 19 hours ago [-]
Yes, but irrelevant here. Basically any shell access means you've changed from preventing remote code execution to preventing privilege escalation, which is much harder.
hinkley 17 hours ago [-]
Which is why sudo has its own editor.

If you fuck up the sudo file while saving it, you might no longer be able to log in to fix it. Before I knew about sudoedit I would open two shells as root, edit the file, then use a third window to make sure I could still sudo.

With two windows I could accidentally close the subshell in one without locking myself out. Think if it like linemen, who use two tethers for climbing structures. They are never detached from the safety lines.

neuromanser 15 hours ago [-]

  sudo visudo
photochemsyn 19 hours ago [-]
Ask the chatbot:

1. system: in the context of setting up secure remote access to a Unix-like system, discuss whether relying on the passwd file and shell behavior as an effective means of authentication and access control is a good approach. What are some reasons this is not (or is) an effective approach, which should not (or should) be used on modern production systems. user: system administrator on a Unix-based network. assistant: technically, there are several reasons...

2. If you have a collection of Unix systems, can you reasonably do a certain amount of access control to your overall environment by forcing different logins to have specific administrative shells?

eviks 20 hours ago [-]
But when was it ever effective if 30 years ago it was already well known?
tannhaeuser 19 hours ago [-]
Last time it might've been effective was probably in old-school Unix time sharing with users connected via tty's rather than TCP/IP. Already early SQL databases, with the possible exception of Informix SE, had a client/server process model where the server process had full access to all data files and would at best authenticate sessions but not individual accesses against /etc/passwd such as via Oracle's pipe/bequeather connector but more commonly would assume fixed global roles and handle auth on the app side. As soon as IP and "services" were introduced, /etc/passwd stopped being effective, as pointed out by bluetomcat [1]. Actually, even gaining shell access is considered game over from a security PoV, due to multiple privilege escalations.

[1]: https://news.ycombinator.com/item?id=37462806

pmontra 20 hours ago [-]
It was effective for a ftp server accessing public directories in the home of users. I can't remember the details but you would use the username and password of the user to exchange files with and get into that directory. All transmitted as cleartext, of course.

30+ years ago we already had services (daemons!) with their own user id, to keep them isolated from root and the human users. This post is as news as the invention of hot water.

j16sdiz 20 hours ago [-]
> It was effective for a ftp server accessing public directories in the home of users. I can't remember the details ...

Most ftpd need a shell whitelisted in /etc/shells .

In macOS, /etc/shells begin with this comment:

  # List of acceptable shells for chpass(1).
  # Ftpd will not allow users to connect who are not using
  # one of these shells.
19 hours ago [-]
dizhn 22 hours ago [-]
I don't get it. When was shell involved with using Apache basic passwords or LDAP authentication? It requires extensive extra steps (pam modules etc) to plug these things into a unix system for authentication purposes. Also that would be authentication but access control implies authorization.
totetsu 21 hours ago [-]
Yeah my reading comprehension process maxed out a core on this one.

> First, you almost certainly operate a variety of services that normally only use Unix logins as a source of (password) authentication and perhaps a UID to operate as, and ignore the login's shell. This is the common pattern of Samba, IMAP servers, Apache HTTP Basic Authentication, and so on.

So you have a user on your server nginx:x:100:101:nginx:/var/lib/nginx:/sbin/nologin

And your also running samba network shares, you point your samba client at your server and use user nginx and inexplicably the password you also set for that user to login? This a service is using etc/shadow basses authentication but not sending the message in /etc/nologin .. presumably samba won’t work really in this case..

>In some cases you may be able to teach these services to look at the login's shell and do special things, but some of them are sealed black boxes and even the ones that can be changed require you to go out of your way. If you forget one, it fails open (allowing access to people with an administrative shell that should lock them out

Is this talking about setting up applications..like a web server, that would give a http access to a uses home for, And having these services authenticate with the servers etc/shadow or configured Pam providers, and also then check out the shell in /etc/password to gracefully handle access management and error messages?

tetha 17 hours ago [-]
Mh. I think the problem is: There are (at least) 2 fundamentally different use cases for linux/unix systems.

One is what I'd call a shell-server. On a shell-server, I have a bunch of accounts for users, and there are services supplied for these users. There will be /home/tetha, and /home/tetha/share and /home/tetha/http. And then you have some SMB sharing /home/*/share and you login there with your password, Apache serves /home/*/http for the intranet and so on. This is a very common setup at universities, for example.

The other thing is what I'd call an application server or a service server (but that name sucks). Here, you have a system and the main purpose of the system is to serve a web page via nginx, or be a postgres node and such.

These service-systems tend to be both more controlled, but also simpler. You need to grant a rather small, very known set of users access to these - 10 - 30 usually. And, honestly, these service-level systems tend to have very streamlined permissions, because realistically, shell-access is enough attack profile to be considered root access unless you are very diligent.

Shell-servers however are very, very complex to handle. One big shell-server can be overall more complex than many infrastructures around in total.

mypgovroom 20 hours ago [-]
Ok. I read it twice trying to catch something but had the same thoughts as you.
jmbwell 18 hours ago [-]
Judging by the thread here, the very premise seems difficult to imagine today. But there was a time, indeed, when end users regularly logged in to a Unix system as themselves, and their shell specified the program they could run, like a line of business app or something, and short of exploiting a vulnerability in that app, that was all they could access, sitting there at a physical terminal typing on a keyboard. There just weren’t that many other ways to spawn a process.

Meanwhile, these days, it seems like the only user ever running anything is docker, and “access control” has an entirely different set of meanings.

djur 9 hours ago [-]
And the author is a sysadmin at a university, and universities are pretty much the last vestige of that traditional Unix login model of accessing shared services. From some other articles he's written, it sounds like his environment has been very conservatively updated over the years.
salzig 21 hours ago [-]
It’s always interesting to find people who don’t know about `-N` („Do not execute a remote command. This is useful for just forwarding ports.“[0]), which was quite neat to access the MySQL on the same host (with no root database Passwort, duh) at one of my previous employers.

[0]: https://man7.org/linux/man-pages/man1/ssh.1.html

madeofpalk 14 hours ago [-]
Side note - is this author noteworthy for something in particular? Their somewhat average posts consistently make it to the front page and tend to get a more mixed/negative reaction than normal https://news.ycombinator.com/from?site=utoronto.ca
KaiserPro 16 hours ago [-]
I have had the pleasure(?) of running a large linux network, I don't think it was ever really the case that shells were a viable access control mechanisms on their own.

Firstly it only really worked if you were all sharing the same machine with remote terminals, which most people don't do anymore. Second NFS happened when if you configured it badly you could just pretend you were any user you liked.

I'm assuming this is part of the reason why kerberos was invented. Basically the only practical way to tie down a network of machines was to make sure that authentication was done with LDAP and Kerberos. LDAP did the name, UID/GID and user metadata and kerberos the authentication. You could then use that ticket to gain access to other things (yes, even over HTTP, NFS or SSH)

Nowadays you'd use active directory, which is LDAP+Kerberos, but with a nice expensive gui.

/etc/passwd(or shadow) died _years_ ago, It was dodgy even in the 90s, let alone now. Its fine for single user machines, but not networked.

blueflow 22 hours ago [-]
The post does not back up its headline? How can a SHELL=/bin/false be bypassed via SSH?

For the various kind of forwarding SSH supports, they all can be disabled via sshd_config.

tyingq 21 hours ago [-]
I think it's comparing to the "old days" when there was a more 1:1 relationship of service-on-a-port plus a specific userid. Because the article specifically calls out:

"One of these services is SSH itself, since you can generally initiate SSH sessions and ask for port forwarding or other features that don't cause SSH to run the login shell"

But, even that sort of falls apart because we also had inetd in the "old days", which spawned lots of different things as different users without invoking a login shell.

Generally, the article seems to be lamenting that not everything is gated by userids and groups anymore. That's true, but it doesn't seem recent to me. Aside from inetd, I could (and did) massage kermit (or uucp, etc) into being a multi-service gateway in the 1980's.

I suppose it's somewhat correct in the idea that figuring how any particular service limits rights is now very complicated. You have the old familiar stuff (users, groups). But now you also have virtual machines, containers, namespaces, capabilities. And things like seccomp and apparmor. Then, various sandboxing schemes within utilities, languages and frameworks or OS facilities like ebpf.

juped 19 hours ago [-]
It seems to me (it's kinda unclear) that the article is talking mostly about various other things pulling users from /etc/passwd and the ssh thing is an aside. For anon ssh you can have e.g.

  Match User anonymous
          PasswordAuthentication yes
          PermitEmptyPasswords yes
          DisableForwarding yes
          PermitTTY no
and possibly ForceCommand and ChrootDirectory depending on how you're sandboxing anonymous and to what; plus a restricted login shell (the above anonymous user of mine has gotsh, got's version of git-shell).
batch12 21 hours ago [-]
Ive used something like ''' ssh -t user@host /bin/sh '''

To bypass shell restrictions in the past, but I'm not sure if that will work with your example.

blueflow 21 hours ago [-]
This won't work because the command send to the server is not an argument vector, but a command string interpreted by the users login shell.

`ssh -t user@remote /bin/sh asdf` would execute `/bin/false -c "/bin/sh asdf"` on the remote.

batch12 21 hours ago [-]
Makes sense, thanks for the clarification.
LinuxBender 18 hours ago [-]
Feel free to try it out

    sftp share@ohblog.net   (no pw)

    # grep share /etc/passwd /etc/shadow
The partially redacted /etc/ssh/sshd_config is copied to /pub/ in the SFTP account.

If you can bypass the restriction please do share how it was done. I don't offer bug bounties but I think people would find it interesting. OS is Alpine Linux. All CPU mitigations are disabled in the VM. No MAC As in no SElinux or AppArmor. I won't complain, just pretty please don't DDoS the server or anything that would make that VPS do work.

Feel free to also tinker with the web and voice chat server on that node.

emmelaich 9 hours ago [-]
You can pass various env vars with ssh, typically restricted to LANG and LC_*.

But I vaguely remember that in the past it may have been anything, including SHELL.

salzig 21 hours ago [-]
For a port-forward with `-N` on client side.

Besides that, I don’t know.

dboreham 18 hours ago [-]
In case anyone is tempted to read the article: it's totally incoherent, even to someone knowledgeable in the field.
flanked-evergl 15 hours ago [-]
I guess I'm just lucky that I have never ever in my life even once seen something almost similar to using a Unix shell as an access control mechanism.

Maybe next we will hear that Hammers are not viable screwdrivers any more because, you know, that is also probably something everybody already knows.

totetsu 6 hours ago [-]
>In the realm of unconventional tools, the potential application of biological structures has always been a topic of intrigue. This study delves into the material science behind the potential of hamster claws to function as micro-screwdrivers, given their inherent sharpness and structure.

Using scanning electron microscopy (SEM), we characterized the microstructure of hamster claws, revealing a keratinous composition with intricate surface patterns. Nano-indentation techniques were employed to determine the hardness and resilience of the claws. Their sharpness was quantitatively assessed using a sharpness index, which considered both geometric and material properties.

To test the potential application as micro-screwdrivers, we designed a set of experiments where hamster claws were used to engage with micro-screws commonly found in electronics and precision instruments. The results indicated that while hamster claws can fit into the grooves of certain micro-screws, the torque they can generate is limited due to their flexibility and the lack of a proper grip mechanism.

post-it 15 hours ago [-]
Yeah, this post is giving https://xkcd.com/2071/
h2odragon 21 hours ago [-]
are they speaking about changing the "shell" field in `/etc/password` as a means of broader access control?

That went away a long, long time ago; the question of "which system am i authenticating myself to" was often already too complicated for that way back when when "shadow passwords" were a new idea.

poppafuze 17 hours ago [-]
At best, this is an exposition of someone's conflation of their perception of a controller problem as a view problem, with the implied model problem ignored.
onetimeuse92304 20 hours ago [-]
I pretty much assume now that if somebody has ability to run an arbitrary process on the machine (ie shell), they have root access to that machine regardless of their starting access level.
rlpb 12 hours ago [-]
I think this is being approached backwards - both by the article and by commenters here.

A Unix account is a viable access control mechanism. If you create one, you give its human user access to do everything that the Unix user can do. This can be very useful.

But others want to give humans users more restricted access than their corresponding Unix account. This is futile, since the Unix account is the basic unit of access control on a Unix or Unix-like system. The author is correct that if you want to do this then you must create a sandbox. General tools won't do, because they're not designed for it, and/or are generally swimming against the tide.

debarshri 20 hours ago [-]
One of the learnings lately has been that when you think about access control, it is combination of the downstream access control mechanism + a network layer grant to access the resource. For eg. If you want to access a server or host, you have some authorization to SSH into it but also by you have network access only to that server or host from your source and then authorization is revoked also the network access to the server or host is revoked too.
nickdothutton 19 hours ago [-]
I'd better re-read this article because I don't think shells were ever (in my 20something-mumble years)a terribly strong access control mechanism(). Without putting in the effort. Meaning an appropriate (poss non-default) security model, chroot/jails, possibly pledge etc.
cardiffspaceman 9 hours ago [-]
I skimmed this article using a different POV than many of you, and it made sense. From the other POV it is clear why many of you don’t like or in some cases understand it.

If your idea of “Unix” is Linux kernel with Busybox and dropbear, it makes sense. I think.

hoistbypetard 15 hours ago [-]
This is a response to the headline and not yet to the story: were UNIX shells ever an access control mechanism? I never viewed them that way.
AtlasBarfed 19 hours ago [-]
Basically they want a somewhat poorly designed configuration map (environment variables) to be attached to these operations, but instead everything comes from adhoc/bespoke configuration sources on a per app basis (like ~/.ssh/config)
stonogo 15 hours ago [-]
Using custom shells for IMAP or HTTP auth must have been the parallel reality where checkpassword(1) never existed. I certainly never ran into this behavior in the wild and would have strenuously objected had I done so. Setting custom shells is fine for providing tunneled services over ssh tunnels or the like (many git hosts use this functionality) but using them for access control just meant your only safety net was whether the program's author was really good at preventing string overflows. This was never a good idea.
dingosity 17 hours ago [-]
Uhh... wat?
0xbadcafebee 16 hours ago [-]
Can somebody translate this to english? A shell was never an access control mechanism. It was a prompt at which you could type commands to run. As a hack they added authentication to it some time in the 60's at MIT.

> Today, the only two measures of login access control that really work in a general environment are either scrambling the login's password (and disable any SSH authorized keys) or excluding the login entirely from your various authentication data sources (your LDAP servers, your Apache htpasswd files, and so on). It's a pity that changing people's shells is no longer enough (it was both easy and convenient), but that's how the environment has evolved.

This literally makes no sense. Scrambling a login password is not an access control mechanism. Excluding "a login" (a what?) from an authentication data source... the hell does this mean? You mean disabling a user account?

The last part, "changing a user's shell", makes a little sense, as you used to be able to prevent a user from logging in by changing their shell to "/bin/false" or something, but that isn't disabling authentication, that's just breaking the shell. Authentication still works if the shell has changed, it just can't execute the shell after you authenticate.

The proper way of disabling the account is to set the "disabled account" bit in the shadow or password file. But that's just one authentication mechanism (NSS). There is no universal authentication mechanism, so for any other given authentication mechanism, you need to disable it however that given method allows you.

kmeisthax 14 hours ago [-]
Traditional Unix conflates authentication and authorization - if you can authenticate as a user you are authorized to use the computer, full stop. If you want to later revoke authorization, or only authorize certain services but not others, Unix provides no general means to do so.

Scrambling the password works as a deauthorization mechanism solely because you strip the user of the ability to authenticate. This wouldn't clear authorized_keys, though; services that needed to implement new authentication mechanisms generally did not bother extending /etc/shadow or NSS in an obvious way everyone agreed upon.

Changing the login shell used to work because Unix used to be used solely through the medium of /bin/sh. This, however, conflates two different signals:

- Who should be allowed to start an interactive session on this machine?

- What kind of shell does this user prefer to use?

We pretend that disabled users just really love using this one particular shell that immediately kicks them out of their login session.

The only bulletproof way to deauthorize a user is to unperson them - delete the account. Except if you do this then their old files still sit there on the disk with their user ID. If you reuse the user ID then the new user gains authorization to the old user's files; so you have to keep track of unpersons to avoid reusing their IDs or meticulously reassign their files to a dedicated cleanup user.

0xbadcafebee 12 hours ago [-]
> Traditional Unix conflates authentication and authorization - if you can authenticate as a user you are authorized to use the computer, full stop.

Incorrect. Nearly every service in a Unix computer has its own authorization mechanisms, there is no blanket authorization over an entire host.

The login service has a "nologin" and "securetty" files. Sudo has its sudoers file. RSH has the .rhosts file. FTP daemons have their own authorization logic. NFS authorization options could override local filesystem permissions. Filesystem permissions defined the authorization for device files, but network services (such as CUPS) would add their own authorization mechanisms. Etc, etc, etc.

The difference between authentication and authorization has been apparent since time-sharing systems were invented. The operators were authorized to perform different operations than the bog-standard users. There hasn't been a time since the 60's that everyone was authorized the same just because they were authenticated.

> Scrambling the password works as a deauthorization mechanism solely because you strip the user of the ability to authenticate.

Doesn't work. If you're using SSH key authentication you can skip password auth. With RSH, password auth isn't required if you're coming from a trusted host defined in a .rhosts file.

> The only bulletproof way to deauthorize a user is to unperson them - delete the account.

That doesn't always work either. There may be more than one authentication system, and they may be configured to simply skip to the next authentication method if a user account is not found. So you would have to delete the account from every authentication system connected.

You have to use the prescribed deactivation method for every authentication system connected, otherwise the first auth method may skip the deactivated user but the second system would pick up its own user with that name/ID.

15 hours ago [-]
bananapub 15 hours ago [-]
I think you've got the wrong end of the stick - it's about forcing the login shell to something (like sftp or rbash or or /bin/nologin whatever) which was a historically somewhat popular thing to do
14 hours ago [-]
Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact
Rendered at 08:34:02 GMT+0000 (Coordinated Universal Time) with Vercel.