0

Homelab | 架构设计与实现-Low-level design --Nginx Reverse Proxy

 1 year ago
source link: https://www.v2ex.com/t/951133
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  分享发现

Homelab | 架构设计与实现-Low-level design --Nginx Reverse Proxy

  shunagliu008 · 2 小时 50 分钟前 · 132 次点击

关于 “架构设计与实现-High-level design”篇章里,云上部分的实现重点是-Nginx Reverse Proxy ,依据策略,部分流量在“云本地”处理,部分流量通过 FRP 转发到‘Homelab’另一个本地。

请输入图片描述

依据上图,云上主机部署如下应用:

  1. Typecho 博客,LNMP 方式部署在宿主机上
  2. Wordpress 博客,通过 Docker 部署
  3. FRP server ,通过 Docker 部署
  4. Letsencrypt, 通过 docker 部署
  5. portainer ,通过 Docker 部署
root@myblog:~# docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED        STATUS        PORTS                                          NAMES
a943473882e5   snowdreamtech/frps              "/bin/sh -c '/usr/bi…"   5 months ago   Up 3 days                                                    frps
83e72086e158   portainer/portainer-ce:latest   "/portainer"             5 months ago   Up 2 months   8000/tcp, 9443/tcp, 127.0.0.1:9000->9000/tcp   portainer
05408a9f98d8   mysql:5.7                       "docker-entrypoint.s…"   5 months ago   Up 2 months   33060/tcp, 127.0.0.1:13306->3306/tcp           myblog-db-1
2137b27bdf51   linuxserver/swag                "/init"                  5 months ago   Up 11 days    80/tcp, 443/tcp                                letsencrypt
cb2a2593f729   wordpress:latest                "docker-entrypoint.s…"   5 months ago   Up 2 months   0.0.0.0:8001->80/tcp, :::8001->80/tcp          myblog-wordpress-1

1 Typecho 博客,LNMP 方式部署在宿主机

How To Install Linux, Nginx, MySQL, PHP (LNMP stack) on Ubuntu 20.04

2 Wordpress 博客,通过 Docker 部署

version: '2'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: ${MYSQL_DATABASE_PASSWORD:-wordpress007}
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress001
       MYSQL_PASSWORD: wordpress007

   wordpress:
     image: wordpress:latest
     ports:
       - 8001:80
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress001
       WORDPRESS_DB_PASSWORD: wordpress007

volumes:
    db_data:

3 FRP server ,通过 Docker 部署

docker run --restart=always --network host -d -v /root/frps.ini:/etc/frp/frps.ini --name frps snowdreamtech/frps

4 Letsencrypt, 通过 docker 部署

https://homelab.samliu.tech/archives/lets-encrypt-%E9%80%9A%E9%85%8D%E7%AC%A6%E8%AF%81%E4%B9%A6.html

5 portainer ,通过 Docker 部署

docker run -d --network host --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest

6 Nginx 反向代理配置

前面依据安装好了 Nginx ,修改配置之前,需要了解下 Nginx 配置文件结构关系。 Understanding the Nginx Configuration File Structure and Configuration Contexts

root@myblog:~# tree /etc/nginx/
/etc/nginx/
├── conf.d
│   └── ssl-nginx.conf
├── fastcgi.conf
├── fastcgi_params
├── koi-utf
├── koi-win
├── mime.types
├── modules-available
├── modules-enabled
│   ├── 50-mod-http-image-filter.conf -> /usr/share/nginx/modules-available/mod-http-image-filter.conf
│   ├── 50-mod-http-xslt-filter.conf -> /usr/share/nginx/modules-available/mod-http-xslt-filter.conf
│   ├── 50-mod-mail.conf -> /usr/share/nginx/modules-available/mod-mail.conf
│   └── 50-mod-stream.conf -> /usr/share/nginx/modules-available/mod-stream.conf
├── nginx.conf
├── nginx.conf.bak
├── nginx.conf.save
├── proxy_params
├── scgi_params
├── sites-available
│   ├── default
│   ├── http
│   ├── http.bak
│   ├── https
│   └── https.bak
├── sites-enabled
│   ├── http -> /etc/nginx/sites-available/http
│   └── https -> /etc/nginx/sites-available/https
├── snippets
│   ├── fastcgi-php.conf
│   └── snakeoil.conf
├── uwsgi_params
├── win-utf
└── wireguard.stream.conf
  • /etc/nginx/nginx.conf: 主配置文件,里面嵌套了多个不同路径下的子配置文件,通过 include 语句。
root@myblog:~# more /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##
        client_max_body_size 30m;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

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

        ##
        # SSL Settings
        ##

        # ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        # ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_min_length 256;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

#stream {
#    include /etc/nginx/wireguard.stream.conf;
#}

#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}
  • sites-available: 该文件夹是存放关于 HTTP 配置文件的地方,特定配置文件需要软链接到 sites-enabled 文件夹才生效
  • sites-enabled:该文件夹包括实际生效的,关于 HTTP 的所有相关配置
  • conf.d: 关于 HTTP 其他子配置文件存放地,例如 SSL 配置
