401 status code - Public key not found

I’m the admin of bgme.me.
After enable secure mode, the instance 2to2.xyz reported that they can’t receive message from our instance and our instance can receive message from 2to2.xyz normally.

After checking the log, it was found that the GET request from 2to2.xyz failed and return 401 status code with Public key not found for key https://2to2.xyz/actor#main-key.

I try to use curl to fetch the key of https://2to2.xyz/actor#main-key on the same machine and I can download the key without any problem.

Logs

caddy log

{
  "level": "error",
  "ts": 1609314539.690381,
  "logger": "http.log.access.log0",
  "msg": "handled request",
  "request": {
    "remote_addr": "18.180.61.183:44596",
    "proto": "HTTP/1.1",
    "method": "GET",
    "host": "bgme.me",
    "uri": "/users/FluffyDream",
    "headers": {
      "User-Agent": [
        "http.rb/4.4.1 (Mastodon/3.3.0; +https://2to2.xyz/)"
      ],
      "Date": [
        "Wed, 30 Dec 2020 07:48:55 GMT"
      ],
      "Accept-Encoding": [
        "gzip"
      ],
      "Accept": [
        "application/activity+json, application/ld+json"
      ],
      "Signature": [
        "keyId=\"https://2to2.xyz/actor#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date accept\",signature=\"EtvS8T63rcjoSVvgD9f/rkl6LrkSQn8u1sUkEepimdgpfeehrhlme7B1qJhAFsHedwDyoCICG+eFEDX5pOaesipREmkDUikk4gc+IPal2eV5MJS/TKHhoCGzdiLWiVRkk5I6kPcSFJ+B1+LmEJKD05xtdrFoCJyv4pWrKcGC6nPLrRfgBFKwu/6j9HzvStdH/qF5wB2MJYXOwOvEn9ncq9MD/bN0hvzJ5+XFvhadFrm8JpPNA4xtva04pvB/fxR+vbb8eqBgjJMQDhKeUVeBGzRKfHA2d8hb2dMpXyMWt33wSif1wVjfW5/zXp6zA0V3BNKCwPRYBW35OMOsBf1r2w==\""
      ],
      "Connection": [
        "close"
      ],
      "Content-Length": [
        "0"
      ]
    },
    "tls": {
      "resumed": false,
      "version": 772,
      "cipher_suite": 4865,
      "proto": "",
      "proto_mutual": true,
      "server_name": "bgme.me"
    }
  },
  "common_log": "18.180.61.183 - - [30/Dec/2020:07:48:59 +0000] \"GET /users/FluffyDream HTTP/1.1\" 401 80",
  "duration": 3.457062106,
  "size": 80,
  "status": 401,
  "resp_headers": {
    "X-Xss-Protection": [
      "1; mode=block"
    ],
    "X-Content-Type-Options": [
      "nosniff"
    ],
    "Vary": [
      "Accept-Encoding, Origin"
    ],
    "X-Runtime": [
      "3.436231"
    ],
    "Strict-Transport-Security": [
      "max-age=31536000;"
    ],
    "Alt-Svc": [
      "h3-29=\":443\"; ma=2592000"
    ],
    "X-Frame-Options": [
      "DENY"
    ],
    "Content-Encoding": [
      "gzip"
    ],
    "X-Request-Id": [
      "3cd2e212-e78c-4f41-a6a0-a44a9713916a"
    ],
    "Content-Type": [
      "text/plain; charset=utf-8"
    ],
    "Cache-Control": [
      "no-cache"
    ],
    "Server": [
      "Caddy"
    ]
  }
}

journalctl -u mastodon-sidekiq.service

