From 68d3f3ee91b7180a32ff234a5dfa617b4bcea4a4 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 15 Feb 2021 22:06:53 +0000 Subject: [PATCH] Broch mode --- blocking.py | 51 ++++++++++++++++++++++++++++++++++++++++++++ daemon.py | 18 +++++++++++++++- epicyon.py | 13 ++++++++++- tests.py | 12 ++++++++--- translations/ar.json | 3 ++- translations/ca.json | 3 ++- translations/cy.json | 3 ++- translations/de.json | 3 ++- translations/en.json | 3 ++- translations/es.json | 3 ++- translations/fr.json | 3 ++- translations/ga.json | 3 ++- translations/hi.json | 3 ++- translations/it.json | 3 ++- translations/ja.json | 3 ++- translations/oc.json | 3 ++- translations/pt.json | 3 ++- translations/ru.json | 3 ++- translations/zh.json | 3 ++- webapp_profile.py | 10 +++++++++ 20 files changed, 129 insertions(+), 20 deletions(-) diff --git a/blocking.py b/blocking.py index 982d4e14c..cfa885a79 100644 --- a/blocking.py +++ b/blocking.py @@ -7,6 +7,7 @@ __email__ = "bob@freedombone.net" __status__ = "Production" import os +from utils import setConfigParam from utils import hasUsersPath from utils import getFullDomain from utils import removeIdEnding @@ -356,3 +357,53 @@ def outboxUndoBlock(baseDir: str, httpPrefix: str, nicknameBlocked, domainBlockedFull) if debug: print('DEBUG: post undo blocked via c2s - ' + postFilename) + + +def setBrochMode(baseDir: str, domainFull: str, enabled: bool) -> None: + """Broch mode can be used to lock down the instance during + a period of time when it is temporarily under attack. + For example, where an adversary is constantly spinning up new + instances. + It surveys the following lists of all accounts and uses that + to construct an instance level allow list. Anything arriving + which is then not from one of the allowed domains will be dropped + """ + allowFilename = baseDir + '/accounts/allowedinstances.txt' + + if not enabled: + # remove instance allow list + if os.path.isfile(allowFilename): + os.remove(allowFilename) + else: + # generate instance allow list + allowedDomains = [domainFull] + for subdir, dirs, files in os.walk(baseDir + '/accounts'): + for acct in dirs: + if '@' not in acct: + continue + if 'inbox@' in acct or 'news@' in acct: + continue + accountDir = os.path.join(baseDir + '/accounts', acct) + followingFilename = accountDir + '/following.txt' + if not os.path.isfile(followingFilename): + continue + with open(followingFilename, "r") as f: + followList = f.readlines() + for handle in followList: + if '@' not in handle: + continue + handle = handle.replace('\n', '') + handleDomain = handle.split('@')[1] + if handleDomain not in allowedDomains: + allowedDomains.append(handleDomain) + break + + # write the allow file + allowFile = open(allowFilename, "w+") + if allowFile: + allowFile.write(domainFull + '\n') + for d in allowedDomains: + allowFile.write(d + '\n') + allowFile.close() + + setConfigParam(baseDir, "brochMode", enabled) diff --git a/daemon.py b/daemon.py index b8f763f33..9d3014250 100644 --- a/daemon.py +++ b/daemon.py @@ -109,6 +109,7 @@ from threads import threadWithTrace from threads import removeDormantThreads from media import replaceYouTube from media import attachMedia +from blocking import setBrochMode from blocking import addBlock from blocking import removeBlock from blocking import addGlobalBlock @@ -4543,6 +4544,17 @@ class PubServer(BaseHTTPRequestHandler): setConfigParam(baseDir, "verifyAllSignatures", verifyAllSignatures) + brochMode = False + if fields.get('brochMode'): + if fields['brochMode'] == 'on': + brochMode = True + if brochMode != self.server.brochMode: + setBrochMode(self.server.baseDir, + self.server.domainFull, + brochMode) + self.server.brochMode = brochMode + setConfigParam(baseDir, "brochMode", brochMode) + # change moderators list if fields.get('moderators'): if path.startswith('/users/' + @@ -13924,7 +13936,8 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None: break -def runDaemon(verifyAllSignatures: bool, +def runDaemon(brochMode: bool, + verifyAllSignatures: bool, sendThreadsTimeoutMins: int, dormantMonths: int, maxNewswirePosts: int, @@ -14007,6 +14020,9 @@ def runDaemon(verifyAllSignatures: bool, # maximum number of posts to appear in the newswire on the right column httpd.maxNewswirePosts = maxNewswirePosts + # whether to enable broch mode, which locks down the instance + httpd.brochMode = brochMode + # whether to require that all incoming posts have valid jsonld signatures httpd.verifyAllSignatures = verifyAllSignatures diff --git a/epicyon.py b/epicyon.py index 1a741302c..cf0289c65 100644 --- a/epicyon.py +++ b/epicyon.py @@ -279,6 +279,11 @@ parser.add_argument("--verifyAllSignatures", const=True, default=False, help="Whether to require that all incoming " + "posts have valid jsonld signatures") +parser.add_argument("--brochMode", + dest='brochMode', + type=str2bool, nargs='?', + const=True, default=False, + help="Enable broch mode") parser.add_argument("--noapproval", type=str2bool, nargs='?', const=True, default=False, help="Allow followers without approval") @@ -2292,6 +2297,11 @@ verifyAllSignatures = \ if verifyAllSignatures is not None: args.verifyAllSignatures = bool(verifyAllSignatures) +brochMode = \ + getConfigParam(baseDir, 'brochMode') +if brochMode is not None: + args.brochMode = bool(brochMode) + YTDomain = getConfigParam(baseDir, 'youtubedomain') if YTDomain: if '://' in YTDomain: @@ -2305,7 +2315,8 @@ if setTheme(baseDir, themeName, domain, args.allowLocalNetworkAccess): print('Theme set to ' + themeName) if __name__ == "__main__": - runDaemon(args.verifyAllSignatures, + runDaemon(args.brochMode, + args.verifyAllSignatures, args.sendThreadsTimeoutMins, args.dormantMonths, args.maxNewswirePosts, diff --git a/tests.py b/tests.py index 7186012a1..5a4bd233e 100644 --- a/tests.py +++ b/tests.py @@ -325,8 +325,10 @@ def createServerAlice(path: str, domain: str, port: int, sendThreadsTimeoutMins = 30 maxFollowers = 10 verifyAllSignatures = True + brochMode = False print('Server running: Alice') - runDaemon(verifyAllSignatures, + runDaemon(brochMode, + verifyAllSignatures, sendThreadsTimeoutMins, dormantMonths, maxNewswirePosts, allowLocalNetworkAccess, @@ -420,8 +422,10 @@ def createServerBob(path: str, domain: str, port: int, sendThreadsTimeoutMins = 30 maxFollowers = 10 verifyAllSignatures = True + brochMode = False print('Server running: Bob') - runDaemon(verifyAllSignatures, + runDaemon(brochMode, + verifyAllSignatures, sendThreadsTimeoutMins, dormantMonths, maxNewswirePosts, allowLocalNetworkAccess, @@ -469,8 +473,10 @@ def createServerEve(path: str, domain: str, port: int, federationList: [], sendThreadsTimeoutMins = 30 maxFollowers = 10 verifyAllSignatures = True + brochMode = False print('Server running: Eve') - runDaemon(verifyAllSignatures, + runDaemon(brochMode, + verifyAllSignatures, sendThreadsTimeoutMins, dormantMonths, maxNewswirePosts, allowLocalNetworkAccess, diff --git a/translations/ar.json b/translations/ar.json index 605d5b98b..fd4f8fbbe 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -368,5 +368,6 @@ "Skip to Newswire": "انتقل إلى Newswire", "Skip to Links": "تخطي إلى روابط الويب", "Publish a blog article": "نشر مقال بلوق", - "Featured writer": "كاتب متميز" + "Featured writer": "كاتب متميز", + "Broch mode": "وضع الكتيب" } diff --git a/translations/ca.json b/translations/ca.json index 3c8846bbf..2965f88d8 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Vés a Newswire", "Skip to Links": "Vés als enllaços web", "Publish a blog article": "Publicar un article del bloc", - "Featured writer": "Escriptor destacat" + "Featured writer": "Escriptor destacat", + "Broch mode": "Mode Broch" } diff --git a/translations/cy.json b/translations/cy.json index 6e45de39d..f1e31b718 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Neidio i Newswire", "Skip to Links": "Neidio i Dolenni Gwe", "Publish a blog article": "Cyhoeddi erthygl blog", - "Featured writer": "Awdur dan sylw" + "Featured writer": "Awdur dan sylw", + "Broch mode": "Modd Broch" } diff --git a/translations/de.json b/translations/de.json index c15cb492f..4053a453c 100644 --- a/translations/de.json +++ b/translations/de.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Springe zu Newswire", "Skip to Links": "Springe zu Weblinks", "Publish a blog article": "Veröffentlichen Sie einen Blog-Artikel", - "Featured writer": "Ausgewählter Schriftsteller" + "Featured writer": "Ausgewählter Schriftsteller", + "Broch mode": "Broch-Modus" } diff --git a/translations/en.json b/translations/en.json index 3fbbfdd34..d376154ee 100644 --- a/translations/en.json +++ b/translations/en.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Skip to Newswire", "Skip to Links": "Skip to Links", "Publish a blog article": "Publish a blog article", - "Featured writer": "Featured writer" + "Featured writer": "Featured writer", + "Broch mode": "Broch mode" } diff --git a/translations/es.json b/translations/es.json index 3566d06b0..135ff9c13 100644 --- a/translations/es.json +++ b/translations/es.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Saltar a Newswire", "Skip to Links": "Saltar a enlaces web", "Publish a blog article": "Publica un artículo de blog", - "Featured writer": "Escritora destacada" + "Featured writer": "Escritora destacada", + "Broch mode": "Modo broche" } diff --git a/translations/fr.json b/translations/fr.json index 78c7ff547..308ba5e9b 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Passer à Newswire", "Skip to Links": "Passer aux liens Web", "Publish a blog article": "Publier un article de blog", - "Featured writer": "Écrivain en vedette" + "Featured writer": "Écrivain en vedette", + "Broch mode": "Mode Broch" } diff --git a/translations/ga.json b/translations/ga.json index 75f87780c..92f67c50f 100644 --- a/translations/ga.json +++ b/translations/ga.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Scipeáil chuig Newswire", "Skip to Links": "Scipeáil chuig Naisc Ghréasáin", "Publish a blog article": "Foilsigh alt blagála", - "Featured writer": "Scríbhneoir mór le rá" + "Featured writer": "Scríbhneoir mór le rá", + "Broch mode": "Modh broch" } diff --git a/translations/hi.json b/translations/hi.json index acf417f88..82c401422 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Newswire पर जाएं", "Skip to Links": "वेब लिंक पर जाएं", "Publish a blog article": "एक ब्लॉग लेख प्रकाशित करें", - "Featured writer": "फीचर्ड लेखक" + "Featured writer": "फीचर्ड लेखक", + "Broch mode": "ब्रोच मोड" } diff --git a/translations/it.json b/translations/it.json index f2bc1e1ed..c189c2335 100644 --- a/translations/it.json +++ b/translations/it.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Passa a Newswire", "Skip to Links": "Passa a collegamenti Web", "Publish a blog article": "Pubblica un articolo sul blog", - "Featured writer": "Scrittore in primo piano" + "Featured writer": "Scrittore in primo piano", + "Broch mode": "Modalità Broch" } diff --git a/translations/ja.json b/translations/ja.json index 9f1275544..49bfffbef 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Newswireにスキップ", "Skip to Links": "Webリンクにスキップ", "Publish a blog article": "ブログ記事を公開する", - "Featured writer": "注目の作家" + "Featured writer": "注目の作家", + "Broch mode": "ブロッホモード" } diff --git a/translations/oc.json b/translations/oc.json index c9e3717a0..fa4620d9a 100644 --- a/translations/oc.json +++ b/translations/oc.json @@ -364,5 +364,6 @@ "Skip to Newswire": "Skip to Newswire", "Skip to Links": "Skip to Links", "Publish a blog article": "Publish a blog article", - "Featured writer": "Featured writer" + "Featured writer": "Featured writer", + "Broch mode": "Broch mode" } diff --git a/translations/pt.json b/translations/pt.json index b2a29ca2d..52694082b 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Pular para Newswire", "Skip to Links": "Pular para links da web", "Publish a blog article": "Publique um artigo de blog", - "Featured writer": "Escritor em destaque" + "Featured writer": "Escritor em destaque", + "Broch mode": "Modo broch" } diff --git a/translations/ru.json b/translations/ru.json index 618c5cbf0..41c2d5a91 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -368,5 +368,6 @@ "Skip to Newswire": "Перейти к ленте новостей", "Skip to Links": "Перейти к веб-ссылкам", "Publish a blog article": "Опубликовать статью в блоге", - "Featured writer": "Избранный писатель" + "Featured writer": "Избранный писатель", + "Broch mode": "Брош режим" } diff --git a/translations/zh.json b/translations/zh.json index e7fab5755..f63deb616 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -368,5 +368,6 @@ "Skip to Newswire": "跳到新闻专线", "Skip to Links": "跳到网页链接", "Publish a blog article": "发布博客文章", - "Featured writer": "特色作家" + "Featured writer": "特色作家", + "Broch mode": "断点模式" } diff --git a/webapp_profile.py b/webapp_profile.py index 8c7704390..0d2fe362d 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -1278,6 +1278,16 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str, ' ' + \ translate['Verify all signatures'] + '
\n' + if getConfigParam(baseDir, "brochMode"): + instanceStr += \ + ' ' + \ + translate['Broch mode'] + '
\n' + else: + instanceStr += \ + ' ' + \ + translate['Broch mode'] + '
\n' instanceStr += '' moderators = ''