SegmentFault 小人物最新的文章
2020-11-16T11:20:34+08:00
https://segmentfault.com/feeds/blogs
https://creativecommons.org/licenses/by-nc-nd/4.0/
使用NGINX反向代理部署Spring Boot应用
https://segmentfault.com/a/1190000038181155
2020-11-16T11:20:34+08:00
2020-11-16T11:20:34+08:00
断舍离
https://segmentfault.com/u/systemofdown
2
<h2>什么是Spring Boot</h2><p><a href="https://link.segmentfault.com/?enc=yQdLl47FwLkGf%2BvpIyi0eg%3D%3D.KRGdqEgbglo3Yq60c05WwF6A91GX0%2B3cK8NigJPtqCBXATr9x0x59ILwqHv%2B4fZY" rel="nofollow">Spring Boot</a>通过大量的默认配置,让使用<a href="https://link.segmentfault.com/?enc=OF7pFdiBUnTOHbH7%2FliZrA%3D%3D.axva4EeJLhrs3GVebQXKsLE770kcc4YSMLuYluGHA52k01eDcbsPp8Pn2I%2FSU7r2" rel="nofollow">Spring框架</a>进行开发变得方便快捷,从而使得Java开发人员专注于程序原型设计。本文介绍如何创建一个简单的Spring Boot应用,然后通过NGINX反向代理进行发布。</p><h2>创建一个初始化脚本</h2><p>将Spring Boot应用设置为服务以在服务器重启时自启动:</p><pre><code>/etc/systemd/system/helloworld.service
[Unit]
Description=Spring Boot HelloWorld
After=syslog.target
After=network.target[Service]
User=username
Type=simple
[Service]
ExecStart=/usr/bin/java -jar /home/linode/hello-world/build/libs/hello-world-0.0.1-SNAPSHOT.jar
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=helloworld
[Install]
WantedBy=multi-user.target</code></pre><p>启动服务:</p><pre><code>sudo systemctl start helloworld</code></pre><p>检查状态是否生效:</p><pre><code>sudo systemctl status helloworld</code></pre><h2>反向代理</h2><p>现在Spring应用已作为服务运行,NGINX代理允许将应用部署到非特权端口并设置SSL。</p><p>1.为反向代理创建NGINX配置文件:</p><pre><code>/etc/nginx/conf.d/helloworld.conf
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
}</code></pre><p>2.测试配置以确保无误:</p><pre><code>sudo nginx -t</code></pre><p>3.如果没有错误,请重新启动NGINX以使更改生效:</p><pre><code>sudo systemctl restart nginx</code></pre><p>4.现在可以通过浏览器访问该应用。</p>
maven项目老是提示找不到包,可是明明包都存在
https://segmentfault.com/a/1190000038174118
2020-11-15T13:27:57+08:00
2020-11-15T13:27:57+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>把包内的<em>.lastUpdated和</em>.repositories都删了,刷新下maven</p><p>项目执行maven clean install</p>
Yii2下composer 自定义github仓库
https://segmentfault.com/a/1190000021741328
2020-02-13T17:29:24+08:00
2020-02-13T17:29:24+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>专栏备份:<a href="https://link.segmentfault.com/?enc=HsHsWpj2nuJSpbSw74SKyQ%3D%3D.kYcG9P3XgfghF%2FBd92ogYDha3m1jsmh4eFPanXjJraAZwrMhwwF60MkIaopUUyvo" rel="nofollow">https://www.bestyii.com/topic/32</a><br>现在开源项目凉凉的比较多。 有些扩展还是相互依赖,有些时候就是临时改几处又没必要走Package发布过程。 解决办法很简单:</p>
<ol>
<li>克隆原始库,修改代码</li>
<li>发布新版本</li>
<li>composer.json中映射库到自己的github地址上</li>
</ol>
<pre><code>
"repositories": {
"0": {
"type": "composer",
"url": "https://asset-packagist.org"
},
"github": {
"type": "vcs",
"url": "https://github.com/GrazioX/markdown-latex"
},
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
}</code></pre>
Yii2 composer安装慢的解决办法
https://segmentfault.com/a/1190000020343984
2019-09-10T12:00:24+08:00
2019-09-10T12:00:24+08:00
断舍离
https://segmentfault.com/u/systemofdown
4
<p>专栏内容备份:<a href="https://link.segmentfault.com/?enc=0p0xv%2FbItpBdbBtI3Vf4kw%3D%3D.61VHtYj%2FQhLXQ14Wj9cnD19J69F8xYUNRg4hZXNjZi0%3D" rel="nofollow">https://www.bestyii.com/topic/1</a></p>
<p>在yii中引用php的开源项目用composer已经很方便了,引用前端的开源项目也有composer的插件<a href="https://link.segmentfault.com/?enc=ZfAigH168LbMCEiXvZ7Aog%3D%3D.KgNcPm8NOMFR4K%2FR7%2FSEufe8NvzwbDP4f5DlpO6kCpC2Lu2m0CCDiNOWaW2djj8k" rel="nofollow">fxp-asset</a>和<a href="https://link.segmentfault.com/?enc=nqScZKebjIP4pNglmxgrpQ%3D%3D.r5OHK2MS9%2F7TKZ6kaw1%2B4gYusIlTby41yjt00st2DScy%2BdQk6Itbc9q28DBG3ArG" rel="nofollow">Asset Packagist</a></p>
<p>以前yii默认采用前者,现在新的yii2模版默认采用后者,后者的作者就很厉害了,貌似是个重度yii用户,看来是被fxp-asset的执行缓慢给弄急眼了,所以自己搞了个更新的方法。<br>言归正传:<br>所以更快速的安装方式就是 Asset Packagist <a href="https://link.segmentfault.com/?enc=k9VVMh%2FqujXjFnq%2F9DMo8A%3D%3D.7yJfWHYD6LLR%2FPP%2FzkjH96XWdOYuFPA9F1xar51ClTg%3D" rel="nofollow">https://asset-packagist.org</a></p>
<p>其实就是2步:</p>
<ol>
<li>在config中关闭fxp-asset的调用</li>
<li>在源列表中加入asset-packagist库的配置</li>
</ol>
<pre><code>"config": {
"process-timeout": 1800,
"fxp-asset": {
"enabled": false
}
},
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
}
]</code></pre>
<p>如果composer的源采用阿里云镜像,完整写法如下:</p>
<pre><code>"repositories": {
"0": {
"type": "composer",
"url": "https://asset-packagist.org"
},
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
}</code></pre>
<p>需要注意的是,yii在yii\base\Application 中定义vendor路径的时候也定义了bower和npm路径:</p>
<pre><code class="php">
/**
* Sets the directory that stores vendor files.
* @param string $path the directory that stores vendor files.
*/
public function setVendorPath($path)
{
$this->_vendorPath = Yii::getAlias($path);
Yii::setAlias('@vendor', $this->_vendorPath);
Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower');
Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm');
}</code></pre>
<p>这就和asset-packagist的默认安装路径有了差别解决办法:<br>重新定义yii中的bower和npm路径</p>
<pre><code class="php">
$config = [
...
'aliases' => [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
],
...
];</code></pre>
Yii2 的安全最佳实践(Best Practices Of Security)
https://segmentfault.com/a/1190000020215733
2019-08-28T16:37:56+08:00
2019-08-28T16:37:56+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>专栏文章备份:<a href="https://link.segmentfault.com/?enc=3BMoZ5VYsYPhLrL%2FFquydA%3D%3D.SOEPgnx6wUKgZ941Y7eV5tUCu8sj292ozuywnX838c8%3D" rel="nofollow">https://www.bestyii.com/topic/2</a></p>
<p>下面,我们将会回顾常见的安全原则,并介绍在使用 Yii 开发应用程序时,如何避免潜在安全威胁。 大多数这些原则并非您独有,而是适用于网站或软件开发, 因此,您还可以找到有关这些背后的一般概念的进一步阅读的链接。</p>
<h2>基本准则</h2>
<p>无论是开发何种应用程序,我们都有两条基本的安全准则:</p>
<ul>
<li>过滤输入</li>
<li>转义输出</li>
</ul>
<h3>过滤输入</h3>
<p>过滤输入的意思是,用户输入不应该认为是安全的,你需要总是验证你获得的输入值是在允许范围内。 比如,我们假设可以通过三个字段完成排序<code> title,created_at 和 status</code>,然后,这个值是由用户输入提供的, 那么,最好在我们接收参数的时候,检查一下这个值是否是指定的范围。 对于基本的 PHP 而言,上述做法类似如下:</p>
<pre><code class="php">$sortBy = $_GET['sort'];
if (!in_array($sortBy, ['title', 'created_at', 'status'])) {
throw new Exception('Invalid sort value.');
}</code></pre>
<p>在 Yii 中,很大可能性,你会使用 <code>表单校验器</code> 来执行类似的检查。</p>
<p><strong>进一步阅读该主题:</strong></p>
<p><a href="https://link.segmentfault.com/?enc=LRuiaVnxYkZo88YMxgrC%2Fw%3D%3D.LgK1jTey6m0Qhomo%2B575qV7SDz8UNkyWbkycNfRgNzm%2Fxe8u1p2Ow4L2NnXq0gJo" rel="nofollow">https://www.owasp.org/index.p...</a><br><a href="https://link.segmentfault.com/?enc=AzJlAKu%2F4TgZKmeIFHPMrg%3D%3D.%2BgTgs51bm3k%2F58Mn7Uc4AjRAm%2FCTwI9qTF46Yd8cUetrdccpKzkZiTrs08IEMEO%2FQ3TbKu4MFrI3SuL0bOAWWQ%3D%3D" rel="nofollow">https://www.owasp.org/index.p...</a></p>
<h3>转义输出</h3>
<p>转义输出的意思是,根据我们使用数据的上下文环境,数据需要被转义。比如:在 HTML 上下文, 你需要转义<code> <,> </code>之类的特殊字符。在 JavaScript 或者 SQL 中,也有其他的特殊含义的字符串需要被转义。 由于手动的给所用的输出转义容易出错, Yii 提供了大量的工具来在不同的上下文执行转义。</p>
<p><strong>进一步阅读该话题:</strong></p>
<p><a href="https://link.segmentfault.com/?enc=LblNS5GRSw5EGOB%2Bl%2B0Jzw%3D%3D.hPFpbWaPXUpSqNptppw9s641anFWtpusFMwXsVwk2QBCVuzAuA85YdhNrEg%2BoyIDKvdcsg5dotK3JP%2Fu4z5yfA%3D%3D" rel="nofollow">https://www.owasp.org/index.p...</a><br><a href="https://link.segmentfault.com/?enc=FyMkjOnRQHbsvmcJTocmhw%3D%3D.mJYu6adw1ngUOldclolr4uOMeOFPGQEvLB7payxmkcKq%2FiHlKrOKgPafTPhidfkE" rel="nofollow">https://www.owasp.org/index.p...</a><br><a href="https://link.segmentfault.com/?enc=WOVZQ0PmASD6Mej%2Fhv5xdA%3D%3D.lOSeHR6x5TvXAVp1AldFhV7lunpY0WIJgiK%2BN%2FRNtHAciaNSCem9kb2684n54bGRSin1DltEgkTKjsZmcxSQYQ%3D%3D" rel="nofollow">https://www.owasp.org/index.p...</a></p>
<h2>避免 SQL 注入</h2>
<p>SQL 注入发生在查询语句是由连接未转义的字符串生成的场景,比如:</p>
<pre><code class="php">$username = $_GET['username'];
$sql = "SELECT * FROM user WHERE username = '$username'";</code></pre>
<p>除了提供正确的用户名外,攻击者可以给你的应用程序输入类似<code> '; DROP TABLE user; -- </code>的语句。 这将会导致生成如下的 SQL:</p>
<pre><code>SELECT * FROM user WHERE username = ''; DROP TABLE user; --'</code></pre>
<p>这是一个合法的查询语句,并将会执行以空的用户名搜索用户操作,然后,删除 user 表。 这极有可能导致网站出错,数据丢失。(你是否进行了规律的数据备份?)</p>
<p>在 Yii 中,大部分的数据查询是通过 <code>Active Record</code> 进行的, 而其是完全使用 PDO 预处理语句执行 SQL 查询的。在预处理语句中,上述示例中,构造 SQL 查询的场景是不可能发生的。</p>
<p>有时,你仍需要使用 <code>raw queries</code> 或者 <code>query builder</code>。 在这种情况下,你应该使用安全的方式传递参数。如果数据是提供给表列的值,最好使用预处理语句:</p>
<pre><code class="php">// query builder
$userIDs = (new Query())
->select('id')
->from('user')
->where('status=:status', [':status' => $status])
->all();
// DAO
$userIDs = $connection
->createCommand('SELECT id FROM user where status=:status')
->bindValues([':status' => $status])
->queryColumn();</code></pre>
<p>如果数据是用于指定列的名字,或者表的名字,最好的方式是只允许预定义的枚举值。</p>
<pre><code class="php">function actionList($orderBy = null)
{
if (!in_array($orderBy, ['name', 'status'])) {
throw new BadRequestHttpException('Only name and status are allowed to order by.')
}
// ...
}</code></pre>
<p>如果上述方法不行,表名或者列名应该被转义。Yii 针对这种转义提供了一个特殊的语法, 这样可以在所有支持的数据库都使用一套方案。</p>
<pre><code class="php">$sql = "SELECT COUNT([[$column]]) FROM {{table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();</code></pre>
<p>你可以在 Quoting Table and Column Names 中获取更多的语法细节。</p>
<p><strong>进一步阅读该话题:</strong></p>
<p><a href="https://link.segmentfault.com/?enc=sa4jicID7%2FlfvkGXiA0tOA%3D%3D.beGdQ0Hu6SJ4UkJcN7V%2BT8sdf7PVy6AiIKo4ew2kTf%2Bv9DGQofl%2FA%2FJIicnTsL5s" rel="nofollow">https://www.owasp.org/index.p...</a></p>
<h2>防止 XSS 攻击</h2>
<p>XSS 或者跨站脚本发生在输出 HTML 到浏览器时,输出内容没有正确的转义。 例如,如果用户可以输入其名称,那么他输入 <code><script>alert('Hello!');</script></code> 而非其名字 <code>Alexander</code>, 所有输出没有转义直接输出用户名的页面都会执行 JavaScript 代码 <code>alert('Hello!');</code>, 这会导致浏览器页面上出现一个警告弹出框。就具体的站点而言,除了这种无意义的警告输出外, 这样的脚本可以以你的名义发送一些消息到后台,甚至执行一些银行交易行为。</p>
<p>避免 XSS 攻击在 Yii 中非常简单,有如下两种一般情况:</p>
<ul>
<li>你希望数据以纯文本输出。</li>
<li>你希望数据以 HTML 形式输出。</li>
</ul>
<p>如果你需要的是纯文本,你可以如下简单的转义:</p>
<pre><code class="php"><?= \yii\helpers\Html::encode($username) ?></code></pre>
<p>如果是 HTML,我们可以用 <code>HtmlPurifier</code> 帮助类来执行:</p>
<pre><code class="php"><?= \yii\helpers\HtmlPurifier::process($description) ?></code></pre>
<p>注意 HtmlPurifier 帮助类的处理过程较为费时,建议增加缓存。</p>
<p><strong>进一步阅读该话题:</strong></p>
<p><a href="https://link.segmentfault.com/?enc=IofH1K9qi2BcQq2wjLPCSA%3D%3D.rD92%2BiwWSSEFWvbEZ%2Bml6kjKWsY3l%2F%2FT4%2B7uqfG4okSLllq4H7o9WsiypZkeEKI4%2BRQQpt%2Br4Ra8yiX3Kke9Xw%3D%3D" rel="nofollow">https://www.owasp.org/index.p...</a></p>
<h2>防止 CSRF 攻击</h2>
<p>CSRF 是跨站请求伪造的缩写。这个攻击思想源自许多应用程序假设来自用户的浏览器请求是由用户自己产生的, 而事实并非如此。</p>
<p>例如,网站 an.example.com 有一个 /logout 网址,当使用简单的 GET 请求访问时, 记录用户退出。 只要用户的请求一切正常,但是有一天坏人们故意在用户经常访问的论坛上放上 <code><img src="http://an.example.com/logout"></code>。 浏览器在请求图像或请求页面之间没有任何区别, 所以当用户打开一个带有这样一个被操作过的 <img> 标签的页面时, 浏览器将 GET 请求发送到该 URL,用户将从 an.example.com 注销。</p>
<p>这是 CSRF 攻击如何运作的基本思路。可以说用户退出并不是一件严重的事情, 然而这仅仅是一个例子,使用这种方法可以做更多的事情,例如触发付款或者是改变数据。 想象一下如果某个网站有一个这样的 <code>http://an.example.com/purse/transfer?to=anotherUser&amount=2000</code> 网址。 使用 GET 请求访问它会导致从授权用户账户转账 $2000 给 anotherUser。 我们知道,浏览器将始终发送 GET 请求来加载图像, 所以我们可以修改代码以仅接受该 URL 上的 POST 请求。 不幸的是,这并不会拯救我们,因为攻击者可以放置一些 JavaScript 代码而不是 <img> 标签,这样就可以向该 URL 发送 POST 请求。</p>
<p>出于这个原因,Yii 应用其他机制来防止 CSRF 攻击。</p>
<p><strong>为了避免 CSRF 攻击,你总是需要:</strong></p>
<ol>
<li>遵循 HTTP 准则,比如 GET 不应该改变应用的状态。 有关详细信息,请参阅 <a href="https://link.segmentfault.com/?enc=C4ML%2BLmaNORjcdV3KMwnVw%3D%3D.XCGN2rWJBr59G4eUIc8XLSvCV%2FOJOlW4Z9ZP5jr9cttLASN5azpV%2BazQUle9fap9H%2B6z2%2BbxXQnR4hkpDHlvKg%3D%3D" rel="nofollow">RFC2616</a>。</li>
<li>保证 Yii CSRF 保护开启。</li>
</ol>
<p>有的时候你需要对每个控制器和/或方法使用禁用 CSRF。可以通过设置其属性来实现:</p>
<pre><code class="php">namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public $enableCsrfValidation = false;
public function actionIndex()
{
// CSRF validation will not be applied to this and other actions
}
}</code></pre>
<p>要对每个自定义方法禁用 CSRF 验证,您可以使用:</p>
<pre><code class="php">namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function beforeAction($action)
{
// ...set `$this->enableCsrfValidation` here based on some conditions...
// call parent method that will check CSRF if such property is true.
return parent::beforeAction($action);
}
}</code></pre>
<p>在 standalone actions 禁用 CSRF 必须在 <code>init()</code> 方法中设置。 不要把这段代码放在 beforeRun() 方法中,因为它不会起任何作用。</p>
<pre><code class="php"><?php
namespace app\components;
use yii\base\Action;
class ContactAction extends Action
{
public function init()
{
parent::init();
$this->controller->enableCsrfValidation = false;
}
public function run()
{
$model = new ContactForm();
$request = Yii::$app->request;
if ($request->referrer === 'yiipowered.com'
&& $model->load($request->post())
&& $model->validate()
) {
$model->sendEmail();
}
}
}</code></pre>
<blockquote>
<code>警告:</code> 禁用 CSRF 将允许任何站点向您的站点发送 POST 请求。在这种情况下,实施额外验证非常重要,例如检查 IP 地址或秘密令牌。</blockquote>
<p><strong>进一步阅读该话题:</strong></p>
<p><a href="https://link.segmentfault.com/?enc=iOR6FRQZzcORdHo7L5NYdQ%3D%3D.S21fT90rM8lSnCTuOZOBsMrAg6b1zlZsr0sIc2I52GP%2FJMDiYC%2F1Sqdw3%2FY5dn4e" rel="nofollow">https://www.owasp.org/index.p...</a></p>
<h2>防止文件暴露</h2>
<p>默认的服务器 webroot 目录指向包含有 <code>index.php</code> 的 <code>web</code> 目录。在共享托管环境下,这样是不可能的, 这样导致了所有的代码,配置,日志都在webroot目录。</p>
<p>如果是这样,别忘了拒绝除了 web 目录以外的目录的访问权限。 如果没法这样做,考虑将你的应用程序托管在其他地方。</p>
<p>在生产环境关闭调试信息和工具<br>在调试模式下, Yii 展示了大量的错误信息,这样是对开发有用的。 同样,这些调试信息对于攻击者而言也是方便其用于破解数据结构,配置值,以及你的部分代码。 永远不要在生产模式下将你的 <code>index.php</code> 中的 <code>YII_DEBUG</code> 设置为 <code>true</code>。</p>
<p>你同样也不应该在生产模式下开启 Gii。它可以被用于获取数据结构信息, 代码,以及简单的用 Gii 生成的代码覆盖你的代码。</p>
<p>调试工具栏同样也应该避免在生产环境出现,除非非常有必要。它将会暴露所有的应用和配置的详情信息。 如果你确定需要,反复确认其访问权限限定在你自己的 IP。</p>
<p><strong>进一步阅读该话题:</strong></p>
<p><a href="https://link.segmentfault.com/?enc=AVaS818MMHOyJGFduf3HvA%3D%3D.wYPvhTuviiDMkuYmUdfKuTvPga6YmL80BR8fwPcEMGylytqaIpVF0IJ5N%2FQ2pgCzYBQA8y%2FD7JO7YntWMaNFPw%3D%3D" rel="nofollow">https://www.owasp.org/index.p...</a><br><a href="https://link.segmentfault.com/?enc=wy1Y6lus1Lfvi%2FsT6d7W6w%3D%3D.CCuaKVQ%2Fip1tD75hxuzpwoqM%2B7vm1ablWT1jKb3qkj9JzDvfWQV%2BVWekyFk%2BIHX3%2FbVZFUXezNXBiF7U3Mm1Hw%3D%3D" rel="nofollow">https://www.owasp.org/index.p...</a></p>
<h2>使用 TLS 上的安全连接(HTTPS的启用)</h2>
<p>Yii 提供依赖 cookie 和/或 PHP 会话的功能。如果您的连接受到威胁,这些可能会很容易受到攻击。 如果应用程序通过 TLS 使用安全连接,则风险会降低。<br>有关如何配置它的说明,请参阅您的 Web 服务器文档。 </p>
<p>现在各大云平台都提供免费的单域名SSL证书,如阿里云,<a href="https://link.segmentfault.com/?enc=eLUaztUyR5vCNMOO49Y3qA%3D%3D.%2BagYwSX5Y8WUqoVJGlzyZadqn16doKvak1TzP7QF%2FBT74TEWk9MSsJ8kRRVgwdCPhLRtFCXUhnSARZnggzo%2Ftw%3D%3D" rel="nofollow">腾讯云</a>。</p>
<p>以阿里云部署Nginx下的SSL证书为例:<br>修改nginx.conf文件如下:</p>
<pre><code># 以下属性中以ssl开头的属性代表与证书配置有关,其他属性请根据自己的需要进行配置。
server {
listen 443 ssl;
server_name localhost; # localhost修改为您证书绑定的域名。
root html;
index index.html index.htm;
ssl_certificate cert/domain name.pem; #将domain name.pem替换成您证书的文件名。
ssl_certificate_key cert/domain name.key; #将domain name.key替换成您证书的密钥文件名。
ssl_session_timeout 5m;
#使用此加密套件。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
#使用该协议进行配置。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root html; #站点目录。
index index.html index.htm;
}
}
</code></pre>
<p>设置http请求自动跳转https。(一般都这么做)</p>
<pre><code>server {
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}</code></pre>
<blockquote>参考官方说明,写的能不能配置成功自己脑补<br>腾讯云 <a href="https://link.segmentfault.com/?enc=7eEYz%2F1huMkCMi%2BXVCuNnQ%3D%3D.xS50OZWxnYlK2unDS1tC%2Fld2rh8TiPaQi32IDLszpErpKIGpi8ZJLZE31YXkUgappJwbsHaqUgecldUM9s2sUA%3D%3D" rel="nofollow">Nginx 服务器证书安装</a><br>阿里云 <a href="https://link.segmentfault.com/?enc=b4bGVoDqICDsP9AixL5MVw%3D%3D.0jD9MlM2EeQLomipNMNsmeDMxnOS97RFCQDDamMHx3W5B6nDqr7SOLGyy3C0V918U93h8MoAv7ipNv3ZGeoLdg%3D%3D" rel="nofollow">在Nginx/Tengine服务器上安装证书</a>
</blockquote>
<h2>安全服务器配置</h2>
<p>本节的目的是强调在为基于 Yii 的网站提供服务配置时需要考虑的风险。 除了这里涉及的要点之外, 可能还有其他与安全相关的配置选项, 所以不要认为这部分是完整的。</p>
<h3>避免 Host-header 攻击</h3>
<p>像 yiiwebUrlManager 和 yiihelpersUrl 这样的类会使用 currently requested host name 来生成链接。 如果 Web 服务器配置为独立于 <code>Host</code> 标头的值提供相同的站点,这个信息并不可靠, 并且 <a href="https://link.segmentfault.com/?enc=WaEXO4D8eNPqu2bwuHs5Dg%3D%3D.v7hi4bj6G%2Fo49ZfshyAY3YWUiXWoi%2FgkLyymJGrwQ6eTXUh%2FJZoMZJQIkX%2FIQiXiMBFqwD9JCk6m3M0rCbbrDw%3D%3D" rel="nofollow">可能由发送HTTP请求的用户伪造</a>。 在这种情况下,您应该修复您的 Web 服务器配置以便仅为指定的主机名提供站点服务 或者通过设置 <code>request</code> 应用程序组件的 hostInfo 属性来显式设置或过滤该值。</p>
<blockquote>
<code>注意:</code> 您应该始更倾向于使用 web 服务器配置 'host header attack' 保护而不是使用过滤器。 仅当服务器配置设置不可用时 yiifiltersHostControl 才应该被使用。</blockquote>
<p><strong>以Nginx为例:</strong></p>
<p>方法一:</p>
<p>修改nginx.conf</p>
<p>添加一个默认server,当host头被修改匹配不到server时会跳到该默认server,该默认server直接返回403错误。</p>
<p>例子如下:</p>
<pre><code class="config">server {
listen 80 default;
server_name _;
server_name_in_redirect off;
location / {
return 403;
}
}</code></pre>
<p>重启nginx即可。</p>
<p>方法二:</p>
<p>修改nginx.conf</p>
<p>在目标server添加检测规则,参考以下标红配置:</p>
<pre><code class="config">server {
server_name abc.com;
listen 80;
if ($http_Host !~*^abc.com:80$)
{
return 403;
}
...
}</code></pre>
<p>重启nginx即可。</p>
<p>有关于服务器配置的更多信息,请参阅您的 web 服务器的文档:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=tQvvrUSkR1eSyYm3rZeNZQ%3D%3D.PXG7QPwaeGuDPL24WI%2BAzOxb5nR2IQVr3XpDw83bOs5nSTqJhgYtXepAwf0izYkt0yQ7JkPmfeRJzLuM7Tdbxg%3D%3D" rel="nofollow">在Web服务器防止Host头攻击</a></li>
<li>Apache 2:<a href="https://link.segmentfault.com/?enc=OvPjOWYy96aNqp6OD979xw%3D%3D.v8iRiUQ6MtwykHVkg2zctWPhdABSar8XYV2gRw92mJMbZM%2Fl3pVYJpvq%2FVtpqNUEHVEX5XibGdfQHZ7oLJjznOU79eLdZ7ahYx5po%2BD1f3c%3D" rel="nofollow">http://httpd.apache.org/docs/...</a>
</li>
<li>Nginx:<a href="https://link.segmentfault.com/?enc=1W6TB9MEyZFTy40r8qqfQg%3D%3D.pLK5u6%2F%2FRwuyUY552kRDZmfm2DiHyqnWTvHHtXE0TE9EHLyq4u%2FKT%2BL3laJJzEZkl1Rw4ajnxB5X%2Bn%2F6a%2BeURj1EXH18r%2BLOF%2FoFNBe%2FUV8%3D" rel="nofollow">https://www.nginx.com/resourc...</a>
</li>
</ul>
<p><strong><code>如果您无权访问服务器配置,您可以在应用程序级别设置 yii\filters\HostControl 过滤器, 以防此类的攻击。</code></strong></p>
<pre><code class="php">// Web Application configuration file
return [
'as hostControl' => [
'class' => 'yii\filters\HostControl',
'allowedHosts' => [
'example.com',
'*.example.com',
],
'fallbackHostInfo' => 'https://example.com',
],
// ...
];</code></pre>
<h2>补充阅读</h2>
<ul><li><a href="https://link.segmentfault.com/?enc=jZnn4Pd8%2FqNsyD5DgONYfw%3D%3D.A05CQh2x4CHcNtC%2FCJ1QlsAMlYMSvYSjnLwd2CWSPVJoG3e07jET01WCD4VjrT3mneBatIOKvGCTVLonB0vshA%3D%3D" rel="nofollow">web安全攻防思维导图</a></li></ul>
<p><img src="/img/bVbwZh6" alt="web安全攻防思维导图" title="web安全攻防思维导图"></p>
<ul><li>web攻击及防御技术 (来源网络)</li></ul>
<p><img src="/img/bVbwZlh" alt="web攻击及防御技术" title="web攻击及防御技术"></p>
12种开源Web安全扫描程序
https://segmentfault.com/a/1190000020166648
2019-08-23T16:41:04+08:00
2019-08-23T16:41:04+08:00
断舍离
https://segmentfault.com/u/systemofdown
3
<h2>1.Arachni</h2>
<p>Arachni是一款基于Ruby框架构建的高性能安全扫描程序,适用于现代Web应用程序。它可用于Mac,Windows和Linux的便携式二进制文件</p>
<p><img src="/img/bVbwMjX?w=800&h=480" alt="arachni.png" title="arachni.png"></p>
<ul>
<li>Arachnin能适用于下面的平台和语言</li>
<li>Windows, Solaris, Linux, BSD, Unix</li>
<li>Nginx, Apache, Tomcat, IIS, Jetty</li>
<li>Java, Ruby, Python, ASP, PHP</li>
<li>Django, Rails, CherryPy, CakePHP, ASP.NET MVC, Symfony</li>
</ul>
<p>漏洞检测有下面这些:</p>
<ul>
<li>NoSQL/Blind/SQL/Code/LDAP/Command/XPath injection</li>
<li>Cross-site request forgery</li>
<li>Path traversal</li>
<li>Local/Remote File inclusions</li>
<li>Response splitting</li>
<li>Cross-site scripting</li>
<li>Unvalidated DOM redirects</li>
<li>Source code disclosure</li>
</ul>
<p>可以选择使用HTML,XML,文本,JSON,YAML等格式的审计报告,Arachni可以利用插件将扫描范围扩展到下一个级别</p>
<h2>2.XssPy</h2>
<p>一个基于Python的XSS(跨站脚本)漏洞扫描器</p>
<h2>3.w3af</h2>
<p>w3af,从2006开始使用python开发的开源项目,可以用在window和linux环境下,<br>w3af可以将有效载荷注入到标题,URL,cookie,查询字符串,后期数据等,以利用Web应用程序进行审计。它支持各种记录方法进行报告。</p>
<p>例如:</p>
<ul>
<li>CSV</li>
<li>HTML</li>
<li>Console</li>
<li>Text</li>
<li>XML</li>
<li>Email</li>
</ul>
<p>更多的功能可利用插件库</p>
<h2>4.Nikto</h2>
<p>Netsparker赞助的开源项目旨在发现Web服务器的配置错误,插件和网页漏洞。 Nikto对6500多个风险项目进行综合测试。<br>它支持HTTP代理,SSL,或NTLM身份验证等,并可以定义每个目标扫描的最大执行时间。 <br>Nikola也可以在Kali Linux中使用<br><img src="/img/bVbwMkf?w=579&h=415" alt="kali-linux-nitko.png" title="kali-linux-nitko.png"></p>
<p>它看起来很有希望用于Intranet解决方案来查找Web服务器的安全风险</p>
<h2>5.Wfuzz</h2>
<p>Wfuzz(Web Fuzzer)是针对渗透测试的应用程序评估工具。您可以对任何字段的HTTP请求中的数据进行模糊处理,以利用该Web应用程序并审核Web应用程序。 Wfuzz需要在要运行扫描的计算机上安装Python。</p>
<h2>6.OWASP ZAP</h2>
<p>ZAP(Zet Attack Proxy)是全球数百名志愿者积极更新的着名渗透测试工具之一。 它是跨平台的基于Java的工具,可以在Raspberry Pi上运行。 ZIP位于浏览器和Web应用程序之间,用于拦截和检查消息<br><img src="/img/bVbwMkr?w=749&h=599" alt="zap.jpeg" title="zap.jpeg"></p>
<p>下面的一些值得一提的是ZAP的功能。</p>
<ul>
<li>Fuzzer</li>
<li>Automated & passive scanner</li>
<li>Supports multiple scripting languages</li>
<li>Forced browsing</li>
</ul>
<p>强烈建议查看OWASP ZAP教程视频来学习</p>
<h2>7.Wapiti</h2>
<p>Wapiti扫描给定目标的网页,并寻找脚本和表单来注入数据,看看是否有漏洞。它不是一个源代码安全检查,而是执行黑盒扫描。<br>它支持GET和POST HTTP方法,HTTP和HTTPS代理,多个认证等。</p>
<h2>8.Vega</h2>
<p>Vega由Subgraph开发,Subgraph是一个用Java编写的多平台支持工具,用于查找XSS,SQLi,RFI和许多其他漏洞。 维加有良好的图形用户界面,并能够通过登录到具有给定凭据的应用程序来执行自动扫描。<br><img src="/img/bVbwMkU?w=423&h=375" alt="vega.png" title="vega.png"></p>
<p>如果您是开发人员,则可以利用vega API创建新的攻击模块</p>
<h2>9.SQLmap</h2>
<p>利用SQLmap可以对数据库执行渗透测试来发现缺陷。<br><img src="/img/bVbwMkX?w=630&h=344" alt="sqlmap.png" title="sqlmap.png"></p>
<p>它适用于任何操作系统上的Python 2.6或2.7。如果你正在寻找SQL注入和利用数据库,那么sqlmap会有帮助。</p>
<h2>10.Grabber</h2>
<p>它是基于Python的小工具,并且做得很不错。一些Grabber的功能是:<br>JavaScript源代码分析器 跨站点脚本,<br>SQL注入,<br>盲注SQL PHP应用程序测试使用PHP-SAT</p>
<h2>11.Golismero</h2>
<p>管理和运行Wfuzz,DNS recon,sqlmap,OpenVas,机器人分析器等一些流行安全工具的框架。<br><img src="/img/bVbwMo9?w=802&h=585" alt="golismero.jpg" title="golismero.jpg"></p>
<p>Golismero非常棒,它可以巩固来自其他工具的测试反馈,并合并显示一个单一的结果。</p>
<h2>12.OWASP Xenotix XSS</h2>
<p>OWASP的Xenotix XSS是一个用于查找和利用跨站点脚本的高级框架。它内置了三个智能模糊器,用于快速扫描和改进结果。<br><img src="/img/bVbwMpc?w=805&h=480" alt="owasp-xss.png" title="owasp-xss.png"></p>
<p>它有数百个功能,我们可以看看这里列出的所有。</p>
<blockquote>网络安全对于在线业务至关重要,我希望上面列出的免费/开源漏洞扫描程序可以帮助您找到风险,以便在有人利用此漏洞之前减轻风险</blockquote>
CentOS查看进程、杀死进程、启动进程等常用命令
https://segmentfault.com/a/1190000020130447
2019-08-20T17:03:28+08:00
2019-08-20T17:03:28+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>关键字: linux 查进程、杀进程、起进程<br>1.查进程</p>
<pre><code>ps命令查找与进程相关的PID号:
ps a 显示现行终端机下的所有程序,包括其他用户的程序。
ps -A 显示所有程序。
ps c 列出程序时,显示每个程序真正的指令名称,而不包含路径,参数或常驻服务的标示。
ps -e 此参数的效果和指定"A"参数相同。
ps e 列出程序时,显示每个程序所使用的环境变量。
ps f 用ASCII字符显示树状结构,表达程序间的相互关系。
ps -H 显示树状结构,表示程序间的相互关系。
ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。
ps s 采用程序信号的格式显示程序状况。
ps S 列出程序时,包括已中断的子程序资料。
ps -t<终端机编号> 指定终端机编号,并列出属于该终端机的程序的状况。
ps u 以用户为主的格式来显示程序状况。
ps x 显示所有程序,不以终端机来区分。
最常用的方法是ps aux,然后再通过管道使用grep命令过滤查找特定的进程,然后再对特定的进程进行操作。
ps aux | grep program_filter_word,ps -ef |grep tomcat
</code></pre>
<p>ps -ef|grep java|grep -v grep 显示出所有的java进程,去处掉当前的grep进程。</p>
<p>2.杀进程<br> 使用kill命令结束进程:kill xxx<br> 常用:kill -9 324<br> Linux下还提供了一个killall命令,可以直接使用进程的名字而不是进程标识号,例如:# killall -9 NAME</p>
<p>3.进入到进程的执行文件所在的路径下,执行文件 ./文件名</p>
<p>附:</p>
<p>这是本人花了两天时间整理得来的,一些最常用的地球人都知道的命令就省去啦!最后提供pdf手册下载</p>
<ol><li>更改档案拥有者</li></ol>
<p>命令 : chown [-cfhvR] [--help] [--version] user[:group] file... <br>功能 : 更改文件或者文件夹的拥有者 <br>参数格式 : <br> user : 新的档案拥有者的使用者 IDgroup : 新的档案拥有者的使用者群体(group) <br> -c : 若该档案拥有者确实已经更改,才显示其更改动作 <br> -f : 若该档案拥有者无法被更改也不要显示错误讯息 <br> -h : 只对于连结(link)进行变更,而非该 link 真正指向的档案 <br> -v : 显示拥有者变更的详细资料 <br> -R : 对目前目录下的所有档案与子目录进行相同的拥有者变更(即以递回的方式逐个变更) </p>
<p>例如:chown -R oracle:oinstall /oracle/u01/app/oracle</p>
<pre><code> 更改目录拥有者为oracle
</code></pre>
<ol><li>
<p>修改权限 <br> 命令:chmod (change mode) <br> 功能:改变文件的读写和执行权限。有符号法和八进制数字法。 <br> 选项:(1)符号法: <br>命令格式:chmod {u|g|o|a}{+|-|=}{r|w|x} filename</p>
<pre><code> u (user) 表示用户本人。
g (group) 表示同组用户。
o (oher) 表示其他用户。
a (all) 表示所有用户。
+ 用于给予指定用户的许可权限。
- 用于取消指定用户的许可权限。 </code></pre>
</li></ol>
<pre><code> = 将所许可的权限赋给文件。
r (read) 读许可,表示可以拷贝该文件或目录的内容。
w (write) 写许可,表示可以修改该文件或目录的内容。
x (execute)执行许可,表示可以执行该文件或进入目录。
(2)八进制数字法: </code></pre>
<p>命令格式:chmod abc file <br> 其中a,b,c各为一个八进制数字,分别表示User、Group、及Other的权限。</p>
<pre><code> 4 (100) 表示可读。
2 (010) 表示可写。
1 (001) 表示可执行。 </code></pre>
<p>若要rwx属性则4+2+1=7; <br> 若要rw-属性则4+2=6; <br> 若要r-x属性则4+1=5。</p>
<pre><code>例如:# chmod a+rx filename
让所有用户可以读和执行文件filename。
# chmod go-rx filename
取消同组和其他用户的读和执行文件filename的权限。
# chmod 741 filename
让本人可读写执行、同组用户可读、其他用户可执行文件filename。 </code></pre>
<p># chmod -R 755 /home/oracle</p>
<pre><code>递归更改目录权限,本人可读写执行、同组用户可读可执行、其他用户可读可执行
</code></pre>
<ol>
<li>修改文件日期 <br> 命令:touch <br> 格式:touch filenae <br> 功能:改变文件的日期,不对文件的内容做改动,若文件不存在则建立新文件。 <br> 例如:% touch file</li>
<li>
<p>链接文件 <br> 命令:ln (link) <br> 格式:ln [option] filename linkname</p>
<pre><code> ln [option] directory pathname </code></pre>
<p>功能:为文件或目录建立一个链。其中,filename和directory是源文件名和</p>
<pre><code> 源目录名;linkname和pathname分别表示与源文件或源目录名相链接的
文件或目录。 </code></pre>
<p>选项:-s 为文件或目录建立符号链接。不加-s表示为文件或目录建立硬链接 <br> 注释:链接的目地在于,对一个文件或目录赋予两个以上的名字,使其可以出</p>
<pre><code> 现在不同的目录中,既可以使文件或目录共享,又可以节省磁盘空间。 </code></pre>
<p>例如:% ln -s filename linkname</p>
</li>
<li>显示日期 <br> 命令:date <br> 例如:% date</li>
<li>显示日历 <br> 命令:cal (calendar) <br> 格式:cal [month] year <br> 功能:显示某年内指定的日历 <br> 例如:% cal 1998</li>
<li>
<p>显示文件头部 <br> 命令:head <br> 格式:head [option] filename <br> 功能:显示文件的头部 <br> 选项:缺省 显示文件的头10行。</p>
<pre><code> -i 显示文件的开始 i行。 </code></pre>
<p>例如:% head filename</p>
</li>
<li>
<p>显示文件尾部 <br> 命令:tail <br> 格式:tail [option] filename <br> 功能:显示文件的尾部 <br> 选项:缺省 显示文件的末10行。</p>
<pre><code> -i 显示文件最后 i行。
+i 从文件的第i行开始显示。 </code></pre>
<p>例如:% tail filename</p>
</li>
<li>显示用户标识 <br> 命令:id <br> 格式:id [option] [user] <br> 功能:显示用户标识及用户所属的所有组。 <br> 选项:-a 显示用户名、用户标识及用户所属的所有组 <br> 注释: <br> 例如:% id username</li>
<li>查看当前登录的用户 <br> 命令:users</li>
<li>显示都谁登录到机器上 <br> 命令:who <br> 格式:who <br> 功能:显示当前正在系统中的所有用户名字,使用终端设备号,注册时间。 <br> 例如:% who</li>
<li>显示当前终端上的用户名 <br> 命令:whoami <br> 格式:whoami <br> 功能:显示出当前终端上使用的用户。 <br> 例如:% whoami</li>
<li>
<p>寻找文件 <br> 命令:find <br> 格式:find pathname [option] expression <br> 功能:在所给的路经名下寻找符合表达式相匹配的文件。 <br> 选项:-name 表示文件名</p>
<pre><code> -user 用户名,选取该用户所属的文件
-size 按大小查找,以block为单位,一个block是512B
-mtime n 按最后一次修改时间查找,选取n天内被修改的文件 </code></pre>
<p>-perm 按权限查找</p>
<pre><code> -type 按文件类型查找 </code></pre>
<p>-atime 按最后一次访问时间查找 </p>
<p>例如:% find ./ -name '<em>abc</em>' -print</p>
</li>
<li>搜索文件中匹配符 <br> 命令:grep <br> 格式:grep [option] pattern filenames <br> 功能:逐行搜索所指定的文件或标准输入,并显示匹配模式的每一行。 <br> 选项:-i 匹配时忽略大小写 <br>-v 找出模式失配的行 <p>例如:% grep -i 'java*' ./test/run.sh</p>
</li>
<li>统计文件字数 <br> 命令:wc [option] filename <br> 功能:统计文件中的文件行数、字数和字符数。 <br> 选项:-l 统计文件的行数</li>
</ol>
<p>-w 统计文件的单词数 <br>-c 统计文件的字符数</p>
<pre><code>注释:若缺省文件名则指标准输入
例如:% wc -c ./test/run.sh
</code></pre>
<ol><li>
<p>显示磁盘空间 <br>命令:df (disk free) <br>格式:df [option] <br>功能:显示磁盘空间的使用情况,包括文件系统安装的目录名、块设备名、总</p>
<pre><code> 字节数、已用字节数、剩余字节数占用百分比。 </code></pre>
<p>选项:</p>
</li></ol>
<p>-a:显示全部的档案系统和各分割区的磁盘使用情形 <br>-i:显示i -nodes的使用量 <br>-k:大小用k来表示 (默认值) <br>-t:显示某一个档案系统的所有分割区磁盘使用量 <br>-x:显示不是某一个档案系统的所有分割区磁盘使用量 <br>-T:显示每个分割区所属的档案系统名称 <br>-h: 表示使用「Human-readable」的输出,也就是在档案系统大小使用 GB、MB 等易读的格式。</p>
<pre><code>注释:
例如:% df -hi
</code></pre>
<ol><li>查询档案或目录的磁盘使用空间 <br>命令:du (disk usage) <br>格式:du [option] [filename] <br>功能:以指定的目录下的子目录为单位,显示每个目录内所有档案所占用的磁盘空间大小 <br>选项:</li></ol>
<p>-a:显示全部目录和其次目录下的每个档案所占的磁盘空间 <br>-b:大小用bytes来表示 (默认值为k bytes) <br>-c:最后再加上总计 (默认值) <br>-s:只显示各档案大小的总合 <br>-x:只计算同属同一个档案系统的档案 <br>-L:计算所有的档案大小 <br>-h: 表示档案系统大小使用 GB、MB 等易读的格式。</p>
<pre><code>例如:% du -a </code></pre>
<p>% du -sh /etc 只显示该目录的总合 <br>% du /etc | sort -nr | more 统计结果用sort 指令进行排序, <br>sort 的参数 -nr 表示要以数字排序法进行反向排序。</p>
<ol><li>
<p>显示进程 <br> 命令:ps <br> 格式:ps [option] <br> 功能:显示系统中进程的信息。包括进程ID、控制进程终端、执行时间和命令。 <br> 选项: <br>-a 显示所有进程信息 <br>-U uidlist 列出这个用户的所有进程</p>
<pre><code> -e 显示当前运行的每一个进程信息
-f 显示一个完整的列表 </code></pre>
<p>-x 显示包括没有终端控制的进程状况 。 <br> 注释: 例如:% ps -ef % ps -aux 然后再利用一个管道符号导向到grep去查找特定的进程,然后再对特定的进程进行操作。 19. 终止进程 命令:kill 格式:kill [option] pid 功能:向指定的进程送信号或终止进程。kill指令的用途是送一个signal给某一个process, 因为大部份送的都是用来杀掉 process 的 SIGKILL 或 SIGHUP ,因此称为 kill 选项:-9 强行终止进程 注释:pid标示进程号,可由ps命令得到。 例如:% kill -9 pid 你也可以用 kill -l 来察看可代替 signal 号码的数目字。kill 的详细情形请参阅 man kill。 20. 查看自己的IP地址 命令:ifconfig 格式:ifconfig -a 21. 查看路由表 命令:netstat 格式:netstat -rn 22. 远程登录 命令:telnet 格式:telnet hostname 23. 文件传输 命令:ftp (file transfer program) 格式:ftp hostname 功能:网络文件传输及远程操作。 选项:ftp命令: cd [dirname] 进入远程机的目录 lcd [dirname] 设置本地机的目录 dir/ls 显示远程的目录文件 bin 以二进制方式进行传输 asc 以文本文件方式进行传输 get/mget 从远程机取一个或多个文件 put/mput 向远程机送一个或多个文件 prompt 打开或关闭多个文件传送时的交互提示 close 关闭与远程机的连接 quit 退出ftp !/exit ftp登陆状态下,!表示暂时退出ftp状态回到本地目录,exit表示返回ftp状态 注释: 例如:% ftp hostname 24. 查看自己的电子邮件 命令:mailx 格式:mailx 选项: delete 删除 next 下一个 quit 退出 reply 回复 25. 回忆命令 命令:history 格式:history 功能:帮助用户回忆执行过的命令。 选项: 注释: 例如:% history 26. 网上对话 命令:talk 格式:talk username 功能:在网上与另一用户进行对话。 选项: 注释:对话时系统把终端分为上下两部分,上半部显示自己键入信息,下半部 显示对方用户键入的信息。键入delete或Ctrl+C则结束对话。 例如:% talk username 27. 允许或拒绝接受信息 命令:mesg (message) 格式:mesg [n/y] 功能:允许或拒绝其它用户向自己所用的终端发送信息。 选项:n 拒绝其它用户向自己所用的终端写信息 y 允许其它用户向自己所用的终端写信息(缺省值) 注释: 例如:% mesg n 28. 给其他用户写信息 命令:write 格式:write username [ttyname] 功能:给其他用户的终端写信息。 选项: 注释:若对方没有拒绝,两用户可进行交谈,键入EOF或Ctrl+C则结束对话。 例如:write username 29. 创建、修改、删除用户和群组 a. 创建群组: 例如: groupadd oinstall 创建群组名为oinstall的组 groupadd -g 344 dba 创建组号是344的组,此时在/etc/passwd文件中产生一个组ID(GID)是344的项目。 b. 修改群组: groupmod:该命令用于改变用户组帐号的属性 groupmod –g 新的GID 用户组帐号名 groupmod –n 新组名 原组名:此命令由于改变用户组的名称 c. 删除群组: groupdel 组名:该命令用于删除指定的组帐号 d. 新建用户: 命令: useradd [-d home] [-s shell] [-c comment] [-m [-k template]] [-f inactive] [-e expire ] [-p passwd] [-r] name 主要参数 -c:加上备注文字,备注文字保存在passwd的备注栏中。 -d:指定用户登入时的启始目录。 -D:变更预设值。 -e:指定账号的有效期限,缺省表示永久有效。 -f:指定在密码过期后多少天即关闭该账号。 -g:指定用户所属的群组。 -G:指定用户所属的附加群组。 -m:自动建立用户的登入目录。 -M:不要自动建立用户的登入目录。 -n:取消建立以用户名称为名的群组。 -r:建立系统账号。 -s:指定用户登入后所使用的shell。 -u:指定用户ID号。 举例: # useradd -g oinstall -G dba oracle 创建Oracle用户 e. 删除用户 命令: userdel 用户名 删除指定的用户帐号 userdel –r 用户名(userdel 用户名;rm 用户名):删除指定的用户帐号及宿主目录 例:#useradd -g root kkk //把kkk用户加入root组里 f. 修改用户 命令: usermod 修改已有用户的信息 usermod –l 旧用户名 新用户名: 修改用户名 usermod –L 用户名: 用于锁定指定用户账号,使其不能登陆系统 usermod –U 用户名: 对锁定的用户帐号进行解锁 passwd –d 用户名: 使帐号无口令,即用户不需要口令就能登录系统 例:#usermod -l user2 user1 //把用户user2改名为user1 30. 启动、关闭防火墙 永久打开或则关闭 chkconfig iptables on chkconfig iptables off 即时生效:重启后还原 service iptables start service iptables stop 或者: /etc/init.d/iptables start /etc/init.d/iptables stop 31. 启动VSFTP服务 即时启动: /etc/init.d/vsftpd start 即时停止: /etc/init.d/vsftpd stop 开机默认VSFTP服务自动启动: 方法一:(常用方便) [root@localhost etc]# chkconfig --list|grep vsftpd ( 查看情况) vsftpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off [root@localhost etc]# chkconfig vsftpd on (执行ON设置) 或者:方法二: 修改文件 /etc/rc.local , 把行/usr/local/sbin/vsftpd & 插入文件中,以实现开机自动启动。 32. vi技巧 a. 进入输入模式 新增 (append) a :从光标所在位置後面开始新增资料,光标後的资料随新增资料向後移动。 A:从光标所在列最後面的地方开始新增资料。 插入 (insert) i:从光标所在位置前面开始插入资料,光标後的资料随新增资料向後移动。 I :从光标所在列的第一个非空白字元前面开始插入资料。 开始 (open) o :在光标所在列下新增一列并进入输入模式。 O: 在光标所在列上方新增一列并进入输入模式。 b. 退出vi 在指令模式下键入:q,:q!,:wq或:x(注意:号),就会退出vi。其中:wq和:x是存盘退出,而:q是直接退出,如果文件已有新的变化,vi会提示你保存文件而:q命令也会失效,这时你可以用:w命令保存文件后再用:q 退出,或用:wq或:x命令退出,如果你不想保存改变后的文件,你就需要用:q!命令,这个命令将不保存文件而直接退出vi。 c. 删除与修改文件的命令: x:删除光标所在字符。 dd :删除光标所在的列。 r :修改光标所在字元,r 後接著要修正的字符。 R:进入取替换状态,新增文字会覆盖原先文字,直到按 [ESC] 回到指令模式下为止。 s:删除光标所在字元,并进入输入模式。 S:删除光标所在的列,并进入输入模式。 d. 屏幕翻滚类命令 Ctrl+u: 向文件首翻半屏 Ctrl+d: 向文件尾翻半屏 Ctrl+f: 向文件尾翻一屏 Ctrl+b: 向文件首翻一屏 nz: 将第n行滚至屏幕顶部,不指定n时将当前行滚至屏幕顶部。 e. 删除命令 ndw或ndW: 删除光标处开始及其后的n-1个字 do: 删至行首 d$: 删至行尾 ndd: 删除当前行及其后n-1行 x或X: 删除一个字符,x删除光标后的,而X删除光标前的 Ctrl+u: 删除输入方式下所输入的文本 f. 搜索及替换命令 /pattern: 从光标开始处向文件尾搜索pattern ?pattern: 从光标开始处向文件首搜索pattern n: 在同一方向重复上一次搜索命令 N: 在反方向上重复上一次搜索命令 :s/p1/p2/g: 将当前行中所有p1均用p2替代 :n1,n2s/p1/p2/g: 将第n1至n2行中所有p1均用p2替代 :g/p1/s//p2/g: 将文件中所有p1均用p2替换 g. 复制,黏贴 (1) 选定文本块,使用v进入可视模式;移动光标键选定内容 (2) 复制选定块到缓冲区,用y;复制整行,用yy (3) 剪切选定块到缓冲区,用d;剪切整行用dd (4) 粘贴缓冲区中的内容,用p h. 其他 在同一编辑窗打开第二个文件,用:sp [filename] 在多个编辑文件之间切换,用Ctrl+w</p>
</li></ol>
supervisord进程管理服务
https://segmentfault.com/a/1190000020130381
2019-08-20T16:58:39+08:00
2019-08-20T16:58:39+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>专栏文章备份:<a href="https://link.segmentfault.com/?enc=t6MmVgODQtDdEAton8h6rw%3D%3D.lCG4u%2B6f9PQyZoIWiJSzQcDpQMMWw5iZiQwAhe9D0SI%3D" rel="nofollow">https://www.bestyii.com/topic/3</a></p>
<h2>简介</h2>
<p>官网 <a href="https://link.segmentfault.com/?enc=%2BZ7lsv5al59Zma7EAZ7DjQ%3D%3D.JugycEbBq8pI%2B8C%2F7TppO0qPsKNEaRC%2BqzKJeDASSec%3D" rel="nofollow">http://supervisord.org/</a><br>supervisor是一个允许用户监视和控制在linux操作系统的进程数量的客户端/服务器系统。由python语言编写,用以监控服务器的运行,发现问题能立即自动预警及自动重启等功能。supervisor还要求管理的程序是非daemon程序,supervisord会帮你把它转成daemon程序。</p>
<h2>组件</h2>
<ul><li>supervisord</li></ul>
<p>服务端,他负责在他自己的进程下起一个子进程,相应来自客户端的命令,重启崩溃或异常退出的子进程,输出相关日志,针对于子进程活跃期间的时间进行生成和管理<br>配置文件位置: /etc/supervisord.conf 注意配置合理权限</p>
<ul><li>supervisorctl</li></ul>
<p>命令行客户端,有supervisord提供的一个shell-like接口,通过它,用户可以连接到不同的supervisorctl进程,查看,起停子进程,列出正在运行的子进程。通过TCP进行交互,提供认证,在[supervisorctl]段进行统一的配置</p>
<ul><li>web server</li></ul>
<p>supervisorctl的web管理界面,通过访问<a href="https://link.segmentfault.com/?enc=GQDtwqDO01hXOstPr8oa1w%3D%3D.MMG3nA%2FxjkB7bjC04%2FKLMA06%2FE0364ot54vjrbW4xjU%3D" rel="nofollow">http://localhost</a>:9001/来管理子进程状态,[inet_http_server]这段进行配置</p>
<h2>安装</h2>
<p>前提条件是要有python环境,linux一般自带python环境,这里以centOS为例。</p>
<ul><li>yum安装</li></ul>
<pre><code>yum install -y supervisor</code></pre>
<h2>启动</h2>
<pre><code>systemctl start supervisor</code></pre>
<h2>配置文件解析</h2>
<p>生成配置文件:<br>echo_supervisord_conf > /tmp/supervisord.conf<br>一般yum安装后配置文件默认位置是/etc/supervisor/supervisord.conf。其中注释是以分号开头</p>
<pre><code>[unix_http_server] #这段是通过socket文件启动的web server,这个要有,因为命令行supervisorctl是通过这个实现的。
file = /tmp/supervisor.sock
chmod = 0777
chown= nobody:nogroup
username = user
password = 123
[inet_http_server] #通过网络端口启动的web server
port = 127.0.0.1:9001
username = user
password = 123
[supervisord] #这块是服务配置
logfile = /tmp/supervisord.log 日志文件
logfile_maxbytes = 50MB 日志文件最大size
logfile_backups=10 日志轮询下备份数
loglevel = info 日志级别
pidfile = /tmp/supervisord.pid pid文件位置
nodaemon = false 如果是true,supervisor将在前端启动
minfds = 1024 supervisord启动成功的最小文件描述符数
minprocs = 200 supervisord启动成功的最小进程描述符数
umask = 022
user = chrism 启动用户,这块要注意,这个用户要有相应的目录权限
identifier = supervisor supervisor进程的 identifier字符串,用户RPC协议接口
directory = /tmp 当supervisord服务daemonizes时,切换到这个目录,可用这个%(here)s变量来扩展到整个配置文件
nocleanup = true 禁止supervisord在启动时间清空任何存在的AUTO子日志文件
childlogdir = /tmp AUTO自日志文件目录
strip_ansi = false 除去在子日志文件中所有的 ANSI转义序列
environment = KEY1="value1",KEY2="value2" 一个键/值的列表,一个环境变量吧?
[supervisorctl]
serverurl = unix:///tmp/supervisor.sock
username = chris
password = 123
prompt = mysupervisor String used as supervisorctl prompt.作为supervisorctl提示字符串。</code></pre>
<h3>管理进程配置</h3>
<p>配置文件位置:/etc/supervisor/conf.d/<br>一般有如下配置项:</p>
<pre><code>process_name=%(program_name)s #进程名称,默认是程序名称
command 启动程序命令
numprocs=1 #进程数量
directory=/tmp #路径
umask=022 #掩码
priority=999 #优先级,越大被开起的越早
autorestart=true #自动重启
startsecs=10 #启动等待时间(秒)
startretries=3 #启动重试次数
stopsignal=TERM #关闭信号
stopwaitsecs=10 #关闭前等待时间
user=chrism #监控用户权限
redirect_stderr=false #重定向报错输出
stdout_logfile=/a/path #输入重定向为日志
stdout_logfile_maxbytes=1MB #日志大小
stdout_logfile_backups=10 #日志备份
stdout_capture_maxbytes=1MB
stderr_logfile=/a/path
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10
stderr_capture_maxbytes=1MB
environment=A=1,B=2 #预定义环境变量
serverurl=AUTO #系统URL
</code></pre>
<h3>示例</h3>
<p>为了更好的展示,我这边写了一个简单的服务。下面的具体的代码:</p>
<pre><code>#!/usr/bin/env python
import socket
HOST, PORT = '', 8080
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
while True:
client_connection, client_address = listen_socket.accept()
request = client_connection.recv(1024)
http_response = """\
HTTP/1.1 200 OK
Hello World!
"""
client_connection.sendall(http_response)
client_connection.close()</code></pre>
<p>这个脚本是一个简单的web服务器,8080端口,所有访问都会返回 Hello World!<br>下面我们看下配置文件/etc/supervisor/conf.d/webserver.conf</p>
<pre><code>[program:webserver]
autostart=true
startretries=3
command=/opt/webserver.py</code></pre>
<p>查看状态</p>
<pre><code class="sh">root@0c1fc23d1398:~# supervisorctl status
webserver RUNNING pid 1120, uptime 0:08:07</code></pre>
<p>supervisorctl命令</p>
<p>1.交互模式</p>
<p>直接输入supervisorctl就进入交互模式。</p>
<pre><code>root@0c1fc23d1398:~# supervisorctl
webserver RUNNING pid 1120, uptime 0:09:40
supervisor> </code></pre>
<p>2.命令行模式</p>
<p>如上节所说的<code>supervisorctl status</code></p>
<p>3.具体命令项</p>
<p>交互和命令行模式有一样。</p>
<pre><code>reread 重新加载配置文件
update 将配置文件里新增的子进程加入进程组,如果设置了autostart=true则会启动新新增的子进程
status 查看所有进程状态
status 查看指定进程状态
start all 启动所有子进程
start 启动指定子进程
restart all 重启所有子进程
restart 重启指定子进程
stop all 停止所有子进程
stop 停止指定子进程
reload 重启supervisord
add 添加子进程到进程组
reomve 从进程组移除子进程,需要先stop。注意:移除后,需要使用reread和update才能重新运行该进程</code></pre>
<h2>web server界面</h2>
<p>还记得“配置文件解析”一节关于web server段的配置吗?不记得可以回去看一眼。我们稍微展示下web界面。浏览器输入<a>http://</a><ip>:<port>,会弹出输入用户名和密码的弹窗,输入信息后可以看到界面了。</p>
<p><img src="/img/bVbwDes" alt="图片描述" title="图片描述"></p>
<p>web界面</p>
<p>从界面中可以看到,服务的状态,进程id和运行的时间。还有一些简单的操作,例如重启,停止,清除日志,监控日志等。<br>常见的错误</p>
<p>1.多进程启动</p>
<p>报错信息如下:</p>
<pre><code>Starting supervisor: Error: %(process_num) must be present within process_name when numprocs > 1 in section 'program:nginx' (file: '/etc/supervisor/conf.d/nginx.conf')
For help, use /usr/bin/supervisord -h</code></pre>
<p>这是配置文件格式不对,下面是格式简介<br>当numprocs=1时,process_name=%(program_name)s<br>当numprocs>=2时,%(program_name)s_%(process_num)<br>类似下面的配置</p>
<pre><code>[program:sleeptime]
autostart=true
startretries=3
command=/opt/sleeptime.py
#主要是下面的2行
process_name=%(program_name)s%(process_num)s
numprocs=4</code></pre>
<p>这个时候查看进程状态,会发现有4个进程出现</p>
<pre><code>root@0c1fc23d1398:/etc/supervisor/conf.d# supervisorctl status
sleeptime:sleeptime0 RUNNING pid 1139, uptime 0:00:04
sleeptime:sleeptime1 RUNNING pid 1140, uptime 0:00:04
sleeptime:sleeptime2 RUNNING pid 1141, uptime 0:00:04
sleeptime:sleeptime3 RUNNING pid 1142, uptime 0:00:03
webserver RUNNING pid 1120, uptime 0:30:00</code></pre>
<p>2.直接运行 supervisorctl status 报:</p>
<pre><code>Error: Server requires authentication
For help, use /usr/local/bin/supervisorctl -h</code></pre>
<p>因为你设置访问账号密码,所以只能先supervisorctl进去,在status。<br>主要还是看日志信息,和程序本身的日志。</p>
Docker 升级到最新版本
https://segmentfault.com/a/1190000020073249
2019-08-14T18:14:00+08:00
2019-08-14T18:14:00+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>专栏文章备份:<a href="https://link.segmentfault.com/?enc=69qwXxiTkPfuAYizQsp0Ow%3D%3D.bvQx0F9vAWelkzLac3c1urvQD5UwG7vsYFERVPRfCiY%3D" rel="nofollow">https://www.bestyii.com/topic/4</a></p>
<p>1、查看系统要求</p>
<p>Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看CentOS的内核版本。</p>
<pre><code>uname -a</code></pre>
<p>2、删除旧版本</p>
<pre><code>yum remove docker docker-common docker-selinux docker-engine</code></pre>
<p>3、安装需要的软件包<br>yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的</p>
<pre><code>sudo yum install -y yum-utils device-mapper-persistent-data lvm2</code></pre>
<p>4、设置Docker yum源</p>
<pre><code>sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo</code></pre>
<p>5、查看所有仓库中所有docker版本<br>可以查看所有仓库中所有docker版本,并选择特定的版本安装。</p>
<pre><code>yum list docker-ce --showduplicates | sort -r</code></pre>
<p>6、安装docker</p>
<pre><code>sudo yum install docker-ce</code></pre>
<p>由于repo中默认只开启stable仓库,故这里安装的是最新稳docker-ce-cli-19.03.1-3.el7.x86_64。<br>如果要安装特定版本:</p>
<pre><code>sudo yum install docker-ce-18.06.1.ce </code></pre>
<p>7、启动<br>设置为开机启动</p>
<pre><code>systemctl enable docker</code></pre>
<p>启动</p>
<pre><code>systemctl start docker</code></pre>
<p>查看启动状态</p>
<pre><code>systemctl status docker</code></pre>
<p>查看版本</p>
<pre><code>docker version</code></pre>
关于PHP文件包含目录配置 open_basedir
https://segmentfault.com/a/1190000020024481
2019-08-09T16:41:26+08:00
2019-08-09T16:41:26+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>open_basedir</p>
<p>open_basedir 官方介绍<br>open_basedir string<br>将 PHP 所能打开的文件限制在指定的目录树,包括文件本身。本指令不受安全模式打开或者关闭的影响。<br>当一个脚本试图用例如 fopen() 或者 gzopen() 打开一个文件时,该文件的位置将被检查。<br>当文件在指定的目录树之外时 PHP 将拒绝打开它。<br>所有的符号连接都会被解析,所以不可能通过符号连接来避开此限制。<br>特殊值 . 指明脚本的工作目录将被作为基准目录。但这有些危险,因为脚本的工作目录可以轻易被 chdir() 而改变。<br>在 httpd.conf 文件中中,open_basedir 可以像其它任何配置选项一样用“php_admin_value open_basedir none”的方法关闭(例如某些虚拟主机中)。<br>在 Windows 中,用分号分隔目录。在任何其它系统中用冒号分隔目录。作为 Apache 模块时,父目录中的 open_basedir 路径自动被继承。<br>用 open_basedir 指定的限制实际上是前缀,不是目录名。<br>也就是说“open_basedir = /dir/incl”也会允许访问“/dir/include”和“/dir/incls”,如果它们存在的话。<br>如果要将访问限制在仅为指定的目录,用斜线结束路径名。例如:“open_basedir = /dir/incl/”。</p>
<p>Note: 支持多个目录是 3.0.7 加入的。<br>默认是允许打开所有文件。</p>
<p>接下来总结下, 可以有几种方式设置限制包含目录<br>1)php.ini open_basedir = /home/wwwroot/<br>2)ini_set 注意:PHP >5.2.3+ PHP_INI_ALL ,不建议使用,这么设置太随意了。<br>3)apache 的 httpd.conf 中Directory配置<br>"php_admin_value open_basedir none" #关闭 <br>php_admin_value open_basedir "/home/wwwroot/:/tmp/:/var/tmp/:/proc/"</p>
<p>httpd.conf中VirtualHost<br>php_admin_value open_basedir "/home/wwwroot/:/tmp/:/var/tmp/:/proc/"</p>
<p>4)nginx fastcgi.conf<br>fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/";<br>5).user.ini 文件<br>设置方法同 1 .</p>
CentOS7下 yum方式安装MySQL5.7
https://segmentfault.com/a/1190000019835909
2019-07-22T15:25:41+08:00
2019-07-22T15:25:41+08:00
断舍离
https://segmentfault.com/u/systemofdown
2
<blockquote>在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB。</blockquote>
<h2>1 下载并安装MySQL官方的 Yum Repository</h2>
<p>使用下面的命令就直接下载了安装用的Yum Repository</p>
<pre><code> wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm</code></pre>
<h2>2 安装 Yum Repository</h2>
<pre><code> yum -y install mysql57-community-release-el7-10.noarch.rpm</code></pre>
<h2>3 安装MySQL服务</h2>
<p>这步可能会花些时间,安装完成后就会覆盖掉之前的mariadb。</p>
<pre><code> yum -y install mysql-community-server</code></pre>
<h2>4 启动MySQL</h2>
<pre><code> systemctl start mysqld.service</code></pre>
<p>查看MySQL运行状态,运行状态如图:</p>
<pre><code>systemctl status mysqld.service</code></pre>
CentOS7下gitlab邮件服务设置
https://segmentfault.com/a/1190000019826441
2019-07-21T14:22:44+08:00
2019-07-21T14:22:44+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<h2>1.配置文件位置</h2>
<pre><code>vim /etc/gitlab/gitlab.rb</code></pre>
<p>以腾讯企业邮箱为例其它邮箱大同小异</p>
<pre><code>gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.exmail.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "邮箱地址"
gitlab_rails['smtp_password'] = "password"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_domain'] = "exmail.qq.com"
gitlab_rails['gitlab_email_from'] = '邮箱地址' </code></pre>
<h2>2.更新配置</h2>
<pre><code> gitlab-ctl reconfigure</code></pre>
<h2>3.重启服务</h2>
<pre><code>gitlab-ctl restart</code></pre>
<h2>4.非必需步骤进入控制台</h2>
<p>测试邮件服务是否正常</p>
<pre><code>gitlab-rails console
等到出现 “>”再执行下面命令
Notify.test_email("XXX@XXX.XX","title","gitlab").deliver_now</code></pre>
CentOS7下GitLab跨大版本升级
https://segmentfault.com/a/1190000019826212
2019-07-21T13:41:31+08:00
2019-07-21T13:41:31+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<h2>备份&升级</h2>
<p>1.在升级前一定要做好备份,记录自己当前gitlab-ce的版本号。</p>
<p>查看当前gitlab版本号</p>
<pre><code>yum list | grep gitlab-ce</code></pre>
<p>2.备份文件</p>
<pre><code>gitlab-rake gitlab:backup:create</code></pre>
<blockquote>在目录/var/opt/gitlab/backups/下会生成一个备份文件如:1552552057_gitlab_backup.tar,其中1552552057即为此次备份都版本号。<br><strong>还原备份(失败)</strong><br>命令:<em>gitlab-rake gitlab:backup:restore BACKUP=备份版本号</em>
</blockquote>
<p>3.配置gitlab-yum 本地源<br>如清华的镜像:<br><a href="https://link.segmentfault.com/?enc=yLWf4mHrHR9f%2FX8z3yUaNA%3D%3D.l25CrsBM0MLaHUvwtEXA8g5m6bW%2FwBK2WCuJTqz%2BHskRpPD7drwwBgH2DsWp7c8ljFaFkuNgoCqr%2FIRRbt5spg%3D%3D" rel="nofollow"></a><a href="https://link.segmentfault.com/?enc=MoN8Ddy7ET%2Bjhte7hk09DA%3D%3D.lr5fYTbmDZPnFH8cOPvVQAbsBNUah0gSjEfid06c3iQmtuE4umofdwVlsiRkVm8goCo7f4S8XABeUK3OpLH9qw%3D%3D" rel="nofollow">https://mirrors.tuna.tsinghua...</a></p>
<pre><code>[root@localhost ~]# cat << EOF > /etc/yum.repos.d/gitlab-ce.repo
> [gitlab-ce]
> name=gitlab-ce
> baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/
> repo_gpgcheck=0
> gpgcheck=0
> enable=1
> gpgkey=https://packages.gitlab.com/gpg.key
> EOF</code></pre>
<p>4.yum install安装</p>
<blockquote><strong>升级Gitlab(注意:由于升级不能跨越大版本号,因此只能升级到当前大版本号到最高版本,方可升级到下一个大版本号)</strong></blockquote>
<p>依次执行下面指令逐步升级,在每一步安装成功后如果发现界面500,不可访问,那么执行gitlab-ctl reconfigure指令刷新配置文件。(一定保证数据可以正常访问方可执行下一步升级指令)</p>
<blockquote>升级过程中有可能会升级PostgreSQL,命令:sudo gitlab-ctl pg-upgrade</blockquote>
<pre><code>yum install gitlab-ce-10.8.7-ce.0.el7
yum install gitlab-ce-11.0.0-ce.0.el7
yum install gitlab-ce-11.11.5-ce.0.el7
yum install gitlab-ce-12.0.0-ce.0.el7
...
yum update</code></pre>
<p>查看当前版本号</p>
<pre><code>cat /opt/gitlab/embedded/service/gitlab-rails/VERSION</code></pre>
Yii2 queue的队列使用
https://segmentfault.com/a/1190000019805030
2019-07-18T19:11:06+08:00
2019-07-18T19:11:06+08:00
断舍离
https://segmentfault.com/u/systemofdown
3
<p>专栏文章备份:<a href="https://link.segmentfault.com/?enc=gHrFQDJIiE0nmHMB5RQaCw%3D%3D.360XzuutBvhgr45J%2BKtacxMlGROquOrCwSxpCvsM9bo%3D" rel="nofollow">https://www.bestyii.com/topic/7</a></p>
<p>少废话主要看文档<br><a href="https://link.segmentfault.com/?enc=a4isP3AYZZn3T2daaW%2BzRQ%3D%3D.KHgkr5p6GwcUm1EuyTGWZ9SSnwi41stlPTZO2gA2WNVRcEQHQaUWQXm1R34d%2Bl8elWdzqCQB3lRcV1o8MjjZDWp5Erl7v5xseq0gcv3lD8A%3D" rel="nofollow">官方文档 </a><a href="https://link.segmentfault.com/?enc=9el4NOHZdkLUcytQxMuvvw%3D%3D.tm%2Fjl6%2FC70c65fJTAYbRnHp37Ecneu6yMepvkiTr7UwBSZTWqF3bbF6e%2BhBHg9bUC5wtO4QCeEim4PDg8Xn1JACddPNlqvJxZSfqETC1WHo%3D" rel="nofollow">https://github.com/yiisoft/yi...</a></p>
<h2>yii2-queue 的使用</h2>
<h3>1.安装</h3>
<pre><code>composer require --prefer-dist yiisoft/yii2-queue
</code></pre>
<h3>2.配置,在 common/config/main.php 中配置</h3>
<p>redis作为驱动</p>
<pre><code>return [
'bootstrap' => [
'queue', // 把这个组件注册到控制台
],
'components' => [
'redis' => [
'class' => \yii\redis\Connection::class,
// ...
],
'queue' => [
'class' => \yii\queue\redis\Queue::class,
'as log' => \yii\queue\LogBehavior::class,//错误日志 默认为 console/runtime/logs/app.log
'redis' => 'redis', // 连接组件或它的配置
'channel' => 'queue', // Queue channel key
],
],
];
</code></pre>
<p>File 作为驱动</p>
<pre><code>return [
'bootstrap' => [
'queue', // 把这个组件注册到控制台
],
'components' => [
'queue' => [
'class' => \yii\queue\file\Queue::class,
'as log' => \yii\queue\LogBehavior::class,//错误日志 默认为 console/runtime/logs/app.log
'path' => '@runtime/queue',
],
],
];
</code></pre>
<h3>3.新建 frontend/components/DownloadJob</h3>
<pre><code>class DownloadJob extends BaseObject implements \yii\queue\JobInterface
{
public $url;
public $file;
public function execute($queue)
{
file_put_contents($this->file, file_get_contents($this->url));
}
}
</code></pre>
<h3>4.控制台</h3>
<p>控制台用于监听和处理队列任务。<br>cmd 下 监听队列</p>
<pre><code>yii queue/listen
</code></pre>
<h3>5.添加到队列</h3>
<p>将任务添加到队列:</p>
<pre><code>Yii::$app->queue->push(new frontend\components\DownloadJob([
'url' => 'http://example.com/image.jpg',
'file' => '/tmp/image.jpg',
]));
</code></pre>
<p>将任务推送到队列中延时5分钟运行:</p>
<pre><code>Yii::$app->queue->delay(5 * 60)->push(new frontend\components\DownloadJob([
'url' => 'http://example.com/image.jpg',
'file' => '/tmp/image.jpg',
]));
</code></pre>
<h3>6.测试</h3>
<p>执行 5 中的程序,控制台监听到,便会后台自动 下载<a href="https://link.segmentfault.com/?enc=d60vPQ%2BHXF2vAXir5WA95g%3D%3D.8mvZ2HoK9U6o%2Bx9FR%2FMlkXOO%2Bi33u3Jk9gD%2BwSlzWuK3rN5%2FgkjJqZx8nGBtP0prxE5wp3gNQkcvbPqGny90r1ZChcRIEssMt6Oi7BM4Xas%3D" rel="nofollow">http://example.com/image.jpg...</a></p>
<h2>启动worker</h2>
<p>可以使用Supervisor或Systemd 来启动多进程worker,也可以使用 Cron,我们这里主要说一下Supervisor</p>
<h2>centos7 supervisor的使用</h2>
<h3>1.安装supervisor</h3>
<pre><code>yum update
yum install epel-release
yum install -y supervisor
#开机启动
systemctl enable supervisord
#启动
systemctl start supervisord
</code></pre>
<h3>2.supervisor 命令</h3>
<pre><code>supervisorctl status 查看进程状态
supervisorctl reload 重启supervisord
supervisorctl start|stop|restart 启动关闭重启进程
</code></pre>
<h3>3.添加配置文件</h3>
<p>Supervisor 配置文件通常在 /etc/supervisord.d 目录下. 你可以创建一些配置文件在这里.<br><strong>注:文件名是.ini结尾</strong></p>
<p>下面就是个例子:</p>
<pre><code>[program:yii-queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/php /var/www/my_project/yii queue/listen --verbose=1 --color=0
autostart=true
autorestart=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/my_project/log/yii-queue-worker.log
</code></pre>
RxJs脑图
https://segmentfault.com/a/1190000019181425
2019-05-14T22:14:38+08:00
2019-05-14T22:14:38+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p><img src="/img/bVbsD7U?w=1830&h=3598" alt="图片描述" title="图片描述"></p>
ant.design 奇技淫巧
https://segmentfault.com/a/1190000019151022
2019-05-12T09:59:26+08:00
2019-05-12T09:59:26+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>如果你在 vscode 中编写Angular,那么安装 <a href="https://link.segmentfault.com/?enc=ZQJ7oIDTWTN2ZKdY46ZhDg%3D%3D.HL8WWgzGCUibzg4UYrHgRl9e%2BGNqpUCFiqpfURe4th%2BSaV%2FTFveLzPb0jIVBJyyEvyUrRXiHJL4%2B7itgTDy4fDoHyy6H%2FqnWPPnkdUbwKp145%2BOy%2F9J5v1MBVMJ7ObnA" rel="nofollow">ng-zorro-vscode</a> 代码片断,对开发效率很有帮助。</p>
<p><img src="/img/bVbswdm?w=960&h=400" alt="help.gif" title="help.gif"></p>
angular 的坑
https://segmentfault.com/a/1190000019150972
2019-05-12T09:52:49+08:00
2019-05-12T09:52:49+08:00
断舍离
https://segmentfault.com/u/systemofdown
0
<p>在angular.cli中使用cnpm包管理用具</p>
<pre><code>ng config --global cli.packageManager cnpm</code></pre>
<h2>安装全局,这样允许直接在CMD命令行中使用 <code>ng</code> 命令。</h2>
<pre><code>cnpm install -g @angular/cli@latest</code></pre>
<h2>创建项目</h2>
<pre><code>ng new demo
cd demo</code></pre>
<h2>安装包</h2>
<pre><code>npm install --save ng-zorro-antd</code></pre>
认识JWT
https://segmentfault.com/a/1190000019060284
2019-05-03T12:41:17+08:00
2019-05-03T12:41:17+08:00
断舍离
https://segmentfault.com/u/systemofdown
9
<h2>1.JSON Web Token是什么</h2>
<p>JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。</p>
<h2>2.什么时候你应该用JSON Web Tokens</h2>
<p>下列场景中使用JSON Web Token是很有用的:</p>
<ol>
<li>Authorization (授权) :<br> 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。</li>
<li>Information Exchange (信息交换) : <br> 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWTs可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。</li>
</ol>
<h2>3.JSON Web Token的结构是什么样的</h2>
<p><img src="/img/bVbr8BP?w=645&h=141" alt="874963-20180709124807031-664967381.png" title="874963-20180709124807031-664967381.png"></p>
<p>JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:</p>
<ul>
<li>Header</li>
<li>Payload</li>
<li>Signature</li>
</ul>
<p>因此,一个典型的JWT看起来是这个样子的:</p>
<pre><code>xxxxx.yyyyy.zzzzz
</code></pre>
<p>接下来,具体看一下每一部分:</p>
<p><strong>Header</strong></p>
<p>header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。</p>
<p>例如:<br><img src="/img/bVbr8BU?w=209&h=89" alt="874963-20180707143936465-1142974441.png" title="874963-20180707143936465-1142974441.png"></p>
<p>然后,用Base64对这个JSON编码就得到JWT的第一部分</p>
<p><strong>Payload</strong></p>
<p>JWT的第二部分是payload,它包含声明(要求)。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型: registered, public 和 private。</p>
<ul>
<li>Registered claims : 这里有一组预定义的声明,它们不是强制的,但是推荐。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。</li>
<li>Public claims : 可以随意定义。</li>
<li>Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。</li>
</ul>
<p>下面是一个例子:<br><img src="/img/bVbr8BV?w=254&h=110" alt="874963-20180707144153274-292205768.png" title="874963-20180707144153274-292205768.png"></p>
<p>对payload进行Base64编码就得到JWT的第二部分</p>
<p><strong><em>注意,不要在JWT的payload或header中放置敏感信息,除非它们是加密的。</em></strong></p>
<p><strong>Signature</strong></p>
<p>为了得到签名部分,你必须有编码过的header、编码过的payload、一个秘钥,签名算法是header中指定的那个,然对它们签名即可。</p>
<p>例如:</p>
<pre><code>HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
</code></pre>
<p>签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。</p>
<p>看一张官网的图就明白了:<br><img src="/img/bVbr8BX?w=1178&h=826" alt="874963-20180707150229764-2037235703.png" title="874963-20180707150229764-2037235703.png"></p>
<h2>4.JSON Web Tokens是如何工作的</h2>
<p>在认证的时候,当用户用他们的凭证成功登录以后,一个JSON Web Token将会被返回。此后,token就是用户凭证了,你必须非常小心以防止出现安全问题。一般而言,你保存令牌的时候不应该超过你所需要它的时间。</p>
<p>无论何时用户想要访问受保护的路由或者资源的时候,用户代理(通常是浏览器)都应该带上JWT,典型的,通常放在Authorization header中,用Bearer schema。</p>
<p>header应该看起来是这样的:</p>
<pre><code>Authorization: Bearer <token>
</code></pre>
<p>服务器上的受保护的路由将会检查Authorization header中的JWT是否有效,如果有效,则用户可以访问受保护的资源。如果JWT包含足够多的必需的数据,那么就可以减少对某些操作的数据库查询的需要,尽管可能并不总是如此。</p>
<p>如果token是在授权头(Authorization header)中发送的,那么跨源资源共享(CORS)将不会成为问题,因为它不使用cookie。</p>
<p>下面这张图显示了如何获取JWT以及使用它来访问APIs或者资源:</p>
<p><img src="/img/bVbnIzK?w=1500&h=571" alt="874963-20180707144719025-1833412608.png" title="874963-20180707144719025-1833412608.png"></p>
<p>应用(或者客户端)想授权服务器请求授权。例如,如果用授权码流程的话,就是/oauth/authorize<br>当授权被许可以后,授权服务器返回一个access token给应用<br>应用使用access token访问受保护的资源(比如:API)</p>
<h2>5.基于Token的身份认证 与 基于服务器的身份认证</h2>
<h3>5.1 基于服务器的身份认证</h3>
<p>在讨论基于Token的身份认证是如何工作的以及它的好处之前,我们先来看一下以前我们是怎么做的:</p>
<blockquote>HTTP协议是无状态的,也就是说,如果我们已经认证了一个用户,那么他下一次请求的时候,服务器不知道我是谁,我们必须再次认证</blockquote>
<p>传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过。</p>
<p><strong>这种基于服务器的身份认证方式存在一些问题:</strong></p>
<p>Sessions : 每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。<br>Scalability : 由于Session是在内存中的,这就带来一些扩展性的问题。<br>CORS : 当我们想要扩展我们的应用,让我们的数据被多个移动设备使用时,我们必须考虑跨资源共享问题。当使用AJAX调用从另一个域名下获取资源时,我们可能会遇到禁止请求的问题。<br>CSRF : 用户很容易受到CSRF攻击。</p>
<h3>5.2 JWT与Session的差异</h3>
<p>相同点是,它们都是存储用户信息;然而,Session是在服务器端的,而JWT是在客户端的。</p>
<p>Session方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。</p>
<p>而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。</p>
<p>Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端。</p>
<p><img src="/img/bVbr8B2?w=481&h=591" alt="874963-20180707160150557-1205884800.png" title="874963-20180707160150557-1205884800.png"></p>
<h3>5.3 基于Token的身份认证是如何工作的</h3>
<p>基于Token的身份认证是无状态的,服务器或者Session中不会存储任何用户信息。</p>
<blockquote>没有会话信息意味着应用程序可以根据需要扩展和添加更多的机器,而不必担心用户登录的位置。</blockquote>
<p>虽然这一实现可能会有所不同,但其主要流程如下:</p>
<ol>
<li>用户携带用户名和密码请求访问</li>
<li>服务器校验用户凭据</li>
<li>应用提供一个token给客户端</li>
<li>客户端存储token,并且在随后的每一次请求中都带着它</li>
<li>服务器校验token并返回数据</li>
</ol>
<p><strong>注意:</strong></p>
<ol>
<li>每一次请求都需要token</li>
<li>Token应该放在请求header中</li>
<li>我们还需要将服务器设置为接受来自所有域的请求,用Access-Control-Allow-Origin: *</li>
</ol>
<h3>5.4 用Token的好处</h3>
<ul>
<li>无状态和可扩展性:Tokens存储在客户端。完全无状态,可扩展。我们的负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息。</li>
<li>安全:Token不是Cookie。(The token, not a cookie.)每次请求的时候Token都会被发送。而且,由于没有Cookie被发送,还有助于防止CSRF攻击。即使在你的实现中将token存储到客户端的Cookie中,这个Cookie也只是一种存储机制,而非身份认证机制。没有基于会话的信息可以操作,因为我们没有会话!</li>
</ul>
<p><img src="/img/bVbr8B3?w=780&h=173" alt="874963-20180707162551160-1143708148.png" title="874963-20180707162551160-1143708148.png"></p>
<p>还有一点,token在一段时间以后会过期,这个时候用户需要重新登录。这有助于我们保持安全。还有一个概念叫token撤销,它允许我们根据相同的授权许可使特定的token甚至一组token无效。</p>
<h3>5.5 JWT与OAuth的区别</h3>
<ol>
<li>OAuth2是一种授权框架 ,JWT是一种认证协议</li>
<li>无论使用哪种方式切记用HTTPS来保证数据的安全性</li>
<li>OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app),而<strong>JWT是用在前后端分离</strong>, 需要简单的对后台API进行保护时使用。</li>
</ol>
<h3>5.6 关于OAuth可以参考下面几篇</h3>
<p>《<a href="https://link.segmentfault.com/?enc=k%2BUQE%2FWj7XsEJrtCcBYFRw%3D%3D.Ti%2B3ad0c946TrYLclsKfPa7DWG4m9d8j6Ec0y9h6aanvxs0XXzWUpN5yJKXxjLcs" rel="nofollow">OAuth 2.0</a>》</p>
<p>《<a href="https://link.segmentfault.com/?enc=yEJItC%2BJaNfk%2BOEhqAByGg%3D%3D.lJhTxe6%2BrAUVlVXb5t2lSUI7E3y7akjUC8mFeVxXpa0y3H%2Bh6QOrCSHUrkJWsUS6" rel="nofollow">Spring Security OAuth 2.0</a>》</p>
<p>《<a href="https://link.segmentfault.com/?enc=3DJI3ZqUXNwu%2FcaFRKIOVA%3D%3D.UPUDF8Hhbxgx54IHBoLuX1mdiqBUaEAEAXY%2Fitd8HiWSc6x%2F2i%2FqR%2BUvKmh5E4T0" rel="nofollow">OAuth 2.0 授权码请求</a>》</p>
<h2>6.参考</h2>
<p><a href="https://link.segmentfault.com/?enc=SQqKYI57ETVmgwZabZ8FcQ%3D%3D.JTBVYnEo5fvUVv2Apk1hvw%3D%3D" rel="nofollow">https://jwt.io/</a></p>
<p><a href="https://link.segmentfault.com/?enc=7pYwSbMKnaI1mFzqSRgjQQ%3D%3D.zAfGxJhhDyxAQpgorzqYLQWVvHGp6yQ5tTZcRqAp%2Bc5S89VxFi3AnjokN7oBUmtA%2BSsiCmgrY2mj2xPVppQ9aP4mvAfHdagqNjO7Wg1m5t8xTiz%2B2g456ztfjk7oB61fF6y6B3Og%2FTI1ClDAWWiPAA%3D%3D" rel="nofollow">https://scotch.io/tutorials/t...</a></p>
<p><a href="https://link.segmentfault.com/?enc=pW9%2FyOseSu9BI%2B1hdQhnVQ%3D%3D.a46hPPbu7w%2FYJjgnnHsQyWT%2BGRXtn8gcimKP3%2FWMJYAuRJq1tccW7P4hIKGX2NF8" rel="nofollow">https://tools.ietf.org/html/r...</a></p>
<p><a href="https://link.segmentfault.com/?enc=8N4flik%2BgPUtelfnYDNkKw%3D%3D.y4d6NNwNcm5zKtfsnsCrCnRyTIEfXlKwsaI4Z0HykdHiHSna8N%2BgYKRYbO4WNkY39wesbC6Wn6OQWhPCj2eHfA%3D%3D" rel="nofollow">http://blog.leapoahead.com/20...</a></p>
<p><a href="https://link.segmentfault.com/?enc=ygzEWMSouA9CaKmUsRK77w%3D%3D.9ueWHp5grj0deij%2FCUVqonwt1brQSN8dZaJk%2F1FQCtWtQucd3cFP86ygZx6kOrtgmUJVHmUgIh06TEKjMWGbZw%3D%3D" rel="nofollow">https://cnodejs.org/topic/557...</a></p>
<p><a href="https://link.segmentfault.com/?enc=NJ7Gq0cKBu2c0qNCsvtnzw%3D%3D.%2Bqs8qw2Nnm42KlMOIBRtpKlVkVe%2FsGoxlrjz%2FDPbPld9Bg4eBRVrG2eVTmhsv1vOJrLpTkLkuqYRwr7F50b6Cx%2FUXvduZ%2FWFuX4DEY7zZDo%3D" rel="nofollow">http://blog.leapoahead.com/20...</a></p>
[转] centos7 调整XFS格式的LVM大小
https://segmentfault.com/a/1190000008377274
2017-02-16T21:32:46+08:00
2017-02-16T21:32:46+08:00
断舍离
https://segmentfault.com/u/systemofdown
2
<p>前提:XFS是centos7 预装的操作系统,XFS只能扩大不能缩小,所以需要利用xfsdump / xfsrestore 工具在必须缩小lvm 的情况下,备份与还原资料。</p>
<p>本实验的效果是:<br>1,/dev/mapper/centos-home仅仅保留500G;<br>2,将/home分出来的空间分给/dev/mapper/centos-root。<br>原始空间大小如下图示:<br><img src="/img/bVJjvK?w=526&h=154" alt="图片描述" title="图片描述"></p>
<h2>step1:安裝 xfsdump 套件</h2>
<pre><code>yum -y install xfsdump</code></pre>
<h2>step2:备份 /home</h2>
<pre><code> xfsdump -f /home.xfsdump /home
please enter label for this dump session (timeout in 300 sec)
-> home
please enter label for media in drive 0 (timeout in 300 sec)
-> home</code></pre>
<h2>step3:缩减/dev/mapper/centos-home大小</h2>
<p>卸載 /home</p>
<pre><code># umount /home</code></pre>
<p>將 /home 的 Logical Volume 縮減為 5GB</p>
<pre><code># lvreduce -L 5G /dev/mapper/centos-home
Do you really want to reduce home? [y/n]: y</code></pre>
<h2>step4:增加/dev/mapper/centos-root的空间大小</h2>
<pre><code># lvextend -l +100%FREE /dev/centos/root</code></pre>
<p>延展 xfs 空间</p>
<pre><code># xfs_growfs /dev/centos/root</code></pre>
<h2>step5:恢复/home的内容</h2>
<p>格式化 /home 的 lvm</p>
<pre><code># mkfs.xfs -f /dev/mapper/centos-home</code></pre>
<p>挂载 /home /dev/mapper/centos-home</p>
<pre><code># mount /home</code></pre>
<p>还原备份资料到 /home</p>
<pre><code># xfsrestore -f /home.xfsdump /home</code></pre>
<p>调整过后的空间大小如下图示:</p>
<p><img src="/img/bVJjvM?w=531&h=161" alt="图片描述" title="图片描述"></p>
<blockquote><p>来源:<a href="https://link.segmentfault.com/?enc=9a7%2FsLTu6lBa37l4d6lsVQ%3D%3D.LzNHRG5LE7PHqzky9y8yXvl6geI7xXkcodw%2BMgsdlX9GA4blatvDSWMbDa%2FxCOcU" rel="nofollow">http://www.mykernel.cn/archiv...</a></p></blockquote>