簡介
記錄我在 mac 上用 VisualBox 建立虛擬服務(wù)機(jī)后通過 nginx 搭建雙向驗證的網(wǎng)站的過程,包括虛擬機(jī)的建立、文件共享設(shè)置、虛擬機(jī)網(wǎng)絡(luò)設(shè)置、SSH 連接虛擬機(jī)、nginx 配置。
Linux Server (ubuntu) 的建立
用 VisualBox 建立一個 Linux Server 虛擬機(jī)(ubuntu-16.04.2-server-amd64),建立過程除了存儲那邊改選了固定大小其它的都是默認(rèn)的選項。


之后就是安裝系統(tǒng)。在虛擬機(jī)的設(shè)置里選擇存儲那一項的控制器 IDE 里的光驅(qū)選擇要裝的系統(tǒng)的鏡像文件文件,確認(rèn)后啟動虛擬機(jī)裝好系統(tǒng)。


文件共享
為了實現(xiàn)虛擬機(jī)與 mac 文件共享要安裝增強(qiáng)功能,主機(jī)上根據(jù) ubuntu 的版本下載 VBoxGuestAdditions 鏡像文件,然后和裝系統(tǒng)時一樣地在設(shè)置里的存儲里增加這個鏡像文件,在虛擬機(jī)界面的 Devices -> Optical Drives 里確保 VBoxGuestAdditions.iso 是打勾被選中的,然后在虛擬機(jī)里運(yùn)行:
sudo mount /dev/cdrom /media/cdrom
進(jìn)入 /media/cdrom 里面可以看到一些可執(zhí)行文件,執(zhí)行:
sudo ./VBoxGuestAdditions.run
重啟虛擬機(jī):
sudo reboot
在虛擬機(jī)的設(shè)置里創(chuàng)建一個固定分配共享文件夾:

共享文件夾自動掛載在虛擬機(jī)的 /media 目錄下,名稱是 sf_ 加上共享文件夾的名稱。這時訪問共享文件目錄非 root 用戶會出現(xiàn)權(quán)限問題(一般登錄的都是非 root 用戶):

運(yùn)行以下命令:
sudo usermod -aG vboxsf 當(dāng)前登錄的用戶名 # 如:sudo usermod -aG vboxsf cxswow
重啟虛擬機(jī)生效:
sudo reboot
共享文件完成。
網(wǎng)絡(luò)設(shè)置:NAT+Host-Only
虛擬機(jī)設(shè)置里默認(rèn)的網(wǎng)絡(luò)是只有一張使用 NAT 的網(wǎng)卡,這時虛擬機(jī)可以上網(wǎng),但是主機(jī)和虛擬機(jī)不互通,因此我要加一張網(wǎng)卡來讓主機(jī)可以訪問虛擬機(jī),用的 Host-Only 模式。
在虛擬機(jī)關(guān)機(jī)的情況下打開虛擬機(jī)的設(shè)置 -> 網(wǎng)絡(luò),網(wǎng)卡1默認(rèn)的不用修改,打開網(wǎng)卡2,啟用網(wǎng)卡2的網(wǎng)絡(luò)連接,連接方式選 Host-Only,

這里要有一個界面名稱,如果沒有可選的,在 VirtualBox 的設(shè)置 -> 網(wǎng)絡(luò)里的 Host-Only 界面增加一個,用默認(rèn)的設(shè)置就行。

打開虛擬機(jī),編輯網(wǎng)絡(luò)設(shè)置文件:
sudo vim /etc/network/interfaces
我的文件初始內(nèi)容是這樣的:

這里的 auto 后面跟的是網(wǎng)卡名字,之后就是對這個網(wǎng)卡的一些設(shè)置。如果不知道對應(yīng)的網(wǎng)卡的名字,運(yùn)行以下命令可以查看當(dāng)前網(wǎng)卡的信息:
ip link
這里可以看到新增加的網(wǎng)卡名字(我的是 enp0s8),所以我的網(wǎng)絡(luò)配置文件修改成以下這樣:

重啟虛擬機(jī)網(wǎng)絡(luò):
sudo /etc/init.d/networking restart


