最後更新: 2018-12-16
目錄
- Install
- Cron jobs
- Postfix configuration
- Usage
- DOC
介紹:
HomePage: https://code.google.com/p/response/
program:
- Python 2.6
- Daemons program
- Backends: MySQL, PostgreSQL, ...
supports:
* response limits per recipient ("one autoresponse per recipient in 7 days")
* relies on the delivering MTA to silently copy a given mail and hand it over. (Postfix: recipient_bcc_maps)
* custom subjects and custom bodies per response-sender
* No local file access
Components (3):
A LMTP-daemon
* handle incoming messages, validate sender, recipient, and headers.
The Notifier.(Cron)
* It can use any custom SMTP relay to send the responses. (keep it as flexible as possible)
Cleanup component
* It takes care of disabling expired autoresponse configurations
* removing obsolete response records.
Install
Debian6 Dependencies:
aptitude install python python-{mysqldb,sqlalchemy}
Centos6 Dependencies:
yum install MySQL-python python-sqlalchemy
# 建立 DB:
修改 /opt/response/examples/DATABASE.mysql 的以下一行 FIXME
# response-lmtpd, response-notify and response-cleanup
GRANT USAGE ON *.* TO 'response'@'localhost' IDENTIFIED BY 'FIXME';
# roundcube webmail user
GRANT USAGE ON *.* TO 'responserc'@'localhost' IDENTIFIED BY 'FIXME';
mysql -p < DATABASE.mysql
# 建立 User:
useradd --system --home-dir /opt/response --shell /bin/false response
# 放 file 及設定它們的 permission:
cd /opt/
ln -s response-0.8 response
mv response/response.cfg /etc/
mkdir -p /var/run/response
# Set permission
chown response:response /etc/response.cfg /var/run/response
chmod 600 /etc/response.cfg
chmod 700 /var/run/response
chmod 770 /opt/response-0.8/
chown root.response /opt/response-0.8/
# 設定 response.cfg
vi /etc/response.cfg
[LMTPD] # default 的 10024 好多時被 amavisd 用了 SOCKET_PORT = 10027 SOCKET_ADDR = 127.0.0.1 # 什麼人可以連它 SOCKET_ACL = 127.0.0.1 #### Error Handling / Informing the client of problems ( The "client" is the application speaking to LMTP-daemon ) # a non-delivery status-notification issued by the MTA back to the sender!(5xx error-code) HARDFAIL = False # Ask the client to re-send a message if we have problems (4xx error-code) SOFTFAIL = True # silently drop a message if the backend is unavailable (missing autoresponse) FAILSAFE = False [BACKEND] USERNAME = response PASSWORD = FIXME DATABASE = response ADAPTER = MySQL DATABASE_HOST = 127.0.0.1 DATABASE_PORT = 3306 # For better performance this should be performed directly by the MTA query_validate_recipient_enabled = False [NOTIFY] SMTP_HOST = localhost SMTP_PORT = 25 SMTP_TIMEOUT = 20 SMTP_AUTH = False SMTP_USERNAME = SMTP_PASSWORD = SMTP_STARTTLS = False # The null sender ("<>") is *strongly* recommended to avoid loops and other bad stuff! SMTP_ENVELOPE_FROM = <> # Set a realname to use in the "From" header. MESSAGE_HEADER_FROM_NAME = Autoresponder MESSAGE_HEADER_FROM_ADDRESS = [email protected] # 多耐才 sent 多次 auto response, Default 7 天 REQUIRED_TIMEDELTA = 604800 MESSAGE_CHARSET = UTF-8 # Insert special headers to prevent other systems responding to our autoresponses? MESSAGE_INSERT_SPECIAL_HEADERS = True MESSAGE_HEADER_SUBJECT_PREFIX = [AutoResponse] [CLEANUP] # Delete last hit 耐過幾時的 reponse record, Default 7 天 (response-cleanup --delete-old-response-records 用到) DELETE_RECORDS_WITH_LAST_HIT_BEFORE = 604800
# Start it:
Debian7:
cp -a examples/debian-initscript /etc/init.d/response-lmtpd
chmod 755 /etc/init.d/response-lmtpd
/etc/init.d/response-lmtpd start
Centos6:
/root/scripts/response.sh
#!/bin/bash DAEMON_ARGS="--syslog --syslog-facility=MAIL" PID_FILE="/var/run/response/lmtpd.pid" RESPONSE="/opt/response/response-lmtpd" USER="response" if [ -e $PID_FILE ];then echo "Kill Old lmtpd" kill -9 `cat $PID_FILE` &> /dev/null rm -f $PID_FILE fi echo "Start New One" if [ "`whoami`" = "root" ] then echo "switch to user: $USER" sudo -u $USER $RESPONSE $DAEMON_ARGS &> /dev/null else $RESPONSE $DAEMON_ARGS &> /dev/null fi # check pid sleep 2 echo "PID: `cat $PID_FILE`"
Set permission
chmod 770 /etc/scripts/response.sh
chmod g=rx /etc/scripts/response.sh
Start
/root/scripts/response.sh
output:
Kill Old lmtpd Start New One PID: 10785
Auto Run
/etc/rc.local
# for e-mail auto reply /root/scripts/response.sh > /dev/null 2>&1
Remark
在舊版 Centos 上要 hardcode 用 python6
vi /opt/response/response-lmtpd
#!/usr/bin/env python26
Testing
Log:
/var/log/maillog
Dec 27 13:27:13 mail response[22829]: response-lmtpd version 0.8 starting up... (loglevel: WARNING) Dec 27 13:27:13 mail response[22831]: Daemon PID=22831
# 當一切沒有問題就可拿走 "/etc/init.d/response-lmtpd" 內的 –debug
DAEMON_ARGS="--debug --syslog --syslog-facility=MAIL"
telnet test:
telnet localhost 10027
220 server_hostname 0.8
Cron jobs
cd /opt/response
cp -a examples/crontab /etc/cron.d/response
/etc/cron.d/response 的內容
PATH=/opt/response:/usr/bin # 每 5 min auto reply 一次, 每次只 reply 10 個人 */5 * * * * response response-notify --debug --syslog -L 10 &> /dev/null 0,30 * * * * response response-cleanup --debug --syslog --disable-expired-configs &> /dev/null 12 1 * * * response response-cleanup --debug --syslog --delete-old-response-records &> /dev/null 12 2 * * * response response-cleanup --debug --syslog --delete-unused-response-records &> /dev/null
chmod 644 response
Jul 17 12:17:01 mail crond[29649]: (root) BAD FILE MODE (/etc/cron.d/response)
/etc/init.d/crond reload
Testing
log:
sudo -u response /opt/response/response-notify --debug
Dec 17 13:21:33 mail response[11581] (response-notify:113) [WARNING]: response-notify version 0.8 starting up... (loglevel: DEBUG)
Dec 17 13:21:33 mail response.pidfile[11581] (pidfile.py:67) [DEBUG]: Writing pidfile /var/run/response/notify.pid with pid 11581
Dec 17 13:21:33 mail response[11581] (response-notify:128) [WARNING]: Running with PID=11581
Dec 17 13:21:33 mail response[11581] (response-notify:139) [WARNING]: Initializing...
Dec 17 13:21:33 mail response[11581] (response-notify:140) [WARNING]: Upper limit of generated response mails: 100
Dec 17 13:21:33 mail response[11581] (response-notify:143) [WARNING]: Connecting to backend...
Dec 17 13:21:33 mail response.backend[11581] (backend.py:136) [INFO]: MySQL: Asking pool for a connection
Dec 17 13:21:33 mail response.backend[11581] (backend.py:136) [DEBUG]: MySQL: Successfully aquired connection from pool
Dec 17 13:21:33 mail response.backend[11581] (backend.py:136) [DEBUG]: MySQL: Opening cursor for connection
Dec 17 13:21:33 mail response[11581] (response-notify:163) [INFO]: Not creating any successive autoresponse for ...
Dec 17 13:21:33 mail response.backend[11581] (backend.py:136) [DEBUG]: MySQL: Executing query: SELECT `record`.`id` AS `id` ...
Dec 17 13:21:33 mail response[11581] (response-notify:167) [WARNING]: No pending responses found.
Dec 17 13:21:33 mail response[11581] (response-notify:323) [WARNING]: Doing a graceful shutdown...
Dec 17 13:21:33 mail response[11581] (response-notify:326) [INFO]: Closing SMTP connection
Dec 17 13:21:33 mail response.backend[11581] (backend.py:136) [DEBUG]: MySQL: Closing cursor for connection
Dec 17 13:21:33 mail response.backend[11581] (backend.py:136) [INFO]: MySQL: Releasing connection
Dec 17 13:21:33 mail response.backend[11581] (backend.py:136) [INFO]: MySQL: Disposing connection pool...
Dec 17 13:21:33 mail response[11581] (response-notify:340) [DEBUG]: Cleaning up...
Dec 17 13:21:33 mail response.pidfile[11581] (pidfile.py:77) [DEBUG]: Deleting pidfile /var/run/response/notify.pid
Dec 17 13:21:33 mail response[11581] (response-notify:343) [WARNING]: Quit.
Opts:
–debug # 當一切沒有問題就不用加
-L LIMIT, --limit-response-mails=LIMIT # never create more than this amount of response mails, default: 10
Cron Log
Message from syslogd@mail at Dec 27 16:01:02 ... ?<20>response[23434] (response-notify:222) [WARNING]: [1] [email protected] -> <[email protected]> (record id: 1)
Troubleshoot
Dec 17 18:43:53 mail crond[25547]: (root) BAD FILE MODE (/etc/cron.d/response)
Postfix configuration
/etc/postfix/master.cf
response unix - - n - 4 lmtp -o disable_dns_lookups=yes
/etc/postfix/transport_map_response
response.internal response:[127.0.0.1]:10027
postmap /etc/postfix/transport_map_response
/etc/postfix/recipient_bcc_map_response.cf
cd /etc/postfix
touch recipient_bcc_map_response.cf
chmod 640 recipient_bcc_map_response.cf
chown root.postfix recipient_bcc_map_response.cf
內容:
hosts = 127.0.0.1 user = response password = FIXME dbname = response query = SELECT '%u#%[email protected]' FROM `autoresponse_config` WHERE `address` = '%s' AND `enabled` = 1
/etc/postfix/main.cf
# concurrency per domain --> concurrency per recipient response_destination_recipient_limit = 1 # Register our internal only response domain for the transport transport_maps = hash:/etc/postfix/transport_map_response ........ proxy_read_maps = ............. $recipient_bcc_maps ............. # for auto reponse recipient_bcc_maps = proxy:mysql:/etc/postfix/recipient_bcc_map_response.cf
最後 reload Postfix
postfix reload
Usage
TABLE `autoresponse_config`
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`address` varchar(255) NOT NULL UNIQUE, <--- [email protected] (它是在 alias table 前的 !!)
`enabled` bool NOT NULL,
`changed` datetime NOT NULL,
`expires` datetime NOT NULL, <--- DATETIME 'YYYY-MM-DD HH:MM:SS'
`subject` varchar(255) NOT NULL,
`message` longtext NOT NULL <--- 比對方的內容
TABLE `autoresponse_record`
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`sender_id` integer NOT NULL,
`recipient` varchar(255) NOT NULL,
`hit` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', <-- 最後一次收 sender(recipient) 的信的時間
`sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', <-- 何時 auto reply 了
UNIQUE (`sender_id`, `recipient`)
roundcubemail Plugin
Tested Package:
- rc-vacation-master.zip
- roundcubemail-1.0.3.tar.gz
Download:
https://github.com/bhuisgen/rc-vacation
unzip rc-vacation-master.zip
mv rc-vacation-master vacation
DB:
GRANT SELECT , INSERT , DELETE ON `response` . * TO 'responserc'@'localhost';
SQL:
// database DSN $rcmail_config['vacation_sql_dsn'] = 'mysql://user:password@localhost/postfix'; // read data queries $rcmail_config['vacation_sql_read'] = array("SELECT subject AS vacation_subject, message AS vacation_message, " . "enabled AS vacation_enable FROM response.autoresponse_config " . "WHERE address=%username;" ); // write data queries $rcmail_config['vacation_sql_write'] = array( "DELETE FROM response.autoresponse_record WHERE sender_id IN (SELECT id FROM response.autoresponse_config WHERE address=%email);", "DELETE FROM response.autoresponse_config WHERE address=%email;", "INSERT INTO response.autoresponse_config (address,subject,message,changed,expires,enabled) VALUES (%email,%vacation_subject,%vacation_message,NOW(),ADDDATE( NOW( ) , 31 ),%vacation_enable);" );
roundcube
config/main.inc.php
$rcmail_config['plugins'] = array('vacation');
P.S.
/usr/share/roundcubemail/plugins/vacation Folder 的 PHP 一定要叫 vacation.php
%username <-- 成個 login name (由於 login name 是成個 domain, 所以用它亦可)
%email_domain <-- email_domain
watchdog
By monit
/etc/monit.d/response.conf
check process response-lmtpd with pidfile /var/run/response/lmtpd.pid start program = "/etc/scripts/response.sh" as uid "response" and gid "response" with timeout 60 seconds stop program = "/bin/sh -c 'kill -9 `cat /var/run/response/lmtpd.pid`'" if failed port 10027 then restart if 2 restarts within 3 cycles then alert
By hourly cron job
response_watchdog.sh
#!/bin/bash # # Function: restart response & notify admin when it fail # pidfile="/var/run/response/lmtpd.pid" prog="/root/scripts/response.sh" admin="[email protected]" function mail2admin { echo "Send mail to admin" echo `date` | mail -s "auto response fail" $admin } function checkpid { if [ -f $pidfile ]; then pid=`cat $pidfile` kill -0 $pid &> /dev/null if [ $? != 0 ]; then echo "program crash, start new one" rm $pidfile bash $prog mail2admin else echo "porgram working fine" fi else echo "without pid file, start new one" bash $prog mail2admin fi sleep 1 } checkpid
DOC
在 examples Folder 內
- crontab
- DATABASE.mysql
- debian-initscript
- POSTFIX.conf