2

I'm trying to automate the deployment of my blog.

Most CI providers are using virtual machines/Docker containers with Linux, so I'm learning about shell scripts and SSH now, which is all new to me.


What I have

In order to deploy the finished site from the CI server to the webserver, I'm connecting via SSH like this:

rsync -rSlh --stats build/ my-ssh-user@example.com:/www/htdocs/blah/tar
ssh -o StrictHostKeyChecking=yes my-ssh-user@example.com 'bash -s' -- < deploy.sh /www/htdocs/blah/

(code copied & pasted from multiple blog posts and tutorials)

Authentication is done via a SSH public/private key pair.


My question

Apparently even though I'm authenticating with SSH keys, the user name is still needed (both lines of code above contain my-ssh-user@example.com).

Given that the code above will eventually end up in a public repository on Bitbucket (because that's where the source code of my blog is):

Security-wise, would publishing my SSH username be a problem?
I'm not sure whether I should treat it like a secret or not.

On one hand, the actual authentication is done via SSH keys, so the username is "not that important". On the other hand, now everyone knows my username and could try to brute-force my password.

  • 2
    "StrictHostKeyChecking=no" - that's what should be ringing your alarm bells - not your username. – symcbean Feb 06 '19 at 22:18
  • @symcbean: As I already wrote in the question - I copied the code from some "deploy with Bitbucket Pipelines to your server" tutorials (including this part) and I don't know much about SSH yet. For a start, I googled what StrictHostKeyChecking does, and changed it in my code (and in the question) to `yes`. The SSH connection from CI server to webserver is still working, so this shouldn't be a problem anymore. – Christian Specht Feb 06 '19 at 22:32
  • 1
    If you are authenticating with public keys and only public keys, there's no danger of someone brute forcing your password... since password authentication would be disabled... unless they have your private ssh key. So, turn off password authentication and don't distribute your private ssh key. – RubberStamp Feb 06 '19 at 23:10
  • For more general advice about usernames, see [Should usernames be kept secret?](https://security.stackexchange.com/questions/4729/should-usernames-be-kept-secret) – Sjoerd Feb 07 '19 at 09:39

3 Answers3

3

On the other hand, now everyone knows my username and could try to brute-force my password.

Assuming you don't use the same username for every last thing, what you would want to do in the case of SSH is to not allow credential-based authentication. SSH can be configured to not accept credentials even if they are right, so that you are forced to use key-based authentication instead.

For this reason, you'd want to keep the key very very private. Your username is not nearly as important as the authentication method.

You could also add a "passphrase" to authenticate the key before the key is used to authenticate your user into the shell session, as additional security.

But, as symcbean mentioned in their comment, unless you're debugging something internally, StrictHostKeyChecking=no is a no-no.

psosuna
  • 201
  • 1
  • 7
  • My webserver is just webspace on shared hosting. I can configure SSH to be enabled or disabled, but that's pretty much it :-) I can set up a different SSH user for each website, so this user would be used **only** for this site. – Christian Specht Feb 06 '19 at 22:38
  • @ChristianSpecht Even so, that would be *security through obscurity*, which isn't much of a security plan. That being said, does this SSH access allow you administrator-level privileges onto the web server? If so, then you should be able to modify the configuration file where the configuration lives. But, don't change this until you have the key-based authentication set-up, or you could lock yourself out. – psosuna Feb 06 '19 at 22:40
  • Please clarify - what exactly is it that would be security through obscurity? – Christian Specht Feb 06 '19 at 22:44
  • Concerning the passphrase: As far as I understand, the passphrase must be entered manually when connecting? If yes, then I can't use it, because this is about a CI server connecting to a webserver during an automated build. – Christian Specht Feb 06 '19 at 22:44
  • @ChristianSpecht I'm referring to the practice of just changing your username on different servers. It's something, but it's not much. It's not a negative criticism, however -- Every layer helps! It just should never be the end-all be-all. – psosuna Feb 06 '19 at 22:45
  • @ChristianSpecht I'm sure you can find a way to automatically input the passphrase, but if actual input is an issue then yes, you may have to do without it. That being said, it's a nice thing to have, but it's also not foolproof, as it adds keystrokes which can be logged. – psosuna Feb 06 '19 at 22:46
1

You can avoid setting the username there, moving it to the sh config.

On your .ssh/config file place:

Host example.com
User my-ssh-user

And use just example.com above.

Moreover, you can even use a different name as an alias, such as blogmachine:

Host blogmachine
User my-ssh-user
HostName example.com

and it would actually connect to example.com

Ángel
  • 18,188
  • 3
  • 26
  • 63
1

How to hide the username

The above answers are great, but I want to add in one more simple option.

Most CI providers also have a way of storing "variables" that you can reference in your build scripts. To pick a real world example, bitbucket has "variables" and you can configure them at a few levels (for instance, at the repository level or the branch level). So you could imagine creating a variable named SSH_USERNAME. In your deployment script you would reference $SSH_USERNAME and when bitbucket runs the script it would fill that in with whatever you configured the variable to be. This has two advantages:

  1. You no longer need to put your username in your repository, adding a small layer of security
  2. You can have different values for different branches/builds, allowing you to do things like using different ssh usernames for a production deployment and a testing deployment.

Granted, this isn't the best use-case for #2 above (in this particular case it would probably be better to have consistent usernames in all environments), but there are many other cases where this can be not just helpful but necessary.

A good idea?

This shows one way in which you could go about hiding the username if you wanted to. While I'm here though I might as well answer your question: is it worth doing? I agree with @psosuna. To be explicit, as long as you are using key-based authentication, securing the key is far more important than securing the username. Without the key the username is effectively worthless. As a result, hiding the username is not super important.

However if you are already using variables in your script then I would personally go ahead and put the username in a variable too. It wouldn't necessarily improve security much, but it is very easy to do and might make your life a little easier down the road regardless.

Conor Mancone
  • 30,380
  • 13
  • 92
  • 98