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 = ''