aaPanel面板安装与配置
aaPanel的安装
aaPanel 为宝塔面板国际版,由于国内版本宝塔面板可以使用微信扫一扫登录,且强制要求绑定账号等。基本可以认为其有能力直接访问服务器中的任何资源且不被发现(通过微信扫一扫以及宝塔账号登录说明极大可能宝塔官方具有一个能够通过服务器认证的验证密钥,哪怕验证是在自己的服务器上进行,微信扫一扫的过程中宝塔官方只需后台替换账号信息,就可以用任意微信账号模拟原来的用户登录),并在需要时向相关部门开放。故安装国际版,根据此贴的说明,国际版同样具有一定程度的跟踪器,我们将进行去除后安装使用。
传统方法安装(不去除跟踪器)
根据不同系统,直接使用 ssh 在 root 权限下运行下列指令并依据提示操作即可
CentOS:
yum install -y wget && wget -O install.sh http://www.aapanel.com/script/install_6.0_en.sh && bash install.sh
Debian/Ubuntu/Deepin:
wget -O install.sh http://www.aapanel.com/script/install-ubuntu_6.0_en.sh && sudo bash install.sh
去除跟踪器的安装方法
明确跟踪器位置
根据此贴说明,跟踪器分别位于安装脚本中的第700行左右的统计代码(汇报安装面板时的服务器IP、安装时间以及该 IP 的安装次数)
curl -sS --connect-timeout 10 -m 60 https://brandnew.aapanel.com/api/setupCount/setupPanel?type=Linux > /dev/null 2>&1
curl -sS --connect-timeout 10 -m 60 https://console.aapanel.com/Api/SetupCount?type=Linux > /dev/null 2>&1
以及安装完毕后的 ajax.py
文件中,第473行与第504行分别用于记录安装面板的ip以及用于收集用户站点总数、数据库和 ftp 、设备信息(系统版本、内存大小、处理器型号、Web服务器类型、面板版本)用于判断是否需要更新面板。
public.arequests('get', '{}/api/setupCount/setupPanel?type=Linux'.format(self.__official_url))#line 473
updateInfo = json.loads(public.httpPost(sUrl,data))#line 504
下载安装脚本并进行编辑
通过ssh连接vps并执行指令 wget -O install.sh http://www.aapanel.com/script/install_6.0_en.sh
使用vi将700行左右的如下内容前加上 #
改为注释,注意这三行都要加 #
,下面是原始状态
curl -sS --connect-timeout 10 -m 60 https://brandnew.aapanel.com/api/setupCount/setupPanel?type=Linux > /dev/null 2>&1
#curl -sS --connect-timeout 10 -m 60 https://www.aapanel.com/Api/SetupCount?type=Linux > /dev/null 2>&1
curl -sS --connect-timeout 10 -m 60 https://console.aapanel.com/Api/SetupCount?type=Linux > /dev/null 2>&1
安装aaPanel
执行命令 bash install.sh
并根据提示进行选择安装面包,直到出现以下面板信息时,安装完毕,注意留存下列信息用于登陆面板。登陆前请先继续使用ssh移除安装完毕后的跟踪器,避免访问时触发。
aaPanel Internet Address: http://your-ip:8888/randstring
aaPanel Internal Address: http://your-ip:8888/randstring
username: username
password: password
Warning:
If you cannot access the panel,
release the following port (8888|888|80|443|20|21) in the security group
去除安装完毕后文件中的跟踪器
使用任意文档编辑器,打开 /www/server/panel/class/ajax.py
,首先将下列段落中的 public.arequests('get', '{}/api/setupCount/setupPanel?type=Linux'.format(self.__official_url))
直接添加井号注释掉,该行代码只用于提交ip,对其他功能无任何影响。
#line 466
def UpdatePanel(self,get):
try:
if not public.IsRestart(): return public.returnMsg(False,'EXEC_ERR_TASK')
import json
conf_status = public.M('config').where("id=?",('1',)).field('status').find()
if int(session['config']['status']) == 0 and int(conf_status['status']) == 0:
# public.HttpGet('{}/api/setupCount/setupPanel?type=Linux'.format(self.__official_url))
public.arequests('get', '{}/api/setupCount/setupPanel?type=Linux'.format(self.__official_url))
public.M('config').where("id=?",('1',)).setField('status',1)
随后继续查看之后30行起的代码段
#line 487
mplugin.ROWS = 10000
panelsys = system.system()
data = {}
data['ds'] = ''#self.get_other_info()
data['sites'] = str(public.M('sites').count())
data['ftps'] = str(public.M('ftps').count())
data['databases'] = str(public.M('databases').count())
data['system'] = panelsys.GetSystemVersion() + '|' + str(mem.total / 1024 / 1024) + 'MB|' + str(public.getCpuType()) + '*' + str(psutil.cpu_count()) + '|' + str(public.get_webserver()) + '|' +session['version']
data['system'] += '||'+self.GetInstalleds(mplugin.getPluginList(None))
data['logs'] = logs
data['client'] = request.headers.get('User-Agent')
data['oem'] = ''
data['intrusion'] = 0
data['uid'] = self.get_uid()
#msg = public.getMsg('PANEL_UPDATE_MSG');
data['o'] = public.get_oem_name()
sUrl = '{}/api/panel/updateLinuxEn'.format(self.__official_url)
updateInfo = json.loads(public.httpPost(sUrl,data))
if not updateInfo: return public.returnMsg(False,"CONNECT_ERR")
#updateInfo['msg'] = msg;
if os.path.exists('/www/server/panel/data/is_beta.pl'):
updateInfo['is_beta'] = 1
session['updateInfo'] = updateInfo
其中的核心上传代码为 updateInfo = json.loads(public.httpPost(sUrl,data))
,但是根据下面紧跟的代码逻辑可以看出,该行代码同样需要有返回值得到最新的版本信息,如果直接注释掉可能会影响版本更新。而 data
中又确实包含了太多可能含有隐私的信息,所以笔者选择新建一个空数据代替 data
进行上传。修改完的代码如下
#line 487
mplugin.ROWS = 10000
panelsys = system.system()
data = {}
data['ds'] = ''#self.get_other_info()
data['sites'] = str(public.M('sites').count())
data['ftps'] = str(public.M('ftps').count())
data['databases'] = str(public.M('databases').count())
data['system'] = panelsys.GetSystemVersion() + '|' + str(mem.total / 1024 / 1024) + 'MB|' + str(public.getCpuType()) + '*' + str(psutil.cpu_count()) + '|' + str(public.get_webserver()) + '|' +session['version']
data['system'] += '||'+self.GetInstalleds(mplugin.getPluginList(None))
data['logs'] = logs
data['client'] = request.headers.get('User-Agent')
data['oem'] = ''
data['intrusion'] = 0
data['uid'] = self.get_uid()
#msg = public.getMsg('PANEL_UPDATE_MSG');
data['o'] = public.get_oem_name()
fuckdata = {}
sUrl = '{}/api/panel/updateLinuxEn'.format(self.__official_url)
updateInfo = json.loads(public.httpPost(sUrl,fuckdata))
if not updateInfo: return public.returnMsg(False,"CONNECT_ERR")
#updateInfo['msg'] = msg;
if os.path.exists('/www/server/panel/data/is_beta.pl'):
updateInfo['is_beta'] = 1
session['updateInfo'] = updateInfo
其余已经发现会和主服务器通信的非必要内容(可根据需要自行修改)
/www/server/panel/class/ajax.py
data = json.loads(public.HttpGet('{}/api/panel/getBetaVersionLogs'.format(self.__official_url))) # line 450 用于获取内测版日志
return public.HttpGet(public.GetConfigValue('home') + '/Api/GetAD?name='+get.name + '&soc=' + get.soc)# line 1027 用于获取广告
关于手机客户端
如非必要建议不要使用 aaPanel Mobile
手机客户端。其实现方式是在面板上安装一个同名插件,手机上安装一个 App ,手机向面板插件发出申请,面板插件鉴权后,调用面板 API 进行操作。与面板本身开源不同,该插件和App并未开源,不知道是否存在通过过其他手段登录服务器的方式,故不建议使用。否则无需再去除上方跟踪器,仅仅是手机登录就足够收集更多的信息。
修改面板地址和端口(使用免费Cloudflare必须修改端口,否则可选)
按照上一步给出的网址登录 aaPanel 面板。由于之后要添加 Cloudflare CDN ,且 Cloudflare 对于免费用户支持的端口有限,需要从此文中提到的几个端口中选择一个并将默认的 10000
端口改为对应端口。这里因为我之后要套SSL协议,选择了支持 https 的2053
修改位于 Settings -> Panel port
及 Settings -> Domain
即可,随后前往Cloudflare将DNS记录指向面板IP。
但是请注意:笔者在书写文章完毕后重新思考了Cloudflare的原理,发现如果使用 Cloudflare 代理 Https 流量,本质上 Cloudflare 是在进行 MITM 即中间人攻击。他们会代替你向源服务器发出请求,并解读收到的数据包后,重新用自己的证书进行签名并返回给你,在这一过程中,Cloudflare 是可以获取你的 Https 解密数据的(哪怕增加二步验证也无效,因为 Cloudflare 可以直接抓取 Cookie )。如果使用 Cloudflare 代理控制面板,则代表你已经知晓并信任 Cloudflare ,否则建议对所有需要严格端到端加密的网站和数据,选择仅路由。
安装 LNMP 环境
安装面板后第一次进入应该会自动跳出提示窗,要求安装 LNMP 或 LAMP (推荐 LNMP),直接在该弹窗内选择即可。若未出现该弹窗,可以登出后,ssh连接服务器,执行 /etc/init.d/bt
命令重启面板,重新登陆可再次弹出,若仍未出现该窗口,请在 aaPanel -> App Store
自行选择版本并安装。如果你担心安全问题,可以选择自行编译,但是所需时间较长。(如果你知道本文存在的关键内容,以及就是为了部署该内容而来的,请使用自行编译安装,尤其是 Nginx)
添加 TLS 证书启用HTTPS协议(建议,可选)
注意,添加证书前,建议先配置 LNMP 或 LAMP 环境。因为如果使用 Let's Encrypt 申请,会验证网址下方的一个特定文件内容,如果没有环境无法创建80端口站点,也就无法访问和验证域名归属。同时,提交完成后看提示需要等待一段时间的不需要等太久,直接前往 https 协议的网址查看状态即可,配置成功后会自动切断 http 的连接,所以等不到返回的成功提示。
通过 Cloudflare CDN 生成证书文件并添加(不建议)
首先说明,由于 Cloudflare 给每个用户的每个网站都提供免费不限量证书,且有效期极长(10年以上),如果全部缴纳费用则价格极高。所以 Cloudflare 曾经在此说明,他们使用了自己创建的Origin CA来签发生成证书链并签发证书。而 Cloudflare Origin CA 目前没有受到被公众信任的证书签发机构给予的交叉签名,故暂不受各主流浏览器信任。如果你选择使用 Cloudflare 给你生成的SSL证书,需要手动安装信任 Cloudflare Origin CA ,否则依然会出现证书错误。
生成证书
进入Cloudflare 选中你的网站,并跳转到 SSL/TLS -> 源服务器 -> 源证书 -> 创建证书
,根据你的需求填写证书签名请求 (CSR) 以及需要保护的站点,并选择有效期。
应用证书
进入 aaPanel 转到 Settings -> Panel SSL(注意一定要点击绿色文字)
,分别填写私钥和证书文件的内容。随后根据需求修改选项并应用。刷新后查看证书信息会发现已经生效。
通过Let's Encrypt自动申请证书并应用
进入 aaPanel 转到 Settings -> Panel SSL(注意一定要点击开关按钮)
,会弹出一个窗口提示你这是高级功能,可能有无法访问面板的风险。我们在该窗口的 Cert Type
证书类型切换为 Let's Encrypt
,因为使用 Self-signed certificate
自签证书浏览器会提示证书不受信任,需要手动安装信任。随后填写你接收通知用的邮箱,提交即可。顺带一提, aaPanel 自己给自己申请的 Let's Encrypt 证书文件位于 /www/server/panel/ssl
,如有需要可以取用。
汉化面板(可选)
在去除跟踪器时偶然发现,面板安装路径 /www/server/panel/BTPanel/static/language/
即为语言包,其中 aaPanel 的 Simplified_Chinese
内容同样为英文,但是国内版面板项目中该部分内容为中文,可以通过替换合并对应文件,来实现 aaPanel 汉化。注意,截至到书写本文时,国际版的宝塔即 aaPanel 面板似乎并未提供切换语言的UI,需要在汉化完成后前往 /www/server/panel/config/config.json
修改其中的 language
键值对的值为 Simplified_Chinese
,方能得到效果。
我这边用代码合并了一个,汉化度大概70%,有细微缺陷,不介意可以下载之后替换使用。使用前请注意备份原先的语言文件避免出现错误无法修复。
Typecho的安装与配置(其他建站过程可类比)
首先说明,不管你是正常使用还是要干别的,建立任意站点都是可以的,这里用Typecho只是单纯因为我的服务器迁移了,需要重新搭建,所以用它做个示范,别的站点过程都差不多,另外本站点教程中出现的所有参数和配置全都在实际使用时候修改过了,有心人不需要专门找什么遗留信息了,自己搭建就好~
在aaPanel中创建站点
转到 Website -> Add Site
,将 Domain name
中的内容改为将来访问时使用的网址,同时 Database
选择 MySQL
(如有可能,建议创建数据库时使用 utf8mb4
格式,因为 MySQL 的 UTF-8 并不完整,只支持每个字符最多三个字节,而真正的 UTF-8 是每个字符最多四个字节,他们并没有修复这个问题,而是选择建立了一个新格式 utf8mb4
来实现四字节也就是真正的 UTF-8 ),并记录数据库名和密码,其余默认即可,如有需要自行更改。(如该站点是服务器上第一个使用数据库的站点,建立数据库前,可能需要先前往 aaPanel -> Database -> root password
重置数据库管理员账号密码)
修改DNS记录将域名解析到服务器
前往你所在的域名注册商或 DNS 解析服务提供商处修改即可
下载Typecho代码并上传到服务器对应位置
前往Typecho主页或官方项目地址下载你所需要版本的 Typecho 代码包,随后转到 aaPanel -> Files -> /www/wwwroot/your.site.domain
上传刚刚下载的代码包
安装Typecho
浏览器打开 https://your.site.domain/install.php
会出现安装引导界面,按照引导界面的提示依次进行即可。
给站点套SSL证书
使用 aaPanel 则直接在 Website -> your.site.domain -> SSL
,其他情况可以参考我之前的文章进行部署。顺带一提,用 aaPanel 给网站申请的 Let's Encrypt 证书位于 /www/server/panel/vhost/letsencrypt
和 /www/server/panel/vhost/ssl
如有需要可以取用。
Congratulations!
恭喜你,到这里你已经完成了一个普通服务器的搭建全过程,用类似方法多套几个网站就好~(后续内容付费解锁2333 开玩笑,后续内容其实才是最重要以及本文中含金量最高的,不过目前只给自己看,如果需要的人很多可以考虑部分公开,可以猜猜看后面有啥呀XD
可能遇到的问题
Typecho 无法进入后台
由于隐藏部分使用了特殊的方法来设置网站的TLS证书,所以有可能出现Typecho那里登录的时候,明明用户名密码都正确但还是没反应,界面刷一下改啥样还啥样,或者部分主题会说你用户名或密码错误,这个时候根据此 issues 的解决方式,先关闭https,正常访问登录Typecho后台 -> 设置 -> 基本设置 -> 站点地址改成https的域名。
然后编辑Typecho站点根目录下的文件config.inc.php加入下面一行配置,否则网站后台还是会调用HTTP资源。
define('__TYPECHO_SECURE__',true);
参考内容
对以上文章作者以及本文中引用到的其他文档作者和问题回答者表示由衷的感谢,顺序不分先后