2022-01-27 20:30:12 星期四
一、项目简介
这份文档记录我在实验室搭建协作平台的方案迭代过程、所使用的方法以及简略步骤。
在做这个平台之前,我对服务器搭建一窍不通,做完之后,我对服务器搭建有了大概的理解,出现问题也能有个大概的方向去寻找解决的办法。
当时搭建的协作平台所需要完成的主要功能有:知识库、网盘以及git。其中知识库我们使用的是wordpress,搭配wedocs做知识库还不错;网盘用的是nextcloud,git用的是gitea,都是开源免费的项目。
wordpress的灵活性特别大,本来是被用来做网站的,但是他包含了非常多的插件,你可以按照你的需求组装插件,使wordpress具有其他功能。
在本文档中,就以基于wordpress搭建个人网站为例子,讲解如何搭建服务,搭建网站、git都可以用同样的套路。
本文档与个人网站搭建教程的区别
网上关于搭建个人网站的教程非常多,但关于为什么要用这些工具,这些工具之间的联系是什么,另外,关于网站完善的文章也比较少。
所以,我希望能写一份文档,讲清楚网站搭建的来龙去脉,希望能在读者脑中建立起常用服务架构的轮廓,读者也能够自己动手搭建自己的网站。
阅读之后你能明白
- 如何快速地搭建一个网站
- 如何完善你的网站
- 如何搭建一个自己的网站
- 搭建一个服务的过程大概是什么样的
- 搭建服务中所用到的工具技术各是什么意思,它们之间有什么联系
二、方案迭代
所谓搭建服务,说白了就是在电脑上装一个软件,和windows上安装qq相比,需要你进行考虑:软件依赖的运行环境(如LNMP和LAMP)、如何访问、如何安全访问等问题,而安装qq简单只是因为他把这些步骤都封装好了,你下载一个exe就可以了。
下面就对这些问题进行探讨。
1、内网服务
这一步只需要会linux和docker最简单的命令就可以了。
最简单的网站
搭建网站最简单的方法就是使用docker搭建。
比如搭建个人主页,使用docker pull从dockerhub下载wordpress镜像,然后在主机上docker run,就可以实现使用ip:port对服务进行访问了。
进一步
因为docker run wordpress,会把数据库和服务耦合在一起,之后你想要把数据换个硬盘保存还会比较麻烦,并且如果你想要使用phpMyAdmin对数据库可视化操作,这个时候使用docker run就难以实现了。
而这个想法可以使用docker compose实现,docker compose就是使用docker-compose.yml文件,运行多个镜像(wordpress、mysql、phpMyAdmin),并在他们之间建立联系。
2、外网访问
上一步搭建的服务,只能在同一个局域网内进行访问,比如你的服务器和你的电脑不在同一个路由器下,可能就无法访问了。
如果你的服务需要使用外网进行访问,那就需要使用到内网穿透,内网穿透简单来说就是一个转发的功能,所以这一步需要你具有公网ip。
可以是一台具有公网ip的服务器(如阿里云),也有一些内网穿透软件也有单卖端口给你做穿透,如果你的路由器具有公网ip也可以使用静态NAT。
当你具有公网ip之后,我们就实现内网穿透啦。主要可以使用的工具有:ssh、frp,其中frp使用密码进行连接,可能不太安全,配置项相对于ssh来说比较丰富(麻烦),而使用ssh可以一句命令搞定。
进一步
因为ssh相当于本地主机对公网主机建立连接,所以本地主机每次开机或者网络重连之后都需要重新主动连接公网主机。那么如何实现开机自动连接?就需要写一份service文件,使用systemctl命令,让linux每次启动时执行你的命令。
3、其他完善
域名访问
上面的步骤中,我们都是使用ip:port进行访问,那么如何使用 www.yoursite.com 这样的形式进行访问呢?需要你去域名商那里购买域名,然后在他的dns服务器上把域名指向你的公网ip;同时,也需要使用nginx反代,为域名提供相应的服务。
加密传输
由于http使用明文传输,而用户登录密码等信息用明文传输肯定是不安全的,如何使用进行加密传输?这个时候就需要把你的网站升级到用https访问,需要使用到acme.sh脚本进行部署。
多项服务
如果我不止有wordpress服务,我还有nextcloud、gitea等,那我是否需要对每个服务端口都进行穿透?此时可以使用nginx反向代理,比如让nginx监听8080端口,然后再根据用户访问的域名,反代到相应的服务端口。
nginx配置属于服务器运维,对小白来说还是需要一些时间的,所以就有了一些服务器运维可视化的软件,如宝塔面板。宝塔面板可以对服务器端口防火墙、网站配置、反向代理、https等信息进行可视化配置,对于linux不太熟悉的同学会比较友好。
我一开始就是使用宝塔面板进行维护的,但是宝塔是闭源的,不知道安全性如何,所以后来我就不再使用了,直接使用linux对nginx进行配置。
环境依赖
一般运行web服务需要LNMP或者LAMP环境,即Linux+Nginx+Mysql+php,或Apache。php用来运行你的服务代码,Mysql用来装数据,Nginx用来做反向代理、负载均衡等。
因为每个服务可能依赖不同的环境版本,而要使几个服务之间相互兼容,最好的解决办法可能就是使用docker了,也就是我们上面用的方法,这也是云原生中容器化的方案。
静态NAT
在前面做内网穿透的步骤,如果你的路由器具有公网ip,也可以在路由器上添加一个静态NAT配置来实现。
由于我们实验室的服务器是放在国外的,访问比较慢,所以我在路由器中添加了静态NAT,这样使用校园网访问就很快了。
数据备份
可以使用sh脚本和crontab定时执行
三、在本地/云主机上搭建wordpress
# 安装docker和docker-compose
# 去到你想存放数据的位置
cd pathtoinstall
# 创建文件夹来储存wordpress文件、数据库
mkdir -p wordpress/wp wordpress/db
# 创建docker-compose.yml
cd wordpress
touch docker-compose.yml
vim docker-compose.yml
# 将demo内容复制到docker-compose.yml中,保存并退出
# docker-compose.yml demo
version: '3.1'
services:
wordpress:
image: wordpress
restart: always
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- ./wp:/var/www/html
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- ./db:/var/lib/mysql
phpmyadmin:
image: phpmyadmin
restart: always
ports:
- 8081:80
environment:
MYSQL_ROOT_PASSWORD: examplepass
PMA_HOST: db
PMA_PORT: 3306
depends_on:
- db
该yml文件在wordpress官方给的demo基础上,将挂载卷改成了挂载主机目录,创建修改和备份起来会方便一些;并加入了phpmyadmin镜像,可以对数据库进行可视化操作
# 启动docker-compose
docker-compose up
等待docker启动完成后,在浏览器中输入ip:8080
就可以进行访问啦
四、部署https
这一节讲如何使用https对网站访问进行加密,可以对用户的账户密码等数据进行加密,防止明文传输被窃听。
https的访问流程如图,关于https更详细的原理可以阅读 HTTPS请求的整个过程的详细分析
1、部署逻辑
你需要有一个域名,根据这个域名去证书颁发机构申请证书,这份证书证明这个域名是你的,包含了密钥对。申请到证书之后,需要将其部署到你的服务器上,在我们的案例里,是将其部署到nginx中。
2、详细步骤
申请的步骤可以使用acme.sh脚本,这个脚本可以完成以下功能:自动申请、到期自动重新申请、自动部署。因为免费证书是有期限的,一般是90天,所以到期需要重新申请,acme可以自动完成。
申请过程acme会让你证明这个域名是你的,最简单的方式是通过DNS服务商给的api进行自动认证,详见acme使用dnsapi部署。
关系acme更多的信息和用法可以阅读 acme.sh
申请、部署
# 切换为root用户运行,后面的部署会方便很多
sudo su root
# 下载脚本
curl https://get.acme.sh
# 去对应的DNS服务商获取,如果用阿里云的子账户,那就需要开通子用户的dns管理权限
# 参考 https://www.jianshu.com/p/012b1eb233f7
export Ali_Key="xxx"
export Ali_Secret="xxx"
# 申请证书
acme.sh --issue --dns dns_ali -d naturalbase.cn -d *.naturalbase.cn
# 安装证书到nginx,每次更新证书时,会自动重新部署。
mkdir -p /etc/nginx/ssl/naturalbase.cn/
acme.sh --install-cert -d naturalbase.cn
--key-file /etc/nginx/ssl/naturalbase.cn/key.pem
--fullchain-file /etc/nginx/ssl/naturalbase.cn/cert.pem
--reloadcmd "service nginx force-reload"
nginx配置https访问
上面的步骤只是实现把证书放到nginx目录,下面还需要配置nginx,让你的网站支持https
# 打开你的网站配置文件,如 /etc/nginx/conf.d/naturalbase.conf
vim /etc/nginx/conf.d/naturalbase.conf
# 复制下面的demo到文件里
server {
listen 80;
listen [::]:80;
server_name www.naturalbase.cn naturalbase.cn;
# SSL-START SSL相关配置
#error_page 404/404.html;
# HTTP_TO_HTTPS_END 强制开启https
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
# HTTP_TO_HTTPS_END
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/naturalbase.cn/cert.pem;
ssl_certificate_key /etc/nginx/ssl/naturalbase.cn/key.pem;
ssl_buffer_size 16k;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_session_timeout 3h;
ssl_stapling on;
ssl_session_tickets on;
# SSL-END
# 反向代理配置
location ~* .(gif|png|jpg|css|js|woff|woff2)$
{
proxy_pass http://127.0.0.1:9500;
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 REMOTE-HOST $remote_addr;
expires 12h;
}
location / {
proxy_pass http://127.0.0.1:9500;
index index.html index.htm;
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 REMOTE-HOST $remote_addr;
add_header X-Cache $upstream_cache_status;
#Set Nginx Cache
add_header Cache-Control no-cache;
}
# END 反向代理配置
}
五、内网穿透
如果你的服务是部署在本地主机上,而想要在外网进行访问。
原理基本都是第三方转发,主要可以利用的工具有ssh、frp、静态NAT。
ssh和frp的原理是类似的,都是在云服务器上安装一个服务端sshd或frps,然后在本地主机上安装一个客户端ssh和frpc。
客户端frpc告诉服务器frps去监听云服务器的某个端口,这个端口是你用来访问服务的端口,然后将这个端口收到的数据转发给frpc,frpc再转发给你的本地服务端口,以此来实现转发的功能。
但frp是基于弱口令密码,安全性较低,所以一般我都是用ssh,而且ssh更简单,只需要一行命令就行了。
静态NAT的原理与前两个不太一样,意思大概是利用:当你发送数据到另一个网络时,路由器会把你数据包里面的ip:port改成路由器自己的ip:port,如果你的路由器具有公网ip,那就可以在路由器里面添加一条静态NAT,就可以实现外网访问了。
实现ssh映射
用到的命令:
ssh -NTf -R 远程端口:目标地址:目标端口 用户@公网ip
如:
ssh -NTf -R 12345:localhost:3000 root@47.106.xx.xx
这句话就将本地主机的3000端口映射为远程主机的localhost:12345端口,当你访问47.106.xx.xx:12345端口时,就访问到了本地主机的3000端口。
测试有没有成功,在远程主机上运行 netstat -ntlp | grep 12345
,有的话会有正确的地址:端口
更多关于ssh,请阅读 调试利器-SSH隧道
建议:不要用奇奇怪怪的端口直接访问服务,而是通过反向代理,全部扔到HTTPS(如443)下面
六、参考文献
这里推荐一些搭建服务器过程中成体系的参考资料。
在服务器的搭建中,主要用到计算机网络、linux系统管理和服务器维护的知识。
计算机网络可以看《图解TCP/IP》
这本书,内容精简实用,也比谢希仁的《计算机网络》容易理解。
linux系统管理和服务器维护可以看《鸟哥的linux私房菜 基础篇》
这本书,比较厚,可以先看每章的小结,遇到感兴趣的再详细看内容。
《私房菜》确实太厚了,也可以先从 Linux工具快速教程 这个手册简单了解linux的基本用途。
docker学习资源:Docker 从入门到实践。