使用OpenSSL自建CA + Nginx配置HTTPS

Ubuntu 16.04(ECS),OpenSSL 1.0.2g  1 Mar 2016,Nginx 1.10.3 (Ubuntu),html

瀏覽器:Chrome 67,Firefox 61,Edge 40,IE 11前端

 

序言nginx

孤以前歷來沒有創建過HTTPS網站,感受很高級、很難,雖然也讀過很多博文、資料,十年前在大學時,也使用過OpenSSL操做過創建證書,但後來都忘記了。git

前同事說創建HTTPS網站很容易的,當時本身是不信的,併發生了一些爭論,在此表示歉意。web

因爲本身搭建了網站,提供了註冊、登陸功能,所以,有安全方面的考慮。前兩日研究了前端加密、Base64編碼等方案(crypto-js),但都沒法很好地保證用戶數據安全。ubuntu

最付出很多精時後,最終決定將網站升級爲HTTPS網站,本文記錄了試驗過程當中的關鍵步驟——兩步:瀏覽器

1.自建CA並簽名Server證書安全

2.配置Nginx服務器服務器

 

自建CA並並簽名Server證書併發

本步驟徹底參考了自建CA並簽名server證書實現https by Andy____Li,只是對一些文件名、配置參數進行了修改。

注意:在執行此步驟以前,請確保Linux操做系統上安裝了OpenSSL。

能夠分爲下面的小步驟(拷貝了參考連接中的命令):

1.自建CA

生成CA私匙
openssl genrsa -out icatchtek.key 2048

執行結果:提示建立成功,可又提示unable to什麼的,爲何?還須要dig,

 

Generating RSA private key, 2048 bit long modulus
................+++
...........................................................................................+++
unable to write 'random state'
e is 65537 (0x10001)

 

生成CA證書請求
openssl req -new -key icatchtek.key -out icatchtek.csr
PS:證書請求是對簽名的請求,須要使用私鑰進行簽名

此命令輸入後,須要填寫信息。

生成CA根證書
openssl x509 -req -in icatchtek.csr -extensions v3_ca -signkey icatchtek.key -out icatchtek.crt
PS:證書是自簽名或CA簽名過的憑據,用來進行身份認證

執行結果:

Signature ok
subject=/C=CN/ST=Guangdong/L=Shenzhen/OU=.../CN=.../emailAddress=xxxx@example.com
Getting Private key
unable to write 'random state'

 

2.自建server端證書

生成server私匙
openssl genrsa -out smarthome_server.key 2048

結果同上。

生成server證書請求
openssl req -new -key smarthome_server.key -out smarthome_server.csr

結果同上,需輸入參數。

生成server證書:下面命令的紫色部分就是上面創建的一系列文件,不用弄錯了。
生成server證書,須要一份配置文件,可參閱:vi openssl.cnf
openssl x509 -days 365 -req -in smarthome_server.csr -extensions v3_req -CAkey icatchtek.key -CA icatchtek.crt -CAcreateserial -out smarthome_server.crt -extfile openssl.cnf

 

關於生產Server證書這一步,孤是直接拷貝了參考連接中的內容,並進行了修改。關於此文件怎麼寫,孤是不太熟悉的,還須要看更多資料,好比參考連接中的OpenSSL主配置文件openssl.cnf

下面是本身的open.cnf(私密信息沒有)(在參考連接中,[req]下面的幾個section是有縮進的,不知道爲何):

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = Guangdong
stateOrProvinceName_default = Guangdong
localityName = Shenzhen
localityName_default = Shenzhen
organizationalUnitName  = ...
organizationalUnitName_default  = ...
commonName = ...
commonName_max  = 64

