Advertisement
G666h05t

Bugs apple

Sep 28th, 2023
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.82 KB | None | 0 0
  1. Let's see your Apple;)
  2.  
  3.  
  4.  
  5. USING SQL FOR LOOKUPS, LOG/REPORTING AND QUARANTINE
  6. ===================================================
  7.  
  8. Greetz to all members of AnonGhost Indonesia
  9.  
  10.  
  11.  
  12. ../
  13. ./
  14. .
  15. -
  16. ----- ------
  17. ---------
  18.  
  19. Since amavisd-new-20020630 SQL is supported for lookups.
  20. Since amavisd-new-2.3.0 SQL is also supported for storing information
  21. about processed mail (logging/reporting) and optionally for quarantining
  22. to a SQL database.
  23.  
  24. The amavisd.conf variables @storage_sql_dsn and @lookup_sql_dsn control
  25. access to a SQL server and specify a database (dsn = data source name).
  26. The @lookup_sql_dsn enables and specifies a database for lookups,
  27. the @storage_sql_dsn enables and specifies a database for reporting
  28. and quarantining. Both settings are independent.
  29.  
  30. Interpretation of @lookup_sql_dsn and @storage_sql_dsn lists is as follows:
  31. - empty list disables the function and is a default;
  32. - if both lists are empty no SQL support code will be compiled-in,
  33. reducing the amount of virtual memory needed for each child process;
  34. - a list can contain one or more triples: [dsn,user,passw]; more than one
  35. triple may be specified to specify multiple (backup) SQL servers - the first
  36. that responds will be used as long as it works, then search is retried;
  37. - if both lists contain refs to the _same_ triples (not just equal triples),
  38. only one connection to a SQL server will be used; otherwise two independent
  39. connections to databases will be used, possibly to different SQL servers,
  40. which may even be of different type (e.g. SQLlite for lookups (read-only),
  41. and PostgreSQL or MySQL for transactional reporting, offering fine lock
  42. granularity).
  43.  
  44. Example setting:
  45. @lookup_sql_dsn =
  46. ( ['DBI:mysql:database=mail;host=127.0.0.1;port=3306', 'user1', 'passwd1'],
  47. ['DBI:mysql:database=mail;host=host2', 'username2', 'password2'],
  48. ['DBI:Pg:database=mail;host=host1', 'amavis', '']
  49. ["DBI:SQLite:dbname=$MYHOME/sql/mail_prefs.sqlite", '', ''] );
  50.  
  51. @storage_sql_dsn = @lookup_sql_dsn; # none, same, or separate database
  52.  
  53. See man page for the Perl module DBI, and corresponding DBD modules
  54. man pages (DBD::mysql, DBD::Pg, DBD::SQLite, ...) for syntax of the
  55. first argument.
  56.  
  57. Since version 2.3.0 amavisd-new also offers quarantining to a SQL database,
  58. along with a mechanism to release quarantined messages (either from SQL or
  59. from normal files, possibly gzipped). To enable quarantining to SQL, the
  60. @storage_sql_dsn must be enabled (facilitating quarantine management), and
  61. some or all variables $virus_quarantine_method, $spam_quarantine_method,
  62. $banned_files_quarantine_method and $bad_header_quarantine_method should
  63. specify the value 'sql:'. Specifying 'sql:' as a quarantine method without
  64. also specifying a database in @storage_sql_dsn is an error.
  65.  
  66. When setting up access controls to a database, keep in mind that amavisd-new
  67. only needs read-only access to the database used for lookups, the permission
  68. to do a SELECT suffices. For security reasons it is undesirable to permit
  69. other operations such as INSERT, DELETE or UPDATE to a dataset used for
  70. lookups. For managing the lookups database one should preferably use a
  71. different username with more privileges.
  72.  
  73. The database specified in @storage_sql_dsn needs to provide read/write access
  74. (SELECT, INSERT, UPDATE), and a database server offering transactions
  75. must be used.
  76.  
  77.  
  78. Below is an example that can be used with MySQL or PostgreSQL or SQLite.
  79. The provided schema can be cut/pasted or fed directly into the client program
  80. to create a database. The '--' introduces comments according to SQL specs.
  81.  
  82. -- MySQL notes:
  83. -- - SERIAL can be used instead of INT UNSIGNED NOT NULL AUTO_INCREMENT
  84. -- with databases which do not recognize AUTO_INCREMENT;
  85. -- The attribute SERIAL was introduced with MySQL 4.1.0, but it
  86. -- implicitly creates an additional UNIQUE index, which is redundant.
  87. -- - instead of declaring a time_iso field in table msgs as a string:
  88. -- time_iso char(16) NOT NULL,
  89. -- one may want to declare is as:
  90. -- time_iso TIMESTAMP NOT NULL DEFAULT 0,
  91. -- in which case $timestamp_fmt_mysql *MUST* be set to 1 in amavisd.conf
  92. -- to avoid MySQL inability to accept ISO 8601 timestamps with zone Z
  93. -- and ISO date/time delimiter T; failing to set $timestamp_fmt_mysql
  94. -- makes MySQL store zero time on INSERT and write current local time
  95. -- on UPDATE if auto-update is allowed, which is different from the
  96. -- intended mail timestamp (localtime vs. UTC, off by seconds)
  97. -- - field quarantine.mail_text should be of data type 'blob' and not 'text'
  98. -- as suggested in older documentation; this is to prevent it from being
  99. -- unjustifiably associated with a character set, and to be able to
  100. -- store any byte value; to convert existing field from type 'text'
  101. -- to type 'blob' the following clause may be used:
  102. -- ALTER TABLE quarantine CHANGE mail_text mail_text blob;
  103.  
  104. -- PostgreSQL notes (initially provided by Phil Regnauld):
  105. -- - use SERIAL instead of INT UNSIGNED NOT NULL AUTO_INCREMENT
  106. -- - remove the 'unsigned' throughout,
  107. -- - remove the 'ENGINE=InnoDB' throughout,
  108. -- - instead of declaring time_iso field in table msgs as a string:
  109. -- time_iso char(16) NOT NULL,
  110. -- it is more useful to declare it as:
  111. -- time_iso TIMESTAMP WITH TIME ZONE NOT NULL,
  112. -- if changing existing table from char to timestamp is desired,
  113. -- the following clause may be used:
  114. -- ALTER TABLE msgs ALTER time_iso
  115. -- TYPE TIMESTAMP WITH TIME ZONE
  116. -- USING to_timestamp(time_iso,'YYYYMMDDTHH24MMSSTZ');
  117. -- - field quarantine.mail_text should be of data type 'bytea' and not 'text'
  118. -- as suggested in older documentation; this is to prevent it from being
  119. -- unjustifiably associated with a character set, and to be able to
  120. -- store any byte value; to convert existing field from type 'text'
  121. -- to type 'bytea' the following clause may be used:
  122. -- ALTER TABLE quarantine ALTER mail_text TYPE bytea
  123. -- USING decode(replace(mail_text,'\\','\\\\'),'escape');
  124. -- - version of Perl module DBD::Pg 1.48 or higher should be used;
  125. -- - create an amavis username and the database (choose name, e.g. mail)
  126. -- $ createuser -U pgsql --no-adduser --createdb amavis
  127. -- $ createdb -U amavis mail
  128. -- - populate the database using the schema below:
  129. -- $ psql -U amavis mail < amavisd-pg.sql
  130.  
  131. -- SQLite notes:
  132. -- - use INTEGER PRIMARY KEY AUTOINCREMENT
  133. -- instead of INT UNSIGNED NOT NULL AUTO_INCREMENT;
  134. -- - replace SERIAL by INTEGER;
  135. -- - SQLite is well suited for lookups database, but is not appropriate
  136. -- for @storage_sql_dsn due to coarse lock granularity;
  137.  
  138. -- local users
  139. CREATE TABLE users (
  140. id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, -- unique id
  141. priority integer NOT NULL DEFAULT '7', -- sort field, 0 is low prior.
  142. policy_id integer unsigned NOT NULL DEFAULT '1', -- JOINs with policy.id
  143. email varchar(255) NOT NULL UNIQUE,
  144. fullname varchar(255) DEFAULT NULL, -- not used by amavisd-new
  145. local char(1) -- Y/N (optional field, see note further down)
  146. );
  147.  
  148. -- any e-mail address (non- rfc2822-quoted), external or local,
  149. -- used as senders in wblist
  150. CREATE TABLE mailaddr (
  151. id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  152. priority integer NOT NULL DEFAULT '7', -- 0 is low priority
  153. email varchar(255) NOT NULL UNIQUE
  154. );
  155.  
  156. -- per-recipient whitelist and/or blacklist,
  157. -- puts sender and recipient in relation wb (white or blacklisted sender)
  158. CREATE TABLE wblist (
  159. rid integer unsigned NOT NULL, -- recipient: users.id
  160. sid integer unsigned NOT NULL, -- sender: mailaddr.id
  161. wb varchar(10) NOT NULL, -- W or Y / B or N / space=neutral / score
  162. PRIMARY KEY (rid,sid)
  163. );
  164.  
  165. CREATE TABLE policy (
  166. id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  167. -- 'id' this is the _only_ required field
  168. policy_name varchar(32), -- not used by amavisd-new, a comment
  169.  
  170. virus_lover char(1) default NULL, -- Y/N
  171. spam_lover char(1) default NULL, -- Y/N
  172. banned_files_lover char(1) default NULL, -- Y/N
  173. bad_header_lover char(1) default NULL, -- Y/N
  174.  
  175. bypass_virus_checks char(1) default NULL, -- Y/N
  176. bypass_spam_checks char(1) default NULL, -- Y/N
  177. bypass_banned_checks char(1) default NULL, -- Y/N
  178. bypass_header_checks char(1) default NULL, -- Y/N
  179.  
  180. spam_modifies_subj char(1) default NULL, -- Y/N
  181.  
  182. virus_quarantine_to varchar(64) default NULL,
  183. spam_quarantine_to varchar(64) default NULL,
  184. banned_quarantine_to varchar(64) default NULL,
  185. bad_header_quarantine_to varchar(64) default NULL,
  186. clean_quarantine_to varchar(64) default NULL,
  187. other_quarantine_to varchar(64) default NULL,
  188.  
  189. spam_tag_level float default NULL, -- higher score inserts spam info headers
  190. spam_tag2_level float default NULL, -- inserts 'declared spam' header fields
  191. spam_kill_level float default NULL, -- higher score triggers evasive actions
  192. -- e.g. reject/drop, quarantine, ...
  193. -- (subject to final_spam_destiny setting)
  194. spam_dsn_cutoff_level float default NULL,
  195. spam_quarantine_cutoff_level float default NULL,
  196.  
  197. addr_extension_virus varchar(64) default NULL,
  198. addr_extension_spam varchar(64) default NULL,
  199. addr_extension_banned varchar(64) default NULL,
  200. addr_extension_bad_header varchar(64) default NULL,
  201.  
  202. warnvirusrecip char(1) default NULL, -- Y/N
  203. warnbannedrecip char(1) default NULL, -- Y/N
  204. warnbadhrecip char(1) default NULL, -- Y/N
  205. newvirus_admin varchar(64) default NULL,
  206. virus_admin varchar(64) default NULL,
  207. banned_admin varchar(64) default NULL,
  208. bad_header_admin varchar(64) default NULL,
  209. spam_admin varchar(64) default NULL,
  210. spam_subject_tag varchar(64) default NULL,
  211. spam_subject_tag2 varchar(64) default NULL,
  212. message_size_limit integer default NULL, -- max size in bytes, 0 disable
  213. banned_rulenames varchar(64) default NULL -- comma-separated list of ...
  214. -- names mapped through %banned_rules to actual banned_filename tables
  215. );
  216.  
  217.  
  218.  
  219. -- R/W part of the dataset (optional)
  220. -- May reside in the same or in a separate database as lookups database;
  221. -- REQUIRES SUPPORT FOR TRANSACTIONS; specified in @storage_sql_dsn
  222. --
  223. -- MySQL note ( http://dev.mysql.com/doc/mysql/en/storage-engines.html ):
  224. -- ENGINE is the preferred term, but cannot be used before MySQL 4.0.18.
  225. -- TYPE is available beginning with MySQL 3.23.0, the first version of
  226. -- MySQL for which multiple storage engines were available. If you omit
  227. -- the ENGINE or TYPE option, the default storage engine is used.
  228. -- By default this is MyISAM.
  229. --
  230. -- Please create additional indexes on keys when needed, or drop suggested
  231. -- ones as appropriate to optimize queries needed by a management application.
  232. -- See your database documentation for further optimization hints. With MySQL
  233. -- see Chapter 15 of the reference manual. For example the chapter 15.17 says:
  234. -- InnoDB does not keep an internal count of rows in a table. To process a
  235. -- SELECT COUNT(*) FROM T statement, InnoDB must scan an index of the table,
  236. -- which takes some time if the index is not entirely in the buffer pool.
  237. --
  238. -- Wayne Smith adds: When using MySQL with InnoDB one might want to
  239. -- increase buffer size for both pool and log, and might also want
  240. -- to change flush settings for a little better performance. Example:
  241. -- innodb_buffer_pool_size = 384M
  242. -- innodb_log_buffer_size = 8M
  243. -- innodb_flush_log_at_trx_commit = 0
  244. -- The big performance increase is the first two, the third just helps
  245. -- with lowering disk activity.
  246.  
  247.  
  248. -- provide unique id for each e-mail address, avoids storing copies
  249. CREATE TABLE maddr (
  250. id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  251. email varchar(255) NOT NULL UNIQUE, -- full mail address
  252. domain varchar(255) NOT NULL -- only domain part of the email address
  253. -- with subdomain fields in reverse
  254. ) ENGINE=InnoDB;
  255.  
  256. -- information pertaining to each processed message as a whole;
  257. -- NOTE: records with NULL msgs.content should be ignored by utilities,
  258. -- as such records correspond to messages just being processes, or were lost
  259. -- NOTE: with PostgreSQL, instead of a character field time_iso, please use:
  260. -- time_iso TIMESTAMP WITH TIME ZONE NOT NULL,
  261. -- NOTE: with MySQL, instead of a character field time_iso, one might prefer:
  262. -- time_iso TIMESTAMP NOT NULL DEFAULT 0,
  263. -- but the following MUST then be set in amavisd.conf: $timestamp_fmt_mysql=1
  264. CREATE TABLE msgs (
  265. mail_id varchar(12) NOT NULL PRIMARY KEY, -- long-term unique mail id
  266. secret_id varchar(12) DEFAULT '', -- authorizes release of mail_id
  267. am_id varchar(20) NOT NULL, -- id used in the log
  268. time_num integer unsigned NOT NULL, -- rx_time: seconds since Unix epoch
  269. time_iso char(16) NOT NULL, -- rx_time: ISO8601 UTC ascii time
  270. sid integer unsigned NOT NULL, -- sender: maddr.id
  271. policy varchar(255) DEFAULT '', -- policy bank path (like macro %p)
  272. client_addr varchar(255) DEFAULT '', -- SMTP client IP address (IPv4 or v6)
  273. size integer unsigned NOT NULL, -- message size in bytes
  274. content char(1), -- content type: V/B/S/s/M/H/O/C:
  275. -- virus/banned/spam(kill)/spammy(tag2)
  276. -- /bad mime/bad header/oversized/clean
  277. -- is NULL on partially processed mail
  278. quar_type char(1), -- quarantined as: ' '/F/Z/B/Q/M
  279. -- none/file/zipfile/bsmtp/sql/mailbox
  280. quar_loc varchar(255) DEFAULT '', -- quarantine location (e.g. file)
  281. dsn_sent char(1), -- was DSN sent? Y/N/q (q=quenched)
  282. spam_level float, -- SA spam level (no boosts)
  283. message_id varchar(255) DEFAULT '', -- mail Message-ID header field
  284. from_addr varchar(255) DEFAULT '', -- mail From header field, UTF8
  285. subject varchar(255) DEFAULT '', -- mail Subject header field, UTF8
  286. host varchar(255) NOT NULL, -- hostname where amavisd is running
  287. FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT
  288. ) ENGINE=InnoDB;
  289. CREATE INDEX msgs_idx_sid ON msgs (sid);
  290. CREATE INDEX msgs_idx_time_num ON msgs (time_num);
  291. -- alternatively when purging based on time_iso (instead of msgs_idx_time_num):
  292. -- CREATE INDEX msgs_idx_time_iso ON msgs (time_iso);
  293.  
  294. -- per-recipient information related to each processed message;
  295. -- NOTE: records in msgrcpt without corresponding msgs.mail_id record are
  296. -- orphaned and should be ignored and eventually deleted by external utilities
  297. CREATE TABLE msgrcpt (
  298. mail_id varchar(12) NOT NULL, -- (must allow duplicates)
  299. rid integer unsigned NOT NULL, -- recipient: maddr.id (dupl. allowed)
  300. ds char(1) NOT NULL, -- delivery status: P/R/B/D/T
  301. -- pass/reject/bounce/discard/tempfail
  302. rs char(1) NOT NULL, -- release status: initialized to ' '
  303. bl char(1) DEFAULT ' ', -- sender blacklisted by this recip
  304. wl char(1) DEFAULT ' ', -- sender whitelisted by this recip
  305. bspam_level float, -- spam level + per-recip boost
  306. smtp_resp varchar(255) DEFAULT '', -- SMTP response given to MTA
  307. FOREIGN KEY (rid) REFERENCES maddr(id) ON DELETE RESTRICT,
  308. FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
  309. ) ENGINE=InnoDB;
  310. CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
  311. CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
  312.  
  313. -- mail quarantine in SQL, enabled by $*_quarantine_method='sql:'
  314. -- NOTE: records in quarantine without corresponding msgs.mail_id record are
  315. -- orphaned and should be ignored and eventually deleted by external utilities
  316. CREATE TABLE quarantine (
  317. mail_id varchar(12) NOT NULL, -- long-term unique mail id
  318. chunk_ind integer unsigned NOT NULL, -- chunk number, starting with 1
  319. mail_text blob NOT NULL, -- store mail as chunks (in PostgreSQL use: bytea)
  320. PRIMARY KEY (mail_id,chunk_ind),
  321. FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
  322. ) ENGINE=InnoDB;
  323.  
  324. -- field msgrcpt.rs is primarily intended for use by quarantine management
  325. -- software; the value assigned by amavisd is a space;
  326. -- a short _preliminary_ list of possible values:
  327. -- 'V' => viewed (marked as read)
  328. -- 'R' => released (delivered) to this recipient
  329. -- 'p' => pending (a status given to messages when the admin received the
  330. -- request but not yet released; targeted to banned parts)
  331. -- 'D' => marked for deletion; a cleanup script may delete it
  332.  
  333.  
  334. -- =====================
  335. -- Example data follows:
  336. -- =====================
  337. INSERT INTO users VALUES ( 1, 9, 5, '[email protected]','Name1 Surname1', 'Y');
  338. INSERT INTO users VALUES ( 2, 7, 5, '[email protected]', 'Name1 Surname1', 'Y');
  339. INSERT INTO users VALUES ( 3, 7, 2, '[email protected]', 'Name2 Surname2', 'Y');
  340. INSERT INTO users VALUES ( 4, 7, 7, '[email protected]', 'Name3 Surname3', 'Y');
  341. INSERT INTO users VALUES ( 5, 7, 7, '[email protected]', 'Name4 Surname4', 'Y');
  342. INSERT INTO users VALUES ( 6, 7, 1, '[email protected]', 'Name5 Surname5', 'Y');
  343. INSERT INTO users VALUES ( 7, 5, 0, '@sub1.example.com', NULL, 'Y');
  344. INSERT INTO users VALUES ( 8, 5, 7, '@sub2.example.com', NULL, 'Y');
  345. INSERT INTO users VALUES ( 9, 5, 5, '@example.com', NULL, 'Y');
  346. INSERT INTO users VALUES (10, 3, 8, 'userA', 'NameA SurnameA anywhere', 'Y');
  347. INSERT INTO users VALUES (11, 3, 9, 'userB', 'NameB SurnameB', 'Y');
  348. INSERT INTO users VALUES (12, 3,10, 'userC', 'NameC SurnameC', 'Y');
  349. INSERT INTO users VALUES (13, 3,11, 'userD', 'NameD SurnameD', 'Y');
  350. INSERT INTO users VALUES (14, 3, 0, '@sub1.example.net', NULL, 'Y');
  351. INSERT INTO users VALUES (15, 3, 7, '@sub2.example.net', NULL, 'Y');
  352. INSERT INTO users VALUES (16, 3, 5, '@example.net', NULL, 'Y');
  353. INSERT INTO users VALUES (17, 7, 5, '[email protected]', 'u1', 'Y');
  354. INSERT INTO users VALUES (18, 7, 6, '[email protected]', 'u2', 'Y');
  355. INSERT INTO users VALUES (19, 7, 3, '[email protected]', 'u3', 'Y');
  356.  
  357. -- INSERT INTO users VALUES (20, 0, 5, '@.', NULL, 'N'); -- catchall
  358.  
  359. INSERT INTO policy (id, policy_name,
  360. virus_lover, spam_lover, banned_files_lover, bad_header_lover,
  361. bypass_virus_checks, bypass_spam_checks,
  362. bypass_banned_checks, bypass_header_checks, spam_modifies_subj,
  363. spam_tag_level, spam_tag2_level, spam_kill_level) VALUES
  364. (1, 'Non-paying', 'N','N','N','N', 'Y','Y','Y','N', 'Y', 3.0, 7, 10),
  365. (2, 'Uncensored', 'Y','Y','Y','Y', 'N','N','N','N', 'N', 3.0, 999, 999),
  366. (3, 'Wants all spam','N','Y','N','N', 'N','N','N','N', 'Y', 3.0, 999, 999),
  367. (4, 'Wants viruses', 'Y','N','Y','Y', 'N','N','N','N', 'Y', 3.0, 6.9, 6.9),
  368. (5, 'Normal', 'N','N','N','N', 'N','N','N','N', 'Y', 3.0, 6.9, 6.9),
  369. (6, 'Trigger happy', 'N','N','N','N', 'N','N','N','N', 'Y', 3.0, 5, 5),
  370. (7, 'Permissive', 'N','N','N','Y', 'N','N','N','N', 'Y', 3.0, 10, 20),
  371. (8, '6.5/7.8', 'N','N','N','N', 'N','N','N','N', 'N', 3.0, 6.5, 7.8),
  372. (9, 'userB', 'N','N','N','Y', 'N','N','N','N', 'Y', 3.0, 6.3, 6.3),
  373. (10,'userC', 'N','N','N','N', 'N','N','N','N', 'N', 3.0, 6.0, 6.0),
  374. (11,'userD', 'Y','N','Y','Y', 'N','N','N','N', 'N', 3.0, 7, 7);
  375.  
  376. -- sender envelope addresses needed for white/blacklisting
  377. INSERT INTO mailaddr VALUES (1, 5, '@example.com');
  378. INSERT INTO mailaddr VALUES (2, 9, '[email protected]');
  379. INSERT INTO mailaddr VALUES (3, 9, '[email protected]');
  380. INSERT INTO mailaddr VALUES (4, 9, '[email protected]');
  381. INSERT INTO mailaddr VALUES (5, 5, '@example.net');
  382. INSERT INTO mailaddr VALUES (6, 9, '[email protected]');
  383. INSERT INTO mailaddr VALUES (7, 9, '[email protected]');
  384.  
  385. -- whitelist for user 14, i.e. default for recipients in domain sub1.example.net
  386. INSERT INTO wblist VALUES (14, 1, 'W');
  387. INSERT INTO wblist VALUES (14, 3, 'W');
  388.  
  389. -- whitelist and blacklist for user 17, i.e. [email protected]
  390. INSERT INTO wblist VALUES (17, 2, 'W');
  391. INSERT INTO wblist VALUES (17, 3, 'W');
  392. INSERT INTO wblist VALUES (17, 6, 'W');
  393. INSERT INTO wblist VALUES (17, 7, 'W');
  394. INSERT INTO wblist VALUES (17, 5, 'B');
  395. INSERT INTO wblist VALUES (17, 4, 'B');
  396.  
  397. -- $sql_select_policy setting in amavisd.conf tells amavisd
  398. -- how to fetch per-recipient policy settings.
  399. -- See comments there. Example:
  400. --
  401. -- SELECT *,users.id FROM users,policy
  402. -- WHERE (users.policy_id=policy.id) AND (users.email IN (%k))
  403. -- ORDER BY users.priority DESC;
  404. --
  405. -- $sql_select_white_black_list in amavisd.conf tells amavisd
  406. -- how to check sender in per-recipient whitelist/blacklist.
  407. -- See comments there. Example:
  408. --
  409. -- SELECT wb FROM wblist,mailaddr
  410. -- WHERE (wblist.rid=?) AND (wblist.sid=mailaddr.id) AND (mailaddr.email IN (%k))
  411. -- ORDER BY mailaddr.priority DESC;
  412.  
  413.  
  414.  
  415. -- NOTE: the SELECT, INSERT and UPDATE clauses as used by the amavisd-new
  416. -- program are configurable through %sql_clause; see amavisd.conf-default
  417.  
  418.  
  419.  
  420. Some examples of a query:
  421.  
  422. -- mail from last two minutes (MySQL):
  423. SELECT
  424. UNIX_TIMESTAMP()-msgs.time_num AS age, SUBSTRING(policy,1,2) as pb,
  425. content AS c, dsn_sent as dsn, ds, bspam_level AS level, size,
  426. SUBSTRING(sender.email,1,18) AS s,
  427. SUBSTRING(recip.email,1,18) AS r,
  428. SUBSTRING(msgs.subject,1,10) AS subj
  429. FROM msgs LEFT JOIN msgrcpt ON msgs.mail_id=msgrcpt.mail_id
  430. LEFT JOIN maddr AS sender ON msgs.sid=sender.id
  431. LEFT JOIN maddr AS recip ON msgrcpt.rid=recip.id
  432. WHERE content IS NOT NULL AND UNIX_TIMESTAMP()-msgs.time_num < 120
  433. ORDER BY msgs.time_num DESC;
  434.  
  435. -- mail from last two minutes (PostgreSQL):
  436. SELECT
  437. now()-time_iso AS age, SUBSTRING(policy,1,2) as pb,
  438. content AS c, dsn_sent as dsn, ds, bspam_level AS level, size,
  439. SUBSTRING(sender.email,1,18) AS s,
  440. SUBSTRING(recip.email,1,18) AS r,
  441. SUBSTRING(msgs.subject,1,10) AS subj
  442. FROM msgs LEFT JOIN msgrcpt ON msgs.mail_id=msgrcpt.mail_id
  443. LEFT JOIN maddr AS sender ON msgs.sid=sender.id
  444. LEFT JOIN maddr AS recip ON msgrcpt.rid=recip.id
  445. WHERE content IS NOT NULL AND now() - time_iso < INTERVAL '2 minutes'
  446. ORDER BY msgs.time_num DESC;
  447.  
  448. -- clean messages ordered by count, grouped by domain:
  449. SELECT count(*) as cnt, avg(bspam_level), sender.domain
  450. FROM msgs
  451. LEFT JOIN msgrcpt ON msgs.mail_id=msgrcpt.mail_id
  452. LEFT JOIN maddr AS sender ON msgs.sid=sender.id
  453. LEFT JOIN maddr AS recip ON msgrcpt.rid=recip.id
  454. WHERE content='C'
  455. GROUP BY sender.domain ORDER BY cnt DESC LIMIT 50;
  456.  
  457. -- top spamy domains with >10 messages, sorted by spam average,
  458. -- grouped by domain:
  459. SELECT count(*) as cnt, avg(bspam_level) as spam_avg, sender.domain
  460. FROM msgs
  461. LEFT JOIN msgrcpt ON msgs.mail_id=msgrcpt.mail_id
  462. LEFT JOIN maddr AS sender ON msgs.sid=sender.id
  463. LEFT JOIN maddr AS recip ON msgrcpt.rid=recip.id
  464. WHERE bspam_level IS NOT NULL
  465. GROUP BY sender.domain HAVING count(*) > 10
  466. ORDER BY spam_avg DESC LIMIT 50;
  467.  
  468. -- sender domains with >100 messages, sorted on sender.domain:
  469. SELECT count(*) as cnt, avg(bspam_level) as spam_avg, sender.domain
  470. FROM msgs
  471. LEFT JOIN msgrcpt ON msgs.mail_id=msgrcpt.mail_id
  472. LEFT JOIN maddr AS sender ON msgs.sid=sender.id
  473. LEFT JOIN maddr AS recip ON msgrcpt.rid=recip.id
  474. GROUP BY sender.domain HAVING count(*) > 100
  475. ORDER BY sender.domain DESC LIMIT 100;
  476.  
  477.  
  478.  
  479.  
  480. Upgrading from pre 2.4.0 amavisd-new SQL schema to the 2.4.0 schema requires
  481. adding column 'quar_loc' to table msgs, and creating FOREIGN KEY constraint
  482. to facilitate deletion of expired records.
  483.  
  484. The following clauses should be executed for upgrading pre-2.4.0 amavisd-new
  485. SQL schema to the 2.4.0 schema:
  486.  
  487. -- mandatory change:
  488. ALTER TABLE msgs ADD quar_loc varchar(255) DEFAULT '';
  489.  
  490. -- optional but highly recommended:
  491. ALTER TABLE quarantine
  492. ADD FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE;
  493. ALTER TABLE msgrcpt
  494. ADD FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE;
  495.  
  496. -- the following two ALTERs are not essential; if data type of maddr.id is
  497. -- incompatible with msgs.sid and msgs.rid (e.g. BIGINT vs. INT) and MySQL
  498. -- complains, don't bother to apply the constraint:
  499. ALTER TABLE msgs
  500. ADD FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT;
  501. ALTER TABLE msgrcpt
  502. ADD FOREIGN KEY (rid) REFERENCES maddr(id) ON DELETE RESTRICT;
  503.  
  504.  
  505. BRIEF MySQL EXAMPLE of a log/report/quarantine database housekeeping
  506. ====================================================================
  507.  
  508. DELETE FROM msgs WHERE time_num < UNIX_TIMESTAMP() - 14*24*60*60;
  509. DELETE FROM msgs WHERE time_num < UNIX_TIMESTAMP() - 60*60 AND content IS NULL;
  510. DELETE FROM maddr
  511. WHERE NOT EXISTS (SELECT 1 FROM msgs WHERE sid=id)
  512. AND NOT EXISTS (SELECT 1 FROM msgrcpt WHERE rid=id);
  513.  
  514.  
  515. BRIEF MySQL EQUIVALENT EXAMPLE based on time_iso if its data type is TIMESTAMPS
  516. ===============================================================================
  517. (don't forget to set: $timestamp_fmt_mysql=1 in amavisd.conf)
  518.  
  519. DELETE FROM msgs WHERE time_iso < UTC_TIMESTAMP() - INTERVAL 14 day;
  520. DELETE FROM msgs WHERE time_iso < UTC_TIMESTAMP() - INTERVAL 1 hour
  521. AND content IS NULL;
  522. DELETE FROM maddr
  523. WHERE NOT EXISTS (SELECT 1 FROM msgs WHERE sid=id)
  524. AND NOT EXISTS (SELECT 1 FROM msgrcpt WHERE rid=id);
  525.  
  526.  
  527. BRIEF PostgreSQL EXAMPLE of a log/report/quarantine database housekeeping
  528. =========================================================================
  529.  
  530. DELETE FROM msgs WHERE time_iso < now() - INTERVAL '14 days';
  531. DELETE FROM msgs WHERE time_iso < now() - INTERVAL '1 h' AND content IS NULL;
  532. DELETE FROM maddr
  533. WHERE NOT EXISTS (SELECT 1 FROM msgs WHERE sid=id)
  534. AND NOT EXISTS (SELECT 1 FROM msgrcpt WHERE rid=id);
  535.  
  536.  
  537. COMMENTED LONGER EXAMPLE of a log/report/quarantine database housekeeping
  538. =========================================================================
  539.  
  540. -- discarding indexes makes deletion faster; if we expect a large proportion
  541. -- of records to be deleted it may be quicker to discard index, do deletions,
  542. -- and re-create index (not necessary with PostgreSQL, may benefit MySQL);
  543. -- for daily maintenance this does not pay off
  544. --DROP INDEX msgs_idx_sid ON msgs;
  545. --DROP INDEX msgrcpt_idx_rid ON msgrcpt;
  546. --DROP INDEX msgrcpt_idx_mail_id ON msgrcpt;
  547.  
  548. -- delete old msgs records based on timestamps only (for time_iso see next),
  549. -- and delete leftover msgs records from aborted mail checking operations
  550. DELETE FROM msgs WHERE time_num < UNIX_TIMESTAMP()-14*24*60*60;
  551. DELETE FROM msgs WHERE time_num < UNIX_TIMESTAMP()-60*60 AND content IS NULL;
  552.  
  553. -- provided the time_iso field was created as type TIMESTAMP DEFAULT 0 (MySQL)
  554. -- or TIMESTAMP WITH TIME ZONE (PostgreSQL), instead of purging based on
  555. -- numerical Unix timestamp as above, one may select records based on ISO 8601
  556. -- UTC timestamps. This is particularly suitable for PostgreSQL:
  557. --DELETE FROM msgs WHERE time_iso < now() - INTERVAL '14 days';
  558. --DELETE FROM msgs WHERE time_iso < now() - INTERVAL '1 h' AND content IS NULL;
  559. and is also possible with MySQL, using slightly different format:
  560. --DELETE FROM msgs
  561. -- WHERE time_iso < UTC_TIMESTAMP() - INTERVAL 14 day;
  562. --DELETE FROM msgs
  563. -- WHERE time_iso < UTC_TIMESTAMP() - INTERVAL 1 hour AND content IS NULL;
  564.  
  565. -- optionally certain content types may be given shorter lifetime
  566. --DELETE FROM msgs WHERE time_num < UNIX_TIMESTAMP()-7*24*60*60
  567. -- AND (content='V' OR (content='S' AND spam_level>20));
  568.  
  569. -- (optional) just in case the ON DELETE CASCADE did not do its job, we may
  570. -- explicitly delete orphaned records (with no corresponding msgs entry);
  571. -- if ON DELETE CASCADE did work, there should be no deletions at this step
  572. DELETE FROM quarantine
  573. WHERE NOT EXISTS (SELECT 1 FROM msgs WHERE mail_id=quarantine.mail_id);
  574. DELETE FROM msgrcpt
  575. WHERE NOT EXISTS (SELECT 1 FROM msgs WHERE mail_id=msgrcpt.mail_id);
  576.  
  577. -- re-create indexes (if they were removed in the first step):
  578. --CREATE INDEX msgs_idx_sid ON msgs (sid);
  579. --CREATE INDEX msgrcpt_idx_rid ON msgrcpt (rid);
  580. --CREATE INDEX msgrcpt_idx_mail_id ON msgrcpt (mail_id);
  581.  
  582. -- delete unreferenced e-mail addresses
  583. DELETE FROM maddr
  584. WHERE NOT EXISTS (SELECT 1 FROM msgs WHERE sid=id)
  585. AND NOT EXISTS (SELECT 1 FROM msgrcpt WHERE rid=id);
  586.  
  587. -- (optional) optimize tables once in a while
  588. --OPTIMIZE TABLE msgs, msgrcpt, quarantine, maddr;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement