不记得从何时开始,密码管理软件成为了我生活中不可或缺的一部分。在尝试过多种软件之后,我一开始使用的是开源的KeePass。但是可能也正因为开源的原因,其对应的软件以及浏览器插件需要靠志愿者来支持,因此质量相对就参差不齐。后来也尝试过其他的软件比如说SafeinCloud,这个软件对比Keepass已经要方便不少。后来有一天我在Reddit看沙雕贴的时候无意看到有人提了一嘴BitWarden,一试之下马上就转用它了。特别是它提供self-hosting的选项更是点燃了我学习使用Docker的热情。可惜的是官方self-hosting的镜像对于vps的性能要求较高,我的小服务器完全没法承受。还好有大神在官方镜像的基础上开发了一个轻量版Bitwarden_rs,经过我几年的使用,功能齐全,性能稳定,我想也是时候写一篇文章,寄希望于可以帮助更多的人在自己的服务器上保存自己的密码。
废话不多说,开整。
安装Docker
我在这里默认大家已经安装好了Docker以及Docker Compose,不知道如何安装的朋友可以参考官方文档如下。
Traefik 2的配置
接下来就是Traefik的Docker Compose文件,Traefik的静态和动态配置文件范例。在本文中我会把Traefik和BitWarden的docker-compose文件分开,这样两个conatiner不需要在同一时间生成以便于管理。同时我也放弃了外联gist,因为有些Hexo的皮肤对于外链gist的支持不好。
Docker Compose - docker-compose.yml
这一次我会详细讲解一下这个文件的一些配置和作用(我的粗浅理解,见笑见笑),以后其他文章可以直接引用。
Attributes |
Name |
Information |
Image |
traefik:latest |
这里我用的是最新的Traefik的docker image |
container_name |
traefik |
我把这个container命名为traefik 方便之后的查看 |
security_opt |
no-new-privileges:true |
防止container获取不必要的权限,可加可不加 |
ports |
80:80 |
打开80端口(http) |
|
443:443 |
打开443端口(https) |
volumes |
/etc/localtime:/etc/localtime:ro |
解决可能会出现的conatiner和主机时间不一致的问题 |
|
/etc/timezone:/etc/timezone:ro |
解决可能会出现的conatiner和主机时间不一致的问题 |
|
/var/run/docker.sock:/var/run/docker.sock:ro |
检测Docker的动向 |
|
./data/traefik.yml:/traefik.yml:ro |
挂载本地静态配置 文件traefik.yml |
|
./data/acme.json:/acme.json |
挂载acme.json 文件用来放SSL证书 |
|
./data/configurations:/configurations |
挂载configuration 文件夹,里面是动态配置 文件 |
networks |
proxy |
把Traefik加入到外部的叫proxy 的网络中 |
labels |
traefik.enable=true |
允许Traefik使用本container |
|
traefik.http.routers.traefik.entrypoints=http |
定义通过哪个entry point可以访问。我在静态配置 里面定义了http 是80端口 |
|
traefik.http.routers.traefik.rule=Host(traefik.yourdomain ) |
定义访问http的host name |
|
traefik.http.routers.traefik.middlewares=https-redirect@file |
使用这个叫做https-redirect 的middleware来把http转到https,该middleware我们会在动态配置 文件里面定义 |
|
traefik.http.routers.traefik-secure.entrypoints=https |
定义通过哪个entry point可以访问。我在静态配置 里面定义了https 是443端口 |
|
traefik.http.routers.traefik-secure.rule=Host(traefik.yourdomain ) |
定义访问https的host name |
|
traefik.http.routers.traefik-secure.middlewares=user-auth@file |
使用这个叫做user-auth 的middleware,该middleware提供简易的认证服务,保护Traefik的dashboard。该middleware我们会在动态配置 文件里面定义 |
|
traefik.http.routers.traefik-secure.tls=true |
这里声明的是我们会使用SSL证书 |
|
traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt |
定义用具体的某个服务平台来提供证书,证书的平台在静态配置 里面配置。 |
|
traefik.http.routers.traefik-secure.service=api@internal |
这里是把api https的访问和traefik的dashboard作为服务连接在一起 |
networks: |
Proxy: external: true |
定义Proxy这个网络 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| version: '3.3'
services: traefik: image: traefik:latest container_name: traefik restart: always security_opt: - no-new-privileges:true ports: - 80:80 - 443:443 volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/traefik.yml:/traefik.yml:ro - ./data/acme.json:/acme.json - ./data/configurations:/configurations networks: - proxy labels: - "traefik.enable=true" - "traefik.http.routers.traefik.entrypoints=http" - "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain`)" - "traefik.http.routers.traefik.middlewares=https-redirect@file" - "traefik.http.routers.traefik-secure.entrypoints=https" - "traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain`)" - "traefik.http.routers.traefik-secure.middlewares=user-auth@file" - "traefik.http.routers.traefik-secure.tls=true" - "traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.traefik-secure.service=api@internal" networks: proxy: external: true
|
看起来好像很复杂,实际上如果你用我的配置,只需要修改您的域名应该可以拿来就用……
Static Configuration - traefik.yml
这个我觉得还是挺好理解的。这里声明Traefik使用docker和file两个provider,docker当然不用解释,file这个provider主要挂载了动态的配置文件。
另外我添加了两个证书服务,一个是Let’sEncrypt,另外一个是BuyPass。两者都是免费的,前者的证书有效期3个月但是可以随意搭配包括通配符在内的所有DV证书。后者有效期6个月,但是只提供免费的单域名证书。对于普通用户来说,只要不需要通配符以及不需要在同一张证书上放所有的域名,用哪个都一样。对了,BuyPass有证书数量的限制,具体可以参考其官网。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| api: dashboard: true
entryPoints: http: address: ":80" https: address: ":443"
providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false file: filename: /configurations/dynamic.yml
certificatesResolvers: letsencrypt: acme: email: [email protected] storage: acme.json keyType: EC384 httpChallenge: entryPoint: http buypass: acme: email: [email protected] storage: acme.json caServer: https://api.buypass.com/acme/directory keyType: EC256 httpChallenge: entryPoint: http
|
Dynamic Configuration - dynamic.yml
动态配置文件主要放的是一些middleware和SSL的选项。这些middleware还算是比较简单明了
Attributes |
Name |
Information |
middleware |
https-redirect |
这个用于http转接https |
|
secureHeaders |
这个用于,呃,把网站的ssllabs评级调到A+ …… |
|
bw-stripPrefix |
BitWarden WebSocket需要,可选用 |
|
user-auth |
Traefik Dashboard,用户名和密码的基础认证 |
tls |
cipherSuites |
规定使用的cipher suites,关闭一些比较弱的cipher。 |
|
minVersion |
规定最低的TLS版本,我这里规定最低TLS1.2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| http: middlewares: https-redirect: redirectScheme: scheme: https permanent: true secureHeaders: headers: frameDeny: true sslRedirect: true browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true stsIncludeSubdomains: true stsPreload: true stsSeconds: 31536000 bw-stripPrefix: stripPrefix: prefixes: - "/notifications/hub" forceSlash: false user-auth: basicAuth: users: - "admin:$apr1$tm53ra6x$FntXd6jcvxYM/YH0P2hcc1" tls: options: default: cipherSuites: - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 minVersion: VersionTLS12
|
BitWarden的Docker Compose - docker-compose.yml
这个docker compose文件跟上面Traefik的大同小异,只是多了websocket的部分。
老实说我自己正在用的BitWarden并没有用WebSocket,不过大部分教程包括官方实例都有包括它,所以我在大量试错之后找到了以下的配置方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| version: '3'
services: bitwarden: image: bitwardenrs/server:latest container_name: bitwarden restart: always volumes: - ./bw-data:/data environment: - SIGNUPS_ALLOWED=false - WEBSOCKET_ENABLED=true networks: - proxy labels: - "traefik.enable=true" - "traefik.http.routers.bitwarden.entrypoints=http" - "traefik.http.routers.bitwarden.rule=Host(`bw.yourdomain`)" - "traefik.http.routers.bitwarden.service=bitwarden" - "traefik.http.services.bitwarden.loadbalancer.server.port=80" - "traefik.http.routers.bitwarden.middlewares=https-redirect@file" - "traefik.http.routers.bitwarden-secure.middlewares=secureHeaders@file" - "traefik.http.routers.bitwarden-secure.entrypoints=https" - "traefik.http.routers.bitwarden-secure.rule=Host(`bw.yourdomain`)" - "traefik.http.routers.bitwarden-secure.service=bitwarden-secure" - "traefik.http.services.bitwarden-secure.loadbalancer.server.port=80" - "traefik.http.routers.bitwarden-secure.tls=true" - "traefik.http.routers.bitwarden-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.bitwarden-ws.entrypoints=https" - "traefik.http.routers.bitwarden-ws.rule=Host(`bw.sslfor.fun`) && Path(`/notifications/hub`)" - "traefik.http.middlewares.bitwarden-ws=bw-stripPrefix@file" - "traefik.http.middlewares.bitwarden-ws=secureHeaders@file" - "traefik.http.routers.bitwarden-ws.tls=true" - "traefik.http.routers.bitwarden-ws.tls.certresolver=letsencrypt" - "traefik.http.routers.bitwarden-ws.service=bitwarden-ws" - "traefik.http.services.bitwarden-ws.loadbalancer.server.port=3012"
networks: proxy: external: true
|
最后
在修改保存好这些文件之后只需先输入docker network create proxy
生成proxy网络,然后分别在两个文件夹运行docker-compose up -d
即可部署。
需要注意一点的是这两个文件需要放在不同的文件夹里面,比如说Traefik的这个放在~/docker-compose.yml
,BitWarden这个可以放在比如说~/bitwarden/docker-compose.yml
这样的文件夹下。
那么有没有办法不分开两个文件呢?有的😁
Traefik和BitWarden同一时间部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| version: '3'
services: traefik: image: traefik:latest container_name: traefik restart: unless-stopped security_opt: - no-new-privileges:true ports: - 80:80 - 443:443 volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/traefik.yml:/traefik.yml:ro - ./data/acme.json:/acme.json - ./data/configurations:/configurations labels: - "traefik.enable=true" - "traefik.http.routers.traefik.entrypoints=http" - "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain`)" - "traefik.http.routers.traefik.middlewares=https-redirect@file" - "traefik.http.routers.traefik-secure.entrypoints=https" - "traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain`)" - "traefik.http.routers.traefik-secure.middlewares=user-auth@file" - "traefik.http.routers.traefik-secure.tls=true" - "traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.traefik-secure.service=api@internal" bitwarden: image: bitwardenrs/server:latest container_name: bitwarden restart: always volumes: - ./bw-data:/data environment: - SIGNUPS_ALLOWED=false - WEBSOCKET_ENABLED=true labels: - "traefik.enable=true" - "traefik.http.routers.bitwarden.entrypoints=http" - "traefik.http.routers.bitwarden.rule=Host(`bw.yourdomain`)" - "traefik.http.routers.bitwarden.service=bitwarden" - "traefik.http.services.bitwarden.loadbalancer.server.port=80" - "traefik.http.routers.bitwarden.middlewares=https-redirect@file" - "traefik.http.routers.bitwarden-secure.middlewares=secureHeaders@file" - "traefik.http.routers.bitwarden-secure.entrypoints=https" - "traefik.http.routers.bitwarden-secure.rule=Host(`bw.yourdomain`)" - "traefik.http.routers.bitwarden-secure.service=bitwarden-secure" - "traefik.http.services.bitwarden-secure.loadbalancer.server.port=80" - "traefik.http.routers.bitwarden-secure.tls=true" - "traefik.http.routers.bitwarden-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.bitwarden-ws.entrypoints=https" - "traefik.http.routers.bitwarden-ws.rule=Host(`bw.yourdomain`) && Path(`/notifications/hub`)" - "traefik.http.middlewares.bitwarden-ws=bw-stripPrefix@file" - "traefik.http.middlewares.bitwarden-ws=secureHeaders@file" - "traefik.http.routers.bitwarden-ws.tls=true" - "traefik.http.routers.bitwarden-ws.tls.certresolver=letsencrypt" - "traefik.http.routers.bitwarden-ws.service=bitwarden-ws" - "traefik.http.services.bitwarden-ws.loadbalancer.server.port=3012"
|
希望此教程可以刺激各位开始使用密码管理软件,甚至在自己的服务器上管理自己的密码。
谢谢观看