為了討論Web安全,我們首先得有一個網站。我們使用LAMP搭建網站。網路上的教程很多,我們會快速的過一下LAMP基本網站搭建,然後重點討論的是HTTPS。

  1. HTTP

說起Web安全,大家的第一反應是什麼呢?很多人應該馬上想到的就是HTTPS。

為啥呢?因為我們https天天用啊,譬如說現在瀏覽器的左上角,不就是https麼?旁邊還有一把小鎖。

問題是,什麼是HTTPS?HTTPS就是HTTP secure,那接下來的問題是,什麼是HTTP?

HTTP的全稱是Hyper Text Transfer Protocol。什麼是Hyper Text呢?

Hyper Text的名字由來應該是HTML,Hyper Text Markup Language。發明HTTP協議和HTML語言,以及提出URI的人都是同一人。

早期的網頁長這樣:Programming with pcap;

世界上第一個網站中的頁面

Web是由Tim在歐洲核子研究組織(CERN)期間於1989~1991年發明的,初始目的是互聯CERN內部的文檔。在1990年10月之前,他實現了三種基礎技術:命名方案(URI),通信協議(HTTP)和用於創建網頁(HTML)的語言,這些技術至今仍然是當今網路的基礎。同年12月,Tim以自己的NeXT電腦為伺服器,架設了人類歷史上第一個網站,網站域名為Info.cern.ch,至今還保留著。也即,他一人發明瞭萬維網、第一個網路瀏覽器、以及允許網路擴展的基本協議和演算法。

HTML我們留著後面討論,HTTP我們使用兩個操作來理解一下。

第一個是直接使用瀏覽器,F12,打開console。我們可以看到類似於下面的內容。一個是Request:

然後是response:

第二個是使用命令行。

雖然我們每天都在使用HTTP(s),但是感覺對它還是不熟悉,主要原因就是因為瀏覽器的封裝太好了。瀏覽器在背後偷偷做了好多事情,都沒讓用戶知道。

客戶端發送一個HTTP請求到伺服器的請求消息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求數據四個部分組成。

Http請求消息結構

具體怎麼理解呢?

第一部分:請求行,用來說明請求類型,要訪問的資源以及所使用的HTTP版本.

GET說明請求類型為GET, 1.html為要訪問的資源,最後一部分說明使用的是HTTP1.1版本。

第二部分:請求頭部,緊接著請求行(即第一行)之後的部分,用來說明伺服器要使用的附加信息

第三部分:空行,請求頭部後面的空行是必須的

即使第四部分的請求數據為空,也必須有空行。

第四部分:請求數據也叫主體,可以添加任意的其他數據。

以上例子的請求數據都為空。

當然也可以使用POST方法來獲取數據。

GET和POST的區別後面再討論。

可以繼續嘗試PUT方法。

出錯了。 可以去/var/log/apache2查看錯誤日誌:

然後更改一下請求的內容:

這時候發現返回的信息發生了變化。說明是許可權有問題。然後開始更改許可權。具體操作如下:

啟動了一些Module。

更改了配置文件:

當然,還需要把/var/www改成777許可權。之後,可以成功地使用PUT命令:

2. URI

HTTP使用統一資源標識符(Uniform Resource Identifiers, URI)來傳輸數據和建立連接。URL是一種特殊類型的URI,包含了用於查找某個資源的足夠的信息。URL,全稱是UniformResourceLocator, 中文叫統一資源定位符,是互聯網上用來標識某一處資源的地址。

關於URI和URL的區別,如果拿人做例子,譬如在我們這個教室,所以人的名字都不相同,通過名字這個字元串就可以標識出唯一的一個人。在現實當中名字會重複的,所以URI是身份證號,通過身份證號能讓我們唯一確定一個人。

那統一資源定位符URL是什麼呢。江蘇省/蘇州市/**路/唯真樓/103教室/第五排/第三個人

同時呢,這個字元串同樣標識出了唯一的一個人,起到了URI的作用,所以URL是URI的子集。

這裡我們來詳細地分析一下URL。

我們來看一下,它為什麼叫做URL。它包括:

  • 協議部分:該URL的協議部分為「http:」,這代表網頁使用的是HTTP協議。在Internet中可以使用多種協議,如HTTP,FTP等等本例中使用的是HTTP協議。在"HTTP"後面的「//」為分隔符。可以看一些其他協議譬如data和javascript的例子

data:,Hello%2C%20World!
簡單的 text/plain 類型數據

data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
base64 編碼過的數據

data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E
一個HTML文檔源代碼 <h1>Hello, World</h1>

data:text/html,<script>alert(hi);</script>
一個會執行 JavaScript alert 的 HTML 文檔。注意,script 閉標籤是必須的。

data:image/gif;base64,R0lGODlhMwAxAIAAAAAAAP/// yH5BAAAAAAALAAAAAAzADEAAAK8jI+pBr0PowytzotTtbm/DTqQ6C3hGX ElcraA9jIr66ozVpM3nseUvYP1UEHF0FUUHkNJxhLZfEJNvol06tzwrgd LbXsFZYmSMPnHLB+zNJFbq15+SOf50+6rG7lKOjwV1ibGdhHYRVYVJ9Wn k2HWtLdIWMSH9lfyODZoZTb4xdnpxQSEF9oyOWIqp6gaI9pI1Qo7BijbF ZkoaAtEeiiLeKn72xM7vMZofJy8zJys2UxsCT3kO229LH1tXAAAOw==

javascript:alert(1)

  • 域名部分:該URL的域名部分為「stanford.edu」。URL中,也可以使用IP地址作為域名使用
  • 埠部分:跟在域名後面的是埠,域名和埠之間使用「:」作為分隔符。埠不是一個URL必須的部分,如果省略埠部分,將採用默認埠
  • 路徑部分:從域名後的第一個「/」開始到最後一個「/」為止,是路徑部分。虛擬目錄也不是一個URL必須的部分。本例中的路徑是class。
  • 文件名部分:從域名後的最後一個「/」開始到「?」為止,是文件名部分,如果沒有「?」,則是從域名後的最後一個「/」開始到「#」為止,是文件部分,如果沒有「?」和「#」,那麼從域名後的最後一個「/」開始到結束,都是文件名部分。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名。
  • 錨部分:從「#」開始到最後,都是錨部分。本例中的錨部分是「homework」。錨部分也不是一個URL必須的部分。
  • 參數部分:從「?」開始到「#」為止之間的部分為參數部分,又稱搜索部分、查詢部分。本例中的參數部分為「name=cs155」。參數可以允許有多個參數,參數與參數之間用「&」作為分隔符。

3. Apache配置

那我們現在開始配置和啟動一個網站。瀏覽器是我們的客戶端,相應的需要有伺服器端。可以想一下,伺服器端主要是用來做什麼?

伺服器端需要解析客戶端發來的請求,需要與各個組件譬如PHP和資料庫交互,需要從資料庫或硬碟獲得客戶所需的數據,同時還需要兼顧性能和安全性等等。想起來就是非常複雜的程序。大家之前可能用過各種Web後端的伺服器程序,這裡我們主要用Apache。

apache的安裝很簡單: sudo apt-install apache2 就可以了。目前我們不需要php和mysql,所以只需要按照apache。

apache安裝之後默認啟動,這時候我們就可以打開瀏覽器,然後在URL中輸入127.0.0.1或者是Localhost就可以看到一個頁面。apache的不同版本中,默認的頁面也不相同。

問題是,這個頁面是在哪裡的?為什麼可以看到這個頁面?

這裡我們需要有一些基本的概念,譬如說埠號,DNS域名。Apache也是一個服務,它的默認埠是80,那麼可以使用其他的埠嗎?如果需要使用其他的埠,可以怎麼做呢?

那我們來看一下/etc/apache2中的一些配置文件。對Linux熟悉的同學應該知道/etc中放的是系統的配置文件。apache2的目錄下,放著的是關於apache的配置文件。這裡也需要注意一下,不同的版本中,配置文件的名字和位置都不同,不過主體內容都是大同小異。

首先來看一下ports.conf。

ports.conf的出場配置應該是這樣的。表示什麼意思呢?

Listen 80表示的是默認偵聽80埠;就是這個80埠已經被它佔用了。然後下面的有一對標籤的,雖然我們沒有專門去學apache配置語言的格式,也能猜的出來,就是如果啟用了模塊ssl_module或者模塊 mod_gnutls,那麼就偵聽443埠。

這個怎麼理解呢?apache是模塊化的結構,就是它可以支持很多的功能,但是在默認啟動的時候,只啟動最核心的一些功能,然後其他的模塊可以按需增加。現在大家應該知道這兩個文件夾 mods-available和mods-enabled是什麼意思。那譬如說我們想確認一下ssl_module有沒有啟動,應該怎麼做呢?

那如果我們想在81埠上也偵聽,那沒關係,就在配置文件上寫上一句, Listen 81就行。這樣81埠開始偵聽,但是跟它配套的還有網頁,所以還需要改一點其他的配置。

我們點開sites-available。

可以看到兩個配置文件,這裡每個配置文件對應著一個埠上的一個或多個網站。打開看看就知道apache默認就支持了80埠和443埠。如果我們想讓apache同時支持更多個埠,只需要多寫幾個配置文件就行了。

這會兒我們可以複製一份這個文件,或者直接修改現在的default。

打開default,看到80埠,我們把80埠改成81就行。

<VirtualHost *:80>

修改完配置文件之後,需要重新啟動Apache,告訴它用新的配置。

這時應該可以看到Localhost:81出現了頁面。

另外,如果希望建立自己的文件夾作為根目錄,而不是使用默認的/var/www/html(這裡操作需要sudo),那麼可以修改default配置文件中的

DocumentRoot /var/www/html

把這個修改了就可以。

但是,更換根目錄,可能會出現下面的錯誤。

這時候需要在配置文件中添加:

還有一點是,Localhost作為一個域名是怎麼被解析的呢?/etc/中有一個hosts文件,中間是域名和IP對的映射關係。

接下來,譬如我們想啟動ssl-module可以怎麼做呢?

一個簡單的命令就可以了。a2enmod,就是apache2 enable module 後面跟上想要啟動的模塊。

可以試一下啟動模塊之後,效果如何。在啟動模塊之前,訪問https:

啟動模塊之後,

此時不是連不上,而是報一個警告,鏈接不安全。為啥HTTPs還是不安全的,我們後面會講。

另外,apache的功能很強,包括在同一埠支持多個不同的域名和網站,可以多嘗試。

參考:

  1. 關於HTTP協議,一篇就夠了 - ranyonsue - 博客園
  2. zhihu.com/question/2195

推薦閱讀:

查看原文 >>
相關文章