请选择 进入手机版 | 继续访问电脑版

『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 251|回复: 17

[经验分享] 适合小白使用Nginx的安装和配置

[复制链接]

12

主题

122

帖子

569

积分

论坛分享达人

积分
569
金钱
447
HASS币
30
发表于 2020-3-21 12:59:29 | 显示全部楼层 |阅读模式
本帖最后由 姚远 于 2020-3-21 13:18 编辑

首先鸣谢网上各路大神,我这里都是从大神那里搬过来的,并把我迈过的坑填好,给初学小白一个参照。跟着我来,小白的你一定有所收获。
为什么要使用Nginx代理
在家庭智能化应用过程中,我们难免需要与外网进行信息交互。如果仅仅是访问外网,我们现在光猫+路由器+wifi的机制完全可以胜任。但如果需要外网访问内网的时候,比如智能音箱需要读到我们内网的hass主机,企业微信推送hass消息也需要腾讯读到我们的内网消息。此时这个机制就不足了。当外网需要https安全访问内网时,我理解需要至少走两步,第一步穿透到内网中来,打通网络通道。第二步进行ssl验证,否则https是不能访问的。

那Nginx可以做什么?它本质上就是一个外网到内网的”桥“,通过这个桥,你就可以安全的内网互通,尤其是可以通过自定义端口,将一个域名、自定义不同端口,访问到内网不同的服务器、不同的应用。

image-20200321075502590.png

所以,nginx很强大。但要特别注意一点,你的外网必须可以穿透进来。否则一切都是废话,白忙活
外网穿透进来的必要条件:你的进户ip必须可以在外网访问得到。百度搜索输入”ip“,看看是你家光猫进口的ip吗?如果不是,找运营商开通。”喂,我家有智能设备应用,需要给我开通公网ip“,就这么简单。

另外一个问题,我的hass应用可以配置https,我还需要这个”桥“吗?说说我的惨痛教训。
我之前由于种种原因,外网穿透进来之后,在hass中直接配置了https认证,一切应用还不错。但接下来出现麻烦了。在启用hass配置https外网访问后,hass运行全程需要ssl认证,这就导致node-red,esphome等与hass集成的内网应用出现各种状况。尤其是esphome是为hass配套的固件系统,没有找到其与ssl相关的处理方式,彻底不能用了。不得已必须取消hass的ssl认证的运行方式。此时花生棒等ddns服务也是一个很好的选择。但花生棒绑定的https服务,只能一个棒对应一个https应用,而hass和微信的集成应用时,企业微信如果要安全接入进来,就会遇到外网端口不够的情况。

至此,就需要一个决策,hass要非ssl运行方式,家里对外网端口又需要可以承担多个应用的穿透。Nginx可能是一个比较好的选择。尤其是nginx网上教程较多,虽然配置有些麻烦,但反向代理,可以为今后多个内网穿透提供统一的服务。我选择nginx做什么?就是建立一个代理服务器,一个桥,将内外网进行安全转发。内网应用不做变化,外网应用可安全映射到内网应用上。
安装nginx
想明白了,就开始安装吧。我是树莓派3,没有docker,直接安装。
1 安装
网上安装教程很多,官网教程更较详细。我是参考:树莓派安装Nginx,
sudo apt-get install nginx
2 启动
 sudo /etc/init.d/nginx start

3 测试安装是否成功
nginx默认端口:80
浏览器访问自己安装nginx服务器的ip+80,比如,http://192.168.1.3:80
看到如下页面,nginx就安装成功了
image-20200321082428866.png
4 简单试运行
1 目的:体会和理解nginx的运行机制。
 sudo nano /etc/nginx/sites-available/default
2 修改其中一段代码,其他不要动,不要动,不要动
找到server下面的listen行:修改两处的监听端口。就是试试原先80端口,现在改为8888端口,体会nginx是做什么的

image-20200321082958426.png

3 保存配置,重新启动nginx服务
 sudo /etc/init.d/nginx reload
4 浏览器上访问,你的ip:8888   如果能看到刚才的欢迎页面,就是说明端口转发了。如果没看到,那回过头看看配置中的端口是8888吗?是哪个端口号,你浏览器就输入哪个端口号。

5 设置开机自启动服务
1 设置开机启动
 systemctl enable nginx.service
2 启动nginx服务
 systemctl start nginx.service
3 设置开机自启动
 systemctl enable nginx.service
4 其他服务命令

需要的时候再有针对性的执行这些命令

  • 停止开机自启动

systemctl disable nginx.service     # 停止开机自启动

  • 查看服务当前状态

 systemctl status nginx.service

  • 重新启动服务

 systemctl restart nginx.service

  • 查看所有已启动的服务

 systemctl list-units --type=service