Dec 30 06:09:09 git bundle[13246]: 2020-12-30T06:09:09.444Z pid=13246 tid=3jatn2 class=ActivityPub::DeliveryWorker jid=00044bac368e98f852b38612 elapsed=5.737 INFO: fail
Dec 30 06:09:09 git bundle[13246]: 2020-12-30T06:09:09.445Z pid=13246 tid=3jatn2 WARN: {"context":"Job raised exception","job":{"retry":16,"queue":"push","dead":false,"class":"ActivityPub::DeliveryWorker","args":["{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"sensitive\":\"as:sensitive\",\"toot\":\"http://joinmastodon.org/ns#\",\"votersCount\":\"toot:votersCount\"}],\"id\":\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/activity\",\"type\":\"Create\",\"actor\":\"https://mstdn.jp/users/sukanyan\",\"published\":\"2020-12-30T06:04:08Z\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://mstdn.jp/users/sukanyan/followers\",\"https://bgme.me/users/kjrrrrr\"],\"object\":{\"id\":\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583\",\"type\":\"Note\",\"summary\":null,\"inReplyTo\":\"https://bgme.me/users/kjrrrrr/statuses/105467166365558431\",\"published\":\"2020-12-30T06:04:08Z\",\"url\":\"https://mstdn.jp/@sukanyan/105467625373823583\",\"attributedTo\":\"https://mstdn.jp/users/sukanyan\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://mstdn.jp/users/sukanyan/followers\",\"https://bgme.me/users/kjrrrrr\"],\"sensitive\":false,\"atomUri\":\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583\",\"inReplyToAtomUri\":\"https://bgme.me/users/kjrrrrr/statuses/105467166365558431\",\"conversation\":\"tag:bgme.me,2020-12-30:objectId=7368207:objectType=Conversation\",\"content\":\"<p><span class=\\\"h-card\\\"><a href=\\\"https://bgme.me/@kjrrrrr\\\" class=\\\"u-url mention\\\">@<span>kjrrrrr</span></a></span> 哈哈哈这么说的话女团综艺就是我原点了!欅坂早期的综艺还是不错的,MC很强,会搞事的成员又多(后来平手不笑了,会搞事的成员也相继出事。。)当搞笑综艺看看还是挺不错的hh</p><p>说起来奥黛丽成为我本命也是因为日向坂的综艺吧(</p><p>反而是很少接触band,今年爱上的有indigo la end和ジェニーハイhh</p>\",\"contentMap\":{\"zh\":\"<p><span class=\\\"h-card\\\"><a href=\\\"https://bgme.me/@kjrrrrr\\\" class=\\\"u-url mention\\\">@<span>kjrrrrr</span></a></span> 哈哈哈这么说的话女团综艺就是我原点了!欅坂早期的综艺还是不错的,MC很强,会搞事的成员又多(后来平手不笑了,会搞事的成员也相继出事。。)当搞笑综艺看看还是挺不错的hh</p><p>说起来奥黛丽成为我本命也是因为日向坂的综艺吧(</p><p>反而是很少接触band,今年爱上的有indigo la end和ジェニーハイhh</p>\"},\"attachment\":[],\"tag\":[{\"type\":\"Mention\",\"href\":\"https://bgme.me/users/kjrrrrr\",\"name\":\"@kjrrrrr@bgme.me\"}],\"replies\":{\"id\":\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/replies\",\"type\":\"Collection\",\"first\":{\"type\":\"CollectionPage\",\"next\":\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/replies?only_other_accounts=true&page=true\",\"partOf\":\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/replies\",\"items\":[]}}},\"signature\":{\"type\":\"RsaSignature2017\",\"creator\":\"https://mstdn.jp/users/sukanyan#main-key\",\"created\":\"2020-12-30T06:04:08Z\",\"signatureValue\":\"JSCYeUF/VVTQlQQOF7OF3+GIp8QgvCuv+PT7YNNwJWGHF211pYnH1pnniMRoPBDvfFfWL2s6wSgfJI31FPL/1btyTG4eV8Ob+7MhiXJ9Fd4khUXYDgGEnm+VjUjjo5yU/1ewakShyJ4zHgy2lXxHMVdUSdRSiVck6TeKeAiEk/h5Ad/DeKCraK0G9dWemQ4ASFHHnon2PIKyxXQ2lf1TccYbcCLF9fg9rGw1IJxYQ2AQojuvh0/qJrjLegPX1L0Raj8cyOzyoU8H+exIdzzDpYw5iMol7FildoSdgdxp8Slby9l8adHBOb8RlLC1HwhQrfQWJlFwu5p4hI43nLhlYA==\"}}",79016,"https://2to2.xyz/inbox"],"jid":"00044bac368e98f852b38612","created_at":1609308248.9864783,"enqueued_at":1609308542.9440951,"error_message":"https://2to2.xyz/inbox","error_class":"Stoplight::Error::RedLight","failed_at":1609308254.8647058,"retry_count":3,"retried_at":1609308421.7657871},"jobstr":"{\"retry\":16,\"queue\":\"push\",\"dead\":false,\"class\":\"ActivityPub::DeliveryWorker\",\"args\":[\"{\\\"@context\\\":[\\\"https://www.w3.org/ns/activitystreams\\\",{\\\"ostatus\\\":\\\"http://ostatus.org#\\\",\\\"atomUri\\\":\\\"ostatus:atomUri\\\",\\\"inReplyToAtomUri\\\":\\\"ostatus:inReplyToAtomUri\\\",\\\"conversation\\\":\\\"ostatus:conversation\\\",\\\"sensitive\\\":\\\"as:sensitive\\\",\\\"toot\\\":\\\"http://joinmastodon.org/ns#\\\",\\\"votersCount\\\":\\\"toot:votersCount\\\"}],\\\"id\\\":\\\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/activity\\\",\\\"type\\\":\\\"Create\\\",\\\"actor\\\":\\\"https://mstdn.jp/users/sukanyan\\\",\\\"published\\\":\\\"2020-12-30T06:04:08Z\\\",\\\"to\\\":[\\\"https://www.w3.org/ns/activitystreams#Public\\\"],\\\"cc\\\":[\\\"https://mstdn.jp/users/sukanyan/followers\\\",\\\"https://bgme.me/users/kjrrrrr\\\"],\\\"object\\\":{\\\"id\\\":\\\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583\\\",\\\"type\\\":\\\"Note\\\",\\\"summary\\\":null,\\\"inReplyTo\\\":\\\"https://bgme.me/users/kjrrrrr/statuses/105467166365558431\\\",\\\"published\\\":\\\"2020-12-30T06:04:08Z\\\",\\\"url\\\":\\\"https://mstdn.jp/@sukanyan/105467625373823583\\\",\\\"attributedTo\\\":\\\"https://mstdn.jp/users/sukanyan\\\",\\\"to\\\":[\\\"https://www.w3.org/ns/activitystreams#Public\\\"],\\\"cc\\\":[\\\"https://mstdn.jp/users/sukanyan/followers\\\",\\\"https://bgme.me/users/kjrrrrr\\\"],\\\"sensitive\\\":false,\\\"atomUri\\\":\\\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583\\\",\\\"inReplyToAtomUri\\\":\\\"https://bgme.me/users/kjrrrrr/statuses/105467166365558431\\\",\\\"conversation\\\":\\\"tag:bgme.me,2020-12-30:objectId=7368207:objectType=Conversation\\\",\\\"content\\\":\\\"<p><span class=\\\\\\\"h-card\\\\\\\"><a href=\\\\\\\"https://bgme.me/@kjrrrrr\\\\\\\" class=\\\\\\\"u-url mention\\\\\\\">@<span>kjrrrrr</span></a></span> 哈哈哈这么说的话女团综艺就是我原点了!欅坂早期的综艺还是不错的,MC很强,会搞事的成员又多(后来平手不笑了,会搞事的成员也相继出事。。)当搞笑综艺看看还是挺不错的hh</p><p>说起来奥黛丽成为我本命也是因为日向坂的综艺吧(</p><p>反而是很少接触band,今年爱上的有indigo la end和ジェニーハイhh</p>\\\",\\\"contentMap\\\":{\\\"zh\\\":\\\"<p><span class=\\\\\\\"h-card\\\\\\\"><a href=\\\\\\\"https://bgme.me/@kjrrrrr\\\\\\\" class=\\\\\\\"u-url mention\\\\\\\">@<span>kjrrrrr</span></a></span> 哈哈哈这么说的话女团综艺就是我原点了!欅坂早期的综艺还是不错的,MC很强,会搞事的成员又多(后来平手不笑了,会搞事的成员也相继出事。。)当搞笑综艺看看还是挺不错的hh</p><p>说起来奥黛丽成为我本命也是因为日向坂的综艺吧(</p><p>反而是很少接触band,今年爱上的有indigo la end和ジェニーハイhh</p>\\\"},\\\"attachment\\\":[],\\\"tag\\\":[{\\\"type\\\":\\\"Mention\\\",\\\"href\\\":\\\"https://bgme.me/users/kjrrrrr\\\",\\\"name\\\":\\\"@kjrrrrr@bgme.me\\\"}],\\\"replies\\\":{\\\"id\\\":\\\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/replies\\\",\\\"type\\\":\\\"Collection\\\",\\\"first\\\":{\\\"type\\\":\\\"CollectionPage\\\",\\\"next\\\":\\\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/replies?only_other_accounts=true&page=true\\\",\\\"partOf\\\":\\\"https://mstdn.jp/users/sukanyan/statuses/105467625373823583/replies\\\",\\\"items\\\":[]}}},\\\"signature\\\":{\\\"type\\\":\\\"RsaSignature2017\\\",\\\"creator\\\":\\\"https://mstdn.jp/users/sukanyan#main-key\\\",\\\"created\\\":\\\"2020-12-30T06:04:08Z\\\",\\\"signatureValue\\\":\\\"JSCYeUF/VVTQlQQOF7OF3+GIp8QgvCuv+PT7YNNwJWGHF211pYnH1pnniMRoPBDvfFfWL2s6wSgfJI31FPL/1btyTG4eV8Ob+7MhiXJ9Fd4khUXYDgGEnm+VjUjjo5yU/1ewakShyJ4zHgy2lXxHMVdUSdRSiVck6TeKeAiEk/h5Ad/DeKCraK0G9dWemQ4ASFHHnon2PIKyxXQ2lf1TccYbcCLF9fg9rGw1IJxYQ2AQojuvh0/qJrjLegPX1L0Raj8cyOzyoU8H+exIdzzDpYw5iMol7FildoSdgdxp8Slby9l8adHBOb8RlLC1HwhQrfQWJlFwu5p4hI43nLhlYA==\\\"}}\",79016,\"https://2to2.xyz/inbox\"],\"jid\":\"00044bac368e98f852b38612\",\"created_at\":1609308248.9864783,\"enqueued_at\":1609308542.9440951,\"error_message\":\"https://2to2.xyz/inbox\",\"error_class\":\"Stoplight::Error::RedLight\",\"failed_at\":1609308254.8647058,\"retry_count\":3,\"retried_at\":1609308421.7657871}"}
Dec 30 06:09:09 git bundle[13246]: 2020-12-30T06:09:09.445Z pid=13246 tid=3jatn2 WARN: Mastodon::UnexpectedResponseError: https://2to2.xyz/inbox returned code 401
--
Dec 30 06:09:11 git bundle[13246]: /home/mastodon/live/app/workers/activitypub/delivery_worker.rb:67:in `perform_request'
Dec 30 06:09:11 git bundle[13246]: 2020-12-30T06:09:11.878Z pid=13246 tid=3jaunm class=ActivityPub::LowPriorityDeliveryWorker jid=8506efad2d79804fd06f6c4c elapsed=0.049 INFO: fail
Dec 30 06:09:11 git bundle[13246]: 2020-12-30T06:09:11.908Z pid=13246 tid=3jaunm WARN: {"context":"Job raised exception","job":{"retry":8,"queue":"pull","dead":false,"class":"ActivityPub::LowPriorityDeliveryWorker","args":["{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\"}],\"id\":\"https://alive.bar/users/kmethne/statuses/104695104332603029#delete\",\"type\":\"Delete\",\"actor\":\"https://alive.bar/users/kmethne\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"object\":{\"id\":\"https://alive.bar/users/kmethne/statuses/104695104332603029\",\"type\":\"Tombstone\",\"atomUri\":\"https://alive.bar/users/kmethne/statuses/104695104332603029\"},\"signature\":{\"type\":\"RsaSignature2017\",\"creator\":\"https://alive.bar/users/kmethne#main-key\",\"created\":\"2020-12-30T05:19:44Z\",\"signatureValue\":\"sRPhSyfmnVC6UhqjjYfreITzU7fQlSAn+LHEWcNXNOTwHYYHikcXCsQjOHANCDpXYezOna84ynZJI67PNNQB39WNKv579zjGMZkmNVpeQlVRiCuxvFDvs5oplYkUQEjxZhC6dd8iQ8NEOYTNMwrIKbPd7c/oILeMqgyVjJWSTChkJcq4/NG7YS+oR36kW3AFOXW0+rF9xI8+PI70PWuVvZ1T66rvF15Yq0cZRenI/DP61MPif/nI5k4eTLDktLv5Zl5LfW7g1FNBO1XOtaD4yLiUWlvTXmjsXwtviyS4Serx9yTitQCaWKbVvhi9dNMVd5OXE++vU0J7xQ0v8CNnww==\"}}",80576,"https://2to2.xyz/inbox"],"jid":"8506efad2d79804fd06f6c4c","created_at":1609305586.1595027,"enqueued_at":1609308551.8289003,"error_message":"https://2to2.xyz/inbox","error_class":"Stoplight::Error::RedLight","failed_at":1609305621.0071929,"retry_count":6,"retried_at":1609307109.5087583},"jobstr":"{\"retry\":8,\"queue\":\"pull\",\"dead\":false,\"class\":\"ActivityPub::LowPriorityDeliveryWorker\",\"args\":[\"{\\\"@context\\\":[\\\"https://www.w3.org/ns/activitystreams\\\",{\\\"ostatus\\\":\\\"http://ostatus.org#\\\",\\\"atomUri\\\":\\\"ostatus:atomUri\\\"}],\\\"id\\\":\\\"https://alive.bar/users/kmethne/statuses/104695104332603029#delete\\\",\\\"type\\\":\\\"Delete\\\",\\\"actor\\\":\\\"https://alive.bar/users/kmethne\\\",\\\"to\\\":[\\\"https://www.w3.org/ns/activitystreams#Public\\\"],\\\"object\\\":{\\\"id\\\":\\\"https://alive.bar/users/kmethne/statuses/104695104332603029\\\",\\\"type\\\":\\\"Tombstone\\\",\\\"atomUri\\\":\\\"https://alive.bar/users/kmethne/statuses/104695104332603029\\\"},\\\"signature\\\":{\\\"type\\\":\\\"RsaSignature2017\\\",\\\"creator\\\":\\\"https://alive.bar/users/kmethne#main-key\\\",\\\"created\\\":\\\"2020-12-30T05:19:44Z\\\",\\\"signatureValue\\\":\\\"sRPhSyfmnVC6UhqjjYfreITzU7fQlSAn+LHEWcNXNOTwHYYHikcXCsQjOHANCDpXYezOna84ynZJI67PNNQB39WNKv579zjGMZkmNVpeQlVRiCuxvFDvs5oplYkUQEjxZhC6dd8iQ8NEOYTNMwrIKbPd7c/oILeMqgyVjJWSTChkJcq4/NG7YS+oR36kW3AFOXW0+rF9xI8+PI70PWuVvZ1T66rvF15Yq0cZRenI/DP61MPif/nI5k4eTLDktLv5Zl5LfW7g1FNBO1XOtaD4yLiUWlvTXmjsXwtviyS4Serx9yTitQCaWKbVvhi9dNMVd5OXE++vU0J7xQ0v8CNnww==\\\"}}\",80576,\"https://2to2.xyz/inbox\"],\"jid\":\"8506efad2d79804fd06f6c4c\",\"created_at\":1609305586.1595027,\"enqueued_at\":1609308551.8289003,\"error_message\":\"https://2to2.xyz/inbox\",\"error_class\":\"Stoplight::Error::RedLight\",\"failed_at\":1609305621.0071929,\"retry_count\":6,\"retried_at\":1609307109.5087583}"}
Dec 30 06:09:11 git bundle[13246]: 2020-12-30T06:09:11.909Z pid=13246 tid=3jaunm WARN: Stoplight::Error::RedLight: https://2to2.xyz/inbox
Test script

Test script

#!/usr/bin/env python
# coding: utf-8

# In[1]:


from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5 
from Crypto.Hash import SHA256 
from base64 import b64decode
import requests
import json
import re


# In[2]:


def verify_mastodon(caddy_object):
    request = caddy_object['request']
    headers = request['headers']
    headers = dict(map(lambda x: (x[0].lower(), x[1][0]), tuple(headers.items())))
    signature_header = headers['signature']
    signature_header_dict = dict(map(lambda x: re.match(r'^(\w+)="(.+)"',x).groups(),signature_header.split(',')))

    resp = requests.get(signature_header_dict['keyId'], headers = {'Accept':'application/activity+json'})
    pub_key = resp.json()['publicKey']['publicKeyPem']

    rsakey = RSA.importKey(pub_key)
    signer = PKCS1_v1_5.new(rsakey)
    digest = SHA256.new() 

    def gen_sign_string(signature_header_dict, request, headers):
        sign_headers = signature_header_dict['headers'].split(' ')
        sign_string_list = []
        for sign_header in sign_headers:
            if sign_header == 'host':
                sign_string_list.append((sign_header ,request['host']))
            elif sign_header == '(request-target)':
                request_target = '{method} {path}'.format(method=request['method'].lower(), path=request['uri'])
                sign_string_list.append((sign_header, request_target))
            else:
                sign_string_list.append((sign_header, headers[sign_header]))

        sign_string = '\n'.join(tuple(map(lambda x: ': '.join(x) ,sign_string_list)))
        return sign_string

    sign_string = gen_sign_string(signature_header_dict, request, headers)

    digest.update(sign_string.encode('utf-8'))
    return signer.verify(digest, b64decode(signature_header_dict['signature']))


# In[3]:


def replay_mastodon(caddy_object):
    request = caddy_object['request']
    headers = request['headers']
    headers = dict(map(lambda x: (x[0].lower(), x[1][0]), tuple(headers.items())))
    url = 'https://{host}{path}'.format(host=request['host'],path=request['uri'])
    resp = requests.get(url, headers = headers)
    return resp


# In[4]:


with open('mastodon.social.json') as f:
    mastodon_social = json.load(f)
    
with open('2to2.xyz.json') as f:
    m2to2_xyz = json.load(f)

with open('2to2.xyz_2.json') as f:
    m2to2_xyz_2 = json.load(f)
    
with open('2to2.xyz_3.json') as f:
    m2to2_xyz_3 = json.load(f)


# In[5]:


print('mastodon_social',verify_mastodon(mastodon_social))

print('m2to2_xyz',verify_mastodon(m2to2_xyz))

print('m2to2_xyz_2',verify_mastodon(m2to2_xyz_2))

print('m2to2_xyz_3',verify_mastodon(m2to2_xyz_3))


# In[6]:


r = replay_mastodon(m2to2_xyz_3)
print(r)
print(r.text)
print(r.headers)

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.