主機(jī)通過 ssh 連接虛擬機(jī)
通過密碼連接
確保虛擬機(jī)和客戶端都裝了 OpenSSL 的相關(guān)軟件后——如果在主機(jī)上用 ssh 連接虛擬機(jī)被拒絕了(Connection refused)一般就是虛擬機(jī)沒有安裝 ssh,虛擬機(jī)安裝 ssh 命令: sudo apt-get install openssh-client openssh-server——主機(jī)直接通過終端的 ssh 命令就能連上服務(wù)端:
ssh 虛擬機(jī)用戶名@虛擬機(jī) IP 地址 # 如:ssh cxswow@192.168.56.101,這個 IP 是 Host-Only 的那個 IP
第一次連接一個虛擬機(jī)的時候會警告你要連接的這個機(jī)之前未知,讓你確認(rèn)是否繼續(xù)連接,輸入 yes 繼續(xù)連接。然后會讓你輸入該機(jī)該用戶的密碼,輸入正確后就連接成功,此時就可以像在虛擬機(jī)的終端里一樣地使用了。
退出連接輸入:
exit
使用別名連接
每一次連接都輸入用戶名和 IP 是一件比較繁瑣的事,可以通過配置文件來給固定的用戶名和 IP 對起別名,之后通過別名連接會方便點(diǎn)。
做法是在客戶端的用戶根目錄下的 .ssh 文件夾里建立 config 文件,文件內(nèi)容如下:
Host myUbuntu
User cxswow
HostName 192.168.56.101
之后就可以通過下面的命令來連接了:
ssh myUbuntu
使用證書連接
每次都輸入密碼也不是一個好的選擇,通過密鑰認(rèn)證連接會方便安全點(diǎn)。
在客戶端的用戶根目錄下的 .ssh 目錄下運(yùn)行以下命令生成密鑰對:
ssh-keygen -b 1024 -t rsa
這里可選項 -b 后面跟的是密鑰的長度 1024 字節(jié),最長 4096 字節(jié),長度影響解密時間,一般 1024 或 2048 就足夠了;可選項 -t 后面跟的是加密方式,默認(rèn)是 rsa,還要一種 dsa。
生成時會提示輸入密鑰名字,默認(rèn)名字是 id_rsa ,我給命名成 mymac 了,這里如果使用自己命名的密鑰名字,之后將公鑰傳到虛擬機(jī)上的命令就要指定公鑰,每次用 ssh 連接的時候也要指定簽名的密鑰(如:增加 -i mymac 指定)。
還會讓你輸入私鑰短語,有的話安全點(diǎn)。
之后運(yùn)行下面語句將公鑰傳到虛擬機(jī)上:
ssh-copy-id -i mymac.pub myUbuntu
-i后面跟的是對應(yīng)的公鑰,如果創(chuàng)建密鑰的時候用了非默認(rèn)名字,這里就要指定。
然后運(yùn)行:
ssh -i mymac myUbuntu
實現(xiàn)免密登錄。但是這里如果創(chuàng)建密鑰對的時候輸入了密鑰的短語,還是要輸入短語的,想要每次連接連短語也不輸入的話,可以運(yùn)行:
ssh-add ~/.ssh/mymac
來輸入短語后緩存,之后連接就不用再輸入額外的信息了。
nginx 配置
安裝 nginx:
sudo apt-get install nginx
/etc/nginx/nginx.conf 就是 nginx 的配置文件,不過一般不將我們的網(wǎng)站的配置放在這里,而是在 /ect/nginx/sites-available 文件夾下,該文件夾下面初始有個演示的例子的配置文件 default,內(nèi)容如下:
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
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;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
# fastcgi_pass unix:/run/php/php7.0-fpm.sock;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
# 后面是注釋掉的內(nèi)容,注釋掉的內(nèi)容很多是 nginx 的標(biāo)準(zhǔn)配置方法,去掉注釋的內(nèi)容后實際內(nèi)容如下:
server {
# 默認(rèn)監(jiān)聽本機(jī)80端口
listen 80 default_server;
listen [::]:80 default_server;
# 指名 html 文件夾所在
root /var/www/html;
# 網(wǎng)站主頁
index index.html index.htm index.nginx-debian.html;
# 訪問的網(wǎng)址
server_name _;
# 路由詳細(xì)配置
location / {
try_files $uri $uri/ =404;
}
}
我們可以通過拷貝默認(rèn)配置文件再在上面修改成我們想要的配置,拷貝命令(假設(shè)要配置的網(wǎng)站是 example.com ):
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
修改配置成:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/example.com/html; # 自建的 html 的文件夾位置
index index.html index.htm; # 該文件夾下要有其中一個文件可以當(dāng)主頁
server_name example.com www.example.com; # 只是好看的網(wǎng)址,之后會說
location / {
try_files $uri $uri/ =404;
}
}
這里要注意的是 server_name 后面跟的網(wǎng)址,如果像上面寫的那樣要修改 /etc/hosts 文件,該文件是本機(jī)訪問的網(wǎng)站的名稱和 ip 的映射,要用 example.com 這個域名來訪問你的網(wǎng)址(本機(jī)訪問,也就是虛擬機(jī)訪問,好像這里并沒什么用,因為這個虛擬機(jī)沒有瀏覽器,好像還是要通過主機(jī)的瀏覽器訪問虛擬機(jī)的 ip 來訪問網(wǎng)站,不太懂)就要在 /etc/hosts 文件里加上一行,大概是這樣的:
127.0.0.1 localhost
127.0.0.1 example.com
這樣說起來直接寫 server_name 127.0.0.1更方便。
保存該配置文件后啟動或重啟 nginx 后,主機(jī)可以通過訪問虛擬機(jī)的 ip 來查看網(wǎng)站了,比如之前設(shè)置的是 192.168.56.101,那直接訪問 192.168.56.101 就可以看到你指定的網(wǎng)站的主頁了。
nginx 啟動命令: sudo service nginx start 。
nginx 重啟命令: sudo service nginx restart 。
查看 nginx 目前情況: ps -ef | grep nginx 。
單向驗證的網(wǎng)站
要讓這個網(wǎng)站變成 https 的網(wǎng)站要生成自己的 SSL 證書, 創(chuàng)建放證書的文件夾(之后配置文件里要寫明證書位置,放在某個地方比較方便管理而已):
sudo mkdir /etc/nginx/ssl
生成證書:
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/example.key -out /etc/nginx/ssl/example.crt
生成的時候會問一些問題,按描述填寫就行。問題像這樣:
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:BJ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:my company
Organizational Unit Name (eg, section) []:tech
Common Name (e.g. server FQDN or YOUR name) []:cxswow
Email Address []:
生成的 example.crt 就是證書文件,example.key 是私鑰。
然后把配置文件修改成:
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl; # 新增加,ssl 默認(rèn)監(jiān)聽的端口就是443,開啟監(jiān)聽
root /var/www/example.com/html;
index index.html index.htm;
server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/example.crt; # 新增,聲明證書
ssl_certificate_key /etc/nginx/ssl/example.key; # 新增,聲明私鑰
location / {
try_files $uri $uri/ =404;
}
}
重啟 nginx : sudo service nginx restart 。
然后訪問網(wǎng)站,這時候就是走的 https 。
雙向驗證的網(wǎng)站
雙向驗證最少要有三方,像是甲方、乙方、見證人這樣的。這里一般叫 server、client、CA 。
之前單向驗證只生成了 server,而且 server 的證書是自己給自己簽名的,這里的 server 證書和 client 證書都要 CA 來簽發(fā),之前的證書不能用了。
所以 server 和 client 生成私鑰和證書簽名請求文件(Certificate Signing Request):
# 生成 server 的私鑰和證書簽名請求文件,還是放在之前說的 /etc/nginx/ssl 文件夾里面,這里進(jìn)入該文件夾執(zhí)行下面的命令
sudo openssl genrsa -des3 -out server.key 1024
sudo openssl req -new -key server.key -out server.csr
# 生成 client 的私鑰和證書簽名請求文件
sudo openssl genrsa -des3 -out client.key 1024
sudo openssl req -new -key client.key -out client.csr
# 生成 CA 私鑰和自簽名證書
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout ca.key -out ca.crt
然后生成 ca 認(rèn)證的 server 證書和 client 證書:
# ca 簽發(fā) server 證書
sudo openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
# ca 簽發(fā) client 證書
sudo openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
而客戶端證書要用在瀏覽器上,一般要轉(zhuǎn)換成瀏覽器可以用的格式,這里轉(zhuǎn)成 .p12 格式:
openssl pkcs12 -export -inkey client.key -in client.crt -out client.p12
這里會讓你輸入密碼,是在證書導(dǎo)入瀏覽器的時候要輸入的密碼。
p12 格式的文件在主機(jī)上知己雙擊運(yùn)行安裝就行。
修改 nginx 的配置文件,對虛擬機(jī)上部署的 server 進(jìn)行反向代理:
server {
# 開啟
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl on;
listen 443 ssl default_server;
# Add index.php to the list if you are using PHP
#index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 當(dāng)客戶端證書認(rèn)證通過后,將客戶端證書中 Common Name 提取到 X-ClientCert-DN 頭里
# 這樣上游的 Node.JS Server 就可以從這里知道登錄用戶的身份了(名字)
proxy_set_header X-ClientCert-DN $ssl_client_s_dn;
}
}
這里 proxy_pass 就是別人訪問虛擬機(jī)的默認(rèn)443端口會返回的請求內(nèi)容,這里要返回本機(jī)8080端口的內(nèi)容,要另外自己開個 server 監(jiān)聽8080端口。
在主機(jī)上安裝 client.p12 證書(雙擊文件可以直接安裝),再訪問 https://192.168.56.101 的時候就可以選擇 client.p12 證書來進(jìn)行驗證了。
8080端口的那個 server 也可以根據(jù)請求頭的 Common Name 來返回不同的內(nèi)容。
參考:
Guest Additions
File permission issues with shared folders under Virtual Box
VirtualBox 中 ubuntu 的網(wǎng)絡(luò)設(shè)置
SSH原理與運(yùn)用(一):遠(yuǎn)程登錄
How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 14.04 LTS
How To Create an SSL Certificate on Nginx for Ubuntu 14.04
Protect your Node.js API with nginx and SSL client certificates
反向代理
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
- 配置運(yùn)行Nginx服務(wù)器用戶(組) 用于配置運(yùn)行Nginx服務(wù)器用戶(組)的指令是user,其語法格式為: use...
- 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx?那么一定聽過它的“同行”Apache吧!Ngi...
- 上一篇《WEB請求處理一:瀏覽器請求發(fā)起處理》,我們講述了瀏覽器端請求發(fā)起過程,通過DNS域名解析服務(wù)器IP,并建...
- 小時候,只知道家里不斷在還債.父母并沒有什么文化,只能從事體力勞動,那個時候父親還在當(dāng)?shù)氐臒掍搹S子里工作,兩班倒的...