简单配置试验

建议小白一定要做,一定要做,一定要做。
为什么小白要做?因为坑来了,很大很大,但又是很简单很简单。还有一个要做的原因,深入理解nginx能做啥,怎么做的。这不需要我们成为专家,但至少要知道出问题会是哪里,抄大神配置的时候怎么抄,自己搞点小配置怎么配。我是磕磕碰碰,在这里绕了几个月都没有出来。人太笨了。

外网访问路由器
路由器是外网入户的第一关,进门就是路由器,所以你必须要能访问到了。之后,你用https访问,ssl验证就需要nginx了。所以,这里的外网访问是说https访问。

目标:理解ssl的配制方法,以及通过外网https访问路由器。

要真正配置nginx了,第一个坑来了,最大最大的坑。就是网上看的所有教程,都是配置的片段,而不是全部。如果你把这个片段拷贝成你的配置文件,你就和我一样,死定了。
我理解nginx分为四大部分,初始块、events、http、server。初始块、events、http三大块,就先认为是全局的、固定的,以后碰到具体问题再去看他们。我们需要配置的,也是网上各种教程配置的,基本都是server块。所以,一定一定先盯住server{},其他三大块暂时不动。这就是坑!

修改配置文件,是/etc/nginx/sites-available/default还是/etc/nginx/nginx.conf。应该是/etc/nginx/sites-available/default文件。但是我之前犯了一个错误,将/etc/nginx/nginx.conf全面替换为只有server{}的内容,导致无法启用/etc/nginx/sites-available/default配置文件。虽然后面重新进行了补充和修改,但没有再启用/etc/nginx/sites-available/default,而是将所有的配置都放到了/etc/nginx/nginx.conf文件中。所以我后面的配置都是在/etc/nginx/nginx.conf做的。各位如果安装之后立即配置,应该在/etc/nginx/sites-available/default中。nginx基础配置文件中有句话,将详细配置指向了/etc/nginx/sites-available/default文件。但我由于初始时破坏了源文件,也找不到这句话的位置了。所以,都在/etc/nginx/nginx.conf文件里进行的配置,以后有机会再改吧。
保持其他三大块不动,配置外网https访问路由器。
注释掉原先的server{}的内容,替换为:
server {
  server_name 你已经ssl认证过的域名;
  listen 你在路由器端口转发到内网的端口号 ssl;
  ssl_certificate /etc/nginx/cert/你的ssl证书的pem文件名;
  ssl_certificate_key /etc/nginx/cert/你的ssl证书的key文件名; 
  ssl_prefer_server_ciphers on;
  location / {
    proxy_ssl_server_name on;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $host:$server_port;
   proxy_pass http://你的路由器ip;
      }
注意几点

image-20200321092036181.png

  1. 运营商封了你的端口号?你一个域名想访问多个应用?没关系你在外网访问的时候加上端口号就行了。经过路由器映射进来,在nginx还可以映射一次,转向你的应用。
     我的整体访问配置就是:

  • 外网浏览器上,https://abc.com:9001
  • 路由器配置端口映射:9001 --> 192.168.3.nginx服务器ip:9001
  • nginx反代:abc.com, 9001, ssl, 到 192.168.3.1

  2. ssl,加上这个就是https访问。如果直接写”listen 9001“,是http访问,就不需要ssl了。
  3. ssl证书尽量放在nginx之下,否则读写这个文件的权限问题就能搞死小白
  4. location下的内容,暂时理解为就是你内网代理的一堆设置。那个http已经是内网的了,所以按照内网配置就可以了。

我的是在/etc/nginx/nginx.conf文件配置的,完整的nginx.conf文件内容如下:
#user root;
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;
   keepalive_timeout 65;

    #gzip on;

   server {
      server_name 你的ssl认证并可解析的域名;
      listen 9001 ssl;
      ssl_certificate /etc/nginx/cert/cert_nginx.pem;
      ssl_certificate_key /etc/nginx/cert/cert_nginx.key; 
      ssl_prefer_server_ciphers on;
      location / {
         proxy_ssl_server_name on;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $host:$server_port;
         proxy_pass http://192.168.3.1;
      }
   } 
}


插播ssl证书的下载和安装
在配置路由器https访问之前,我们应该已经下载并安装好了ssl证书。这里插播这个章节,主要是很多像我一样的小白会在这里迷茫,会犯错误。所以在这里特别提出来进行补充。
请先确保你已经申请ssl证书,验证通过,并绑定域名,可以进行正常解析,解析是正确的,可以通过http访问进你的内网。可以访问进内网,说明你外网穿透成功了,才可以进行后续的nginx。注意,此时的访问是没有配置nginx之前的访问,我这里的章节是插播的。

1. 下载ssl证书
下载证书,nginx版:下载域名所对应的ssl证书;下载nginx版
image-20200321100038014.png

2. 解压并放置到nginx服务器

  • 解压文件,获得pem和key两个文件
  • 给文件改个较短的文件名
  • 上传到树莓派nginx,/etc/nginx/cert/
  • 修改文件的权限

    • 改变所属群组, chgrp

    sudo chgrp 用户组 文件名

    • 改变档案拥有者,chown

    sudo chown 用户 文件

3. 检查ssl证书的文件名、放置目录,是否与nginx配置文件相符

image-20200321100547469.png


重启nginx访问路由器
  • 重启nginx

sudo nginx -s reload
  • https访问路由器
    https://我的域名:9001
  • 手机断掉wifi访问路由器,看看是不是真的是外网访问进来的
  • 内网ip访问路由器,看看是不是真的内网没有受到影响。http://192.168.3.1

外网访问hass
配置文件/etc/nginx/nginx.conf
注意,你的配置文件应该是/etc/nginx/sites-available/default
这个配置相对比较复杂,要特别注意几点:

  1. 有一部分内容放到了server之外,http块下,这个要注意
image-20200321104000808.png
  2. server{}中listen监听的端口,是你路由器映射之后的端口,别搞错了。

  我的路由器映射端口
image-20200321105246671.png

  我的nginx配置端口
image-20200321103741459.png
        我在外网访问方式:https://abc.com:3352

  3. server{}中listen监听,我只启用了ssl,也就是只有https服务才过nginx。我不打算外网http访问。
  4. server{}中location的ip和端口,是你内网访问的端口,内外有别,这里配置内网的。

image-20200321104139654.png

完整的配置文件
直接上完整的配置文件,免得小白走我的坑。注意,我是在/etc/nginx/nginx.conf下的配置。你在下的配置文件/etc/nginx/sites-available/default可能只需要其中的server{}部分。由于我前面犯的错误,找不到原始的/etc/nginx/nginx.conf文件了,不知道里面的配置是哪一段指向了你的配置文件。请千万千万注意。
#user root;
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;
    keepalive_timeout 65;
​
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
​
     #gzip on;
​
    server {
       server_name 你的ssl认证并可解析的域名;
       listen 9001 ssl;
       ssl_certificate /etc/nginx/cert/cert_nginx.pem;
       ssl_certificate_key /etc/nginx/cert/cert_nginx.key; 
       ssl_prefer_server_ciphers on;
       location / {
          proxy_ssl_server_name on;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header X-Forwarded-Proto $scheme;
             proxy_set_header Host $host:$server_port;
          proxy_pass http://192.168.3.1;
       }
    } 
​
​
    server {
      listen 3352 ssl http2;
      ssl_certificate /etc/nginx/cert/cert_nginx.pem;
      ssl_certificate_key /etc/nginx/cert/cert_nginx.key; 
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
      ssl_prefer_server_ciphers on;
      ssl_session_timeout 10m;
      ssl_session_cache builtin:1000 shared:SSL:10m;
      ssl_buffer_size 1400;
      add_header Strict-Transport-Security max-age=15768000;
      ssl_stapling on;
      ssl_stapling_verify on;
      server_name 你的ssl认证并可解析的域名;
      access_log /var/log/nginx/你的ssl认证并可解析的域名_nginx.log combined;
      error_log /var/log/nginx/你的ssl认证并可解析的域名_nginx.error.log debug;
      index index.html index.htm index.php;
      if ($ssl_protocol = "") {
          return 301 https://$host$request_uri; 
      }
   
      #error_page 404 /404.html;
      #error_page 502 /502.html;
      charset utf-8; #默认编码方式
      client_max_body_size 75M;
​
      # 其他的请求全部交给Python的uWSGI来处理
      location / {
       proxy_pass http://127.0.0.1:8123;
       proxy_set_header Host $host;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection $connection_upgrade;
      }
    }
}

如果你的配置文件三大公共块和我配置不一样,不用管他,盯住server{}部分就行了。

重启nginx访问路由器
  • 重启nginx

sudo nginx -s reload

  • https访问路由器
    https://我的域名:3352
  • 手机断掉wifi访问路由器,看看是不是真的是外网访问进来的
  • 内网ip访问hass,看看是不是真的内网没有受到影响。http://192.168.3.我的内网hassip:8123

配置hass,使得小度音箱可用
完全内网配置,不需要配置http,不需要ssl配置,内网ip访问配置

image-20200321105951474.png
注意:
  • 如果你之前配置过havcs,采用现在”内网方式“时,可能需要在hass服务器中,重新下载havcs插件

  • 可能百度技能需要重新授权


至此,小白nginx基本应用就告一段落了。后面我在集成企业微信、简单图片服务器都使用到了nginx,而且配置都很简单。就是网上的教程太坑人了。小白们一起交流吧





评分

参与人数 1金钱 +20 HASS币 +10 收起 理由
+ 20 + 10 教程很详细,楼主辛苦了!

查看全部评分

回复

使用道具 举报

13

主题

400

帖子

2041

积分

金牌会员

Rank: 6Rank: 6

积分
2041
金钱
1641
HASS币
0
发表于 2020-3-21 14:10:17 | 显示全部楼层
好复杂 群晖咋用 能用docker安装吗
回复

使用道具 举报

12

主题

122

帖子

569

积分

论坛分享达人

积分
569
金钱
447
HASS币
30
 楼主| 发表于 2020-3-21 15:08:51 | 显示全部楼层
nuaawmy 发表于 2020-3-21 14:10
好复杂 群晖咋用 能用docker安装吗

docker看看这位大神的https://bbs.hassbian.com/thread-6893-1-1.html
不是复杂,是一脚跨入了网络行业。我蒙头转向搞了好长时间才明白了一点,仅作参考吧
回复

使用道具 举报

47

主题

745

帖子

2781

积分

金牌会员

Rank: 6Rank: 6

积分
2781
金钱
2036
HASS币
10
发表于 2020-3-21 18:27:19 | 显示全部楼层
问一下,既然开通外网ip,外网ip能访问进来,在路由器上做个端口转换不就行了吗?为什么要用反代理?
回复

使用道具 举报

8

主题

328

帖子

919

积分

高级会员

Rank: 4

积分
919
金钱
591
HASS币
0
发表于 2020-3-21 18:45:18 | 显示全部楼层
还是没看明白。不过终于知道为什么我nr  群晖装得就是死活不能和n1 装的hassio联通了
回复

使用道具 举报

12

主题

122

帖子

569

积分

论坛分享达人

积分
569
金钱
447
HASS币
30
 楼主| 发表于 2020-3-21 18:58:34 | 显示全部楼层
xuyang 发表于 2020-3-21 18:27
问一下,既然开通外网ip,外网ip能访问进来,在路由器上做个端口转换不就行了吗?为什么要用反代理? ...

现在的配置就是为了https访问。外网安全访问到服务器,需要安装ssl证书,那就需要你有一个认证过程。现在配置的就是在nginx中统一认证,然后谁的端口就转发到谁的服务器和端口上。现在很多外网应用都要https访问,这就要我们必须有这个桥了。如果外网可以http访问,这个就用处不大。当然nginx还有很多很多用途,而现在的配置只是软门,构成https访问。
外网穿透到内网解决了硬通道,而这个nginx现在的配置就是软门,不认证不让你访问到服务器。
回复

使用道具 举报

9

主题

66

帖子

281

积分

论坛分享达人

积分
281
金钱
215
HASS币
0
发表于 2020-3-21 19:08:59 | 显示全部楼层
帖子真不错。我找了几个教程 东平西凑的看。一直配置有问题
回复

使用道具 举报

47

主题

745

帖子

2781

积分

金牌会员

Rank: 6Rank: 6

积分
2781
金钱
2036
HASS币
10
发表于 2020-3-21 19:32:32 | 显示全部楼层
姚远 发表于 2020-3-21 18:58
现在的配置就是为了https访问。外网安全访问到服务器,需要安装ssl证书,那就需要你有一个认证过程。现在 ...

我也是用的https,阿里云的免费ssl,ha和nodered是两台服务器,就是通过路由来做的地址转换。
回复

使用道具 举报

2

主题

7

帖子

52

积分

论坛分享达人

积分
52
金钱
45
HASS币
0
发表于 2020-3-21 19:33:44 | 显示全部楼层
写得不错,作者用心了。

外网访问涉及到的知识点比较多,需要对网络比较熟悉。

运营商分配的ip很多是内网ip,需要申请开放公网ip
公网ip也是动态分配的,经常变化。
80端口被封,https证书的认证也是个问题。

我写了一个动态域名的小工具,大家可能用得上呵。
https://www.cnblogs.com/flyfire-cn/p/10381298.html
回复

使用道具 举报

2

主题

179

帖子

483

积分

论坛分享达人

积分
483
金钱
304
HASS币
0
发表于 2020-3-21 21:03:01 来自手机 | 显示全部楼层
请问一下,ipv6开https一样的配置吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2020-4-2 10:27 , Processed in 0.131758 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表