Docker系列 阅后即焚公共平台Privatebin

发布于 2022-07-02  69 次阅读


前言

最近经朋友推荐,我发现了一个很特别的应用,叫PrivateBin,其Github Repo有4k+的Star。PrivateBin是一个开源的在线匿名分享服务,有阅后即焚的方便功能。它的作用很简单,就是在无需实名和注册的情况下,通过PrivateBin可粘贴内容/上传文件并生成一个链接。不过,对于接收文件的人来说,这是一个有限制的链接。比如,如果在密码栏里输入一个密码,那么有密码的人才可以查阅链接内容;或者是有效期很短,甚至是只可以打开1次(所谓的阅后即焚)。对于某些想临时传送文件或内容的小伙伴来说,简直就是神器!

根据PrivateBin的自我介绍(Google机翻):

PrivateBin是一个极简的开源在线粘贴箱 ,服务器对粘贴数据的了解为零。数据在浏览器中使用256位AES在Galois Counter模式下进行加密和解密。
这是ZeroBin的一个分支,最初由Sébastien Sauvage开发。PrivateBin进行了重构,以允许更简单、更清晰的扩展,并具有许多附加功能。然而,它仍然完全兼容原始的 ZeroBin 0.19 数据存储方案。因此,此类安装可以升级到 PrivateBin而不会丢失任何数据。

作为服务器管理员,如果您的用户发布在您所在国家/地区被视为非法的内容,您不必担心。您可以合理地否认任何粘贴内容。如果要求或强制执行,您可以从系统中删除任何粘贴。类似Pastebin的系统,用于存储文本文档、代码示例等。加密发送到服务器的数据。可以设置阅读粘贴所需的密码。它进一步保护了粘贴并防止人们在没有密码的情况下偶然发现粘贴的链接。

作为用户,您必须相信服务器管理员不会注入任何恶意代码。为了安全起见,必须通过HTTPS使用PrivateBin安装!否则,您还必须信任您的互联网提供商以及流量通过的任何司法管辖区。此外,该实例应由HSTS保护。它可以使用传统的证书颁发机构和/或使用受DNSSEC保护的DANE记录。
用于加密粘贴的“密钥”是URL的一部分。如果您公开发布不受密码保护的粘贴URL,任何人都可以阅读它。如果您希望您的粘贴保持私密,请使用密码。在这种情况下,请确保使用强密码并私下共享并进行端到端加密。
可以强制服务器管理员将访问日志交给当局。PrivateBin会加密您的文本和讨论内容,但谁访问了粘贴(首先)可能仍会通过访问日志披露。
如果服务器遭到破坏,您的数据是安全的,因为它仅以加密方式存储在服务器上。但是,服务器可能被滥用,或者服务器管理员可能被合法地强制向其用户发送恶意代码,该代码记录解密密钥并在用户访问粘贴时将其发送到服务器。因此,如果您认为任何 PrivateBin实例已被入侵,请不要访问它。只要没有用户使用先前生成的URL访问此实例,就无法解密内容。

看上去功能似乎很强大。不过,我在CSDN看到过一个PrivateBin漏洞的近期披露报告:开源工具 PrivateBin 修复XSS 漏洞,大伙可以看看。我觉得,开源应用多多少少都有一些漏洞,有时你也不知道这是偶然漏洞还是开发者有意留下的后门。另外一个疑点是,目前PrivateBin似乎也没有参数可以定义有限的上传者(比如要注册用户;或者仅服务管理者),开发者似乎有意让PrivateBin变得极具扩张性和渗透性。PrivateBin官方还收集了许多自建站点并制作成列表

NVIDIA_Share_I8lYo4O6cC

虽然PrivateBin宣称它的种种好处,但我觉得传送一些普通的内容是没问题的;如果你打算利用PrivateBin传送重要数据,还是要三思而后行

另外,服务管理员为什么要公开PrivateBin呢,这样知道地址的人不是可以随便白嫖你的PrivateBin了?可能的原因之一是因为PrivateBin可以通过info参数自定义字段从而植入广告。比如,一个经典的PrivateBin外观如下:

image-20220619084700373

你可以在右下角放一些自己的链接啥的。我有一个自建Demo,大伙试玩一下,目前功能还是比较有限的:https://bonus01.hwb0307.com,日后视情况可能会关闭,总之很不稳定,只作测试,不要当主力使用!本教程主要是展示要如何通过Docker自建PrivateBin应用。由于本教程的方法使用MYSQL数据库进行管理,并且自定义了很多参数,所以和默认的官方安装方法相比略显复杂。但性能和自定义程度自然也是大大的增加了!

