- 教育
- 音视频
- 后端
- 前端
【免费下载链接】bigbluebutton
A complete web conferencing system for virtual classes and more!
本篇技术指南以 BigBlueButton 官方管理文档《Privacy》为骨架,系统梳理了在虚拟课堂等真实部署场景中个人数据的处理与存储位置,涵盖录制(Recordings)的全局开关、缓存文件与保留期、各类日志的轮转与降噪、TURN/coturn 等集成组件的隐私影响,以及 Greenlight、Scalelite 前端联动下的合规配置方案。读完本文,你将掌握如何在 BigBlueButton 服务器上实现"默认最小化留存"的隐私策略,并能针对 GDPR 等法规要求逐项落地的可执行配置。
概述:隐私法规与 BigBlueButton 的合规定位
许多国家与地区都出台了个人数据保护法规。对 BigBlueButton 服务的运营者而言,私有数据保护是最重要的议题之一:欧盟有《通用数据保护条例》(GDPR),美国加州有《加州消费者隐私法案》(CCPA),巴西有《通用数据保护法》(LGPD),且部分法规在特定条件下对境外主体同样具有域外效力。
本节文档的目的,是帮助运营者理解在一个典型 BigBlueButton 部署中,私人数据在哪里被处理、在哪里被存储,以及有哪些配置选项可以控制它。需要特别说明的是:以下内容既不是法律意见,也不完整,属于持续完善中的工作文档(work-in-progress)。在涉及具体合规决策时,仍应咨询法律专业人士。
BigBlueButton 核心组件的隐私相关配置
本节记录 BigBlueButton 自身的隐私相关设置、默认值及配置选项。有一点需要特别注意:通过 apt 升级时,你在配置文件中的修改可能会被静默覆盖(参见上游 issue 9111)。为防止这一点,务必使用/etc/bigbluebutton目录存放本地覆盖配置(参见 配置文件的本地覆盖机制),以确保更改在升级和重启后仍然保留。
录制(Recordings):要么全部录制,要么完全不录制
BigBlueButton 在录制行为上有一个重要的技术特性:当一个房间被创建为"允许录制"(即录制按钮可见)时,BigBlueButton 会录制整个会话,无论录制按钮是否真的被按下。技术原因在于录制产物的一部分(尤其是白板的 SVG 文件)依赖于早期的状态才能被正确加工,详见 录制(Recording)开发文档。
默认情况下这些文件会保存两周(见下文"缓存文件的保留期")。此外,根据不同的使用场景与司法管辖要求,保留"追溯录制"的能力(例如当用户忘记点击录制按钮时)可能是审慎的做法。
前端通过 BigBlueButton API 创建/开启房间时,行为如下:
- 前端指定
record=true:整个会话都会被录制(除非 BigBlueButton 中全局禁用了所有房间的录制); - 前端指定
record=false或未指定该参数:会话不会被录制,会话期间也不会出现"开始/停止"录制按钮。
解决方案一:在 BigBlueButton 中全局禁用录制
服务器运营者可以在/etc/bigbluebutton/bbb-web.properties中覆盖/usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties里disableRecordingDefault的默认值——将disableRecordingDefault=false改为disableRecordingDefault=true即可全局禁用录制。此外,还建议设置breakoutRoomsRecord=false禁用分组讨论室(breakout rooms)的录制。这一点值得独立于disableRecordingDefault=true来推行,因为分组讨论室对典型用户而言往往隐含着一定程度的隐私预期。
从仓库源码可以印证这两个参数的实际含义与注入路径:bigbluebutton.properties 中定义了默认值disableRecordingDefault=false(注释明确说明:true - don't record even if record param in the api call is set to record)以及breakoutRoomsRecord=false;这两个属性随后通过 resources.xml 注入到 Spring Bean 中(disableRecordingDefault与breakoutRoomsRecord属性),最终影响会议创建时的录制开关。
解决方案二:部署后处理脚本,删除无录制标记的录制
服务器运营者可以部署一个自定义脚本,用于清理**没有创建任何录制标记(recording markers)**的录制及其缓存文件。
简单版本:在/etc/sudoers中授权bbb-record:
bigbluebutton ALL = NOPASSWD: /usr/bin/bbb-record并在/usr/local/bigbluebutton/core/scripts/archive/archive.rb(约第 242 行之后)加入删除逻辑:
BigBlueButton.logger.info("There are no recording marks for #{meeting_id}, deleting the recording.") system('sudo', 'bbb-record', '--delete', "#{meeting_id}") || raise('Failed to delete local recording')该思路与仓库中 archive 脚本的现有逻辑一脉相承:archive.rb 在检测到"没有录制标记"时会记录日志There's no recording marks for #{meeting_id}, not processing recording.,并写入一个.norecord状态文件(archive_norecord_file),该文件正是后续 cron 清理任务判断"未录制会议"的依据。对于还需要显式删除 FreeSWITCH/Kurento 录制缓存文件的更完整版本,可参考社区项目 bbb-recording-archive-workaround。
BigBlueButton 会存储会话期间上传的演示文稿
即使房间以record=false启动,BigBlueButton 仍会把会话中的演示文稿(presentations)存储在/var/bigbluebutton目录下。
解决方案:官方文档目前标注为"未知,不清楚未产生录制时哪些后处理动作会被触发"(TODO 待补充最佳实践)。运营者需自行评估该目录的数据留存策略。
BigBlueButton 会完整存储原始录制数据
对于有录制标记的会议,BigBlueButton 会无限期存储原始录制数据,其中包括主持人/演示者尚未点击录制按钮的会话片段。
解决方案:在会议成功归档(archived)后删除原始录制数据。使用 Scalelite 的部署可通过以下修改实现:
在/etc/sudoers中授权:
bigbluebutton ALL = NOPASSWD: /usr/bin/bbb-record并在/usr/local/bigbluebutton/core/scripts/post_publish/scalelite_post_publish.rb(约第 66 行之后)加入:
system('sudo', 'bbb-record', '--delete', "#{meeting_id}") || raise('Failed to delete local recording')对于其他部署方式,应将删除/var/bigbluebutton/recording/raw/$meeting/的操作加入 post-archive 脚本。该数据也可以按周期清理,参见下文"缓存文件的保留期"。
所有录制默认始终可访问
默认情况下,BigBlueButton 的录制是公开可访问的(参见上游 issue 8505)。此外,录制的 URL 很容易被枚举(参见 issue 1466 与 issue 9443)。
解决方案:服务器管理员可以修改 nginx 配置,限制录制 URL 的访问。根据具体场景,nginx 中的鉴权语句可以与前端联动以实施更严格的限制(例如要求与前端相同的凭据)。可参考社区项目 bbb-rec-perm 提供的配置示例与面向 Greenlight 前端的认证回调。
缓存文件(Cache files)
启用录制时,BigBlueButton 组件栈会产生多种缓存文件,具体位置包括:
/var/bigbluebutton/recording/raw//var/bigbluebutton/unpublished//var/bigbluebutton/published/presentation//usr/share/red5/webapps/video/streams//usr/share/red5/webapps/screenshare/streams//usr/share/red5/webapps/video-broadcast/streams//var/kurento/recordings//var/kurento/screenshare//var/freeswitch/meetings/
解决方案:除通过上文"后处理脚本"自动清理外,还可以将这些目录以tmpfs 挂载,让录制缓存只驻留在内存中、不落盘。为此需在/etc/fstab中添加如下条目:
tmpfs /var/bigbluebutton/recording/raw/ tmpfs rw,nosuid,noatime,uid=998,gid=998,size=16G,mode=0755 0 0 tmpfs /var/bigbluebutton/unpublished/ tmpfs rw,nosuid,noatime,uid=998,gid=998,size=16G,mode=0755 0 0 tmpfs /var/bigbluebutton/published/presentation/ tmpfs rw,nosuid,noatime,uid=998,gid=998,size=16G,mode=0755 0 0 tmpfs /usr/share/red5/webapps/video/streams/ tmpfs rw,nosuid,noatime,uid=999,gid=999,size=16G,mode=0755 0 0 tmpfs /usr/share/red5/webapps/screenshare/streams/ tmpfs rw,nosuid,noatime,uid=999,gid=999,size=16G,mode=0755 0 0 tmpfs /usr/share/red5/webapps/video-broadcast/streams/ tmpfs rw,nosuid,noatime,uid=999,gid=999,size=16G,mode=0755 0 0 tmpfs /var/kurento/recordings/ tmpfs rw,nosuid,noatime,uid=996,gid=996,size=16G,mode=0755 0 0 tmpfs /var/kurento/screenshare/ tmpfs rw,nosuid,noatime,uid=996,gid=996,size=16G,mode=0755 0 0 tmpfs /var/freeswitch/meetings/ tmpfs rw,nosuid,noatime,uid=997,gid=997,size=16G,mode=0755 0 0应用后,服务器管理员需执行bbb-conf --stop; mount -a; bbb-conf --start。需要特别注意的是:uid/gid 必须按本地安装实际情况调整,上例假设的用户如下:
red5:x:999:999:red5 user-daemon:/usr/share/red5:/bin/falsebigbluebutton:x:998:998:bigbluebutton:/home/bigbluebutton:/bin/falsefreeswitch:x:997:997:freeswitch:/opt/freeswitch:/bin/bashkurento:x:996:996::/var/lib/kurento:
(官方文档 TODO 注明:应进一步说明这些 uid/gid 的含义以及如何获取本机正确的取值——建议通过id命令对照各服务用户实际 UID/GID 后再填入。)
已删除的录制仍残留在磁盘上
通过deleteRecordingsAPI 删除录制时,BigBlueButton不会立即从磁盘移除文件,而是将其移动到/var/bigbluebutton/deleted/目录,这是一种软删除机制。这样做的目的是在误删时还能恢复,但管理员应意识到:这些文件会持续占用存储空间,且可能包含受合规要求约束的敏感数据。
系统不会自动清理这些文件,已删除的录制将无限期保留在磁盘上(对公众不可访问),直到手动移除。虽然 API 响应中仍能看到相关元数据,但录制文件本身只有手动清理后才会真正消失。
解决方案:要彻底释放磁盘空间,管理员必须手动删除这些文件,最直接的方式是执行:
rm -rf /var/bigbluebutton/deleted/*该命令将永久清除"已删除录制目录"中的全部内容。由于此操作不可逆,强烈建议在操作前确认已有可用备份。
缓存文件的保留期(Retention of cache files)
BigBlueButton 会保留多种缓存与日志文件,其通用保留周期可在/etc/cron.daily/bigbluebutton中配置,相关参数含义如下:
history:演示文稿、red5 缓存、kurento 缓存和 freeswitch 缓存的保留天数;unrecorded_days:没有录制标记的会议(用户预期"未被录制")其录制的保留天数;published_days:已发布录制的原始数据的保留天数;要禁用该清理,需注释掉remove_raw_of_published_recordings这一行。
仓库中的 cron.daily/bigbluebutton 脚本给出了这些参数的默认值:history=5、unrecorded_days=14、published_days=14、log_history=28,并允许通过/etc/default/bigbluebutton-cron-config覆盖。从脚本实现可以看到两个关键机制:
remove_raw_of_recordings_without_marks会扫描/var/bigbluebutton/recording/status下*.norecord状态文件(正是上文 archive.rb 在"无录制标记"时写入的标记文件),对超过unrecorded_days的会议执行bbb-record --delete;remove_raw_of_published_recordings会检查/var/bigbluebutton/recording/status/published/$meeting-$type.done文件,仅删除"已正确发布"(对应全部处理类型均有.done标记)且超过published_days的原始目录。
如需立即删除这些缓存,请参照上文"后处理脚本删除无录制标记的录制"一节。
日志(Logs)
通用日志轮转
如果运营者选择保留录制文件和日志,应当了解并修改以下设置:
/etc/cron.daily/bigbluebutton中的log_history设置,决定录制文件与日志的保留时长(仓库默认log_history=28天,对应/var/log/bigbluebutton、/var/log/bbb-webrtc-sfu、/opt/freeswitch/var/log/freeswitch下超期文件的清理);/etc/logrotate.d/下的bbb-record-core.logrotate与bbb-webrtc-sfu.logrotate配置:前者每8 天轮转/var/log/bigbluebutton/下的bbb-rap-worker.log与sanity.log,后者每7 天轮转/var/log/bbb-webrtc-sfu/下的日志;/usr/share/bbb-web/WEB-INF/classes/logback.xml:每天轮转/var/log/bigbluebutton/bbb-web.log并保留14 天。
BigBlueButton 日志内容
BigBlueButton 会记录与房间的所有交互——何时创建、谁在何时加入、何时离开——这些记录在/var/log/bigbluebutton/bbb-web.log中。可以通过以下方式降低核心应用的日志详细程度:
- 在
/etc/bigbluebutton/bbb-web.properties中设置appLogLevel=Error; - 调整
/usr/share/bbb-web/WEB-INF/classes/logback.xml中的各项设置。
为避免 bbb-webrtc-sfu 记录 IP 地址,可在/usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml中设置level: error。此外,/etc/bbb-apps-akka/application.conf与/etc/bbb-apps-akka/logback.xml中包含与聊天使用情况及聊天消息相关的日志级别配置。
nginx
默认情况下,BigBlueButton 为 nginx 启用了"完整访问日志"(full access logs),其中包含用户 IP 地址、用户名、加入的会议等信息。可以在/etc/nginx/sites-available/bigbluebutton与/etc/nginx/nginx.conf中把日志级别改为仅记录 'ERROR' 来禁用:
error_log /var/log/nginx/bigbluebutton.error.log; access_log /dev/null;FreeSWITCH
FreeSWITCH 的默认安装默认以 DEBUG 级别记录日志,可通过/etc/bbb-fsesl-akka/application.conf与/etc/bbb-fsesl-akka/logback.xml调整。默认配置会存储用户名、加入的会话及时间戳。
集成组件(Integrations)
TURN 服务器
BigBlueButton 使用 TURN 服务器进行 NAT 穿透。默认情况下,BigBlueButton 配置了 freeswitch.org 的 STUN 服务器。你可以自行搭建 TURN/STUN 服务器(参见 TURN 服务器配置指南),并在/usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml中完成配置。
sip.js
在/usr/share/bigbluebutton/html5-client/compatibility/sip.js中硬编码了一个 Google STUN 服务器。不过通常无需担心:由于向 BBB-web 请求 TURN/STUN 设置失败时应返回空数组并覆盖该设置,硬编码的 STUN 服务器并不会被使用。尽管如此,谨慎的服务器管理员仍可选择替换这个默认值。
Greenlight 前端相关的隐私要点
Greenlight 是常与 BigBlueButton 配合的会议室前端,其行为同样影响整体隐私态势。
Greenlight 默认以 record=true 开启新房间
默认情况下,Greenlight 创建会议时向 BigBlueButton 传递record=true,这意味着即使没有按下录制按钮,这些会议也会被录制(参见上文 BigBlueButton 的录制语义)。
解决方案:可以在 Greenlight 房间设置中为所有人全局禁用录制,或由各用户在各自房间内可选关闭(参见上游 pull request 1296)。如有必要,也可直接在 BigBlueButton 服务器配置中彻底禁用录制功能。
Greenlight 默认不要求访客同意隐私政策/录制
BigBlueButton 本身没有强制参与者加入房间前同意隐私政策或被录制的能力。Greenlight 提供一个可选功能(需在基础设置中开启):"Requires the consent of the room initiator and the participants for recording"(要求房间发起者与参与者同意录制),开启后所有参与者进入会议前会看到"本房间将被录制"的警告文本。
解决方案:上游 issue 1163 讨论了如何进一步落地所需改动——可在现有免责声明代码(app/views/rooms/components/_room_event.html.erb第 21 行)基础上扩展:增加隐私政策链接,以及一个用户必须勾选以确认"知晓会议将被录制并同意"的复选框,且仅当勾选后才能启用"加入"按钮。更实质性的改造方向是选择性录制:即排除未同意录制用户的视频、音频、聊天与绘图输入。
Greenlight 在房间 URL 中包含用户名
Greenlight 的房间 URL 中包含房间所有者的用户名,这可能因当地法律而被视为私人数据。该问题的解决依赖上游 issue 1057。
服务条款(Terms of Service)
Greenlight 支持在注册时或为已注册用户展示条款与条件(terms and conditions)。
录制的访问控制
如前文所述,BigBlueButton 录制默认公开且 URL 可枚举(issue 8505、1466、9443)。Greenlight 默认提供两种录制可见性设置:public(录制列在房间页面上)与unlisted(录制仅能通过可枚举的直接链接访问)。
解决方案:Greenlight 可通过补丁获得更细粒度的录制可见性控制。使用社区分支 rec_restrictions 可在录制可见性下拉菜单中增加第三个值(public/unlisted/private),并在 Scalelite 或 BigBlueButton 主机上设置对应录制元数据(gl-listed=true/unlisted/false)。随后可用 bbb-rec-perm 依据该元数据校验录制请求:当录制被设为 private 时返回 403,设为 unlisted 或 public 时正常返回录制。
日志
Rails 日志
默认情况下,Greenlight 记录到$GREENLIGHTDIR/logs/production.log。从.env中删除对应行可以保留日志但不向 Docker 宿主暴露它们。最简单的方案是将$GREENLIGHTDIR/logs/production.log链接到/dev/null。
nginx 日志
默认情况下 Greenlight 为 nginx 启用完整访问日志,包含用户 IP 地址、用户名、加入的会议等信息。可通过在/etc/nginx/sites-available/bigbluebutton与/etc/nginx/nginx.conf中将日志级别切换为仅 'ERROR' 来禁用:
error_log /var/log/nginx/bigbluebutton.error.log; access_log /dev/null;coturn 的日志处理
默认情况下,coturn 记录到/var/log/coturn.log,并带有常规日志轮转。该日志文件包含使用 TURN 服务器的用户的 IP 地址及其使用的端口——结合其他 BigBlueButton 日志,可以识别这些用户加入的会话。
coturn没有限制日志记录的选项,因此这里的最佳方案是将/var/log/coturn.log链接到/dev/null。
Scalelite 的日志处理
Scalelite 使用一个运行 nginx 的容器作为前端,会积累标准的访问日志。默认情况下 Scalelite 为 nginx 启用完整访问日志,包含用户 IP 地址、用户名、加入/观看的会议等信息。最简单的处理方式是将 nginx 迁移到宿主机上(从而去掉 Docker),然后在/etc/nginx/sites-available/bigbluebutton与/etc/nginx/nginx.conf中将日志级别切换为 'ERROR':
error_log /var/log/nginx/bigbluebutton.error.log; access_log /dev/null;此外,scalelite-API 镜像(blindsidenetwks/scalelite:v1-api)的容器也会记录用户活动,例如谁加入了哪个会议:
{"log":"I, [<timestamp>] INFO -- : [<some_identifier>] Redirected to https://<URL>/bigbluebutton/api/join?meetingID=<meeting_ID>\u0026fullName=<name>\u0026password=<hashed_pw>... }自 Scalelite 1.0.9 起实现了日志轮转,这些日志会在一天后自动删除。
GDPR 通用考量
GDPR 列出了几项重要的原则与权利,尤其是:
- 请求(机器可读的)全部已存私人数据聚合副本的权利;
- 擦除全部个人数据的权利;
- 目的限制(Purpose limitation);
- 数据最小化(Data minimisation);
- 存储限制(Storage limitation)。
这些要求在 BigBlueButton 场景下具有特殊性——尤其是房间可以匿名加入:运营者可能无法轻易识别与某个用户关联的所有已存私人信息,尽管这些信息(例如以化名作为访客加入房间时的摄像头录制)按法律仍属于个人/私人数据。
对许多用例而言,最简单的解决方案是不存储用户的任何私人数据。具体措施包括:
- 降低日志级别或禁用日志(将日志指向
/dev/null); - 仅将临时数据保存在内存中(tmpfs)而非磁盘;
- 禁用会话录制功能。
需要明确的是:即便上述措施全部完成,BigBlueButton 服务器仍然会处理所有这些数据。因此,通常仍需要与服务器托管公司签订数据处理协议(Data Processing Agreement),并向服务用户提供关于私人数据处理的告知信息。
总结
BigBlueButton 的隐私治理可以归纳为三条主线:弄清数据在哪(录制原始数据、缓存文件、各类日志的落盘位置)、减少留存(全局禁用录制、调整保留期、tmpfs 内存化、软删除目录手动清理)、控制访问与告知(nginx 录制鉴权、Greenlight 同意弹窗与服务条款、日志降噪)。结合本文给出的源码级配置佐证(如 bigbluebutton.properties 的录制开关、cron.daily/bigbluebutton 的保留期机制、archive.rb 的无标记检测逻辑),运营者可以据此制定符合本地法律要求且可落地的数据保护方案,并为数据处理协议与用户告知提供事实依据。
- 教育
- 音视频
- 后端
- 前端
【免费下载链接】bigbluebutton
A complete web conferencing system for virtual classes and more!
相关推荐
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考