Nginx反向代理halo博客并实现https访问

冷菌 2020年10月31日 133次浏览

最后更新时间2020年11月7日

一、需要准备什么

  • 一个正常访问的vps
  • OS:CentOS 7
  • 一个域名,并已解析到服务器的ip

二、配置SSL证书

  • 安装Certbot

    yum install -y python36 && pip3 install certbot 
    

    运行这条命令后,显示 Successfully installed xxxx, xxxx, xxxx (各种软件包名字)表示成功

  • 停止防火墙 (在CentOS7版本以上,默认开启防火墙,不关闭防火墙将无法申请证书)

    systemctl stop firewalld && systemctl disable firewalld
    

    运行这条命令后,显示

    Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.

    Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

    (表示成功)

  • 申请SSL证书

    certbot certonly --standalone --agree-tos -n -d www.●●●●●● -d ●●●●●● -m ▲▲▲@▲▲▲.▲▲▲
    

    第一个-d加一个带www的域名,第二个-d加一个不带www的域名,-m后面加你的电子邮箱。注意前后要带空格。

    例子:(域名:www.10086.website,邮箱:10086@protonmail.com)

    certbot certonly --standalone --agree-tos -n -d www.10086.website -d 10086.website -m 10086@protonmail.com

    运行这条命令后,如果显示:

    IMPORTANT NOTES:
    Congratulations! Your certificate and chain have been saved at:
    /etc/letsencrypt/live/www.10086.website/fullchain.pem
    Your key file has been saved at:
    /etc/letsencrypt/live/www.10086.website/privkey.pem
    Your cert will expire on 2020-06-04. To obtain a new or tweaked
    version of this certificate in the future, simply run certbot
    again. To non-interactively renew *all* of your certificates, run
    "certbot renew"
    Your account credentials have been saved in your Certbot
    configuration directory at /etc/letsencrypt. You should make a
    secure backup of this folder now. This configuration directory will
    also contain certificates and private keys obtained by Certbot so
    making regular backups of this folder is ideal.
    If you like Certbot, please consider supporting our work by:
    
    Donating to ISRG / Let's Encrypt:  https://letsencrypt.org/donate
    Donating to EFF:                    https://eff.org
    (表示成功)
    

    注意:这一步比较容易出错,常见的问题有:

    • 其它代理占用了80,443端口。解决方法:停止其它代理软件,或重装VPS。
    • 没有正确配置域名解析。解决方法:ping一下域名,看看能不能正确解析到IP。
    • 没有关闭防火墙。解决方法:关闭防火墙。
  • 配置证书自动更新

    echo "0 0 1 */2 * service nginx stop; certbot renew; service nginx start;" | crontab
    

    我们申请的证书只有三个月期限,上面的命令表示每隔两个月,证书就自动续命一次,从而保证可以一直用下去。
    运行这条命令后,如果没有任何信息输出,就表示成功。

    可以查看crontab定时任务

     crontab -l
    

三、安装Nginx

yum install -y nginx
  • centos下没有nginx源需要手动添加
    vi /etc/yum.repos.d/nginx.repo
    

    在文件中写入以下内容:

    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=0
    enabled=1
    

    保存退出后,直接安装

     yum install -y nginx
    

