From f633fc5fb9b975ddce323d8a38a21588b16033e7 Mon Sep 17 00:00:00 2001 From: Kyle Baran Date: Fri, 4 Oct 2024 16:00:17 -0700 Subject: [PATCH 1/2] Switched batchinvalidator to use vite-node --- ir-engine/Chart.yaml | 2 +- ir-engine/templates/batch-invalidator-cronjob.yaml | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ir-engine/Chart.yaml b/ir-engine/Chart.yaml index bc82382..9cea2ec 100755 --- a/ir-engine/Chart.yaml +++ b/ir-engine/Chart.yaml @@ -7,7 +7,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 1.0.0 +version: 1.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. diff --git a/ir-engine/templates/batch-invalidator-cronjob.yaml b/ir-engine/templates/batch-invalidator-cronjob.yaml index 8e905a4..caf3cf2 100755 --- a/ir-engine/templates/batch-invalidator-cronjob.yaml +++ b/ir-engine/templates/batch-invalidator-cronjob.yaml @@ -50,9 +50,7 @@ spec: {{ end }} command: [ 'npx', - 'cross-env', - 'ts-node', - '--swc', + 'vite-node', 'scripts/run-batch-invalidation.ts' ] restartPolicy: Never From a400dec8bb50ae590d74cadf1812c500411e9db3 Mon Sep 17 00:00:00 2001 From: Kyle Baran Date: Thu, 5 Dec 2024 16:11:26 -0800 Subject: [PATCH 2/2] Updated nginx configuration for proxying instanceserver websocket connections Previous configuration would use the address and port provided in connection query params to proxy to the correct server. This was subject to manipulation, however, as someone could put whatever values they wanted in there. This would generally only result in getting back something else, but it could be used by a malicious actor to have someone follow an otherwise-genuine engine link that would redirect to a malicious link via the address param. Now, the nginx server-snippet uses a fork of lua-rest-mysql to look up the instance via the instanceID passed as part of the websocket. If it's a valid instance, then it will get the ipAddress from the instance record and proxy to that; otherwise it will terminate the connection attempt. Users cannot make that request proxy to any link they want to any more. This required making an initContainer on the nginx server that installs the and mounts the forked lua-resty-mysql plugin, as it is not included in the core ingress-nginx image. The SQL server connection values must be configured as environment variables here, and a new main-snippet makes them available for nginx to read, as normally nginx does not have access to any ENV_VARs. Resolves IR-5570 --- configs/dev.template.values.yaml | 64 +++++++++++++++++++++++++++- configs/nginx-ingress-aws-values.yml | 47 +++++++++++++++++++- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/configs/dev.template.values.yaml b/configs/dev.template.values.yaml index 8064441..5c3eb90 100644 --- a/configs/dev.template.values.yaml +++ b/configs/dev.template.values.yaml @@ -307,13 +307,75 @@ instanceserver: nginx.ingress.kubernetes.io/affinity-mode: persistent nginx.ingress.kubernetes.io/server-snippet: | location ~* /primus?$ { + set $address ''; + + rewrite_by_lua_block { + local mysql = require("plugins.lua_resty_mysql.main") + local UUID_PATTERN = "^[%daAbBcCdDeEfF-]+$" + local db, err = mysql:new() + if not db then + ngx.say("Failed to instantiate mysql ", err) + return + end + + db:set_timeout(2000) + + local ok, err, errcode, sqlstate = db:connect{ + host = os.getenv("MYSQL_HOST"), + port = os.getenv("MYSQL_PORT"), + database = os.getenv("MYSQL_DATABASE"), + user = os.getenv("MYSQL_USER"), + password = os.getenv("MYSQL_PASSWORD"), + charset = "utf8" + } + + if not ok then + if err then ngx.log(ngx.WARN, "db connection err " .. err) end + if errcode then ngx.log(ngx.WARN, "db connection errcode " .. errcode) end + if sqlstate then ngx.log(ngx.WARN, "db connection sqlstate " .. sqlstate) end + ngx.say("failed to connect: ", err, ": ", errcode, " ", sqlstate) + db:close() + return + end + + local instanceid = ngx.unescape_uri(ngx.var.arg_instanceID) + + if not string.len(instanceid) == 36 then + ngx.say("Invalid instanceID") + ngx.exit(ngx.HTTP_BAD_REQUEST) + end + + local match = string.match(instanceid, UUID_PATTERN) + + if not match then + ngx.say("Invalid instance ID") + ngx.exit(ngx.HTTP_BAD_REQUEST) + end + + if not string.byte(instanceid, 9) == 45 or not string.byte(instanceid, 14) == 45 or not string.byte(instanceid, 19) == 45 or not string.byte(instanceid, 24) then + ngx.say("Invalid instanceId") + ngx.exit(ngx.HTTP_BAD_REQUEST) + end + + local sql = "select id,ipAddress from instance where id = " .. ngx.quote_sql_str(instanceid) .. " and ended = 0" + + local res, err, errcode, sqlstate = db:query(sql) + + if not res or not res[1] then + ngx.say("Invalid instance ID") + ngx.exit(ngx.HTTP_BAD_REQUEST) + end + + ngx.var.address = res[1].ipAddress + } + proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; - proxy_pass http://$arg_address:$arg_port/primus?$args; + proxy_pass http://$address/primus?$args; } host: instanceserver-dev. resources: diff --git a/configs/nginx-ingress-aws-values.yml b/configs/nginx-ingress-aws-values.yml index 3dcf34b..8b301ed 100755 --- a/configs/nginx-ingress-aws-values.yml +++ b/configs/nginx-ingress-aws-values.yml @@ -6,8 +6,7 @@ rbac: controller: allowSnippetAnnotations: true admissionWebhooks: - certManager: - enabled: false + enabled: false config: ssl-redirect: "false" server-snippet: | @@ -15,12 +14,56 @@ controller: if ( $server_port = 80 ) { return 308 https://$host$request_uri; } + plugins: "lua_resty_mysql" + main-snippet: | + env MYSQL_HOST; + env MYSQL_PORT; + env MYSQL_DATABASE; + env MYSQL_PASSWORD; + env MYSQL_USER; containerPort: http: 80 https: 443 special: 8000 opentelemetry: enabled: false + extraVolumes: + - name: lua-plugins + emptyDir: { } + extraInitContainers: + - name: init-clone-lua-resty-mysql + image: k8s.gcr.io/git-sync/git-sync:v3.1.7 + env: + - name: GIT_SYNC_REPO + value: "https://github.com/ir-engine/lua-resty-mysql" + - name: GIT_SYNC_BRANCH + value: "master" + - name: GIT_SYNC_ROOT + value: "/lua_plugins" + - name: GIT_SYNC_DEST + value: "custom" + - name: GIT_SYNC_ONE_TIME + value: "true" + - name: GIT_SYNC_DEPTH + value: "1" + volumeMounts: + - name: lua-plugins + mountPath: /lua_plugins + extraVolumeMounts: + - name: lua-plugins + mountPath: /etc/nginx/lua/plugins/lua_resty_mysql + subPath: custom + extraEnvs: + - name: MYSQL_HOST + value: "" + - name: MYSQL_PORT + value: "" + - name: MYSQL_USER + value: "" + - name: MYSQL_PASSWORD + value: "" + - name: MYSQL_DATABASE + value: "" service: externalTrafficPolicy: Local targetPorts: