Web安全實踐1:搭建HTTPS(1)
為了討論Web安全,我們首先得有一個網站。我們使用LAMP搭建網站。網路上的教程很多,我們會快速的過一下LAMP基本網站搭建,然後重點討論的是HTTPS。
- 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版本.
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的功能很強,包括在同一埠支持多個不同的域名和網站,可以多嘗試。
參考:
- 關於HTTP協議,一篇就夠了 - ranyonsue - 博客園
- https://www.zhihu.com/question/21950864/answer/154309494
推薦閱讀: