Nginx内网环境开启https双协议


前言

nginx开启https前提:

  1. 服务器支持open-ssl
  2. nginx 包含--with-http_ssl_module --with-stream --with-stream_ssl_preread_module模块

一、open-ssl

1. 验证

openssl version

2. 安装

  1. 下载openssl安装包openssl安装包
  2. 安装openssl
 mkdir /usr/local/ssl
 cd /usr/local/ssl
 # 解压
 tar -xf openssl-3.0.1.tar.gz
 # 设置SSL库文件路径
 ./config --prefix=/usr/local/ssl/
 make
 make install
vi /etc/ld.so.conf
# 最后一行添加/usr/local/ssl/ 路径
sudo ldconfig 

常见报错:openssl: error while loading shared libraries: libssl.so.10: cannot open shared object file: No such file or directory
系统版本和openssl版本不一致,具体哪里的日志记录需要的版本忘记了

3.生成ssl证书

# 第一步:生成私钥
mkdir /etc/ssl/certs/www.abc.com
cd /etc/ssl/certs/www.abc.com
openssl genrsa -des3 -out server.key 2048
# 输入一个4位以上的密码
# 确认密码
#第二步:生成CSR(证书签名请求)
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=JiLin/L=ChangChun/O=commany/OU=commany/CN=www.abc.com"
#第三步:去除私钥中的密码
#在第1步创建私钥的过程中,由于必须要指定一个密码。而这个密码会带来一个副作用,那就是在每次启动Web服务器时,都会要求输入密码
#这显然非常不方便。要删除私钥中的密码,操作如下:
openssl rsa -in server.key -out server.key
#第四步:生成自签名SSL证书
# -days 证书有效期-天
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

一、nginx

1. 验证支持模块

nginx -V

2. 安装必要模块

可以参考我之前的博客 Nginx 平滑升级

2.1 重新编译nginx

./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-pcre --with-http_gzip_static_module --with-stream --with-stream_ssl_preread_module

生成nginx二进制执行文件到当前目录 /objs

 make

2.2 替换原文件

替换

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp /usr/local/nginx-1.13.3/objs/nginx /usr/local/nginx/sbin/

验证

