2

Intention

I would like to permit SSH root access to my server, but for security reasons from local network only.

Environment

  • OS: GNU/Linux Debian 9 Stretch fully updated.
  • SSH: OpenSSH version 1:7.4p1-10+deb9u3.

Procedure

  1. In the main config file:

    /etc/ssh/sshd_config
    

    I removed the global line forbidding direct root access, i.e.:

    PermitRootLogin no
    

    and have set it up as follows instead:

    # root is allowed from local network only
    Match Address 192.168.0.*
        PermitRootLogin yes
    
    # otherwise you need to log in as a user
    Match all
        PermitRootLogin no
    
  2. I have temporarily enabled password access with:

    PasswordAuthentication yes
    
  3. I have generated a private-public key pair for root account with:

    ssh-keygen -t rsa -b 8192
    

    while logged in as root, of course.

  4. Then on the client laptop, I have copied the public key using:

    ssh-copy-id root@192.168.0.xxx -p yyyyy    # I have hidden the port number and ip
    
  5. I have been able then to successfully log into my server using public key as root, so I disabled password access with:

    # use only public key, never a password
    PubkeyAuthentication yes
    PasswordAuthentication no
    AuthenticationMethods publickey
    

Questions

Did I do all the steps necessary in order for non-local computers to be unable to even try to log into my server?

If I did not, please elaborate as to what you recommend?

  • I never advocate having ssh open to the outside world due to the principle of the minimum exposure possible and also due to it still logging attempts. – Rui F Ribeiro Jul 28 '18 at 14:01
  • Technically, I think you might not need the ssh-keygen on the server, since the key pair is only used for outgoing connections. (It has the side effect of creating the ~/.ssh directory for you, though, I'm not 100% sure ssh-copy-id would do that if it wasn't there already.) – Ulrich Schwarz Jul 28 '18 at 14:09
  • I would have set PermitRootLogin without-password myself. That disables the ability for root to login with a password, even if passwordAuthentication is otherwise enabled. – Stephen Harris Jul 28 '18 at 15:48
3

Did I do all the steps necessary in order for non-local computers to be unable to even try to log into my server?

You stopped them from trying to log into your server as root. So this makes a difference:

  1. If you ever add an SSH key for a second account.
  2. During any maintenance steps like these, where you temporarily enabled password logins. Unless you crudely disconnect your network from the Internet, but I notice you didn't mention that in your steps.

If you are planning to satisfy the question above, it seems better to code that directly. For example, I believe you could control logins by all users with one line. This would avoid the need to "temporarily" open yourself up to internet-based password-guessing attacks :-).

AllowUsers *@192.168.0.*

But you should not rely on an SSH daemon configuration. You should ask why you're not enforcing this policy in a central firewall. If you do not want non-local logins, there is no need to expose yourself to hypothetical bugs in the pre-auth code of your SSH server, for example.

I will limit myself to one piece of unsolicited advice. You may be surprised if you ever improve your local systems to resolve hostnames to IPv6 addresses, even unintentionally. Because the above will not allow any connection made to an IPv6 address :). If you rely purely on a central firewall then you wouldn't have to worry about this either.

The simplest network configuration is to have a centralized firewall that distinguishes your local network from internet traffic (and anything else e.g. guest wireless). Block any connection from the internet, unless you have a specific reason to allow it.

This has been standardized as the default on home/small business routers. (You should still verify such assumptions because these devices are notoriously cheap and security-challenged. This particular issue is a very obvious one that campaigners do notice, but it is known that some devices made the "wrong" choice when they first implemented IPv6).

Of course if you want you can also configure a "redundant" firewall on the host itself. E.g. this is potentially useful to enforce a "No Open Ports"-by-default policy on Ubuntu or Debian. The disadvantage is that firewalls are difficult things to remember about, configure, and troubleshoot when they break things, and now you have two separate ones! Going from one to two significantly increases complexity, each time you want to start using a pure server app (like SSH), or a peer-to-peer app which has not engineered some maximally reliable variant of hole punching.

The next simplest network configuration is to add redundant options in the style of sshd ListenAddress. To add some IPv6 support, you might make sure your router assigns Unique Local Addresses as well as the globally-routable ones, and listen on the Unique Local Address. When you have IPv6, forcing specific ListenAddress's adds a material safety margin. This is different from a time when you only had IPv4, and the internet would not be able to attack your server anyway (because of NAT) unless

  1. your server was the router or
  2. you had a pure modem and not a combination modem+router or
  3. you rented at least one additional global IP address and it had been assigned to your server.

In general, it would still make sense to use a firewall (and I can't remember any specific exceptions), while treating the likes of ListenAddress as a second safety margin.

Coding your SSH daemon configuration with not just the server's own IP address, but the range of the network it is on, is by far the least desirable of the techniques listed here IMO :).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.