在阿里云服务器ECS上搭建SSL+Git+Docker环境(二)

服务器   2024-09-23 10:40   467   0  

更换完操作系统后,需要安装 Nginx + SSL ,实现使用 http/https 访问系统,自动强制将 http 转为 https,提高访问的安全性。SSL 的实现需要域名证书的配合。

一、安装 Nginx 并配置

这里需要注意安装后的 Nginx 与后面 Docker 容器里的 Nginx 需要使用相同的用户和组,否则会存在用户不一致导致权限不匹配,无权访问文件的问题。

1、准备用户组、用户,和 docker 容器中的用户匹配,解决挂载目录权限的问题

#查看所有组和用户
cat /etc/group
cat /etc/passwd

#指定 gid 添加用户组
groupadd -g 102 nginx

#指定uid添加用户,并加入上面创建的用户组中
useradd -u 101 -g nginx nginx


2、安装nginx

yum install -y nginx


3、设置 nginx 开机自启动,并启动 nginx

systemctl enable nginx
systemctl start nginx


4、配置 nginx

修改 nginx 的全局配置

vi /etc/nginx/nginx.conf

一份示例 nginx.conf 配置及说明如下

user nginx; # 指定运行 nginx 程序的用户,这里设置为上面新增的用户:nginx
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

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"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    server {
        # 禁止未知的域名解析到本服务器  
        listen 80 default_server; # 监听80端口并作为默认服务器 
        listen [::]:80 default_server ipv6only=on;# 监听ip6的80端口并作为默认服务器 
        server_name _; # 使用下划线作为占位符    
        return 403; # 对所有不符合的域名请求返回403 Forbidden 
    }

    server {
        # 禁止未知的域名解析到本服务器
        listen 443 default_server; # 监听443端口并作为默认服务器
        listen [::]:443 default_server ipv6only=on;# 监听ip6的443端口并作为默认服务器
        server_name _; # 使用下划线作为占位符
	
	# 使用 Let’s Encrypt 申请的 SSL 证书的公钥、私钥位置,实现 https 访问
	ssl_certificate /etc/letsencrypt/live/{your_domain}/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/{your_domain}/privkey.pem;

	# Include the SSL configuration from cipherli.st
	include /etc/nginx/snippets/ssl-params.conf;  # ssl 参数配置文件
        return 403; # 对所有不符合的域名请求返回403 Forbidden
    }
    include /etc/nginx/conf.d/*.conf; # 各 web 项目自己的配置文件
}


/etc/nginx/snippets/ssl-params.conf ssl 参数配置文件如下

# See https://cipherli.st/ for details on this configuration
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver 119.29.29.29 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options SAMEORIGIN; # SAMEORIGIN:允许同源 irame 嵌套, DENY:禁止 irame嵌套;
add_header X-Content-Type-Options nosniff;

# Add our strong Diffie-Hellman group
ssl_dhparam /etc/nginx/certs/dhparam.pem;  # DH密钥交换协议所需的参数文件


项目配置文件示例  /etc/nginx/conf.d/blog.conf

# 监听 80 端口,将所有 http 请求转发到 https 的 443 端口
server {
   listen 80;	   
   listen [::]:80;
   server_name your_domain;
   return 301 https://$host$request_uri;
}

server {
    # Enable HTTP/2
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name your_domain;
    access_log	/var/log/nginx/access.log;
    error_log /var/log/nginx/error.log notice;


    # Use the Let’s Encrypt certificates
    ssl_certificate /etc/letsencrypt/live/{your_domain}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{your_domain}/privkey.pem;

    # Include the SSL configuration from cipherli.st
    include /etc/nginx/snippets/ssl-params.conf;    

    location / {  
        proxy_pass http://localhost:8081;  # 转发到宿主机的8081端口(映射到 docker 容器的80端口)  
        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_set_header X-Forwarded-Proto $scheme;  
    }  
    
    error_page 404 /404.html;
    location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    }
}


docker 容器内应用的 nginx 配置示例,比如 my_web.conf

server {
   listen 80;
   server_name your_domain;
   root /usr/share/nginx/html/public;
   index index.php index.html index.htm;
   access_log /var/log/nginx/access.log;
   error_log /var/log/nginx/error.log notice;

   #允许跨域
   add_header 'Access-Control-Allow-Origin' '$http_origin' always;
   add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS' always;
   
   # 强制浏览器将请求升级到 HTTPS
   # 宿主机已经将 https 转为 http 映射到容器,这里如果不强制升级
   # 容器内的一些静态文件,如 js 发起网络请求,会使用 http,造成协议冲突,被浏览器限制访问
   add_header 'Content-Security-Policy' 'upgrade-insecure-requests;';  

   if ($http_x_forwarded_proto = "https") {
       set $https_scheme https;
   }

   if ($request_method = 'OPTIONS') {
       return 204;
   }

   location / {
       try_files $uri $uri/ /index.php?$query_string;
   }

   location ~ \.php$ {
       fastcgi_pass  unix:/run/php/php8.1-fpm.sock;
       fastcgi_keep_conn on;
       fastcgi_index index.php;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       include fastcgi_params;
   }

   location ~ \.(gif|jpg|jpeg|png|bmp|ico|css|js)$ {
      expires max;
   }

   location ~* \.(eot|ttf|woff|woff2)$ {
       add_header Access-Control-Allow-Origin '*';
   }
}


二、安装 git

为后面的代码版本控制、申请免费ssl证书时使用 hook 做准备

yum install -y git

安装完成后,设置全局配置,用于提交时将 windows 换行符强制转换为LF,检出时不转换

git config --global core.autocrlf input

生成 ssh 公钥、私钥用于代码版本控制

ssh-keygen -t rsa -C {your_name}

将会在 ~/.ssh 目录下生成 id_rsa、id_rsa.pub 私钥和公钥文件