另外,下面的密码和帐户均经过匿名化处理,不是真实的用户和密码。一般自建服务时,大家也要按需修改相应参数,最好不要用我的默认参数(我发现很多人直接无脑粘贴我的命令,这是极不推荐的;应该在理解参数的前提下进行个性化定制)。

准备工作

设定一个工作目录:

# 按需修改
work=~/docker/privatebin && mkdir -p $work/privatebin-data && cd $work

设置好privatebin-data的用户(组)(按官方文档的建议。否则PrivateBin无法正常使用):

sudo chown -R 65534:82 $work/privatebin-data

防火墙开启相应的端口:

# 按需修改
sudo ufw allow 3456/tcp comment 'PrivateBin' && sudo ufw reload

拉取镜像:

docker pull privatebin/nginx-fpm-alpine:latest
# docker pull mysql:5.7 # 如果有mysql镜像就不用再拉了

配置php.ini

设置PrivateBin的参数上限。我的习惯是上限设置得很大。

这里是php.in参考示例。首先,新建php.ini文件:

vim $work/php.ini

添加以下内容:

[PHP]
; Enable the PHP scripting language engine under Apache.
; http://php.net/engine
engine = On

; This directive determines whether or not PHP will recognize code between
; <? and ?> tags as PHP source which should be processed as such. It is
; generally recommended that <?php and ?> should be used and that this feature
; should be disabled, as enabling it may result in issues when generating XML
; documents, however this remains supported for backward compatibility reasons.
; Note that this directive does not control the <?= shorthand tag, which can be
; used regardless of this directive.
; Default Value: On
; Development Value: Off
; Production Value: Off
; http://php.net/short-open-tag
short_open_tag = Off

; The number of significant digits displayed in floating point numbers.
; http://php.net/precision
precision = 14

; Output buffering is a mechanism for controlling how much output data
; (excluding headers and cookies) PHP should keep internally before pushing that
; data to the client. If your application's output exceeds this setting, PHP
; will send that data in chunks of roughly the size you specify.
; Turning on this setting and managing its maximum buffer size can yield some
; interesting side-effects depending on your application and web server.
; You may be able to send headers and cookies after you've already sent output
; through print or echo. You also may see performance benefits if your server is
; emitting less packets due to buffered output versus PHP streaming the output
; as it gets it. On production servers, 4096 bytes is a good setting for performance
; reasons.
; Note: Output buffering can also be controlled via Output Buffering Control
;   functions.
; Possible Values:
;   On = Enabled and buffer is unlimited. (Use with caution)
;   Off = Disabled
;   Integer = Enables the buffer and sets its maximum size in bytes.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
; http://php.net/output-buffering
output_buffering = 4096

; Maximum allowed size for uploaded files.
upload_max_filesize = 100M

; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 100M

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 1280M

; Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 180

:wq保存即可。

配置conf.php

配置PrivateBin的实际运行参数。按需修改。

参考官方文档:https://github.com/PrivateBin/PrivateBin/blob/master/cfg/conf.sample.php

<?php http_response_code(403);
[main]
/*个性化服务名*/
name = "BenszPrivateBin"
/*允许讨论*/
discussion = true
/*阅后即焚为默认选项。默认情况下,所有的链接只能被浏览1次。*/
burnafterreadingselected = true
/*允许文件上传。默认上限是10M。这里我设置了20M*/
fileupload = ture
sizelimit = 20971520
/*个性化备注。通常用来植入广告。*/
info = "在<a href='https://blognas.hwb0307.com/ad'>这里</a>有更多苯苯推荐好物!"
/*语言可选*/
languageselection = true
/*默认粘贴文本类型为markdown*/
defaultformatter = "markdown"
/*支持一键二维码*/
qrcode = true

[expire_options]
/*设置时间。由于是公开的,所以我将最长有效时间设置为15min。默认条件下甚至可以设置为永久。大家看官方文档设置吧,我这里不多介绍。*/
5min = 300
10min = 600
15min = 900

[model]
/*使用MYSQL进行文件管理。仔细体会参数的含义,应该不难。*/
class = Database
[model_options]
dsn = "mysql:host=db;dbname=test_userdb;charset=UTF8"
tbl = "privatebin_"
usr = "test_user"
pwd = "aLQtB6aNBPTZk7mkvU5FySzxy"
opt[12] = true