四、上传配置文件&运行

  • Nginx的配置文件存储在

    cd /etc/nginx/conf.d
    
  • 转到conf.d目录,编辑default.conf文件

      server {
      ### 1:标注“●”的地方填写域名,注意这里的域名带www,例如 www.10086.website
      ### 一共有三处需要填,都以“●”标出,“●”应该被删除,并被域名代替
      server_name ●●●●●●●●●●●●;
    
      listen 80;
      rewrite ^(.*) https://$server_name$1 permanent;
      autoindex off;
      server_tokens off;
      }
    
      server {
      ssl_certificate /etc/letsencrypt/live/●●●●●●●●●●●●/fullchain.pem;
    
      ssl_certificate_key /etc/letsencrypt/live/●●●●●●●●●●●●/privkey.pem;
    
      location / 
    	{
          proxy_pass http://127.0.0.1:8090;
    
    	proxy_redirect off;
    
          proxy_http_version 1.1;
         proxy_set_header HOST $host;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          client_max_body_size 1000m;
    
          sendfile on;
          tcp_nopush on;
          tcp_nodelay on;
          keepalive_requests 25600;
          keepalive_timeout 300 300;
          proxy_buffering off;
          proxy_buffer_size 8k;
      }
    
      listen 443 ssl http2;
      server_name $server_name;
      charset utf-8;
    
      ssl_protocols TLSv1.2 TLSv1.3;
      ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
      ssl_prefer_server_ciphers on;
    
      ssl_session_cache shared:SSL:60m;
      ssl_session_timeout 1d;
      ssl_session_tickets off;
    
      ssl_stapling on;
      ssl_stapling_verify on;
      resolver 8.8.8.8 8.8.4.4 valid=300s;
      resolver_timeout 10s;
    
      add_header X-Frame-Options DENY;
      add_header X-XSS-Protection "1; mode=block";
      add_header X-Content-Type-Options nosniff;
      add_header Strict-Transport-Security max-age=31536000 always;
      autoindex off;
      server_tokens off;
    
      location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF|png|mp4|mp3|ico)$
      {
        proxy_pass http://127.0.0.1:8090;
      }
    
      }
    
  • 【2020年4月18日更新】 开启GZIP

    vi /etc/nginx/nginx.conf
    

    在http块写入以下内容

      gzip  on;
      gzip_min_length  1k;
      gzip_buffers     4 16k;
      gzip_http_version 1.1;
      gzip_comp_level 5;
      gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
      gzip_disable "MSIE [1-6]\.";
      gzip_vary on;
    
  • 保存退出,验证一下Nginx配置是否正确,输入:

    nginx -t
    

    显示

    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    

    说明配置没有问题

  • 运行Nginx

    • 启动Nginx: service nginx start
    • 重启Nginx: service nginx restart
    • 查看Nginx状态:service nginx status
    • 停止Nginx:service nginx stop
    • Nginx开机自启:
      • sudo systemctl enable nginx
      • sudo systemctl start nginx

五、安装 Halo

  • 安装 Java 运行环境

    • 安装 OpenJRE
    sudo yum install java-1.8.0-openjdk -y
    
    • 检测是否安装成功
    java -version
    
  • 下载Halo配置文件

    • 下载配置文件到 ~/.halo 目录
    curl -o ~/.halo/application.yaml --create-dirs https://dl.halo.run/config/application-template.yaml
    

    打开这个配置文件vi ~/.halo/application.yaml 可以看到以下内容,不需要修改任何内容,默认即可,如果要修改也可以。

    server:
    port: 8090 
    ### 如果要修改这个8090端口,nginx中的配置文件中的端口8090
    ### proxy_pass http://127.0.0.1:8090;
    ### 也需要修改
    
    # Response data gzip.
    compression:
    enabled: false
    spring:
    datasource:
    
    # H2 database configuration.
    driver-class-name: org.h2.Driver
    url: jdbc:h2:file:~/.halo/db/halo
    username: admin
    password: 123456
    
    # MySQL database configuration.
    #    driver-class-name: com.mysql.cj.jdbc.Driver
    #    url: jdbc:mysql://127.0.0.1:3306/halodb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    #    username: root
    #    password: 123456
    
     # H2 database console configuration.
    h2:
    console:
      settings:
        web-allow-others: false
      path: /h2-console
      enabled: false
    
    halo:
    # Your admin client path is https://your-domain/{admin-path}
    admin-path: admin
    
    # memory or level
    cache: memory
    
  • 下载Halo安装包

     cd /usr/local
    

    Halo下载地址:https://halo.run/archives/download.html ,这里我选择 halo 1.4.2

     yum -y install wget && wget https://github.com/halo-dev/halo/releases/download/v1.4.2/halo-1.4.2.jar -O halo-latest.jar
    
  • 启动测试

      java -jar halo-latest.jar
    

    出现以下日志输出,则代表启动成功

      run.halo.app.listener.StartedListener    : Halo started at         https://www.10086.website
      run.halo.app.listener.StartedListener    : Halo admin started at   https://www.10086.website/admin
      run.halo.app.listener.StartedListener    : Halo has started successfully!
    

    这时在浏览器输入域名测试能否进行博客初始化

