2018年6月22日 星期五

Centos 查詢對外IP位址

租用雲端空間的虛擬機器,使用ifconfig往往看到的都是內網IP,要查詢實際外網IP可使用下列指令

curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//' 
or shorter
curl ipinfo.io/ip 

2018年6月7日 星期四

jenkins執行shell script中無法使用sudo的解法

再導入DotNet Core專案在CentOS環境,欲利用Jenkins進行發布時發現在建置時尚需重啟DotNET Core Project.service,不過這服務jenkins原生的權限不足,所以加上sudo前墜後出現錯誤"sudo: no tty present and no askpass program specified",改善方式如下:

1. 在終端輸入 sudo visudo

2. 於文件最後增加 jenkins ALL=(ALL) NOPASSWD: ALL

3. 重啟jenkins

2018年3月30日 星期五

asterisk 與 fail2ban小記

下午用戶反映說總機掛了不能用,檢查SIP註冊是OK的,不過FreePBX記憶體顯示紅燈,SERVER看fail2ban的process CPU用量逼近100%,記憶體大多也是被這服務吃掉。ASTERISK的Console顯示大量的register fail事件。

先使用iptables去擋掉頻繁try account/pass的request IP後,在檢查設定發現問題出在logpath,設定成/var/log/asterisk/security這個設定不能說錯,不過ASTERISK的LogFile得同步設定,改成本來就有的messages就擋到了。

不過在過濾的正則表示式原使用的版本式asterisk 1.8設定,恩恩...不太符合所使用版本的格式,後又看到較進階版本(更精簡)設定,還是量身訂造的設定比較好(如下所示),做個備忘囉。

後記: 當初架設好的服務搭配fail2ban也是測試OK的,用久了版本更新沒再回來檢查,所以bot就再次發會打不死的精神進來,疏忽不得。

fail2ban-client status asterisk-iptables
Status for the jail: asterisk-iptables
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     34
|  `- File list:        /var/log/asterisk/messages
`- Actions
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   XXX.XXX.XXX.XXX


vim /etc/fail2ban/jail.local

[asterisk-iptables]
enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
           sendmail[name=ASTERISK, dest=myaccount@xxx.xxx, sender=srvaccount@xxx.xxx.]
logpath  = /var/log/asterisk/messages
maxretry = 6
findtime = 21600
bantime = 86400


vim /etc/fail2ban/filter.d/asterisk.conf

# Fail2Ban configuration file
# Author: Xavier Devlamynck
 
[INCLUDES]
 
# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf
 
[Definition]
 
# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile.
# Values:  TEXT
#
log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[\S+\d*\])? \S+:\d*
 
failregex = ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Wrong password$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - No matching peer found$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Username/auth name mismatch$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Device does not match ACL$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Peer is not supposed to register$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - ACL error \(permit/deny\)$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Not a local domain$
            ^%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$
            ^%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
            ^%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
            ^%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
            ^%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
            ^%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*<sip:[^@]+@<HOST>>;tag=\w+\S*$
            ^%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d+",SessionID="0x[\da-f]+",LocalAddress="IPV[46]/(UD|TC)P/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UD|TC)P/<HOST>/\d+"(,Challenge="\w+",ReceivedChallenge="\w+")?(,ReceivedHash="[\da-f]+")?$
 
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex = 


後記:
最近又發現一堆機器人Try Password的LOG,結果fail2ban GG惹...原因在於message file太大造成記憶體太小就服務終止。後來在Message LOG 設定只儲存NOTICE跟SECURITY就好,因為FULL LOG已經都包含其他的,這樣設定也OK

另外fail2ban的Log儲存預設是SYSLOG,這樣在檢視時會造成混淆也不好找,因此修改
fail2ban.conf的logtarget設定。

搜尋:logtarget = SYSLOG
改為:logtarget = /var/log/fail2ban.log


2018年3月20日 星期二

夯名詞:新零售, 區塊鏈, 人工智慧有感

最近聽得多CI BI AI,這類高來高去的名詞,身為一位相對務實的開發人員,對於這些總是環繞在怎麼做到~做到了又如何應用的死循環中。

先有需求再建構/配合模型,自所擁有的管道(軟體服務)蒐集(CI)有用的RAW DATA,送入模型後得到BI(商業智慧),進送入機器學習建構資源庫未來依此來判別(AI),感覺上好像是在消滅自己工作一樣,一但有了AI那麼系統開發作業不就會被代勞嗎(=.= 真是想太多了,不過工程師有個好處,沒有理論支援下產出的工人智慧,對某些人來看也會被美化成人工智慧)。

AI在課堂中最早是從類神經網路的建構,透過訓練方式來歸納出許多的 pattern,這些在依照所配得權重以計算出最合適的結果,恩恩...這樣看來如何取代工作呢? 不過市場上所有產品都是需要包裝的,當軟體要搭上這股熱潮再不打算大改的情況下,只好再透過重新包裝來應付,但這些也是得燒掉多的腦細胞。

