admin/home: warn FRP users
Massimo Melina committed
Apr 13, 2022 at 22:17 UTC
f3dff992dd04c360ef925c59c79cf1c2ffa86172
4 files changed
+24
-4
admin/src/HomePage.ts
+7
-1
@@ -60,6 +60,12 @@ export default function HomePage() {
60
reloadCfg()
61
}
62
}, "ignore this warning")),
63
+ status.frpDetected && entry('warning', `FRP is detected. It should not be used with "type = tcp" with HFS. Possible solutions are`,
64
+ h('ol',{},
65
+ h('li',{}, `configure FRP with type=http (best solution)`),
66
+ h('li',{}, md(`configure FRP to connect to HFS _not_ with 127.0.0.1 (safe, but you won't see users' IPs)`)),
67
+ h('li',{}, `disable "admin access for localhost" in HFS (safe, but you won't see users' IPs)`),
68
+ ))
69
)
70
}
71
@@ -85,5 +91,5 @@ function cfgLink(text=`Configuration page`) {
91
}
92
93
export function proxyWarning(cfg: any, status: any) {
88
- return cfg && !cfg.proxies && !cfg.ignore_proxies && status?.proxyDetected
94
+ return cfg && !cfg.proxies && !cfg.ignore_proxies && status.proxyDetected
95
}
admin/src/index.css
+2
@@ -17,3 +17,5 @@ code {
17
.MuiTreeItem-content {
18
box-sizing: border-box; /* avoid unwanted scrolling caused by its width:100% + padding */
19
}
20
+
21
+ol, ul { margin-top: .2em }
server/src/adminApis.ts
+14
-3
@@ -3,11 +3,11 @@
3
import { ApiError, ApiHandlers } from './apiMiddleware'
4
import { defineConfig, getConfig, getWholeConfig, setConfig } from './config'
5
import { getStatus, getUrls } from './listen'
6
-import { BUILD_TIMESTAMP, FORBIDDEN, HFS_STARTED, VERSION } from './const'
6
+import { BUILD_TIMESTAMP, FORBIDDEN, HFS_STARTED, IS_WINDOWS, VERSION } from './const'
7
import vfsApis from './api.vfs'
8
import accountsApis from './api.accounts'
9
import { Connection, getConnections } from './connections'
10
-import { isLocalHost, onOff, pendingPromise } from './misc'
10
+import { debounceAsync, isLocalHost, onOff, pendingPromise } from './misc'
11
import _ from 'lodash'
12
import events from './events'
13
import { getFromAccount } from './perm'
@@ -19,6 +19,8 @@ import { createReadStream } from 'fs'
19
import * as readline from 'readline'
20
import { loggers } from './log'
21
import { mapPlugins, getAvailablePlugins, Plugin } from './plugins'
22
+import { execFile } from 'child_process'
23
+import { promisify } from 'util'
24
25
export const adminApis: ApiHandlers = {
26
@@ -51,7 +53,10 @@ export const adminApis: ApiHandlers = {
53
https: serverStatus(st.httpsSrv, getConfig('https_port')),
54
urls: getUrls(),
55
proxyDetected: getProxyDetected(),
54
- }
56
+ frpDetected: getConfig('localhost_admin') && !getProxyDetected()
57
+ && getConnections().every(c => isLocalHost(c.ctx || c.socket.remoteAddress || ''))
58
+ && await frpDebounced(),
59
+ }
60
61
function serverStatus(h: typeof st.httpSrv, configuredPort?: number) {
62
return {
@@ -212,3 +217,9 @@ export function ctxAdminAccess(ctx: Koa.Context) {
217
&& !ctx.state.proxiedFor // this may detect an http-proxied request on localhost
218
|| getFromAccount(ctx.state.account, a => a.admin)
219
}
220
+
221
+const frpDebounced = debounceAsync(async () => {
222
+ if (!IS_WINDOWS) return false
223
+ const { stdout } = await promisify(execFile)('tasklist', ['/fi','imagename eq frpc.exe','/nh'])
224
+ return stdout.includes('frpc')
225
+})
server/src/middlewares.ts
+1
@@ -111,6 +111,7 @@ export const someSecurity: Koa.Middleware = async (ctx, next) => {
111
return next()
112
}
113
114
+// this is only about http proxies
115
export function getProxyDetected() {
116
return proxyDetected
117
}