Pmilterã¨ãããµã¼ãã½ããã¦ã§ã¢ãä½ãã¾ããã
Pmilterã¯Programmable Mail Filterã®ç¥ã§ãSMTPãµã¼ãï¼éä¿¡ãåä¿¡ï¼ã¨milterãããã³ã«ã§éä¿¡ããSMTPãµã¼ãã®éåä¿¡ã®æ¯ãèããRubyã§ã³ã³ããã¼ã«ã§ãããµã¼ãã½ããã¦ã§ã¢ã§ãã
ããã¾ã§ã«ããmilter managerãRubyã®gemã使ã£ã¦milterãµã¼ããä½ãã¨ãã£ãç´ æ´ãããã½ããã¦ã§ã¢ãããã¾ãããã§ãããä»ååããã«ã¹ã¯ã©ããã§ä½ãããã£ãçç±ã¨ãã¦ã¯ã
- ã¨ã«ããã¤ã³ã¹ãã¼ã«ãè¨å®ãã·ã³ãã«ã§éç¨ãããããµã¼ãã½ããã¦ã§ã¢ã«ããã
- ããã«ã¦ã§ã¢ã¨ãã¦æ¯ãèããè¨å®ããæè¦ã§Rubyã§å¶å¾¡ããäºã«å°å¿µããã
- ä¾åã©ã¤ãã©ãªãæ¸ããã¯ã³ãã¤ããªã§ãµã¼ãã«é ç½®ã§ããããã«ããã
- è¨å®å¤æ´ã«åèµ·åãããã¨ãªãRubyãå¤æ´ããã ãã§æ¯ãèããå¤ããããããã«ããã
- ã¤ã³ãã©ã¨ã³ã¸ãã¢ã楽ããç°¡åã«ã³ã¼ããæ¸ããªããã¡ã¼ã«ãµã¼ããéç¨ããã
- spamã¡ã¼ã«ãè¸ã¿å°ãªã©ã«å¯¾ãã¦ç¬èªã®ã¢ã«ã´ãªãºã ãç°¡åã«å®è£ ãã¦ã¡ã¼ã«ãã¥ã¼ã«å ¥ãåã«rejectããã
ãªã©ããã£ãã®ã¨ãå¾ã¯Webã°ã£ãããããªãã¦ã¡ã¼ã«ã«é¢ããã½ããã¦ã§ã¢ãã¡ããã¨ä½ã£ã¦ãããããªã¨æã£ãããã§ãã
å®éä½ã£ã¦ã¿ãã¨SMTPãmilterãããã³ã«ãåå¼·ãããã¨ã«ããªã£ã¦ãããã楽ããã£ãã§ãã
ã¨ãããã¨ã§ã以ä¸ã«pmilterã®ä½¿ãæ¹ãç°¡åã«ç´¹ä»ãã¾ãã
pmilterã®ä½¿ãæ¹
pmilterã¯milterãããã³ã«ã§SMTPãµã¼ãã¨éä¿¡ãã¦å¶å¾¡ã§ããã½ããã¦ã§ã¢ã§ããmilterãããã³ã«ã®è©³ç´°ã¯çç¥ãã¾ãããç°¡åã«ããã¨ãSMTPãµã¼ãã§ã¯ã©ã¤ã¢ã³ãï¼MUAã ã£ããMTAã ã£ããï¼ããæ¥ç¶ãåããæã«ãå種ã³ãã³ãã§ããåããè¡ãã¾ãããã®éã®ãå種ã³ãã³ããã¤ãã³ãæã«ãmilterãµã¼ãã«å¯¾ãã¦éä¿¡ãè¡ã£ã¦æ¥ç¶æ å ±ã渡ããåããmilterãµã¼ãã¯ãã®æ å ±ãå ã«ãã£ã«ã¿ã¼å¦çãæ¥ç¶ã®å¯å¦ãªã©ã®å¦çãè¡ã£ã¦ãçµæãSMTPãµã¼ãã«è¿ãã¾ããsendmailãpostfixã¯milterãããã³ã«ã«å¯¾å¿ãã¦ãããããå°å ¥ãè¨å®ã«1è¡ããã°ããå¹³æã§ãã
ã¤ã¾ãã¤ã¡ã¼ã¸ã¨ãã¦ã¯Webãµã¼ãã¨ä¼¼ã¦ãã¦ããªã¯ã¨ã¹ãããã¬ã¹ãã³ã¹ãè¿ãã¾ã§ã«å種ã¤ãã³ããã§ã¼ãºããã£ã¦ããã®ã¤ãã³ãæ¯ã«pmilterã«å¦çãããã¯ãã¦ãpmilterã§å¦çãè¡ãçµæãè¿ãã¦ãSMTPãµã¼ãå´ã®å¦çãæ¡å¼µãããã¨ãããããªåãã§ãã
pmilterã¯ãµã¼ãã¨ãã¦Unix Domain Socketããããã¯ãTCPã§Listenãã¦èµ·åå¾ãSMTPãµã¼ãããå種ã¤ãã³ãã§å¦çã®ä¾é ¼ããã¾ãããã®ã¿ã¤ãã³ã°ã§ãRubyã®ã¹ã¯ãªãããããã¯ãã¦ãããã¨ãã§ãã¾ããRubyã®ã¹ã¯ãªããå
ã§ã¯ Pmilter
ã¯ã©ã¹ã«ãã£ã¦SMTPãµã¼ãã¸ã®å種æ¥ç¶æ
å ±ãåãã ããã¨ãã§ãããã®ãã¼ã¿ãå
ã«Rubyå´ã§å¦çãè¡ãï¼ä¾ãã°ãã¯ã©ã¤ã³ãIPã¢ãã¬ã¹ãenvelopeã®æ
å ±ãããããããã£çãDBã«ä¿åãã¦è§£æãã¦DoSã£ã½ãã¡ã¼ã«ã¯ä¸æçã«å¼¾ããªã©ï¼çµæãSMTPãµã¼ãã«ä¼ããäºãã§ãã¾ãã
Rubyã¹ã¯ãªãããç»é²ã§ããããã¯ã¯ä»¥ä¸ã® pmilter.conf
ã«ããããã«ãæ§ã
ãªãã§ã¼ãºãé¸æãããã¨ãã§ãã¾ãã
pmilter.conf
[server] # hoge.sock or ipaddree:port listen = "/var/spool/postfix/pmilter/pmilter.sock" timeout = 7210 log_level = "notice" mruby_handler = true listen_backlog = 128 debug = 0 [handler] # connection info filter handler mruby_connect_handler = "handler/connect.rb" # SMTP HELO command filter handler mruby_helo_handler = "handler/helo.rb" # envelope sender filter handler mruby_envfrom_handler = "handler/mail_from.rb" # envelope recipient filter handler mruby_envrcpt_handler = "handler/rcpt_to.rb" ## header filter handler mruby_header_handler = "handler/header.rb" # end of header handler #mruby_eoh_handler = "/path/to/handler.rb" # body block filter handler mruby_body_handler = "handler/body.rb" # end of message handler mruby_eom_handler = "handler/eom.rb" # message aborted handler #mruby_abort_handler = "/path/to/handler.rb" # connection cleanup handler #mruby_close_handler = "/path/to/handler.rb" # unknown SMTP commands handler #mruby_unknown_handler = "/path/to/handler.rb" ## DATA command handler #mruby_data_handler = "/path/to/handler.rb"
ä¾ãã°ããã§ç»é²ãã¦ããRubyã¹ã¯ãªããã¯ä»¥ä¸ã®ãããªå 容ã§æ¸ãã¦ããã¨ãã¾ãããµã³ãã«ãªã®ã§å¹³æãªã³ã¼ãã«ãã¦ãã¾ãã
handler/connect.rb
puts "hello pmilter handler called from #{Pmilter.name}" puts "client ipaddr #{Pmilter::Session.new.client_ipaddr}" puts "client hostname #{Pmilter::Session.new.client_hostname}" puts "client daemon #{Pmilter::Session.new.client_daemon}" puts "handler phase name: #{Pmilter::Session.new.handler_phase_name}"
ã³ãã¯ããã§ã¼ãºã§ã¯è²ã ã¨ã³ãã¯ãæ å ±ãåå¾ã§ãã¾ãã
handler/helo.rb
puts "helo hostname: #{Pmilter::Session.new.helo_hostname}" puts "tls client issuer: #{Pmilter::Session.new.cert_issuer}" puts "tls client subject: #{Pmilter::Session.new.cert_subject}" puts "tls session key size: #{Pmilter::Session.new.cipher_bits}" puts "tls encrypt method: #{Pmilter::Session.new.cipher}" puts "tls version: #{Pmilter::Session.new.tls_version}"
handler/mail_from.rb
puts "env from from args: #{Pmilter::Session.new.envelope_from}" puts "env from from symval: #{Pmilter::Session.new.mail_addr}" puts "SASL login name: #{Pmilter::Session.new.auth_authen}" puts "SASL login sender: #{Pmilter::Session.new.auth_author}" puts "SASL login type: #{Pmilter::Session.new.auth_type}" if Pmilter::Session.new.envelope_from == "<[email protected]>" Pmilter.status = Pmilter::SMFIS_REJECT end
ä¸è¨ã®ããã«REJECTã®ã¹ãã¼ã¿ã¹ãã»ããããã¨ãSMTPãã¯ã©ã¤ã¢ã³ãï¼MUAãMTAï¼ããã®æ¥ç¶ãã¡ããã¨REJECTãã¦ããã¾ãã®ã§ãããã«ä½ããã¼ã¿ãå ã«ã¢ã¯ã»ã¹å¶å¾¡ãããªãã¦ãã¨ãç°¡åã«ã§ããã§ããããmruby-geoipã使ã£ã¦ãããç¹å®ã®FromãæªããSubjectã大éã«ãã¦ãã¦ããã¤ãæ¥ç¶å ã®IPã¢ãã¬ã¹ãæªããã«ã³ããªã¼ã³ã¼ãã ã£ããã10ç§éå¼¾ãããªãã¦ãã¨ãRubyã§å®è£ ããã°ããã»ã©è¦ãªãå®è£ ã§ããã®ã§ã¯ãªããã¨æãã¾ãã
handler/rcpt_to.rb
puts "env to from arg: #{Pmilter::Session.new.envelope_to}" puts "env to from symval: #{Pmilter::Session.new.rcpt_addr}"
handler/eom.rb
puts "myhostname: #{Pmilter::Session.new.myhostname}" puts "message_id: #{Pmilter::Session.new.message_id}" puts "reveive_time: #{Time.at Pmilter::Session.new.receive_time}" puts "add_header(X-Pmilter:True): #{Pmilter::Session::Headers.new['X-Pmilter'] = 'Enable'}"
ã¾ã ãã¾ãå¤æ´æ¹é¢ã®ã¡ã½ããã¯ããã¦å®è£ ãã¦ãã¾ããããä¸å¿ãããã追å ããã¡ã½ããã ãã¯å®è£ ãã¦ãã¾ãããã®ãããã¯ãè²ã ã¨æ§åãè¦ãªããå®è£ ãã¦ãããããªã¨æã£ã¦ãã¾ãã
handler/header.rb
puts "header: #{Pmilter::Session::Headers.new.header}"
handler/body.rb
puts "body chunk; #{Pmilter::Session.new.body_chunk}" # Skip over rest of same callbacks # only once call body handler when return Pmilter::SMFIS_SKIP Pmilter.status = Pmilter::SMFIS_SKIP
ä¸è¨ã®headerãã§ã¼ãºãbodyãã§ã¼ãºã¯ãheaderã®è¡æ¯ãbodyã®chunkæ¯ã«ã³ã¼ã«ããã¯ããã¾ãããå¿ è¦ãªå¦çãéä¸ã§çµãã£ãããSKIPã¹ãã¼ã¿ã¹ãè¿ããã¨ã§åæ§ã®ãã§ã¼ãºã®å¾ç¶ã®ã³ã¼ã«ããã¯ã¯ããªãããã«ãããªã©ãå¯è½ã§ãã
ã¾ãããããã®Rubyã³ã¼ãã¯ãpmilterèµ·åä¸ã§ãã£ã¦ãåèµ·åãããã¨ãªãå¤æ´å¯è½ã§ãã
ããã¦ãpostfixã§ä»¥ä¸ã®ããã«pmilterãµã¼ããç»é²ãã¾ãã
- postfix main.cf
# postfix chroot on /var/spool/postfix # create pmilter.socket as /var/spool/postfix/pmilter/pmilter.sock smtpd_milters = unix:/pmilter/pmilter.sock
ãã®å¾ãpostfixãèµ·åããã¦ãpostfixãä»ãã¦ã¡ã¼ã«ãéã£ããåä¿¡ãããããã¨ã以ä¸ã®ããã«miterã¨éä¿¡ãã¦milterã®Rubyã®å¦çãè¡ããã¦ããäºãåããã¨æãã¾ãã
hello pmilter handler called from pmilter client ipaddr 192.168.123.123 client hostname mx.example.net client daemon milter-test-server handler phase name: mruby_connect_handler helo hostname: delian tls client issuer: cert_issuer tls client subject: cert_subject tls session key size: 0 tls encrypt method: 0 tls version: 0 env from from args: <[email protected]> env from from symval: mail_addr SASL login name: SASL login sender: SASL login type: env to from arg: <[email protected]> env to from symval: <[email protected]> header: {"From"=>"<[email protected]>"} header: {"To"=>"<[email protected]>"} header: {"Subject"=>"Hello"} body chunk; Hello world!! myhostname: mail.example.com message_id: message-id reveive_time: Wed Nov 02 21:02:15 2016 add_header(X-Pmilter:True): Enable
ãã®ä¾ã§ã¯ãåã«putsããã ãã®ãã®ã§ãããmrbgemãªã©ã§è²ã ã¨æ¡å¼µãã¤ã¤ãç¬èªã®ã¢ã¯ã»ã¹å¶å¾¡ãªã©ãç°¡åã«å®è£ ã§ããã¨æãã¾ããä¾ãã°ãhttp-dos-detectorã¨ããApacheãnginxç¨ã®DoSæ¤ç¥ã½ããã¦ã§ã¢ã以ååããããªæ¹æ³ã§ä½ãã¾ããããsmtp-dos-detectorãªã©ãç°¡åã«ä½ããã¨ãã§ããã§ããããpmilterã使ã£ãã¡ã¼ã«ã®æ¡å¼µå®è£ ãOSSã§å ¬éããã¨ãã®ãè¯ãã§ãããã
ãã®ä»ãGitHubã«ãã³ããã¼ã¯ããã®ä»ã®åèæ å ±ãè¼ãã¦ãã¾ããããããããæ°ä½ãªã®ã§ãæ¯éæå ã§è²ã ã¨è©¦ãã¦é ããã°ãããã¨æãã¾ãã
ã¾ã¨ã
ã¨ãããã¨ã§ãã¡ã¼ã«ãµã¼ããããããä½ã人ããããã¾ã§ã®ã¡ã¼ã«ãµã¼ããéç¨ãã人ããã¯ã³ãã¤ããªã§ç°¡åã«ãããã¤ã§ããä½åã§ãèµ·åããã¦ãlocalã§unix domain socketã§éä¿¡ãã¦SMTPãµã¼ããRubyã§å¶å¾¡ããããããTCPã§ãªãã¹ã³ãã¦è¤æ°ã®SMTPãµã¼ãã§åä¸ã®pmilterã¨éä¿¡ãã¦ãå ¨ä½ã¸ã®ã¢ã¯ã»ã¹ãä¸å 管çã§å¶å¾¡ããããã¼ã¿ãä¿åãããããããããè¤æ°ã®pmilterãç«ã¦ã¦postfixã«pmilterãè¤æ°ç»é²ãããããããªã©ãªã©Rubyã§ç°¡åã«SMTPã®æåãã¢ã¯ã»ã¹å¶å¾¡ã¨ãã£ãå®è£ ãç°¡åã«ã§ããããã«ãªãã¾ããã
ã¾ããMXã¨ãã¦ã®SMTPãéä¿¡ãµã¼ãç¨ã®SMTPãªã©ãæ§ã ãªå ´æã§pmilterãæ±ããã®ã§ãspamã®åä¿¡ãã©ãå¶å¾¡ããããspamã®è¸ã¿å°ãã¡ã¼ã«éä¿¡ãããåé¡ãã©ãå¶å¾¡ãããããªã©ããRubyã§è²ã ã¨è©¦è¡é¯èª¤ãã¦å®è£ ãããã¨ãã§ããã§ãããã
ã¾ããpmitlerã¯ã§ããã ãã·ã³ãã«ãªä½ãã«ãã¦ããã®ã§ãä»ã¾ã§ãªããªãæãå±ããªãã£ãã¡ã¼ã«ãµã¼ãã®è¤éãªå¦çããã»ã¨ãã©Rubyã®ç¥èããªãã¦ãè¨å®ã®æè¦ã§ç°¡åã«ãããã®ã§ã¯ãªããï¼ä¸è¨ã®è¨å®ãã¿ã¦ããããã¨ãããè¤éãªå®è£ ã¯ãã¦ããªãï¼ã¨æãã®ã§ãã¾ãã¯è²ã ã¨è©¦ãã¦é ããã°å¹¸ãã§ããããããã¡ã¼ã«ã®æ¥½ããã«æ°ä»ãããããã¾ããã
ç¹ã«ãmod_mrubyãngx_mrubyã触ã£ã¦ãã人ã¯ãã»ã¨ãã©åããããªæè¦ã§å®è£ ã§ããä¸ã«ããã®ãã§ä½¿ã£ãè³ç£ï¼KVSãªã©è²ã ï¼ãæ´»ç¨ã§ããã¨æãã®ã§ãæ¯éã試ããã ããã