Trojan (debian) + NGINX reverse proxy (alpine) + OpenWRT 基本配置法

剛弄好,因此寫個簡單的配置教學。K8s or LXD 相關就暫時先擱置,畢竟只是個小服務不是大流量服務 😅

Pre-Requirement

有些前置作業因為篇幅(?)就不做太多說明:

需要一台裝好設定好的 Proxmox 的主機(其他虛擬化系統也可以,甚至你有錢直接拿主機堆疊順便浪費電也行),以及對應可用的網路。
我是配置三個容器,一個 openwrt,一個 Alpine Linux 跑 NGINX,一個 debian 跑 Trojan-GFW。openwrt 配接上對外網路的 bridge 與對另外兩個容器的 bridge;另外兩個容器就只配接上與 openwrt 相同 LAN 的 bridge,直接把 openwrt 作為 default gateway。

以 proxmox 來說,建置好 lxc 之後還得開啟容器共享 ssl 證書的空間:
sudo zfs create rpool/ssl # 假設你有個叫做 rpool 的 zpool,在上面蓋一個 ssl 的 zfs 空間
echo "lxc.mount.entry: /rpool/ssl etc/ssl none bind,create=dir,rw 0 0" | sudo tee -a /etc/pve/lxc/<CT ID>.conf # 這行要做兩次,分別是 debian & alpine 的 lxc;openwrt 不做服務,所以不用吃 ssl 證書。

Trojan-GFW

在前面配置好的 Debian 容器中部署 Trojan-GFW;為何不選更精簡的 alpine Linux? 因為現成的 pre-build package 在 alpine 上面不能用,得重新編譯,稍嫌麻煩。
https://github.com/trojan-gfw/trojan/issues/293
https://github.com/trojan-gfw/trojan/issues/567

接下來有兩個方法配置 troj:
echo "deb http://ftp.tw.debian.org/debian buster-backports main contrib" | sudo tee -a /etc/apt/sources.list
sudo apt update && sudo apt install -y trojan/buster-backports # buster-backports 的版本比較新

vim /etc/trojan/config.json
    "run_type": "server",
    "local_addr": "輸入你要監聽的IP",
    "local_port": 你想用的PORT,
    "remote_addr": "127.0.0.1",
    "remote_port": 80,
    "password": [
        "連線要用的密碼1",
"連線要用的密碼2",
"..."
    ],
    "log_level": 1,
    "ssl": {
        "verify_hostname": true,
        "cert": "你的SSL CERT檔案位置,通常透過Let'sEncrypt取得",
        "key": "你的SSL Private Key 檔案位置,通常透過Let'sEncrypt取得",
        "key_password": "",
"sni": "你想服務的DOMAIN NAME,與連線站台相同名稱則免填",

…… (後面不用更動)

vim /etc/systemd/system/trojan.service # 因為 apt 裝的 trojan 不會在開機啟動,得自己做一個 systemd 的啟動腳本

[Unit]
Description=trojan  
After=network.target  
[Service]
Type=simple  
PIDFile=/run/trojan.pid
ExecStart=/usr/bin/trojan -c "/etc/trojan/config.json"  
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=1s
[Install]
WantedBy=multi-user.target

然後記得設定開機自動執行
sudo systemctl enable trojan && sudo systemctl start trojan

另一個方法是或是使用人家做好的懶人包,直接上 github / gitlab 搜尋 trojan 就會搜尋到很多人寫好的一鍵腳本,但是每個腳本相關的配置位置都不盡相同,也會出現各種問題,使用請小心。
我曾用過這個但是不能直接用,另外自己搞定證書的部分,把腳本中證書的部分註解掉。https://github.com/V2RaySSR/Trojan

最後,trojan-gfw 原始碼在此 https://github.com/trojan-gfw/trojan

NGINX reverse proxy

NGINX 這邊比較單純,就只是做 service/traffic bypass,所以我們採用相對精簡的 alpine linux 即可。大部分參考這邊 https://wiki.alpinelinux.org/wiki/Nginx_as_reverse_proxy_with_acme_(letsencrypt)
這邊大概描述一下跟上面網址不同的內容,儘量簡要。

pct enter <nginx ct id> 之後
echo "http://dl-cdn.alpinelinux.org/alpine/latest-stable/main
http://dl-cdn.alpinelinux.org/alpine/latest-stable/community" > /etc/apk/repositories
# 採用最新的 repositories
apk update ; apk upgrade # 順手更新系統
apk add nginx nginx-mod-stream

接著 NGINX 設定檔會在 /etc/nginx 底下,應該會有幾個檔案需要存在:
stream.conf 預設即可
mime.types 不存在的話可複製這邊的 https://github.com/chrisgeo/docker-alpine-nginx/blob/master/conf/mime.types
nginx.conf 這個有些地方建議修改:

ssl_protocols TLSv1.2 TLSv1.3; # 拿掉 TLSv1.1
include /etc/nginx/stream.conf; # 拿掉最前面的 #

接著是 http.d/ 目錄底下

http.d/acme.inc 這個檔案是用來跟 Let’sEncrypt 要證書的時候會用到,參考前面 alpinelinux 的 wiki 連結配置

http.d/default.conf 這個不用動它,預設送你 404

http.d/proxy_set_header.inc 這個是普通的 reverse proxy 時會用到的,一樣參考前面 alpinelinux wiki 的連結配置

http.d/ssl-params.inc 這個不是必要的存在,當你有其他站台需要做 reverse proxy 的時候才會用到,alpinelinux 的 wiki 裡面的配置範例會跟預設的 nginx.conf 衝突(重複),需要註解掉:
#ssl_protocols TLSv1.3; # Requires nginx >= 1.13.0 else use TLSv1.2
#ssl_protocols TLSv1.2; # We use TLSv1.2 because current stable nginx release don't support TLSv1.3 yet
#ssl_prefer_server_ciphers on;
#ssl_session_cache shared:SSL:10m;
#ssl_session_tickets off; # Requires nginx >= 1.5.9

http.d/your_site_configs.conf 這個檔案名稱任你決定,通常是直接設定成 <host & domain name>.conf,裡面需要配置 http port 80 相關配置,port 443 ssl 在後面 stream.d 的地方會提到。
server {
    listen 80;
listen [::]:80; # 如果你需要 IPv6 支援
    server_name <host & domain name>;
    include conf.d/acme.inc;
#   include conf.d/redirect_http.inc; # 普通的站台可能會需要,順手做 HSTS 支援?我們只做 trojan 就不太需要。
    location / {
include conf.d/proxy_set_header.inc;
proxy_pass http://<前面配置的 debian container IP>; # 這個看你要怎麼發揮,可以產生各種不同的應用,我們這邊先這樣配置就行。
# return 404; # 這個是預設的,應該不用了,註解掉。
    }
}

然後是 stream.d/ 目錄底下

stream.d/your_site_configs.conf 這個檔名同樣是任你決定,建議定成 <host & domain name>.conf,參考來源是 https://gist.github.com/phlinhng/84e4fe056b4383e24898b22c95394c5c
map $ssl_preread_server_name $backend_name {
<host & domain name> <hostname>; # 記得替換成你的網域名稱
default web;
}
upstream web {
server 127.0.0.1:80; # 就,預設
}
upstream <hostname> {
server <請設定成前面 debian 內網 IP>:443;
}
server {
listen 443 reuseport;
listen [::]:443 reuseport; # 如果需要 IPv6
proxy_pass  $backend_name;
ssl_preread on;
}

然後打完字發現其實也沒多單純…(?)

最後當然別忘了配置開機執行的部分
rc-update add nginx && rc-service nginx start

Let’s Encrypt certificates

這個,稍微,有點,麻煩。
我是直接在前面 NGINX proxy 的 container 裡面實作,再存到共同空間給後面的 trojan-gfw 使用。

apk add acme.sh

然後參考你的 domain name 供應商提供的指引去操作配置;我是直接寫成 script … 當然現成的工具很多不止 acme 可以用,其他還有 certbot,甚至如果你用 turnkey linux 也有 turnkey-make-ssl-cert 之類的工具。

我用 dynv6,https://fossies.org/linux/acme.sh/dnsapi/dns_dynv6.sh 這邊有人有寫好的工具,但是… 個人覺得太複雜,所以是參考 https://dynv6.com/docs/apishttps://github.com/acmesh-official/acme.sh 自己弄了 script 來做 certificate 的安裝與部署;script 內容稍後行有餘力再補上😬 (我應該會直接懶得補了)

OpenWRT (21.02-RC2)

OpenWRT 部分很簡單,假設 OpenWRT 已設置好可連通網路(能克服 openwrt 的難設定,後面應該問題都不大了 🤣),剩下的就是設置好 IPv4 的 port forwarding 即可。IPv6 的部分有需要的話目前我自己這邊是部署在 reverse proxy (NGINX) 上面。除非還需要做流量控管,就還需要 QoS 配置。當然 openwrt 也支援前面的 ssl 憑證自動更新、ddns 自動刷新等等,配置跟 alpine/debian 等 linux dist 有點不太相同。當然,openwrt 也是可以建制 troj、ssr、v2ray、wg、ssl-vpn 等各式 VPN service,考量到機率不大的轉移問題,還是以分開佈建為主。

Trojan Client

客戶端由於我自己只有實測 iOS & Android,macOS 試不出來,沒有 windows,openwrt還沒空測試(雖然朋友那邊似乎有試成功)所以只介紹 iOS & Android。

iOS: https://apps.apple.com/tw/app/spectre-vpn/id1508712998 安裝完之後在裡面增加伺服器:trojan://密碼@DomainName:Port

https://github.com/trojan-gfw/trojan-url

Android: https://play.google.com/store/apps/details?id=com.crosserr.trojan 後續步驟同上,非常簡單。

配置好了之後用瀏覽器開個網頁測試能不能開就大概能知道是否連線順利了,雖然還是有無連線偽裝成有連線的情況跟肺炎快篩偽陽性一樣

Note: 剛剛預覽發現縮排有跑掉的情況我就懶得再去 debug 了… 或是有人知道 wordpress 怎麼縮排比較漂亮也可以分享給我感謝 ☺

分類: 未分類,標籤: , 。這篇內容的永久連結

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。