:如何對(duì)我存放在 /var/www/html/
目錄中的所有文件設(shè)置只讀權(quán)限?
你可以使用 chmod
命令對(duì) Linux/Unix/macOS/OS X/*BSD 操作系統(tǒng)上的所有文件來(lái)設(shè)置只讀權(quán)限。這篇文章介紹如何在 Linux/Unix 的 web 服務(wù)器(如 Nginx、 Lighttpd、 Apache 等)上來(lái)設(shè)置只讀文件權(quán)限。
如何設(shè)置文件為只讀模式
語(yǔ)法為:
### 僅針對(duì)文件 ###
chmod 0444 /var/www/html/*
chmod 0444 /var/www/html/*.php
如何設(shè)置目錄為只讀模式
語(yǔ)法為:
### 僅針對(duì)目錄 ###
chmod 0444 /var/www/html/
chmod 0444 /path/to/your/dir/
# ***************************************************************************
# 假如 web 服務(wù)器的用戶/用戶組是 www-data,文件擁有者是 ftp-data 用戶/用戶組
# ***************************************************************************
# 設(shè)置目錄所有文件為只讀
chmod -R 0444 /var/www/html/
# 設(shè)置文件/目錄擁有者為 ftp-data
chown -R ftp-data:ftp-data /var/www/html/
# 所有目錄和子目錄的權(quán)限為 0445 (這樣 web 服務(wù)器的用戶或用戶組就可以讀取我們的文件)
find /var/www/html/ -type d -print0 | xargs -0 -I {} chmod 0445 "{}"
找到所有 /var/www/html
下的所有文件(包括子目錄),鍵入:
### 僅對(duì)文件有效 ###
find /var/www/html -type f -iname "*" -print0 | xargs -I {} -0 chmod 0444 {}
然而,你需要在 /var/www/html
目錄及其子目錄上設(shè)置只讀和執(zhí)行權(quán)限,如此才能讓 web 服務(wù)器能夠訪問(wèn)根目錄,鍵入:
### 僅對(duì)目錄有效 ###
find /var/www/html -type d -iname "*" -print0 | xargs -I {} -0 chmod 0544 {}
警惕寫權(quán)限
請(qǐng)注意在 /var/www/html/
目錄上的寫權(quán)限會(huì)允許任何人刪除文件或添加新文件。也就是說(shuō),你可能需要設(shè)置一個(gè)只讀權(quán)限給 /var/www/html/
目錄本身。
### web根目錄只讀 ###
chmod 0555 /var/www/html
在某些情況下,根據(jù)你的設(shè)置要求,你可以改變文件的屬主和屬組來(lái)設(shè)置嚴(yán)格的權(quán)限。
### 如果 /var/www/html 目錄的擁有人是普通用戶,你可以設(shè)置擁有人為:root:root 或 httpd:httpd (推薦) ###
chown -R root:root /var/www/html/
### 確保 apache 擁有 /var/www/html/ ###
chown -R apache:apache /var/www/html/
關(guān)于 NFS 導(dǎo)出目錄
你可以在 /etc/exports
文件中指定哪個(gè)目錄應(yīng)該擁有只讀或者讀寫權(quán)限 [1]。這個(gè)文件定義各種各樣的共享在 NFS 服務(wù)器和他們的權(quán)限。如:
# 對(duì)任何人只讀權(quán)限
/var/www/html *(ro,sync)
# 對(duì)192.168.1.10(upload.example.com)客戶端讀寫權(quán)限訪問(wèn)
/var/www/html 192.168.1.10(rw,sync)
關(guān)于用于 MS-Windows客戶端的 Samba(CIFS)只讀共享
要以只讀共享 sales
,更新 smb.conf
,如下:
[sales]
comment = Sales Data
path = /export/cifs/sales
read only = Yes
guest ok = Yes
關(guān)于文件系統(tǒng)表(fstab)
你可以在 Unix/Linux 上的 /etc/fstab
文件中配置掛載某些文件為只讀模式。
你需要有專用分區(qū),不要設(shè)置其他系統(tǒng)分區(qū)為只讀模式。
如下在 /etc/fstab
文件中設(shè)置 /srv/html
為只讀模式。
/dev/sda6 /srv/html ext4 ro 1 1
你可以使用 mount
命令重新掛載分區(qū)為只讀模式[2](使用 root 用戶)
# mount -o remount,ro /dev/sda6 /srv/html
或者
# mount -o remount,ro /srv/html
上面的命令會(huì)嘗試重新掛載已掛載的文件系統(tǒng)到 /srv/html
上。這是改變文件系統(tǒng)掛載標(biāo)志的常用方法,特別是讓只讀文件改為可寫的。這種方式不會(huì)改變?cè)O(shè)備或者掛載點(diǎn)。讓文件變得再次可寫,鍵入:
# mount -o remount,rw /dev/sda6 /srv/html
或
# mount -o remount,rw /srv/html
Linux:chattr 命令
你可以在 Linux 文件系統(tǒng)上使用 chattr
命令改變文件屬性為只讀[3],如:
chattr +i /path/to/file.php
TML 中使用 <input> 元素表示單行輸入框和 <textarea> 元素表示多行文本框。
HTML中使用的 <input> 元素在 JavaScript 中對(duì)應(yīng)的是 HTMLInputElement 類型。HTMLInputElement 繼承自 HTMLElement 接口:
interface HTMLInputElement extends HTMLElement {
...
}
HTMLInputElement 類型有一些獨(dú)有的屬性和方法:
而在上述介紹 HTMLInputElement 類型中的屬性時(shí),type 屬性要特別關(guān)注一下,因?yàn)楦鶕?jù) type 屬性的改變,可以改變<input>的屬性。
類型 | 描述 |
text | 文本輸入 |
password | 密碼輸入 |
submit | 表單數(shù)據(jù)提交 |
button | 按鈕 |
radio | 單選框 |
checkbox | 復(fù)選框 |
file | 文件 |
hidden | 隱藏的字段 |
image | 定義圖像作為提交按鈕 |
reset | 重置按鈕 |
省略 type 屬性與 type="text"效果一樣, <input> 元素顯示為文本框。
當(dāng) type 的值為text/password/number/時(shí),會(huì)有以下屬性對(duì) <input> 元素有效。
屬性 | 類型 | 描述 |
autocomplete | string | 字符串on或off,表示<input>元素的輸入內(nèi)容可以被瀏覽器自動(dòng)補(bǔ)全。 |
maxLength | long | 指定<input>元素允許的最多字符數(shù)。 |
size | unsigned long | 表示<input>元素的寬度,這個(gè)寬度是以字符數(shù)來(lái)計(jì)量的。 |
pattern | string | 表示<input>元素的值應(yīng)該滿足的正則表達(dá)式 |
placeholder | string | 表示<input>元素的占位符,作為對(duì)元素的提示。 |
readOnly | boolean | 表示用戶是否可以修改<input>的值。 |
min | string | 表示<input>元素的最小數(shù)值或日期。 |
max | string | 表示<input>元素的最大數(shù)值或日期。 |
selectionStart | unsigned long | 表示選中文本的起始位置。如果沒(méi)有選中文本,返回光標(biāo)在<input>元素內(nèi)部的位置。 |
selectionEnd | unsigned long | 表示選中文本的結(jié)束位置。如果沒(méi)有選中文本,返回光標(biāo)在<input>元素內(nèi)部的位置。 |
selectionDirection | string | 表示選中文本的方向。可能的值包括forward、backward、none。 |
下面創(chuàng)建一個(gè) type="text" ,一次顯示 25 個(gè)字符,但最多允許顯示 50 個(gè)字符的文本框:
<input type="text" size="25" maxlength="50" value="initial value">
HTML 使用的 <textarea> 元素在 JavaScript 中對(duì)應(yīng)的是 HTMLTextAreaElement 類型。HTMLTextAreaElement類型繼承自 HTMLElement 接口:
interface HTMLTextAreaElement extends HTMLElement {
...
}
HTMLTextAreaElement 類型有一些獨(dú)有的屬性和方法:
下面創(chuàng)建一個(gè)高度為 25,寬度為 5 的 <textarea> 多行文本框。它與 <input> 不同的是,初始值顯示在 <textarea>...</textarea> 之間:
<textarea rows="25" cols="5">initial value</textarea>
注意:處理文本框值的時(shí)候最好不要使用 DOM 方法,而應(yīng)該使用 value 屬性。
<input> 與 <textarea> 都支持 select() 方法,該方法用于選中文本框中的所有內(nèi)容。該方法的語(yǔ)法為:
select(): void
下面看一個(gè)示例:
let textbox = document.forms[0].elements["input-box"];
textbox.select();
也可以在文本框獲得焦點(diǎn)時(shí),選中文本框的內(nèi)容:
textbox.addEventListener("focus", (event) => {
event.target.select();
});
當(dāng)選中文本框中的文本或使用 select() 方法時(shí),會(huì)觸發(fā) select 事件。
let textbox = document.forms[0].elements["textbox1"];
textbox.addEventListener("select", (event) => {
console.log(`Text selected: ${textbox.value}`);
});
HTML5 對(duì) select 事件進(jìn)行了擴(kuò)展,通過(guò) selectionStart 和 selectionEnd 屬性獲取文本選區(qū)的起點(diǎn)偏移量和終點(diǎn)偏移量。如下所示:
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart,
textbox.selectionEnd);
}
注意:在 IE8 及更早版本不支持這兩個(gè)屬性。
HTML5 提供了 setSelectionRange() 方法用于選中部分文本:
setSelectionRange(start, end, direction): void;
下面看一個(gè)例子:
<input type="text" id="text-sample" size="20" value="Hello World!">
<button onclick="selectText()">選中部分文本</button>
<script>
function selectText() {
let input = document.getElementById("text-sample");
input.focus();
input.setSelectionRange(4, 8); // o Wo
}
</script>
如果想要看到選中效果,必須讓文本框獲得焦點(diǎn)。
不同文本框經(jīng)常需要保證輸入特定類型或格式的數(shù)據(jù),或許數(shù)據(jù)需要包含特定字符或必須匹配某個(gè)特定模式。而文本框并未提供驗(yàn)證功能,因此要配合 JavaScript 腳本實(shí)現(xiàn)輸入過(guò)濾功能。
有些輸入框需要出現(xiàn)或不出現(xiàn)特定字符。如果想要將輸入框變成只讀的,只需要使用 preventDefault()方法將按鍵都屏蔽:
input.addEventListener("keypress", (event) => {
event.preventDefault();
});
而要屏蔽特定字符,就需要檢查事件的 charCode 屬性。如下所示,使用正則表達(dá)式實(shí)現(xiàn)只允許輸入數(shù)字的輸入框:
input.addEventListener("keypress", (event) => {
if (!/\d/.test(event.key)) {
event.preventDefault();
}
});
還有一個(gè)問(wèn)題需要處理:復(fù)制、粘貼及涉及Ctrl 鍵的其他功能。在除IE 外的所有瀏覽器中,前面代碼會(huì)屏蔽快捷鍵Ctrl+C、Ctrl+V 及其他使用Ctrl 的組合鍵。因此,最后一項(xiàng)檢測(cè)是確保沒(méi)有按下Ctrl鍵,如下面的例子所示:
textbox.addEventListener("keypress", (event) => {
if (!/\d/.test(String.fromCharCode(event.charCode)) &&
event.charCode > 9 &&
!event.ctrlKey){
event.preventDefault();
}
});
最后這個(gè)改動(dòng)可以確保所有默認(rèn)的文本框行為不受影響。這個(gè)技術(shù)可以用來(lái)自定義是否允許在文本框中輸入某些字符。
IE 是第一個(gè)實(shí)現(xiàn)了剪切板相關(guān)的事件以及通過(guò)JavaScript訪問(wèn)剪切板數(shù)據(jù)的瀏覽器,其它瀏覽器在后來(lái)也都支持了相同的事件和剪切板的訪問(wèn),后來(lái) HTML5 將其納入了規(guī)范。以下是與剪切板相關(guān)的 6 個(gè)事件:
剪切板事件的行為及相關(guān)對(duì)象會(huì)因?yàn)g覽器而異。在 Safari、Chrome 和 Firefox 中,beforecopy、beforecut 和 beforepaste 事件只會(huì)在顯示文本框的上下文菜單時(shí)觸發(fā),但 IE 不僅在這種情況下觸發(fā),也會(huì)在 copy、cut 和 paste 事件在所有瀏覽器中都會(huì)按預(yù)期觸發(fā)。
在實(shí)際的事件發(fā)生之前,通過(guò)beforecopy、beforecut 和 beforepaste 事件可以在向剪貼板發(fā)送或從中檢索數(shù)據(jù)前修改數(shù)據(jù)。不過(guò),取消這些事件并不會(huì)取消剪貼板操作。要阻止實(shí)際的剪貼板操作,必須取消 copy、cut和 paste 事件。
剪貼板的數(shù)據(jù)通過(guò) clipboardData 對(duì)象來(lái)獲取,且clipboardData 對(duì)象提供 3 個(gè)操作數(shù)據(jù)的方法:
而 clipboardData 對(duì)象在 IE 中使用 window 獲取,在 Firefox、Safari 和 Chrome 中使用 event 獲取。為防止未經(jīng)授權(quán)訪問(wèn)剪貼板,只能在剪貼板事件期間訪問(wèn) clipboardData 對(duì)象;IE 會(huì)在任何時(shí)候都暴露 clipboardData 對(duì)象。因此,要兼容兩者,最好在剪貼板事件期間使用該對(duì)象。
function getClipboardText(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
}
function setClipboardText (event, value){
if (event.clipboardData){
return event.clipboardData.setData("text/plain", value);
} else if (window.clipboardData){
return window.clipboardData.setData("text", value);
}
}
如果文本框只有數(shù)字,那剪貼時(shí),就需要使用paste事件檢查剪貼板上的文本是否無(wú)效。如果無(wú)效,可以取消默認(rèn)行為:
input.addEventListener("paste", (event) => {
let text = getClipboardText(event);
if (!/^\d*$/.test(text)){
event.preventDefault();
}
});
注意:Firefox、Safari和Chrome只允許在onpaste事件中訪問(wèn)getData()方法。
在 JavaScript 中,可以用在當(dāng)前字段完成時(shí)自動(dòng)切換到下一個(gè)字段的方式來(lái)增強(qiáng)表單字段的易用性。比如,常用手機(jī)號(hào)分為國(guó)家好加手機(jī)號(hào)。因此,我們?cè)O(shè)置 2 個(gè)文本框:
<form>
<input type="text" name="phone1" id="phone-id-1" maxlength="4">
<input type="text" name="phone2" id="phone-id-2" maxlength="11">
</form>
當(dāng)文本框輸入到最大允許字符數(shù)后,就把焦點(diǎn)移到下一個(gè)文本框,這樣可以增加表單的易用性并加速數(shù)據(jù)輸入。如下所示:
<script>
function tabForward(event){
let target = event.target;
if (target.value.length == target.maxLength){
let form = target.form;
for (let i = 0, len = form.elements.length; i < len; i++) {
if (form.elements[i] == target) {
if (form.elements[i+1]) {
form.elements[i+1].focus();
}
return;
}
}
}
}
let inputIds = ["phone-id-1", "phone-id-2"];
for (let id of inputIds) {
let textbox = document.getElementById(id);
textbox.addEventListener("keyup", tabForward);
}
</script>
這里,tabForward() 函數(shù)通過(guò)比較用戶輸入文本的長(zhǎng)度與 maxLength 屬性的值來(lái)檢測(cè)輸入是否達(dá)到了最大長(zhǎng)度。如果兩者相等,就通過(guò)循環(huán)表中的元素集合找到當(dāng)前文本框,并把焦點(diǎn)設(shè)置到下一個(gè)元素。
注意:上面的代碼只適用于之前既定的標(biāo)記,沒(méi)有考慮可能存在的隱藏字段。
HTML5 新增了一些表單提交前,瀏覽器會(huì)基于指定的規(guī)則進(jìn)行驗(yàn)證,并在出錯(cuò)時(shí)顯示適當(dāng)?shù)腻e(cuò)誤信息。而驗(yàn)證會(huì)基于某些條件應(yīng)用到表單字段中。
表單字段中添加 required 屬性,用于標(biāo)注該字段是必填項(xiàng),不填則無(wú)法提交。該屬性適用于<input>、<textarea>和<select>。如下所示:
<input type="text" name="account" required>
也可以通過(guò) JavaScript 檢測(cè)對(duì)應(yīng)元素的 required 屬性來(lái)判斷表單字段是否為必填項(xiàng):
let isRequired = document.forms[0].elements["account"].required;
也可以檢測(cè)瀏覽器是否支持 required 屬性:
let isRequiredSupported = "required" in document.createElement("input");
注意:不同瀏覽器處理必填字段的機(jī)制不同。Firefox、Chrome、IE 和Opera 會(huì)阻止表單提交并在相應(yīng)字段下面顯示有幫助信息的彈框,而Safari 什么也不做,也不會(huì)阻止提交表單。
HTML5 為 <input> 元素增加了幾個(gè)新的 type 值。如下所示:
類型 | 描述 |
number | 數(shù)字值的輸入 |
date | 日期輸入 |
color | 顏色輸入 |
range | 一定范圍內(nèi)的值的輸入 |
month | 允許用戶選擇月份和年份 |
week | 允許用戶選擇周和年份 |
time | 允許用戶選擇時(shí)間(無(wú)時(shí)區(qū)) |
datetime | 允許用戶選擇日期和時(shí)間(有時(shí)區(qū)) |
datetime-local | 允許用戶選擇日期和時(shí)間(無(wú)時(shí)區(qū)) |
電子郵件地址的輸入 | |
search | 搜索(表現(xiàn)類似常規(guī)文本) |
tel | 電話號(hào)碼的輸入 |
url | URL地址的輸入 |
這些輸入表名字段應(yīng)該輸入的數(shù)據(jù)類型,并且提供了默認(rèn)驗(yàn)證。如下所示:
<input type="email" name="email">
<input type="url" name="homepage">
要檢測(cè)瀏覽器是否支持新類型,可以在 JavaScript 中創(chuàng)建 <input> 并設(shè)置 type 屬性,之后讀取它即可。老版本中會(huì)將我只類型設(shè)置為 text,而支持的會(huì)返回正確的值。如下所示:
let input = document.createElement("input");
input.type = "email";
let isEmailSupported = (input.type == "email");
而上面介紹的幾個(gè)如 number/range/datetime/datetime-local/date/month/week/time 幾個(gè)填寫數(shù)字的類型,都可以指定 min/max/step 等幾個(gè)與數(shù)值有關(guān)的屬性。step 屬性用于規(guī)定合法數(shù)字間隔,如 step="2",則合法數(shù)字應(yīng)該為 0、2、4、6,依次類推。如下所示:
<input type="number" min="0" max="100" step="5" name="count">
上面的例子是<input>中只能輸入從 0 到 100 中 5 的倍數(shù)。
也可以使用 stepUp() 和 stepDown() 方法對(duì) <input> 元素中的值進(jìn)行加減,它倆會(huì)接收一個(gè)可選參數(shù),用于表示加減的數(shù)值。如下所示:
input.stepUp(); // 加1
input.stepUp(5); // 加5
input.stepDown(); // 減1
input.stepDown(10); // 減10
HTML5 還為文本添加了 pattern 屬性,用于指定一個(gè)正則表達(dá)式。這樣就可以自己設(shè)置 <input> 元素的輸入模式了。如下所示:
<input type="text" pattern="\d+" name="count">
注意模式的開頭和末尾分別假設(shè)有^和$。這意味著輸入內(nèi)容必須從頭到尾都嚴(yán)格與模式匹配。
與新增的輸入類型一樣,指定 pattern 屬性也不會(huì)阻止用戶輸入無(wú)效內(nèi)容。模式會(huì)應(yīng)用到值,然后瀏覽器會(huì)知道值是否有效。通過(guò)訪問(wèn) pattern 屬性可以讀取模式:
let pattern = document.forms[0].elements["count"].pattern;
使用如下代碼可以檢測(cè)瀏覽器是否支持pattern 屬性:
let isPatternSupported = "pattern" in document.createElement("input");
HTML5 新增了 checkValidity() 方法,用來(lái)檢測(cè)表單中任意給定字段是否有效。而判斷的條件是約束條件,因此必填字段如果沒(méi)有值會(huì)被視為無(wú)效,字段值不匹配 pattern 屬性也會(huì)被視為無(wú)效。如下所示:
if (document.forms[0].elements[0].checkValidity()){
// 字段有效,繼續(xù)
} else {
// 字段無(wú)效
}
要檢查整個(gè)表單是否有效,可以直接在表單上調(diào)用checkValidity()方法。這個(gè)方法會(huì)在所有字段都有效時(shí)返回true,有一個(gè)字段無(wú)效就會(huì)返回false:
if(document.forms[0].checkValidity()){
// 表單有效,繼續(xù)
} else {
// 表單無(wú)效
}
validity 屬性會(huì)返回一個(gè)ValidityState 對(duì)象,表示 <input> 元素的校驗(yàn)狀態(tài)。返回的對(duì)象包含一些列的布爾值的屬性:
因此,通過(guò) validity 屬性可以檢查表單字段的有效性,從而獲取更具體的信息,如下所示:
if (input.validity && !input.validity.valid){
if (input.validity.valueMissing){
console.log("請(qǐng)指定值.")
} else if (input.validity.typeMismatch){
console.log("請(qǐng)指定電子郵件地址.");
} else {
console.log("值無(wú)效.");
}
}
通過(guò)指定 novalidate 屬性可以禁止對(duì)表單進(jìn)行任何驗(yàn)證:
<form method="post" action="/signup" novalidate>
<!-- 表單元素 -->
</form>
也可以在 JavaScript 通過(guò) noValidate 屬性設(shè)置,為 true 表示屬性存在,為 false 表示屬性不存在:
document.forms[0].noValidate = true; // 關(guān)閉驗(yàn)證
如果一個(gè)表單中有多個(gè)提交按鈕,那么可以給特定的提交按鈕添加formnovalidate 屬性,指定通過(guò)該按鈕無(wú)需驗(yàn)證即可提交表單:
<form method="post" action="/foo">
<!-- 表單元素 -->
<input type="submit" value="注冊(cè)提交">
<input type="submit" formnovalidate name="btnNoValidate"
value="沒(méi)有驗(yàn)證的提交按鈕">
</form>
也可以使用 JavaScript 設(shè)置 formNoValidate 屬性:
// 關(guān)閉驗(yàn)證
document.forms[0].elements["btnNoValidate"].formNoValidate = true;
以上總結(jié)了 <input> 和 <textarea> 兩個(gè)元素的一些功能,主要是 <input> 元素可以通過(guò)設(shè)置 type 屬性獲取不同類型的輸入框,可以通過(guò)監(jiān)聽鍵盤事件并檢測(cè)要插入的字符來(lái)控制文本框的內(nèi)容。
還有一些與剪貼板相關(guān)的事件,并對(duì)剪貼的內(nèi)容進(jìn)行檢測(cè)。還介紹了一些 HTML5 新增的屬性和方法和新增的更多的 <input> 元素的類型,和一些與驗(yàn)證相關(guān)的屬性和方法。
隨著網(wǎng)絡(luò)的廣泛連接和數(shù)據(jù)的海量增長(zhǎng),我們面臨著越來(lái)越多的安全風(fēng)險(xiǎn)。
國(guó)家有關(guān)部門為了進(jìn)一步保護(hù)加強(qiáng)信息安全,在《中華人民共和國(guó)網(wǎng)絡(luò)安全法》中規(guī)定,網(wǎng)絡(luò)運(yùn)營(yíng)者應(yīng)當(dāng)按照網(wǎng)絡(luò)安全等級(jí)保護(hù)制度的要求,履行安全保護(hù)義務(wù),保障網(wǎng)絡(luò)免受干擾、破壞或者未經(jīng)授權(quán)的訪問(wèn),防止網(wǎng)絡(luò)數(shù)據(jù)泄露或者被竊取、篡改。
在等級(jí)保護(hù)規(guī)范《GBT 25070-2019 信息安全技術(shù)網(wǎng)絡(luò)安全等級(jí)保護(hù)安全設(shè)計(jì)技術(shù)要求》中,明確要求用戶數(shù)據(jù)完整性保護(hù),可采用常規(guī)校驗(yàn)機(jī)制,檢驗(yàn)存儲(chǔ)的用戶數(shù)據(jù)的完整性,以發(fā)現(xiàn)其完整性是否被破壞。
企業(yè)網(wǎng)站是企業(yè)的重要數(shù)字門戶,網(wǎng)頁(yè)防篡改正是為了防止網(wǎng)站內(nèi)容被惡意篡改破壞,確保網(wǎng)站數(shù)據(jù)的真實(shí)性和完整性,滿足等級(jí)保護(hù)用戶數(shù)據(jù)完整性保護(hù)要求。
同時(shí),網(wǎng)頁(yè)防篡改也有助于維護(hù)企業(yè)網(wǎng)站聲譽(yù)、保障業(yè)務(wù)正常運(yùn)行、避免法律責(zé)任。
網(wǎng)頁(yè)防篡改技術(shù)分析
網(wǎng)頁(yè)被篡改原因分析
網(wǎng)頁(yè)被篡改通常有以下幾種方式:
通過(guò)服務(wù)器漏洞: 攻擊者利用服務(wù)器操作系統(tǒng)或應(yīng)用程序(如 Web 服務(wù)器軟件)的安全漏洞,獲取對(duì)服務(wù)器的非法訪問(wèn)權(quán)限,進(jìn)而修改網(wǎng)頁(yè)文件。
賬號(hào)密碼被竊取: 如果網(wǎng)站管理員或相關(guān)賬號(hào)的密碼強(qiáng)度不夠或被泄露,攻擊者獲取到這些賬號(hào)后,可以登錄到后臺(tái)管理系統(tǒng)進(jìn)行網(wǎng)頁(yè)篡改。
惡意軟件感染: 服務(wù)器或網(wǎng)站所在的系統(tǒng)感染了惡意軟件,這些惡意軟件可能會(huì)修改網(wǎng)頁(yè)文件。
網(wǎng)絡(luò)連接被劫持: 攻擊者通過(guò)網(wǎng)絡(luò)劫持技術(shù),在數(shù)據(jù)傳輸過(guò)程中篡改網(wǎng)頁(yè)內(nèi)容。
內(nèi)部人員篡改: 網(wǎng)站內(nèi)部的工作人員由于各種原因,故意篡改網(wǎng)頁(yè)內(nèi)容。
要防止網(wǎng)頁(yè)被篡改,需要 加強(qiáng)服務(wù)器安全防護(hù)、定期更新軟件、使用強(qiáng)密碼、加強(qiáng)網(wǎng)絡(luò)安全監(jiān)控 等措施。
網(wǎng)頁(yè)防篡改主流方案
對(duì)于已經(jīng)被入侵的系統(tǒng),如何防止網(wǎng)頁(yè)被篡改,主要有以下技術(shù)手段:
系統(tǒng)文件過(guò)濾驅(qū)動(dòng): 在操作系統(tǒng)內(nèi)核層對(duì)文件操作進(jìn)行監(jiān)控和過(guò)濾,實(shí)時(shí)阻止非法的文件寫入和修改。
事件觸發(fā)機(jī)制: 設(shè)定特定事件(如文件修改事件)觸發(fā)檢測(cè)和保護(hù)動(dòng)作。
數(shù)字水印技術(shù): 在網(wǎng)頁(yè)中嵌入數(shù)字水印,一旦網(wǎng)頁(yè)被篡改,水印信息會(huì)發(fā)生變化,從而被檢測(cè)到。
加密技術(shù): 對(duì)網(wǎng)頁(yè)文件進(jìn)行加密,使攻擊者難以直接修改加密后的內(nèi)容。
完整性校驗(yàn)技術(shù): 如哈希算法,計(jì)算網(wǎng)頁(yè)文件的特征值,通過(guò)對(duì)比特征值來(lái)判斷是否被篡改。
本文將介紹在 Amazon Web Services 上,如何使用系統(tǒng)能力以及 Amazon Web Services 提供的服務(wù)能力,實(shí)現(xiàn)網(wǎng)頁(yè)防篡改。
Amazon EC2 篡改防護(hù)
如果我們的網(wǎng)站業(yè)務(wù)直接部署于 Amazon EC2 系統(tǒng)中,為了確保內(nèi)容不被篡改,最簡(jiǎn)單的辦法就是讓系統(tǒng)內(nèi)文件只讀。 但是只讀后文件無(wú)法更新,所以,我們還需要對(duì)應(yīng)的更新方案。
對(duì)于掛載后,我們也需要持續(xù)的監(jiān)控文件是否有變化。如果有,要及時(shí)發(fā)現(xiàn)。
下面我們分別針對(duì) Linux 與 Windows 系統(tǒng)進(jìn)行介紹。
Amazon EC2 Linux 篡改防護(hù)
Amazon EC2 Linux 系統(tǒng)預(yù)防篡改
Amazon EC2 Linux 系統(tǒng)創(chuàng)建內(nèi)容盤。
1.在 Amazon Web Services 控制臺(tái),我們先創(chuàng)建一塊新的 Amazon EBS 硬盤,具體操作流程參考創(chuàng)建 Amazon EBS 卷。 https://docs.amazonaws.cn/zh_cn/ebs/latest/userguide/ebs-creating-volume.html
2.創(chuàng)建成功后,將創(chuàng)建的 Amazon EBS 硬盤,附加到我們的內(nèi)容服務(wù)器,具體流程參考將 Amazon EBS 卷掛載到實(shí)例。 https://docs.aws.amazon.com/zh_cn/ebs/latest/userguide/ebs-attaching-volume.html
3.掛載完成后,還需要在 Linux 系統(tǒng)內(nèi)對(duì) Amazon EBS 卷進(jìn)行分區(qū)、格式化、掛載等操作,具體流程請(qǐng)參考使 Amazon EBS 卷可供使用。 https://docs.amazonaws.cn/zh_cn/ebs/latest/userguide/ebs-using-volumes.html
4.之后,我們就可以使用 Amazon EBS 卷進(jìn)行讀寫操作,編輯我們的網(wǎng)站內(nèi)容,編輯完成后,即可對(duì)該 Amazon EBS 卷進(jìn)行快照操作,創(chuàng)建快照的操作參考創(chuàng)建 Amazon EBS 快照。 https://docs.aws.amazon.com/zh_cn/ebs/latest/userguide/ebs-creating-snapshot.html
5.創(chuàng)建好的快照,就是我們后面網(wǎng)站內(nèi)容的“模版”,通過(guò)該快照創(chuàng)建 Amazon EBS,實(shí)現(xiàn)內(nèi)容的發(fā)布。
Amazon EC2 Linux 系統(tǒng)只讀掛載。
1.通過(guò)之前創(chuàng)建好的快照,創(chuàng)建 Amazon EBS 卷,過(guò)程可以參考官方文檔從快照創(chuàng)建卷。 https://docs.amazonaws.cn/zh_cn/ebs/latest/userguide/ebs-creating-volume.html#ebs-create-volume-from-snapshot
2.然后,與前文一致,將 Amazon EBS 卷掛載到實(shí)例。
3.掛載完成后,在 Linux 系統(tǒng)內(nèi),我們還需要進(jìn)行加載。為了保護(hù)內(nèi)容,我們采用只讀掛載的方式。
1.# 確保目錄存在
2.sudo mkdir -p /mnt/protect-content
3.# 確保沒(méi)有掛載其他盤
4.sudo umount /mnt/protect-content
5.# `/dev/nvm1p1` 更換為實(shí)際device node
6.sudo mount -o ro /dev/nvm1p1 /mnt/protect-content
4.掛載完成,只讀的內(nèi)容即可供外部訪問(wèn)。由于是只讀掛載,內(nèi)容不可被修改。
Amazon EC2 Linux 系統(tǒng)內(nèi)容更新。
未來(lái),我們肯定希望對(duì)內(nèi)容進(jìn)行更新。更新的流程,與創(chuàng)建內(nèi)容、只讀掛載發(fā)布類似。
1.通過(guò)快照創(chuàng)建 Amazon EBS 卷。
2.正常可讀寫方式掛載到內(nèi)容編輯服務(wù)器,在服務(wù)器內(nèi)進(jìn)行內(nèi)容編輯。
3.編輯完成,重新制作 Amazon EBS 卷快照。
4.使用新的 Amazon EBS 卷快照,生成新的 Amazon EBS 卷。
5.將原來(lái)的 Amazon EBS 卷從實(shí)例分離,參考將 Amazon EBS 卷與實(shí)例分離。 https://docs.amazonaws.cn/zh_cn/ebs/latest/userguide/ebs-detaching-volume.html
6.只讀方式,掛載新的 Amazon EBS 卷
7.刪除原來(lái)的 Amazon EBS 卷,參考刪除 Amazon EBS 卷。 https://docs.amazonaws.cn/zh_cn/ebs/latest/userguide/ebs-deleting-volume.html
Amazon EC2 Linux 系統(tǒng)偵測(cè)篡改事件
Inotify 是一種 Linux 內(nèi)核機(jī)制,用于監(jiān)視文件系統(tǒng)中的事件。它允許應(yīng)用程序監(jiān)視文件或目錄的創(chuàng)建、刪除、修改、屬性更改,以及移動(dòng)或重命名等事件。
Inotify 提供了一種高效且可擴(kuò)展的方式,來(lái)監(jiān)視文件系統(tǒng)活動(dòng),并使其成為各種應(yīng)用程序的寶貴工具。
Inotify 有多種應(yīng)用場(chǎng)景,包括:
文件系統(tǒng)監(jiān)控: inotify 可用于監(jiān)視文件系統(tǒng)活動(dòng),例如文件創(chuàng)建、刪除、修改和重命名。這對(duì)于備份應(yīng)用程序、病毒掃描程序和其他需要監(jiān)視文件系統(tǒng)活動(dòng)的應(yīng)用程序很有用。
桌面通知: inotify 可用于在文件或目錄發(fā)生更改時(shí)向用戶發(fā)送桌面通知。這對(duì)于文件共享應(yīng)用程序、同步工具和其他需要通知用戶文件系統(tǒng)活動(dòng)的應(yīng)用程序很有用。
實(shí)時(shí)事件處理: inotify 可用于實(shí)時(shí)處理文件系統(tǒng)事件。這對(duì)于日志記錄應(yīng)用程序、審計(jì)工具和其他需要實(shí)時(shí)響應(yīng)文件系統(tǒng)活動(dòng)的應(yīng)用程序很有用。
Inotify 的特性,使得它在文件保護(hù)、防篡改方面,是最適合的工具。
下面的示例代碼,可用于監(jiān)控 Linux 文件變化,在變化的時(shí)候通知我們,讓我們能第一時(shí)間反應(yīng)、處理:
1.#include <stdio.h>
2.#include <stdlib.h>
3.#include <sys/inotify.h>
4.#include <unistd.h>
5.#include <fcntl.h>
6.#include <string.h>
7.
8.#define EVENT_SIZE? ( sizeof(struct inotify_event) )
9.#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
10.
11.void handle_event(struct inotify_event *event) {
12.? if (event->len) {
13.? ? // Check for specific events (modify, create, delete)
14.? ? if (event->mask IN_MODIFY) {
15.? ? ? printf("File %s in directory was modified.\n", event->name);
16.? ? } else if (event->mask IN_CREATE) {
17.? ? ? printf("File %s was created in directory.\n", event->name);
18.? ? } else if (event->mask IN_DELETE) {
19.? ? ? printf("File %s was deleted from directory.\n", event->name);
20.? ? }
21.? }
22.}
23.
24.int main(int argc, char *argv[]) {
25.? if (argc != 2) {
26.? ? printf("Usage: %s <directory>\n", argv[0]);
27.? ? exit(1);
28.? }
29.
30.? // Open the inotify instance
31.? int fd = inotify_init();
32.? if (fd == -1) {
33.? ? perror("inotify_init");
34.? ? exit(1);
35.? }
36.
37.? // Add a watch on the specified directory
38.? int wd = inotify_add_watch(fd, argv[1], IN_MODIFY | IN_CREATE | IN_DELETE);
39.? if (wd == -1) {
40.? ? perror("inotify_add_watch");
41.? ? exit(1);
42.? }
43.
44.? char buffer[EVENT_BUF_LEN];
45.
46.? // Continuously read events
47.? while (1) {
48.? ? int nread = read(fd, buffer, EVENT_BUF_LEN);
49.? ? if (nread == -1) {
50.? ? ? perror("read");
51.? ? ? exit(1);
52.? ? }
53.
54.? ? int i = 0;
55.? ? while (i < nread) {
56.? ? ? struct inotify_event *event = (struct inotify_event *) buffer[ i ];
57.? ? ? // Check if event refers to the watched directory (avoid subdirectories)
58.? ? ? if (strcmp(event->name, "") == 0) {
59.? ? ? ? continue; // Skip events for the directory itself (empty name)
60.? ? ? }
61.? ? ? handle_event(event);
62.? ? ? i += EVENT_SIZE + event->len;
63.? ? }
64.? }
65.
66.? // Close inotify instance (would never be reached in this example)
67.? close(fd);
68.
69.? return 0;
70.}
滑動(dòng)查看更多
通過(guò)編譯,執(zhí)行該代碼,即可實(shí)現(xiàn)網(wǎng)頁(yè)文件內(nèi)容變更通知:
1.# 編譯代碼
2.gcc -o inotify inotify.c
3.# 運(yùn)行監(jiān)控
4../inotify <dir>
Amazon EC2 Windows 篡改防護(hù)
Amazon EC2 Windows 系統(tǒng)預(yù)防篡改
Amazon EC2 Windows 只讀掛載防篡改與 Linux 基本一致,差異部分在于如何只讀掛載 Amazon EBS 卷。
1.# 關(guān)閉自動(dòng)掛載
2.mountvol.exe /N
3.# 進(jìn)入分區(qū)管理
4.diskpart
5.# 列出磁盤
6.list volume
7.# 根據(jù)上面列出的,選擇分區(qū),替換<X>
8.select volume <X>
9.# 設(shè)置分區(qū)屬性, readonly
10.attributes volume set readonly
11.# 查看結(jié)果
12.detail volume
滑動(dòng)查看更多
其他的,與前文 Linux 系統(tǒng)內(nèi)容類似。
Amazon EC2 Windows 系統(tǒng)偵測(cè)篡改事件
與 Linux 類似,Windows .NET SDK 提供了 FileSystemWatcher 這個(gè)接口。
它是 Windows 中用于監(jiān)視文件系統(tǒng)活動(dòng)的 API。它允許應(yīng)用程序監(jiān)視文件或目錄的創(chuàng)建、刪除、修改、重命名等事件。
我們可以參考官網(wǎng)的例子,編寫對(duì)應(yīng)的應(yīng)用來(lái)監(jiān)控變化。 https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=net-8.0redirectedfrom=MSDN
也可以直接使用一些現(xiàn)有的開源工具, 比如 https://github.com/thekid/inotify-win
Inotify-win 實(shí)現(xiàn)了類似 Linux inotify 的功能,通過(guò)以下命令,即可實(shí)現(xiàn)文件目錄的監(jiān)控通知:
1.inotifywait.exe -r -m <dir>
Amazon S3 篡改防護(hù)
Amazon S3 網(wǎng)站方案
Amazon S3 簡(jiǎn)介
Amazon Simple Storage Service(Amazon S3)是一種對(duì)象存儲(chǔ)服務(wù),提供行業(yè)領(lǐng)先的可擴(kuò)展性、數(shù)據(jù)可用性、安全性和性能。
各種規(guī)模和行業(yè)的客戶都可以使用 Amazon S3 存儲(chǔ)和保護(hù)任意數(shù)量的數(shù)據(jù),用于數(shù)據(jù)湖、網(wǎng)站、移動(dòng)應(yīng)用程序、備份和恢復(fù)、歸檔、企業(yè)應(yīng)用程序、IoT 設(shè)備和大數(shù)據(jù)分析。
可以使用 Amazon S3 托管靜態(tài)網(wǎng)站,還可以將 Amazon S3 與內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)(如 Amazon CloudFront)結(jié)合使用來(lái)交付網(wǎng)頁(yè)。
Amazon S3 作為 Website 先決條件
在將自定義域配置為在 Amazon Web Services 中國(guó)(寧夏)區(qū)域托管 Amazon S3 靜態(tài)網(wǎng)站之前,必須滿足以下先決條件。
取得 ICP 備案
如果域名通過(guò) Amazon Web Services 中國(guó)(寧夏)區(qū)域中,由寧夏西云數(shù)據(jù)科技有限公司(NWCD)運(yùn)營(yíng)的服務(wù)器進(jìn)行公共訪問(wèn),必須通過(guò) NWCD 申請(qǐng) ICP 備案。
配置 Amazon S3 靜態(tài)網(wǎng)站
1.創(chuàng)建域存儲(chǔ)桶和可選的子域存儲(chǔ)桶:
對(duì)于域存儲(chǔ)桶,啟用靜態(tài)網(wǎng)站托管,然后上傳網(wǎng)站內(nèi)容。啟用靜態(tài)網(wǎng)站托管后,域存儲(chǔ)桶會(huì)被分配一個(gè) Amazon S3 網(wǎng)站端點(diǎn),例如 www.example.com.cn.s3-website.cn-north-1.amazonaws.com.cn,使用此網(wǎng)站端點(diǎn)配置 Amazon Route 53 自定義域。
對(duì)于子域存儲(chǔ)桶,在靜態(tài)網(wǎng)站托管下,為對(duì)象配置重定向請(qǐng)求,以重定向至上傳到域存儲(chǔ)桶的網(wǎng)站內(nèi)容。
域存儲(chǔ)桶包含構(gòu)成網(wǎng)站的文件,子域存儲(chǔ)桶會(huì)將請(qǐng)求重新路由到域存儲(chǔ)桶。例如,如果客戶進(jìn)入 www.example.com.cn,子域存儲(chǔ)桶會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到域存儲(chǔ)桶:example.com.cn。
2.清除所有四種 Amazon S3 屏蔽公共訪問(wèn)權(quán)限設(shè)置,以便可以添加允許對(duì)存儲(chǔ)桶進(jìn)行公共讀取訪問(wèn)的存儲(chǔ)桶策略。
3.添加允許對(duì)存儲(chǔ)桶進(jìn)行公共讀取訪問(wèn)的存儲(chǔ)桶策略,將網(wǎng)站暴露給外部進(jìn)行訪問(wèn)。
使用 Amazon Route 53 配置自定義域
完成在 Amazon S3 中配置靜態(tài)網(wǎng)站后,就有了網(wǎng)站端點(diǎn),假設(shè)為 www.example.com.cn.s3-website.cn-north-1.amazonaws.com.cn(www.example.com.cn),可以將自定義域名映射到此端點(diǎn),并通過(guò)自定義域訪問(wèn)網(wǎng)站。
要為域和子域配置別名記錄,請(qǐng)按照以下步驟操作:
1.通過(guò)以下網(wǎng)址打開 Amazon Route 53 控制臺(tái): https://console.aws.amazon.com/route53/
2.請(qǐng)選擇托管區(qū)域。
3.在托管區(qū)域列表中,請(qǐng)選擇與域名匹配的托管區(qū)域的名稱。
4.要為托管區(qū)創(chuàng)建別名記錄,請(qǐng)選擇創(chuàng)建記錄。
5.請(qǐng)選擇切換到向?qū)А?
6.選擇簡(jiǎn)單路由,然后選擇下一步。
7.選擇定義簡(jiǎn)單記錄。
對(duì)于記錄名稱,接受默認(rèn)值。
對(duì)于記錄類型,選擇 CNAME 將流量路由到另一個(gè)域名和某些 Amazon Web Services 資源。
對(duì)于值/流量路由至,選擇根據(jù)記錄類型選擇 IP 地址或其他值。在文本框中,輸入 Amazon S3 網(wǎng)站端點(diǎn):s3-website.cn-north-1.amazonaws.com.cn。
選擇定義簡(jiǎn)單記錄。
8.通過(guò)自定義域名(例如 http://example.com.cn)訪問(wèn)網(wǎng)站,以驗(yàn)證網(wǎng)站和重定向是否有效。
通過(guò) Amazon CloudFront 建立加速緩存
Amazon CloudFront 是 Amazon Web Services 上的 CDN 服務(wù),它可以將 Amazon S3 設(shè)置為分發(fā)的對(duì)象,將 Amazon S3 上的資源,通過(guò) Amazon Web Services 分布在邊緣節(jié)點(diǎn)將內(nèi)容提供給用戶。
同時(shí),Amazon CloudFront 還提供了 Amazon S3 不支持的 HTTPS 協(xié)議,讓前端應(yīng)用更加安全。然而由于 Amazon Web Services 中國(guó)(寧夏)區(qū)域的一些特殊情況,在此使用 Amazon S3 + Amazon CloudFront,需要一些不同于 Global 的額外配置。
1. 建立 Amazon S3 數(shù)據(jù)桶。
注意:需要設(shè)置阻止公開訪問(wèn)。
2. 建立 Amazon Route 53。
紅框內(nèi)輸入已備案的域名。
3. 建立 Amazon CloudFront 分配。
源選擇存放前端資源的 Amazon S3 桶,桶中如果沒(méi)有子文件夾,則留空源路徑輸入框,來(lái)源訪問(wèn)選擇“遺留訪問(wèn)身份”,點(diǎn)擊“建立新的 OAI”,下面選擇“否,我將更新存儲(chǔ)桶策略”。
在備用域名中,添加剛才在 Amazon Route 53 添加的域名,默認(rèn)根對(duì)象填寫 index.html (根 HTML 文件文件名)。
建立完成后,進(jìn)入“源”標(biāo)簽頁(yè),記下 Origin access 的值,如圖紅框所示:
4. 更新 Amazon S3 桶策略并保存。
代碼如下(替換{$ORIGIN_ACCESS_ID}和BUCKET_ARN/*):
1.{
2.? ? "Version": "2012-10-17",
3.? ? "Statement": [
4.? ? ? ? {
5.? ? ? ? ? ? "Effect": "Allow",
6.? ? ? ? ? ? "Principal": {
7.? ? ? ? ? ? ? ? "AWS": "arn:aws-cn:iam::cloudfront:user/CloudFront Origin Access Identity {$ORIGIN_ACCESS_ID}"
8.? ? ? ? ? ? },
9.? ? ? ? ? ? "Action": "s3:GetObject",
10.? ? ? ? ? ? "Resource": “BUCKET_ARN/*"
11.? ? ? ? }
12.? ? ]
13.}
滑動(dòng)查看更多
5. 回到 Amazon Route 53,增加別名。
如果實(shí)用子域名,則需要新增 CNAME 記錄,并在 Amazon CloudFront 的備用域名中,輸入該記錄的完整域名。
全部完成后,等待片刻,即可去設(shè)定的域名測(cè)試效果。
Amazon S3 網(wǎng)站預(yù)防內(nèi)容篡改
Amazon S3 對(duì)象版本
Amazon S3 中的版本控制,是在相同的存儲(chǔ)桶中保留對(duì)象的多個(gè)版本的方法。對(duì)于存儲(chǔ)桶中存儲(chǔ)的每個(gè)對(duì)象,可以使用 Amazon S3 版本控制功能來(lái)保留、檢索和還原它們的各個(gè)版本,從而達(dá)到防止被篡改的效果。
啟用了版本控制的存儲(chǔ)桶,可以恢復(fù)因意外或被外部惡意刪除操作而被篡改的對(duì)象。例如,如果刪除對(duì)象,Amazon S3 會(huì)插入刪除標(biāo)記,而不是永久刪除該對(duì)象。
存儲(chǔ)桶擁有者和所有獲得授權(quán)的 Amazon IAM 用戶,都可以啟用版本控制。
版本 ID
如果為存儲(chǔ)桶啟用版本控制,Amazon S3 會(huì)自動(dòng)為要存儲(chǔ)的對(duì)象生成唯一版本 ID。例如,在一個(gè)存儲(chǔ)桶中,可以擁有兩個(gè)具有相同鍵(對(duì)象名稱)的對(duì)象,但版本 ID 不同,例如 photo.gif(版本 111111)和 photo.gif(版本 121212)。
無(wú)論 Amazon S3 版本控制是否啟用,每個(gè)對(duì)象都有一個(gè)版本 ID。
如果未啟用 Amazon S3 版本控制,Amazon S3 將版本 ID 的值設(shè)置為 null。如果啟用 Amazon S3 版本控制,Amazon S3 會(huì)為對(duì)象分配版本 ID 值。此值將該對(duì)象與同一個(gè)鍵的其他版本區(qū)分開來(lái)。
在現(xiàn)有存儲(chǔ)桶上啟用 Amazon S3 版本控制時(shí),已存儲(chǔ)在存儲(chǔ)桶中的對(duì)象將保持不變。版本 ID(null)、內(nèi)容和權(quán)限保持不變。啟用 Amazon S3 版本控制后,添加到存儲(chǔ)桶的每個(gè)對(duì)象都會(huì)獲得一個(gè)版本 ID,該 ID 將此版本與同一個(gè)鍵的其他版本區(qū)分開來(lái)。
版本控制工作流程
當(dāng)在啟用版本控制的存儲(chǔ)桶中,通過(guò) PUT 放入對(duì)象時(shí),不會(huì)覆蓋非當(dāng)前版本。如下圖所示,當(dāng)將 photo.gif 的新版本 PUT 到一個(gè)已經(jīng)包含同名對(duì)象的存儲(chǔ)桶中時(shí),會(huì)發(fā)生以下行為:
原始對(duì)象(ID = 111111)保留在存儲(chǔ)桶中。
Amazon S3 生成一個(gè)新的版本 ID(121212),并將這個(gè)較新版本的對(duì)象添加到存儲(chǔ)桶中。
使用此功能,如果對(duì)象被意外覆蓋或刪除,則可以檢索對(duì)象的先前版本。
當(dāng) DELETE 對(duì)象時(shí),所有版本都將保留在存儲(chǔ)桶中,而 Amazon S3 將插入刪除標(biāo)記,如下圖所示:
刪除標(biāo)記將成為對(duì)象的當(dāng)前版本。默認(rèn)情況下,GET 請(qǐng)求將檢索最新存儲(chǔ)的版本。在當(dāng)前版本為刪除標(biāo)記時(shí),執(zhí)行 GET Object 請(qǐng)求將返回 404 Not Found 錯(cuò)誤,如下圖所示:
但是,可以通過(guò)指定對(duì)象版本 ID,通過(guò) GET 獲取非當(dāng)前版本的對(duì)象。在下圖中,GET 特定對(duì)象版本 111111。即使該對(duì)象版本不是當(dāng)前版本,Amazon S3 也會(huì)返回它。
有關(guān)更多信息,請(qǐng)參閱從啟用了版本控制的存儲(chǔ)桶中檢索對(duì)象版本。 https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/RetrievingObjectVersions.html
可以通過(guò)指定要?jiǎng)h除的版本來(lái)永久刪除對(duì)象。只有 Amazon S3 存儲(chǔ)桶的擁有者或者授權(quán)的 Amazon IAM 用戶,才能永久刪除某個(gè)版本。如果 DELETE 操作指定了 versionId,則會(huì)永久刪除該對(duì)象版本,Amazon S3 不會(huì)插入刪除標(biāo)記。
可以通過(guò)配置存儲(chǔ)桶,來(lái)啟用多重身份驗(yàn)證(MFA)刪除,從而提升安全性。 對(duì)存儲(chǔ)桶啟用 MFA 刪除時(shí),存儲(chǔ)桶擁有者,必須在任何請(qǐng)求中包含兩種形式的身份驗(yàn)證,以刪除版本或更改存儲(chǔ)桶的版本控制狀態(tài)。
在存儲(chǔ)桶上啟用版本控制
在 Amazon S3 存儲(chǔ)桶上,啟用或禁用版本控制:
1.登錄到 Amazon Web Services Management Console。
2.在存儲(chǔ)桶列表中,請(qǐng)選擇要為其啟用版本控制的存儲(chǔ)桶的名稱。
3.請(qǐng)選擇屬性。
4.在存儲(chǔ)桶版本控制下,請(qǐng)選擇編輯。
5.請(qǐng)選擇 Suspend (暫停) 或 Enable (啟用),然后選擇 Save changes (保存更改)。
Amazon S3 使用對(duì)象鎖
一次寫入多次讀
Amazon S3 Object Lock 是 Amazon S3 的一項(xiàng)功能, 允許使用一次寫入、多次讀取(WORM)模式存儲(chǔ)對(duì)象, 可以在數(shù)據(jù)寫入后不得更改或刪除的情況下,使用 WORM 保護(hù),使用此功能無(wú)需支付額外費(fèi)用。
Amazon S3 Object Lock 提供兩種管理對(duì)象保留的方法, 第一種是保留期,第二種是合法保留。
保留期規(guī)定了對(duì)象保持鎖定狀態(tài)的固定時(shí)間段。在此期間,對(duì)象受 WORM 保護(hù),不能被覆蓋或刪除。保留期的單位可以是天數(shù),也可以是年數(shù),最短為 1 天,沒(méi)有最長(zhǎng)限制。
合法保留提供的保護(hù)與保留期相同,但沒(méi)有過(guò)期日期。相反,合法保留會(huì)一直存在,直到明確將其移除。
使用 Amazon S3 對(duì)象鎖,可以防止對(duì)象在固定時(shí)間內(nèi)被刪除或覆蓋,或直到合法保留被移除。一個(gè)對(duì)象版本可以同時(shí)具有保留期和合法保留。
Amazon S3 偵測(cè)對(duì)象內(nèi)容變更
在對(duì)對(duì)象做了相應(yīng)的安全保護(hù)手段之后,最后我們還需要具備偵測(cè)的能力,即當(dāng)對(duì)象真的被篡改之后,可以收到相應(yīng)的通知,以及時(shí)采取后續(xù)策略。
我們可以利用 Amazon S3 的事件功能結(jié)合 Amazon SNS 服務(wù),將通知發(fā)送到運(yùn)維或相關(guān)人員的郵箱、微信等其他應(yīng)用。
目前, Amazon S3 可以發(fā)布用于以下事件的通知:
新的對(duì)象創(chuàng)建事件
對(duì)象移除事件
還原對(duì)象事件
低冗余存儲(chǔ) (RRS) 對(duì)象丟失事件
復(fù)制事件
Amazon S3 生命周期到期事件
Amazon S3 生命周期轉(zhuǎn)換事件
Amazon S3 Intelligent-Tiering 自動(dòng)歸檔事件
對(duì)象標(biāo)記事件
對(duì)象 ACL PUT 事件
本文以對(duì)象被移除并發(fā)布郵件通知為例進(jìn)行說(shuō)明。
對(duì)象內(nèi)容變化監(jiān)控架構(gòu):
當(dāng)托管在 Amazon S3 當(dāng)中的靜態(tài)網(wǎng)頁(yè)被移除時(shí)(篡改),配置好的 Amazon S3 事件會(huì)偵測(cè)到這個(gè)動(dòng)作,并且通過(guò) Amazon SNS 服務(wù)將通知發(fā)送給訂閱好的郵箱。
實(shí)現(xiàn)過(guò)程
1.上傳托管的靜態(tài)文件。
2.創(chuàng)建 Amazon SNS 通知主題。
這里需要注意的是,為了讓 Amazon S3 event 具有可以調(diào)用 Amazon SNS API 的權(quán)限,需要配置 topic 的 access policy,按照如下樣例進(jìn)行配置:
1.{
2.? ? "Version": "2012-10-17",
3.? ? "Id": "example-ID",
4.? ? "Statement": [
5.? ? ? ? {
6.? ? ? ? ? ? "Sid": "Example SNS topic policy",
7.? ? ? ? ? ? "Effect": "Allow",
8.? ? ? ? ? ? "Principal": {
9.? ? ? ? ? ? ? ? "Service": "s3.amazonaws.com"
10.? ? ? ? ? ? },
11.? ? ? ? ? ? "Action": [
12.? ? ? ? ? ? ? ? "SNS:Publish"
13.? ? ? ? ? ? ],
14.? ? ? ? ? ? "Resource": "SNS-topic-ARN",
15.? ? ? ? ? ? "Condition": {
16.? ? ? ? ? ? ? ? "ArnLike": {
17.? ? ? ? ? ? ? ? ? ? "aws:SourceArn": "arn:aws:s3:*:*:bucket-name"
18.? ? ? ? ? ? ? ? },
19.? ? ? ? ? ? ? ? "StringEquals": {
20.? ? ? ? ? ? ? ? ? ? "aws:SourceAccount": "bucket-owner-account-id"
21.? ? ? ? ? ? ? ? }
22.? ? ? ? ? ? }
23.? ? ? ? }
24.? ? ]
25.}
滑動(dòng)查看更多
3.使用郵箱訂閱主題,完成后的郵箱會(huì)收到郵件確認(rèn),點(diǎn)擊鏈接后完成訂閱主題。
4.在屬性標(biāo)簽配置 Amazon S3 事件,創(chuàng)建事件通知。
5.配置事件通知參數(shù)。
選擇之前創(chuàng)建的 Amazon SNS 主題。
6.測(cè)試刪除文件后,是否能捕獲通知。
總結(jié)
本文介紹在 Amazon Web Services 上,如何在 Amazon EC2 Linux/Windows 系統(tǒng)、Amazon S3 網(wǎng)站托管,實(shí)現(xiàn)網(wǎng)頁(yè)防篡改。
在 Amazon EC2 系統(tǒng)中,可以通過(guò) Amazon EBS Snapshot 只讀掛載實(shí)現(xiàn),同時(shí),通過(guò) inotify 機(jī)制實(shí)現(xiàn)監(jiān)控;在 Amazon S3,可以通過(guò)對(duì)象鎖、對(duì)象版本實(shí)現(xiàn)只讀,通過(guò) Amazon Lambda 實(shí)現(xiàn) Amazon S3 變更事件的通知與自動(dòng)化處理。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。