1. 28

  2. 17

    You can still run it on any other port < 1024 if you think unprivileged ports are a problem. But the whole point of SSH is to authenticate the endpoints and secure the connection even if the network is hostile.

    For SSH it doesn’t matter whether MITM of the port 2222 happens on some router or on your own box. It’s going to hold up as long as the host key is secure and user doesn’t bypass “you’re being attacked” security alerts (that is the weakest link though).

    1. 10

      I submitted this because this is the second time in the week I’ve seen other posts recommending moving the sshd listening port to an unprivileged port and I think this is always a terrible idea.

      1. 43

        Now, back to SSH: when we start SSH on port 22, we know for a fact that this is done by root or a root-process since no other user could possibly open that port. But what happens when we move SSH to port 2222? This port can be opened without a privileged account, which means I can write a simple script that listens to port 2222 and mimics SSH in order to capture your passwords. And this can easily be done with simple tools commonly available on every linux system/server. So running SSH on a non-privileged port makes it potentially LESS secure, not MORE. You have no way of knowing if you are talking to the real SSH server or not. This reason, and this reason alone makes it that you should NEVER EVER use a non-privileged port for running your SSH server.

        The author is suggesting trusting port 22 because it is a “root” process.There is a “way of knowing if you are talking to the real SSH server or not”, and it’s actually one of SSHs features since its first release. I would trust any port, no matter the “privilege level” required to listen on that port, for a single reason: I trust the SSH server based on its fingerprint, not on its listening port; and I know that my server’s key data is only readable by root, it has been like this in almost all SSH default installations for the last 20 years.

        Now, let’s pretend you STILL want to move the port away because you get so many attacks on your SSH port. First of all: are you able to logon as root? If so, fix that now. Secondly: are you using passwords? If so, fix that now and change into public key authentication.

        I want to move the port away because of the insane amount of traffic that I have to pay for (if I rent a server, VPS, or anything similar which bills me on network egress/ingress). Disabling password access (for any user) will not make dumb port scans and SSH fingerprinters stop looking at my SSH banner and then decide, based on this information, to just try out username/password combinations, even when my server rejects this authentication method.

        The rest of the arguments are personal opinion.

        1. 8

          Besides, by this reasoning creating a connection to the many many services that run on port >1024 is a bad idea too. Connect to MySQL on 3306? Oh noes! Have your app run on localhost:8080 and a proxy on *:80? Oh noes!

          1. 3

            Please move your MySQL port to 306 and launch MySQL as root.

            1. 1

              call me crazy but I don’t think “you risk an attacker accessing your database” and “you risk an attacker having a shell to do whatever they want” are really equivalent.

              1. 1

                Well, the DB in most cases have much more value to the attacker than your machine, so I would say, that from the pragmatic viewpoint, DB is more likely to be targeted.

            2. 8

              the insane amount of traffic that I have to pay for

              how much money per month do you estimate you were paying for to handle traffic from people attempting to ssh into a given node?

              1. 3

                About 2 euro cents a month, per host.

                1. 1

                  the question is: how many resources of concurrent connections does this take, which are completely unnecessary and are filling your logs

                  1. 3

                    Clearly not enough to make log tuning worthwhile.

                    A lot of these blanket statements ignore the fact that action or inaction is perfectly reasonable dependent on threat model. But of course, most people making blanket statements aren’t applying a threat model when doing so.

                2. 6

                  This was basically what I was going to say.

                  If a server can somehow knock down sshd, listen on the same unrestricted port, they still would have to present the appropriate hostkeys.

                  Even then, LSM’s like SELinux, etc can put restrictions on who can name_bind on any port you want. only caveat is that you have to write the policy for it. I am strongly against the >1024 privileged ports restriction in the era of LSMs.

                  1. 1

                    I am strongly against the >1024 privileged ports restriction in the era of LSMs.

                    Can you expand?

                    1. 1

                      With LSM you can disable opening any port by all applications and then allow opening ports per application. So on server it allows for much greater security, as you can directly list which application will be able to open connections (and even make it so no port requires super user, as application/user combo will be handled by LSM).

                      1. 1

                        This is an argument for LSM-based port binding policies, not against the <1024 requires root policy. Unless the two are mutually exclusive?

                        1. 1

                          Not exclusive, but even with LSM allowing the usage of port <1024 you still need to run given program as root. So all you gain is more complexity instead of simplification

                  2. 2

                    I trust the SSH server based on its fingerprint

                    I very rarely know the fingerprint of a server before connecting to it.

                    For my most commonly used hosts, I can look it up with a little bit of work (sourcehut, github, gitlab) but of those, only github made it easy to find and verify. For a lot of hosts in a corporate cloud though, the instances are torn down and replaced so often that host-based keys are essentially meaningless.

                    1. 7

                      If you’re not verifying host keys, you’re basically trusting the network - but you don’t, otherwise you could use telnet instead of ssh.

                      Maybe look into SSH host key signing, so you just need one public signing key to verify that the host has been provisioned by a trusted entity.

                      1. 3

                        It is also possible to use ssh with kerberos. Then you know that the server is the correct one. Even without ssh-fingerprints.

                      2. 5

                        You should really start checking the fingerprints. Ignoring that crucial step is how you get hacked. There are way more attack vectors than you can think of. An attacker could get in, for example through your jobs documentation intranet and modify an ip on a document. Or for example, if a DNS server of yours is compromised. If you use password authentication in these situations, you are essentially let the attacker in all servers you have access to.

                        Other comments already pointed out viable solutions. You should adopt one of them or simply start checking the fingerprints. What you are doing is dangerous.

                        1. 6

                          The “implied trust on first use”-model works well enough for many – though perhaps not all – purposes. It’s the “host fingerprint changed”-warning that provides almost all of the security.

                          1. 2

                            Most of the security no doubt. Almost all… That is debatable. If something happens once every 1000 would you not care to protect against it because you already provided 99.9% of the security?

                            What security is in essence, is accounting for the unlikely yet exploitable cases. You look at that attack vectors as a corner case until it is not a corner case anymore. This is how security threats evolve.

                            1. 1

                              The thing is, what is the attack vector here, and how do you really protect from it? In your previous post you mentioned modifying the internal documentation to change the IP; but where do you get the host key? From the same internal documentation? Won’t the attacker be able to change that, too?

                              You can use SSHFP records; but of course an attacker can potentially get access to the DNS too, as you mentioned.

                              The thing is that good distribution of these fingerprints is not a trivial problem if you’re really worried about these kind of attacks. Are they unfeasible? Certainly not, and if you’re working for a bank, CA registrar, or anything else that has high security requirements you should probably think about all of this. But most of us don’t, and the difficulty of pulling all of this off effectively is so high that most of us don’t really need to worry about it.

                              We don’t lock our houses with vault doors; a regular door with a regular lock is a “good enough” trade-off for most cases. If you’re rich you may want to have something stronger, and if you’re a bank you want the best. But that’s not most of us.

                              1. 1

                                The attack vector is making you believe you are initially trusting the host you think you know, but it is in fact another host.

                                But you are right, it you misguide a user into connecting to another host, you could also show him another fingerprint and trick them into believing itnid legit too. Fingerprints are just a huge number usually displayed as an unintelligible string of chars. It’s not like the user recognise them by heart.

                                I do check them if I change computer, or if l connect to a knowm machine I ask a coleage to verify it. But I’ll agree that it.s a trade off and that maybe it.s ok for most people to just trust.

                    2. 3

                      I think this post and discussion around it is a waste of time. Right now, wasting my time. But I wanted to come here and proclaim in spectrum of terrible ideas, it doesn’t even register. Do you have scale that starts at terrible and then just goes to some k multiple of terrible?

                      I moved my ssh port in like 2002 (the year) , and you know what, I no longer had to see 150+ log messages a day about failed logins, it went to zero. Like 1-1. Mission Accomplished.

                      Please enumerate all the other terrible ideas I shouldn’t follow, might be a good list.

                      edit, btw, I am just poking good terrible fun at you.

                    3. 10

                      security through obscurity perhaps, but it does work in terms of reducing log noise:

                      Status for the jail: sshd
                      |- Filter
                      |  |- Currently failed:	0
                      |  |- Total failed:	0
                      |  `- Journal matches:	_SYSTEMD_UNIT=sshd.service + _COMM=sshd
                      `- Actions
                         |- Currently banned:	0
                         |- Total banned:	0
                         `- Banned IP list:	

                      I also run endlessh on port 22 to bait the bots.

                      EDIT: I already commented about unprivileged port and potential DoS/Security here

                      1. 8

                        If you’re reason for doing this is security, the article is basically right. An nmap scan of your server will reveal all the ports that are open to the internet in a very short time and a script that tries ssh on all of the open tcp ports will run quickly too. If you are trying to reduce traffic or keep your logs from filling up, that’s a reasonable reason to move ssh from port 22. The article is also right that you lose a little security if you move ssh to a non-privileged port by editing /etc/ssh/sshd_config. If you do want to run on an alternative port, consider redirecting traffic in your firewall configuration rather than editing /etc/ssh/sshd_config. This configuration is a little obscure so comment both /etc/ssh/sshd_config and your firewall config accordingly.

                        1. 5

                          When you are logged onto a system as a non-root user (anyone not being uid 0), you cannot create a listing TCP or UDP port below 1024.

                          I wonder how much this argument holds when using CAP_NET_BIND_SERVICE https://man7.org/linux/man-pages/man7/capabilities.7.html ?

                          1. 6

                            I’d rather use sysctl net.ipv4.ip_unprivileged_port_start=0 (despite the name, works for IPv6 too) to disable this artificial limitation altogether. In fact, that’s what I do on my Linux systems.

                            1. 3

                              Wait, but how will use privileged ports as a reason to needlessly run software as root and hope that it does right thing before starting?

                              1. 2

                                I didn’t even know net.ipv4.ip_unprivileged_port_start was a thing; thank you for this. I usually just used the NET_BIND_SERVICE “capability.” but it might be easier than having some binary or using ambient capabilities.

                            2. 4

                              I really don’t get the “reduce log noise” argument.

                              It’s essentially like saying, if a company keeps cold-calling you about something you don’t want, you will change your phone number, and go through the hassle that entails… rather than using the tools available, and blocking the unwanted party.

                              fail2ban is a thing that exists, and works very well. As others have said moving the port just means the bot at the other end has to run a port scan on your IP first. It doesn’t actually prevent them making a connection.

                              1. 3

                                fail2ban is a thing that exists, and works very well

                                For me, it’s way easier to just switch ports and use ssh -p instead of bothering to learn how to use fail2ban. If the logs really bothered me then I’d probably just do that.

                                1. 2

                                  … if the logs don’t bother you, then why bother at all?

                                  Furthermore, I’ve just confirmed my original suspicion. The Debian packages at least, there’s nothing to “learn” if you want basic blocking. sudo apt install fail2ban and it’s be installed, running, doing ip blocks in response to failed auth of common services such as SSH.

                                  I’d argue that’s even quicker and easier than changing the SSH port number.

                                  1. 1

                                    right, I wanted to tell you what I’d do if I had to dig through logs for whatever reason. good to know though

                              2. 4

                                Non-privileged ports can still be restricted to root via SELinux.

                                No, I can’t tell you how.

                                1. 2

                                  :s/Why putting/Why only putting/g

                                  There. Fixed that clickbait’sh for ya.