mirror of
https://github.com/DIYgod/RSSHub.git
synced 2025-12-05 12:21:31 +08:00
feat!: allowlist & denylist (#13681)
* feat!: allowlist & denylist * Update website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md * Update website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md * Update website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md * Update website/docs/install/README.md * Update website/docs/install/README.md * Update website/docs/install/README.md * Update website/docs/install/README.md * Update website/docs/install/README.md * chore: revert ---------
This commit is contained in:
@@ -85,8 +85,8 @@ const calculateValue = () => {
|
||||
pass: envs.HTTP_BASIC_AUTH_PASS || 'passw0rd',
|
||||
},
|
||||
// access control
|
||||
blacklist: envs.BLACKLIST && envs.BLACKLIST.split(','),
|
||||
whitelist: envs.WHITELIST && envs.WHITELIST.split(','),
|
||||
denylist: envs.DENYLIST && envs.DENYLIST.split(','),
|
||||
allowlist: envs.ALLOWLIST && envs.ALLOWLIST.split(','),
|
||||
allowLocalhost: envs.ALLOW_LOCALHOST,
|
||||
accessKey: envs.ACCESS_KEY,
|
||||
// logging
|
||||
|
||||
@@ -15,7 +15,7 @@ module.exports = async (ctx, next) => {
|
||||
const accessKey = ctx.query.key;
|
||||
const accessCode = ctx.query.code;
|
||||
|
||||
const isControlled = config.accessKey || config.whitelist || config.blacklist;
|
||||
const isControlled = config.accessKey || config.allowlist || config.denylist;
|
||||
|
||||
const allowLocalhost = config.allowLocalhost && (await isLocalhost(ip));
|
||||
|
||||
@@ -38,14 +38,14 @@ module.exports = async (ctx, next) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (config.whitelist) {
|
||||
if (config.whitelist.find((white) => ip.includes(white) || requestPath.includes(white) || requestUA.includes(white))) {
|
||||
if (config.allowlist) {
|
||||
if (config.allowlist.find((item) => ip.includes(item) || requestPath.includes(item) || requestUA.includes(item))) {
|
||||
return grant();
|
||||
}
|
||||
}
|
||||
|
||||
if (config.blacklist) {
|
||||
if (!config.blacklist.find((black) => ip.includes(black) || requestPath.includes(black) || requestUA.includes(black))) {
|
||||
if (config.denylist) {
|
||||
if (!config.denylist.find((item) => ip.includes(item) || requestPath.includes(item) || requestUA.includes(item))) {
|
||||
return grant();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ const timezone = require('@/utils/timezone');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const baseUrl = 'https://ostudy.ynnedu.cn/';
|
||||
const blacklist = ['ynnu-mv.html', 'https://chjiao.ynnu.edu.cn/zsgz/zsjz.htm', 'https://chjiao.ynnu.edu.cn/info/1006/1404.htm', 'https://chjiao.ynnu.edu.cn/zsgz/dksw.htm'];
|
||||
const denylist = ['ynnu-mv.html', 'https://chjiao.ynnu.edu.cn/zsgz/zsjz.htm', 'https://chjiao.ynnu.edu.cn/info/1006/1404.htm', 'https://chjiao.ynnu.edu.cn/zsgz/dksw.htm'];
|
||||
const { body } = await got(baseUrl);
|
||||
const $index = cheerio.load(body);
|
||||
ctx.state.data = {
|
||||
@@ -16,7 +16,7 @@ module.exports = async (ctx) => {
|
||||
// 顶部幻灯片抓取
|
||||
Promise.all(
|
||||
$index('div[carousel-item] > div')
|
||||
.filter((_, element) => !blacklist.includes($index(element).find('a').attr('href')))
|
||||
.filter((_, element) => !denylist.includes($index(element).find('a').attr('href')))
|
||||
.map((_, element) => {
|
||||
const $element = $index(element);
|
||||
const $a = $element.find('a');
|
||||
@@ -46,7 +46,7 @@ module.exports = async (ctx) => {
|
||||
Promise.all(
|
||||
cheerio
|
||||
.load($index('#serviceInform-tpl').html())('.news-li:not(:last-child)')
|
||||
.filter((_, element) => !blacklist.includes($index(element).find('a').attr('href')))
|
||||
.filter((_, element) => !denylist.includes($index(element).find('a').attr('href')))
|
||||
.map((_, element) => {
|
||||
const $element = $index(element);
|
||||
const $a = $element.find('a');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const noFound = 'Auto: Route No Found';
|
||||
const whiteListedUser = ['dependabot[bot]', 'pull[bot]']; // dependabot and downstream PR requested by pull[bot]
|
||||
const allowedUser = ['dependabot[bot]', 'pull[bot]']; // dependabot and downstream PR requested by pull[bot]
|
||||
|
||||
module.exports = async ({ github, context, core }, body, number, sender) => {
|
||||
core.debug(`sender: ${sender}`);
|
||||
@@ -82,10 +82,10 @@ module.exports = async ({ github, context, core }, body, number, sender) => {
|
||||
await updatePrState('open');
|
||||
}
|
||||
|
||||
if (whiteListedUser.includes(sender)) {
|
||||
core.info('PR created by a whitelisted user, passing');
|
||||
if (allowedUser.includes(sender)) {
|
||||
core.info('PR created by a allowed user, passing');
|
||||
await removeLabel();
|
||||
await addLabels(['Auto: whitelisted']);
|
||||
await addLabels(['Auto: allowed']);
|
||||
return;
|
||||
} else {
|
||||
core.debug('PR created by ' + sender);
|
||||
|
||||
@@ -10,17 +10,17 @@ function checkBlock(response) {
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.ACCESS_KEY;
|
||||
delete process.env.BLACKLIST;
|
||||
delete process.env.WHITELIST;
|
||||
delete process.env.DENYLIST;
|
||||
delete process.env.ALLOWLIST;
|
||||
jest.resetModules();
|
||||
server.close();
|
||||
});
|
||||
|
||||
describe('access-control', () => {
|
||||
it(`blacklist`, async () => {
|
||||
it(`denylist`, async () => {
|
||||
const key = '1L0veRSSHub';
|
||||
const code = md5('/test/2' + key);
|
||||
process.env.BLACKLIST = 'est/1,233.233.233.,black';
|
||||
process.env.DENYLIST = 'est/1,233.233.233.,black';
|
||||
process.env.ACCESS_KEY = key;
|
||||
server = require('../../lib/index');
|
||||
const request = supertest(server);
|
||||
@@ -43,21 +43,21 @@ describe('access-control', () => {
|
||||
const response23 = await request.get('/test/2').set('user-agent', 'blackua');
|
||||
checkBlock(response23);
|
||||
|
||||
// wrong key/code, not on blacklist
|
||||
// wrong key/code, not on denylist
|
||||
const response311 = await request.get(`/test/2?key=wrong+${key}`);
|
||||
expect(response311.status).toBe(200);
|
||||
|
||||
const response312 = await request.get(`/test/2?code=wrong+${code}`);
|
||||
expect(response312.status).toBe(200);
|
||||
|
||||
// wrong key/code, on blacklist
|
||||
// wrong key/code, on denylist
|
||||
const response321 = await request.get(`/test/2?key=wrong+${key}`).set('X-Forwarded-For', '233.233.233.233');
|
||||
checkBlock(response321);
|
||||
|
||||
const response322 = await request.get(`/test/2?code=wrong+${code}`).set('X-Forwarded-For', '233.233.233.233');
|
||||
checkBlock(response322);
|
||||
|
||||
// right key/code, on blacklist
|
||||
// right key/code, on denylist
|
||||
const response331 = await request.get(`/test/2?key=${key}`).set('X-Forwarded-For', '233.233.233.233');
|
||||
expect(response331.status).toBe(200);
|
||||
|
||||
@@ -65,10 +65,10 @@ describe('access-control', () => {
|
||||
expect(response332.status).toBe(200);
|
||||
});
|
||||
|
||||
it(`whitelist`, async () => {
|
||||
it(`allowlist`, async () => {
|
||||
const key = '1L0veRSSHub';
|
||||
const code = md5('/test/2' + key);
|
||||
process.env.WHITELIST = 'est/1,233.233.233.,white';
|
||||
process.env.ALLOWLIST = 'est/1,233.233.233.,white';
|
||||
process.env.ACCESS_KEY = key;
|
||||
server = require('../../lib/index');
|
||||
const request = supertest(server);
|
||||
@@ -97,14 +97,14 @@ describe('access-control', () => {
|
||||
const response23 = await request.get('/test/2').set('user-agent', 'whiteua');
|
||||
expect(response23.status).toBe(200);
|
||||
|
||||
// wrong key/code, not on whitelist
|
||||
// wrong key/code, not on allowlist
|
||||
const response311 = await request.get(`/test/2?code=wrong+${code}`);
|
||||
checkBlock(response311);
|
||||
|
||||
const response312 = await request.get(`/test/2?key=wrong+${key}`);
|
||||
checkBlock(response312);
|
||||
|
||||
// wrong key/code, on whitelist
|
||||
// wrong key/code, on allowlist
|
||||
const response321 = await request.get(`/test/2?code=wrong+${code}`).set('X-Forwarded-For', '233.233.233.233');
|
||||
expect(response321.status).toBe(200);
|
||||
|
||||
|
||||
@@ -638,15 +638,15 @@ For readers that do not support HTTP Basic authentication, please refer to [Acce
|
||||
|
||||
### Access Control Configuration
|
||||
|
||||
RSSHub supports access control via access key/code, whitelisting and blacklisting, enabling any will activate access control for all routes. `ALLOW_LOCALHOST: true` will grant access to all localhost IP addresses.
|
||||
RSSHub supports access control via access key/code, allowlisting and denylisting, enabling any will activate access control for all routes. `ALLOW_LOCALHOST: true` will grant access to all localhost IP addresses.
|
||||
|
||||
#### White/blacklisting
|
||||
#### Allowlisting/denylisting
|
||||
|
||||
- `WHITELIST`: the blacklist. When set, values in `BLACKLIST` are disregarded
|
||||
- `ALLOWLIST`: the allowlist. When set, values in `DENYLIST` are disregarded
|
||||
|
||||
- `BLACKLIST`: the blacklist
|
||||
- `DENYLIST`: the denylist
|
||||
|
||||
White/blacklisting support IP, route and UA as values, fuzzy matching. Use `,` as the delimiter to separate multiple values, eg: `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59`
|
||||
Allowlisting/denylisting support IP, route and UA as values, fuzzy matching. Use `,` as the delimiter to separate multiple values, eg: `ALLOWLIST=1.1.1.1,2.2.2.2,/qdaily/column/59`
|
||||
|
||||
#### Access Key/Code
|
||||
|
||||
@@ -662,12 +662,12 @@ Access code is the md5 generated based on the access key + route, eg:
|
||||
|
||||
- Or using `key` directly, eg: `https://rsshub.app/qdaily/column/59?key=ILoveRSSHub`
|
||||
|
||||
See the relation between access key/code and white/blacklisting.
|
||||
See the relation between access key/code and allowlist/denylisting.
|
||||
|
||||
| | Whitelisted | Blacklisted | Correct access key/code | Wrong access key/code | No access key/code |
|
||||
| | Allowlist | Denylist | Correct access key/code | Wrong access key/code | No access key/code |
|
||||
| ----------- | ----------- | ----------- | ----------------------- | --------------------- | ------------------ |
|
||||
| Whitelisted | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Blacklisted | ✅ | ❌ | ✅ | ❌ | ❌ |
|
||||
| Allowlist | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Denylist | ✅ | ❌ | ✅ | ❌ | ❌ |
|
||||
|
||||
### Logging Configurations
|
||||
|
||||
@@ -888,7 +888,7 @@ See docs of the specified route and `lib/config.js` for detailed information.
|
||||
|
||||
- pianyuan 全部路由:[注册地址](https://pianyuan.org)
|
||||
|
||||
- `PIANYUAN_COOKIE`: 对应 cookie 中的 `py_loginauth`, 例: PIANYUAN_COOKIE='py_loginauth=xxxxxxxxxx'
|
||||
- `PIANYUAN_COOKIE`: 对应 cookie 中的 `py_loginauth`, 例:PIANYUAN_COOKIE='py_loginauth=xxxxxxxxxx'
|
||||
|
||||
- Pixabay: [Documentation](https://pixabay.com/api/docs/)
|
||||
|
||||
@@ -1020,7 +1020,7 @@ See docs of the specified route and `lib/config.js` for detailed information.
|
||||
|
||||
- 网易云歌单及听歌排行
|
||||
|
||||
- `NCM_COOKIES`: 网易云音乐登陆后的 cookie 值.
|
||||
- `NCM_COOKIES`: 网易云音乐登陆后的 cookie 值。
|
||||
|
||||
- 微博 个人时间线路由:[申请地址](https://open.weibo.com/connect)
|
||||
|
||||
@@ -1030,11 +1030,11 @@ See docs of the specified route and `lib/config.js` for detailed information.
|
||||
|
||||
- 微博 自定义分组
|
||||
|
||||
- `WEIBO_COOKIES`: 用户访问网页微博时所使用的 cookie, 获取方式:
|
||||
1. 打开并登录 [https://m.weibo.cn](https://m.weibo.cn) (确保打开页面为手机版,如果强制跳转电脑端可尝试使用可更改 UserAgent 的浏览器插件)
|
||||
2. 按下`F12`打开控制台,切换至`Network(网络)`面板
|
||||
3. 在该网页切换至任意关注分组,并在面板打开最先捕获到的请求 (该情形下捕获到的请求路径应包含`/feed/group`)
|
||||
4. 查看该请求的`Headers(请求头)`, 找到`Cookie`字段并复制内容
|
||||
- `WEIBO_COOKIES`: 用户访问网页微博时所使用的 cookie, 获取方式:
|
||||
1. 打开并登录 [https://m.weibo.cn](https://m.weibo.cn) (确保打开页面为手机版,如果强制跳转电脑端可尝试使用可更改 UserAgent 的浏览器插件)
|
||||
2. 按下`F12`打开控制台,切换至`Network(网络)`面板
|
||||
3. 在该网页切换至任意关注分组,并在面板打开最先捕获到的请求 (该情形下捕获到的请求路径应包含`/feed/group`)
|
||||
4. 查看该请求的`Headers(请求头)`, 找到`Cookie`字段并复制内容
|
||||
|
||||
- 小宇宙:需要 App 登陆后抓包获取相应数据。
|
||||
|
||||
@@ -1054,5 +1054,5 @@ See docs of the specified route and `lib/config.js` for detailed information.
|
||||
|
||||
- 知乎用户关注时间线
|
||||
|
||||
- `ZHIHU_COOKIES`: 知乎登录后的 cookie 值.
|
||||
1. 可以在知乎网页版的一些请求的请求头中找到,如 `GET /moments` 请求头中的 `cookie` 值.
|
||||
- `ZHIHU_COOKIES`: 知乎登录后的 cookie 值。
|
||||
1. 可以在知乎网页版的一些请求的请求头中找到,如 `GET /moments` 请求头中的 `cookie` 值。
|
||||
|
||||
@@ -27,7 +27,7 @@ sidebar: auto
|
||||
|
||||
默认推荐使用 `diygod/rsshub` 即 `diygod/rsshub:latest` 最新版镜像以获取最新路由。
|
||||
|
||||
当 `diygod/rsshub:latest` 存在问题时,可以使用以日期为标签的近期镜像临时使用,例如:
|
||||
当 `diygod/rsshub:latest` 存在问题时,可以使用以日期为标签的近期镜像临时使用,例如:
|
||||
|
||||
```bash
|
||||
$ docker pull diygod/rsshub:2021-06-18
|
||||
@@ -144,7 +144,7 @@ $ docker run -d --name rsshub -p 1200:1200 -e CACHE_EXPIRE=3600 -e GITHUB_ACCESS
|
||||
|
||||
## Ansible 部署
|
||||
|
||||
这个 Ansible playbook 包括了 RSSHub, Redis, browserless (依赖 Docker) 以及 Caddy 2
|
||||
这个 Ansible playbook 包括了 RSSHub, Redis, browserless (依赖 Docker) 以及 Caddy 2
|
||||
|
||||
目前只支持 Ubuntu 20.04
|
||||
|
||||
@@ -632,15 +632,15 @@ async function handleRequest(request) {
|
||||
|
||||
### 访问控制配置
|
||||
|
||||
RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行访问控制。开启任意选项将会激活全局访问控制,没有访问权限将会导致访问被拒绝。同时可以通过 `ALLOW_LOCALHOST: true` 赋予所有本地 IP 访问权限。
|
||||
RSSHub 支持使用访问密钥 / 码,允许清单和拒绝清单三种方式进行访问控制。开启任意选项将会激活全局访问控制,没有访问权限将会导致访问被拒绝。同时可以通过 `ALLOW_LOCALHOST: true` 赋予所有本地 IP 访问权限。
|
||||
|
||||
#### 黑白名单
|
||||
#### 允许清单/拒绝清单
|
||||
|
||||
- `WHITELIST`: 白名单,设置白名单后黑名单无效
|
||||
- `ALLOWLIST`: 允许清单,设置允许清单后拒绝清单无效
|
||||
|
||||
- `BLACKLIST`: 黑名单
|
||||
- `DENYLIST`: 拒绝清单
|
||||
|
||||
黑白名单支持 IP、路由和 UA,模糊匹配,设置多项时用英文逗号 `,` 隔开,例如 `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59`
|
||||
允许清单/拒绝清单支持 IP、路由和 UA,模糊匹配,设置多项时用英文逗号 `,` 隔开,例如 `ALLOWLIST=1.1.1.1,2.2.2.2,/qdaily/column/59`
|
||||
|
||||
#### 访问密钥 / 码
|
||||
|
||||
@@ -656,13 +656,13 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
||||
|
||||
- 或使用访问密钥 `key` 直接访问所有路由,例如:`https://rsshub.app/qdaily/column/59?key=ILoveRSSHub`
|
||||
|
||||
访问密钥 / 码与黑白名单的访问控制关系如下:
|
||||
访问密钥 / 码与允许清单/拒绝清单的访问控制关系如下:
|
||||
|
||||
| | 正确访问密钥 / 码 | 错误访问密钥 / 码 | 无访问密钥 / 码 |
|
||||
| ---------- | ----------------- | ----------------- | --------------- |
|
||||
| 在白名单中 | ✅ | ✅ | ✅ |
|
||||
| 在黑名单中 | ✅ | ❌ | ❌ |
|
||||
| 无黑白名单 | ✅ | ❌ | ❌ |
|
||||
| 在允许清单中 | ✅ | ✅ | ✅ |
|
||||
| 在拒绝清单中 | ✅ | ❌ | ❌ |
|
||||
| 无允许清单/拒绝清单 | ✅ | ❌ | ❌ |
|
||||
|
||||
### 日志配置
|
||||
|
||||
@@ -785,7 +785,7 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
||||
|
||||
- Discourse
|
||||
|
||||
- `DISCOURSE_CONFIG_{id}`: 一个 Discourse 驱动的论坛的配置信息, `id` 可自由设定为任意数字或字符串。值应形如`{"link":link,"key":key}`。其中:
|
||||
- `DISCOURSE_CONFIG_{id}`: 一个 Discourse 驱动的论坛的配置信息, `id` 可自由设定为任意数字或字符串。值应形如`{"link":link,"key":key}`。其中:
|
||||
- `link`:论坛的链接。
|
||||
- `key`访问论坛 API 的密钥,可参考 [此处代码](https://pastebin.com/YbLCgdWW) 以获取。需要确保有足够权限访问对应资源。
|
||||
|
||||
@@ -871,7 +871,7 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
||||
|
||||
- pianyuan 全部路由:[注册地址](https://pianyuan.org)
|
||||
|
||||
- `PIANYUAN_COOKIE`: 对应 cookie 中的 `py_loginauth`, 例: PIANYUAN_COOKIE='py_loginauth=xxxxxxxxxx'
|
||||
- `PIANYUAN_COOKIE`: 对应 cookie 中的 `py_loginauth`, 例:PIANYUAN_COOKIE='py_loginauth=xxxxxxxxxx'
|
||||
|
||||
- pixiv 全部路由:[注册地址](https://accounts.pixiv.net/signup)
|
||||
|
||||
@@ -1011,7 +1011,7 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
||||
|
||||
- 网易云歌单及听歌排行
|
||||
|
||||
- `NCM_COOKIES`: 网易云音乐登陆后的 cookie 值.
|
||||
- `NCM_COOKIES`: 网易云音乐登陆后的 cookie 值。
|
||||
|
||||
- 微博 个人时间线路由:[申请地址](https://open.weibo.com/connect)
|
||||
|
||||
@@ -1021,11 +1021,11 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
||||
|
||||
- 微博 自定义分组
|
||||
|
||||
- `WEIBO_COOKIES`: 用户访问网页微博时所使用的 cookie, 获取方式:
|
||||
1. 打开并登录 [https://m.weibo.cn](https://m.weibo.cn) (确保打开页面为手机版,如果强制跳转电脑端可尝试使用可更改 UserAgent 的浏览器插件)
|
||||
2. 按下`F12`打开控制台,切换至`Network(网络)`面板
|
||||
3. 在该网页切换至任意关注分组,并在面板打开最先捕获到的请求 (该情形下捕获到的请求路径应包含`/feed/group`)
|
||||
4. 查看该请求的`Headers(请求头)`, 找到`Cookie`字段并复制内容
|
||||
- `WEIBO_COOKIES`: 用户访问网页微博时所使用的 cookie, 获取方式:
|
||||
1. 打开并登录 [https://m.weibo.cn](https://m.weibo.cn) (确保打开页面为手机版,如果强制跳转电脑端可尝试使用可更改 UserAgent 的浏览器插件)
|
||||
2. 按下`F12`打开控制台,切换至`Network(网络)`面板
|
||||
3. 在该网页切换至任意关注分组,并在面板打开最先捕获到的请求 (该情形下捕获到的请求路径应包含`/feed/group`)
|
||||
4. 查看该请求的`Headers(请求头)`, 找到`Cookie`字段并复制内容
|
||||
|
||||
- 小宇宙:需要 App 登陆后抓包获取相应数据。
|
||||
|
||||
@@ -1045,5 +1045,5 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
||||
|
||||
- 知乎用户关注时间线
|
||||
|
||||
- `ZHIHU_COOKIES`: 知乎登录后的 cookie 值.
|
||||
1. 可以在知乎网页版的一些请求的请求头中找到,如 `GET /moments` 请求头中的 `cookie` 值.
|
||||
- `ZHIHU_COOKIES`: 知乎登录后的 cookie 值。
|
||||
1. 可以在知乎网页版的一些请求的请求头中找到,如 `GET /moments` 请求头中的 `cookie` 值。
|
||||
|
||||
Reference in New Issue
Block a user