趁著連假,扛著一個小孩返鄉,體驗了走路、公車、捷運和高鐵。挑戰最大的是高鐵,在一個壅擠的座位上哄著小孩,也算是個磨練了。還好我不用選台鐵,那肯定是瘋了!
這陣子咀嚼著又似看透一些世俗話題,從黃毛小子、強說愁,總算累積了一點社會經歷,只是如同雷軍創業的初始心態:財務自由了,再來談創業、再來談不為錢做事的方向。很多事的起頭,都是有前提的,也認清自己不夠本去做哪些事。
返鄉看著兩老和周邊的考驗,漸漸浮現出這類現實的感觸,不再像學生時代的低機會成本,不再是年少輕狂自傲能扛著天,我想,漸漸地就像練武的人,什麼一次打十個,還是逃命吧 XD 一次打一個吧!
我想,我還是會積極地把握機會,但需要更沉得住氣、需要更多耐心和命運磨合磨合。
2017年3月1日 星期三
2017年2月24日 星期五
Captive portal 研究心得,以 iptables 實作
之前略知使用 Taipei Free 或 CHT Wi-Fi時,會彈跳出認證(登入)的網頁,但卻不知其所以然,直到最近研究了 Captive portal 的東西。一開始用 Captive portal 關鍵字找了一些 RFC 文件,殊不知那些都是煙霧彈 XD 如:
至於 router 上的實作,簡單的說,就是透過防火牆機制:
以 NoCatSplash 產出的 iptables 為筆記:
其他 iptabes 簡介:
- Captive-Portal Identification Using DHCP or Router Advertisements (RAs) https://tools.ietf.org/html/rfc7710
- Additional HTTP Status Codes - The 511 Status Code and Captive Portals https://tools.ietf.org/html/rfc6585
- 用戶連上 router 時,可以進行 DNS lookup
- 未通過認證的用戶,無法透過 router 進行網路連線請求,如連上 facebook.com
- 通過認證的用戶,透過 router 可以正常使用網路
至於 router 上的實作,簡單的說,就是透過防火牆機制:
- 防火牆設計各種狀態,例如未認證,已認證的 flag (mark)
- 當用戶完成認證時,透過 CGI 執行防火牆指令,給予標記 (mark)
- 允許已標記的 client 封包通行
- http://dev.wifidog.org/
- https://www.dd-wrt.com/wiki/index.php/NoCatSplash
- https://github.com/arjan/NoCatSplash
- https://github.com/mhaas/fbwlan
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N WD_wlan0_AuthServs
-N WD_wlan0_Global
-N WD_wlan0_Internet
-N WD_wlan0_Known
-N WD_wlan0_Locked
-N WD_wlan0_Unknown
-N WD_wlan0_Validate
-A FORWARD -i wlan0 -j WD_wlan0_Internet
-A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i wlan0 -o eth0 -j ACCEPT
-A WD_wlan0_AuthServs -d SERVER_IP/32 -j ACCEPT
-A WD_wlan0_Internet -m state --state INVALID -j DROP
-A WD_wlan0_Internet -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A WD_wlan0_Internet -j WD_wlan0_AuthServs
-A WD_wlan0_Internet -m mark --mark 0x254 -j WD_wlan0_Locked
-A WD_wlan0_Internet -j WD_wlan0_Global
-A WD_wlan0_Internet -m mark --mark 0x1 -j WD_wlan0_Validate
-A WD_wlan0_Internet -m mark --mark 0x2 -j WD_wlan0_Known
-A WD_wlan0_Internet -j WD_wlan0_Unknown
-A WD_wlan0_Known -j ACCEPT
-A WD_wlan0_Locked -j REJECT --reject-with icmp-port-unreachable
-A WD_wlan0_Unknown -p udp -m udp --dport 53 -j ACCEPT
-A WD_wlan0_Unknown -p tcp -m tcp --dport 53 -j ACCEPT
-A WD_wlan0_Unknown -p udp -m udp --dport 67 -j ACCEPT
-A WD_wlan0_Unknown -p tcp -m tcp --dport 67 -j ACCEPT
-A WD_wlan0_Unknown -j REJECT --reject-with icmp-port-unreachable
-A WD_wlan0_Validate -j ACCEPT
以 NoCatSplash 產出的 iptables 為筆記:
$ iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N NoCat
-N NoCat_Inbound
-N NoCat_Ports
-A FORWARD -j NoCat
-A NoCat -j NoCat_Ports
-A NoCat -j NoCat_Inbound
-A NoCat -s SERVER_IP/24 -i wlan0 -m mark --mark 0x1 -j ACCEPT
-A NoCat -s SERVER_IP/24 -i wlan0 -m mark --mark 0x2 -j ACCEPT
-A NoCat -s SERVER_IP/24 -i wlan0 -m mark --mark 0x3 -j ACCEPT
-A NoCat -j DROP
-A NoCat_Ports -i wlan0 -p tcp -m tcp --dport 25 -m mark --mark 0x3 -j DROP
-A NoCat_Ports -i wlan0 -p udp -m udp --dport 25 -m mark --mark 0x3 -j DROP
$ iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N NoCat_Capture
-N NoCat_NAT
-A PREROUTING -j NoCat_Capture
-A POSTROUTING -j NoCat_NAT
-A NoCat_Capture -p tcp -m mark --mark 0x4 -m tcp --dport 80 -j REDIRECT --to-ports 5280
-A NoCat_Capture -p tcp -m mark --mark 0x4 -m tcp --dport 443 -j REDIRECT --to-ports 5280
-A NoCat_NAT -s SERVER_IP/24 -o eth0 -m mark --mark 0x1 -j MASQUERADE
-A NoCat_NAT -s SERVER_IP/24 -o eth0 -m mark --mark 0x2 -j MASQUERADE
-A NoCat_NAT -s SERVER_IP/24 -o eth0 -m mark --mark 0x3 -j MASQUERADE
其他 iptabes 簡介:
2017年2月7日 星期二
[Linux] 使用 xargs 執行任務,參數不只接在指令尾部
原先很習慣用 find 找到東西後,搭配 -exec 去執行任務,這時要串起來的指令很方便。然而,若是要在一個清單內,找到東西後,再接一串指令時,就會試試 xargs 這指令。只是 xargs 習慣都是把變數接在指令後頭:
此例就是找到的關鍵字”我”,再丟給 echo 去印出來。但如果,想要把找到的關鍵字都包起來時:
這時就會卡卡的,沒錯,就派 shell 上場了:
如此一來,透過 sh 在包一層,就可以完美使用 xargs 做事了。而我真正的需求是檢查一個檔案清單,查看清單內的檔案是否都存在:
$ grep 我 user.dict | xargs -n 1 echo | head -n 5
分我杯羹
天知地知,你知我知
禮豈為我設
誨爾諄諄,聽我藐藐
惠子知我
此例就是找到的關鍵字”我”,再丟給 echo 去印出來。但如果,想要把找到的關鍵字都包起來時:
找到”分我杯羹”了
找到”天知地知,你知我知”了
找到”禮豈為我設”了
找到”誨爾諄諄,聽我藐藐”了
找到”惠子知我”了
這時就會卡卡的,沒錯,就派 shell 上場了:
$ grep 我 user.dict | xargs -n 1 sh -c 'echo "找到\"${@}"\"了' "${0}" | head -n 5
找到"分我杯羹"了
找到"天知地知,你知我知"了
找到"禮豈為我設"了
找到"誨爾諄諄,聽我藐藐"了
找到"惠子知我"了
如此一來,透過 sh 在包一層,就可以完美使用 xargs 做事了。而我真正的需求是檢查一個檔案清單,查看清單內的檔案是否都存在:
$ grep keyword file-list.txt | xargs -n 1 sh -c 'test -r "${@}" || echo "${@} NOT FOUND" ' "${0}"
2017年2月3日 星期五
Ansible 筆記 - 透過 Reverse SSH Tunnel 維護機器
有時候就是這樣,某些機器本身連不進去,這時要測試發佈流程時,就適合從中間機器建立 SSH Tunnel 啦。例如 A <-> B <-> C 關係中,B 可以分別連到 A 跟 C ,但 A 跟 C 彼此無法連上。這時就從 B 的角色建立個 Reverse SSH Tunnel 了
如此一來,在 A 機器中,就可以自連 ssh 127.0.0.1:2266 就可以直達 C 機器囉!
接著,若在 A 機器發動 ansible deploy 任務,就會有需要指定 ansible-playbook 運作時,那個 ssh port 要換一下,所幸的,用 ansible-playbook -h 就有教學啦 XD 其中 sftp 跟 scp/ssh 的參數名不一樣,所以得個別設定,完整的範例:
此例 bin/echo.sh 只是一個讓我組出 ansible-playbook 所需的格式:
@B:
$ ssh -NR 2266:C_HOST_IP:22 user@A_HOST_IP
如此一來,在 A 機器中,就可以自連 ssh 127.0.0.1:2266 就可以直達 C 機器囉!
接著,若在 A 機器發動 ansible deploy 任務,就會有需要指定 ansible-playbook 運作時,那個 ssh port 要換一下,所幸的,用 ansible-playbook -h 就有教學啦 XD 其中 sftp 跟 scp/ssh 的參數名不一樣,所以得個別設定,完整的範例:
@A:
$ HOST=tag_Ansible_MY_Task DATA="['127.0.0.1']" ansible-playbook -i bin/echo.sh MY_Task.yml --private-key=ssh-private-key.pem --sftp-extra-args="-oPORT=2266" --scp-extra-args="-p 2266" --ssh-extra-args="-p 2266"
此例 bin/echo.sh 只是一個讓我組出 ansible-playbook 所需的格式:
$ cat bin/echo.sh
#!/bin/bash
echo "{\"$HOST\":$DATA}"
$ HOST=tag_Ansible_MY_Task DATA="['127.0.0.1']" bin/echo.sh
{"tag_Ansible_MY_Task":['127.0.0.1']}
$ head -n 7 MY_Task.yml
---
- hosts: tag_Ansible_MY_Task
remote_user: ubuntu
become: true
become_user: root
become_method: sudo
標籤:
ansible,
ansible_ssh_port,
ssh,
tunnel
2017年1月13日 星期五
[NodeJS] 批次處理 Website snapshot 並存進 MySQL DB @ Ubuntu Server 14.04
延續之前 [NodeJS] 使用 WebShot 進行網頁截圖、顯示正確的中文(CJK)等編碼 @ Ubuntu 14.04 Server 的部分,稍微改幾行 code 就支援批次處理啦
前置環境:
如此一來,就稍微搞定批次產出了。若要把產出的東西存進 MySQL DB server,那可以再這樣做:
如此一來,就可以自動掃目錄下符合 *.png 的檔案,並將 binary data 紀錄至 db server 中。
前置環境:
$ sudo apt-get install nodejs npm xfonts-wqy xfonts-kaname
$ sudo ln -s /usr/bin/nodejs /usr/bin/node
$ mkdir -p job/images && cd job
$ npm install webshot
程式主體:
$ vim build.js
var output_dir = 'images';
var concurrent_limit = 10;
var running_task = 0;
var total_task = [
{ domain: 'tw.yahoo.com', url: 'https://tw.yahoo.com' } ,
{ domain: 'facebook.com', url: 'https://facebook.com' } ,
];
function build_website_snapshot() {
while(total_task.length > 0 && running_task < concurrent_limit) {
var item = total_task.shift();
var url = item.url;
var domain = item.domain;
// https://github.com/brenden/node-webshot
webshot(url, output_dir+'/'+domain+'.png', {
screenSize: {
width: 320,
height: 480,
},
shotSize: {
width: 320,
height: 320,
},
timeout: 20000,
renderDelay: 3000,
userAgent: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.20 (KHTML, like Gecko) Mobile/7B298g'
}, function(err) {
if(err)
console.log(err);
running_task--;
if (running_task == 0)
console.log('done');
if (total_task.length > 0)
build_website_snapshot();
});
running_task++;
}
}
$ node build.js
如此一來,就稍微搞定批次產出了。若要把產出的東西存進 MySQL DB server,那可以再這樣做:
$ npm install mysql
$ vim import.js
var fs = require('fs');
var path = require('path');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'dbuser',
password : 'dbpassword',
database : 'dbname',
});
var scan_source_dir = 'images';
var files = [];
var sql_values = [];
fs.readdirSync(scan_source_dir).filter(function(file){
//console.log(file);
if (fs.statSync(path.join(scan_source_dir, file)).isFile() && file.lastIndexOf('.png') == (file.length - 4)) {
var domain = file.substring(0, file.length - 4);
//files[domain] = fs.readFileSync(path.join(scan_source_dir, file), {encoding: 'binary'});
files[domain] = fs.readFileSync(path.join(scan_source_dir, file));
sql_values.push([domain, files[domain], Math.round(new Date().getTime()/1000), Math.round(new Date().getTime()/1000)]);
}
});
// console.log (sql_values);
/*
CREATE TABLE `snapshot_table ` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`domain` varchar(64) NOT NULL DEFAULT '',
`image` blob,
`createtime` int(11) DEFAULT NULL,
`updatetime` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `domain` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
*/
var sql = "INSERT INTO snapshot_table (domain, image, createtime, updatetime) VALUES ? ON DUPLICATE KEY UPDATE image=VALUES(image), updatetime=VALUES(updatetime) ";
connection.query(sql, [sql_values], function(err) {
console.log(err);
});
connection.end();
如此一來,就可以自動掃目錄下符合 *.png 的檔案,並將 binary data 紀錄至 db server 中。
訂閱:
文章 (Atom)