[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
IP.1 = xxx.xxx.xxx.xxx
DNS.1 = www.example.com

 

說明,上面的每一步都會在 執行命令的 當前目錄下 創建相應的文件!下面是孤試驗過程當中創建的:

$ ls
ben_server.crt ben_server.key icatchtek.csr icatchtek.srl
ben_server.csr icatchtek.crt icatchtek.key openssl.cnf

 

配置Nginx服務器

按照參考連接的說法,是在server 塊內 listen 端口後添加下面的語句

ssl on;
ssl_certificate /home/ubuntu/webvideo/nginx/conf/smarthome_server.crt;
ssl_certificate_key /home/ubuntu/webvideo/nginx/conf/smarthome_server.key;

 

注意,*.crt、*.key文件的路徑須要更改,孤是將它們放在/etc/nginx/conf.d/ca裏面的。

 

做爲Nginx新手,孤的Nginx配置文件中只有一個Server的,端口是80。可HTTPS網站的默認端口不是443嗎?

修改前的Nginx配置文件:

server {
	listen 80 default_server;
	listen [::]:80 default_server;

	# SSL configuration
	#
	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;

修改後的配置文件:

server {
	listen 80 default_server;
	listen [::]:80 default_server;

	# SSL configuration
	#
	listen 443 ssl default_server;
	listen [::]:443 ssl default_server;
	
	ssl on;
	ssl_certificate      /etc/nginx/conf.d/ca/smarthome_server.crt;
	ssl_certificate_key  /etc/nginx/conf.d/ca/smarthome_server.key;
	
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332

 

分別訪問http、https對應的網頁,http的訪問失敗了、但https訪問成功:緣由是,只有一個服務器,可本身監聽了兩個端口,還須要結合nginx的rewrite技術,將http請求轉到對應的https請求。

 

最後,創建了兩個Server:一個sever監聽80端口、一個監聽443端口,前者http連接被rewrite到後者的連接,配置文件以下:

80端口後面沒有default_server了——不知道本身爲什麼如此配置;在只有一個server時,其server_name爲_,如今有兩個了,怎麼配置呢?可否相同?

server {
        listen 80;
        listen [::]:80;

        rewrite ^(.*)$ https://$host$1 permanent;
}

server {
        # SSL configuration
        #
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        ssl on;
        ssl_certificate /etc/nginx/conf.d/ca/ben_server.crt;
        ssl_certificate_key /etc/nginx/conf.d/ca/ben_server.key;

 

上面的配置完畢後,就能夠經過http、https訪問網站了,不過,http的是轉向了https,因此,頁面最後看到的是https。

可是,由於瀏覽器有證書安全校驗的機制,所以,不是全部瀏覽器均可以成功打開頁面,測試結果是,只有Firefox在設置後能夠打開頁面,其它幾種瀏覽器都失敗了。

-Chrome瀏覽器

 

-Firefox瀏覽器:最終訪問成功。

 

IE瀏覽器:

 

 

網頁不能訪問,緣由是瀏覽器認爲 頒發證書的CA 不安全。參考連接說把本身的CA根證書加入到瀏覽器。

在嘗試事後,發現問題並無解決——Chrome、IE都試了試,不行啊!懷疑和本身創建證書的過程有關係,也可能和最新版本的瀏覽器的安全機制升級有關係,更可能的是前者。

並且,如上面所講,本身在創建key是出現了unable to write 'random state'錯誤!後面能夠解決此問題後再作嘗試,繼續dig。

怎麼導入呢?Chrome的設置-搜索「證書」,IE、Edge的Internet選項:其實二者配置的是一個東西,其屬於操做系統。

 

後記

總算知道怎麼讓本身的網站變爲HTTPS的了,自建的證書既然沒法正常使用,那麼,去申請證書吧——知道一個免費申請的機構,固然,付費的就不少了。

Nginx配置不熟悉;

雖然本文用OpenSSL作了一些操做,但是,爲什麼這麼作呢?官方文檔在哪裏呢?配置文件怎麼寫呢?如今只能踩着先行者的腳步往前走,感謝!

路漫漫啊,

 

參考連接

自建CA並簽名server證書實現https by Andy____Li

https SSL 自建證書的製做 by Erice_e

OpenSSL主配置文件openssl.cnf by 園友 我爲何堅持寫博客

nginx 將http請求轉發到https請求

openssl簽署和自簽署證書的多種實現方式 by 園友 駿馬金龍 (Highlycommended,博主的相關文章也很棒,已讀兩篇)

相關文章
相關標籤/搜索