前言
前段时间把 Homelab 从矿渣更换为 HPE ProLiant MicroServer Gen10 Plus,不得不说企业级的产品还是比矿渣用起来会舒服很多。目前在 Gen10 Plus 上安装了 ESXi 作为虚拟化环境,跑着 DSM 和 OpenWRT ,开了一个虚拟机专门跑 Docker,同时也跑着我的开发环境。
家里的网络是带公网 IP 的,但是把网页应用直接暴露到公网会有各种各样的安全问题,因此之前一直在找方法保护暴露到公网上的应用。一开始是打算使用 APISIX 或者 Nginx 的AUTH方式来实现,但总感觉有点高射炮打蚊子的诡异感,因此一直没实施。前几天无意间接触到 OAuth-Proxy 这个应用,再加上自己也一直有参与一个 SSO 开源项目——Casdoor 的开发,于是便想着在 Homelab 上部署这套系统来保护暴露在公网上的网页应用。
Casdoor 的部署与设置
Casdoor 是一款支持 OAuth 2.0、OIDC 和 SAML 的 UI 优先集中式身份验证/单点登录 (SSO) 平台,可以使用 Docker 或直接使用源码运行,安装步骤可见:安装文档。
在安装完 Casdoor 后,使用初始账户密码:admin 123
即可进入管理后台。
在登陆 Casdoor 后我们可以添加一些提供商(下称 idp ),方便我们进行登录。如下图我已经添加了四个 idp :
Casdoor 支持的三方登录以及配置流程可以参考官方文档。在完成 idp 的添加后我们进入用户选项栏,我们可以选择添加一个用户或者就使用当前的 admin 账号,点击编辑
按钮,进行三方登录账号的绑定,如下图我已完成所有账户的绑定:
完成用户绑定后,前往应用选项栏,添加一个应用给 OAuth-Proxy 进行使用,目前我们不需要在这里设置过多东西,只需要在提供商部分把我们刚刚添加的 idp 添加上去:
然后我们可以把页面里显示的客户端ID,客户端密钥记录下来,后面会使用到.
另外,个人建议把开启密码登录、启用注册关闭,只使用 idp 进行登录,进一步提高安全性:
至此Casdoor的相关设置就基本结束。
OAuth-Proxy 部署及设置
OAuth-Proxy 的安装有几种方法,我这里是采用了最简单的预编译好的二进制文件。把下载好的可执行文件放到Homelab 中并设置好相关执行权限后,创建一个配置文件,可以根据示例配置文件进行修改。但由于普通的配置文件的 upstreams 功能不太直观,所以我使用的是 Alpha Configuration ,我使用的配置文件config.yml
如下:
injectRequestHeaders:
- name: X-Forwarded-Groups
values:
- claim: groups
- name: X-Forwarded-User
values:
- claim: user
- name: X-Forwarded-Email
values:
- claim: email
- name: X-Forwarded-Preferred-Username
values:
- claim: preferred_username
- name: X-Forwarded-Access-Token
values:
- claim: access_token
metricsServer:
BindAddress: ""
SecureBindAddress: ""
TLS: null
providers:
- ADFSConfig: {}
approvalPrompt: force
azureConfig:
tenant: common
bitbucketConfig: {}
clientID: 7cdxxx96cb6 #这里写刚刚Casdoor获取的客户端ID
clientSecret: 0e6fxxxa36e7ec #这里写刚刚Casdoor获取的客户端m
githubConfig: {}
gitlabConfig: {}
googleConfig: {}
id: oidc=c58c570b63c9bdbfe00c
keycloakConfig: {}
loginGovConfig: {}
oidcConfig:
emailClaim: name
groupsClaim: groups
insecureSkipNonce: true
issuerURL: https://door.example.in #Casdoor的部署地址,需要外网可以访问
userIDClaim: name
provider: oidc
server:
BindAddress: "" #如果不用ssl,这里直接写0.0.0.0:端口号
SecureBindAddress: :7443 #OAuth-Proxy的ssl端口号
TLS:
Cert:
fromFile: /path/to/cert/example.pem #证书文件
Key:
fromFile: /path/to/cert/example.key #证书私钥
upstreamConfig: #这后面的部分就是目前我要保护的一些内网应用
upstreams:
- flushInterval: 1s
id: dsm
passHostHeader: true
path: ^/dsm/(.*)$
rewriteTarget: /$1
proxyWebSockets: true
uri: http://192.168.2.234:5000
insecureSkipTLSVerify: true
- id: emby
path: ^/emby/(.*)$
rewriteTarget: /$1
uri: http://192.168.2.235:8096
- id: pt
path: ^/pt/(.*)$
rewriteTarget: /transmission/web/$1
uri: http://192.168.2.234:9091
- id: esxi
path: ^/esxi/(.*)$
rewriteTarget: /ui/$1
uri: https://192.168.2.135
insecureSkipTLSVerify: true
- id : esxisdk
path: ^/sdk/(.*)$
rewriteTarget: /sdk/$1
uri: https://192.168.2.135
insecureSkipTLSVerify: true
- id: esxiscreen
path: ^/screen(.*)$
rewriteTarget: /screen$1
uri: https://192.168.2.135
insecureSkipTLSVerify: true
- id: esxiws
path: ^/ticket/(.*)$
rewriteTarget: /ticket/$1
insecureSkipTLSVerify: true
uri: https://192.168.2.135
还有一些配置是 Alpha Configuration 无法配置的,因此还要一个普通的配置文件setting.cfg
:
email_domains = [
"*"
]
cookie_secret = "uq-aoO1wq4VVTvkshcNVmD6adSsuE="
cookie_secure = false
上面这个cookie_secret可以通过以下命令生成:
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1 | base64
完成上面的设置之后,运行:
./oauth2-proxy --config setting.cfg --alpha-config config.yml
然后就可以打开设置的地址,访问相关资源,比如我访问我设置的 emby ,会首先显示 OAuth-Proxy 的认证页面:
点击按钮,就会跳转到 Casdoor 的认证页面:
选择方便的方式进行登录,然后就可以看到 Emby 页面了:
存在的问题
如果只打算反代一个网站,基本没有什么问题。如果像我这样希望用一个端口根据不同的路径访问,首先要设置path
和rewriteTarget
,大部分网站设置好这个就ok了,但是像 ESXi 管理页面这种比较麻烦,因为他不会根据当前 uri 来进行识别所有资源地址,因此可以看到配置文件我 ESXi 要反代很多个path,但是emby这种支持比较好,只设置根目录的转发,其他也能很好转发。因此如果应用不多,可以多开几个 OAuth-Proxy,每个 OAuth-Proxy 对应一个端口和应用。
还有一个问题是OpenWRT的网页始终无法通过反代打开,原因还待研究。