發表文章

目前顯示的是 11月, 2012的文章

由Oracle PL/SQL中寄信

我有時候會使用Oracle的PL/SQL來寫一些程序,可以提供給前端的程式來叫用,或者使用Oracle的排程器來叫用,就可以做到許多原本要用C#或PB等開發工具才能做到的事。PL/SQL可以提供很好的效能,配合SQL Developer工具就可以跨平台在Windows或Mac OSX,Linux等不同電腦上寫程式。 最近在寫一個定期檢查的功能,想要在程式檢查到某些特別狀況時,希望可以寄送信件通知。找了一些資料,先稍作整理: 1. PL/SQL寄email的方式由早期的UTL_TCP,UTL_SMTP,到10g之後主要是推UTL_MAIL, 但是UTL_MAIL預設沒有安裝,必須由DBA先行安裝並設定一個指定郵件主機的初始參數。 $cd $ORACLE_HOME/rdbms/admin $sqlplus / as sysdba > @ utlmail.sql > @ prvtmail.plb > grant execute on UTL_MAIL to public; > alter system set smtp_out_server='xxx.xxx.xxx.xxx' 然後就可以很簡單的叫用一個程序來寄信了。 utl_mail.send(sender, recipients, cc, bcc, subject, message, mine_type); 我直接在SQL Developer裡測試正常,但是將此程式包在另一個程序裡叫用時,卻出現ORA-24247的錯誤。Google了一下找到這篇 ORA-06502 ORA-24247 calling UTL_MAIL from Oracle 11gR2  說要再建立一個ACL,然後要利用此ACL指派權限可以存取該郵件主機。不過,我在建立ACL時,卻又出現另一個錯誤訊息:function-based index XDB.XDB$ACL_XIDX is disabled並告訴我可以重建或啟用該索引。我直接在SQL Developer中重建該索引,卻一直失敗。再去Google後找到另一篇 Fine-grained access to network services ,發現他也是同樣的情況,而且他說他重建索引後就可以了。我才想到自己雖然具有DBA的權限,但是...

又被垃圾信攻擊了

最近做例行主機檢查時,發現郵件閘道主機異常的大量在往外寄信,但都無法寄出去。看了一下mailq, 果然發現有很大量的信在/var/spool/mqueue中。 直覺的先在mail log裡查看問題,但只看到一大堆由A主機寄到B主機的訊息,而B主機則是一大堆由A主機寄來信件以及試著要寄出,但無法寄出的訊息。 我們的架構是預設由A主機來寄信,如若寄不出去,則轉到B主機,由B主機來試著寄看看。所以真的寄不出去的信,都會queue在B主機。由初步看到的現象,我判斷(假設)攻擊者很有可能已經猜到我們使用者的帳號及密碼,然後由A主機大量的寄信進來。 我必須印證這個想法,並且若真為此情況,則必須找到是那個帳號被利用了。 但要如何印證呢?當然可以由mail log來查看,一定可以看到誰在那個時候,使用那個帳號進入,然後寄了多少信。這表示我必須查看大量的log訊息了,其實未必,我想到一個方法,在B主機裡queue了大量無法寄出的垃圾信,正好提供我重要的資訊。 #cd /var/spool/mqueue #ls * #cat xxxxxxx 如此,列出這些垃圾信的內容,(可能要多看幾封)結果我發現大部份的垃圾信都是在前幾天的幾點幾分寄到A主機的。如此,我只要看那個時刻的log就可以了。 #bzcat /var/log/maillog.0.bz2 | grep 16:08 | grep auth 以上列指令,在正確的mail log檔裡找到該時刻的資訊,而其實我也只要知道是不是有人使用SMTP AUTH的方式驗證進入。所以這樣我很快的只要查看很少的資訊就發現,果然有。而且找到是那個帳號被利用了。再進行反覆確認,以這個帳號來查看當天寄了多少信,登入驗證多少次,果然都是很異常的大量,而且其ip, FQDN, enveloper的內容等,也都符合。 我甚至還猜了一次該帳號的密碼,還真的猜對了。實在太好猜了。 最後,我只好先將該帳號鎖定(其實系統只是改了他的密碼),並將所有在mailq中的所有垃圾信都刪除。再觀察情況都正常後就收工了。

Oracle SQL Developer可以對PL/SQL程式除錯

圖片
之前在使用Oracle SQL Developer寫PL/SQL的時候,就有發現有除錯的功能,但是也沒耐心去找說明文件看如何使用,就直接用用看。但是每次都是有錯誤訊息,一時之間也不知道問題在那裡,又急著寫出程式,就先使用老方法DBMS_OUTPUT.PUT_LINE()把變數的內容印出來,其實也都可以解決。所以就一直沒去想為什麼除錯功能都不能用,最近比較有時間可以找問題,稍微試了一下,發現除錯功能是可以用的。 首先,網路上很多文章都有在講怎麼使用,例如這篇 Testing and Debugging Procedures using SQL Developer 。但是都講的很順,沒提到會碰到的問題。所以都會告訴你正常進入除錯模式的樣子長怎樣: 基本的可以看變數的內容值,可以設中斷點,可以進入或往下跑的功能都有。 我碰到的問題是在按除錯時,就出現錯誤訊息,不會進入這個除錯的畫面。而錯誤訊息是連線到一個奇怪的ip address 169.95.x.x之類的。然後告訴我連不到,我一直沒想到這個位址是何方神聖,後來一想,我的機器有安裝過虛擬機器的軟體,所以會有一張軟體的網路卡,而其ip address就是這種奇怪的樣子。 福至心靈,把那張虛擬機器建的軟體網卡停用後,再按除錯,就出現“其他的錯誤訊息”了。但是原本的錯誤訊息不見了,這表示已成功了一步。 我再按一下“編譯以除錯”按鈕,之後再去試按除錯,就成功了!可以正常的出現選取要除錯目標的視窗。之後的操作也都正常。