
Stupid Unix Tricks - signa11
https://sneak.berlin/20191011/stupid-unix-tricks/
======
raimue
Regarding the point of "SSH: Faster Crypto", you should not enforce only one
single specific cipher for ssh. The reason also seems wrong, modern hardware
should be capable of achieving better performance with an AEAD cipher (such as
AES-GCM or ChaCha20-Poly1305) instead of AES-CTR, as the latter also requires
an additional HMAC.

If there really is a slow (or insecure) cipher you do not want to use, remove
it by prepending a minus sign, for example `Ciphers -3des-cbc`, which keeps
all other default ciphers. Otherwise, you will miss out on better ciphers as
they are added and would be stuck on this one forever.

~~~
xoa
> _Otherwise, you will miss out on better ciphers as they are added and would
> be stuck on this one forever._

Is that actually a real concern at this point vs the risk that comes from not
white listing a few known reliable ones? It seems like old-style security,
favoring modularity and "what if we need to change this someday soon?", but in
practice it's turned out to be a lot less valuable than expected and raise
significant risks of accidentally using something bad. We seem to be past the
point where new ciphers being "better" is actually an event to be expected
with any real frequency, prime/elliptic curve seems pretty mature now. Post-
quantum could be a new frontier at some point, but may well require
significant other changes as well.

WireGuard for example decided to just flat out say that any cipher changes
will be tightly coupled with a full on version change. If you're using it you
know exactly what you're getting and that's it.

I don't disagree that white listing means care with what is chosen, and
picking AEAD-based seems like a better idea anyway (WG is
Curve25519/ChaCha20-Poly1305/SipHash/BLAKE2s). Plus there is server
compatibility to consider in some cases. But I'm not sure the logic of "you
might miss out on better ciphers as they are added" is convincing either, vs
setting yourself an alarm to recheck your SSH setup every year or two.
Shouldn't any cipher additions/deletions arguably be something you actively
consider, rather than have automagically added?

~~~
paulddraper
> what if we need to change this someday soon?

Git was created in 2005 and its hash algorithm is already outdated.

Additionally, software and hardware support continue to develop for better
performance.

