首页
留言
动态
归档
推荐
音乐
工具
Search
1
Emby公益服-上万部电影电视剧免费看
64,073 阅读
2
openwrt-docker部署lxk0301京东自动签到脚本
12,679 阅读
3
QuantumultX-京东签到撸京东豆
11,042 阅读
4
LXK0301京东签到脚本-自动提交互助码
9,452 阅读
5
微信-域名被封监测以及自动更换被封域名
9,071 阅读
随便写写
科学上网
Web开发
瞎折腾
Search
标签搜索
quantumultx
laravel
openwrt
laravel nova
laradock
telegram
薅羊毛
google adsense
jd_scripts
京东签到
ubuntu
oh-my-zsh
web开发环境
nginx
工具
shadowsocks shadowsocksR
RBAC
权限管理
内网穿透
Python
orzlee
累计撰写
44
篇文章
累计收到
595
条评论
首页
栏目
随便写写
科学上网
Web开发
瞎折腾
页面
留言
动态
归档
推荐
音乐
工具
搜索到
2
篇与
nginx
的结果
2021-04-13
Nginx SNI 分流(端口复用)使用Xray+VLESS+XTLS
前言 Xray已经出来一段时间了,之前一直使用VLESS+tls+ws方式科学上网,其实都够用,没什么问题。但是了解了下XTLS黑科技,再看看Xray性能测试,这货简直爆炸,性能是TLS的数倍。 其实之前折腾过一次,但是Xray要监听443端口(不监听也行,但是不完美啊),影响做站。虽然有解决方法,但是不够完整,我一不小心就跳坑里面去了。Xray已经带了SNI回落功能(教程看这里:通过 SNI 回落功能实现伪装与按域名分流),Nginx也带SNI功能,我还是觉得用Nginx的比较好,免得折腾Xray影响网站运行。 这里我不会写如何安装Xray,因为教程实在是太多了,嫌麻烦还有一键脚本:Xray_onekey(V2ray脚本别用这个作者的哈,特别是服务器有站点的!!!Xray脚本这个大佬的还不错)。 坑 因为服务器上有几个站点,装完Xray后实现SNI分流,过程非常顺利,但是chrome上有问题,几个二级域名访问的内容全部和第一个访问的域名一样。 例如:我先访问 a.example.com 然后在访问 b.example.com,b.example.com 响应内容和 a.example.com 一模一样,然后再访问 c.example.com 还是和 a.example.com 一样。开chrome隐身模式直接访问 c.example.com 正常,然后访问 a.example.com 或 b.example.com 内容又全是 c.example.com 的(不一定会每次都这样,要看浏览器是否使用现有连接或服务器是否断开了之前的连接)。 这个问题折腾我很长时间,最后发现和HTTP/2有关,我所有站点不使用HTTP/2就会正常,只要有一个站点使用了HTTP/2,你先访问HTTP/2站点,那么后面的其他子域名都会变成它的内容。这个情况没有仔细测试证明,无法确定。 最开始我使用Xray的SNI也是这样,我还以为是Xray SNI的问题,之后换成Nginx使用SNI还是这样。chrome中有这个问题,用手机safari浏览器完全正常。 经过网上一番搜刮,终于找到了问题根源:通配符域名证书。 首先你得了解什么是SNI,个人理解:SNI就是通过证书区分服务。多个二级域名使用通配符域名证书的话,相同的证书无法区分具体想访问的服务,因为它们的证书都一样。 用下人家的图(原作者文章:Multiplex TLS Traffic with SNI Routing): *由于原始服务器10.0.3.2使用的TLS证书具有通配符名称 .example.com,因此Web浏览器可以建立服务器名称为 b.example.com 的 TLS连接,并对HTTP/2请求使用相同的连接到 a.example.com。这可能会在网站和应用程序中导致未定义的行为。** 因为HTTP/2会保持TCP连接,导致你访问了 a.example.com 后,在访问 b.example.com 的时候使用的同一个连接,SNI跟失效了一样,直接使用该连接访问之前的服务。我在Xray的调试日志中发现访问错误的域名没有获取到,是空的! 两个域名使用同一个连接(红框内是连接ID),可以很清楚的看到两个域名使用同一个连接,返回的内容也是一模一样: 解决办法两种: 不使用HTTP/2。不确定是否HTTP2的问题,但是你可以试一试 不使用通配符域名证书,站点域名证书一个个申请。 配置Nginx SNI 使用Nginx首先得安装(如果服务器自带就不用折腾了),不会安装Nginx可以看我之前的文章:Ubuntu 安装nginx(如果使用Xray_onekey脚本,那他已经帮你全部弄好了,你都不用折腾)。 nginx.conf配置追加: stream { map $ssl_preread_server_name $orzlee { a.example.com a; b.example.com b; c.example.com c; } upstream a { server 127.0.0.1:60088; ### A站点监听端口,xray xtls伪装站点 } upstream xtls { server 127.0.0.1:4443; ### 你的Xray端口 } upstream b { server 127.0.0.1:60001; ### B站点监听端口,业务站点 } upstream c { server 127.0.0.1:60002; ### C站点监听端口,业务站点 } server { listen 443 reuseport; listen [::]:443 reuseport; proxy_pass $orzlee; ssl_preread on; proxy_protocol on; } server { ### Xray XTLS listen 127.0.0.1:60088 proxy_protocol; proxy_pass xtls; } } a.example.com.conf配置(伪装站点): server { listen 80; listen [::]:80; server_name a.example.com; return 301 https://$http_host$request_uri; } server { ### 伪造站点由Xray处理SSL listen 127.0.0.1:60003 proxy_protocol; ### xray http/1.1 listen 127.0.0.1:60004 http2 proxy_protocol; ### xray http/2 set_real_ip_from 127.0.0.1; real_ip_header proxy_protocol; port_in_redirect off; ###重定向去掉端口号 server_name a.example.com; index index.html index.htm index.php default.php default.htm default.html; root /var/www/a.example.com; ... } b.example.com.conf配置(其他业务站点配置照葫芦画瓢): server { listen 80; server_name b.example.com; rewrite ^(.*) https://b.example.com$1 permanent; } server { listen 127.0.0.1:60001 proxy_protocol ssl http2; set_real_ip_from 127.0.0.1; ### 获取真实客户IP,不然全是127.0.0.1 real_ip_header proxy_protocol; port_in_redirect off; ###重定向去掉端口号。不然类似 try_files nginx帮你重定向时,你浏览器上都带了60003这样的端口 ssl_certificate b.example.com.cer; ### 证书换成你的 ssl_certificate_key b.example.com.key; ### 证书换成你的 server_name b.example.com; root /var/www/b.example.com; index index.php index.html index.htm; ... } 配置Xray 服务端配置: { "log": { "access": "/var/log/xray/access.log", "error": "/var/log/xray/error.log", "loglevel": "warning" }, "inbounds": [ { "listen": "127.0.0.1", "port": 4443, "protocol": "vless", "settings": { "clients": [ { "id": "你的UUID", "flow": "xtls-rprx-direct" } ], "decryption": "none", "fallbacks": [ { "dest": 60003, "xver": 1 }, { "dest": 60004, "alpn": "h2", "xver": 1 } ] }, "streamSettings": { "network": "tcp", "security": "xtls", "xtlsSettings": { "alpn": [ "h2", "http/1.1" ], "minVersion": "1.3", "certificates": [ { "certificateFile": "b.example.com.cer 记得换证书", "keyFile": "b.example.com.key 记得换证书" } ] } }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } } ], "outbounds": [ { "protocol": "freedom" } ] } 客户端看作者说明吧,值得一看:Outbounds 可用协议列表-VLESS,flow仔细看看。 结语 本来折腾Xray的,结果Nginx折腾大半天。虽然掉坑里了,总算是爬出来了,受益匪浅! 通配符证书用起来省事,碰到坑了一下还不好找问题。就今天这个坑上网找都不知道怎么描述,基本上找不到相关问题,比较冷门。之前参考其他博主Nginx SNI配置发现有其他同学也有这样的问题,但是无从查起,不了了之! 遇到这个坑不长记性都难。
2021年04月13日
8,109 阅读
52 评论
3 点赞
2018-11-23
Ubuntu 安装nginx
前言 开发期间经常需要搭建环境,网上也有很多集成环境,但是我还是推荐自己搭建。做开发的还是需要最基础的技能,开发人员不愿意折腾,难道让用户去折腾吗? nginx nginx是轻量级但非常强大的异步框架Web服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势,官方测试支持五万个并发连接。了解更多信息前往维基百科-Nginx。 安装 安装方法分为两种,编译安装和linux packages安装。linux packages安装非常方便,但是如果需要第三方扩展还是非常麻烦的。 编译安装 从Nginx news下载最新的安装包(当然也可以下载其他版本的安装包). wget http://nginx.org/download/nginx-1.15.6.tar.gz 解压安装包 tar -zxvf nginx-1.15.6.tar.gz 进入文件夹 cd nginx-1.15.6 安装编译工具和依赖库 apt install build-essential apt install libpcre3-dev zlib1g-dev libssl-dev 编译安装 ./configure --prefix=/usr --conf-path=/etc/nginx --user=www-data --group=www-data make sudo make install 安装完成后配置文件在/etc/nginx目录下,执行文件在/usr/sbin目录下。 可以在编译时指定模块,方便扩展(以下是apt安装nginx配置参数): ##安装依赖 apt install libxml2 libxml2-dev libxslt1-dev libgdchart-gd2-xpm libgdchart-gd2-xpm-dev libgeoip-dev ##配置 ./configure --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module 如果找不到nginx的话,配置下环境变量: nano /etc/profile ##末尾加入 export PATH="$PATH:/usr/share/nginx/sbin" 恢复/etc/nginx/目录方法: sudo apt purge nginx-common apt install nginx-common 更多./configure配置信息可以去nginx configure查看,相关文档nginx documentation。 从linux packages安装 直接安装会安装比较老旧的版本。 sudo apt install nginx 安装nginx-signing.key For Debian/Ubuntu, in order to authenticate the nginx repository signature and to eliminate warnings about missing PGP key during installation of the nginx package, it is necessary to add the key used to sign the nginx packages and repository to the apt program keyring. Please download this key from our web site, and add it to the apt program keyring with the following command: 对于Debian / Ubuntu,为了验证nginx存储库签名并在安装nginx包期间消除有关丢失PGP密钥的警告,有必要将用于签署nginx包和存储库的密钥添加到apt程序密钥环。请从我们的网站下载此密钥,并使用以下命令将其添加到apt程序密钥环: wget http://nginx.org/keys/nginx_signing.key sudo apt-key add nginx_signing.key 添加官方源 echo "deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx">> /etc/apt/sources.list echo "deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx">> /etc/apt/sources.list 更新源并安装nginx apt update apt install nginx 至此,nginx就安装完成了,配置文件在/etc/nginx目录下。 配置 如果nginx主进程使用root运行,那么nginx 将会调用 setuid()/setgid() 去设置 user/group。如果 group 没有特别指定,那么 nginx 会使用 user 相同的名称设置 group。默认为 nobody nogroup 或者安装nginx的时候在 ./configure 指定的 --user=USER 和 --group=GROUP 由于是linux packages安装,安装好nginx之后首先需要修改nginx user。 nano /etc/nginx/nginx.conf ##指定user为www-data user www-data; nano保存修改退出 保存 Ctrl+o 确认修改 Enter 退出 Ctrl+x 重启nginx sudo service nginx restart 新站点 个人喜欢使用配置域名命名配置文件www.example.com。 新建一个配置文件 nano /etc/nginx/conf.d/www.example.com.conf ###内容 server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; root /var/www/web_site/public; ##修改为自己站点目录 index index.php index.html index.htm; server_name server_domain_or_IP ##修改为自己的域名(www.example.com example.com); location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri /index.php =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } 每次创建新的站点配置文件,或者修改配置文件都要养成好习惯。先测试,再重载,特别是线上环境。 nginx -t nginx -s reload 现在可以去浏览器测试自己的站点是否配置正确,正常访问了。 结语 orzlee以前也使用Apache,那时候还在用C#开发,接触PHP的后才慢慢转向nginx。同行中也有不少在使用Apache,其实都各有优缺点。个人觉得nginx比Apache要简单,性能方面nginx要优于Apache。orzlee服务器主要使用Ubuntu 16.04。
2018年11月23日
3,082 阅读
0 评论
1 点赞