root@myblog:~# more /etc/nginx/conf.d/ssl-nginx.conf
    ########################################################################
    # from https://cipherlist.eu/                                            #
    ########################################################################

    ssl_protocols TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
    ssl_prefer_server_ciphers on;
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
    ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
    ssl_session_timeout  10m;
    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 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    # Disable preloading HSTS for now.  You can use the commented out header line that includes
    # the "preload" directive if you understand the implications.
    #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    ##################################
    # END https://cipherlist.eu/ BLOCK #
    ##################################
  • 关于 WEB 流量的反向代理配置,着重关注 sites-enabled 文件夹。
root@myblog:~# more /etc/nginx/sites-enabled/http
server {
    listen 80 default_server;
    #listen [::]:80;
    server_name _;
    return 412;
    #access_log /var/www/your_domain3/your_domain3_http.log;
}

server {
    listen 80;
    #listen [::]:80;
    server_name *.samliu.tech *.duckdns.org;
    return 301 https://$host$request_uri;
    #access_log /var/www/your_domain3/your_domain3_http.log;
}

HTTP 配置逻辑: 针对收到的 HTTP 请求,检查域名( host 字段),精确匹配条件优先于其他,因此,对于*.samliu.tech *.duckdns.org ,重定向到 HTTPS 流量;对于 server_name _,其他所有域名,返回 412 错误码。

root@myblog:~# more /etc/nginx/sites-enabled/https
server {
    listen 443 ssl http2 default_server;
    server_name _;
    return 412;
    ssl_certificate /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/fullchain.pem;
    ssl_certificate_key /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
}


server {
    listen 185.186.146.68:9000 ssl http2;
    server_name $host;
    ssl_certificate /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/fullchain.pem;
    ssl_certificate_key /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    #include /etc/nginx/conf.d/ssl-nginx.conf

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        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;
    }
    #access_log /var/www/your_domain2/your_domain2_https.log;


}


server {
    listen 443 ssl http2;
    #listen [::]:443 ssl http2;
    server_name typecho.samliu.tech homelab.samliu.tech;
    root /var/www/typechooo;
    # include typecho.conf;
    index index.html index.htm index.php;

    ssl_certificate /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/fullchain.pem;
    ssl_certificate_key /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    #include /etc/nginx/conf.d/ssl-nginx.conf

    if (!-e $request_filename) {
        rewrite ^(.*)$ /index.php$1 last;
        }

    location / {
        try_files $uri $uri/ =404;
        }

    location ~ .*\.php(\/.*)*$ {
        set $path_info "";
        set $real_script_name $fastcgi_script_name;
        if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
        set $real_script_name $1;
        set $path_info $2;
        }
        fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
        fastcgi_param SCRIPT_NAME $real_script_name;
        fastcgi_param PATH_INFO $path_info;

        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
    #access_log /var/www/your_domain1/your_domain1_https.log;
}




server {
    listen 443 ssl http2;
    #listen [::]:443 ssl http2;
    server_name blog.samliu.tech;

    ssl_certificate /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/fullchain.pem;
    ssl_certificate_key /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    #include /etc/nginx/conf.d/ssl-nginx.conf

    ########################################################################

    location / {
        proxy_pass http://127.0.0.1:8001;
        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;
    }
    #access_log /var/www/your_domain2/your_domain2_https.log;
}



server {
    listen 443 ssl http2;
    #listen [::]:443 ssl http2;
    server_name *.samliu.tech *.duckdns.org;

    ssl_certificate /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/fullchain.pem;
    ssl_certificate_key /root/letsencrypt-config/etc/letsencrypt/live/samliu.tech/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    #include /etc/nginx/conf.d/ssl-nginx.conf

    ########################################################################

    location / {
        proxy_pass http://127.0.0.1:980;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        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;
    }
    #access_log /var/www/your_domain2/your_domain2_https.log;
}

HTTPS 配置逻辑: 收到 HTTPS 情况后,明细条件优先与其他,保留所有原始 HTTP header 信息以便支持 websocket 等,相同的 SSL 配置信息剥离到 /etc/nginx/conf.d/ssl-nginx.conf 。

-listen 185.186.146.68:9000 ssl http2 匹配该 IP+端口,转发到 http://127.0.0.1:9000 ,此处为 portainer

-typecho.samliu.tech homelab.samliu.tech 匹配该域名,转发到 Typecho 网站,root /var/www/typechooo ,此处是部署在本地的服务,非反向代理服务。

-blog.samliu.tech 匹配该域名,转发到 http://127.0.0.1:8001 ,此处为 Wordpress 网站,docker 部署的

-*.samliu.tech *.duckdns.org 匹配该域名,转发到 http://127.0.0.1:980 ,此处为 FRP server 服务,docker 部署的,作为二级反向代理

-server_name _ 剩下的所有其他 HTTPS 请求,返回 return 412 错误码。 [/scode]

三 其他 /引用

How To Install WordPress With Docker Compose

https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose

How to Set Up SSH Keys on Ubuntu 20.04 https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-ubuntu-20-04

How To Install Linux, Nginx, MySQL, PHP (LEMP stack) on Ubuntu 20.04 https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04

How To Configure Nginx as a Web Server and Reverse Proxy for Apache on One Ubuntu 20.04 Server https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-web-server-and-reverse-proxy-for-apache-on-one-ubuntu-20-04-server

How To Improve Website Performance Using gzip and Nginx on Ubuntu 20.04 https://www.digitalocean.com/community/tutorials/how-to-improve-website-performance-using-gzip-and-nginx-on-ubuntu-20-04


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK