💾 Archived View for thrig.me › tech › openbsd › fingerd.gmi captured on 2023-11-04 at 12:57:59. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-06-14)
-=-=-=-=-=-=-
fingerd can be enabled on OpenBSD, though the default configuration is perhaps not suitable to expose to the whole internet, as this will expose the IP addresses that one logs in from. This may not be a good idea, especially if one is prone to annoy young males at their "wild age", as Stilgar puts it, or for various other reasons. It is difficult to avoid creepy corporate tracking these days, but one may not want to give them free hand-outs.
You could only login over a wireguard tunnel, in which case the IP address shown will probably be RFC 1918 something, but it's probably more sensible to expose only the information you want to the whole internet, which probably does not include the IP addresses you use to connect from.
The last step should be to open up TCP/79 in the firewall to the internet. The first step might be to ensure that TCP/79 is blocked by the firewall. Next, write a custom script for fingerd to execute. Most simply:
$ cat /usr/libexec/lawn #!/bin/sh echo get off my lawn $ chmod +x /usr/libexec/lawn
And then to modify /etc/inetd.conf to execute this program:
$ grep fingerd /etc/inetd.conf finger stream tcp nowait _fingerd /usr/libexec/fingerd fingerd -lsmP /usr/libexec/lawn finger stream tcp6 nowait _fingerd /usr/libexec/fingerd fingerd -lsmP /usr/libexec/lawn
You may want to remove the -l flag to cut down on log noise?
inetd will need to be enabled and started. This all could be done with configuration management, if you are that organized.
$ doas rcctl enable inetd $ doas rcctl start inetd $ finger root@localhost [localhost/127.0.0.1] get off my lawn
The observant may notice that our lawn script gives the same answer regardless of the user, or lack of user given:
finger @localhost finger squarebobspongepants@localhost ...
Here the dreaded "second-system effect" comes into play, as we must bloat our elegant lawn script with features and wingdings.
// lawn2-electric-boogaloo - lawn with features and bloat. it // reads a ~/.lawn file or falls back to a generic message #include <ctype.h> #include <fcntl.h> #include <pwd.h> #include <stdio.h> #include <unistd.h> #define MAX_USERNAME_LEN 32 int main(int argc, char *argv[]) { close(STDIN_FILENO); if (pledge("stdio rpath unveil", NULL) == -1) goto NOPE; // fingerd on OpenBSD inserts a -- so we must remove that or // any other flags along for the ride, and ape the flags that // finger(1) supports int unused; while ((unused = getopt(argc, argv, "lmMpsho")) != -1) ; argc -= optind; argv += optind; if (argc == 0) goto ALLUSERS; // is the username somewhat sane? char *ch = *argv; if (*ch == '\0') goto ALLUSERS; int i = 0; while (*ch != '\0') { if (++i > MAX_USERNAME_LEN) goto ALLUSERS; if (!isalnum(*ch)) goto ALLUSERS; ch++; } // does the user have a home directory? struct passwd *pw = getpwnam(*argv); if (!pw) goto ALLUSERS; char *home = pw->pw_dir; if (!home) goto ALLUSERS; if (chdir(home) == -1) goto ALLUSERS; // traditional would be ".plan" and ".project" but those // might be better reserved for internal use unveil(".lawn", "r"); unveil(NULL, NULL); int fd = open(".lawn", O_RDONLY | O_NOFOLLOW); if (fd < 0) goto ALLUSERS; if (pledge("stdio", NULL) == -1) goto NOPE; char buf[4096]; while (1) { ssize_t amount = read(fd, buf, sizeof(buf)); if (amount <= 0) break; write(STDOUT_FILENO, buf, (size_t) amount); } close(STDOUT_FILENO); exit(0); ALLUSERS: if (pledge("stdio", NULL) == -1) goto NOPE; write(STDOUT_FILENO, "get off our lawns\n", 18); close(STDOUT_FILENO); exit(0); NOPE: close(STDOUT_FILENO); exit(1); }
A security risk here is that an attacker might use this script to enumerate users on the system, perhaps to find people to spam, phish, check for weak passwords by way of SMTP, etc. Attackers can be terribly clever here and may be able to use timing information to determine if an account exists or not.
On the squeaky clean corporate but spammer and attacker overrun internet you probably do not want to be running a fingerd. But where is the fun in that?
An even more complicated option would be to run a custom fingerd with all sorts of features and hopefully no security exploits. This could be less expensive than having to fork off programs for every request. Implementations can be found on the internet, or it might be good practice to write one.
gemini://gemini.thebackupbox.net/~epoch/blog/fingering
Would be text that contains #finger and some other words?
tags #finger #openbsd #c