Broch mode

merge-requests/18/head
Bob Mottram 2021-02-15 22:06:53 +00:00
parent 721ff8ddf5
commit 68d3f3ee91
20 changed files with 129 additions and 20 deletions

View File

@ -7,6 +7,7 @@ __email__ = "bob@freedombone.net"
__status__ = "Production" __status__ = "Production"
import os import os
from utils import setConfigParam
from utils import hasUsersPath from utils import hasUsersPath
from utils import getFullDomain from utils import getFullDomain
from utils import removeIdEnding from utils import removeIdEnding
@ -356,3 +357,53 @@ def outboxUndoBlock(baseDir: str, httpPrefix: str,
nicknameBlocked, domainBlockedFull) nicknameBlocked, domainBlockedFull)
if debug: if debug:
print('DEBUG: post undo blocked via c2s - ' + postFilename) 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)

View File

@ -109,6 +109,7 @@ from threads import threadWithTrace
from threads import removeDormantThreads from threads import removeDormantThreads
from media import replaceYouTube from media import replaceYouTube
from media import attachMedia from media import attachMedia
from blocking import setBrochMode
from blocking import addBlock from blocking import addBlock
from blocking import removeBlock from blocking import removeBlock
from blocking import addGlobalBlock from blocking import addGlobalBlock
@ -4543,6 +4544,17 @@ class PubServer(BaseHTTPRequestHandler):
setConfigParam(baseDir, "verifyAllSignatures", setConfigParam(baseDir, "verifyAllSignatures",
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 # change moderators list
if fields.get('moderators'): if fields.get('moderators'):
if path.startswith('/users/' + if path.startswith('/users/' +
@ -13924,7 +13936,8 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None:
break break
def runDaemon(verifyAllSignatures: bool, def runDaemon(brochMode: bool,
verifyAllSignatures: bool,
sendThreadsTimeoutMins: int, sendThreadsTimeoutMins: int,
dormantMonths: int, dormantMonths: int,
maxNewswirePosts: int, maxNewswirePosts: int,
@ -14007,6 +14020,9 @@ def runDaemon(verifyAllSignatures: bool,
# maximum number of posts to appear in the newswire on the right column # maximum number of posts to appear in the newswire on the right column
httpd.maxNewswirePosts = maxNewswirePosts 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 # whether to require that all incoming posts have valid jsonld signatures
httpd.verifyAllSignatures = verifyAllSignatures httpd.verifyAllSignatures = verifyAllSignatures

View File

@ -279,6 +279,11 @@ parser.add_argument("--verifyAllSignatures",
const=True, default=False, const=True, default=False,
help="Whether to require that all incoming " + help="Whether to require that all incoming " +
"posts have valid jsonld signatures") "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='?', parser.add_argument("--noapproval", type=str2bool, nargs='?',
const=True, default=False, const=True, default=False,
help="Allow followers without approval") help="Allow followers without approval")
@ -2292,6 +2297,11 @@ verifyAllSignatures = \
if verifyAllSignatures is not None: if verifyAllSignatures is not None:
args.verifyAllSignatures = bool(verifyAllSignatures) args.verifyAllSignatures = bool(verifyAllSignatures)
brochMode = \
getConfigParam(baseDir, 'brochMode')
if brochMode is not None:
args.brochMode = bool(brochMode)
YTDomain = getConfigParam(baseDir, 'youtubedomain') YTDomain = getConfigParam(baseDir, 'youtubedomain')
if YTDomain: if YTDomain:
if '://' in YTDomain: if '://' in YTDomain:
@ -2305,7 +2315,8 @@ if setTheme(baseDir, themeName, domain, args.allowLocalNetworkAccess):
print('Theme set to ' + themeName) print('Theme set to ' + themeName)
if __name__ == "__main__": if __name__ == "__main__":
runDaemon(args.verifyAllSignatures, runDaemon(args.brochMode,
args.verifyAllSignatures,
args.sendThreadsTimeoutMins, args.sendThreadsTimeoutMins,
args.dormantMonths, args.dormantMonths,
args.maxNewswirePosts, args.maxNewswirePosts,

View File

@ -325,8 +325,10 @@ def createServerAlice(path: str, domain: str, port: int,
sendThreadsTimeoutMins = 30 sendThreadsTimeoutMins = 30
maxFollowers = 10 maxFollowers = 10
verifyAllSignatures = True verifyAllSignatures = True
brochMode = False
print('Server running: Alice') print('Server running: Alice')
runDaemon(verifyAllSignatures, runDaemon(brochMode,
verifyAllSignatures,
sendThreadsTimeoutMins, sendThreadsTimeoutMins,
dormantMonths, maxNewswirePosts, dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess, allowLocalNetworkAccess,
@ -420,8 +422,10 @@ def createServerBob(path: str, domain: str, port: int,
sendThreadsTimeoutMins = 30 sendThreadsTimeoutMins = 30
maxFollowers = 10 maxFollowers = 10
verifyAllSignatures = True verifyAllSignatures = True
brochMode = False
print('Server running: Bob') print('Server running: Bob')
runDaemon(verifyAllSignatures, runDaemon(brochMode,
verifyAllSignatures,
sendThreadsTimeoutMins, sendThreadsTimeoutMins,
dormantMonths, maxNewswirePosts, dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess, allowLocalNetworkAccess,
@ -469,8 +473,10 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
sendThreadsTimeoutMins = 30 sendThreadsTimeoutMins = 30
maxFollowers = 10 maxFollowers = 10
verifyAllSignatures = True verifyAllSignatures = True
brochMode = False
print('Server running: Eve') print('Server running: Eve')
runDaemon(verifyAllSignatures, runDaemon(brochMode,
verifyAllSignatures,
sendThreadsTimeoutMins, sendThreadsTimeoutMins,
dormantMonths, maxNewswirePosts, dormantMonths, maxNewswirePosts,
allowLocalNetworkAccess, allowLocalNetworkAccess,

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "انتقل إلى Newswire", "Skip to Newswire": "انتقل إلى Newswire",
"Skip to Links": "تخطي إلى روابط الويب", "Skip to Links": "تخطي إلى روابط الويب",
"Publish a blog article": "نشر مقال بلوق", "Publish a blog article": "نشر مقال بلوق",
"Featured writer": "كاتب متميز" "Featured writer": "كاتب متميز",
"Broch mode": "وضع الكتيب"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Vés a Newswire", "Skip to Newswire": "Vés a Newswire",
"Skip to Links": "Vés als enllaços web", "Skip to Links": "Vés als enllaços web",
"Publish a blog article": "Publicar un article del bloc", "Publish a blog article": "Publicar un article del bloc",
"Featured writer": "Escriptor destacat" "Featured writer": "Escriptor destacat",
"Broch mode": "Mode Broch"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Neidio i Newswire", "Skip to Newswire": "Neidio i Newswire",
"Skip to Links": "Neidio i Dolenni Gwe", "Skip to Links": "Neidio i Dolenni Gwe",
"Publish a blog article": "Cyhoeddi erthygl blog", "Publish a blog article": "Cyhoeddi erthygl blog",
"Featured writer": "Awdur dan sylw" "Featured writer": "Awdur dan sylw",
"Broch mode": "Modd Broch"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Springe zu Newswire", "Skip to Newswire": "Springe zu Newswire",
"Skip to Links": "Springe zu Weblinks", "Skip to Links": "Springe zu Weblinks",
"Publish a blog article": "Veröffentlichen Sie einen Blog-Artikel", "Publish a blog article": "Veröffentlichen Sie einen Blog-Artikel",
"Featured writer": "Ausgewählter Schriftsteller" "Featured writer": "Ausgewählter Schriftsteller",
"Broch mode": "Broch-Modus"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Skip to Newswire", "Skip to Newswire": "Skip to Newswire",
"Skip to Links": "Skip to Links", "Skip to Links": "Skip to Links",
"Publish a blog article": "Publish a blog article", "Publish a blog article": "Publish a blog article",
"Featured writer": "Featured writer" "Featured writer": "Featured writer",
"Broch mode": "Broch mode"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Saltar a Newswire", "Skip to Newswire": "Saltar a Newswire",
"Skip to Links": "Saltar a enlaces web", "Skip to Links": "Saltar a enlaces web",
"Publish a blog article": "Publica un artículo de blog", "Publish a blog article": "Publica un artículo de blog",
"Featured writer": "Escritora destacada" "Featured writer": "Escritora destacada",
"Broch mode": "Modo broche"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Passer à Newswire", "Skip to Newswire": "Passer à Newswire",
"Skip to Links": "Passer aux liens Web", "Skip to Links": "Passer aux liens Web",
"Publish a blog article": "Publier un article de blog", "Publish a blog article": "Publier un article de blog",
"Featured writer": "Écrivain en vedette" "Featured writer": "Écrivain en vedette",
"Broch mode": "Mode Broch"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Scipeáil chuig Newswire", "Skip to Newswire": "Scipeáil chuig Newswire",
"Skip to Links": "Scipeáil chuig Naisc Ghréasáin", "Skip to Links": "Scipeáil chuig Naisc Ghréasáin",
"Publish a blog article": "Foilsigh alt blagála", "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"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Newswire पर जाएं", "Skip to Newswire": "Newswire पर जाएं",
"Skip to Links": "वेब लिंक पर जाएं", "Skip to Links": "वेब लिंक पर जाएं",
"Publish a blog article": "एक ब्लॉग लेख प्रकाशित करें", "Publish a blog article": "एक ब्लॉग लेख प्रकाशित करें",
"Featured writer": "फीचर्ड लेखक" "Featured writer": "फीचर्ड लेखक",
"Broch mode": "ब्रोच मोड"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Passa a Newswire", "Skip to Newswire": "Passa a Newswire",
"Skip to Links": "Passa a collegamenti Web", "Skip to Links": "Passa a collegamenti Web",
"Publish a blog article": "Pubblica un articolo sul blog", "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"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Newswireにスキップ", "Skip to Newswire": "Newswireにスキップ",
"Skip to Links": "Webリンクにスキップ", "Skip to Links": "Webリンクにスキップ",
"Publish a blog article": "ブログ記事を公開する", "Publish a blog article": "ブログ記事を公開する",
"Featured writer": "注目の作家" "Featured writer": "注目の作家",
"Broch mode": "ブロッホモード"
} }

View File

@ -364,5 +364,6 @@
"Skip to Newswire": "Skip to Newswire", "Skip to Newswire": "Skip to Newswire",
"Skip to Links": "Skip to Links", "Skip to Links": "Skip to Links",
"Publish a blog article": "Publish a blog article", "Publish a blog article": "Publish a blog article",
"Featured writer": "Featured writer" "Featured writer": "Featured writer",
"Broch mode": "Broch mode"
} }

View File

@ -368,5 +368,6 @@
"Skip to Newswire": "Pular para Newswire", "Skip to Newswire": "Pular para Newswire",
"Skip to Links": "Pular para links da web", "Skip to Links": "Pular para links da web",
"Publish a blog article": "Publique um artigo de blog", "Publish a blog article": "Publique um artigo de blog",
"Featured writer": "Escritor em destaque" "Featured writer": "Escritor em destaque",
"Broch mode": "Modo broch"
} }

View File

@ -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": "Избранный писатель",
"Broch mode": "Брош режим"
} }

View File

@ -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": "特色作家",
"Broch mode": "断点模式"
} }

View File

@ -1278,6 +1278,16 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
' <input type="checkbox" class="profilecheckbox" ' + \ ' <input type="checkbox" class="profilecheckbox" ' + \
'name="verifyallsignatures"> ' + \ 'name="verifyallsignatures"> ' + \
translate['Verify all signatures'] + '<br>\n' translate['Verify all signatures'] + '<br>\n'
if getConfigParam(baseDir, "brochMode"):
instanceStr += \
' <input type="checkbox" class="profilecheckbox" ' + \
'name="brochMode" checked> ' + \
translate['Broch mode'] + '<br>\n'
else:
instanceStr += \
' <input type="checkbox" class="profilecheckbox" ' + \
'name="brochMode"> ' + \
translate['Broch mode'] + '<br>\n'
instanceStr += '</div>' instanceStr += '</div>'
moderators = '' moderators = ''