新零售也是如此,貌似"無人商店"也得沾上一點邊,亞馬遜所提的概念店面東改西湊(東施效顰的概念),別人有的都加進來沒有的就是優勢? 不過所看的到的都是表象,技術這類的潘朵拉之盒卻得不到;在區塊鏈上因bitcoin而廣受討論,兩個相加起來就是如何去中間話在新零售上,生產->配銷->消費者的概念把中間的"經銷商"由軟體系統取代掉,讓消費者能快速取得新鮮品優的產品(當然能做到價廉就更不可思議了),可現實真是能如此嗎? 大家都覺得經銷商賺得飽飽的(Ex. 專門剝削生產端宰殺消費者的菜蟲?),但是許多事情都有他不為人知的專業在,各個環節所需承擔的風險成本往往是被忽視的,用軟體系統+AI來處理掉中間人學術討論上總是誘人的,回歸現實就傷腦筋囉...

拜讀21世紀資本論(超厚)比起看富爸爸窮爸爸系列來的有感,資本市場講求的看中的或許底蘊有那麼1%重要的,其他99%就不是腦袋硬梆梆只會硬幹的人能去求的,當創造話題的大老們衝在前頭,後頭收尾的工程師們...除了爆些新鮮個肝賺取微薄的OO之外,就只能幻想"有夢最美希望相隨"不是口號的一天,呵呵。

~~有段順口溜流傳許久,繼續做自我看著笑笑即可 ~~
東混西混,一帆風順;  苦幹實幹,撤職查辦;
盡職負責,卻遭指責;  任勞任怨,永難如願;
推拖栽贓,滿排勳章;  屢建奇功,打入冷宮;
不拍不吹,狗屎一堆;  全力以赴,升遷耽誤;
苦苦哀求,互踢皮球;  看緊國庫,馬上解僱;
會捧會現,傑出貢獻;  會鑽會溜,考績特優。

2018年2月9日 星期五

summernote 上傳檔案處理

summernote是個很輕量的編輯器,往常都使用CKEditor來提供服務,不過青菜蘿蔔各有所好...其中最常調整的莫過於檔案上傳處理,備忘一下囉...

HTML Header
include id_summernote.css & id_summernote.js
#語系要更換的話,得多include該文本 summernote-zh-TW.js

只需要將DIV放置在愈顯示處
HTML:
<div id="id_summernote" class="summernote"></div>

如果上傳檔案不特別處理的話,預設式以Base64編碼方式存放於編輯區中,這樣存入資料庫將會大大的增加儲存量,於未來存取時可能耗費更多伺服器資源。改成存放圖檔於伺服器中,這樣瀏覽上路由器/交換器/瀏覽器都可能暫存該圖檔資源,而減輕WEB SERVER吞吐頻寬負擔。

JavaScript
<script type="text/javascript">
jQuery(document).ready(function() {
      //載入
              initEditor();
});

  /* 編輯器初始化 */
  function initEditor() {
    $('.summernote').summernote({
        lang: 'zh-TW',       // default: 'en-US'
        toolbar: [
                ["style", ["style"]],
                ["font", ["bold", 'italic', "underline", "clear"]],
                ["fontname", ["fontname"]],
                ['fontsize', ['fontsize']],
    ["color", ["color"]],
                ["para", ["ul", "ol", "paragraph"]],
                ["table", ["table"]],
                ["insert", ["link", "picture", "video", "hr"]],
                ['height', ['height']],
                ["view", ["fullscreen", "codeview", "undo", "redo", "help"]]
            ],
        height: 200,         // set editor height             
        minHeight: null,    // set minimum height of editor
        maxHeight: null,    // set maximum height of editor
        focus: true,         // set focus to editable area after initializing summe
        tabsize: 2,
            dialogsInBody: true,
        callbacks: {
            onImageUpload: function (files) { //the onImageUpload API
                img = sendFile(files[0], $(this));
            }
        }
     
    });  
  }  
  function sendFile(file, editor) {
            data = new FormData();
            data.append("upload", file);         
            $.ajax({
                data: data,
                type: "POST",
                url: "<?=site_url('controler/function'); ?>",
                cache: false,
                contentType: false,
                processData: false,
                success: function (datas) {
                    var data = $.parseJSON(datas);
                    if (data.uploaded == '1')
                      // the insertImage API
                      editor.summernote('insertImage', data.url, 'image name');
                    else
                      console.log(data.error);
                },
error:function(data){
      console.log(data);
}
            });
      }

</script>

至於回傳的資料中,透過JSON編碼方式回傳,這樣有利於處理檔案儲存狀態的追蹤處理。