~~~
CodesInChaos
SHA-1 was already broken (Feb 2005) when git was first published (April 2005).
But Linus decided that git doesn't need a collision resistant hash function.
[https://marc.info/?l=git&m=115678778717621](https://marc.info/?l=git&m=115678778717621)

~~~
paulddraper
SHA-1 was not broken until 2017.

[http://shattered.io/](http://shattered.io/)

If you know an earlier instance, go ahead and take the crown from the
shattered folks.

\---

The choice to use SHA-1 was a trade-off of security, size, performance. If
Linux invented git today, I imagine the choice would have been different,
because those parameters are now different.

~~~
CodesInChaos
In cryptography broken means "known attack significantly faster that brute-
force", which was published in 2005. And cryptographers were advocating for
deprecating it several years before that, because the security margin was
clearly insufficient.
[https://www.schneier.com/blog/archives/2005/02/sha1_broken.h...](https://www.schneier.com/blog/archives/2005/02/sha1_broken.html)

The time between a theoretical attack and practical demonstration of an attack
should be considered a grace period we can use to migrate to a secure
primitive. Choosing SHA-1 for an application which relies on collision
resistance after the 2005 papers is plain incompetence.

Git chose SHA-1 because Linus did not consider collisions a problem. The
downsides of SHA-256 were pretty small even then (32 instead of 20 bytes, and
somewhat slower performance which is still faster than most IO).

------
asaph
> Don’t try to install things with brew if brew is not installed:
    
    
       if which brew 2>&1 /dev/null ; then
            brew install jq
       fi
    

This just hides a useful error message (brew not installed). I would rather
just see that error message (either interactively or in a log) and have the
script fail. Hiding the error message just leads to an eventual failure down
the road when jq is invoked.

~~~
reacweb
In bash, there is the build-in command named "command". I have used it for the
same purpose, like in:

    
    
        command -v brew >/dev/null && brew install jq

~~~
raldi
Wow. It's impossible to google, and on MacOS, `man command` is useless.

~~~
s_gourichon
$ help command

command: command [-pVv] command [arg ...] Execute a simple command or display
information about commands.

    
    
        Runs COMMAND with ARGS suppressing  shell function lookup, or display
        information about the specified COMMANDs.  Can be used to invoke commands
        on disk when a function with the same name exists.
        
        Options:
          -p    use a default value for PATH that is guaranteed to find all of
                the standard utilities
          -v    print a description of COMMAND similar to the `type' builtin
          -V    print a more verbose description of each COMMAND
        
        Exit Status:
        Returns exit status of COMMAND, or failure if COMMAND is not found.

~~~
m463
Thank you.

I never knew about help to describe a builtin shell command. normally
searching for something like "command" in the bash man page would be very
tedious.

also: help echo

~~~
imihai1988
i do think 'man command' should bring up the specific man page for this, so
there is no need to search into the bash man. this works with most builtin
shell commands. e.g. 'man ls' is a thing

~~~
stragies
On (at least) Debian systems (, and probably many more) `ls` is not a built-
in, but an external binary (`/usr/bin/ls`) is used.

`which ls` and `help ls` will show you, if it is similar on your system.

~~~
imihai1988
It does't need to be a built-in to have a man page (many first party and third
party libraries come with their own man pages).

------
roryrjb
_Before we begin, first note that bashrc refers to something that runs in each
and every new shell, and profile refers to something that runs only in
interactive shells (used by a user at a keyboard, not just a shell script, for
example). They aren’t the same and you don’t want them to be the same._

I'm not an expert on bash exactly though I am a heavy shell user (POSIX shell
for scripting) but this part doesn't sound right. When is .bashrc ever
executed when bash isn't interactive? And as far as I can tell when I open new
shells .profile isn't read. I am using Linux and tmux and the reason I mention
tmux is that it opens bash as a login shell and therefore .bash_profile is
also loaded. Is this a mac OS thing or the version of bash mac OS comes with,
which I believe is really old due to some license issues.

~~~
tremon
_as far as I can tell when I open new shells .profile isn 't read_

True, iff you have a .bash_profile. Bash only reads the first of
~/.bash_profile, ~/.bash_login, ~/.profile. It will ignore the rest of the
list once it's found an existing file.

~~~
ashtonbaker
This explains so many of my problems. Thank you.

~~~
em500
[https://hackernoon.com/bash-profile-vs-bashrc-vs-bin-bash-
vs...](https://hackernoon.com/bash-profile-vs-bashrc-vs-bin-bash-vs-etc-bash-
tutorial-help-example-not-found-command-linux-mac-1c7f98c11186)

Note that in macOS every new Terminal (tab) opens a login shell, while most
GUI Linux environments don't. (In Tmux/screen it depends on the
configuration).

------
derefr
This inspired me to (quickly) write down my own Stupid Bash Tricks:
[https://gist.io/@tsutsu/2c11fc0a36000a46566e9fd62c60dea4](https://gist.io/@tsutsu/2c11fc0a36000a46566e9fd62c60dea4)

Most of it might be somewhat obvious; but scroll down to "Bash Hooks" for a
cool trick I've never seen anywhere else.

~~~
Falcorian
I found the OSX specific XDG section helpful, because I've been setting it to
~/.cache for years! Good to know there is a better way that the OS understands
(a bit a least).

------
jzzskijj
This got me to raise an eyebrow:

    
    
        if [[ -d "$HOME/dev/go" ]]; then
            export GOPATH="$HOME/dev/go"
        fi
    

Using a directory named "dev" not to store device files, but development
tools. I am so stuck with conventions.

~~~
iandinwoodie
This is a point of conflict for me. I use "~/dev" for all of my development
work, but I don't want to because of the convention set by "/dev".

My problem is finding an alternative to "dev" that is just as convenient. Do
any of you have any suggested alternatives?

~~~
mxuribe
I use ~/ops

...but not in the "operator" sense. Rather, the "operations" sense...and that
is because i used to use ~/projects...But i got lazy to type that out.

~~~
benibela
sometimes I use ~/opt

------
teekert
"Docker desktop for mac is closed source software, which is dumb for something
that asks for administrator permissions on your local machine. This lameness
aside, it runs the docker daemon..." ...Proceeds to run MacOS...

~~~
TheRealPomax
Like every time someone points this out: there are an unreasonable amount of
companies that don't let you pick anything else. It's either a macbook, or a
macbook, and if you want a different machine go buy it yourself and use it
outside of work hours "because we can't afford writing three different copies
of the same internal documentation for more than one OS when we're the ones
paying for the machine you work on".

And in an unfortunate twist, if you _have_ to run Docker, macos is actually
the best choice for that. Installing it on linux or windows is an exercise in
"you know what, maybe I should buy a mac for this instead".

~~~
as1mov
> Installing it on linux or windows is an exercise

...? Am I missing something obvious? Installing docker on Ubuntu is as simple
as

    
    
        sudo apt install docker.io
    

and you're done. Installing from the official repos is simple too if you want
the latest version [1]

[1] [https://www.digitalocean.com/community/tutorials/how-to-
inst...](https://www.digitalocean.com/community/tutorials/how-to-install-and-
use-docker-on-ubuntu-18-04)

------
yoloClin
The author configures lots of syncing by setting the location of config files,
I do it by setting up a whitelist based gitignore in my homedir:

    
    
      *
      !.gitignore
      !.bashrc
      !.ssh/authorized_keys
    

It's fast (comparative to a blacklist based 'git status' scan) and less work
:)

On a sidenote, I'm curious about the security implications of the git
repository - if the git host the service is breached, as far as I known
there's really nothing stopping the actor leveraging access to achieve code
execution on my host right?

I'm aware of commit signing but in the context of a raw git directory synced
over ssh an attacker could create and use any valid signature key to commit to
the repo. Hosting on Gitlab/Github would require a breach or significant abuse
of security controls, but is still possible, too.

~~~
Noumenon72
So you have a gitignore that says "ignore everything except these three files"
\-- what does that do? Is it supposed to replace the line where he curls those
files to github? Isn't it awkward having all your other git repos in your home
dir be under that git repo?

~~~
yoloClin
> what does that do? Is it supposed to replace the line where he curls those
> files to github

No, it is for synchronization. See the article sections titled 'SSH: Move Your
SSH Config File Into a Synced Folder' and 'Extra Credit'.

> So you have a gitignore that says "ignore everything except these three
> files" \-- what does that do?

My gitignore is upwards of 100 files, but allows me to track changes and
synchronize configurations across hosts, which I do often as I often work in
short-lived graphical VMs and across multiple hosts. Using a whitelist of
tracked files means 'git status' wont take seconds/minutes to scan the entire
directory tree under my homedir which seemed to be the case when using a
blacklist when I initially configured it.

> Isn't it awkward having all your other git repos in your home dir be under
> that git repo?

It breaks stuff like `git add -A` which I haven't fully solved, but don't
really feel the need to - most of my commits are 2-3 files at most and I'd
prefer to be aware of exactly what's being committed for the additional minor
overhead.

There's other alternatives, like rsync, which solve entire tree
synchronization but that's not what I'd normally like to do as my
ultraportable has a 128gb SSD and my daily driver is a 2TB laptop. I'd be open
to hear other suggestions, but at this point git is a convenient and flexible
solution that works well in my environment :)

------
11235813213455
With docker >= 18.09, you can connect directly over SSH by setting
DOCKER_HOST=ssh://<user>@<host>

------
nat
Is there any advantage/difference to using ProxyCommand with netcat vs just
saying "ProxyJump bastion.example.com"?

~~~
termie
ProxyJump was added in OpenSSH 7.3 so systems from a few years ago might not
support it. It does the same thing as ProxyCommand with -W %h:%p but you can’t
set custom options for the jump connection with ProxyJump.

~~~
stragies
OpenSSH 7.3 was released on 2016-08-01, so more than 3 years ago. Nobody
should be running SSH versions this old (hopefully).

~~~
Pete_D
CentOS 6 lives on in enterprise, unfortunately. (don't know exact OpenSSH
version but didn't support -J when I checked earlier)

------
lilyball
I've had my shell startup scripts modularized for many years now, but I do a
much more complicated system where the scripts actually have a function
`require` exposed to them that can be used to express dependencies. If you
`require` something that's already been loaded it does nothing, so each script
is still only just loaded once.

------
saagarjha
> I use Mac OS X (pron: “ten”).

To be extra pedantic: unless you’re running an eight-year-old OS, you are
likely running either OS X or macOS.

~~~
jlbang
Thank you!

------
visualphoenix
author should probably be using: command -v

instead of: which

~~~
frou_dh
Fighting the good(?) fight for POSIX shell portability.

[https://pubs.opengroup.org/onlinepubs/9699919799/utilities/c...](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html)

[https://shellhaters.org](https://shellhaters.org)

------
wyclif
His tip about running "make clean" on ~/Desktop is okay, assuming people
actually use Desktop the way he does. Which I observe that many, possibly
most, users don't. Apple says that "The desktop is where you do most of your
work", but I see a lot of desktops with no files whatsoever.

[https://support.apple.com/en-gb/guide/mac-
help/mh40612/mac](https://support.apple.com/en-gb/guide/mac-help/mh40612/mac)

~~~
pololee
Very true because I don't want any file icons on my wallpaper. Btw, i use this
[https://irvue.tumblr.com/](https://irvue.tumblr.com/)

~~~
jayrhynas
You can also hide all the desktop icons with a defaults setting:

    
    
        defaults write com.apple.finder CreateDesktop false

~~~
pololee
Aha, thanks for sharing!

------
donalhunt
> "always ssh as root" example

urggh... I've seen devs do this too many times and it breaks a bunch of stuff
when configured incorrectly. You almost never want "Host *" to have a user
entry.

also completely ignores the "don't ssh as root" opsec best practice. I would
strongly argue that even for dev environments, it's worthwhile building the
opsec muscle memory and spending the effort at the start of a project.

------
blfr
_The best way to store SSH private keys is in a hardware security module, or
HSM._

I have three Yubikeys. Would I need to add three ssh keys to every one of my
ssh accounts?

~~~
xenophonf
Yes.

If one Yubikey were lost, stolen, or damaged, you would then revoke its access
by removing the corresponding entry in ~/.ssh/authorized_keys.

------
chsitter
Thanks for the cached ssh connections thing, didn't know that was possible.
Not that useful when I'm on my environment with TMUX (typically have each
connection in its own tmux pane) but massively useful on all the jump boxes
where I don't have a sensible shell environment :)

------
saulrh
Using a tor hidden service for emergency ssh access is pretty sweet and I'm
going to have to go set that up for myself now. Maybe with an extra bit to
auto-publish the hostname so I don't have to write it down every time
something changes.

------
rhabarba
I find it weird that an article about "Unix tricks" requires the GNU bash
shell.

------
oweiler
Instead of which it's better to use command -v.

------
kerng
Ssh ProxyCommand: make sure to use ssh -W option rather then depending on
netcat.

------
esjeon
I was expecting something like

    
    
        cat file | less
    

Stop abusing cats!

------
m463
another interesting site is:

[https://dotfiles.github.io/](https://dotfiles.github.io/)

------
bregma
Bash is not Unix.

~~~
wglb
But it does run on my Unix boxes.

~~~
yjftsjthsd-h
Although amusingly, not exclusively; it also runs on Haiku and NT. (This isn't
at all to say that it doesn't fit in an article about Unix, since it's very
popular there (just like talking about Firefox on Unix wouldn't be out of
place), just a fun side note.)

~~~
waddlesplash
Haiku is a UNIX, though. :)

------
benburleson
Well, I had to stop reading when I scrolled a bit and some pop up blocked the
content with (I presume) the button to close it off screen on mobile.

~~~
frogpelt
There should have been an X at the top right corner.

Also, do you have reader mode on your device? That would fix it too.

~~~
deadbunny
Or you know, people could not put popovers on blogs.

~~~
TheRealPomax
If you're not browsing with an adblocker installed, then this complaint is
basically moot: it's 2019, the ad-free internet died years ago; use a decent
adblocker.

If they show up even with that active, though, now you have a valid complaint.

~~~
gknoy
While this is common on desktop, do you have suggestions for how to do this on
mobile?

~~~
yjftsjthsd-h
Firefox mobile supports extensions, including ublock origin (and umatrix, if
you're into that).

