1. 程式人生 > >Pandorabox路由器申請Let's Encrypt證書,為內網web服務提供SSL支援

Pandorabox路由器申請Let's Encrypt證書,為內網web服務提供SSL支援

對於家中寬頻有公網IP的使用者,有時我們需要將路由器內部網路的某些web服務通過埠轉發暴露到外網(例如NAS遠端訪問),但HTTP是明文傳輸,有被監聽的風險;如果在NAS上使用自簽名證書,再埠轉發,會被Chrome瀏覽器認為是風險連線拒絕訪問(筆者使用80.0.3987版本,命令列引數啟動、系統新增證書信任法均不能通過);使用某些NAS自帶的Let's Encrypt外掛申請到的證書,也只能為NAS單獨一個服務新增HTTPS。本文將介紹如何在路由器上安裝NGINX並部署SSL,反向代理內網中的多個HTTP服務。

要求

一個域名,無須備案;路由器有公網IP,路由器為Pandorabox韌體(理論上基於openwrt的韌體都可以);軟體源已更至最新。

截至2020.03,可用的Pandorabox軟體源地址為http://downloads.pangubox.com:6380/pandorabox

比如我的路由器為newifiD1,配置資訊則為

src/gz 18.10_base http://downloads.pangubox.com:6380/pandorabox/18.10/packages/mipsel_1004kc_dsp/base
src/gz 18.10_lafite http://downloads.pangubox.com:6380/pandorabox/18.10/packages/mipsel_1004kc_dsp/lafite
src/gz 18.10_luci http://downloads.pangubox.com:6380/pandorabox/18.10/packages/mipsel_1004kc_dsp/luci

src/gz 18.10_mtkdrv http://downloads.pangubox.com:6380/pandorabox/18.10/packages/mipsel_1004kc_dsp/mtkdrv
src/gz 18.10_newifi http://downloads.pangubox.com:6380/pandorabox/18.10/packages/mipsel_1004kc_dsp/newifi
src/gz 18.10_packages http://downloads.pangubox.com:6380/pandorabox/18.10/packages/mipsel_1004kc_dsp/packages

安裝NGINX和acme

nginx在pandorabox的web管理介面或命令列opkg install nginx 安裝均可,acme按照官方說明安裝、執行,但之前還需再安裝幾個包:curl wget ca-certificates openssl-util ca-bundle socat

ca-bundle是一堆打包的CA根證書,pandorabox預設不包含任何CA根證書,所以無法建立任何SSL連線。socat在acme的部分功能裡會用到,最好安裝。

安裝過程還有幾個地方需要注意:

1. 安裝nginx後會報啟動失敗,埠被佔用,這是正常的,因為80埠已經被路由器Web管理介面(uhttpd服務)佔用了,之後我們會改nginx配置檔案。

2. 使用http驗證,注意uhttp的預設網站根目錄是/www,並需在防火牆中開啟80埠,如果運營商遮蔽了80埠,那http根目錄驗證無法使用,但可以用standalone模式指定其他埠驗證。比如使用88埠,先在防火牆中開啟88埠,然後驗證命令為:

acme.sh --issue -d example.com --standalone --httpport 88

如果使用nginx自動驗證,要確保nginx已經正確執行,這需要配置uhttpd埠與nginx不衝突,以及防火牆,不建議使用。

3. 使用dns驗證,無需在路由器上做任何配置,建議使用acme的自動txt記錄新增功能

 

4. 拷貝證書可以用acme的拷貝命令,但需做修改如下

acme.sh --installcert -d example.com \
--key-file       /etc/nginx/key.pem  \
--fullchain-file /etc/nginx/cert.pem
# --reloadcmd     "service nginx force-reload" 不要新增這句

配置Nginx

至此證書已經獲取完畢,接下來在nginx中配置。假設我們內網的兩個web服務地址分別為http://192.168.0.100, http://192.168.0.102/test

user nobody nogroup;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    #default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    client_body_timeout 3600;               
    client_header_timeout 1800;             
    keepalive_timeout 15;                   
    send_timeout 3600; 

    gzip  on;

    server {
        listen       443 ssl;  #不方便使用443埠可更換其他埠
        server_name  example.com;

        charset utf-8;
        ssl_certificate    cert.pem; #注意這裡兩個檔案不要寫反了
        ssl_certificate_key  key.pem;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout 5m;  
        ssl_prefer_server_ciphers on; 
        #access_log  logs/host.access.log  main;

        #error_page  404              /404.html;
        proxy_connect_timeout 180;
        proxy_send_timeout 180;
        proxy_read_timeout 180;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarder-For $remote_addr;
 
        location /servertest {
            proxy_pass http://192.168.0.102/test;
            proxy_redirect default;  #nginx伺服器不做快取,所有請求都轉發到目標伺服器進行處理
            proxy_buffering off;
        } 
        location /server1 {                       
            proxy_pass http://192.168.0.100;
            # 不做配置,nginx會對內容進行快取,速度有些許提升,但可能遭遇超時問題
        }   
    
        location ~ //.ht {
            deny all;
        }
        
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   html;
        #}


    }
}
Nginx配置檔案

重啟nginx服務:/etc/init.d/nginx restart

如果沒有錯誤資訊輸出,防火牆的相應埠已經開啟,則訪問https://example.com/server1和https://example.com/servertest(如果指定非443埠需加上埠號),發現服務已經執行在ssl之上了。更多服務只需設定更多子目錄轉發即可。

 注意

1. 理論上到nginx配置之前都可以在內網主機上進行,最終只要手動拷貝生成的兩個證書檔案到路由器/etc/nginx目錄即可,但在證書驗證環節就需要埠轉發,或者用dns驗證。

2. 即使路由器不支援安裝nginx,也可以在內網主機上安裝nginx,然後把此主機設為DMZ或者用埠對映的方式暴露出來,效果是一樣的,具體步驟不再贅述。

3. SSL對路由器效能開銷不小,筆者的newifiD1在測試大檔案下載時速度要比HTTP降低一半左右,且路由器負載跑滿,有條件應使用高配路由器。

&n