:wq保存即可。

配置yml文件

新建文件:

vim $work/docker-compose.yml

添加以下内容:

version: "3.7"

services:
  app:
    image: privatebin/nginx-fpm-alpine:latest
    restart: unless-stopped
    read_only: false
    volumes:
      - './privatebin-data:/srv/data'
      - './conf.php:/srv/cfg/conf.php:ro'
      - './php.ini:/etc/php7/php.ini:ro'
    ports:
      - 3456:8080 # 按需修改。与ufw开放端口对应。
    links:
      - db
    networks: 
      - default

  db:
    image: mysql:5.7
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: T6a8uThA45fGC5Ns6XftjKRf4 # 按需修改。后面有用。
      MYSQL_DATABASE: test_userdb
      MYSQL_USER: test_user
      MYSQL_PASSWORD: aLQtB6aNBPTZk7mkvU5FySzxy # 按需修改,与conf.php的model-pwd参数对应。
    volumes:
      - './db:/var/lib/mysql'
    networks:
      - default

networks:
  default:
    name: privatebin

:wq保存后,直接上线服务:

cd $work && docker-compose up -d

MYSQL设置

修改默认值

默认情况下,mysql的max_allowed_packet只有4M,对于较大的文件上传会出现类似下列报错:

privatebin-db-1   | 2022-06-18T23:26:30.253182Z 2 [Note] Aborted connection 2 to db: 'db' user: 'user' host: 'XXX' (Got a packet bigger than 'max_allowed_packet' bytes)

所以我们要修改这个参数的默认值。主要参考此文

首先,进入mysql容器的内部

docker exec -it privatebin-db-1 /bin/bash

下载安装Vim:

apt update && apt install vim -y

编辑文件:

vim /etc/my.cnf

填入以下内容(这里我将max_allowed_packet设置为100M,你可按需修改):

[mysqld]
max_allowed_packet = 100M

exit命令退出mysql容器内部后,重启服务:

docker-compose restart

检查生效

为了确定更改是否生效,我们可以进入mysql数据库(注意不是bash)的内部:

docker exec -it privatebin-db-1 mysql -u root -p

在本示例中,根据docker-compose.yml的MYSQL_ROOT_PASSWORD参数,密码为T6a8uThA45fGC5Ns6XftjKRf4。实际使用中你要按需修改。

然后,查询max_allowed_packet参数:

mysql> show VARIABLES like 'max_allowed_packet';

结果为:

+--------------------+-----------+
| Variable_name      | Value     |
+--------------------+-----------+
| max_allowed_packet | 104857600 |
+--------------------+-----------+
1 row in set (0.01 sec)

说明设置已经生效。最后,退出mysql:

mysql> exit

NPM & ddns-go

不了解Nginx Proxy Manager用法的小伙伴,请看《Docker系列 两大神器NPM和ddns-go的安装》。

ddns-go或者域名托管后台里添加域名:privatebin.example.com

NPM无特殊设置。类似于:

image-20220619093933029

使用方法

直接访问:https://privatebin.example.com,不用注册和登陆。使用过程如下图:

MobaXterm1_CHS_jdsBiCapyv

成功后,会生成一个很长的链接:

MobaXterm1_CHS_bSI3osgPJP

别人访问这个链接并输入密码后,会看到你要发送的内容:

MobaXterm1_CHS_IqAKNIWGOk

如果对方刷新窗口或者关闭窗口,这个链接就会失效,因为默认设置了阅后即焚。你也可以不勾选它,这样他的有效期就是前面你设置的时间。感觉PrivateBin的使用很简单、很方便!

小结

大家可以在我的自建PrivateBin里试用一下,看看效果。我个人建议是,有条件的话你还是自己搞一个来玩!自建一个PrivateBin,平时和家人、同事或朋友传内容时会方便很多,也不用担心自己的文件或者代码会被互联网截取。最后还要特别提醒大家,使用互联网应用时要严格遵守当地国家地区的相关法律法规,不要做恶!最后还是要多说一句,你用PrivateBin传一些普通内容可以,但强烈不推荐你用PrivateBin来传重要甚至是机密的内容/文件,否则后果自负!

致谢

  • 感谢Derek大佬关于conf.php文件的debug测试!
  • 感谢VDvB32XkkT大佬关于basic authentification的建议(虽然最后还是决定公开)!

参考