Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
們無法在一篇博文里解釋 JavaScript 的所有細節。如果你正或多或少地涉及了 web 應用程序開發,那么,我們的 Java 工具和技術范圍報告揭示了,大多數(71%)Java 開發者被歸到了這一類,只是你對 JavaScript 遇到了阻礙。
毫無疑問,你已經知道了 Java 和 JavaScript,不管它們有著多么類似的命名,彼此沒有共享太多共通之處。Java 的靜態類型、符合直接規律的簡單語法和冗長,與 JavaScript 的動態、缺乏一致性原則和怪異,有著巨大的不同。
然而,JavaScript 是 web 的編程語言,最近由于 Node.js 和 JVM 自己的 Nashorn JavaScript 引擎的發展,在服務器端獲得了相當的注意。
本文,我不想只是漫談 JavaScript 的好與不好,或重復任何人都能免費找到的、不計其數的 JavaScript 教程。我想列出一些有助于理解 JavaScript 做為一種語言的技術點,并從接近 horse的角度來理解。
我們將在本文包含下列語言級別的技術點:
另外,你會找到一些工具方面的推薦,沒有這些工具,你是不想著手 JavaScript 項目的,包含了構建系統的代碼質量分析和測試框架方面的工具。
優點
編寫一次,差不多處處運行!
毋庸置疑 JavaScript 是 web 編程語言,是很多其它語言的編譯目標,也是用來證明有時候人們只是想擁有更多自由時間的終極方式。盡管如此,這不是一件壞事。每一臺能夠瀏覽現代網站的電腦都裝備了具有性能和可用的 JavaScript 引擎。最重要的是,JavaScript 代碼可以在后端運行。
內置到我們喜愛的 JVM 的、輕量級高性能 JavaScript 運行時 Nashorn,完全能夠解釋 JavaScript 腳本,還能夠解釋項目中帶有 Java 代碼的 JavaScript 腳本。
鑒于每臺電腦運行時都可獲得的自由,JavaScript 成為 Java 體驗的完美延續。
函數式編程:一等公民是函數,而不是遞歸
JavaScript 中的函數是第一類公民,它們是值,可被存儲在變量里、傳遞給其它函數、在適當的時候再執行。
這打開了函數式編程世界的大門,這是結構化 JavaScript 編程的完美方式。
注意,JavaScript 里的對象是任何東西的映射,對象的每個特性(attribute)都在同一個映射里:函數、屬性(property)、構造器;易變性帶來了更大的隱患,而對于 Java,你至少能夠確保方法和字段結構在某種程度上是穩定的。
反過來,這使得函數式編程更加有利:涉及到小的、可理解函數和不變的數據結構是在 JavaScript 里運行的方式。
這不是沒有依據的,下面是在 JavaScript 里定義一個 reduce 函數的例子,來自于《Eloquent JavaScript》一書。
function forEach (array, action) { for (var i = 0; i < array.length; i++) { action (array[i]); //apply action to every element of the arra. } } function reduce (combine, base, array) { forEach (array, function (element) { base = combine (base, element); // and here we apply function passed as ‘combine’ parameter to ‘base’ and ‘element’ }); return base; } function add (a, b) { // btw, this is how you define a function in JavaScript return a + b; } function sum (numbers) { return reduce (add, 0, numbers); }
注意:我們沒有在這里使用 reduce 的遞歸版本。JavaScript 沒有以尾調用【注1】為特色,這意味著每個函數的遞歸版本都將用到棧的深度,和 Java 一樣,如果你遞歸太深,程序就崩潰。
繼承:就像真實的世界
JavaScript 的繼承是基于原型的。即,你沒有擴展了其它類型的類型,而實際上,你擁有的實例從其它實例繼承了功能。
想象一下,對象A就像一個映射,我們剛才稍微提到了一些、但是用了不同的視角,然后另一個類似映射的對象B從A繼承了一切。
這說明B可以訪問A所有部分:A的方法、字段等等。
在實踐中,我從來沒有看到有人實際使用簡單的基于原型的繼承。通常當某人需要繼承時,他只是構造類,因此你可以用到所有廣泛的技能,和基于類的繼承的工作模式。
——Rene Saarsoo,XRebel 前端工程師
我不太確定 Java 開發者應該從中吸取什么,但是要當心繼承方式的不同,對于父級對象要格外留意、而不要意外地改變整個程序的行為。
任何時候要避免的
列出不可靠的 JavaScript 設計上的決定比想象中要容易。在 JavaScript 程序中要避免的最明顯的地方就是全局變量的聲明。
注意,在 JavaScript 里,無論什么時候,不使用 var 關鍵詞定義變量,那么定義的變量被推到了它們被定義的作用域頂端。這意味著,每個用這種方式定義的變量將跑到全局范圍頂部,這會引發沖突以及你和同事不可預期的頭痛。
可以開啟 strict 模式。只需在腳本文件頂部寫上“use strict”,那么不經意編寫的全局變量聲明將顯示錯誤。
JavaScript 與 Java 另一個重要的不同點在于,前者是動態類型語言,其真諦是所有東西都可以是任何類型。這很明顯了,實在不能再強調了:不要針對不同類型的值,去復用相同的變量。
跟蹤剛開始是個 string 類型的變量,但是現在它成了浮點數、或者函數了,相信我!
還有,我不想太深入類型和布爾值的討論,但是要警惕 JavaScript 引擎扔給你的隱式類型轉換。
搞定工作的小提示
正如我上面提到的,在編程上要更加注意這種語言的語法和怪癖,而不僅僅是知道。項目很少由于語言的不足而失敗,更多的失敗是與總體項目框架不足有關。下面是有助于你交付項目的一些工具。
靜態代碼分析
大部分項目是不同的,其復雜度和需求導致了大量的細節,你該如何著手代碼庫呢。盡管如此,在所有地方都有一致性的目標,那就是代碼質量。
是的,代碼質量,對于任何開發者來說,最重要的工作就是交付。但是不要在質量上妥協,不要對你提交的代碼感到不自信就不情愿與同事分享。
幸運的是,JavaScript 有一套得體的解決方案——JSHint。JSHint 是為 JavaScript 量身打造的靜態分析工具,與應用于 Java 代碼的 FindBug 類似。JSHint 可以在你的代碼庫運行,并高亮出可疑的或有問題的地方,即使你不會馬上產生 bug,但這些地方將來變得難以維護。在項目中支持它相當簡單。幫自己一個忙——如果你在寫 JavaScript 代碼,就用 JSHint 讓它更安全、少一些尷尬。
REPL
REPL 代表“讀取-求值-輸出”循環(Read-Eval-Print Loop)【注2】,是很多動態語言的強大工具。如果你看過 Scala 或 Groovy,你一定能夠理解這個概念。
激活 JavaScript REPL 的一種途徑是打開瀏覽器的控制臺,它產生了對 JavaScript 代碼求值的界面。
另一個比較方便的工具是 jjs,它捆綁在 JDK1.8。
它是命令行工具,允許你訪問 JDK 中的 Nashorn JavaScript 引擎,完全有能力執行那些甚至最為嚴格的 JavaScript 腳本。
測試
對于任何一個項目,你都想運行一些測試。測試對于動態類型的語言尤為重要,最好選擇一種測試框架。我推薦 Jasmine,它是用于測試 JavaScript 的行為驅動開發框架。
在 Jasmine,你用 describe 描述測試套件,它阻止了你想測試的代碼訪問。在測試中的代碼完成后,你 expect 一些結果。
很明顯這里不是要給出教程,但是我想讓你一瞥 JavaScript 代碼看起來是多么地優雅。Jasmine 是 JavaScript 項目最好的實踐之一,我們私下在產品開發中應用到了 ZeroTurnaround 項目,尤其是對于富含 JavaScript 的不間斷運行的交互分析器 XRebel。
構建工具
最后,你的項目將需要的、比較重要的是構建工具。如果你在 Java 項目中使用 JavaScript,請確保你可以避開 Java 構建工具,這就差不多足夠了。但是,對于獨立的 JavaScript 項目,沒有必要引入龐然大物—Maven【注3】。
可以考慮的 JavaScript 項目用到的構建工具是 GulpJS【注4】。它是基于插件的構建系統,你可以為其指定任務。任務可以是“拷貝 src 目錄下的 .js 文件到 dest”、或“壓縮我的 JavaScript 代碼用于生產環境”。讓人受到震動的是,GulpJS 把任務相關的文件流加入過濾器,因此你可以把上面的兩個任務加入一次有效的清掃中。
還有大量的可用插件,借助適當的構建系統,你將發現項目中的協作會輕松很多。
結論
我們只是看到了 JavaScript 的冰山一角,并盡量介紹一些 Java 開發者在解決 JavaScript 時應該知道的概念和工具。自然地,這里沒有提供要學習的完整的技術清單,但是如果你正準備義無反顧地深入 JavaScript 項目,這會幫助你起步,擁抱 JavaScript 的怪癖將有助于你不會頻繁地沮喪。
你了解讓 JS 開發者走向快樂的秘密或最佳實踐嗎?毫無疑問應該去分享!在下面評論或在 Twitter:@shelajev 上與我交談。我樂于聽到你的想法!
作者:前端小攻略
原文:https://my.oschina.net/u/3972188/blog/2999914
略。基本可以從wikipedia上找到解釋。
http://kylin.incubator.apache.org/docs/gettingstarted/terminology.html
在介紹Kylin的各種操作之前,首先讓我們來了解一下Kylin的總體設計,包括其架構、工作流程、和數據模型。
Kylin目前是一個MOLAP系統,也就是基于對Cube進行預計算來滿足低延遲的查詢處理。Kylin的數據源就是Hive上的表,以星型模式存在。Kylin的離線計算過程(下圖中藍色箭頭的數據流)會讀取Hive中的原始數據,將事實表和維表join起來,然后對各種維度組合(cuboid)進行計算。計算后的cube以key-value的形式存儲在HBase中。
對于SQL請求,Kylin的查詢引擎會判斷SQL能否由HBase中的cube滿足。如果可以,查詢就會轉換為HBase的range scan操作,直接獲得結果數據,因此能做到秒級的響應。對于無法由cube實現的查詢,Kylin可以將查詢路由給Hive執行,不過當前版本由于性能原因,disable了路由查詢的功能。
使用Kylin的工作流程如下圖所示。
首先,RD創建一個Kylin的項目。一個項目中可以定義多個Cube。
然后,RD需要告訴Kylin需要訪問Hive上的哪些表,即「加載Hive表」。注意這里Kylin只會從Hive Metastore同步表的元信息,并不會讀取表的數據。
之后就是最主要的「Cube建模」過程。這一步就是定義Cube的元信息,包括Data Model(指定事實表與維表,以及他們的連接方式)和Cube Model(有哪些維度和度量,如何增量刷新,以及聚集組和rowkey這些高級設置)。
建模完成之后,RD就可以出發「Cube構建」的動作了。Kylin提供了Cube構建管理的REST API,因此Cube的構建是可以與現有的調度系統集成的。
Cube構建成功之后,數據分析師就可以進行查詢啦,例如進行常見的上卷下鉆操作。下一小節會提到,Kylin中的Cube對分析師是透明的,分析師還是對Hive中的星型模式查詢,這是Kylin區別于其他方案(例如生產aggr表和summary表)的主要特征。
在Kylin系統內,不同角色人員看到的數據模型是不同的。下圖說明了其中的區別。
關于Cube建模的步驟和操作方式,目前官方教程已經比較全面了,故不再贅述。請讀者自行閱讀。
http://kylin.incubator.apache.org/docs/tutorial/create_cube.html
.本文為公測版,一旦發現有任何錯誤內容,會立即進行修復,請持續關注本站。
2.本文在正式版之前會不斷的邀請各路黑客大手進行評價測試,歡迎提出異議。
本文僅針對網站部分,本文會對typecho,wordpress進行測試
如果你root端口為22,并且密碼是123456,就沒必要往下看了。
網站環境為linux tengine/nginx mariaDB,同理,apache也有相關設置,百度實驗下即可。
**本文會闡述以下部分
1.基礎權限控制
2.執行目錄限制
3.PHP的限制
4.webshell寫入與執行
5.權限細分,必須寫入的目錄**
1.基礎權限控制
什么叫基礎權限?在LNMP架構下,nginx+php-fpm架構需要什么權限?
這里我們先來看一下默認權限
默認我們的nginx運行用戶是nginx,而php-fpm的默認用戶是apache,默認用戶安全嗎?
看一下webshell
uid=48(apache) gid=48(apache) groups=48(apache)
很明顯,我們的默認用戶是apache
我們使用shell新建一個目錄,很明顯,我們是無法建立文件夾的
mkdir: cannot create directory `1': Permission denied
在網上很多教程會告訴我們,吧nginx和phpfpm改成同樣的用戶,我們看看會發生什么。
[root@gov 1]# sudo -u nginx mkdir 1
[root@gov 1]# ll
total 4
drwxr-xr-x 2 nginx nginx 4096 Aug 19 18:08 1
沒錯,這是一項愚蠢的決定!
所以默認權限是安全的嗎?并不是,你忘了上傳目錄,我們看下上傳目錄的權限
drwxrwx--- 3 nginx apache 4096 Aug 14 17:09 uploads
沒錯,上傳目錄的存在就是放大權限,如果php沒有寫入權限,那么他就無法上傳圖片。
假設,我們手里有一個0day,現在我要用它來getshell
我會選擇uploads目錄
-rw-r--r-- 1 apache apache 0 Aug 19 18:11 1.php
完美寫入,接著你的站就會被玩壞了,寫入shell后我們可以插件數據庫鏈接密碼,進網站后臺,脫褲,掛黑鏈等等等等
網站里有幾個目錄是默認可以寫入的?在你的網站目錄下執行ls -l
通常plugins themes uploads
這三個目錄都是可以寫入的。
你還有其他目錄可以寫入?趕緊修改權限吧!
加入我們的網站在/var/www/html/root
那么下面的命令是極好的,對于必須要有上傳權限的uploads目錄,我們下面再說
chown -R nginx.apache html
find /var/www/html/root -type d -exec chmod 750 {} \;
find /var/www/html/root -not -type d -exec chmod 640 {} \;
chmod 770 /var/www/html/root/uploads -R
如果你有某些插件也需要寫入權限,給他權限,并認真看下面的內容。
2.執行目錄限制
我們的apache權限有多大呢?相同的網站擁有相同的權限。
默認情況下,我們的apache權限能瀏覽大部分目錄。最要命的問題在于,他可以跨站執行,從你的網站一直接執行到網站二。
我們需要給他一個限制,每個虛擬主機一個單獨的限制,沒錯就是open_basedir。
這里我們需要特別的技巧,每個虛擬機都要限制
這樣虛擬主機將只允許在網站目錄和tmp目錄執行,而不能穿越到其他目錄
在烏云有一篇討論繞過open_basedir
的文章,所以open_basedir
只能讓你更安全而不是徹底安全,所以你還需要往下看。
server {
location ~ .*\.php(\/.*)*$ {
#include pathinfo.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/";
3.PHP的限制
我們想一個另類解決辦法,如何限制webshell的執行?
在php.ini里,我們可以選擇關閉某些不安全的函數
但是由于php這玩意分之多又復雜,這里只能整理出一部分不安全的函數。
直接添加到php.ini最后面即可
disable_functions=exec,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open,ini_alter,dl,popen,pcntl_exec,socket_accept,socket_bind,socket_clear_error,socket_close,socket_connect,socket_create_listen,socket_create_pair,socket_create,socket_get_option,socket_getpeername,socket_getsockname,socket_last_error,socket_listen,socket_read,socket_recv,socket_recvfrom,socket_select,socket_send,socket_sendto,socket_set_block,socket_set_nonblock,socket_set_option,socket_shutdown,socket_strerror,socket_write,stream_socket_server,disk_total_space,disk_free_space,diskfreespace,getrusage,get_current_user,getmyuid,getmypid,dl,leak,listen,chgrp,link,symlink,dlopen,proc_nice,proc_get_stats,proc_terminate,shell_exec,sh2_exec,posix_getpwuid,posix_getgrgid,posix_kill,ini_restore,mkfifo,dbmopen,dbase_open,filepro,filepro_rowcount,posix_mkfifo,putenv,sleep,chmod,chown,chroot,ini_set,phpinfo,proc_get_status,error_log,syslog,readlink,putenv
在看webshell,我們會發現里面空空如也了,并不能執行命令了。
4.webshell寫入與執行
現在我們的網站已經很安全了,他能否更加安全?
現在,我們就要說說我們必須要有執行權限的upload目錄了,nginx同樣提供了解決方案
location ~ /(usr/uploads)/.*\.(php|php5)?$
{
deny all;
}
這個時候我們打開uploads中的php文件會提示403
403 Forbidden
You don't have permission to access the URL on this server. Sorry for the inconvenience.
我們的效果得到驗證,即使寫入也不能執行。
5.必須要寫入權限但是又包含php文件的目錄。
例如我的用的郵件通知插件目錄內有cache和和log目錄,是必須有寫入權限的
這里千萬不要犯懶,直接給CommentToMail
寫入
location ~ /(usr/uploads|usr/plugins/CommentToMail/cache|usr/plugins/CommentToMail/log)/.*\.(php|php5)?$
{
deny all;
}
既可以實現寫入文件,又可以讓php無法執行。
總結,上面的所有配置:
用戶與PHP運行權限分離
nginx:apache
執行目錄限制
open_basedir
PHP函數限制
php.ini
特殊目錄關閉PHP解析
deny all
權限細分
xx|xx|xx
歡迎拍磚,同時 起司靶場v2 上線,完全脫離安全鎖之類的軟件,歡迎測試。
起司靶場v2
*請認真填寫需求信息,我們會在24小時內與您取得聯系。