2020-09-12 更新:
V2ray config fallback -> fallbacks
2020-11-04 更新:
感谢 @John 的建议,修改 Haproxy 和 V2ray 配置,增加 Trojan 方式和获取真实 ip
我使用的是 Haproxy+Nginx/OpenResty+V2ray,和 GitHub 仓库示例不同,我没用 V2ray 处理 TLS, 用的是 Haproxy,Tcp 和 WebSocket 方式都有,仅贴出关键配置文件作为参考,客户端连接域名都为 www.example.com,端口 443
怎么安装 xxx 、怎么我没有 xxx 文件、怎么申请域名和证书、怎么配置证书,自行 google
Haproxy:
自行替换域名、证书路径,如有需要自行替换 /ray 路径
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy-stat.sock mode 660 level admin expose-fd listeners
pidfile /run/haproxy.pid
stats timeout 30s
user haproxy
group haproxy
daemon
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-dh-param-file /etc/ssl/dhparam.pem
defaults
log global
mode tcp
option dontlognull
timeout connect 15s
timeout client 300s
timeout server 300s
frontend http
mode tcp
bind *:80
bind [::]:80
tcp-request inspect-delay 5s
tcp-request content accept if HTTP
use_backend openresty_http if HTTP
frontend tls
mode tcp
bind *:443 ssl crt /etc/ssl/ecc.pem crt /etc/ssl/xx.pem alpn h2,http/1.1
bind [::]:443 ssl crt /etc/ssl/ecc.pem crt /etc/ssl/xx.pem alpn h2,http/1.1
tcp-request inspect-delay 5s
tcp-request content accept if HTTP
# V2ray 域名
acl v2ray_host hdr(host) -i www.example.com
# V2ray Websocket
acl hdr_connection_upgrade hdr(Connection) -i upgrade
acl hdr_upgrade_websocket hdr(Upgrade) -i websocket
acl websocket_path path -i /ray
use_backend v2ray_vless-ws if v2ray_host websocket_path hdr_connection_upgrade hdr_upgrade_websocket
# 将 HTTP 流量发给 web 后端
use_backend openresty_tls_http2 if HTTP { ssl_fc_alpn -i h2 }
use_backend openresty_tls_http1_1 if HTTP
# 将其他流量发给 v2ray 后端
default_backend v2ray_trojan-tcp
backend openresty_http
mode tcp
server server1 127.0.0.1:8080 send-proxy
backend openresty_tls_http1_1
mode tcp
server server1 127.0.0.1:8081 send-proxy
backend openresty_tls_http2
mode tcp
server server1 127.0.0.1:8082 send-proxy
backend v2ray_vless-tcp
mode tcp
server server1 127.0.0.1:56667 send-proxy
backend v2ray_vless-ws
mode tcp
server server1 127.0.0.1:56666 send-proxy
backend v2ray_trojan-tcp
mode tcp
server server1 127.0.0.1:56665 send-proxy
Nginx:
主配置就不贴了,贴一个虚拟机配置,自行替换域名,如有需要自行替换 /ray 路径、放置网站和添加 php-fpm 支持等
server {
server_name www.example.com;
access_log /var/log/nginx/www.example.com.log combined;
listen 127.0.0.1:8080 proxy_protocol;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
error_page 497 https://$host;
if ($scheme = http) {
return 301 https://$host;
}
}
server {
server_name www.example.com;
access_log /var/log/nginx/www.example.com.log combined;
root /srv/www/wwwroot/www.example.com;
index index.html index.htm index.php;
listen 127.0.0.1:8081 proxy_protocol;
listen 127.0.0.1:8082 http2 proxy_protocol;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-Xss-Protection "1; mode=block";
add_header Content-Security-Policy "upgrade-insecure-requests block-all-mixed-content";
}
V2ray:
自行替换 uuid 和域名以及 Trojan 密码,如有需要自行替换 /ray 路径
{
"outbounds": [{
"protocol": "freedom",
"settings": {},
"tag": "direct"
},
{
"protocol": "blackhole",
"settings": {},
"tag": "block"
}
],
"inbounds": [{
"port": 56667,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [{
"id": "uuid"
}],
"decryption": "none",
"fallbacks": [{
"alpn": "",
"dest": 8081,
"xver": 1
},
{
"alpn": "h2",
"dest": 8082,
"xver": 1
}
]
},
"streamSettings": {
"tlsSettings": {
"alpn": [
"h2",
"http/1.1"
]
},
"tcpSettings": {
"acceptProxyProtocol": true
}
}
},
{
"port": 56666,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [{
"id": "uuid"
}],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"acceptProxyProtocol": true,
"path": "/ray",
"host": ["www.example.com"]
}
}
},
{
"port": "56665",
"listen": "127.0.0.1",
"protocol": "trojan",
"settings": {
"clients": [{
"password": "password"
}],
"fallbacks": [{
"alpn": "",
"dest": 56667,
"xver": 1
}]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true
}
}
}
]
}
最后一次更新于2021-10-03
補充一下,haproxy透傳至v2ray可以用acceptproxyprotocol獲取真實IP了,更新到最新v2版本就行了,才發現。v2的fallback更簡單,haproxy就sni分流就行了
By John at 2020-10-27 11:04:17.
很好,我用的多域名做了多個項目的Sni分流。對於V2ray我是直接haproxy TCP透傳至v2進行fallback,但是這樣後端無法獲取真實IP,看了博主的配置,又有新想法了!
By John at 2020-10-27 10:26:53.