finger webfinger
Berend De Schouwer
Finger and Webfinger
Finger and Webfinger answer the same question: “what information is available about this user?”
This blog was written because both were harder to get going than necessary.
Webfinger
Webfinger does something similar. Query my mastodon handle,
@berend@emptybox.deschouwer.co.za
, and you should get something like
{
"aliases": [
"https://emptybox.deschouwer.co.za/nextcloud/index.php/index.php/apps/social/@berend",
"https://emptybox.deschouwer.co.za/nextcloud/index.php/u/berend"
],
"links": [
{
"href": "https://emptybox.deschouwer.co.za/nextcloud/index.php/u/berend",
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html"
}
],
"subject": "berend@emptybox.deschouwer.co.za"
}
It’s a good API to find more information about a specific user.
Finger
Finger is old. It’s from 1991, 5 years before http.
You can see it in action by running
finger berend@berend.deschouwer.co.za
The original finger server was horribly insecure. This server is not running that.
Webfinger Back
The Webfinger backend is provided by the Social app on Nextcloud.
I’m going to document some of the pitfalls here, since:
- An installation step isn’t documented
- Some of the error reporting is misleading.
- All of the official help is “configure your webserver/proxy”, even when the answer isn’t that.
- google-ing this doesn’t help, since everything redirects you back to webserver configuration help.
Configure your webserver
Once, for Nextcloud
Yes, you do need to configure your webserver.
Under your nextcloud instance, when logged in as admin, navigate to security.
If Nextcloud Admin Security Check complains with a similar message
Your web server is not configured correctly to resolve “/.well-known/caldav”. More information can be found on our documentation. Your web server is not configured correctly to resolve “/.well-known/carddav”. More information can be found on our documentation.
You need to fix your webserver or proxy. Follow Google. The solutions are complete.
Configuring Nextcloud
Twice, for the Social App in Nextcloud
Nope, you don’t need to do it twice.
If the Social App complains with a similar message
.well-known/webfinger isn’t properly set up!
Social needs the .well-known automatic discovery to be properly set up. If Nextcloud is not installed in the root of the domain, it is often the case that Nextcloud can’t configure this automatically
The problem is not your webserver. It’s the Social App
Configuring the App (the missing installation step)
You will need the CLI occ
from Nextcloud.
You may have used it to perform backups or upgrades. It’s in the webroot, and you will usually run it something like:
sudo -u www /var/www/nextcloud/occ backup
First, look at the config. Run:
cd /var/www/nextcloud/
sudo -u www occ config:list
Look for the Social app.
"social": {
"address": "https:\/\/emptybox.deschouwer.co.za\/",
"enabled": "yes",
"url": "https:\/\/emptybox.deschouwer.co.za\/nextcloud\/index.php\/apps\/social\/",
"social_url": "https:\/\/emptybox.deschouwer.co.za\/nextcloud\/index.php\/index.php\/apps\/social\/",
"cloud_url": "https:\/\/emptybox.deschouwer.co.za\/nextcloud\/"
},
Ensure that these values are OK. If they are not, run
sudo -u www php ./occ config:app:set --value https://emptybox.deschouwer.co.za/overthere social url
Three, misleading errors
Webfinger not supported
Now you get to try:
http --follow 'https://emptybox.deschouwer.co.za/.well-known/webfinger?resource=acct%3Aberend'
If you get 404 and
{
"message": "webfinger not supported"
}
Don’t panic! It doesn’t mean webfinger isn’t supported, it means the account specified isn’t a valid account.
You didn’t specify a domain. Add a domain.
Webfinger is empty and 404
http --follow 'https://emptybox.deschouwer.co.za/.well-known/webfinger?resource=acct%3Aberend%40example.com'
If you get 404 and
""
Dont panic! It means that the specified acocunt (berend@example.com
) is not on this server.
Your Nextcloud instance isn’t example.com
, so you should specify an account you are authoritive for.
Finger Back
The backend for 1991 finger is a simple script that serves my whoami page.
Since the actual finger servers are insecure, I decided to re-implement it again. Since that means even more insecure, I simplified everything.
systemd to the rescue
This is the reason for writing this section. systemd can really help us locking it down.
[Unit]
Description=Finger Per-Connection Server
[Service]
ExecStart=/usr/.../.py # Keep some things secret
StandardInput=socket
# Send errors to the logs, instead of to the caller
StandardError=journal
SyslogIdentifier=finger
# Don't run as root
DynamicUser=yes
# Don't read /tmp, /dev, /home
PrivateTmp=true
PrivateDevices=true
ProtectHome=true
# Restrict for DoS
MemoryMax=100M
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
CPUQuota=50%
IOWeight=25
# Restrict OS calls
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
ProtectSystem=strict
RestrictSUIDSGID=true
MemoryDenyWriteExecute=true
# Don't load calls that are frequently used by exploits
InaccessiblePaths=/usr/bin/at
InaccessiblePaths=/usr/bin/bash
InaccessiblePaths=/usr/bin/sh
InaccessiblePaths=/usr/bin/wget
InaccessiblePaths=/usr/bin/curl
InaccessiblePaths=/usr/bin/ssh
InaccessiblePaths=/usr/bin/scp
InaccessiblePaths=/usr/bin/perl
User
The first level of security, is do not run as root.
No public directories
No public /tmp
or any such directory. If you do hack it, your in a sandbox.
Limited Access
Then we lock it down a bit for DoS reasons. We run it low priority, with limited RAM, so you don’t take down the entire machine.
Too many details
Then we lock up some other processes. Some of these are for example purposes.
It’s really, really nice that systemd allows us to lock it down like this.
Multiple users? Nope
The original finger backend allows you to query any user that exists, and changes the output based on whether they are logged in.
Not for me. I give you the same answer, no matter what.
Redirects? Nope
You could query users on another server. Connecting to example.com
,
you could ask it about joe@smith.com
. Not on my server.
Memory Leaks? Nope
You could send very large user names. On my server, you get 512 bytes, then I disconnect.
Since we don’t care about the data, we discard it.
discard = os.read(0, 512)
DoS? Nope
You can’t keep the finger socket open for very long. If it doesn’t receive data very soon, it will disconnect.
def timeout(signum, frame):
raise Exception("Timed out")
signal.signal(signal.SIGALRM, timeout)
signal.alarm(3)
DDoS? Yep
DDoS is always a “yep”.
More details
I’d give you more details, but here aren’t. We timeout after 3 seconds, we read a maximum of 512 bytes of data, and we always give the exact same response.