PageSourceSearch

https://docs.rspamd.com/assets/js/dc21c1e1.edda0c06.js

js rspamd.com collected 2026-10-02 02:28:22 UTC 10,159 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkrspamd_docs=self.webpackChunkrspamd_docs||[]).push([[493],{11262:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>a,frontMatter:()=>c,metadata:()=>s,toc:()=>t});const s=JSON.parse('{"id":"workers/controller","title":"Controller worker","description":"The controller worker is primarily utilized for managing Rspamd statistics, facilitating the learning process, and serving the WebUI.","source":"@site/docs/workers/controller.md","sourceDirName":"workers","slug":"/workers/controller","permalink":"/workers/controller","draft":false,"unlisted":false,"editUrl":"https://github.com/rspamd/docs.rspamd.com/edit/master/docs/workers/controller.md","tags":[],"version":"current","frontMatter":{"title":"Controller worker"},"sidebar":"docs","previous":{"title":"Normal worker (scanner)","permalink":"/workers/normal"},"next":{"title":"Proxy worker","permalink":"/workers/rspamd_proxy"}}');var i=r(74848),d=r(28453);const c={title:"Controller worker"},o="Controller worker",l={},t=[{value:"Controller configuration",id:"controller-configuration",level:2},{value:"Encryption support",id:"encryption-support",level:2},{value:"Passwords encryption",id:"passwords-encryption",level:2},{value:"Supported commands",id:"supported-commands",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"controller-worker",children:"Controller worker"})}),"\n",(0,i.jsx)(n.p,{children:"The controller worker is primarily utilized for managing Rspamd statistics, facilitating the learning process, and serving the WebUI."}),"\n",(0,i.jsxs)(n.p,{children:["In essence, it operates as a web server that accepts requests and delivers responses in JSON format. Various commands are mapped to specific URLs, and they fall into two categories: read-only commands, which are considered ",(0,i.jsx)(n.code,{children:"unprivileged"}),", and commands like map modification, config alterations, and learning, which necessitate a higher level of privileges called ",(0,i.jsx)(n.code,{children:"enable"}),". These privilege levels are differentiated by passwords. If only one password is specified in the configuration, it is used for both types of commands."]}),"\n",(0,i.jsx)(n.h2,{id:"controller-configuration",children:"Controller configuration"}),"\n",(0,i.jsx)(n.p,{children:"The Rspamd controller worker offers the following configuration options:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Option"}),(0,i.jsx)(n.th,{children:"Default"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"password"})}),(0,i.jsx)(n.td,{children:"-"}),(0,i.jsx)(n.td,{children:"Password required for read-only commands"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"enable_password"})}),(0,i.jsx)(n.td,{children:"-"}),(0,i.jsx)(n.td,{children:"Password required for write (privileged) commands"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"secure_ip"})}),(0,i.jsx)(n.td,{children:"-"}),(0,i.jsxs)(n.td,{children:["List or map of IP addresses allowed password-less access. If using a reverse proxy with ",(0,i.jsx)(n.code,{children:"X-Forwarded-For"}),", include both proxy and client IPs"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"trusted_ips"})}),(0,i.jsx)(n.td,{children:"-"}),(0,i.jsxs)(n.td,{children:["Alias for ",(0,i.jsx)(n.code,{children:"secure_ip"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"static_dir"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"${WWWDIR}"})}),(0,i.jsx)(n.td,{children:"Directory where static files for the web interface are located"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"bind_socket"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"*:11334"})}),(0,i.jsxs)(n.td,{children:["Bind address for the controller worker. Append ",(0,i.jsx)(n.code,{children:"ssl"})," to enable HTTPS (see ",(0,i.jsx)(n.a,{href:"/workers/#https-support",children:"HTTPS support"}),"). See ",(0,i.jsx)(n.a,{href:"/workers/#common-worker-options",children:"common worker options"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"timeout"})}),(0,i.jsx)(n.td,{children:"60s"}),(0,i.jsx)(n.td,{children:"Protocol I/O timeout"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"task_timeout"})}),(0,i.jsx)(n.td,{children:"8s"}),(0,i.jsx)(n.td,{children:"Maximum task processing time for scan requests"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"keypair"})}),(0,i.jsx)(n.td,{children:"-"}),(0,i.jsx)(n.td,{children:"Encryption keypair for secure communications"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"ssl_cert"})}),(0,i.jsx)(n.td,{children:"-"}),(0,i.jsxs)(n.td,{children:["Path to PEM certificate file (required when using ",(0,i.jsx)(n.code,{children:"ssl"})," bind sockets)"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"ssl_key"})}),(0,i.jsx)(n.td,{children:"-"}),(0,i.jsxs)(n.td,{children:["Path to PEM private key file (required when using ",(0,i.jsx)(n.code,{children:"ssl"})," bind sockets)"]})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"encryption-support",children:"Encryption support"}),"\n",(0,i.jsx)(n.p,{children:"To generate a keypair for the scanner you could use:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"rspamadm keypair -u\n"})}),"\n",(0,i.jsx)(n.p,{children:"After running this command, the keypair should appear as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-hcl",children:'keypair {\n    pubkey = "tm8zjw3ougwj1qjpyweugqhuyg4576ctg6p7mbrhma6ytjewp4ry";
1\n    privkey = "ykkrfqbyk34i1ewdmn81ttcco1eaxoqgih38duib1e7b89h9xn3y";\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["You can use its ",(0,i.jsx)(n.strong,{children:"public"})," part thereafter when scanning messages as following:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"rspamc --key tm8zjw3ougwj1qjpyweugqhuyg4576ctg6p7mbrhma6ytjewp4ry <file>\n"})}),"\n",(0,i.jsx)(n.h2,{id:"passwords-encryption",children:"Passwords encryption"}),"\n",(0,i.jsxs)(n.p,{children:["Rspamd now suggests to encrypt passwords when storing them in a configuration. Currently, it uses ",(0,i.jsx)(n.code,{children:"PBKDF2-Blake2"})," function to derive key from a password. To encrypt key, you can use ",(0,i.jsx)(n.code,{children:"rspamadm pw"})," command as following:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"rspamadm pw\nEnter passphrase: <hidden input>\n$1$cybjp37q4w63iogc4erncz1tgm1ce9i5$kxfx9xc1wk9uuakw7nittbt6dgf3qyqa394cnradg191iqgxr8kb\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You can use that line as ",(0,i.jsx)(n.code,{children:"password"})," and ",(0,i.jsx)(n.code,{children:"enable_password"})," (priv) values."]}),"\n",(0,i.jsx)(n.h2,{id:"supported-commands",children:"Supported commands"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/auth"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/symbols"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/actions"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/maps"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/getmap"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/graph"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/pie"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/history"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/historyreset"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/learnspam"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/learnham"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/fuzzyadd"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/fuzzydel"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/fuzzydelhash"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/saveactions"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/savesymbols"})," (priv)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/savemap"})," (priv)"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/scan"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/check"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/checkv2"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/stat"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"/statreset"})," (priv)"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/counters"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/metrics"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["More details available at ",(0,i.jsx)(n.a,{href:"/developers/protocol#controller-http-endpoints",children:"Controller HTTP endpoints"}),"."]})]})}function a(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>c,x:()=>o});var s=r(96540);const i={},d=s.createContext(i);function c(e){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(d.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.