六、Halo进阶配置

以上的启动仅仅为测试 Halo 是否可以正常运行,如果我们关闭 ssh 连接,Halo 也将被关闭。要想一直处于运行状态,请继续看下面的教程。

  • 下载 Halo 官方的 halo.service 模板

    sudo curl -o /etc/systemd/system/halo.service --create-dirs https://dl.halo.run/config/halo.service
    
  • 修改 halo.service

    sudo vi /etc/systemd/system/halo.service
    
  • 打开之后我们可以看到

    [Unit]
    Description=Halo Service
    Documentation=https://halo.run
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/java -server -Xms256m -Xmx256m -jar YOUR_JAR_PATH
    ExecStop=/bin/kill -s QUIT $MAINPID
    Restart=always
    StandOutput=syslog
    
    StandError=inherit
    
    [Install]
    WantedBy=multi-user.target
    
    • YOUR_JAR_PATH:Halo 安装包的绝对路径,需要修改,比如改成/usr/local/halo-latest.jar
    • 如果你不是按照上面的方法安装的 JDK,请确保/usr/bin/java是正确无误的。
    • systemd 中的所有路径均要写为绝对路径,另外,~ 在 systemd 中也是无法被识别的,所以你不能写成类似 ~/halo-latest.jar 这种路径。
  • 修改 service 文件之后需要刷新 Systemd

    sudo systemctl daemon-reload
    

  • Halo常用命令
    Halo开机自启: sudo systemctl enable halo
    
    启动 Halo: sudo service halo start
    
    重启 Halo: sudo service halo restart
    
    停止 Halo: sudo service halo stop
    
    查看 Halo 的运行状态: sudo service halo status
    
  • 更多Halo教程查看官方文档:https://halo.run/

七、halo 升级

升级前请确保主题已适配新版halo

  • 停止halo: service halo stop
  • 备份数据:cp -r ~/.halo ~/.halo.bak
  • 重命名(备份)旧运行包:mv halo-latest.jar halo-latest.jar.bak
  • 下载新运行包:wget https://github.com/halo-dev/halo/releases/download/v1.4.2/halo-1.4.2.jar -O halo-latest.jar
  • 测试是否能够正常启动:java -jar halo-latest.jar
  • 重启:service halo restart

八、加固服务器,配置防火墙

如果VPS上没有其它服务,建议打开防火墙。服务器对外只暴露80,443,SSH端口。前面的步骤中禁用了防火墙firewalld,我们这里使用ufw防火墙作为替代。

  • 安装ufw:

    yum install -y epel-release && yum install -y ufw
    
  • 打开SSH,HTTP,HTTPS端口,运行:

    ufw disable && ufw allow ssh && ufw allow http && ufw allow https && ufw enable
    

    如果ssh端口不是22,那么需要将ssh改为端口号。例如ssh端口为14320,则:

    ufw disable && ufw allow 14320 && ufw allow http && ufw allow https && ufw enable
    
  • ufw 开机自启

    sudo systemctl start ufw
    sudo systemctl enable ufw
    
  • ufw其他常用命令

    查看防火墙状态
    ufw status
    
    打开或关闭某个端口,例如:
    sudo ufw allow smtp 允许所有的外部IP访问本机的25/tcp (smtp)端口
    sudo ufw allow 22/tcp 允许所有的外部IP访问本机的22/tcp (ssh)端口
    sudo ufw allow 53 允许外部访问53端口(tcp/udp)
    sudo ufw allow from 192.168.1.100 允许此IP访问所有的本机端口
    sudo ufw allow proto udp 192.168.0.1 port 53 to 192.168.0.2 port 53
    sudo ufw deny smtp 禁止外部访问smtp服务
    sudo ufw delete allow smtp 删除上面建立的某条规则