[root@web nginx-1.21.5]# make upgrade
/usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
sleep 1
test -f /usr/local/nginx/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`

升级

#验证模块是否加载成功
nginx -V

3. 配置https

下面是一段双协议支持的配置代码
请允许我抄袭一下小左同学的代码

stream {
    upstream http_protocol {
        # 8991端口是一个开启http的端口
        server 127.0.0.1:8991;
    }
    upstream https_protocol {
        # 10002端口是一个开启https的端口
        server 127.0.0.1:10002;
    }
    # 根据不同的协议走不同的upstream
    map $ssl_preread_protocol $upstream {
        default http_protocol;
        "TLSv1.0" https_protocol;
        "TLSv1.1" https_protocol;
        "TLSv1.2" https_protocol;
        "TLSv1.3" https_protocol;
    }
    server {
        listen 8990;
        ssl_preread on;
        proxy_pass $upstream;
    }
}
  server {
        listen 10002 ssl;
        server_name www.xxx.com;
        ssl_certificate /etc/ssl/certs/www.abc.com/server.crt;
        ssl_certificate_key /etc/ssl/certs/www.abc.com/server.key;
        #减少点击劫持
        #add_header X-Frame-Options DENY;
        add_header X-Frame-Options AllowAll;
        #禁止服务器自动解析资源类型
        add_header X-Content-Type-Options nosniff;
        #防XSS攻击
        add_header X-Xss-Protection 1;
        #优先采取服务器算法
        ssl_prefer_server_ciphers on;
        #协议
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        location / {
            proxy_pass http://127.0.0.1:8991/;
        }
    }

在这里插入图片描述

总结

  1. openssl: error while loading shared libraries: libssl.so.10: cannot open shared object file: No such file or directory
    这个问题是很大的难点,排查好久才找到一个对应版本安装成功(我的是麒麟银河V10,版本OpenSSL 1.1.1f),关键是怎么找到对应版本的过程当时没有记录,现在也想不起来了,😫
  2. open-ssl验证时本地发现有open-ssl,所以就跳过了第一步 结果nginx make报错
make -f objs/Makefile
make[1]: Entering directory '/opt/nginx-1.21.5'
cd /usr/local/ssl/ \
&& if [ -f Makefile ]; then make clean; fi \
&& ./config --prefix=/usr/local/ssl//.openssl no-shared no-threads  \
&& make \
&& make install_sw LIBDIR=lib
/bin/sh: line 2: ./config: No such file or directory
make[1]: *** [objs/Makefile:1447: /usr/local/ssl//.openssl/include/openssl/ssl.h] Error 127

OpenSSL源代码未正确指定:在Nginx的配置过程中,你可能没有正确指定OpenSSL的源代码目录。你需要确保–with-openssl选项指向的是OpenSSL的源代码目录,而不是安装目录。
上传openssl-1.1.1f.tar.gz包(和验证时的版本一致即可)解压后指定–with-openssl到解压目录--with-openssl=/opt/openssl-1.1.1f

./configure \
  --prefix=/usr/local/nginx \
  --user=nginx \
  --group=nginx \
  --with-pcre \
  --with-openssl=/opt/openssl-1.1.1f \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_realip_module \
  --with-http_addition_module \
  --with-http_sub_module \
  --with-http_dav_module \
  --with-http_flv_module \
  --with-http_mp4_module \
  --with-http_gunzip_module \
  --with-http_gzip_static_module \
  --with-http_random_index_module \
  --with-http_secure_link_module \
  --with-http_stub_status_module \
  --with-http_auth_request_module \
  --with-http_image_filter_module \
  --with-mail \
  --with-threads \
  --with-mail_ssl_module \
  --with-stream_ssl_module \
  --with-stream --with-stream_ssl_preread_module \
 && make
  1. 双协议不支持获取访问ip穿透
    更改为https或者http单协议可获取到客户端访问ip,如果代理中包含websocket需要把响应代理放到和ssl配置的配置文件中
    关键配置:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

nginx.conf 示例


user root;
worker_processes auto;
error_log /usr/local/nginx/logs/error.log;

events {
    worker_connections  1024;
}

http {
    # log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                   '$status $body_bytes_sent "$http_referer" '
    #                   '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  main  '$year$month$day $hour:$minutes:$seconds ' '[$status] ' '【$http_x_forwarded_for $remote_addr $http_host】' '[$request_uri] ' ;

    access_log  /usr/local/nginx/logs/access.log  main;
	
    underscores_in_headers on;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include /etc/nginx/mime.types;
    client_max_body_size 10m;

    default_type        application/octet-stream;
    #default_type         text/html;


    #gzip
    gzip on;
    gzip_min_length 1024;
    gzip_comp_level 6;
    gzip_types text/plain application/json application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml  font/woff;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    gzip_buffers 32 16k;
    gzip_http_version 1.0;

    include /usr/local/nginx/conf/conf.d/*.conf;

     server {
	    listen 8990 ssl;
		server_name www.bbcc.com;
        ssl_certificate /etc/ssl/certs/www.bbcc.com/server.crt;
        ssl_certificate_key /etc/ssl/certs/www.bbcc.com/server.key;
        #减少点击劫持
        #add_header X-Frame-Options DENY;
        add_header X-Frame-Options AllowAll;
        #禁止服务器自动解析资源类型
        add_header X-Content-Type-Options nosniff;
        #防XSS攻击
        add_header X-Xss-Protection 1;
        #优先采取服务器算法
        ssl_prefer_server_ciphers on;
        #协议
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        # 自定义时间变量
		if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {
			set $year $1;
			set $month $2;
			set $day $3;
			set $hour $4;
			set $minutes $5;
			set $seconds $6;
		}

        location / {
            autoindex off;
        	proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://172.168.18.31:8990/;
        }
        
        location /gws {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_pass http://172.168.18.31:8990;
        }
    }
    
}

在这里插入图片描述

### 内网环境中配置和实施HTTPS的方法 #### 1. 获取SSL证书 为了确保通信的安全性和可信度,获取有效的SSL/TLS证书至关重要。对于生产环境,建议购买由受信任的第三方CA签发的商业证书;而对于测试或开发环境,则可以考虑自签名证书。 - 商业证书通常需要验证域名所有权和其他相关信息。 - 自签名证书虽然免费但不受浏览器默认信任列表支持,在实际应用中可能引起警告提示[^2]。 #### 2. 安装Web服务器并启用SSL模块 根据所使用的操作系统选择合适的Web服务器软件(如Apache HTTP Server、Nginx),然后按照官方文档完成安装过程,并开启相应的SSL加密协议支持: ```bash # 对于Debian/Ubuntu系统下的Apache服务 sudo apt-get install apache2 openssl a2enmod ssl ``` ```bash # 对于CentOS/RHEL系统的Nginx服务 yum install epel-release yum install nginx mod_ssl ``` #### 3. 配置虚拟主机以监听443端口 编辑站点配置文件来指定HTTPS访问规则,使Web服务器能够在TCP 443端口上接收请求并将流量转发给后端应用程序处理。以下是基于Nginx的一个简单例子: ```nginx server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/cert/example.crt; # 替换为自己的路径 ssl_certificate_key /etc/nginx/cert/example.key; # 替换为自己的路径 location / { proxy_pass http://localhost:8080; # 假设后端运行在8080端口 ... } } ``` #### 4. 设置防火墙规则允许外部访问 如果希望从Internet直接访问内网中的HTTP(S)资源,则还需要调整路由器上的端口映射表项以及Linux防火墙策略,开放必要的入站连接权限以便让来自公网的数据包顺利抵达目标机器。 ```bash firewall-cmd --permanent --add-service=https firewall-cmd --reload ``` #### 5. 测试与优化性能表现 最后一步是对整个部署流程进行全面的功能性检测,确认所有组件都能正常工作之后再逐步引入更多复杂的特性比如会话缓存、OCSP stapling等进一步提升用户体验的同时也增强了安全性保障水平。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr-Wanter

感谢大佬

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值