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 的所有細節(jié)。如果你正或多或少地涉及了 web 應(yīng)用程序開發(fā),那么,我們的 Java 工具和技術(shù)范圍報告揭示了,大多數(shù)(71%)Java 開發(fā)者被歸到了這一類,只是你對 JavaScript 遇到了阻礙。
毫無疑問,你已經(jīng)知道了 Java 和 JavaScript,不管它們有著多么類似的命名,彼此沒有共享太多共通之處。Java 的靜態(tài)類型、符合直接規(guī)律的簡單語法和冗長,與 JavaScript 的動態(tài)、缺乏一致性原則和怪異,有著巨大的不同。
然而,JavaScript 是 web 的編程語言,最近由于 Node.js 和 JVM 自己的 Nashorn JavaScript 引擎的發(fā)展,在服務(wù)器端獲得了相當(dāng)?shù)淖⒁狻?/p>
本文,我不想只是漫談 JavaScript 的好與不好,或重復(fù)任何人都能免費找到的、不計其數(shù)的 JavaScript 教程。我想列出一些有助于理解 JavaScript 做為一種語言的技術(shù)點,并從接近 horse的角度來理解。
我們將在本文包含下列語言級別的技術(shù)點:
另外,你會找到一些工具方面的推薦,沒有這些工具,你是不想著手 JavaScript 項目的,包含了構(gòu)建系統(tǒng)的代碼質(zhì)量分析和測試框架方面的工具。
優(yōu)點
編寫一次,差不多處處運行!
毋庸置疑 JavaScript 是 web 編程語言,是很多其它語言的編譯目標,也是用來證明有時候人們只是想擁有更多自由時間的終極方式。盡管如此,這不是一件壞事。每一臺能夠瀏覽現(xiàn)代網(wǎng)站的電腦都裝備了具有性能和可用的 JavaScript 引擎。最重要的是,JavaScript 代碼可以在后端運行。
內(nèi)置到我們喜愛的 JVM 的、輕量級高性能 JavaScript 運行時 Nashorn,完全能夠解釋 JavaScript 腳本,還能夠解釋項目中帶有 Java 代碼的 JavaScript 腳本。
鑒于每臺電腦運行時都可獲得的自由,JavaScript 成為 Java 體驗的完美延續(xù)。
函數(shù)式編程:一等公民是函數(shù),而不是遞歸
JavaScript 中的函數(shù)是第一類公民,它們是值,可被存儲在變量里、傳遞給其它函數(shù)、在適當(dāng)?shù)臅r候再執(zhí)行。
這打開了函數(shù)式編程世界的大門,這是結(jié)構(gòu)化 JavaScript 編程的完美方式。
注意,JavaScript 里的對象是任何東西的映射,對象的每個特性(attribute)都在同一個映射里:函數(shù)、屬性(property)、構(gòu)造器;易變性帶來了更大的隱患,而對于 Java,你至少能夠確保方法和字段結(jié)構(gòu)在某種程度上是穩(wěn)定的。
反過來,這使得函數(shù)式編程更加有利:涉及到小的、可理解函數(shù)和不變的數(shù)據(jù)結(jié)構(gòu)是在 JavaScript 里運行的方式。
這不是沒有依據(jù)的,下面是在 JavaScript 里定義一個 reduce 函數(shù)的例子,來自于《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 沒有以尾調(diào)用【注1】為特色,這意味著每個函數(shù)的遞歸版本都將用到棧的深度,和 Java 一樣,如果你遞歸太深,程序就崩潰。
繼承:就像真實的世界
JavaScript 的繼承是基于原型的。即,你沒有擴展了其它類型的類型,而實際上,你擁有的實例從其它實例繼承了功能。
想象一下,對象A就像一個映射,我們剛才稍微提到了一些、但是用了不同的視角,然后另一個類似映射的對象B從A繼承了一切。
這說明B可以訪問A所有部分:A的方法、字段等等。
在實踐中,我從來沒有看到有人實際使用簡單的基于原型的繼承。通常當(dāng)某人需要繼承時,他只是構(gòu)造類,因此你可以用到所有廣泛的技能,和基于類的繼承的工作模式。
——Rene Saarsoo,XRebel 前端工程師
我不太確定 Java 開發(fā)者應(yīng)該從中吸取什么,但是要當(dāng)心繼承方式的不同,對于父級對象要格外留意、而不要意外地改變整個程序的行為。
任何時候要避免的
列出不可靠的 JavaScript 設(shè)計上的決定比想象中要容易。在 JavaScript 程序中要避免的最明顯的地方就是全局變量的聲明。
注意,在 JavaScript 里,無論什么時候,不使用 var 關(guān)鍵詞定義變量,那么定義的變量被推到了它們被定義的作用域頂端。這意味著,每個用這種方式定義的變量將跑到全局范圍頂部,這會引發(fā)沖突以及你和同事不可預(yù)期的頭痛。
可以開啟 strict 模式。只需在腳本文件頂部寫上“use strict”,那么不經(jīng)意編寫的全局變量聲明將顯示錯誤。
JavaScript 與 Java 另一個重要的不同點在于,前者是動態(tài)類型語言,其真諦是所有東西都可以是任何類型。這很明顯了,實在不能再強調(diào)了:不要針對不同類型的值,去復(fù)用相同的變量。
跟蹤剛開始是個 string 類型的變量,但是現(xiàn)在它成了浮點數(shù)、或者函數(shù)了,相信我!
還有,我不想太深入類型和布爾值的討論,但是要警惕 JavaScript 引擎扔給你的隱式類型轉(zhuǎn)換。
搞定工作的小提示
正如我上面提到的,在編程上要更加注意這種語言的語法和怪癖,而不僅僅是知道。項目很少由于語言的不足而失敗,更多的失敗是與總體項目框架不足有關(guān)。下面是有助于你交付項目的一些工具。
靜態(tài)代碼分析
大部分項目是不同的,其復(fù)雜度和需求導(dǎo)致了大量的細節(jié),你該如何著手代碼庫呢。盡管如此,在所有地方都有一致性的目標,那就是代碼質(zhì)量。
是的,代碼質(zhì)量,對于任何開發(fā)者來說,最重要的工作就是交付。但是不要在質(zhì)量上妥協(xié),不要對你提交的代碼感到不自信就不情愿與同事分享。
幸運的是,JavaScript 有一套得體的解決方案——JSHint。JSHint 是為 JavaScript 量身打造的靜態(tài)分析工具,與應(yīng)用于 Java 代碼的 FindBug 類似。JSHint 可以在你的代碼庫運行,并高亮出可疑的或有問題的地方,即使你不會馬上產(chǎn)生 bug,但這些地方將來變得難以維護。在項目中支持它相當(dāng)簡單。幫自己一個忙——如果你在寫 JavaScript 代碼,就用 JSHint 讓它更安全、少一些尷尬。
REPL
REPL 代表“讀取-求值-輸出”循環(huán)(Read-Eval-Print Loop)【注2】,是很多動態(tài)語言的強大工具。如果你看過 Scala 或 Groovy,你一定能夠理解這個概念。
激活 JavaScript REPL 的一種途徑是打開瀏覽器的控制臺,它產(chǎn)生了對 JavaScript 代碼求值的界面。
另一個比較方便的工具是 jjs,它捆綁在 JDK1.8。
它是命令行工具,允許你訪問 JDK 中的 Nashorn JavaScript 引擎,完全有能力執(zhí)行那些甚至最為嚴格的 JavaScript 腳本。
測試
對于任何一個項目,你都想運行一些測試。測試對于動態(tài)類型的語言尤為重要,最好選擇一種測試框架。我推薦 Jasmine,它是用于測試 JavaScript 的行為驅(qū)動開發(fā)框架。
在 Jasmine,你用 describe 描述測試套件,它阻止了你想測試的代碼訪問。在測試中的代碼完成后,你 expect 一些結(jié)果。
很明顯這里不是要給出教程,但是我想讓你一瞥 JavaScript 代碼看起來是多么地優(yōu)雅。Jasmine 是 JavaScript 項目最好的實踐之一,我們私下在產(chǎn)品開發(fā)中應(yīng)用到了 ZeroTurnaround 項目,尤其是對于富含 JavaScript 的不間斷運行的交互分析器 XRebel。
構(gòu)建工具
最后,你的項目將需要的、比較重要的是構(gòu)建工具。如果你在 Java 項目中使用 JavaScript,請確保你可以避開 Java 構(gòu)建工具,這就差不多足夠了。但是,對于獨立的 JavaScript 項目,沒有必要引入龐然大物—Maven【注3】。
可以考慮的 JavaScript 項目用到的構(gòu)建工具是 GulpJS【注4】。它是基于插件的構(gòu)建系統(tǒng),你可以為其指定任務(wù)。任務(wù)可以是“拷貝 src 目錄下的 .js 文件到 dest”、或“壓縮我的 JavaScript 代碼用于生產(chǎn)環(huán)境”。讓人受到震動的是,GulpJS 把任務(wù)相關(guān)的文件流加入過濾器,因此你可以把上面的兩個任務(wù)加入一次有效的清掃中。
還有大量的可用插件,借助適當(dāng)?shù)臉?gòu)建系統(tǒng),你將發(fā)現(xiàn)項目中的協(xié)作會輕松很多。
結(jié)論
我們只是看到了 JavaScript 的冰山一角,并盡量介紹一些 Java 開發(fā)者在解決 JavaScript 時應(yīng)該知道的概念和工具。自然地,這里沒有提供要學(xué)習(xí)的完整的技術(shù)清單,但是如果你正準備義無反顧地深入 JavaScript 項目,這會幫助你起步,擁抱 JavaScript 的怪癖將有助于你不會頻繁地沮喪。
你了解讓 JS 開發(fā)者走向快樂的秘密或最佳實踐嗎?毫無疑問應(yīng)該去分享!在下面評論或在 Twitter:@shelajev 上與我交談。我樂于聽到你的想法!
作者:前端小攻略
原文:https://my.oschina.net/u/3972188/blog/2999914
略。基本可以從wikipedia上找到解釋。
http://kylin.incubator.apache.org/docs/gettingstarted/terminology.html
在介紹Kylin的各種操作之前,首先讓我們來了解一下Kylin的總體設(shè)計,包括其架構(gòu)、工作流程、和數(shù)據(jù)模型。
Kylin目前是一個MOLAP系統(tǒng),也就是基于對Cube進行預(yù)計算來滿足低延遲的查詢處理。Kylin的數(shù)據(jù)源就是Hive上的表,以星型模式存在。Kylin的離線計算過程(下圖中藍色箭頭的數(shù)據(jù)流)會讀取Hive中的原始數(shù)據(jù),將事實表和維表join起來,然后對各種維度組合(cuboid)進行計算。計算后的cube以key-value的形式存儲在HBase中。
對于SQL請求,Kylin的查詢引擎會判斷SQL能否由HBase中的cube滿足。如果可以,查詢就會轉(zhuǎn)換為HBase的range scan操作,直接獲得結(jié)果數(shù)據(jù),因此能做到秒級的響應(yīng)。對于無法由cube實現(xiàn)的查詢,Kylin可以將查詢路由給Hive執(zhí)行,不過當(dāng)前版本由于性能原因,disable了路由查詢的功能。
使用Kylin的工作流程如下圖所示。
首先,RD創(chuàng)建一個Kylin的項目。一個項目中可以定義多個Cube。
然后,RD需要告訴Kylin需要訪問Hive上的哪些表,即「加載Hive表」。注意這里Kylin只會從Hive Metastore同步表的元信息,并不會讀取表的數(shù)據(jù)。
之后就是最主要的「Cube建模」過程。這一步就是定義Cube的元信息,包括Data Model(指定事實表與維表,以及他們的連接方式)和Cube Model(有哪些維度和度量,如何增量刷新,以及聚集組和rowkey這些高級設(shè)置)。
建模完成之后,RD就可以出發(fā)「Cube構(gòu)建」的動作了。Kylin提供了Cube構(gòu)建管理的REST API,因此Cube的構(gòu)建是可以與現(xiàn)有的調(diào)度系統(tǒng)集成的。
Cube構(gòu)建成功之后,數(shù)據(jù)分析師就可以進行查詢啦,例如進行常見的上卷下鉆操作。下一小節(jié)會提到,Kylin中的Cube對分析師是透明的,分析師還是對Hive中的星型模式查詢,這是Kylin區(qū)別于其他方案(例如生產(chǎn)aggr表和summary表)的主要特征。
在Kylin系統(tǒng)內(nèi),不同角色人員看到的數(shù)據(jù)模型是不同的。下圖說明了其中的區(qū)別。
關(guān)于Cube建模的步驟和操作方式,目前官方教程已經(jīng)比較全面了,故不再贅述。請讀者自行閱讀。
http://kylin.incubator.apache.org/docs/tutorial/create_cube.html
.本文為公測版,一旦發(fā)現(xiàn)有任何錯誤內(nèi)容,會立即進行修復(fù),請持續(xù)關(guān)注本站。
2.本文在正式版之前會不斷的邀請各路黑客大手進行評價測試,歡迎提出異議。
本文僅針對網(wǎng)站部分,本文會對typecho,wordpress進行測試
如果你root端口為22,并且密碼是123456,就沒必要往下看了。
網(wǎng)站環(huán)境為linux tengine/nginx mariaDB,同理,apache也有相關(guān)設(shè)置,百度實驗下即可。
**本文會闡述以下部分
1.基礎(chǔ)權(quán)限控制
2.執(zhí)行目錄限制
3.PHP的限制
4.webshell寫入與執(zhí)行
5.權(quán)限細分,必須寫入的目錄**
1.基礎(chǔ)權(quán)限控制
什么叫基礎(chǔ)權(quán)限?在LNMP架構(gòu)下,nginx+php-fpm架構(gòu)需要什么權(quán)限?
這里我們先來看一下默認權(quán)限
默認我們的nginx運行用戶是nginx,而php-fpm的默認用戶是apache,默認用戶安全嗎?
看一下webshell
uid=48(apache) gid=48(apache) groups=48(apache)
很明顯,我們的默認用戶是apache
我們使用shell新建一個目錄,很明顯,我們是無法建立文件夾的
mkdir: cannot create directory `1': Permission denied
在網(wǎng)上很多教程會告訴我們,吧nginx和phpfpm改成同樣的用戶,我們看看會發(fā)生什么。
[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
沒錯,這是一項愚蠢的決定!
所以默認權(quán)限是安全的嗎?并不是,你忘了上傳目錄,我們看下上傳目錄的權(quán)限
drwxrwx--- 3 nginx apache 4096 Aug 14 17:09 uploads
沒錯,上傳目錄的存在就是放大權(quán)限,如果php沒有寫入權(quán)限,那么他就無法上傳圖片。
假設(shè),我們手里有一個0day,現(xiàn)在我要用它來getshell
我會選擇uploads目錄
-rw-r--r-- 1 apache apache 0 Aug 19 18:11 1.php
完美寫入,接著你的站就會被玩壞了,寫入shell后我們可以插件數(shù)據(jù)庫鏈接密碼,進網(wǎng)站后臺,脫褲,掛黑鏈等等等等
網(wǎng)站里有幾個目錄是默認可以寫入的?在你的網(wǎng)站目錄下執(zhí)行l(wèi)s -l
通常plugins themes uploads
這三個目錄都是可以寫入的。
你還有其他目錄可以寫入?趕緊修改權(quán)限吧!
加入我們的網(wǎng)站在/var/www/html/root
那么下面的命令是極好的,對于必須要有上傳權(quán)限的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
如果你有某些插件也需要寫入權(quán)限,給他權(quán)限,并認真看下面的內(nèi)容。
2.執(zhí)行目錄限制
我們的apache權(quán)限有多大呢?相同的網(wǎng)站擁有相同的權(quán)限。
默認情況下,我們的apache權(quán)限能瀏覽大部分目錄。最要命的問題在于,他可以跨站執(zhí)行,從你的網(wǎng)站一直接執(zhí)行到網(wǎng)站二。
我們需要給他一個限制,每個虛擬主機一個單獨的限制,沒錯就是open_basedir。
這里我們需要特別的技巧,每個虛擬機都要限制
這樣虛擬主機將只允許在網(wǎng)站目錄和tmp目錄執(zhí)行,而不能穿越到其他目錄
在烏云有一篇討論繞過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的執(zhí)行?
在php.ini里,我們可以選擇關(guān)閉某些不安全的函數(shù)
但是由于php這玩意分之多又復(fù)雜,這里只能整理出一部分不安全的函數(shù)。
直接添加到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,我們會發(fā)現(xiàn)里面空空如也了,并不能執(zhí)行命令了。
4.webshell寫入與執(zhí)行
現(xiàn)在我們的網(wǎng)站已經(jīng)很安全了,他能否更加安全?
現(xiàn)在,我們就要說說我們必須要有執(zhí)行權(quán)限的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.
我們的效果得到驗證,即使寫入也不能執(zhí)行。
5.必須要寫入權(quán)限但是又包含php文件的目錄。
例如我的用的郵件通知插件目錄內(nèi)有cache和和log目錄,是必須有寫入權(quán)限的
這里千萬不要犯懶,直接給CommentToMail
寫入
location ~ /(usr/uploads|usr/plugins/CommentToMail/cache|usr/plugins/CommentToMail/log)/.*\.(php|php5)?$
{
deny all;
}
既可以實現(xiàn)寫入文件,又可以讓php無法執(zhí)行。
總結(jié),上面的所有配置:
用戶與PHP運行權(quán)限分離
nginx:apache
執(zhí)行目錄限制
open_basedir
PHP函數(shù)限制
php.ini
特殊目錄關(guān)閉PHP解析
deny all
權(quán)限細分
xx|xx|xx
歡迎拍磚,同時 起司靶場v2 上線,完全脫離安全鎖之類的軟件,歡迎測試。
起司靶場v2
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。