3

I'm running my sshd(8) listening on domain and https ports. (What else is there to run on these ports? :)

Obviously, real DNS (when falling back to TCP) and HTTPS clients might attempt to connect to my SSH server listening on these ports. How can I find out how many connection attempts it receives from DNS/TCP and HTTPS/TCP clients? Is there, for example, some pattern that I can search the server's logs for that is unique to a DNS/TCP client or an HTTPS/TCP client talking to an SSH server? Is there some networking tool that can easily show this?

I have linked the OpenBSD /etc/services and sshd above, so I'm obviously interested in how to do this on OpenBSD primarily. But if there's a cross-platform way of doing this that isn't specific to any single operating system, please include it.

2
  • Based on your answer, it seems by domain port you mean ssh port (22). And I guess you mean "how many connection attempts it receives to these ports from...", as those aren't the ports DNS normally uses, as you probably know.
    – eis
    Commented Jan 11, 2017 at 5:40
  • The answer is showing how to recognize this stuff from the log of an SSH server listening on the conventional port, by redirecting some test DNS and HTTPS clients to its port. The question is talking about SSH servers set up to listen on the non-conventional domain and https ports, as listed in /etc/services, this being the reason why the questioner is interested in recognizing such traffic from logs.
    – JdeBP
    Commented Jan 11, 2017 at 8:27

3 Answers 3

7

You can add content-based firewall rules that analyze the first few bytes of incoming connections. For example, under Linux, with iptables:

iptables -N notssh
iptables -A input -p tcp --dport 443 -m string --algo bm --from 0 --to 7 ! --string SSH-2.0 -j notssh

The counter on the notssh rule provides the number of times this rule was triggered since it was established or since the counter was reset with iptables -Z notssh. There's also a counter on the individual rules.

This incorrectly counts connections where the first packet of the TCP connection contains less than 7 bytes of the SSH protocol but that is rare in practice.

6
  • 1
    interesting! but i don't think that'd work under openbsd. ;)
    – cnst
    Commented Jan 11, 2017 at 0:35
  • 1
    @cnst If you are expecting answers specific to OpenBSD, you must state so in your question.
    – xhienne
    Commented Jan 11, 2017 at 0:37
  • @xhienne, i'm generally looking for cross-platform solutions.
    – cnst
    Commented Jan 11, 2017 at 0:43
  • @cnst You could apply the same principle on *BSD, but you'd have to use pf syntax, which I don't know. Commented Jan 11, 2017 at 0:45
  • 1
    @cnst The first sentence is a true generic (cross-platform) solution. The remaining of the post is only an example.
    – xhienne
    Commented Jan 11, 2017 at 0:48
4

A DNS over TCP client can be emulated with dig(1) like so (we explicitly use port 22 as the domain port might not be translated on the box itself):

dig @example.org -p22 +tcp example.org

Or like so:

dig @example.org -p22 axfr example.org

And it appears to result in the following entries at /var/log/authlog:

Jan 10 15:08:41 example sshd[21075]: Did not receive identification string from 64.124.xxx.xx
Jan 10 15:08:51 example sshd[22052]: Did not receive identification string from 64.124.xxx.xx
Jan 10 15:09:01 example sshd[24980]: Did not receive identification string from 64.124.xxx.xx

Whereas https,

curl https://example.org:22/

appears to result in the following entry (although the number of entries per attempt appears to differ with different browsers):

Jan 10 15:25:06 example sshd[9203]: Bad protocol version identification '\\026\\003\\001' from 64.124.xxx.xx

It appears that some HTTPS connection attempts also end with one fewer character:

Bad protocol version identification '\\026\\003' from

We can determine all other possible variations:

% fgrep " sshd[" /var/log/authlog | cut -d" " -f7-12 | grep ^Bad | sort | uniq -c | sort -rn | head
 351 Bad protocol version identification '\\026\\003\\001' from
 110 Bad protocol version identification '\\026\\003\\001\\001E\\001' from
  91 Bad protocol version identification '\\026\\003\\002' from
  63 Bad protocol version identification '\\026\\003\\001\\001=\\001' from
  52 Bad protocol version identification '\\026\\003\\001\\002' from
  44 Bad protocol version identification '\\026\\003\\003' from
  21 Bad protocol version identification '\\026\\003\\001\\001?\\001' from
  16 Bad protocol version identification '\\026\\003\\001\\001B\\001' from
  13 Bad protocol version identification '\\026\\003\\001\\0017\\001' from
  10 Bad protocol version identification '\\026\\003' from

We can also see a possible number of domain requests:

% fgrep " sshd[" /var/log/authlog | cut -d" " -f7-12 | grep ^Did | sort | uniq -c
 227 Did not receive identification string from
0

It's a little more complex solution but you could try sslh ssl/ssh multiplexer but I guess you will have to manually add checks for DNS packets and you have to configure sslh in transparent mode if you need original client's addresses (for view in DNS, allow/deny in Web-server and from= in ssh authorized_keys)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .