<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>滴滴嘟嘟博客</title><description>记录工作和生活</description><link>https://dididudu998.github.io/</link><language>zh_CN</language><item><title>检查CVE的安装情况</title><link>https://dididudu998.github.io/posts/%E6%A3%80%E6%9F%A5cve%E7%9A%84%E5%AE%89%E8%A3%85%E6%83%85%E5%86%B5/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%A3%80%E6%9F%A5cve%E7%9A%84%E5%AE%89%E8%A3%85%E6%83%85%E5%86%B5/</guid><pubDate>Thu, 02 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;整理下关于CVE是否已经安装的检查方式。&lt;/p&gt;
&lt;p&gt;由于公司现在全面部署了XDR+InsightVM这样的终端安全软件。经常会出现误报的情况，然后不懂技术的，就是只看着数据条目发邮件要求整改。这令我觉得非常的缺乏效率，而且好几个人可能为了填充其工作量的不足，会将一件事情通过2个人在不同的时间进行传达，完全是没有任何的意义。为了减少他们的骚扰，我整理下，从技术手段让这些人能安静一点。&lt;/p&gt;
&lt;h2&gt;Redhat篇&lt;/h2&gt;
&lt;p&gt;检查是否安装了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dnf updateinfo list --cve CVE-2025-38352
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果输出为空，基本上是已经安装了。&lt;/p&gt;
&lt;p&gt;如果要确认，可以使用下面的指令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
rpm -q --changelog kernel | grep -i &quot;CVE-2025-38352&quot;
- posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del() (CKI Backport Bot) [RHEL-112783] {CVE-2025-38352}
- posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del() (CKI Backport Bot) [RHEL-112783] {CVE-2025-38352}
- posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del() (CKI Backport Bot) [RHEL-112783] {CVE-2025-38352}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;检查kernel的状态&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dnf history list kernel
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过列出的序号，可以检查详细的信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
dnf history info 90
Updating Subscription Management repositories.
Transaction ID : 90
Begin time     : Mon 15 Jun 2026 02:50:33 PM CST
Begin rpmdb    : aa24063c07e3c3aa35547dc07497fee7d344346022fa6dcd5dbd4587adf75915
End time       : Mon 15 Jun 2026 02:51:44 PM CST (71 seconds)
End rpmdb      : 20db09ccaa7e23a6b725a299df374992e6abebe402ad5fa354449b1b5884708b
User           : root &amp;lt;root&amp;gt;
Return-Code    : Success
Releasever     : 9
Command Line   : update
Persistence    : Persist
Comment        : 
Packages Altered:
    Install       kernel-5.14.0-687.15.1.el9_8.x86_64              @rhel-9-for-x86_64-baseos-rpms
    Install       kernel-core-5.14.0-687.15.1.el9_8.x86_64         @rhel-9-for-x86_64-baseos-rpms
    Install       kernel-modules-5.14.0-687.15.1.el9_8.x86_64      @rhel-9-for-x86_64-baseos-rpms
    Install       kernel-modules-core-5.14.0-687.15.1.el9_8.x86_64 @rhel-9-for-x86_64-baseos-rpms
    Upgrade       bind-libs-32:9.16.23-40.el9_8.2.x86_64           @rhel-9-for-x86_64-appstream-rpms
    Upgraded      bind-libs-32:9.16.23-40.el9_8.1.x86_64           @@System

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还可以用rpm来查&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm -qa --last | grep kernel

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Ubuntu&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;通过检查变更日志来看&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
apt-changelog openssl | grep -i &quot;CVE-2023-3817&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;通过工具来扫描&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;安装工具
sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install debsecan -y&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;全盘扫描未修复的 CVE（输出会很长）
debsecan&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;精准查找某个特定的 CVE 是否还存在于系统中
debsecan | grep &quot;CVE-2023-41993&quot;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果命令有输出，说明确实存在该漏洞。如果没有输出，说明已经补好漏洞或者系统并不存在这样的漏洞&lt;/p&gt;
&lt;h2&gt;容器&lt;/h2&gt;
&lt;p&gt;如果是容器存在漏洞，则可以按照下面的方式进行检查&lt;/p&gt;
&lt;p&gt;安装trivy，然后扫描对应的容器镜像&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
trivy image my-image:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者安装grype，扫描本地目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
grype dir:/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;只要这些工具的扫描报告中不存在对应的CVE编号，就说明不存在该漏洞了。&lt;/p&gt;
</content:encoded></item><item><title>封装的web游戏的作弊</title><link>https://dididudu998.github.io/posts/%E5%B0%81%E8%A3%85web%E6%B8%B8%E6%88%8F%E7%9A%84%E4%BD%9C%E5%BC%8A/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%B0%81%E8%A3%85web%E6%B8%B8%E6%88%8F%E7%9A%84%E4%BD%9C%E5%BC%8A/</guid><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;继续游戏相关的问题。&lt;/p&gt;
&lt;p&gt;玩游戏最多的使用就是修改器。最常用的是cheat engine，这个对于类似红警2这样的游戏非常友好。但是对于封装过的游戏就不行了。比如通过NW.js打包的RPG maker MV游戏，cheat engine是扫不到对应的内存的。&lt;/p&gt;
&lt;p&gt;由于游戏的机理是浏览器+JavaScript，所以我们只需要开启游戏的debug模式就能够利用浏览器开发者模式进行调控。&lt;/p&gt;
&lt;p&gt;进入游戏目录，找到package.json文件，建议修改package.json前保留一份原始副本。
修改为如下的形式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;name&quot;: &quot;mygame&quot;,
&quot;main&quot;: &quot;index.html&quot;,
&quot;chromium-args&quot;: &quot;--remote-debugging-port=9222 --force-color-profile=srgb --enable-logging&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将chromium-args中禁止调试的参数去掉，增加允许远程调试的参数 --remote-debugging-port=9222，这样可以方便使用chrome://inspect进行调试&lt;/p&gt;
&lt;p&gt;--enable-logging:是启用日志输出&lt;/p&gt;
&lt;p&gt;修改后保存，然后重启游戏。&lt;/p&gt;
&lt;p&gt;重启游戏后，打开chrome浏览器，在地址栏输入chrome://inspect
点击configure按钮，添加localhost:9222,然后确认&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260510130059.png|697]]看到上面有2个，我们选择index.html的这个对应的inspect按钮进入开发者工具控制台，然后就和调试网页一样了。&lt;/p&gt;
&lt;p&gt;首先我们还是得看看data目录下js的一些信息，否则对于属性不了解，就没法发组偶下面的配置。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 我们的主角色的ID是1，因为_actorId:1
const actor=$gameActors.actor(1);

// 然后输入actor，就能看到对应的属性

// 我们这里可以直接设置生命值，灵力值和怒气值都最大

actor._hp=99999
actor._mp=99999
actor._tp=99999


// 修改8项属性的额外加成，顺序对应：[HP加成, MP加成, 攻击, 防御, 魔攻, 魔防, 敏捷, 幸运] // 全部设为99999后，最终属性会直接拉满，闪避（和敏捷强相关）也会到上限 
for (let i = 0; i &amp;lt; 8; i++) { 
	actor._paramPlus[i] = 99999; 
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其他的以此类推，可以直接在开发者模式下，对数据的值双击进行修改，修改后在游戏中查看确认后，保存为游戏记录，下次读取记录后就是无敌模式了。&lt;/p&gt;
&lt;p&gt;但是要注意，不要乱改，游戏的数据不是无限制的，搞不好，改出个负值出来，有可能游戏就进行不下去了。&lt;/p&gt;
&lt;p&gt;不过这种调试非常简单，可以很快的恢复回来。一般的情况下都能够很快的掌握的。&lt;/p&gt;
&lt;p&gt;可以让我玩游戏的时候更注意剧情，而不受游戏中敌人的能力值过大，而需要不断地修炼，耗费时间。&lt;/p&gt;
</content:encoded></item><item><title>解码游戏中的RPGMV图片</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E7%A0%81%E6%B8%B8%E6%88%8F%E4%B8%AD%E7%9A%84rpgmv%E5%9B%BE%E7%89%87/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E7%A0%81%E6%B8%B8%E6%88%8F%E4%B8%AD%E7%9A%84rpgmv%E5%9B%BE%E7%89%87/</guid><pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;兴趣是最好的老师！&lt;/p&gt;
&lt;p&gt;昨天下午随意发现了一款游戏。晚上打开玩了一下，发现画风很好，但是我又没有时间耗费玩通关。所以想要将游戏的图片都保留下来看看。&lt;/p&gt;
&lt;p&gt;发现这个游戏文件夹下有data目录，而且还有img/picture目录，为什么关注这个目录呢，因为这个picture目录是img下面文件大小最大的目录，这个一般就是真实的游戏图片目录了。&lt;/p&gt;
&lt;p&gt;picture目录下的文件都是.png_的后缀，我用lmhex打开一个文件看了下，编码类似如下：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260509154948.png]]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;52 50 47 4D 56 00 00 00 00 03 01 00 00 00 00 00 A4 D1 F7 E0 E1 64 37 B8 34 05 21 8C 6B 57 CD CB 00 00 02 40 00 00 01 80 08 06 00 00 00 45 9A DD 1F 00 00 20 00 49 44 41 54 78 DA EC 9D 07 58 16 C7 D6 C7 AD
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的52 50 47 4D 56用ASCII码解析就是RPGMV格式的magic number。&lt;/p&gt;
&lt;p&gt;然后编码中还有IDAT的字样，这个是PNG图片块。说明图片内容是明文的。&lt;/p&gt;
&lt;p&gt;很好，确定了真实的文件格式了。这个文件大概率是使用RPG maker加密过的PNG图片了。&lt;/p&gt;
&lt;p&gt;现在我要想办法解密它。&lt;/p&gt;
&lt;p&gt;通过搜索，这种加密方式通常采用的是： png+异或+key的方式，而且默认RPGMV只对PNG文件的前16个字节做XOR。还有我需要知道异或用的key是什么。
同样的搜索下知道RPGMV的key一般存在system.json文件里面，这个一下子就找到了，在游戏目录下面的data文件夹下的system.json,打开搜索下encryption，直接就找到了key。&lt;/p&gt;
&lt;p&gt;这下好了。写一个简单的代码尝试解压一个文件看看能不能成功。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#2d81b9a7ec6e2db234052181221f8999

from pathlib import Path
import sys

# =========================================
# 用法:
#
# python decrypt_rpgmv.py input.rpgmvp output.png KEY
#
# 例子:
#
# python decrypt_rpgmv.py Actor1.rpgmvp Actor1.png \
# 00112233445566778899AABBCCDDEEFF
#
# =========================================


PNG_MAGIC = bytes([
    0x89, 0x50, 0x4E, 0x47,
    0x0D, 0x0A, 0x1A, 0x0A
])

RPGMV_HEADER_SIZE = 16


def decrypt_rpgmvp(input_file, output_file, key_hex):
    key = bytes.fromhex(key_hex)

    with open(input_file, &quot;rb&quot;) as f:
        data = bytearray(f.read())

    # 检查文件头
    if data[:4] != b&quot;RPGM&quot;:
        print(&quot;[-] Not a RPGMV encrypted file&quot;)
        return

    print(&quot;[+] RPGMV header detected&quot;)

    # 去掉16字节头
    encrypted_data = data[RPGMV_HEADER_SIZE:]

    # 只解密前16字节
    decrypt_len = min(16, len(encrypted_data), len(key))

    for i in range(decrypt_len):
        encrypted_data[i] ^= key[i]

    # PNG 文件头检查
    if encrypted_data[:8] == PNG_MAGIC:
        print(&quot;[+] PNG header restored successfully&quot;)
    else:
        print(&quot;[!] Warning: PNG header mismatch&quot;)
        print(&quot;    key may be incorrect&quot;)

    with open(output_file, &quot;wb&quot;) as f:
        f.write(encrypted_data)

    print(f&quot;[+] Saved to: {output_file}&quot;)


def main():
    if len(sys.argv) != 4:
        print(&quot;Usage:&quot;)
        print(&quot;python decrypt_rpgmv.py input.rpgmvp output.png KEY&quot;)
        return

    input_file = sys.argv[1]
    output_file = sys.argv[2]
    key_hex = sys.argv[3]

    decrypt_rpgmvp(input_file, output_file, key_hex)


if __name__ == &quot;__main__&quot;:
    main()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;试了下，果然可以解码.png_文件到可以打开的图片文件。&lt;/p&gt;
&lt;p&gt;剩下来就是解密整个picture文件夹了，这个文件夹有1.5GB大小，需要写个批处理了。见下面完整代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from pathlib import Path
import sys

RPGMV_HEADER_SIZE = 16

PNG_MAGIC = bytes([
    0x89, 0x50, 0x4E, 0x47,
    0x0D, 0x0A, 0x1A, 0x0A
])


def is_rpgmv(path):
    try:
        with open(path, &quot;rb&quot;) as f:
            return f.read(4) == b&quot;RPGM&quot;
    except:
        return False


def decrypt_file(src, dst, key):

    with open(src, &quot;rb&quot;) as f:
        data = bytearray(f.read())

    encrypted = data[RPGMV_HEADER_SIZE:]

    for i in range(min(16, len(encrypted), len(key))):
        encrypted[i] ^= key[i]

    if encrypted[:8] != PNG_MAGIC:
        print(f&quot;[WARN] PNG header mismatch: {src.name}&quot;)

    dst.parent.mkdir(parents=True, exist_ok=True)

    with open(dst, &quot;wb&quot;) as f:
        f.write(encrypted)


def main():

    if len(sys.argv) != 4:
        print(&quot;Usage:&quot;)
        print(&quot;python batch_decrypt_any.py input_dir output_dir KEY&quot;)
        return

    input_dir = Path(sys.argv[1]).resolve()
    output_dir = Path(sys.argv[2]).resolve()
    key = bytes.fromhex(sys.argv[3])

    files = list(input_dir.rglob(&quot;*&quot;))

    total = 0
    ok = 0

    for file in files:

        if not file.is_file():
            continue

        if not is_rpgmv(file):
            continue

        total += 1

        try:
            rel = file.relative_to(input_dir)

            # 去掉最后一个 &quot;_&quot; 并改成 png
            name = rel.name
            if name.endswith(&quot;_&quot;):
                name = name[:-1]

            out = output_dir / rel.parent / name

            if out.suffix == &quot;&quot;:
                out = out.with_suffix(&quot;.png&quot;)

            decrypt_file(file, out, key)

            print(f&quot;[OK] {rel}&quot;)
            ok += 1

        except Exception as e:
            print(f&quot;[FAIL] {file}&quot;)
            print(e)

    print()
    print(&quot;====== RESULT ======&quot;)
    print(&quot;Detected RPGMV files:&quot;, total)
    print(&quot;Decrypted:&quot;, ok)


if __name__ == &quot;__main__&quot;:
    main()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;![[Pasted image 20260509155026.png]]&lt;/p&gt;
&lt;p&gt;然后我就可以在输出的文件夹里面挨个的欣赏美图了。&lt;/p&gt;
</content:encoded></item><item><title>zip文件的已知明文攻击</title><link>https://dididudu998.github.io/posts/zip%E6%96%87%E4%BB%B6%E7%9A%84%E5%B7%B2%E7%9F%A5%E6%98%8E%E6%96%87%E6%94%BB%E5%87%BB/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/zip%E6%96%87%E4%BB%B6%E7%9A%84%E5%B7%B2%E7%9F%A5%E6%98%8E%E6%96%87%E6%94%BB%E5%87%BB/</guid><pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这两天在看一本《网络空间安全技术-CTF那些事儿》,作者李舟军，机械工业出版社的书。&lt;/p&gt;
&lt;p&gt;用的工具是&lt;a href=&quot;%22https://github.com/kimci86/bkcrack/releases%22&quot;&gt;bkcrack&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看到zip文件已知明文攻击这里，就顺手试了下。下面是测试过程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建两个txt文件，一个叫test.txt，一个叫demo.txt&lt;/li&gt;
&lt;li&gt;在test.txt中写入数字和字符，不要少于12个字节，最好20个字节以上&lt;/li&gt;
&lt;li&gt;demo.txt可以不用管，这里为了演示，假设这个文件中存在的内容才是我们感兴趣的。或者你让demo.txt作为已知明文文件也行，那就在这个文件中写入超过20个字节的字符&lt;/li&gt;
&lt;li&gt;将这两个文件压缩到一个文件，输入解压密码，加密方法必须是ZipCrypto的方式，AES256是不能通过这样的方式攻击的。这里我压缩为tttt.zip&lt;/li&gt;
&lt;li&gt;现在我有了已知明文，test.txt,还有一个不知道密码的zip文件tttt.zip&lt;/li&gt;
&lt;li&gt;开始使用bkcrack来进行密钥流的爆破&lt;/li&gt;
&lt;li&gt;原理就是密文=明文 XOR 密钥流，那么密钥流=明文 XOR 密文&lt;/li&gt;
&lt;li&gt;过程如下，bkcrack有windows下的可执行文件
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt;: 是加密zip压缩包的位置 (必须的)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt;: 是加密zip压缩包文件的位置 (必须的)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt;: 是明文文件的位置 (必须的)&lt;br /&gt;
如果没有&lt;code&gt;-P&lt;/code&gt;则直接填入明文文件的位置&lt;br /&gt;
如果有&lt;code&gt;-P&lt;/code&gt;则填入明文压缩包中的路径&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;bkcrack.exe -C tttt.zip -c test.txt -p test.txt
bkcrack 1.8.1 - 2025-10-25
[10:17:01] Z reduction using 7 bytes of known plaintext
100.0 % (7 / 7)
[10:17:01] Attack on 850571 Z values at index 6
Keys: 78be59ed 077b1316 a39ccf04
39.1 % (332485 / 850571)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 332485
[10:20:35] Keys
78be59ed 077b1316 a39ccf04

//用获得的密钥流来创建一个新的压缩文件，密码我们自己设定为123456.

bkcrack -C tttt.zip -k 78be59ed 077b1316 a39ccf04 -U d_tttt.zip 123456
bkcrack 1.8.1 - 2025-10-25
[10:24:04] Writing unlocked archive d_tttt.zip with password &quot;123456&quot;
100.0 % (2 / 2)
Wrote unlocked archive.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下来就可以用123456作为解压缩密码解压出来test.txt和demo.txt了，也能打开看到我们期望的demo.txt中的信息了。&lt;/p&gt;
&lt;p&gt;书中提到，黑客在做类似的事情的时候，一般都看压缩包中很少变化的许可文件，因为这些文件大部分在和以前版本的一样。可以尝试破解。&lt;/p&gt;
</content:encoded></item><item><title>最近</title><link>https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91/</guid><pubDate>Wed, 25 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;到了2026年，马上就是清明节。&lt;/p&gt;
&lt;p&gt;AI的发展速度真的飞快，从原来运转的大模型到现在可以给出一个目标，然后agent自行去写完整段代码，并测试通过后，给出详细的设计文档。编程已经不需要普通人再去学习代码语言，只需要能够明确的描述出自己想要的东西就可以了。&lt;/p&gt;
&lt;p&gt;既然程序不需要再由很多的人来写，那么程序员这个岗位基本上那就不需要了。所以才有了2026年初接二连三的互联网公司的裁员潮。&lt;/p&gt;
&lt;p&gt;有时候在想，人如果不能创造点东西出来，那真的是很悲惨的事情。创造工具的目的是替代自己的一部分劳动，降低劳动的难度，从而让自己可以更轻松的实现最初的目的。所以工具的价值在于节约使用者的时间。让使用者可以更幸福，可以节约时间来干自己更喜欢的事情，哪怕躺着休息。&lt;/p&gt;
&lt;p&gt;AI的发展，几乎可以让所有的事情的难度降低到一个人人都可以的地步，当然除了一些私域知识外，比如可口可乐的配方，隐形战机的材料这些，其他的公开的知识的获取没有任何的门槛，以前需要google这样的搜索引擎，现在大模型打开就可以随便问。当然是针对普通的问题，不涉及犯罪的黄赌毒这些。&lt;/p&gt;
&lt;p&gt;当A可以问一个问题S，B也可以问一个问题S的时候，A，B获得的答案相同或者近似，那么你如何评判A和B的水平到底哪个更高？这个最明显的，一个简单的编程问题，在有大模型支持的情况下，他们面对问题，大模型都能给出类似的解。此时你如何评判？你从什么角度来给出A和B不同的价值？&lt;/p&gt;
&lt;p&gt;我们曾经在学校学习，然后自己看书，练习，如果没有一种方法可以区分这种不同类型的A或者B，那么将来的人是否还会理解一些问题发生的本质，是否还能解决一些核心的问题。人们总是倾向于少付出，多回报。&lt;/p&gt;
&lt;p&gt;而且AI模型是吸取几乎所有的公开信息训练出来的，代码，语言翻译，写作等等这些有一定的框架，语法规则的东西都很容易平均化，也就是只要你用了AI，都会给出一个几乎平均值水准的结果。不会太差，但是也不会产生惊艳的效果。对于所有的知识的向量化，然后根据提出者的描述在不同的数据层之间进行拼接和输出，就是现在AI的方式。&lt;/p&gt;
&lt;p&gt;即使是这样，很多人的岗位已经受到影响。而且影响很大。&lt;/p&gt;
&lt;p&gt;基于这些现象，我在想未来的招聘会基于什么角度和技能来区分人才呢？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当然是要能打字写字的&lt;/li&gt;
&lt;li&gt;要可以精细的描述自己心中想要实现的东西的&lt;/li&gt;
&lt;li&gt;要有基本的认知，要实现的东西可能关联了哪些东西的&lt;/li&gt;
&lt;li&gt;要能发现问题，并可以将问题拆解的&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;从这些角度来看，发现问题是最强的技能，拆解和描述问题其次。&lt;/p&gt;
&lt;p&gt;那么怎么样发现问题呢？&lt;/p&gt;
&lt;p&gt;比如小故事中提到的牛顿被苹果砸中脑袋而考虑万有引力，瓦特被烧开的水壶喷出的蒸汽而想到蒸汽机等等。&lt;/p&gt;
&lt;p&gt;人如果发现不了问题，那就没法进步，尤其是在AI泛滥的环境下。&lt;/p&gt;
&lt;p&gt;如果仅仅让AI来提供一些素材，来支持一天的早中晚吃啥喝啥，那其实价值很低。但是如果妄想让AI指出一条轻松赚钱的门路，那也是瞎扯。&lt;/p&gt;
&lt;p&gt;我觉得，个人的经历，通过自己的经历带来的眼界和格局，再加上不断的练习获得的亲身的体验和认知，再加上AI的辅助，才能更好的实现价值。&lt;/p&gt;
&lt;p&gt;所以，不管A和B是否都能通过问AI获取到类似的答案，A与B不同的人生经历，不同的认知，最终会极大的拉开两人之间的距离，因为AI几乎是倍数叠加于人本身的能力，而不是稍稍的改善某一个方面，是全方面的提升，前提是你本人就有很多的想法和基本踏实的技能。&lt;/p&gt;
&lt;p&gt;未来的职场，虽然很多人说一人公司会成为以后的标准，我保留一点点意见。一人公司对于原本就是个人顾问的自由职业者，加上AI，那是挺好的。但是如果一群人，加上AI，那几乎可以飞快的实现某个行业的很精密的赛道，这比一人公司的爆发性更强。&lt;/p&gt;
&lt;p&gt;要想让别人认可和估算价值，那得自己先有一些产品出来。比如程序员看github，作家看出了什么书，猪要看重量等，新时代，如果还是说一切都在不言中，默默的进步，然后到时候惊艳很多人，那就很难了，几乎寸步难行。&lt;/p&gt;
&lt;p&gt;时间对于人来说过的是很快的，但是对于AI来说，那更是快的厉害，它的发展速度远远超过人的发展，智力方面几乎是碾压级别的。当电脑刚出来的时候，比尔盖茨不是说以后人人大概就只需要几百kb的内存就够了的豪言壮语。个人无法在头脑中装下所有的知识，甚至知识的脉络也少的可怜。但是AI会，我们不是将AI中的知识调出来看，而是调出来用，用后再优化，然后再反馈给AI。然后全人类的进步那就飞起来了。&lt;/p&gt;
&lt;p&gt;这些都是从技术角度来说的。&lt;/p&gt;
&lt;p&gt;从社会角度，人们的生产关系可能发生改变。因为生产力会重塑生产关系。
能够提供AI的企业和不能够提供AI的企业，有能力提升AI的企业和没能力提升AI的企业，有方法能将AI用的顺滑的企业和没有方法的企业。&lt;/p&gt;
&lt;p&gt;将在各个地方产生竞争。最后，AI+好的制度+优秀的人会消灭各个竞争者。&lt;/p&gt;
&lt;p&gt;各行各业都会这样。&lt;/p&gt;
&lt;p&gt;将导致小企业大量的没有项目可做。因为大企业会依靠AI，几十倍的产出和优化管理，将原来小企业的小单子都能收入麾下，而人员只少少的增加一点点。&lt;/p&gt;
&lt;p&gt;很有可能出现大量的人无事可做的场景。&lt;/p&gt;
&lt;p&gt;只有让自己更强大，更灵活，随着AI的发展，御风而行才能一直走的更好一点吧。&lt;/p&gt;
&lt;p&gt;2026年才是开始，后面应该会有更大一波裁员潮，然后再是人员回归，然后经济更大的发展。但是这个时期，可能要三五年的裁员潮，三五年的小波动的人员回流，然后经济上行，整个下来得10年吧。&lt;/p&gt;
</content:encoded></item><item><title>Windows下用VIM</title><link>https://dididudu998.github.io/posts/windows%E4%B8%8B%E7%9A%84vim/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windows%E4%B8%8B%E7%9A%84vim/</guid><pubDate>Fri, 16 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;不知道为啥notepad++有时候打开个文件会卡那么一点点，查了下说是打开的标签也太多了导致的，或许，这个现象促使我想要用linux上面的vim来作为日常看文档或者代码了。&lt;/p&gt;
&lt;h1&gt;实现步骤&lt;/h1&gt;
&lt;h2&gt;下载neovim&lt;/h2&gt;
&lt;p&gt;这个有windows的msi安装包版本，直接安装就好了&lt;/p&gt;
&lt;h2&gt;配置init.vim&lt;/h2&gt;
&lt;p&gt;创建对应的目录：C:\Users\Mark\AppData\Local\nvim&lt;/p&gt;
&lt;p&gt;如果nvim这个文件夹不存在，那就手动创建一个.&lt;/p&gt;
&lt;p&gt;为了确保创建的init.vim中的插件可以马上启用，需要安装个插件vim plugin manager.&lt;/p&gt;
&lt;p&gt;它会在C:\Users\Mark\AppData\Local\nvim\autoload目录下，clone plug.vim过来。&lt;/p&gt;
&lt;p&gt;用powershell运行下面的命令即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;iwr -useb https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim `
&amp;gt;   | ni $env:LOCALAPPDATA\nvim\autoload\plug.vim -Force
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在这个文件夹下面C:\Users\Mark\AppData\Local\nvim下创建init.vim文件。&lt;/p&gt;
&lt;p&gt;内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot; === Leader key ===
let mapleader = &quot; &quot;

&quot; === 基础设置 ===
set number
set relativenumber
set mouse=a
set encoding=utf-8
set clipboard=unnamedplus

&quot; === 缩进 ===
set tabstop=4
set shiftwidth=4
set expandtab
set autoindent

&quot; === 搜索 ===
set ignorecase
set smartcase
set incsearch
set hlsearch


call plug#begin(&apos;~/.local/share/nvim/plugged&apos;)
Plug &apos;preservim/nerdtree&apos;
Plug &apos;sheerun/vim-polyglot&apos;      &quot; 语法高亮

Plug &apos;junegunn/fzf&apos;, { &apos;do&apos;: { -&amp;gt; fzf#install() } }
Plug &apos;junegunn/fzf.vim&apos;


&quot; 状态栏
Plug &apos;vim-airline/vim-airline&apos;
&quot; 自动补全
Plug &apos;neoclide/coc.nvim&apos;, {&apos;branch&apos;: &apos;release&apos;}
call plug#end()


&quot; =========================
&quot; NERDTree 配置
&quot; =========================
nnoremap &amp;lt;leader&amp;gt;n :NERDTreeToggle&amp;lt;CR&amp;gt;

&quot; 打开 vim 自动定位当前文件
nnoremap &amp;lt;leader&amp;gt;f :NERDTreeFind&amp;lt;CR&amp;gt;

&quot; 启动 vim 自动打开 NERDTree
autocmd VimEnter * NERDTree




&quot;Let NERDTreeShowHidden=1




&quot; =========================
&quot; coc.nvim 基本配置
&quot; =========================
set signcolumn=yes

&quot; Tab 补全
inoremap &amp;lt;silent&amp;gt;&amp;lt;expr&amp;gt; &amp;lt;TAB&amp;gt;
      \ pumvisible() ? &quot;\&amp;lt;C-n&amp;gt;&quot; :
      \ &amp;lt;SID&amp;gt;check_back_space() ? &quot;\&amp;lt;TAB&amp;gt;&quot; :
      \ coc#refresh()

inoremap &amp;lt;expr&amp;gt;&amp;lt;S-TAB&amp;gt; pumvisible() ? &quot;\&amp;lt;C-p&amp;gt;&quot; : &quot;\&amp;lt;C-h&amp;gt;&quot;

function! s:check_back_space() abort
  let col = col(&apos;.&apos;) - 1
  return !col || getline(&apos;.&apos;)[col - 1]  =~# &apos;\s&apos;
endfunction

&quot; 回车确认补全
inoremap &amp;lt;silent&amp;gt;&amp;lt;expr&amp;gt; &amp;lt;CR&amp;gt; pumvisible() ? coc#_select_confirm() : &quot;\&amp;lt;CR&amp;gt;&quot;

&quot; 跳转定义
nmap gd &amp;lt;Plug&amp;gt;(coc-definition)

&quot; 查看文档
nnoremap K :call CocActionAsync(&apos;doHover&apos;)&amp;lt;CR&amp;gt;


&quot; === LSP / Symbol ===
nnoremap &amp;lt;leader&amp;gt;o :CocList outline&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;s :CocList symbols&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;r &amp;lt;Plug&amp;gt;(coc-references)


&quot; === Window split ===
nnoremap &amp;lt;leader&amp;gt;v :vsplit&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;h :split&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;c :close&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;= &amp;lt;C-w&amp;gt;=



&quot; === Markdown Preview ===
nnoremap &amp;lt;leader&amp;gt;mp :CocCommand markdown-preview-enhanced.openPreview&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;mc :CocCommand markdown-preview-enhanced.closePreview&amp;lt;CR&amp;gt;


nnoremap &amp;lt;leader&amp;gt;p :Files&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;b :Buffers&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;r :Rg&amp;lt;CR&amp;gt;
nnoremap &amp;lt;leader&amp;gt;h :History&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装插件&lt;/h2&gt;
&lt;p&gt;进入powershell终端窗口或者cmd命令行窗口，运行nvim&lt;/p&gt;
&lt;p&gt;然后:PlugInstall等待安装完毕&lt;/p&gt;
&lt;p&gt;安装完毕后，由于对于不同的语言的支持需要单独安装，所以需要使用下面的指令：&lt;/p&gt;
&lt;p&gt;:CocInstall coc-html coc-yaml coc-css coc-json coc-clangd coc-go coc-pyright&lt;/p&gt;
&lt;p&gt;将针对html这些文件，以及go，python，c/c++的支持加上&lt;/p&gt;
&lt;h2&gt;简单说明&lt;/h2&gt;
&lt;p&gt;然后空格键作为leader键，使用快捷键n，f，m等这些可以做一些操作。&lt;/p&gt;
&lt;p&gt;ctrl+w切换窗口，sp，vs用于分屏这些&lt;/p&gt;
&lt;p&gt;/用于查找，这些慢慢用就好了。&lt;/p&gt;
&lt;p&gt;主要是速度就是特别快啊。&lt;/p&gt;
&lt;p&gt;清凉的感觉。&lt;/p&gt;
</content:encoded></item><item><title>清理收藏夹</title><link>https://dididudu998.github.io/posts/%E6%B8%85%E7%90%86%E6%94%B6%E8%97%8F%E5%A4%B9/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%B8%85%E7%90%86%E6%94%B6%E8%97%8F%E5%A4%B9/</guid><pubDate>Thu, 18 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;下面的代码是gemini生成的，基本满足了我的要求，但是其实上还是有很多无效的页面没有被去掉，比如有的网站已经出售，有的网站只有一个页面，不是当时的页面了，不过由于自己的收藏乱七八糟，还是比较有效的过滤了好几千个。&lt;/p&gt;
&lt;p&gt;还要说明的是，用c#的这个代码，使用下面的设置，然后发布的时候，可以让最后生成的可执行文件从60多兆缩减到6兆。主要是&amp;lt;PublishAot&amp;gt;true&amp;lt;/PublishAot&amp;gt;这行。&lt;/p&gt;
&lt;p&gt;最后生成的清理过的文件是html文件，需要将当前的收藏夹清空，然后再导入这个html文件就好了。&lt;/p&gt;
&lt;p&gt;如果不喜欢使用收藏夹，也有可以直接将这个文件作为页面来看待。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt;

  

&amp;lt;PropertyGroup&amp;gt;

&amp;lt;OutputType&amp;gt;Exe&amp;lt;/OutputType&amp;gt;

&amp;lt;TargetFramework&amp;gt;net8.0&amp;lt;/TargetFramework&amp;gt;

&amp;lt;ImplicitUsings&amp;gt;enable&amp;lt;/ImplicitUsings&amp;gt;

&amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;

  

&amp;lt;PublishAot&amp;gt;true&amp;lt;/PublishAot&amp;gt;

  

&amp;lt;StripSymbols&amp;gt;true&amp;lt;/StripSymbols&amp;gt;

&amp;lt;/PropertyGroup&amp;gt;

  

&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是Program.cs代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;

namespace BookmarkCleaner
{
    class Program
    {
        // 配置：并发线程数
        private const int MaxConcurrency = 50;
        // 配置：超时时间（秒）
        private const int TimeoutSeconds = 10;

        // HTTP 客户端 (单例)
        private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler
        {
            AllowAutoRedirect = true, // 允许重定向
            CheckCertificateRevocationList = false,
            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =&amp;gt; true // 忽略SSL错误（很多旧网站证书过期但内容还在）
        })
        {
            Timeout = TimeSpan.FromSeconds(TimeoutSeconds)
        };

        static async Task Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36&quot;);

            Console.WriteLine(&quot;==========================================&quot;);
            Console.WriteLine(&quot;    Chrome/Edge 收藏夹强力清理工具&quot;);
            Console.WriteLine(&quot;==========================================&quot;);

            // 1. 自动寻找路径
            var bookmarkPaths = GetBookmarkPaths();
            if (bookmarkPaths.Count == 0)
            {
                Console.WriteLine(&quot;未找到 Chrome 或 Edge 的收藏夹文件。&quot;);
                return;
            }

            Console.WriteLine(&quot;检测到以下收藏夹文件：&quot;);
            for (int i = 0; i &amp;lt; bookmarkPaths.Count; i++)
            {
                Console.WriteLine($&quot;{i + 1}. {bookmarkPaths[i].Browser}: {bookmarkPaths[i].Path}&quot;);
            }

            Console.Write(&quot;\n请输入要处理的序号 (例如 1): &quot;);
            if (!int.TryParse(Console.ReadLine(), out int choice) || choice &amp;lt; 1 || choice &amp;gt; bookmarkPaths.Count)
            {
                Console.WriteLine(&quot;输入无效。&quot;);
                return;
            }

            var selected = bookmarkPaths[choice - 1];

            // 2. 读取并解析 JSON
            Console.WriteLine($&quot;\n正在读取文件: {selected.Path}...&quot;);
            string jsonString = await File.ReadAllTextAsync(selected.Path);

            // 使用 System.Text.Json 解析为可变的 JsonNode
            var rootNode = JsonNode.Parse(jsonString);
            var roots = rootNode?[&quot;roots&quot;]?.AsObject();

            if (roots == null)
            {
                Console.WriteLine(&quot;无法解析收藏夹结构。&quot;);
                return;
            }

            // 3. 收集所有 URL 节点
            var allUrlNodes = new List&amp;lt;UrlItem&amp;gt;();
            CollectUrls(roots, allUrlNodes);
            Console.WriteLine($&quot;共发现 {allUrlNodes.Count} 个书签。准备开始检测...&quot;);

            // 4. 多线程检测
            var processedCount = 0;
            var invalidCount = 0;
            var lockObj = new object();

            Console.WriteLine($&quot;\n启动 {MaxConcurrency} 线程进行极速检测...\n&quot;);

            var options = new ParallelOptions { MaxDegreeOfParallelism = MaxConcurrency };
            await Parallel.ForEachAsync(allUrlNodes, options, async (item, token) =&amp;gt;
            {
                bool isValid = await CheckUrlAsync(item.Url);

                lock (lockObj)
                {
                    processedCount++;
                    if (!isValid)
                    {
                        invalidCount++;
                        item.IsValid = false; // 标记为无效
                        // 实时打印失败的链接（可选）
                        // Console.WriteLine($&quot;[无效] {item.Url}&quot;);
                    }

                    // 简单的进度条
                    if (processedCount % 10 == 0 || processedCount == allUrlNodes.Count)
                    {
                        Console.Write($&quot;\r进度: {processedCount}/{allUrlNodes.Count} | 已发现无效: {invalidCount}   &quot;);
                    }
                }
            });

            Console.WriteLine($&quot;\n\n检测完成！共删除 {invalidCount} 个无效链接。&quot;);

            // 5. 从 JSON 树中移除无效节点
            Console.WriteLine(&quot;正在重组收藏夹结构...&quot;);
            RemoveInvalidNodes(roots, allUrlNodes);

            // 6. 导出为 HTML
            string exportFileName = $&quot;{selected.Browser}_Cleaned_{DateTime.Now:yyyyMMdd_HHmmss}.html&quot;;
            string exportPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), exportFileName);

            Console.WriteLine(&quot;正在生成 HTML 文件...&quot;);
            ExportToHtml(roots, exportPath);

            Console.WriteLine(&quot;==========================================&quot;);
            Console.WriteLine($&quot;✅ 成功！文件已导出到桌面：&quot;);
            Console.WriteLine(exportPath);
            Console.WriteLine(&quot;您可以打开浏览器 -&amp;gt; 收藏夹管理 -&amp;gt; 导入书签，选择此文件。&quot;);
            Console.WriteLine(&quot;==========================================&quot;);
            Console.ReadKey();
        }

        // ---------------- 核心逻辑方法 ----------------

        // 检查 URL 有效性
        static async Task&amp;lt;bool&amp;gt; CheckUrlAsync(string url)
        {
            // 过滤非 HTTP 协议（如 javascript:, file:, chrome:）
            if (!url.StartsWith(&quot;http&quot;, StringComparison.OrdinalIgnoreCase)) return true;

            try
            {
                // 先尝试 HEAD 请求 (省流量)
                var request = new HttpRequestMessage(HttpMethod.Head, url);
                using var response = await _httpClient.SendAsync(request);

                if (response.IsSuccessStatusCode) return true;

                // 如果 HEAD 失败 (有些服务器不支持)，再尝试 GET
                using var getResponse = await _httpClient.GetAsync(url);

                // 检查状态码
                if (!getResponse.IsSuccessStatusCode) return false;

                // 检查内容长度 (如果连接成功但内容为空)
                // 注意：有些动态网站 Content-Length 可能为 null，需谨慎判断
                if (getResponse.Content.Headers.ContentLength.HasValue &amp;amp;&amp;amp; getResponse.Content.Headers.ContentLength &amp;lt; 50)
                {
                    // 这里是个简单的启发式判断：如果页面小于 50 字节，可能是有问题的
                    return false;
                }

                return true;
            }
            catch
            {
                return false; // 超时、DNS解析失败、连接被拒绝
            }
        }

        // 递归收集 URL
        static void CollectUrls(JsonObject node, List&amp;lt;UrlItem&amp;gt; collection)
        {
            foreach (var property in node)
            {
                var childNode = property.Value;
                if (childNode is JsonObject obj)
                {
                    // 检查是否是文件夹还是具体的 URL 条目
                    if (obj.ContainsKey(&quot;type&quot;) &amp;amp;&amp;amp; obj[&quot;type&quot;]?.GetValue&amp;lt;string&amp;gt;() == &quot;url&quot;)
                    {
                        string url = obj[&quot;url&quot;]?.GetValue&amp;lt;string&amp;gt;() ?? &quot;&quot;;
                        string id = obj[&quot;id&quot;]?.GetValue&amp;lt;string&amp;gt;() ?? Guid.NewGuid().ToString();

                        if (!string.IsNullOrEmpty(url))
                        {
                            collection.Add(new UrlItem { Url = url, JsonRef = obj, IsValid = true, Id = id });
                        }
                    }
                    // 如果有 children 属性，说明是文件夹，继续递归
                    else if (obj.ContainsKey(&quot;children&quot;) &amp;amp;&amp;amp; obj[&quot;children&quot;] is JsonArray children)
                    {
                        foreach (var child in children)
                        {
                            if (child is JsonObject childObj)
                            {
                                // 这里需要构造一个临时的父节点结构来递归，或者直接针对 children 数组递归
                                // 由于 JsonNode API 的特性，我们直接对数组里的对象递归即可
                                // 但为了复用 CollectUrls 方法，我们需要判断
                                CollectUrlsRecursion(childObj, collection);
                            }
                        }
                    }
                    else
                    {
                        // 继续遍历其他可能的嵌套
                        CollectUrls(obj, collection);
                    }
                }
            }
        }

        static void CollectUrlsRecursion(JsonObject obj, List&amp;lt;UrlItem&amp;gt; collection)
        {
            if (obj.ContainsKey(&quot;type&quot;) &amp;amp;&amp;amp; obj[&quot;type&quot;]?.GetValue&amp;lt;string&amp;gt;() == &quot;url&quot;)
            {
                string url = obj[&quot;url&quot;]?.GetValue&amp;lt;string&amp;gt;() ?? &quot;&quot;;
                if (!string.IsNullOrEmpty(url))
                {
                    collection.Add(new UrlItem { Url = url, JsonRef = obj, IsValid = true });
                }
            }
            else if (obj.ContainsKey(&quot;children&quot;) &amp;amp;&amp;amp; obj[&quot;children&quot;] is JsonArray children)
            {
                foreach (var child in children)
                {
                    if (child is JsonObject childObj) CollectUrlsRecursion(childObj, collection);
                }
            }
        }

        // 移除无效节点
        static void RemoveInvalidNodes(JsonObject roots, List&amp;lt;UrlItem&amp;gt; items)
        {
            // 建立一个待删除的 Set
            var invalidItems = items.Where(x =&amp;gt; !x.IsValid).ToHashSet();

            // 定义递归移除函数
            void Prune(JsonNode node)
            {
                if (node is JsonObject obj &amp;amp;&amp;amp; obj.ContainsKey(&quot;children&quot;) &amp;amp;&amp;amp; obj[&quot;children&quot;] is JsonArray children)
                {
                    // 倒序遍历以便删除
                    for (int i = children.Count - 1; i &amp;gt;= 0; i--)
                    {
                        var child = children[i];
                        if (child is JsonObject childObj)
                        {
                            // 如果是 URL 节点
                            if (childObj[&quot;type&quot;]?.GetValue&amp;lt;string&amp;gt;() == &quot;url&quot;)
                            {
                                // 检查这个节点是否在无效列表中
                                // 这里我们通过对象引用的相等性来判断，或者比对 URL
                                // 由于我们在 Collect 时保存了 JsonRef，直接比对引用最准确
                                var isInvalid = invalidItems.Any(x =&amp;gt; x.JsonRef == childObj);
                                if (isInvalid)
                                {
                                    children.RemoveAt(i);
                                }
                            }
                            else
                            {
                                // 是文件夹，递归进去
                                Prune(childObj);
                            }
                        }
                    }
                }

                // 遍历 roots 下的顶层节点 (bookmark_bar, other, synced)
                if (node == roots)
                {
                    foreach (var kvp in roots)
                    {
                        if (kvp.Value is JsonObject rootChild) Prune(rootChild);
                    }
                }
            }

            Prune(roots);
        }

        // 导出为 HTML (Netscape Bookmark Format)
        static void ExportToHtml(JsonObject roots, string outputPath)
        {
            var sb = new StringBuilder();
            sb.AppendLine(&quot;&amp;lt;!DOCTYPE NETSCAPE-Bookmark-file-1&amp;gt;&quot;);
            sb.AppendLine(&quot;&quot;);
            sb.AppendLine(&quot;&amp;lt;META HTTP-EQUIV=\&quot;Content-Type\&quot; CONTENT=\&quot;text/html; charset=UTF-8\&quot;&amp;gt;&quot;);
            sb.AppendLine(&quot;&amp;lt;TITLE&amp;gt;Bookmarks&amp;lt;/TITLE&amp;gt;&quot;);
            sb.AppendLine(&quot;&amp;lt;H1&amp;gt;Bookmarks&amp;lt;/H1&amp;gt;&quot;);
            sb.AppendLine(&quot;&amp;lt;DL&amp;gt;&amp;lt;p&amp;gt;&quot;);

            // 定义递归写入 HTML
            void WriteNode(JsonNode node)
            {
                if (node is JsonObject obj)
                {
                    string type = obj[&quot;type&quot;]?.GetValue&amp;lt;string&amp;gt;();
                    string name = obj[&quot;name&quot;]?.GetValue&amp;lt;string&amp;gt;() ?? &quot;Untitled&quot;;

                    if (type == &quot;url&quot;)
                    {
                        string url = obj[&quot;url&quot;]?.GetValue&amp;lt;string&amp;gt;() ?? &quot;#&quot;;
                        sb.AppendLine($&quot;&amp;lt;DT&amp;gt;&amp;lt;A HREF=\&quot;{url}\&quot;&amp;gt;{System.Net.WebUtility.HtmlEncode(name)}&amp;lt;/A&amp;gt;&quot;);
                    }
                    else // 文件夹
                    {
                        // 根节点处理 (bookmark_bar 等) 没有 type 属性，或者 type 是 folder
                        // 或者是 roots 的直接子节点
                        sb.AppendLine($&quot;&amp;lt;DT&amp;gt;&amp;lt;H3&amp;gt;{System.Net.WebUtility.HtmlEncode(name)}&amp;lt;/H3&amp;gt;&quot;);
                        sb.AppendLine(&quot;&amp;lt;DL&amp;gt;&amp;lt;p&amp;gt;&quot;);

                        if (obj[&quot;children&quot;] is JsonArray children)
                        {
                            foreach (var child in children) WriteNode(child);
                        }

                        sb.AppendLine(&quot;&amp;lt;/DL&amp;gt;&amp;lt;p&amp;gt;&quot;);
                    }
                }
            }

            // 处理主要的几个根目录
            var folders = new[] { &quot;bookmark_bar&quot;, &quot;other&quot;, &quot;synced&quot; };
            foreach (var folderKey in folders)
            {
                if (roots.ContainsKey(folderKey) &amp;amp;&amp;amp; roots[folderKey] is JsonObject folderNode)
                {
                    // 顶层文件夹通常不想显示 &quot;bookmark_bar&quot; 这种名字，可以做个映射，也可以直接递归
                    // 为了结构好看，我们直接递归其 children，把它们放在最外层，或者保留文件夹结构
                    // 这里选择保留文件夹结构
                    WriteNode(folderNode);
                }
            }

            sb.AppendLine(&quot;&amp;lt;/DL&amp;gt;&amp;lt;p&amp;gt;&quot;);
            File.WriteAllText(outputPath, sb.ToString());
        }

        static List&amp;lt;(string Browser, string Path)&amp;gt; GetBookmarkPaths()
        {
            var list = new List&amp;lt;(string, string)&amp;gt;();
            var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

            // Chrome
            string chromePath = Path.Combine(localAppData, @&quot;Google\Chrome\User Data\Default\Bookmarks&quot;);
            if (File.Exists(chromePath)) list.Add((&quot;Google Chrome&quot;, chromePath));

            // Edge
            string edgePath = Path.Combine(localAppData, @&quot;Microsoft\Edge\User Data\Default\Bookmarks&quot;);
            if (File.Exists(edgePath)) list.Add((&quot;Microsoft Edge&quot;, edgePath));

            return list;
        }

        class UrlItem
        {
            public string Id { get; set; }
            public string Url { get; set; }
            public JsonObject JsonRef { get; set; } // 保持对原始 JSON 对象的引用以便删除
            public bool IsValid { get; set; }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>将myfav搬到vps上去了</title><link>https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91%E7%9A%84%E4%BA%8B%E4%BB%A5%E5%8F%8A%E5%B0%86%E6%94%B6%E8%97%8F%E6%90%AC%E5%88%B0vps/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91%E7%9A%84%E4%BA%8B%E4%BB%A5%E5%8F%8A%E5%B0%86%E6%94%B6%E8%97%8F%E6%90%AC%E5%88%B0vps/</guid><pubDate>Fri, 12 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;从11月中旬开始，就和namesilo一直纠缠域名的问题。起因是netcraft发了邮件给namesilo，说是我的一个子域页面用了github的page界面，有窃取用户信息的嫌疑。还给出了两个页面文件的信息。&lt;/p&gt;
&lt;p&gt;然后namesilo这个混蛋，它不是将这个子域给封掉，而是将我整个域名都给封了。所有这个域名下的记录都没了。然后我登录到namesilo的账户，我这个域名直接在活动域名里面都消失了。&lt;/p&gt;
&lt;p&gt;然后就联系namesilo的livechat人员，那边让我联系supprt@namesilo，说了情况，然后他们给我回了邮件说netcraft说的，让我看netcraft的信息，我看了，netcraft信息说这个issue已经解决了，没问题。&lt;/p&gt;
&lt;p&gt;我又联系多次livechat，livechat一会说好的，在2天内给你解决。然后等了2天，没一点反应，账户中这个域名还是不存在。又联系livechat，livechat说2个小时内给你解决，等了一天，还是没用。再联系livechat，他妈的要我提供我的水电费账单和身份信息给他们。我告诉他们我不是美国公民，没有这些。他们直接说，不提供就不给开。&lt;/p&gt;
&lt;p&gt;简直操蛋了。&lt;/p&gt;
&lt;p&gt;气得我，又给netcraft发邮件，其实在开始等的2天里就发过了，还抄送了namesilo，但是沉入大海一样，根本没人理。&lt;/p&gt;
&lt;p&gt;这次netcraft终于发邮件过来了，说他们核实了，确实是他们弄错了。我那个域名没有问题，然后通告了其他相关的机构，要求解封。&lt;/p&gt;
&lt;p&gt;我又抄送这个netcraft的确认邮件给support@namesilo，让他们解封。&lt;/p&gt;
&lt;p&gt;过了一天，收到邮件，解封了。&lt;/p&gt;
&lt;p&gt;解封后我第一件事就是要transfer到cloudflare上面去。&lt;/p&gt;
&lt;p&gt;解锁了域名，申请了授权码，但是身上没带信用卡，也不记得ccv，就先放着了。&lt;/p&gt;
&lt;p&gt;隔天，想了想，看了下raddit上面的说法，说cloudflare也不是省油的灯，也经常直接封域名，而且没有人工客服，出问题经常流程化的等死。&lt;/p&gt;
&lt;p&gt;先这样吧，毕竟个人域名。我买了10年的有效期。&lt;/p&gt;
&lt;p&gt;=====&lt;/p&gt;
&lt;p&gt;以前搞的浏览器的插件，用来收藏我的关注站点的。我不用浏览器自带的是因为我收集的太多太乱了，现在还没整理。等整理了，和我干净收藏的合并起来，再用LLM给我分类，生成一个大的收藏页。&lt;/p&gt;
&lt;p&gt;这个干净的浏览器收藏插件我看了下也很多了，在chrome和edge上都有，我经常两个浏览器换着用。将这些收藏导出到csv，然后合并，过滤重复项，再转为一个html页。在oracle的vps上开一个caddy，然后写一个需要认证的web服务，来展示这个html页就好了。&lt;/p&gt;
&lt;p&gt;这样我在外面不带电脑也能用这些干净的收藏了。&lt;/p&gt;
&lt;p&gt;下来就是整理我这浏览器几十年的收藏夹了。需要检测哪些页面已经没了，要删掉的。还要分类一下。&lt;/p&gt;
</content:encoded></item><item><title>网络层面的混沌工程</title><link>https://dididudu998.github.io/posts/%E7%BD%91%E7%BB%9C%E5%B1%82%E9%9D%A2%E7%9A%84%E6%B7%B7%E6%B2%8C%E5%B7%A5%E7%A8%8B/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%BD%91%E7%BB%9C%E5%B1%82%E9%9D%A2%E7%9A%84%E6%B7%B7%E6%B2%8C%E5%B7%A5%E7%A8%8B/</guid><pubDate>Wed, 03 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;以下内容来自与Gemini的对话后，Gemini的回答&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你想要做的这个&lt;strong&gt;Monkey测试（混沌工程）&lt;/strong&gt;——即模拟系统互联抖动（Jitter）、丢包、异常，来验证&lt;strong&gt;数据完整性（Data Consistency/Integrity）&lt;/strong&gt;，这正是分布式系统中最核心、最难测试的部分。&lt;/p&gt;
&lt;p&gt;虽然 bpftrace 做这个比较吃力，但 Linux 内核自带了一套&lt;strong&gt;神器&lt;/strong&gt;，专门用来做这件事。它不需要你写代码，只需要敲几行命令，就能精准模拟各种“烂网络”。&lt;/p&gt;
&lt;p&gt;这个神器叫做 &lt;strong&gt;tc (Traffic Control)&lt;/strong&gt; 配合 &lt;strong&gt;netem (Network Emulator)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我来教你如何用它们构建一个**“数据完整性地狱”**，来看看你的后端代码能不能扛得住。&lt;/p&gt;
&lt;h3&gt;---&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;核心武器：TC + Netem&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;tc 是 Linux 内核网络栈自带的流量控制器。它可以工作在网卡（Network Interface）的出口，对数据包进行排队、整形、延迟、丢弃。&lt;/p&gt;
&lt;p&gt;不需要安装任何软件，你的 Rocky Linux 里就有。&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;场景一：模拟“网络抖动” (Network Jitter)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;测试目标：&lt;/strong&gt; 验证后端是否有超时重试机制？重试会不会导致&lt;strong&gt;数据重复插入&lt;/strong&gt;（幂等性问题）？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;命令：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bash&lt;/p&gt;
&lt;p&gt;# 在 eth0 网卡上，添加 100ms 的延迟，并带有 +/- 20ms 的随机抖动&lt;br /&gt;
# 且遵循正态分布 (distribution normal)&lt;br /&gt;
sudo tc qdisc add dev eth0 root netem delay 100ms 20ms distribution normal&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;效果：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 ping 包过去，可能是 80ms，也可能是 120ms。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据完整性风险：&lt;/strong&gt; 客户端请求发出了，后端收到了并处理了，但在返回 ACK 时网络抖动导致超时。客户端以为失败了，又发了一次。&lt;strong&gt;结果：数据库里存了两条一样的订单。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;场景二：模拟“随机丢包” (Packet Loss)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;测试目标：&lt;/strong&gt; 验证 TCP 断连后的事务回滚（Transaction Rollback）是否正常？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;命令：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bash&lt;/p&gt;
&lt;p&gt;# 随机丢弃 10% 的数据包&lt;br /&gt;
sudo tc qdisc add dev eth0 root netem loss 10%&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;效果：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你的 SSH 可能会变得非常卡。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据完整性风险：&lt;/strong&gt; 在一个涉及多步操作的事务中（比如：扣款 -&amp;gt; 加积分），扣款请求到了，加积分请求丢包了。&lt;strong&gt;结果：钱扣了，积分没加（数据不一致）。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;场景三：模拟“包损坏”与“乱序” (Corruption &amp;amp; Reordering)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;测试目标：&lt;/strong&gt; 验证应用层协议的校验能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;命令：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bash&lt;/p&gt;
&lt;p&gt;# 随机让 5% 的包发生比特翻转（损坏），让 25% 的包不按顺序到达&lt;br /&gt;
sudo tc qdisc add dev eth0 root netem corrupt 5% reorder 25%&lt;/p&gt;
&lt;h3&gt;---&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;进阶：如何只搞“数据库”，不搞“SSH”？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;直接在 eth0 上搞 netem 会影响所有流量，把你自己的 SSH 也就搞卡了。我们需要&lt;strong&gt;精准打击&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这就需要用到 &lt;strong&gt;tc filter&lt;/strong&gt; 或者更简单的 &lt;strong&gt;IFB (Intermediate Functional Block)&lt;/strong&gt; 设备，但为了简单，我推荐一个更好用的封装工具：&lt;strong&gt;comcast&lt;/strong&gt; 或者 &lt;strong&gt;pumba&lt;/strong&gt;（如果你用 Docker）。&lt;/p&gt;
&lt;p&gt;但如果你想手动用原生命令，可以配合 cgroup 或者端口过滤。这里有一个简单的&lt;strong&gt;端口级故障注入&lt;/strong&gt;流程：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目标：只干扰连接 MySQL (3306) 的流量，模拟写入延迟。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bash&lt;/p&gt;
&lt;p&gt;# 1. 创建一个优先队列 (PRIO)&lt;br /&gt;
sudo tc qdisc add dev eth0 root handle 1: prio&lt;/p&gt;
&lt;p&gt;# 2. 在第 1 个子队列上应用 500ms 延迟 (这就是我们要的故障)&lt;br /&gt;
sudo tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 500ms&lt;/p&gt;
&lt;p&gt;# 3. 设置过滤器：凡是发往 3306 端口的包，扔到第 1 个子队列(故障队列)&lt;br /&gt;
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 3306 0xffff flowid 1:1&lt;/p&gt;
&lt;p&gt;# 4. 其他流量默认走第 2/3 队列 (不受影响)&lt;/p&gt;
&lt;h3&gt;---&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;架构师视角：如何设计“数据完整性”验证实验？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有了上面的工具，你就可以设计实验了。单纯的“卡”没有意义，你需要观测数据。&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;实验设计模板：&lt;/strong&gt;&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;基准状态 (Baseline):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;后端是一个简单的转账接口：A -&amp;gt; B 转 100 元。&lt;/li&gt;
&lt;li&gt;编写一个脚本，并发跑 1000 次转账。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;预期：&lt;/strong&gt; A 减了 100000，B 加了 100000。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注入故障 (Chaos Injection):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;使用 tc 命令，设置 &lt;strong&gt;30% 丢包&lt;/strong&gt; + &lt;strong&gt;200ms 延迟&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;开启故障。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运行负载 (Run Workload):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;再次运行那 1000 次转账脚本。&lt;/li&gt;
&lt;li&gt;你会看到客户端报很多 Timeout Exception 或 Connection Reset。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证一致性 (Verify Consistency):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;这是最关键的一步。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;等待所有请求结束（包括重试）。&lt;/li&gt;
&lt;li&gt;查询数据库：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;情况 A (完美):&lt;/strong&gt; A 减去的金额 == B 增加的金额。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;情况 B (数据丢失):&lt;/strong&gt; A 减了钱，但 B 没收到（丢包导致事务提交了一半？）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;情况 C (数据重复):&lt;/strong&gt; B 收到的钱比 A 减去的还多（超时重试导致重复入账）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&lt;strong&gt;推荐工具：Shopify 的 Toxiproxy&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;如果你觉得 Linux 的 tc 命令太晦涩，太容易把机器搞断网。我强烈推荐你使用 Shopify 开源的 &lt;strong&gt;Toxiproxy&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;它是应用层的：&lt;/strong&gt; 不需要 root 权限，不需要改内核。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原理：&lt;/strong&gt; 它在你的 Client 和 Database 之间架一个代理（Proxy）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;玩法：&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;你连接 Toxiproxy 的端口，Toxiproxy 连数据库。&lt;/li&gt;
&lt;li&gt;通过 HTTP API 告诉 Toxiproxy：“嘿，把现在的连接切断 1 秒钟”或者“把现在的延迟加到 5 秒”。&lt;/li&gt;
&lt;li&gt;它非常适合自动化测试代码集成。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总结：&lt;br /&gt;
要测试系统互联抖动对数据的影响：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;底层派：&lt;/strong&gt; 用 Linux 原生 tc + netem。真实、硬核、能模拟 TCP 协议栈级别的故障。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应用派：&lt;/strong&gt; 用 Toxiproxy。简单、安全、易于集成到 CI/CD 流水线。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这才是真正的“后端内功”修炼。如果你的系统能在 tc qdisc add ... loss 30% 的情况下依然保持账目平齐，那就是真正的高可用系统。&lt;/p&gt;
</content:encoded></item><item><title>ntfy发送信息到手机</title><link>https://dididudu998.github.io/posts/ntfy%E5%8F%91%E9%80%81%E9%80%9A%E7%9F%A5%E5%88%B0%E6%89%8B%E6%9C%BA/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/ntfy%E5%8F%91%E9%80%81%E9%80%9A%E7%9F%A5%E5%88%B0%E6%89%8B%E6%9C%BA/</guid><pubDate>Sat, 22 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;前几天看到有个比较好玩的github项目叫做TrendarRadar，趋势雷达。可以对来自数据源https://newsnow.busiyi.world/ 的信息进行过滤和定时推送。想法非常好，因为利用了github的免费的action和workflow的功能。&lt;/p&gt;
&lt;p&gt;我fork了然后配置好了，在手机上下载了ntfy的app，然后试了下，不错。格式都还挺好的。&lt;/p&gt;
&lt;p&gt;但是这个不满足于我，我需要推送我自己的一些消息，比如针对某个微博的账号的新的消息，我需要推送过来，这样我就不用打开微博app去看了，而且主要是这个可以收集的比较全面，不用找来找去的找。&lt;/p&gt;
&lt;p&gt;本身ntfy.sh提供免费的订阅的，这个没问题，但是好像说有限制。（后来看了下，个人使用根本就用不完，好像一天允许200多次）。&lt;/p&gt;
&lt;p&gt;然后自己在oracle云上面有免费的instance，就到上面搞了一个，配合我自己的域名。让cursor写了个小的脚本做了下数据的split和发送测试，挺好的。&lt;/p&gt;
&lt;p&gt;就是我配置了独立的用户和密码来进行推送，但是没有deny掉其他的，目前是匿名的也可以设定自己的推送，如果知道我的域名和端口的话。为了安全，我修改了端口。&lt;/p&gt;
&lt;p&gt;暂时先这么着吧，这种信息push的方式我觉得用处挺大的，虽然我曾经想着自己写一个websocket的进行推送的东西，目前来看不需要了。&lt;/p&gt;
</content:encoded></item><item><title>iptables的一些常见应用场景</title><link>https://dididudu998.github.io/posts/iptables%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B8%B8%E8%A7%81%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/iptables%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B8%B8%E8%A7%81%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 29 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;iptables有两种类型，一种是nat，一种是filter。&lt;/p&gt;
&lt;p&gt;filter表是默认表，负责过滤，决定数据包是允许，拒绝还是丢弃。它包含的链是input，forward和output。&lt;/p&gt;
&lt;p&gt;nat表负责地址转换，功能是修改数据包的源或者目的地址和端口。
包含的链是prerouting，postrouting，output&lt;/p&gt;
&lt;h1&gt;prerouting&lt;/h1&gt;
&lt;p&gt;数据包刚进入网络接口，在内核进行任何路由决策前，将目的地址进行转化，也就是常说的端口转发&lt;/p&gt;
&lt;p&gt;例如：
内网的机器地址是192.168.1.100的8080端口，然后还有一台公网地址为123.123.123.123的服务器。
你希望让所有访问123.123.123.123:80的流量都转发给内网的192.168.1.100:8080.
那么可以在公网服务器上这样设置，假设eth0是它的公网网卡：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 语法: iptables -t nat -A PREROUTING -i [入站网卡] -p [协议] --dport [外部端口] -j DNAT --to-destination [目标IP:端口]

# 示例: 将从 eth0 进来的 80 端口流量转发到 192.168.1.100 的 8080 端口
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;input&lt;/h1&gt;
&lt;p&gt;数据包经过prerouting和路由决策后，系统确认这个包的最终目的地址是本机的某个进程（比如ssh服务，web服务，数据库服务等）&lt;/p&gt;
&lt;p&gt;input可以用来保护服务器本身，决定是否允许外部访问本机的服务。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;只允许10.1.1.5通过22端口访问服务器&lt;/li&gt;
&lt;li&gt;允许所有人访问web服务，开放80和443端口&lt;/li&gt;
&lt;li&gt;拒绝所有来自5.6.7.8的连接&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 示例A: 只允许 10.1.1.5 访问 22 端口 
iptables -A INPUT -p tcp --dport 22 -s 10.1.1.5 -j ACCEPT

# 示例B: 允许 80 和 443 端口 
iptables -A INPUT -p tcp --dport 80 -j ACCEPT 
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 示例C: 拒绝恶意 IP 
iptables -A INPUT -s 5.6.7.8 -j DROP

# 最佳实践: 默认拒绝所有, 再逐个放行 (首先设置默认策略) 

iptables -P INPUT DROP 
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
# 允许已建立的连接 
iptables -A INPUT -i lo -j ACCEPT 
# 允许本地回环 
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许 SSH

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;forward&lt;/h1&gt;
&lt;p&gt;数据包经过prerouting和路由决策后，系统发现这个包的目的地不是本机，而是需要转发到另一个网络接口。&lt;/p&gt;
&lt;p&gt;一般是将linux服务器用作路由器或者网关，并作为网络的防火墙使用的时候经常用到。&lt;/p&gt;
&lt;p&gt;场景：&lt;/p&gt;
&lt;p&gt;一台linux机器有2块网卡，eth0连接外网，eth1连接内网。
你希望内网机器可以访问互联网，但是互联网的人不能访问内网。&lt;/p&gt;
&lt;p&gt;要注意的是input是无效的，因为数据包的目的地不是linux服务器本身。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 语法: iptables -A FORWARD [匹配条件] -j [动作]

# 示例: 允许内网(eth1)访问外网(eth0)
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

# 示例: 只允许外网(eth0)访问内网(eth1)的已建立连接（即内网发起的连接的返回包）
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

# 最佳实践: 默认拒绝所有转发
iptables -P FORWARD DROP
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;postrouting&lt;/h1&gt;
&lt;p&gt;数据包即将离开本机网络接口之前，这个是在output或者forward之后。&lt;/p&gt;
&lt;p&gt;主要用于源地址转换snat，也就是ip伪装&lt;/p&gt;
&lt;p&gt;场景：&lt;/p&gt;
&lt;p&gt;内网192.168.1.0/24通过eth1连接到linux的路由器机器。然后内网有一台机器192.168.1.50需要访问互联网。但是这个地址是私有地址，互联网上的机器无法将数据包送回到这个地址。因此当数据包离开linux路由器的eth0公网网卡时候，postrouting会将源地址192.168.1.50替换为linux路由器的公网地址123.123.123.123.
当外部服务器响应时，它发送数据给123.123.123.123，然后linux接受后再将数据包发给192.168.1.50这台内网机器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 语法: iptables -t nat -A POSTROUTING -o [出站网卡] -s [源地址段] -j [动作]

# 示例 (IP 伪装, 适用于公网 IP 是动态的, 如ADSL/DHCP):
# 将所有从 eth1 来的包 (源地址为 192.168.1.0/24), 在从 eth0 出去时, 进行 IP 伪装
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE

# 示例 (SNAT, 适用于公网 IP 是固定的):
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 123.123.123.123
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;output&lt;/h1&gt;
&lt;p&gt;数据包由本机进程产生的，在它被路由到postrouting之前。
主要用于限制服务器自身的出站连接。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;禁止这台机器连接外部的25端口&lt;/li&gt;
&lt;li&gt;只允许访问apt仓库地址&lt;/li&gt;
&lt;li&gt;只允许连接到某个数据库&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 语法: iptables -A OUTPUT [匹配条件] -j [动作]

# 示例A: 禁止本机发送邮件
iptables -A OUTPUT -p tcp --dport 25 -j DROP

# 示例B: 只允许访问特定 IP
iptables -P OUTPUT DROP  # 默认禁止所有
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允许返回包
iptables -A OUTPUT -o lo -j ACCEPT # 允许本地回环
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT # 允许 DNS
iptables -A OUTPUT -d 172.217.160.110 -j ACCEPT # 假设这是 apt 仓库 IP

# 示例C: 禁止访问生产数据库
iptables -A OUTPUT -d 198.51.100.10 -j DROP # 生产 DB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;简单来说，分为两个场景：&lt;/p&gt;
&lt;p&gt;场景1： 数据包从internet到内部网络的过程如下：&lt;/p&gt;
&lt;p&gt;公网接口-&amp;gt;prerouting(DNAT)-&amp;gt;路由-&amp;gt;（如果是本地，则input。如果是要转发到其他接口，则用forward)-&amp;gt;如果是forward，则下面可以用postrouting进行源地址伪装&lt;/p&gt;
&lt;p&gt;场景2： 数据包从内网到internet&lt;/p&gt;
&lt;p&gt;本地应用-&amp;gt;output-&amp;gt;postrouting(源地址转换)-&amp;gt;公网接口-&amp;gt;internet&lt;/p&gt;
</content:encoded></item><item><title>ssh隧道的一些应用</title><link>https://dididudu998.github.io/posts/ssh%E9%9A%A7%E9%81%93%E7%9A%84%E4%B8%80%E4%BA%9B%E5%BA%94%E7%94%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/ssh%E9%9A%A7%E9%81%93%E7%9A%84%E4%B8%80%E4%BA%9B%E5%BA%94%E7%94%A8/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 28 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;本地端口转发/映射到远程端口&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;ssh -L [本地监听端口]:[目标服务器地址]:[目标服务器端口] user@sshserver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你的本地应用连接 &lt;code&gt;本地监听端口&lt;/code&gt; $\rightarrow$ 流量通过 SSH 加密 $\rightarrow$ 流量在 &lt;code&gt;SSH服务器&lt;/code&gt; 解密 $\rightarrow$ 流量转发到 &lt;code&gt;目标服务器地址&lt;/code&gt; 的 &lt;code&gt;目标端口&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;可以通过 SSH 安全地访问远程数据库、Web 应用管理界面等。&lt;/p&gt;
&lt;p&gt;可用于绕过防火墙，访问那些只允许 SSH 服务器内部访问的服务。&lt;/p&gt;
&lt;p&gt;比如：
ssh -L 3306:localhost:3306 user@dbserver
这里的意思是连接本地的3306端口就相当于连接到dbserver的3306端口了。这里的localhost指的是dbserver这台机器的本地。&lt;/p&gt;
&lt;h1&gt;远程端口转发&lt;/h1&gt;
&lt;p&gt;允许 &lt;strong&gt;远程网络&lt;/strong&gt; 中的用户通过 &lt;strong&gt;SSH 服务器&lt;/strong&gt; 访问 &lt;strong&gt;你的本地机器&lt;/strong&gt; 上的服务。&lt;/p&gt;
&lt;p&gt;远程用户连接 &lt;code&gt;SSH服务器监听端口&lt;/code&gt; $\rightarrow$ 流量在 &lt;code&gt;SSH服务器&lt;/code&gt; 加密 $\rightarrow$ 流量通过 SSH 加密隧道 $\rightarrow$ 流量在&lt;strong&gt;你的本地机器&lt;/strong&gt;解密 $\rightarrow$ 流量转发到 &lt;strong&gt;本地目标地址&lt;/strong&gt; 的 &lt;code&gt;本地目标端口&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -R [SSH服务器监听端口]:[本地目标地址]:[本地目标端口] user@SSH服务器
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;比如：
将你本地内网的一个服务（如 Web 服务器 $80$ 端口）暴露给外部网络。允许外部技术人员通过你的 SSH 服务器端口，访问你本地机器上的服务&lt;/p&gt;
&lt;p&gt;ssh -R 8080:localhost:80 user@remoteserver&lt;/p&gt;
&lt;p&gt;远程用户连接：&lt;code&gt;remoteserver:8080&lt;/code&gt; (该连接实际上指向你本地的 &lt;code&gt;localhost:80&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSH 服务器&lt;/strong&gt;通常默认只允许 &lt;code&gt;localhost&lt;/code&gt; 访问转发的端口。若要允许外部 IP 访问，需要配置 &lt;code&gt;sshd_config&lt;/code&gt; 中的 &lt;code&gt;GatewayPorts yes&lt;/code&gt;。&lt;/p&gt;
&lt;h1&gt;通过跳板机到目的机器&lt;/h1&gt;
&lt;p&gt;你的目标主机位于一个私有网络（内网）中，&lt;strong&gt;你的本地机器无法直接访问&lt;/strong&gt;。但是，有一台跳板机（Jump Host，通常是堡垒机或位于 DMZ 区的服务器）可以同时访问你的本地机器（接收 SSH 连接）和目标主机。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -J user@jumpserver_address user@destination_address
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 带端口转发的跳板连接
ssh -J user@jump-server -L 8080:localhost:80 user@target-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;![[ssh-tunnel.png]]&lt;/p&gt;
&lt;h1&gt;动态端口转发&lt;/h1&gt;
&lt;p&gt;动态转发创建一个socks代理服务器，允许你的所有应用（浏览器，聊天工具等）通过这个代理服务器访问任何目标地址。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -D [本地监听端口] user@ssh_server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本地应用配置使用socks代理，所有流量都发送到本地监听端口，然后流量通过ssh加密传送到ssh服务器，ssh服务器充当socks代理，帮你访问任意目标网站地址。&lt;/p&gt;
&lt;p&gt;主要用于将网络流量加密，防止本地ISP的监控，绕过本地网络限制，来访问外部资源。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;p&gt;ssh -D 1080 user@proxy_server&lt;/p&gt;
&lt;p&gt;保持连接，然后在应用中配置socks代理，服务器地址localhost，端口1080即可。&lt;/p&gt;
</content:encoded></item><item><title>下载twitter的内容</title><link>https://dididudu998.github.io/posts/%E4%B8%8B%E8%BD%BDtwitter%E7%9A%84%E5%86%85%E5%AE%B9/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%8B%E8%BD%BDtwitter%E7%9A%84%E5%86%85%E5%AE%B9/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Sat, 30 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;很早之前有个twittie还是什么的python的包，可以下载twitter的内容。自从被马斯克收购后，这种类型下载的方式很多被干掉了，因为既缺少可用的软件，又没有什么特别的内容需要，所以就没有继续。前些日子看到一些有趣的内容，又想要收集下来，所以找到这个python的包和windows下的可执行文件&lt;/p&gt;
&lt;p&gt;https://github.com/mikf/gallery-dl/releases&lt;/p&gt;
&lt;p&gt;在Windows在这个目录配置”%APPDATA%\gallery-dl\config.json“文件，示例如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;

{
    &quot;extractor&quot;: {
        &quot;twitter&quot;: {
            &quot;videos&quot;: true,
            &quot;images&quot;: true
        }
    },
    &quot;output&quot;: {
        &quot;template&quot;: &quot;{author[screen_name]}/{tweet_id}_{num}.{extension}&quot;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还有要有x.com账户登录后的cookies信息，否则也是不行的。
这个可以在浏览器上安装插件”Get cookies.txt Local&quot; 来实现，装上插件后，访问x.com，然后export cookies 以Netscape的格式，存为x.txt文件&lt;/p&gt;
&lt;p&gt;再下来就可以在命令行下执行对应的信息收集了&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gallery-dl --cookies x.txt https://x.com/account
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;由于那个json文件没有设置存放的目标文件夹，所以这样的结果就是下载下来的文件默认都放在C:\Users\your_account_name\gallery-dl\twitter这个文件夹下面，然后以不同的下载目标账户来进行区分。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gallery-dl --help
Usage: gallery-dl [OPTIONS] URL [URL...]

General Options:
  -h, --help                  Print this help message and exit
  --version                   Print program version and exit
  -f, --filename FORMAT       Filename format string for downloaded files (&apos;/O&apos; for &quot;original&quot; filenames)
  -d, --destination PATH      Target location for file downloads
  -D, --directory PATH        Exact location for file downloads
  -X, --extractors PATH       Load external extractors from PATH
  -a, --user-agent UA         User-Agent request header
  --clear-cache MODULE        Delete cached login sessions, cookies, etc. for MODULE (ALL to delete everything)
  --compat                    Restore legacy &apos;category&apos; names

Update Options:
  -U, --update-check          Check if a newer version is available

Input Options:
  -i, --input-file FILE       Download URLs found in FILE (&apos;-&apos; for stdin). More than one --input-file can be specified
  -I, --input-file-comment FILE
                              Download URLs found in FILE. Comment them out after they were downloaded successfully.
  -x, --input-file-delete FILE
                              Download URLs found in FILE. Delete them after they were downloaded successfully.
  --no-input                  Do not prompt for passwords/tokens

Output Options:
  -q, --quiet                 Activate quiet mode
  -w, --warning               Print only warnings and errors
  -v, --verbose               Print various debugging information
  -g, --get-urls              Print URLs instead of downloading
  -G, --resolve-urls          Print URLs instead of downloading; resolve intermediary URLs
  -j, --dump-json             Print JSON information
  -J, --resolve-json          Print JSON information; resolve intermediary URLs
  -s, --simulate              Simulate data extraction; do not download anything
  -E, --extractor-info        Print extractor defaults and settings
  -K, --list-keywords         Print a list of available keywords and example values for the given URLs
  -e, --error-file FILE       Add input URLs which returned an error to FILE
  -N, --print [EVENT:]FORMAT  Write FORMAT during EVENT (default &apos;prepare&apos;) to standard output instead of downloading
                              files. Can be used multiple times. Examples: &apos;id&apos; or &apos;post:{md5[:8]}&apos;
  --Print [EVENT:]FORMAT      Like --print, but downloads files as well
  --print-to-file [EVENT:]FORMAT FILE
                              Append FORMAT during EVENT to FILE instead of downloading files. Can be used multiple
                              times
  --Print-to-file [EVENT:]FORMAT FILE
                              Like --print-to-file, but downloads files as well
  --list-modules              Print a list of available extractor modules
  --list-extractors [CATEGORIES]
                              Print a list of extractor classes with description, (sub)category and example URL
  --write-log FILE            Write logging output to FILE
  --write-unsupported FILE    Write URLs, which get emitted by other extractors but cannot be handled, to FILE
  --write-pages               Write downloaded intermediary pages to files in the current directory to debug problems
  --print-traffic             Display sent and read HTTP traffic
  --no-colors                 Do not emit ANSI color codes in output

Networking Options:
  -R, --retries N             Maximum number of retries for failed HTTP requests or -1 for infinite retries (default: 4)
  --http-timeout SECONDS      Timeout for HTTP connections (default: 30.0)
  --proxy URL                 Use the specified proxy
  --source-address IP         Client-side IP address to bind to
  -4, --force-ipv4            Make all connections via IPv4
  -6, --force-ipv6            Make all connections via IPv6
  --no-check-certificate      Disable HTTPS certificate validation

Downloader Options:
  -r, --limit-rate RATE       Maximum download rate (e.g. 500k, 2.5M, or 800k-2M)
  --chunk-size SIZE           Size of in-memory data chunks (default: 32k)
  --sleep SECONDS             Number of seconds to wait before each download. This can be either a constant value or a
                              range (e.g. 2.7 or 2.0-3.5)
  --sleep-request SECONDS     Number of seconds to wait between HTTP requests during data extraction
  --sleep-429 SECONDS         Number of seconds to wait when receiving a &apos;429 Too Many Requests&apos; response
  --sleep-extractor SECONDS   Number of seconds to wait before starting data extraction for an input URL
  --no-part                   Do not use .part files
  --no-skip                   Do not skip downloads; overwrite existing files
  --no-mtime                  Do not set file modification times according to Last-Modified HTTP response headers
  --no-download               Do not download any files

Configuration Options:
  -o, --option KEY=VALUE      Additional options. Example: -o browser=firefox
  -c, --config FILE           Additional configuration files
  --config-yaml FILE          Additional configuration files in YAML format
  --config-toml FILE          Additional configuration files in TOML format
  --config-create             Create a basic configuration file
  --config-status             Show configuration file status
  --config-open               Open configuration file in external application
  --config-ignore             Do not read default configuration files

Authentication Options:
  -u, --username USER         Username to login with
  -p, --password PASS         Password belonging to the given username
  --netrc                     Enable .netrc authentication data

Cookie Options:
  -C, --cookies FILE          File to load additional cookies from
  --cookies-export FILE       Export session cookies to FILE
  --cookies-from-browser BROWSER[/DOMAIN][+KEYRING][:PROFILE][::CONTAINER]
                              Name of the browser to load cookies from, with optional domain prefixed with &apos;/&apos;, keyring
                              name prefixed with &apos;+&apos;, profile prefixed with &apos;:&apos;, and container prefixed with &apos;::&apos;
                              (&apos;none&apos; for no container (default), &apos;all&apos; for all containers)

Selection Options:
  -A, --abort N[:TARGET]      Stop current extractor(s) after N consecutive file downloads were skipped. Specify a
                              TARGET to set how many levels to ascend or to which subcategory to jump to. Examples: &apos;-A
                              3&apos;, &apos;-A 3:2&apos;, &apos;-A 3:manga&apos;
  -T, --terminate N           Stop current &amp;amp; parent extractors and proceed with the next input URL after N consecutive
                              file downloads were skipped
  --filesize-min SIZE         Do not download files smaller than SIZE (e.g. 500k or 2.5M)
  --filesize-max SIZE         Do not download files larger than SIZE (e.g. 500k or 2.5M)
  --download-archive FILE     Record successfully downloaded files in FILE and skip downloading any file already in it
  --range RANGE               Index range(s) specifying which files to download. These can be either a constant value,
                              range, or slice (e.g. &apos;5&apos;, &apos;8-20&apos;, or &apos;1:24:3&apos;)
  --chapter-range RANGE       Like &apos;--range&apos;, but applies to manga chapters and other delegated URLs
  --filter EXPR               Python expression controlling which files to download. Files for which the expression
                              evaluates to False are ignored. Available keys are the filename-specific ones listed by
                              &apos;-K&apos;. Example: --filter &quot;image_width &amp;gt;= 1000 and rating in (&apos;s&apos;, &apos;q&apos;)&quot;
  --chapter-filter EXPR       Like &apos;--filter&apos;, but applies to manga chapters and other delegated URLs

Post-processing Options:
  -P, --postprocessor NAME    Activate the specified post processor
  --no-postprocessors         Do not run any post processors
  -O, --postprocessor-option KEY=VALUE
                              Additional post processor options
  --write-metadata            Write metadata to separate JSON files
  --write-info-json           Write gallery metadata to a info.json file
  --write-tags                Write image tags to separate text files
  --zip                       Store downloaded files in a ZIP archive
  --cbz                       Store downloaded files in a CBZ archive
  --mtime NAME                Set file modification times according to metadata selected by NAME. Examples: &apos;date&apos; or
                              &apos;status[date]&apos;
  --rename FORMAT             Rename previously downloaded files from FORMAT to the current filename format
  --rename-to FORMAT          Rename previously downloaded files from the current filename format to FORMAT
  --ugoira FMT                Convert Pixiv Ugoira to FMT using FFmpeg. Supported formats are &apos;webm&apos;, &apos;mp4&apos;, &apos;gif&apos;,
                              &apos;vp8&apos;, &apos;vp9&apos;, &apos;vp9-lossless&apos;, &apos;copy&apos;, &apos;zip&apos;.
  --exec CMD                  Execute CMD for each downloaded file. Supported replacement fields are {} or {_path},
                              {_directory}, {_filename}. Example: --exec &quot;convert {} {}.png &amp;amp;&amp;amp; rm {}&quot;
  --exec-after CMD            Execute CMD after all files were downloaded. Example: --exec-after &quot;cd {_directory} &amp;amp;&amp;amp;
                              convert * ../doc.pdf&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;虽然上面的config.json里面只写了视频和图片，但是文本内容也是独立的下载下来了。&lt;/p&gt;
&lt;p&gt;到目前我没有很仔细的研究这个软件的使用，只是收集信息的目的，这个软件是帮我实现了。&lt;/p&gt;
&lt;p&gt;等到真的有必要的时候，我再来更新。&lt;/p&gt;
</content:encoded></item><item><title>html页面打包</title><link>https://dididudu998.github.io/posts/html%E9%A1%B5%E9%9D%A2%E6%89%93%E5%8C%85/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/html%E9%A1%B5%E9%9D%A2%E6%89%93%E5%8C%85/</guid><description>比较下打包工具</description><pubDate>Mon, 28 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;上周想起来要做个发票打印的工具，就是拖pdf或者图片文件到工具里面，然后可以自动生成每一页A4上面上下排列2张电子发票发送给打印机。&lt;/p&gt;
&lt;p&gt;用python做了个完全版的，通过pyinstaller打包后竟然要70多兆。太夸张了。&lt;/p&gt;
&lt;p&gt;然后想着直接用html+javascript来做。这个更简单一些。&lt;/p&gt;
&lt;p&gt;做好了，因为需要有字体的依赖，所以先用tauri打了个包，发现也要9MB的大小。如果将字体的依赖去掉，也就是使用online的字体，提供字体访问url，这样打包下来也要8MB。这搞得。&lt;/p&gt;
&lt;p&gt;然后试着用neutralinojs进行打包，虽然打包下来程序2MB，但是依赖的resources.neu资源库也要2MB多，而且我看了下，这个neu文件不能合并到exe可执行文件里，必须同时分发给用户，这就太糟了。虽然打包后文件小，但这种交付方式不好。&lt;/p&gt;
&lt;p&gt;所以还是用tauri了。&lt;/p&gt;
&lt;p&gt;electron很早就试过，这个更夸张，毕竟要塞一个浏览器进去。所以这次就不考虑。&lt;/p&gt;
&lt;p&gt;我只是做一个单html页面，打包后也要几兆，希望有更好的打包工具出现啊。&lt;/p&gt;
</content:encoded></item><item><title>打包golang web服务器可执行文件为单文件</title><link>https://dididudu998.github.io/posts/%E6%89%93%E5%8C%85golang%E7%9A%84web%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%BA%E7%8B%AC%E7%AB%8B%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%89%93%E5%8C%85golang%E7%9A%84web%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%BA%E7%8B%AC%E7%AB%8B%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 26 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;前段时间写了golang的gin程序想着要打包一个独立的可执行文件，但是用embed试了下，没成功，趁着快要下班了，觉得还是再试试。发现下面的方式可行。&lt;/p&gt;
&lt;p&gt;结构如下：&lt;/p&gt;
&lt;p&gt;mytest
main.go
templates/
index.html&lt;/p&gt;
&lt;p&gt;这个是main.go文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main
import (
	&quot;embed&quot;
	&quot;fmt&quot;
	&quot;html/template&quot;
	&quot;net/http&quot;
)

type DataRow struct {
	ID int
	Name string
	Aget int
}

//go:embed templates/index.html
var fs embed.FS

func main(){
	teplBytes,err:=fs.ReadFile(&quot;templates/index.html&quot;)
	if err!=nil{
		panic(err)
		}
		tmpl,err:=template.New(&quot;index.html&quot;).Parse(string(tmplBytes))
		if err!=nil{
			panic(err)
		}
	data:=[]DataRow{
		{ID:1,Name:&quot;Alice&quot;,Age:30},
		{ID:2,Name:&quot;Bob&quot;,Age:33},
		{ID:3,Name:&quot;Charlie&quot;,Age:23},
	}

http.HandleFunc(&quot;/&quot;,func(w http.ResponseWriter, r *http.Request){
	err:=tmpl.ExecuteTemplate(w,&quot;index.html&quot;,data)
	if err!=nil{
		http.Error(w,err.Error(),http.StatusInternalServerError)
	
	}
})

fmt.Println(&quot;server listening on port 6060&quot;)
http.ListenAndServe(&quot;:6060&quot;,nil)

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是在templates目录下创建的index.html文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Test&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;Data table&amp;lt;/h1&amp;gt;
&amp;lt;table&amp;gt;
&amp;lt;thead&amp;gt;
&amp;lt;tr&amp;gt;
&amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;
&amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;
&amp;lt;th&amp;gt;Age&amp;lt;/th&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;/thead&amp;gt;
&amp;lt;tbody&amp;gt;
{{range .}}
&amp;lt;tr&amp;gt;
&amp;lt;td&amp;gt;{{.ID}}&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;{{.Name}}&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;{{.Age}}&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
{{end}}
&amp;lt;/tbody&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后执行编译：
go build -ldflags=&quot;-s -w&quot; main.go&lt;/p&gt;
&lt;p&gt;此时生成的可执行文件，可以拷贝到其他地方也能正常的进行web访问了。&lt;/p&gt;
</content:encoded></item><item><title>一个修改系统默认字体的工具</title><link>https://dididudu998.github.io/posts/%E4%B8%80%E4%B8%AA%E4%BF%AE%E6%94%B9%E7%B3%BB%E7%BB%9F%E9%BB%98%E8%AE%A4%E5%AD%97%E4%BD%93%E7%9A%84%E5%B7%A5%E5%85%B7/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%80%E4%B8%AA%E4%BF%AE%E6%94%B9%E7%B3%BB%E7%BB%9F%E9%BB%98%E8%AE%A4%E5%AD%97%E4%BD%93%E7%9A%84%E5%B7%A5%E5%85%B7/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 30 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;可能看惯了苹果电脑上的字体，或者是屏幕了，现在用这个OLED的笔记本看字体总是觉得有点发虚。网上找了下免费的字体，发现Google的字体还可以。虽然我也想要苹果的字体，但是需要折腾，而且苹果的东西都是要授权的，懒得搞了。&lt;/p&gt;
&lt;p&gt;在这里&lt;a href=&quot;https://fonts.google.com?/lang=zh_Hans&quot;&gt;下载Google字体&lt;/a&gt;.我选择了中文的Noto Sans。&lt;/p&gt;
&lt;p&gt;本以为只要下载个字体，点击安装就好了，后来发现要在各种地方进行设置，所以找了这个软件，好像是来自日本的。用了下，挺好的。&lt;/p&gt;
&lt;p&gt;所以记录下，可能下次不知道什么时候也能用的上。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Tatsu-syo/noMeiryoUI&quot;&gt;Tatsu-syo/noMeiryoUI: No!! MeiryoUI is Windows system font setting tool on Windows 8.1/10/11.&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>使用opencore legacy升级MacBook的操作系统</title><link>https://dididudu998.github.io/posts/%E4%BD%BF%E7%94%A8opencore-legacy%E5%8D%87%E7%BA%A7macbook%E7%B3%BB%E7%BB%9F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BD%BF%E7%94%A8opencore-legacy%E5%8D%87%E7%BA%A7macbook%E7%B3%BB%E7%BB%9F/</guid><pubDate>Sun, 20 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;现在用的Macbook Pro是2015 early的版本，13寸银白，用到现在也有9年了，期间换了一次电池，换了一次屏幕，最后一次换电池，苹果店还把A面也给换了，现在整体的样子还是很新的感觉。&lt;/p&gt;
&lt;p&gt;由于Apple已经不再支持当前的版本Monterey了，导致很多时候要用点东西，连brew都说已经不支持。
想着到底也是个好物件，不能就这么废了吧。以前就知道装黑苹果的事情，现在是真苹果，应该也没问题了。所以搜了下，到了[opencore legacy的官网](&lt;a href=&quot;https://dortania.github.io/OpenCore-Legacy-Patcher/&quot;&gt;OpenCore Legacy Patcher&lt;/a&gt;),照着说明操作即可。&lt;/p&gt;
&lt;p&gt;这个机器可以支持到macOS Ventura，下载dmg，安装，然后准备U盘，创建启动镜像，然后安装即可。整体的过程非常流畅，没有任何的问题。如果长时间没有响应，就等待就好了。&lt;/p&gt;
&lt;p&gt;升级后，没想到硬盘空间反而多了一些，而且运行速度也没有任何的感觉变慢。所有的应用程序都可以和以前一样运行。&lt;/p&gt;
</content:encoded></item><item><title>替换openvpn为wireguard</title><link>https://dididudu998.github.io/posts/%E6%9B%BF%E6%8D%A2openvpen%E4%B8%BAwireguard/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%9B%BF%E6%8D%A2openvpen%E4%B8%BAwireguard/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 27 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今天用openvpn客户端的时候，提示证书过期了。一直用的都是openvpn的容器，速度还是可以的，反应也挺快的，唯一的问题就是openvpn的流量一直被GFW给断掉的。&lt;/p&gt;
&lt;p&gt;试了下将原来的openvpn的容器停掉，重新起一个新的容器，但是试了下，反而报了错了。索性换个新的方式，就选了wireguard，同样的为了方便，也是用容器部署的。
下面是容器的命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;

  docker run -d \
  --name=wg-easy \
  -e LANG=en \
  -e WG_HOST=x.x.x.x \
  -e PASSWORD_HASH=&apos;$2a$12$ZMZ0tyMgTMod2i6iARStLeFk0SikcY6qBhkM3HtvgVkOc7lbOxV4O&apos; \
  -e PORT=51821 \
  -e WG_PORT=51820 \
  -v ~/.wg-easy:/etc/wireguard \
  -p 51820:51820/udp \
  -p 51821:51821/tcp \
  --cap-add=NET_ADMIN \
  --cap-add=SYS_MODULE \
  --sysctl=&quot;net.ipv4.conf.all.src_valid_mark=1&quot; \
  --sysctl=&quot;net.ipv4.ip_forward=1&quot; \
  --restart unless-stopped \
  ghcr.io/wg-easy/wg-easy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的51821是用于登录管理的端口，这里我没有用secure的模式，所以就是http://x.x.x.x:51821就可以了。用密码登录，这个里面的密码哈希是bcrypt的模式，如果忘了密码的话就在生成一个，然后重启容器就可以。&lt;/p&gt;
&lt;p&gt;好的一点是wireguard不管是用wifi还是5g都可以连接上。以后就用这个了好了。&lt;/p&gt;
&lt;p&gt;但是v2ray的安卓客户端里面虽然说可以添加wireguard的配置，扫描后却是失败的。
只有下载到了安卓的wireguard的app，用这个扫描就可以了。应该是v2ray和当前的wireguard不匹配或者版本太老了。&lt;/p&gt;
</content:encoded></item><item><title>定时更新dns记录</title><link>https://dididudu998.github.io/posts/%E5%AE%9A%E6%97%B6%E6%9B%B4%E6%96%B0dns%E8%AE%B0%E5%BD%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%AE%9A%E6%97%B6%E6%9B%B4%E6%96%B0dns%E8%AE%B0%E5%BD%95/</guid><pubDate>Wed, 26 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;清明假期就要到了。有个要更新dns记录的事情要在假期早上做。为了在路上不受到影响，提前做一个定时任务，用于更新bind中的zone的记录，并发邮件给我。&lt;/p&gt;
&lt;h3&gt;下面是python的代码：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env python3

import os
import datetime
import smtplib
from email.mime.text import MIMEText

# Configuration
ZONE_FILE = &quot;internet.mydomain.zone&quot;
BACKUP_DIR = &quot;zone_backups&quot;
sender=&quot;dns_record_update@mydomain.com&quot;
receiver=&quot;me@mydomain.com&quot;
smtpserver=&quot;smtp.mydomain.com&quot;
smtpport=25

# 1. Create Backup Directory (if it doesn&apos;t exist)
if not os.path.exists(BACKUP_DIR):
    os.makedirs(BACKUP_DIR)

# 2. Backup the Zone File
backup_file = os.path.join(BACKUP_DIR, f&quot;{datetime.datetime.now().strftime(&apos;%Y%m%d_%H%M%S&apos;)}_{ZONE_FILE}&quot;)
import shutil
shutil.copy2(ZONE_FILE, backup_file)
print(f&quot;Zone file backed up to: {backup_file}&quot;)

# 3. Modify the Zone File
with open(ZONE_FILE, &apos;r&apos;) as f:
    lines = f.readlines()

current_date = datetime.datetime.now().strftime(&apos;%Y%m%d01&apos;)

for i, line in enumerate(lines):
    if &apos;serial&apos; in line:
        lines[i] = lines[i].replace(&apos;2025032001&apos;, current_date)
    if &apos;transport&apos; in line:
        lines[i] = lines[i].replace(&apos;transport&apos;,&apos;;transport&apos;)
lines.append(&quot;transport IN CNAME transport.xxxx.xx\n&quot;)

with open(ZONE_FILE, &apos;w&apos;) as f:
    f.writelines(lines)

# 4. Restart the Named Service
import subprocess
try:
    subprocess.run([&apos;sudo&apos;, &apos;service&apos;, &apos;named&apos;, &apos;reload&apos;], check=True)  # Or sudo service named restart
    print(&quot;Named service restarted.&quot;)
except subprocess.CalledProcessError as e:
    print(f&quot;Error restarting named service: {e}&quot;)

print(&quot;All operations completed.&quot;)


#5. verify cname resolution
dig_output=subprocess.check_output([&quot;dig&quot;,&quot;+short&quot;,&quot;transport.mydomain.com&quot;]).decode(&quot;utf-8&quot;).strip()
nslookup_output=subprocess.check_output([&quot;nslookup&quot;,&quot;transport.mydomain.com&quot;]).decode(&quot;utf-8&quot;).strip()



emailbody=f&quot;&quot;&quot;
zone file modification completed successfully.

CNAME resolution (dig):

{dig_output}

CNAME resolution (nslookup):

{nslookup_output}

&quot;&quot;&quot;
message=MIMEText(f&quot;zone file modificate -transport cname verification\n\n{emailbody}&quot;)
message[&apos;Subject&apos;]=&quot;dns record update&quot;
message[&apos;From&apos;]=sender
message[&apos;To&apos;]=receiver

with smtplib.SMTP(smtpserver,smtpport) as server:
    server.sendmail(sender,receiver,message.as_string())

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里我的smtp服务器不需要登录。&lt;/p&gt;
&lt;p&gt;测试后，发现可以了。那就要定时执行。
安装at命令，并启动atd服务。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dnf install at
sysemctl enable atd
service atd start
service atd status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;定时执行测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;python update-record.py&quot; | at 14:54
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过后，就定时到真正需要改变的时间点：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;python update-record.py&quot; | at 09:00 next Saturday

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;确定命令输出的时间是需要变更的时间。&lt;/p&gt;
&lt;h3&gt;检查计划队列：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@server01]# atq
5	Sat Mar 29 09:00:00 2025 a root
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;详细查看要执行的代码信息:&lt;/h3&gt;
&lt;p&gt;进入/var/spool/at目录，就能看到一个文件名为a00005xxxx。用cat打开就知道这个第五条任务是什么了，如果新加了任务，那么文件名就为a00006xxxx这样的，以此类推。执行后，这个文件就会被清理掉。&lt;/p&gt;
</content:encoded></item><item><title>epub转有声书</title><link>https://dididudu998.github.io/posts/%E7%94%B5%E5%AD%90%E4%B9%A6epub%E8%BD%AC%E6%9C%89%E5%A3%B0%E4%B9%A6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%B5%E5%AD%90%E4%B9%A6epub%E8%BD%AC%E6%9C%89%E5%A3%B0%E4%B9%A6/</guid><pubDate>Wed, 26 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;手机上一直用librera来听电子书，但是由于手机内置的TTS以及自己找的一些TTS感觉都差点意思，所以一直想要搞一个比较好的听书的东西。这两天看了huggingface上面的一些语音TTS的模型，觉得还挺不错，静下心来搞一下。&lt;/p&gt;
&lt;p&gt;发现有人已经做了，我试了下对中文的epub的支持还挺好的，省事了。&lt;/p&gt;
&lt;p&gt;他的GitHub是这里：&lt;a href=&quot;https://github.com/santinic/audiblez&quot;&gt;audiblez&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;里面中文的语音模型，有两个竟然是陕西话，女声普通话就是xiaoyi，男声我就用第一个yunjian。&lt;/p&gt;
&lt;p&gt;它会将各个章节转化为wav，然后合并为m4b文件。&lt;/p&gt;
&lt;p&gt;就是这样了。我的电脑有GPU，所以用的GPU进行转换的，速度挺快的。&lt;/p&gt;
&lt;p&gt;但是m4b文件有一些播放器读不出来。&lt;/p&gt;
&lt;p&gt;此时如果你用ffmpeg应该也可以自己将wav文件转为mp3.&lt;/p&gt;
&lt;p&gt;但是有人已经做出来直接将m4b文件转mp3格式的软件了，参看这里：&lt;a href=&quot;https://github.com/yermak/AudioBookConverter&quot;&gt;yermak/AudioBookConverter: Improved AudioBookConverter based on freeipodsoftware release&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;直接下载将m4b文件加载，然后选输出按照章节还是按照全部的方式，还能够选择语速，再点开始，选择输出目录，就可以了。速度很快。900MB的m4b文件最后输出为110MB的mp3，手机上省空间了。&lt;/p&gt;
</content:encoded></item><item><title>将huggingface上下载的模型转化为safetensors的格式</title><link>https://dididudu998.github.io/posts/huggingface%E4%B8%8A%E9%9D%A2sd%E6%A8%A1%E5%9E%8B%E5%88%B0safetensors%E7%9A%84%E8%BD%AC%E5%8C%96/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/huggingface%E4%B8%8A%E9%9D%A2sd%E6%A8%A1%E5%9E%8B%E5%88%B0safetensors%E7%9A%84%E8%BD%AC%E5%8C%96/</guid><pubDate>Tue, 25 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;由于在 https://civitai.com/models 上下载模型太慢了，一秒钟只有几百kb的速度，实在是太耗费时间。所以想到直接到huggingface.io上面去下载，这个速度非常快，下载下来转化下格式应该就可以用了。说干就干，下面是步骤。&lt;/p&gt;
&lt;h3&gt;步骤&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;访问huggingface.co找到text-to-image这个标签，或者如果知道自己要下载什么模型直接搜模型名字&lt;/li&gt;
&lt;li&gt;建议搞一个本地的虚拟环境&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;python -m virtualenv myenv
.\myenv\Scripts\activate
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装diffusers&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pip install diffusers
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;用下面的代码下载模型，酌情进行修改吧，不需要生成图片，我们只需要下载模型即可&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;from diffusers import StableDiffusionPipeline
model_id=&quot;emilianJR/chilloutmix_NiPrunedFp32Fix&quot;
pipe=StableDiffusionPipeline.from_pretrained(model_id,torch_dtype=torch.float16)
pipe=pipe.to(&quot;cuda&quot;)
prompt=&quot;a girl&quot;
image=pipe(prompt).images[0]
image.save(&quot;image.png&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&amp;lt;font color=red&amp;gt;注意：这里的精度是float16，后面要用到，否则生成的模型用不了&amp;lt;/font&amp;gt;&lt;/li&gt;
&lt;li&gt;下载diffusers这个库，这里面有脚本工具用来进行转化的&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/huggingface/diffusers.git
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;找到从huggingface下载的模型的位置，Windows默认一般在这里：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;c:\users\myaccount\.cache\huggingface\hub\models--emilianxxxFix\snapshots\xxxxx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果只是将文件位置指定为models--emilianxxx这里，则下面使用的转化工具将提示无法找到对应的unet或vae文件夹，不能执行转化操作。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;现在进入我们clone好的diffusers文件夹下面的Scripts目录&lt;/li&gt;
&lt;li&gt;可以看到有这样的一个脚本convert_diffusers_to_original_stable_diffusion.py&lt;/li&gt;
&lt;li&gt;下面就是进行转化的命令行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;python convert_diffusers_to_original_stable_diffusion.py --model_path c:\users\myaccount\.cache\huggingface\hub\models--emilianxxxFix\snapshots\xxxxx --checkpoint_path d:\mymodel\emilian.safetensors --half --use_safetensors
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;再次提醒： 命令行里面必须有--half这个参数，因为前面下载的是float16的，如果不加这个--half参数，转化后的模型在SD中调用的时候会报错，提示”safetensors_rust.SafetensorError: Error with deserializing header: HeaderTooLarge&quot;.&lt;/li&gt;
&lt;li&gt;将转化后的模型emilian.safetensors移动到SD的models,Stable-diffusion目录下，就可以直接使用了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;这里解决方法，第一用到了曲线下载模型库，第二转化模型到SD原生模式，第三将转化后的模型加载到SD模型库中的三个步骤。&lt;/p&gt;
&lt;p&gt;从huggingface上下载模型速度很快，最高可以到5MB/s，转化速度也很快，下载的模型有5GB大小，转化大概只要20秒就完成了。&lt;/p&gt;
&lt;p&gt;主要是要注意精度问题，如果不做调整，转化出来也不能用。&lt;/p&gt;
</content:encoded></item><item><title>利用deepseek和NLP模型做了个本地的文件知识库问答系统</title><link>https://dididudu998.github.io/posts/%E7%94%A8deepseek%E5%92%8Cnlp%E6%A8%A1%E5%9E%8B%E5%81%9A%E4%BA%86%E4%B8%AA%E6%9C%AC%E5%9C%B0%E7%9F%A5%E8%AF%86%E5%BA%93%E9%97%AE%E7%AD%94/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8deepseek%E5%92%8Cnlp%E6%A8%A1%E5%9E%8B%E5%81%9A%E4%BA%86%E4%B8%AA%E6%9C%AC%E5%9C%B0%E7%9F%A5%E8%AF%86%E5%BA%93%E9%97%AE%E7%AD%94/</guid><pubDate>Mon, 03 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;具体怎么做的，隐藏了。不过过程比较简单的。但是整体实现的效果是很好的。deepseek的思考过程加上NLP的断句，问答起来正确率很高，而且回答的很通顺。&lt;/p&gt;
</content:encoded></item><item><title>powershell一句话脚本更新Windows主机</title><link>https://dididudu998.github.io/posts/%E4%B8%80%E5%8F%A5%E8%AF%9Dshell%E6%9B%B4%E6%96%B0windows%E4%B8%BB%E6%9C%BA/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%80%E5%8F%A5%E8%AF%9Dshell%E6%9B%B4%E6%96%B0windows%E4%B8%BB%E6%9C%BA/</guid><pubDate>Fri, 10 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;很早之前用powershell写过一个自动更新windows的脚本，也给自己的机器都用上了。而前阵子用c#写了个监控核心服务的命令行，如果核心服务出现停止了，会尝试几次重启，如果重启失败了，就会进行报警。&lt;/p&gt;
&lt;p&gt;核心服务停止很多时候就是在系统更新重启后发生的。所以监控系统更新也是个比较重要的事情。&lt;/p&gt;
&lt;p&gt;本想着将这个功能添加到现在的c#代码中，但是奈何powershell太好用了，所以还是算了，直接用powershell，现在做个记录。&lt;/p&gt;
&lt;p&gt;下面是一句话脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -AutoReboot -SendReport -SendHistory -PSWUSettings @{SmtpServer=&quot;smtp.mysmtpserver.com&quot;;From=&quot;auto-windowsupdate@mydomain.com&quot;;To=&quot;myemailaddress&quot;;Port=25} -Verbose
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然前提是要安装下下面的模块。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Install-Module -Name PSWindowsUpdate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完整的我就不重复了。这个只是记录。&lt;/p&gt;
</content:encoded></item><item><title>add-domain-user-into-ad-security-group-api</title><link>https://dididudu998.github.io/posts/add-security-members-into-ad-group-api/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/add-security-members-into-ad-group-api/</guid><pubDate>Wed, 01 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;获得一个简单需求，要能够比较简单的将一些用户添加到安全组里面去，然后根据规则，对这个安全组的人员的网络进行限制。&lt;/p&gt;
&lt;p&gt;大概用了2个小时的时间完成整个工作。&lt;/p&gt;
&lt;p&gt;主要思路就是提供一个api，然后按照add，delete，list这样的动作来进行添加，删除和列表这个安全组的成员。&lt;/p&gt;
&lt;p&gt;用法：
添加：https://server/add?user=user1
删除：https://server/delete?user=user1
列表：https://server/list&lt;/p&gt;
&lt;p&gt;用的是golang实现。&lt;/p&gt;
&lt;p&gt;代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
package main

  

import (

    &quot;crypto/tls&quot;

    &quot;fmt&quot;

    &quot;io&quot;

    &quot;log&quot;

    &quot;net&quot;

    &quot;net/http&quot;

    &quot;os&quot;

    &quot;path/filepath&quot;

    &quot;strings&quot;

    &quot;time&quot;

  

    &quot;github.com/gin-gonic/gin&quot;

    &quot;github.com/go-ldap/ldap/v3&quot;

)

  
//定义连接参数

const (

    adServer    = &quot;ldaps://domaincontroller:636&quot;

    adUser      = &quot;account@example.com&quot;

    adPassword  = &quot;xxxxxx&quot;

    adGroupDN   = &quot;CN=limited_sc,OU=Groups,dc=example,dc=com&quot;

    logDir      = &quot;logs&quot;

    logFile     = &quot;add-netid-into-vpn-group.log&quot;

    certFile    = &quot;server.crt&quot;

    keyFile     = &quot;server.key&quot;

    port        = &quot;:443&quot;

    ldapTimeout = 10 * time.Second

)

  

// Add this init function at the beginning of the file

func init() {

    // Create logs directory if it doesn&apos;t exist

    if err := os.MkdirAll(logDir, 0755); err != nil {

        log.Fatalf(&quot;Failed to create log directory: %v&quot;, err)

    }

  

    // Open log file with append mode

    logPath := filepath.Join(logDir, logFile)

    file, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)

    if err != nil {

        log.Fatalf(&quot;Failed to open log file: %v&quot;, err)

    }

  

    // Set stdout to be unbuffered

  

  

    // Use MultiWriter to write to both file and console

    

  

}

  

// Update the logAction function to include both file logging and console output

func logAction(clientIP, action, details string) {

    ....
        timestamp, clientIP, action, details)

  

    //log.Print(logMessage)

  

    // Flush the output to ensure it appears immediately

    if f, ok := log.Writer().(*os.File); ok {

        f.Sync() // Ensure the output is flushed

    } else {

        // If log.Writer() is not a file, we can use log.Output to flush

        log.Output(2, logMessage) // Adjust the call to ensure immediate output

    }

}

  

func isIPAllowed(ipStr string) bool {

    // Handle empty IP

    if ipStr == &quot;&quot; {

        return false

    }

  

    allowedNetwork := &quot;192.168.10.0/23&quot; // or your specific network

    ip := net.ParseIP(ipStr)

    if ip == nil {

        log.Printf(&quot;Failed to parse IP: %s&quot;, ipStr)

        return false

    }

  

    _, subnet, err := net.ParseCIDR(allowedNetwork)

    if err != nil {

        log.Printf(&quot;Failed to parse CIDR: %v&quot;, err)

        return false

    }

  

    return subnet.Contains(ip)

}

  

func dialLDAP() (*ldap.Conn, error) {

    dialer := &amp;amp;net.Dialer{Timeout: ldapTimeout}

    conn, err := ldap.DialURL(

        adServer,

        ldap.DialWithDialer(dialer),

        ldap.DialWithTLSConfig(&amp;amp;tls.Config{InsecureSkipVerify: true}),

    )

    if err != nil {

        return nil, fmt.Errorf(&quot;failed to connect to AD: %v&quot;, err)

    }

    return conn, nil

}

  

func listGroupMembers() ([]string, error) {

    conn, err := dialLDAP()

    if err != nil {

        return nil, fmt.Errorf(&quot;failed to connect to AD: %v&quot;, err)

    }

    defer conn.Close()

  

    err = conn.Bind(adUser, adPassword)

    if err != nil {

        return nil, fmt.Errorf(&quot;failed to bind to AD: %v&quot;, err)

    }

  

    searchRequest := ldap.NewSearchRequest(

        ....
        nil,

    )

  

    result, err := conn.Search(searchRequest)

    if err != nil {

        return nil, fmt.Errorf(&quot;failed to search group: %v&quot;, err)

    }

  

    if len(result.Entries) == 0 {

        return nil, fmt.Errorf(&quot;group not found&quot;)

    }

  

    members := []string{}

    for _, member := range result.Entries[0].GetAttributeValues(&quot;member&quot;) {

        // Extract CN from DN

        cn := strings.Split(member, &quot;,&quot;)[0]

        cn = strings.TrimPrefix(cn, &quot;CN=&quot;)

        members = append(members, cn)

    }

  

    return members, nil

}

  

func addUserToGroup(userDN string) error {

    conn, err := dialLDAP()

    if err != nil {

        return err

    }

    defer conn.Close()

  

    err = conn.Bind(adUser, adPassword)

    if err != nil {

        return fmt.Errorf(&quot;failed to bind to AD: %v&quot;, err)

    }

  

    modifyReq := ldap.NewModifyRequest(adGroupDN, nil)

    modifyReq.Add(&quot;member&quot;, []string{userDN})

  

    // 使用普通的 Modify 方法，因为 ModifyWithContext 不可用

    err = conn.Modify(modifyReq)

    if err != nil {

        return fmt.Errorf(&quot;failed to add user to group: %v&quot;, err)

    }

  

    return nil

}

  

func removeUserFromGroup(userDN string) error {

    conn, err := dialLDAP()

    if err != nil {

        return err

    }

    defer conn.Close()

  

    err = conn.Bind(adUser, adPassword)

    if err != nil {

        return fmt.Errorf(&quot;failed to bind to AD: %v&quot;, err)

    }

  

    modifyReq := ldap.NewModifyRequest(adGroupDN, nil)

    modifyReq.Delete(&quot;member&quot;, []string{userDN})

  

    // 使用普通的 Modify 方法，而不是 ModifyWithContext

    err = conn.Modify(modifyReq)

    if err != nil {

        return fmt.Errorf(&quot;failed to remove user from group: %v&quot;, err)

    }

  

    return nil

}

  

// Add this type for error response

type ErrorResponse struct {

    Error   string `json:&quot;error&quot;`

    Time    string `json:&quot;time&quot;`

    Details string `json:&quot;details&quot;`

}

  

// Add middleware for IP checking

func checkIPMiddleware() gin.HandlerFunc {

    return func(c *gin.Context) {

        // Try X-Real-IP header first

        ....
            }

        }

  

        // If no proxy headers, use RemoteAddr

        if ip == &quot;&quot; {

            ip = c.ClientIP()

        }

  

        ip = strings.TrimSpace(ip)

  

        if !isIPAllowed(ip) {

            c.JSON(http.StatusForbidden, ErrorResponse{

                Error:   &quot;Access Denied&quot;,

                Time:    time.Now().Format(&quot;2006-01-02 15:04:05&quot;),

                Details: fmt.Sprintf(&quot;IP %s is not allowed to access this service&quot;, ip),

            })

            logAction(ip, &quot;ACCESS_DENIED&quot;, fmt.Sprintf(&quot;Attempted access from unauthorized IP: %s&quot;, ip))

            c.Abort()

            return

        }

        c.Next()

    }

}

  

// Update main function to use Gin

func main() {

    // Set Gin to release mode

    gin.SetMode(gin.ReleaseMode)

  

    r := gin.New()

    // Use Recovery middleware

    r.Use(gin.Recovery())

    // Apply IP check middleware to all routes

    r.Use(checkIPMiddleware())

  

    // Add endpoint

    r.GET(&quot;/add&quot;, func(c *gin.Context) {

        clientIP := c.ClientIP()

        userAccount := c.Query(&quot;user&quot;)

  

        if userAccount == &quot;&quot; {

            ....
            })

            return

        }

  

        userDN := fmt.Sprintf(&quot;CN=%s,dc=example,dc=com&quot;, userAccount)

        ....
            })

            return

        }

  

        logAction(clientIP, &quot;ADD_SUCCESS&quot;, fmt.Sprintf(&quot;user: %s&quot;, userAccount))

        c.String(http.StatusOK, &quot;user %s added successfully&quot;, userAccount)

    })

  

    // List endpoint

    r.GET(&quot;/list&quot;, func(c *gin.Context) {

        clientIP := c.ClientIP()

        members, err := listGroupMembers()

        if err != nil {

            .....
            })

            return

        }

  

        logAction(clientIP, &quot;LIST&quot;, fmt.Sprintf(&quot;total members: %d&quot;, len(members)))

        c.JSON(http.StatusOK, members)

    })

  

    // Delete endpoint

    r.GET(&quot;/delete&quot;, func(c *gin.Context) {

        clientIP := c.ClientIP()

        userAccount := c.Query(&quot;user&quot;)

  

        if userAccount == &quot;&quot; {

            c.JSON(http.StatusBadRequest, ErrorResponse{

                .....

            })

            return

        }

  

        userDN := fmt.Sprintf(&quot;CN=%s,dc=example,dc=com&quot;, userAccount)

        if err := removeUserFromGroup(userDN); err != nil {

          ....

          Details: err.Error(),

            })

            return

        }

  

        logAction(clientIP, &quot;DELETE_SUCCESS&quot;, fmt.Sprintf(&quot;user: %s&quot;, userAccount))

        c.String(http.StatusOK, &quot;user %s removed successfully&quot;, userAccount)

    })

  

    // Get certificate paths

    exePath, err := os.Executable()
	....
   

    // Check certificate files
	....
    

    
  

    // Log startup information

    log.Printf(&quot;Starting HTTPS server on port %s&quot;, port)

    log.Printf(&quot;Using certificate: %s&quot;, certPath)

    log.Printf(&quot;Using private key: %s&quot;, keyPath)

  

    // Start HTTPS server

    if err := r.RunTLS(port, certPath, keyPath); err != nil {

        log.Fatalf(&quot;Failed to start HTTPS server: %v&quot;, err)

    }

}

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>以一种访问权限不允许的方式做了一个访问套接字的尝试</title><link>https://dididudu998.github.io/posts/%E4%BB%A5%E4%B8%80%E7%A7%8D%E8%AE%BF%E9%97%AE%E6%9D%83%E9%99%90%E4%B8%8D%E5%85%81%E8%AE%B8%E7%9A%84%E6%96%B9%E5%BC%8F%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%E8%AE%BF%E9%97%AE%E5%A5%97%E6%8E%A5%E5%AD%97%E7%9A%84%E5%B0%9D%E8%AF%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BB%A5%E4%B8%80%E7%A7%8D%E8%AE%BF%E9%97%AE%E6%9D%83%E9%99%90%E4%B8%8D%E5%85%81%E8%AE%B8%E7%9A%84%E6%96%B9%E5%BC%8F%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%E8%AE%BF%E9%97%AE%E5%A5%97%E6%8E%A5%E5%AD%97%E7%9A%84%E5%B0%9D%E8%AF%95/</guid><pubDate>Thu, 19 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;昨天还运行的挺好的一个python文件，今天就出这个错误了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dashboard.run_server(debug=True, host=&apos;0.0.0.0&apos;, port=8050)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;什么都没变。莫名的问题。&lt;/p&gt;
&lt;p&gt;用netstat -an ｜findstr 8050也没找到哪个进程在使用这个端口
后来找到这个文档：https://github.com/localsend/localsend/discussions/935&lt;/p&gt;
&lt;p&gt;我这边运行netsh interface ipv4 show excludedportrange protocol=tcp的结果如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Protocol tcp Port Exclusion Ranges

Start Port    End Port
----------    --------
      1203        1302
      1697        1796
      3711        3810
      3811        3910
      4111        4210
      4295        4394
      5357        5357
      7994        8093
      8099        8198
     14867       14966
     28385       28385
     28390       28390
     50000       50059     *

* - Administered port exclusions.

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;8050在7994到8093之间，换了个端口8094，好了。&lt;/p&gt;
&lt;p&gt;可是这个是为什么呢？不懂了。&lt;/p&gt;
</content:encoded></item><item><title>linux中的虚拟网卡</title><link>https://dididudu998.github.io/posts/linux%E4%B8%AD%E7%9A%84%E8%99%9A%E6%8B%9F%E7%BD%91%E5%8D%A1/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/linux%E4%B8%AD%E7%9A%84%E8%99%9A%E6%8B%9F%E7%BD%91%E5%8D%A1/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Wed, 23 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;容器中会使用linux的虚拟网卡，那么这个虚拟网卡怎么来的？多个容器之间又是怎么通讯的？下面会给出说明。&lt;/p&gt;
&lt;h1&gt;单独的虚拟网卡&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;创建一个新的网络命名空间net1
&lt;ul&gt;
&lt;li&gt;ip netns add net1&lt;/li&gt;
&lt;li&gt;检查网络空间的link状态
&lt;ul&gt;
&lt;li&gt;ip netns exec net1 ip link list&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;创建一对虚拟网卡，将一端添加到net1中
&lt;ul&gt;
&lt;li&gt;ip link add veth1 type veth peer name veth1_p&lt;/li&gt;
&lt;li&gt;ip link set veth1 netns net1&lt;/li&gt;
&lt;li&gt;执行完毕后，veth1将被添加到net1的空间中，在宿主机只能看到veth1_p了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;分别给这虚拟网卡两端配置上ip地址，然后up起来
&lt;ul&gt;
&lt;li&gt;ip addr add 192.168.0.100/24 dev veth1_p&lt;/li&gt;
&lt;li&gt;ip netns exec net1 ip addr add 192.168.0.101/24 dev veth1&lt;/li&gt;
&lt;li&gt;ip link set dev veth1_p up&lt;/li&gt;
&lt;li&gt;ip netns exec net1 ip link set dev veth1 up&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;检查veth1的配置和veth1_p的配置
&lt;ul&gt;
&lt;li&gt;ip netns exec net1 ifconfig&lt;/li&gt;
&lt;li&gt;ifconfig&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;检查宿主机到net1中的veth1的通讯
&lt;ul&gt;
&lt;li&gt;ip netns exec net1 ping 192.168.0.100 -I veth1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;多个虚拟网卡&lt;/h1&gt;
&lt;p&gt;多个虚拟网卡的操作和单个的步骤是一样的，无非是创建多个网络命名空间，net1，net2，net3等等。但是我们不仅要让宿主机和容器内的虚拟网卡通讯，我们还需要容器之间保证网络通讯，更重要的是我们需要在一个宿主机上面创建大量的网络空间和虚拟网卡，为了简化配置，我们需要使用网桥，将不同的网络空间中的虚拟网卡的一端都挂载在同一个网桥上面，利用网桥的转发功能来实现这些虚拟网卡的通讯。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;确保安装了网桥工具
&lt;ul&gt;
&lt;li&gt;dnf install bridge-utils -y&lt;/li&gt;
&lt;li&gt;apt install bridge-utils -y&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;和创建单个虚拟网卡的过程一样，分别创建veth1，veth1_p和veth2，veth2_p两对虚拟网卡，分别对应两个网络命名空间net1和net2&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;ip netns add net1
ip link add veth1 type veth peer name veth1_p
ip link set veth1 netns net1
ip netns exec net1 ip addr add 192.168.0.101/24 dev veth1
ip netns exec net1 ip link set veth1 up
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;分别配置veth1和veth2的IP地址为192.168.0.101/24,192.168.0.102/24并启用虚拟网卡&lt;/li&gt;
&lt;li&gt;此时这两个虚拟网卡是各自独立的，互相是不能访问的&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;ip netns exec net2 ping 192.168.0.101 -I veth2
PING 192.168.0.101 (192.168.0.101) from 192.168.0.102 veth2: 56(84) bytes of data.
2 packets transmitted, 0 received, 100% packet loss, time 1054ms
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ip netns exec net1 ping 192.168.0.102 -I veth1
PING 192.168.0.102 (192.168.0.102) from 192.168.0.101 veth1: 56(84) bytes of data.
^C
--- 192.168.0.102 ping statistics ---
15 packets transmitted, 0 received, 100% packet loss, time 14363ms
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;开始创建网桥，设定网桥IP，并将p头插入到网桥中
&lt;ul&gt;
&lt;li&gt;brctl addbr br0&lt;/li&gt;
&lt;li&gt;ip link set dev veth1_p master br0&lt;/li&gt;
&lt;li&gt;ip link set dev veth2_p master br0&lt;/li&gt;
&lt;li&gt;ip addr add 192.168.0.100/24 dev br0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;启动插入网桥的p头以及网桥本身
&lt;ul&gt;
&lt;li&gt;ip link set veth1_p up&lt;/li&gt;
&lt;li&gt;ip link set veth2_p up&lt;/li&gt;
&lt;li&gt;ip link set br0 up&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;检查网桥状态和虚拟网卡的通讯
&lt;ul&gt;
&lt;li&gt;brctl show&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;bridge name	bridge id		STP enabled	interfaces
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;br0		8000.ca0127d574d8	no		veth1_p
veth2_p
&lt;code&gt; 	- ip netns exec net1 ping 192.168.0.102 -I veth1 	&lt;/code&gt;bash
ip netns exec net1 ping 192.168.0.102 -I veth1
PING 192.168.0.102 (192.168.0.102) from 192.168.0.101 veth1: 56(84) bytes of data.
64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=0.091 ms
64 bytes from 192.168.0.102: icmp_seq=3 ttl=64 time=0.075 ms
64 bytes from 192.168.0.102: icmp_seq=4 ttl=64 time=0.087 ms
64 bytes from 192.168.0.102: icmp_seq=5 ttl=64 time=0.076 ms
^C
--- 192.168.0.102 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4096ms&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;	- 发现已经通了。
- 如果要删除网桥
	- 先停用已经启动的接口和网桥
		- ip link set veth1_p down
		- ip link set veth2_p down
		- ip link set br0 down
	- 删除网桥
		- brctl delbr br0
	- 再启用p头，恢复原始状态
		- ip set link veth1_p up
		- ip set link veth2_p up

# 总结

这下应该清楚，虚拟网卡的目的是为了隔离网络，为容器服务。那么首先要有一个独立的网络命名空间，然后创建出一对虚拟网卡。将其中的一个加入到对应的网络命名空间，然后分别设置对应的IP地址，就可以通过宿主机访问该虚拟网络。

但是此时两个容器之间是不通的。即使你创建出新的虚拟网卡对，加入到同一个网络命名空间中，设定同一段IP地址，也是不通的。

要想容器间通讯，需要增加网桥，并且配置合适的地址。&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>在Windows sandbox里使用宿主机的代理服务器联网</title><link>https://dididudu998.github.io/posts/windows-sandbox%E4%BD%BF%E7%94%A8%E4%B8%BB%E6%9C%BA%E7%9A%84%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windows-sandbox%E4%BD%BF%E7%94%A8%E4%B8%BB%E6%9C%BA%E7%9A%84%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 16 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;主要是为了安全的考虑，还有安装windows sandbox的原因是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;现在用的笔记本是windows的&lt;/li&gt;
&lt;li&gt;虽然也装了vmware workstation，但是单装一个OS虚拟机也要10个GB左右，而我只需要浏览器就可以，所以没必要用虚拟机&lt;/li&gt;
&lt;li&gt;windows sandbox装起来很快，不费事&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;运行，optionalfeatures，选择windows sandbox，然后安装，需要重启，重启完成后，就是安装成功了。&lt;/p&gt;
&lt;p&gt;由于我本地的代理服务器端口是7897，先开启它的局域网代理模式，允许sandbox使用的default switch使用该端口。&lt;/p&gt;
&lt;p&gt;参考了这篇文章：&lt;a href=&quot;https://juejin.cn/post/7362057701792727076&quot;&gt;Hyper-V之二:Sandbox除错Windows 沙盒的各种 bug ,比如傻傻的复制本地网络导致无法联网,本来应该 - 掘金 (juejin.cn)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后创建一个mysandbox.wsb文件，内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Configuration&amp;gt;
  &amp;lt;MappedFolders&amp;gt;
    &amp;lt;MappedFolder&amp;gt;
      &amp;lt;HostFolder&amp;gt;D:\my-sandbox-folder&amp;lt;/HostFolder&amp;gt;
      &amp;lt;SandboxFolder&amp;gt;C:\Users\WDAGUtilityAccount\Downloads&amp;lt;/SandboxFolder&amp;gt;
      &amp;lt;ReadOnly&amp;gt;false&amp;lt;/ReadOnly&amp;gt;
    &amp;lt;/MappedFolder&amp;gt;
  &amp;lt;/MappedFolders&amp;gt;
  &amp;lt;LogonCommand&amp;gt;
    &amp;lt;Command&amp;gt;C:\Users\WDAGUtilityAccount\Downloads\start.bat&amp;lt;/Command&amp;gt;
  &amp;lt;/LogonCommand&amp;gt;
&amp;lt;/Configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个文件的意思是：我要将我宿主机的D:\my-sandbox-folder目录映射到sandbox的C:\Users\WDAGUtilityAccount\Downloads目录。然后我还要运行一个登录命令，这个登录命令使用的文件是：C:\Users\WDAGUtilityAccount\Downloads\start.bat。&lt;/p&gt;
&lt;p&gt;其实就是在宿主机的D:\my-sandbox-folder下面创建一个start.bat文件，文件内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for /f &quot;tokens=13&quot; %%i in (&apos;ipconfig ^| findstr /i &quot;Gateway&quot;&apos;) do set ip=%%i
netsh interface portproxy add v4tov4 listenaddress=localhost listenport=7897 connectaddress=%ip% connectport=7897
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的批处理命令的意思解释如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;findstr /i &quot;Gateway&quot; 用于筛选出包含“Gateway”这个关键词的行，/i 表示不区分大小写&lt;/li&gt;
&lt;li&gt;for /f &quot;tokens=13&quot; %%i in (...) 用于处理命令输出。tokens=13 表示提取输出的第13个字段，这通常是默认网关的IP地址。&lt;/li&gt;
&lt;li&gt;set ip=%%i 将提取到的IP地址存储在环境变量 ip 中。&lt;/li&gt;
&lt;li&gt;netsh interface portproxy add v4tov4 是用来添加一个IPv4到IPv4的端口代理。&lt;/li&gt;
&lt;li&gt;listenaddress=localhost 指定代理监听在本地地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;listenport=7897&lt;/code&gt; 指定监听的端口号为7897。&lt;/li&gt;
&lt;li&gt;connectaddress=%ip% 使用之前提取的默认网关IP地址作为连接地址。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;connectport=7897&lt;/code&gt; 指定连接的目标端口为7897。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;整个脚本的作用是设置一个端口代理，使得所有发送到本地7897端口的流量都被转发到默认网关的7897端口。&lt;/p&gt;
&lt;p&gt;当你看到sandbox的网络代理的时候发现是127.0.0.1:7897,但是实际上是发送到sandbox的网关的7897端口去了，也就是我们宿主机的代理端口上去了。&lt;/p&gt;
&lt;p&gt;然后最重要的是打开宿主机的防火墙，创建一条incoming的规则，允许到宿主机的TCP 7897端口访问。&lt;/p&gt;
&lt;p&gt;好了。现在返回到最早创建的mysandbox.wsb，双击它，就可以启动我们设定的沙盒了。&lt;/p&gt;
&lt;p&gt;启动后，打开沙盒里面的edge浏览器，访问下站点，到代理服务器上看看日志，就能看到确实是通过代理访问出去了。&lt;/p&gt;
&lt;p&gt;至此，完成了。&lt;/p&gt;
</content:encoded></item><item><title>自动拨入Cisco anyconnect</title><link>https://dididudu998.github.io/posts/%E8%87%AA%E5%8A%A8%E6%8B%A8%E5%85%A5cisco-anyconnect/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%87%AA%E5%8A%A8%E6%8B%A8%E5%85%A5cisco-anyconnect/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 17 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;昨天台风，发了邮件通知，说在家办公，这个时候需要拨VPN。我以前用的mac电脑，直接一个脚本就上去了。但是现在换成windows了，配置了openconnect的gui，记得前些时候试过了都是可以的，但是昨天怎么地都连不上，不知道什么问题。只好下载Cisco的anyconnect客户端，手动连接了。&lt;/p&gt;
&lt;p&gt;这玩意有个毛病，也可能是服务端配置的问题，不能自动记录密码。而且学校这边是两个密码，再加上一个手机上面的Duo，而密码呢又是复杂性的，长度又很长，我一般不记密码，记不住啊。所以只好想办法在windows上做个自动连接的脚本，减少手动的输入麻烦。&lt;/p&gt;
&lt;p&gt;用了两种方法，一种是powershell的，一种是python的。分别如下，主要是测试的时候，这个拉起anyconnect后，焦点的问题，不是直接放到连接按钮上的，所以前面测试搞了好几次tab。用python就好点，因为调试好了。&lt;/p&gt;
&lt;p&gt;下面的是powershell的脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 加载 Windows Forms 库

Add-Type -AssemblyName System.Windows.Forms

  

# 用户名，vpn地址都已经自动保存在profile里面了，所以不用输入

# C:\Users\Mark\appdata\Local\Cisco\Cisco Secure Client\VPN\preferences.xml

$password = &quot;mypassword&quot;

$secondPassword = &quot;push&quot;  # 第二个密码

  

# 启动 Cisco AnyConnect

Start-Process &quot;C:\Program Files (x86)\Cisco\Cisco Secure Client\UI\csc_ui.exe&quot;

# 等待 AnyConnect 启动

Start-Sleep -Seconds 5

# 等待连接窗口加载
# 由于程序打开后，默认的焦点不在连接button上，所以使用3个tab定位到连接button，然后按下enter

&amp;lt;#

[System.Windows.Forms.SendKeys]::SendWait(&quot;{TAB}&quot;)

[System.Windows.Forms.SendKeys]::SendWait(&quot;{TAB}&quot;)

[System.Windows.Forms.SendKeys]::SendWait(&quot;{TAB}&quot;)

#&amp;gt; 

[System.Windows.Forms.SendKeys]::SendWait(&quot;{ENTER}&quot;)
Start-Sleep -Seconds 2

# 输入密码和二次密码

# 输入密码

[System.Windows.Forms.SendKeys]::SendWait(&quot;$password&quot;)

[System.Windows.Forms.SendKeys]::SendWait(&quot;{TAB}&quot;)

  

# 输入第二个密码

[System.Windows.Forms.SendKeys]::SendWait(&quot;$secondPassword&quot;)

[System.Windows.Forms.SendKeys]::SendWait(&quot;{ENTER}&quot;)

  

# 等待Duo确认

Start-Sleep -Seconds 10

[System.Windows.Forms.SendKeys]::SendWait(&quot;{ENTER}&quot;)
  

Write-Host &quot;VPN 连接请求已发送，等待连接完成&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是python的脚本:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&apos;&apos;&apos;

File: auto-anyconnect.py

File Created: Tuesday, 16th September 2024 10:43:02 am

Author: Mark S

-----

Last Modified: Tuesday, 16th September 2024 10:45:05 am

Modified By: Mark S

-----

Copyright MarkShi

&apos;&apos;&apos;

  

import pyautogui

import subprocess

import time

  

# 定义密码

password = &quot;mypassword&quot;

second_password = &quot;push&quot;


# 启动 Cisco AnyConnect

subprocess.Popen(r&apos;&quot;C:\Program Files (x86)\Cisco\Cisco Secure Client\UI\csc_ui.exe&quot;&apos;)

  

# 等待 AnyConnect 启动

time.sleep(5)

pyautogui.press(&apos;enter&apos;)

# 等待连接窗口加载

time.sleep(2)
  

# 输入密码

pyautogui.typewrite(password)

pyautogui.press(&apos;tab&apos;)

  

# 输入第二个密码

pyautogui.typewrite(second_password)

pyautogui.press(&apos;enter&apos;)

  

# 等待Duo连接完成

time.sleep(15)

# 这里再手机上确认后，还有一个点击确认的按钮的步骤，直接电脑操作了，因为duo这个绕不过去，必须人在手机上点

print(&quot;VPN 连接请求已发送。&quot;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>RDP复制粘贴经常失效的问题</title><link>https://dididudu998.github.io/posts/rdp%E7%BB%8F%E5%B8%B8%E5%A4%8D%E5%88%B6%E7%B2%98%E8%B4%B4%E4%B8%8D%E8%83%BD%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/rdp%E7%BB%8F%E5%B8%B8%E5%A4%8D%E5%88%B6%E7%B2%98%E8%B4%B4%E4%B8%8D%E8%83%BD%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Wed, 17 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;换了Windows电脑后，由于屏幕是OLED的，亮度和显示的感觉明显没有MacBook Pro的顺眼。所以还是用MacBook作为主要的使用，需要的时候用RDP连接到Windows的笔记本。&lt;/p&gt;
&lt;p&gt;这样就经常需要来回的复制数据。这台MacBook在和其他的windows电脑使用远程桌面的时用复制粘贴都没有问题，但是和这台新的笔记本，经常性的无法复制粘贴。&lt;/p&gt;
&lt;p&gt;在Google上搜了下，好像很多人碰到说在升级了RDP软件后，就会出现从Mac到Windows连接时碰到这样的问题，说是降级RDP到旧版本就可以解决。&lt;/p&gt;
&lt;p&gt;这真是麻烦了。&lt;/p&gt;
&lt;p&gt;但是我在想，并不是一直都这样的，十次有那么一两次是可以复制粘贴的。&lt;/p&gt;
&lt;p&gt;或许是其他方面的问题，就在我用windows的时候，发现我使用的sinpDo软件，这个是一个给鼠标带来快捷操作的小软件，里面默认开启了复制粘贴等动作，我在想是否是因为这个原因导致某种冲突，进而导致跨RDP的复制无法实现了。&lt;/p&gt;
&lt;p&gt;进到snipDo的设置里面，去掉复制粘贴的动作。然后重新从Mac远程桌面进入到Windows，再试了下复制粘贴，可以了。然后运行了半天，复制粘贴没有失败了。&lt;/p&gt;
&lt;p&gt;所以当出现问题的时候，要多想想。：）&lt;/p&gt;
</content:encoded></item><item><title>alias in Windows11 like shell</title><link>https://dididudu998.github.io/posts/doskey-in-windows-11/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/doskey-in-windows-11/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 01 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;从苹果的MacBook Pro换到Windows笔记本了，是华硕的ROG 幻16Air。这机器的硬件还凑合，但是发热有点大了，C面的上部分即使日常办公也非常的烫，而且什么A面的灯光对我来说一点意义都没有。用了Ghelper管理，直接就关了。还有最大的问题就是屏幕，我怎么调都觉得不适应，和MacBook的屏幕简直无法比较。OLED的这种，调太亮了伤眼，调暗了更伤眼。实在是很难受了。&lt;/p&gt;
&lt;p&gt;回到正题，在MacBook上用的shell是zsh和fish，都配置了profile，里面加上了很多的alias，这下换到Windows，也想保持这些alias，经过查找，按照下面的方式实现了这个需求。&lt;/p&gt;
&lt;h2&gt;步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;创建一个bat文件，这里我直接在C盘根目录创建了autoexec.bat文件，内容如下所示：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;@echo off
doskey gitblit=python C:\cursor-codes\在windows上设置gitblit的地址\set-gitblit-ip-in-hosts.py
doskey adguard=C:\AdGuardHome\AdGuardHome.exe
doskey weibo=python D:\MacOS-下载文件\weibocrawl\weibo-crawler\weibo.py
doskey finfo=python C:\my_shell\show-my-specific-files-in-webpage-adv.py
doskey paper=python C:\my_validate\获取arxiv的论文\get_paper.py 
doskey gugong=cd c:\程序原型与设想init\台湾故宫博物馆
doskey daying=cd c:\程序原型与设想init\爬取大英博物馆油画
doskey icon=cd c:\程序原型与设想init\生成固定大小的图片用于icon
doskey tangshi=c:\程序原型与设想init\从数据库中查询唐诗宋词\tangshisongci.exe
doskey syncthing=&quot;C:\Program Files\Syncthing\syncthing.exe&quot;
doskey notepad=&quot;C:\Program Files\Notepad++\notepad++.exe&quot; $*
doskey myip=c:\my_shell\get_public_ip_windows.cmd
...
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在注册表中创建对应的启动项&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]
&quot;CompletionChar&quot;=dword:00000009
&quot;DefaultColor&quot;=dword:00000000
&quot;EnableExtensions&quot;=dword:00000001
&quot;PathCompletionChar&quot;=dword:00000009
&quot;Autorun&quot;=&quot;c:\\autoexec.bat&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样在系统重启后，这个autoexec.bat会被执行，执行后，上面doskey建立的alias就可以在命令行窗口中直接运行了。&lt;/p&gt;
</content:encoded></item><item><title>mailx使用外部smtp服务器</title><link>https://dididudu998.github.io/posts/mailx%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8smtp%E6%9C%8D%E5%8A%A1%E5%99%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/mailx%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8smtp%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 17 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在Ubuntu中使用unattended-upgrades服务的时候，有一个发送notify的选项，就是在安装了unattended-upgrades服务后，在/etc/apt/apt.conf.d/50unattended-upgrade这个文件中，编辑Unattended-Upgrade::Mail &quot;myemailaddress&quot;;这个栏目。&lt;/p&gt;
&lt;p&gt;但是这个由于比较基础，必须使用mailx或者mail来进行发送邮件，不支持使用别的替代方案。所以需要配置下mailx使用已有的smtp服务器来实现对外发送邮件的目的。&lt;/p&gt;
&lt;p&gt;需要在当前用户目录下新建一个文件“～/.mailrc&quot;.&lt;/p&gt;
&lt;p&gt;如果需要使用TLS的话，还得建立一下证书数据库：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir ~/.certs
certutil -N -d ~/.certs
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# external smtp server
set smtp-use-starttls #如果需要的话
set ssl-verify=ignore
set nss-config-dir=/home/user/.certs # 如果需要的话
set smtp=&quot;smtp://smtp.server:port&quot;   # smtp://smtp.gmail.com:587, smtp://mail.company.net:25
set smtp-auth=login
set smtp-auth-user=&quot;user@domain.ltd&quot;
set smtp-auth-password=&quot;S3cr37&quot;
set from=&quot;whoami@server.com(My Name)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上的配置如果完成后，先测试下发送给自己的外网邮箱，看看是不是可以了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;hello&quot; | mail -s &quot;test&quot; abc@abc.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果可行了，那么再试试自动升级的邮件提醒是不是可以了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unattented-upgrade --debug
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>检查linux中已安装的包</title><link>https://dididudu998.github.io/posts/%E6%A3%80%E6%9F%A5linux%E4%B8%AD%E5%B7%B2%E5%AE%89%E8%A3%85%E7%9A%84%E5%8C%85/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%A3%80%E6%9F%A5linux%E4%B8%AD%E5%B7%B2%E5%AE%89%E8%A3%85%E7%9A%84%E5%8C%85/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Sun, 26 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Ubuntu&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo apt list --installed
sudo apt list --installed |grep chrome
dpkg --get-selections
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;RedHat&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;rpm -qa
rpm -qa |grep chrome
yum list installed
dnf list installed
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>CentOS7 to RedHat8</title><link>https://dididudu998.github.io/posts/centos7-to-redhat8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/centos7-to-redhat8/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 24 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;按照文档的说法应该是很方便的，但是实际上老的系统并不纯净，导致很多折腾。现在记录下整个的过程，提前的备份工作不谈：&lt;/p&gt;
&lt;h2&gt;CentOS7 to RedHat7&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;准备redhat7.9的ISO，这样会方便一些&lt;/li&gt;
&lt;li&gt;安装convert2rhel工具&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;curl -o /etc/yum.repos.d/convert2rhel.repo https://ftp.redhat.com/redhat/convert2rhel/7/convert2rhel.repo
yum repoinfo convert2rhel-for-rhel-7-rpms
yum install -y convert2rhel
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;创建一个挂载点，挂起来，然后创建一个新的Repo。将当前的所有的repo都放到一个单独的文件夹里面。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  mkdir -p /mnt/redhat79
  mount -o loop rhel-server-7.9-x86_64-dvd.iso /mnt/redhat79/
  cd /etc/yum.repos.d
  mkdir repo_backup &amp;amp;&amp;amp; move *.repo ./repo_backup
  cat &amp;gt;rhel.repo &amp;lt;&amp;lt;EOF
  [RHEL7]
  name=Red Hat Enterprise Linux 7
  baseurl=file:///mnt/redhat79
  enabled=1
  EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;进行转化&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;convert2rhel --disable-submgr --disablerepo=* --enablerepo=RHEL7 -y --no-rpm-va
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;这个过程中可能会提示你要做一些参数的设定之类的事，例如&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;export CONVERT2RHEL_ALLOW_UNAVAILABLE_KMODS=1
export CONVERT2RHEL_OUTDATED_PACKAGE_CHECK_SKIP=1
export CONVERT2RHEL_TAINTED_KERNEL_MODULE_CHECK_SKIP=1
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;根据提示，设定后，继续运行4中的转化语句即可&lt;/li&gt;
&lt;li&gt;转化完成后，检查下 cat /etc/os-release到Red Hat 7.9即可&lt;/li&gt;
&lt;li&gt;然后重启下，确保系统可以正常使用&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;RedHat7 到 RedHat8&lt;/h2&gt;
&lt;p&gt;RedHat7.9也是在2024年6月30日就不再支持了，所以还得继续升级。很多时候看到文档说升级到RedHat8需要注册，其实升级本身不需要注册，只是以后要用起来需要。下面是以离线的方式做的整个过程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;到RedHat网站下载最新的RedHat8 ISO下来&lt;/li&gt;
&lt;li&gt;参考这个页面：&lt;/li&gt;
&lt;li&gt;https://access.redhat.com/zh_CN/solutions/7035235&lt;/li&gt;
&lt;li&gt;可以直接下载依赖项，也可以从ISO进行操作，参看这个：https://access.redhat.com/solutions/5492401&lt;/li&gt;
&lt;li&gt;下面的是笨办法：
&amp;lt;p&amp;gt;从&amp;lt;a href=&quot;https://access.redhat.com/downloads/content/69/ver=/rhel---7/7.9/x86_64/packages&quot;&amp;gt;红帽客户门户网站&amp;lt;/a&amp;gt;下载软件包及其依赖项&amp;lt;br /&amp;gt;
&amp;lt;p&amp;gt;以下是软件包及其依赖项列表：&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;audit
audit-libs
audit-libs-python&lt;br /&gt;
checkpolicy&lt;br /&gt;
dnf
dnf-data
json-glib&lt;br /&gt;
leapp&lt;br /&gt;
leapp-deps
leapp-upgrade-el7toel8
leapp-upgrade-el7toel8-deps
libcgroup
libcomps
libdnf
libmodulemd
librepo
libreport-filesystem
librhsm
libsemanage-python
libsolv
libyaml
pciutils
policycoreutils
policycoreutils-python
python-IPy
python-chardet
python-enum34
python-requests
python-urllib3
python2-dnf
python2-hawkey
python2-leapp
python2-libcomps
python2-libdnf
setools-libs
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;p&amp;gt;在离线系统上创建一个文件夹 &amp;lt;code&amp;gt;/tmp/packages&amp;lt;/code&amp;gt;，将所有 rpm 复制到 &amp;lt;code&amp;gt;/tmp/packages&amp;lt;/code&amp;gt;。安装软件包。&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
mkdir /tmp/packages
cd /tmp/packages
yum localinstall *
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;/li&gt;
&lt;li&gt;在进行这个本地安装的时候，会提示一些依赖项的问题，比如无法安装leapp，需要依赖，比如我碰到的问题是需要下面的包：
&lt;ol&gt;
&lt;li&gt;wget https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/hawkey-0.6.3-4.el7.x86_64.rpm&lt;/li&gt;
&lt;li&gt;wget https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/python2-hawkey-0.6.3-4.el7.x86_64.rpm&lt;/li&gt;
&lt;li&gt;wget https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/libsolv-0.6.34-4.el7.x86_64.rpm&lt;/li&gt;
&lt;li&gt;wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/python2-hawkey-0.22.5-2.el7_9.x86_64.rpm&lt;/li&gt;
&lt;li&gt;yum install python2-hawkey-0.6.3-4.el7.x86_64.rpm hawkey-0.6.3-4.el7.x86_64.rpm libsolv-0.6.34-4.el7.x86_64.rpm&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;解决方法就是直接去rpmfind.net去搜，然后安装对应的CentOS的即可，否则就是会出现leapp无法安装的问题。我的链接是这个：https://rpmfind.net/linux/RPM/centos/7.9.2009/x86_64/Packages/&lt;/li&gt;
&lt;li&gt;依赖的包都安装好后，再到步骤6，安装升级需要的必须包&lt;/li&gt;
&lt;li&gt;确保leapp都可以正常使用，在我这里，leapp会爆出urllib3.exception包不存在的问题&lt;/li&gt;
&lt;li&gt;解决方法如下：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;pip3 install --upgrade pip
pip install --target=/usr/lib/python2.7/site-packages urllib3
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;然后再运行leapp发现正常了。接着就是预升级阶段了&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;leapp preupgrade --no-rhsm --iso rhel-8.10-x86_64-dvd.iso 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;等待运行完毕，会生成一个answer文件，位于 /var/log/leapp/answerfile&lt;/li&gt;
&lt;li&gt;打开这个文件，去掉confirm那行的注释，并写入True值，保存。&lt;/li&gt;
&lt;li&gt;重复运行步骤10，进行预检查，我碰到的问题是&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;Inhibitor: Detected loaded kernel drivers which have been removed in RHEL 8. Upgrade cannot proceed.
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;解决方法参见：https://access.redhat.com/solutions/6971716&lt;/li&gt;
&lt;li&gt;就是打开 /var/log/leapp/leapp-report.txt文件，会看到&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;Risk Factor: high (inhibitor)
Title: Detected loaded kernel drivers which have been removed in RHEL 8. Upgrade cannot proceed.
Summary: Support for the following RHEL 7 device drivers has been removed in RHEL 8: 
 - floppy
 - pata_acpi
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;然后执行： sudo rmmod floppy pata_acpi 就可以了&lt;/li&gt;
&lt;li&gt;继续返回，执行 leapp upgrade --no-rhsm --iso rhel-8.10-x86_64-dvd.iso&lt;/li&gt;
&lt;li&gt;确保没有什么error之类的大问题就可以了。然后进入升级环节&lt;/li&gt;
&lt;li&gt;运行 leapp upgrade --no-rhsm --iso rhel-8.10-x86_64-dvd.iso&lt;/li&gt;
&lt;li&gt;这时候一般会出现很多类似冲突的提示，然后结束。收集这些冲突的包，然后删除它。&lt;/li&gt;
&lt;li&gt;我这里删除了这么多的冲突包：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;rpm -qa |grep python36-six
rpm -e python36-six
rpm -e python36-six-1.14.0-3.el7.noarch
rpm -qa |grep python36-requests-2.14.2-2.el7.noarch
rpm -e python36-requests-2.14.2-2.el7.noarch
rpm -qa |grep python36-requests-2.14.2-2.el7.noarch
rpm -qa |grep python36-chardet-3.0.4-12.el7.noarch
rpm -e python36-chardet-3.0.4-12.el7.noarch
rpm -e python36-PyYAML-3.13-1.el7.x86_64
rpm -e python36-markupsafe-0.23-4.el7.x86_64
rpm -e python36-jinja2-2.11.1-1.el7.noarch
rpm -e python36-pycurl-7.43.0-8.el7.x86_64
rpm -e python36-tornado-4.5.3-1.el7.x86_64
rpm -e python36-pycurl-7.43.0-8.el7.x86_64
rpm -e python36-markupsafe-0.23-4.el7.x86_64
rpm -e python36-six-1.14.0-3.el7.noarch
rpm -e python36-urllib3-1.25.6-2.el7.noarch
rpm -e python36-six-1.14.0-3.el7.noarch
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;删除这些冲突后，继续执行步骤19，进行升级&lt;/li&gt;
&lt;li&gt;在运行结束后，会给出一个说明，如果没有什么大的问题，只需要重启就可以了&lt;/li&gt;
&lt;li&gt;重启的过程中，会大量的对系统进行更新，可能需要等待一段时间。&lt;/li&gt;
&lt;li&gt;可以的话，还是要做下注册工作，然后运行下 yum update，确保更新到最新了&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;subscription-manager register --org=&quot;mycompany&quot; --activionkey=&quot;dev&quot;
yum update 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本就是这个过程，非常的麻烦。如果这个机器不值得去折腾，那就不要去做这样的事情。因为时间成本很高。顺利的话，也需要半天时间，根本没必要。&lt;/p&gt;
</content:encoded></item><item><title>redhat satellite content views 自动发布</title><link>https://dididudu998.github.io/posts/redhat-satellite-content-views%E8%87%AA%E5%8A%A8%E5%8F%91%E5%B8%83/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/redhat-satellite-content-views%E8%87%AA%E5%8A%A8%E5%8F%91%E5%B8%83/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 14 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;由于目前使用的RedHat Satellite我们只有部分功能和权限，主要就是要跟上主库的更新，确保本地站点受管的RedHat客户端可以更新到最新的版本。&lt;/p&gt;
&lt;p&gt;前几天写了个用dnf-automatic的脚本，自动下载和安装security更新包，然后清理和邮件通告。&lt;/p&gt;
&lt;p&gt;但是要是content views不更新，那么就会找不到最新的更新。所以这次直接做了个自动任务，每隔4天，在半夜发布下两个content-views，分别是Redhat8和RedHat9.&lt;/p&gt;
&lt;p&gt;Satellite服务器不在我们这边，我能用web访问，然后手动进行发布。&lt;/p&gt;
&lt;p&gt;这都是玩剩下的，直接打开浏览器的开发者工具，追下过程。&lt;/p&gt;
&lt;p&gt;然后简单看下Satellite的官方API，找到其中发布的API。然后在PostMan中试了post下，通过。唯一要注意的是head要用application/json进行提交。&lt;/p&gt;
&lt;p&gt;下面是部分脚本，减去了发送邮件的部分：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;redhat8_url=&quot;https://mycorp.com/katello/api/v2/content_views/91/publish&quot;
redhat9_url=&quot;https://mycrop.com/katello/api/v2/content_views/124/publish&quot;

headers={

&quot;Content-Type&quot;:&quot;application/json&quot;

}

username=&quot;myaccount&quot;

password=keyring.get_password(&quot;gaogaogao&quot;,username)

  
payload={}

successful=1

  
response0=requests.post(redhat8_url,auth=(username,password),data=json.dumps(payload),headers=headers)

  

response1=requests.post(redhat9_url,auth=(username,password),data=json.dumps(payload),headers=headers)
  

redhat8_json_response=response0.json()

redhat9_json_response=response1.json()

  

if response0.status_code==202:

print(&quot;redhat8 content views publish success&quot;)

else:
successful=0
print(&quot;redhat8 content views publish publish failed&quot;)



#print(json.dumps(json_respose,indent=4))

print(json.dumps(redhat8_json_response,indent=4))

......


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试了下，通过。就是由于权限问题，没法生成自己的token，只能用basic authentication的方式。密码明文了。&lt;/p&gt;
&lt;p&gt;不过这个脚本跑在独立的机器上，只有我能访问，就这样吧。&lt;/p&gt;
&lt;p&gt;加上一个计划任务，每隔4天触发下，在半夜运行，然后发送邮件通告给我就好了。&lt;/p&gt;
</content:encoded></item><item><title>最近的一些杂事合并记录</title><link>https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91%E7%9A%84%E4%B8%80%E4%BA%9B%E6%9D%82%E4%BA%8B%E5%90%88%E5%B9%B6%E8%AE%B0%E5%BD%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91%E7%9A%84%E4%B8%80%E4%BA%9B%E6%9D%82%E4%BA%8B%E5%90%88%E5%B9%B6%E8%AE%B0%E5%BD%95/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 02 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;最近的一些杂事记录&lt;/h1&gt;
&lt;p&gt;最近代替其他人做一些基础的事情，包括ivanti，还有自己的一些测试。&lt;/p&gt;
&lt;p&gt;其中ivanti主要做了一些软件分发的东西，比如允许自动更新，定时重启，分发脚本等。&lt;/p&gt;
&lt;p&gt;这里面要说明的是，当写一些shell脚本的时候，传送到windows的库文件服务器时候，要检查下是否符合脚本的编码标准，windows和linux对于换行有不同的定义。极有可能出现类似“bad interpret ^M”这样的提示，总的来说，这个ivanti的玩意，我感觉并不是那么的优秀。&lt;/p&gt;
&lt;p&gt;对于自己的测试这边呢，就是又将以前的code-server给运行起来了。为什么不用vscode呢，因为它到处要我输入我的github账户或者windows账户，我不喜欢。&lt;/p&gt;
&lt;p&gt;为了code-server，就又添加了自签名证书的部分，让我的电脑可以不要出现什么不信任弹框这样的情况。我将这个写了个shell脚本。可以一键制作证书，现在放到下面，以备需要。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;制作一个domains.ext文件，用于申请多域名证书&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = dev01
DNS.3 = mark-win-computer001
DNS.4 = mark-macbookpro-001
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;生成ROOTCA.crt,localhost.key,localhost.crt的shell脚本&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj &quot;/C=US/CN=Mark&quot;

  

openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

  
  

openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj &quot;/C=US/ST=TianTang/L=BBB/O=Mark/CN=mycomputer&quot;

  

openssl x509 -req -sha256 -days 10240 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;将RootCA.crt安装到客户端的受信任跟证书颁发机构中&lt;/li&gt;
&lt;li&gt;将localhost.key和localhost.crt配置到服务器的对应证书位置&lt;/li&gt;
&lt;li&gt;重启服务器端应用，在客户端按照需求配置hosts信息，就可以https访问了&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最近一点新的东西都没做。反而是娱乐的成分多了些。比如用ipad利用桌面电脑的everything通过web看下载的视频，书页没看多少页。&lt;/p&gt;
&lt;p&gt;在手机上下载了个RSS的阅读器，订阅了很多关于信息安全的条目。&lt;/p&gt;
</content:encoded></item><item><title>Windows集群创建角色时提示权限不够的问题</title><link>https://dididudu998.github.io/posts/windows%E9%9B%86%E7%BE%A4%E5%88%9B%E5%BB%BA%E8%A7%92%E8%89%B2%E6%97%B6code0x80070005/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windows%E9%9B%86%E7%BE%A4%E5%88%9B%E5%BB%BA%E8%A7%92%E8%89%B2%E6%97%B6code0x80070005/</guid><pubDate>Fri, 26 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;记录&lt;/h2&gt;
&lt;p&gt;还是那些收尾的事，大概两个月前，让下属照着自己2019年做的那批集群，照着做，交付了几台Windows集群+SQL集群给用户，昨天又收到邮件说两个集群中的角色没创建出来，让尽快解决下。&lt;/p&gt;
&lt;p&gt;这不是一起的事情吗？交付时候不好好检查，一件事情要让人不停的补充延续，这真的很不好。&lt;/p&gt;
&lt;p&gt;然后接手去创建，创建出来后，无法online，提示没有权限。由于域名IP我都已经分好了，明显的角色的计算机对象没创建出来。&lt;/p&gt;
&lt;p&gt;打开ADUC，发现他自己建了一个OU，然后这些集群对象，计算机对象在这OU里面，但是没有给Windows Cluster这些计算机对象授权在这个OU创建对象的权限，还悲剧的我没法在他这个OU里面添加用户权限，全灰的。&lt;/p&gt;
&lt;p&gt;😮‍💨，只好自己新建一个OU，将原来的计算机对象都移动过来，然后给Windows集群的计算机对象授权在这个新OU的Full Control权限。再去这些集群，挨个的重启下节点，让它们刷新下AD的缓存。&lt;/p&gt;
&lt;p&gt;然后再分别去Windows集群节点建角色，这下一下子就好了。&lt;/p&gt;
&lt;p&gt;做事情不细心，搞得别人接手就很烦。再加上这个事情和国外有时差，这一来一去的，两天就过去了。&lt;/p&gt;
&lt;p&gt;😮‍💨😮‍💨😮‍💨&lt;/p&gt;
</content:encoded></item><item><title>redhat8简单的更新脚本</title><link>https://dididudu998.github.io/posts/redhat8%E7%AE%80%E5%8D%95%E7%9A%84%E6%9B%B4%E6%96%B0%E8%84%9A%E6%9C%AC/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/redhat8%E7%AE%80%E5%8D%95%E7%9A%84%E6%9B%B4%E6%96%B0%E8%84%9A%E6%9C%AC/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Thu, 25 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;记录&lt;/h1&gt;
&lt;p&gt;由于只能通过管理服务器来管理redhat8，没有账户密码，而且这个版本原始里面没有mail程序，对于做了操作后效果的检验感觉很不好，所以以系统更新为例子，做个简单脚本进行下放。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
#mark @2024/04/21

dnf install mutt -y
update_log=$(dnf update -y)
dnf update -y &amp;gt;g.txt
ipaddress=$(hostname -I)
datetime=$(date +&quot;%Y-%m-%d %H:%M:%S&quot;)
echo $ipaddress &amp;gt;&amp;gt;g.txt
echo $datetime &amp;gt;&amp;gt;g.txt
mutt -s &quot;dnf update&quot; me@mydomain.com &amp;lt;g.txt
rm g.txt

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;真的很垃圾，我一点也不喜欢什么ivanti这样的所谓终端管理软件。幸亏我只是临时帮忙。&lt;/p&gt;
</content:encoded></item><item><title>用openconnect替换anyconnect</title><link>https://dididudu998.github.io/posts/openconnect%E5%A4%9A%E9%87%8D%E8%AE%A4%E8%AF%81%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/openconnect%E5%A4%9A%E9%87%8D%E8%AE%A4%E8%AF%81%E7%9A%84%E9%97%AE%E9%A2%98/</guid><pubDate>Sun, 14 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;自从这边用cisco anyconnect后，我就一直用openconnect来代替anyconnect了，因为openconnect可以用脚本节省我每次输入密码的麻烦，我基本上不记工作上的密码。&lt;/p&gt;
&lt;p&gt;今天在进行vpn链接的时候，告诉我不行了，我查了下，现在多了个需要选择GROUP的动作，以前是默认的不需要选择。只好从新调整下我的openconnect脚本了。&lt;/p&gt;
&lt;p&gt;调整后的脚本是这样的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; echo &quot;company VPN: All Traffic\nPassword\npush&quot; |sudo openconnect -u myaccount company-vpn.aaa.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里要说明的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;company VPN: All Traffic是group的名字&lt;/li&gt;
&lt;li&gt;Password是我的真实的密码&lt;/li&gt;
&lt;li&gt;push是第二个密码，输入push会推送一个弹窗到手机的DUO应用，点击approve，则会连接VPN。也可以输入sms，这样会收到一条短信，短信中包含有一次性密码。&lt;/li&gt;
&lt;li&gt;myaccount是我的用户名&lt;/li&gt;
&lt;li&gt;company-vpn.aaa.com是公司的vpn服务器地址，其实也就是登录网页&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完整的过程其实是用上面的参数填充登录网页中的各个项，然后发起post请求。&lt;/p&gt;
&lt;p&gt;这样又可以一键上vpn了。&lt;/p&gt;
</content:encoded></item><item><title>门卡失而复得</title><link>https://dididudu998.github.io/posts/%E5%B9%B8%E8%BF%90%E6%97%A5%E9%97%A8%E5%8D%A1%E5%A4%B1%E8%80%8C%E5%A4%8D%E5%BE%97/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%B9%B8%E8%BF%90%E6%97%A5%E9%97%A8%E5%8D%A1%E5%A4%B1%E8%80%8C%E5%A4%8D%E5%BE%97/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Sun, 14 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;早上出门吃早饭的路上发现学校的门卡没了，我一直是放在手机的皮套里面的。这个门卡听说补办一次要100块钱，很倒霉啊，但是丢了也没法子，先吃饭。&lt;/p&gt;
&lt;p&gt;吃饭的时候想着，要么是丢在屋里了，要么是昨天来回医院路上了，要么就是今天出门的路上丢了。等吃完饭，想着那就原路返回，试试看能不能找到吧。&lt;/p&gt;
&lt;p&gt;抱着可有可无的心态，顺路回来的时候还去豆腐店买了块豆腐，然后路过理发店，路过蛋糕房，路过蔬菜店，然后往前走了大概2米，有个清洁工阿姨正在扫地，我一眼看到个蓝色的卡片在地上，而当时她正准备扫那片地方，我赶紧喊了一声，然后冲过去捡起来，一看，哈哈，还真是我的卡。这真是上天眷顾。那阿姨也说要是晚来几秒钟，这片地方的垃圾就扫到旁边垃圾堆里去了，就找不到了。我赶紧感谢。&lt;/p&gt;
&lt;p&gt;真是幸运的一天啊。&lt;/p&gt;
&lt;p&gt;回来后我就想着赶紧注册个虚拟卡，不用实体卡了，实体卡放在学校，我不拿不就不会丢了。&lt;/p&gt;
&lt;p&gt;然后就发现vpn上不去了，然后就修复了下那个openconnect的脚本。&lt;/p&gt;
&lt;p&gt;然后发现学校的那个绑定校园卡的页面还是一直打不开，只好周一去学校用pad试试激活了。&lt;/p&gt;
&lt;p&gt;总之是幸运的一天。&lt;/p&gt;
</content:encoded></item><item><title>monitors:an operating system structuring concept</title><link>https://dididudu998.github.io/posts/an-operating-system-structuring-concept/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/an-operating-system-structuring-concept/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 28 Mar 2024 00:00:00 GMT</pubDate><content:encoded/></item><item><title>implementing condition variables with semaphores</title><link>https://dididudu998.github.io/posts/implementing-condition-variables-with-semaphores/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/implementing-condition-variables-with-semaphores/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 28 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;here the summary of the paper:&lt;/p&gt;
&lt;h2&gt;introduction&lt;/h2&gt;
&lt;p&gt;所有当今流行的用于多线程的操作系统的设计，都基于下面三种数据类型：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;线程，包括针对线程的fork和join&lt;/li&gt;
&lt;li&gt;锁，包括获取和释放&lt;/li&gt;
&lt;li&gt;条件变量，包括等待，信号，和广播&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>增长的分类</title><link>https://dididudu998.github.io/posts/%E5%A2%9E%E9%95%BF%E7%9A%84%E5%88%86%E7%B1%BB/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%A2%9E%E9%95%BF%E7%9A%84%E5%88%86%E7%B1%BB/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 27 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今天看到一篇文章，来自“A study of Linux File System Evolution&quot;, pdf文件在这里：
https://www.usenix.org/system/files/login/articles/03_lu_010-017_final.pdf&lt;/p&gt;
&lt;p&gt;他们将Linux的补丁进行了分类，筛选出针对文件系统的各种措施。&lt;/p&gt;
&lt;p&gt;分类如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bug fixes
&lt;ul&gt;
&lt;li&gt;memory: incorrect handling of memory objects&lt;/li&gt;
&lt;li&gt;concurrency: incorrect concurrent behaviors&lt;/li&gt;
&lt;li&gt;semantic: incorrect design or implementation&lt;/li&gt;
&lt;li&gt;error code: missing or wrong error code handling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;performance improvements&lt;/li&gt;
&lt;li&gt;reliability enhancements&lt;/li&gt;
&lt;li&gt;new features&lt;/li&gt;
&lt;li&gt;maintenance and refactoring&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;针对的文件系统包括：ext3,JFS,ReiserFS,XFS,Btrfs&lt;/p&gt;
&lt;p&gt;这个研究做的真的很厉害，先不说他们需要采集这些Patch，然后读它，还要分类，还要看看到底做了什么，这时间成本就不是一点点。再有，他们是针对不同的人开发的文件系统的研究，这样涵盖了这些做这些人的通病的问题，或者高概率出现问题的地方，通过对这些数据的了解和研究，可以为后来的人带来很多的经验，避免重复犯错。&lt;/p&gt;
&lt;p&gt;补：文章最后说了这个项目耗时1年半。&lt;/p&gt;
&lt;p&gt;文件系统分成几个逻辑组成部分，包括inodes,superblocks,journals.&lt;/p&gt;
&lt;p&gt;更细致的划分为9个组件:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;data block allocation(balloc)&lt;/li&gt;
&lt;li&gt;directory management(dir)&lt;/li&gt;
&lt;li&gt;extent mapping(extent)&lt;/li&gt;
&lt;li&gt;file read and write operations(file)&lt;/li&gt;
&lt;li&gt;inode metadata(inode)&lt;/li&gt;
&lt;li&gt;transactional support(trans)&lt;/li&gt;
&lt;li&gt;superblock metadata(super)&lt;/li&gt;
&lt;li&gt;generic tree procedures(e.g:insert an entry, tree)&lt;/li&gt;
&lt;li&gt;other supporting components&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;关于性能问题的技术分类：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;inefficient usage of synchronization methods(sync)&lt;/li&gt;
&lt;li&gt;smarter access strategies (access)&lt;/li&gt;
&lt;li&gt;I/O scheduling improvement(sched)&lt;/li&gt;
&lt;li&gt;scale on-disk and in-memory data structures(scale)&lt;/li&gt;
&lt;li&gt;data block allocation optimization(locality)&lt;/li&gt;
&lt;li&gt;other performance techniques(other)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;sync problem is more than a quarter of all performance patches across file systems. typical solutions used include removing a pair of unnecessary locks, using finer-grained locking, and replacing write locks with read/write locks.&lt;/p&gt;
&lt;p&gt;access patches use smart strategies to optimize performance, including caching and work avoidance. for example, ext3 caches metadata stats in memory, avoiding I/O. an example Btrfs, before searching for free blocks, the patch first checks whether there is enough free space, avoiding unnecessary work.&lt;/p&gt;
&lt;p&gt;sched, improve I/O scheduling for better performance, such as batching of writes, opportunistic readahead, and avoiding unnecessary synchrony in I/O. sched patches utilize scalable on-disk and in-memory data structures, such as hash tables, trees, and per block-group structures.&lt;/p&gt;
</content:encoded></item><item><title>配置RDP的SSL证书</title><link>https://dididudu998.github.io/posts/%E9%85%8D%E7%BD%AErdp%E7%9A%84ssl%E8%AF%81%E4%B9%A6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E9%85%8D%E7%BD%AErdp%E7%9A%84ssl%E8%AF%81%E4%B9%A6/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 27 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;其实也没有特别的原因，就是早上在搜索加密流量的时候，看到了TLS的东西，想着就更新一下。信任自生成的证书也没什么特别的问题。&lt;/p&gt;
&lt;p&gt;参看这里：&lt;/p&gt;
&lt;p&gt;https://cloud.tencent.com/developer/article/2375679&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;由于我已经有一个域的证书和crt文件，因此我可以直接用下面的命令生成针对windows的格式的证书&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;openssl pkcs12 -export -clcerts -in mydomain-crt.txt -inkey mydomain-key.txt -out mydomain.p12
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;将这个p12证书导入Windows电脑中的计算机账户，个人，证书内&lt;/li&gt;
&lt;li&gt;右键这个证书，将证书的指纹记录下来，因为后面还要用到&lt;/li&gt;
&lt;li&gt;添加权限。右键这个证书，管理私钥，给予NetWork Service读取的权限&lt;/li&gt;
&lt;li&gt;添加指纹到系统，这个需要管理员权限&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash=&quot;记录的证书指纹&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;后续步骤
由于我的这个证书的域名的问题，需要在本地的host记录中，加上这个证书所属的域的计算机名。
然后修改已有的远程连接计算机条目到这个修改的带有域名后缀的名称，连接尝试，就可以直接连接了。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>让R可以正常显示中文</title><link>https://dididudu998.github.io/posts/%E8%AE%A9r%E5%8F%AF%E4%BB%A5%E6%AD%A3%E5%B8%B8%E6%98%BE%E7%A4%BA%E4%B8%AD%E6%96%87/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%AE%A9r%E5%8F%AF%E4%BB%A5%E6%AD%A3%E5%B8%B8%E6%98%BE%E7%A4%BA%E4%B8%AD%E6%96%87/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Fri, 22 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;ol&gt;
&lt;li&gt;退出当前的R&lt;/li&gt;
&lt;li&gt;在终端下，执行下面的命令：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;defaults write org.R-project.R force.LANG en_US.UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;重新打开进入R即可&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>unable mount root fs</title><link>https://dididudu998.github.io/posts/unable-mount-root-fs-and-too-many-open-files-on-ubuntu/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/unable-mount-root-fs-and-too-many-open-files-on-ubuntu/</guid><pubDate>Tue, 19 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;早上SSH连接到Ubuntu的时候，发现连接不上了，想起来，应该是升级的时候有个措施是开启1022端口作为SSH的端口，然后就直接到虚拟机控制台里面进系统查看了配置，开启SSH的22端口后，发现服务总是提示无法重启，莫名的。直接REBOOT了。&lt;/p&gt;
&lt;p&gt;然后好戏就来了，提示“VFS： unable mount root fs....&quot;,就是进不去了。&lt;/p&gt;
&lt;p&gt;下面是解决方法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
1. 重启，选择&quot;Advanced opons for Ubuntu&quot;, 记录下最新的那个内核信息，这里是“6.8.0-11-generic&quot;
2. 选择旧的那个正常的内核，进入系统
3. 创建初始化文件
4. sudo update-initramfs -u -k 6.8.0-11-generic
5. sudo update-grub
6. reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;initramfs&lt;/code&gt; 是一个被加载到内存中的临时根文件系统（initial RAM file system），用于在 Linux 系统启动过程中进行初始化和准备工作。在 Linux 内核启动时，它会首先加载一个小型的、只读的 &lt;code&gt;initramfs&lt;/code&gt;，以便在硬件初始化和根文件系统挂载之前提供必要的设备驱动程序、文件系统模块以及其他初始化所需的资源。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;initramfs&lt;/code&gt; 的目的是在引导过程中提供一个轻量级的环境，使得操作系统能够识别并访问到真正的根文件系统所需的设备和驱动程序。一旦真正的根文件系统被挂载，&lt;code&gt;initramfs&lt;/code&gt; 就会被卸载并释放掉，系统将切换到真正的根文件系统进行后续的初始化和操作。&lt;/p&gt;
&lt;p&gt;不知道为什么会把这玩意儿给弄丢了，可能是更新到24.04的时候，没有完成？？&lt;/p&gt;
&lt;p&gt;进入系统后，做了下apt-get update，提示open too many files.....&lt;/p&gt;
&lt;p&gt;检查当前的状态：&lt;/p&gt;
&lt;p&gt;sysctl fs.inotify&lt;/p&gt;
&lt;p&gt;直接修改：&lt;/p&gt;
&lt;p&gt;sysctl -w fs.inotify.max_user_instances=512&lt;/p&gt;
&lt;p&gt;但是上面的修改，重启后会失效。&lt;/p&gt;
&lt;p&gt;永久解决方法：&lt;/p&gt;
&lt;p&gt;修改 /etc/sysctl.conf，&lt;/p&gt;
&lt;p&gt;在文件末尾加上下面的语句：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 512
fs.inotify.max_user_watches = 16384
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后运行 sysctl -p 让其生效。&lt;/p&gt;
&lt;p&gt;再次运行apt-get update，发现提示没有了。&lt;/p&gt;
</content:encoded></item><item><title>MacBook下gdb不能使用的问题</title><link>https://dididudu998.github.io/posts/22please-check-gdb-is-codesigned22%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/22please-check-gdb-is-codesigned22%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 11 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今天在尝试用gdb对一个小程序进行检查的时候，发现提示这个&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Unable to find Mach task port for process-id 62901: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))
(gdb) exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;翻了下搜索引擎，找到这个解决方法，具体的含义不知道。只是照猫画虎后，gdb可以用了。&lt;/p&gt;
&lt;p&gt;先创建一个文件 gdb-entitlement.xml，内容为:&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&quot;1.0&quot;&amp;gt;
&amp;lt;dict&amp;gt;
&amp;lt;key&amp;gt;com.apple.security.cs.debugger&amp;lt;/key&amp;gt;
&amp;lt;true/&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&amp;lt;/pre&amp;gt;&lt;/p&gt;
&lt;p&gt;再执行:
codesign --entitlements gdb-entitlement.xml -fs gdb-cert $(which gdb)&lt;/p&gt;
&lt;p&gt;文章地址为：https://sourceware.org/gdb/wiki/PermissionsDarwin&lt;/p&gt;
</content:encoded></item><item><title>MacBook下gdb不能使用的问题</title><link>https://dididudu998.github.io/posts/please-check-gdb-is-codesigned%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/please-check-gdb-is-codesigned%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 11 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今天在尝试用gdb对一个小程序进行检查的时候，发现提示这个&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Unable to find Mach task port for process-id 62901: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))
(gdb) exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;翻了下搜索引擎，找到这个解决方法，具体的含义不知道。只是照猫画虎后，gdb可以用了。&lt;/p&gt;
&lt;p&gt;先创建一个文件 gdb-entitlement.xml，内容为:&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&quot;1.0&quot;&amp;gt;
&amp;lt;dict&amp;gt;
&amp;lt;key&amp;gt;com.apple.security.cs.debugger&amp;lt;/key&amp;gt;
&amp;lt;true/&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&amp;lt;/pre&amp;gt;&lt;/p&gt;
&lt;p&gt;再执行:
codesign --entitlements gdb-entitlement.xml -fs gdb-cert $(which gdb)&lt;/p&gt;
&lt;p&gt;文章地址为：https://sourceware.org/gdb/wiki/PermissionsDarwin&lt;/p&gt;
</content:encoded></item><item><title>MacOS不能安装app的解决方法</title><link>https://dididudu998.github.io/posts/2024-03-05-macos%E4%B8%8D%E8%83%BD%E5%AE%89%E8%A3%85app%E7%9A%84%E8%A7%A3%E5%86%B3/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/2024-03-05-macos%E4%B8%8D%E8%83%BD%E5%AE%89%E8%A3%85app%E7%9A%84%E8%A7%A3%E5%86%B3/</guid><pubDate>Tue, 05 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今天在这台MacOS 12.5的系统上安装VMware Fusion，下载了最新的13.5.1，双击打开的时候，提示应用程序无法打开。因为以前也碰到过这样的情况，怀疑是app的版本过高了，这电脑的操作系统不支持。随即又下载了13.01版本的，依然提示无法打开，这就怪了。应该不是app的问题了。&lt;/p&gt;
&lt;p&gt;网上搜了下，可以用这个命令来解决问题：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo xattr -r -d com.apple.quarantine /Users/username/Downloads/VMware-Fusion-13.5.1-23298085_universal.dmg 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是针对该命令行的说明:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;`sudo xattr -r -d com.apple.quarantine` 是一个命令行命令，用于递归地移除 macOS 上文件或目录的 `com.apple.quarantine` 扩展属性。

在 macOS 系统中，当你从互联网或其他不可信的来源下载文件时，系统会为这些文件设置 `com.apple.quarantine` 扩展属性。该属性可以标记文件或目录是从网络下载的，并可能需要进行安全性检查或用户确认。

使用 `sudo xattr -r -d com.apple.quarantine` 命令可以移除文件或目录及其子目录中的所有 `com.apple.quarantine` 扩展属性，以解除下载文件的限制。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是这app是在vmware的官网下载的，看来要么是vmware的app做的不够好，要么就是这中间过程可能被内部的一些代理或者其他安全设备将有些数据被篡改了。&lt;/p&gt;
&lt;p&gt;我也没有对照这个哈希，算了，能用就行。&lt;/p&gt;
</content:encoded></item><item><title>批量转化图片格式</title><link>https://dididudu998.github.io/posts/%E6%89%B9%E9%87%8F%E8%BD%AC%E5%8C%96%E5%9B%BE%E7%89%87%E6%A0%BC%E5%BC%8F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%89%B9%E9%87%8F%E8%BD%AC%E5%8C%96%E5%9B%BE%E7%89%87%E6%A0%BC%E5%BC%8F/</guid><pubDate>Thu, 29 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;前些日子从台湾故宫博物馆的开放数据中下载了一些高清的唐宋代的古画图片，由于是高清的，每个图片都有20多兆，只有四百张画，不算陶器，玉器和字帖，占用就超过了8GB，然后将这些图片备份到了我的台式机后，准备将笔记本上的图片做个压缩，使用webp格式的，这种格式是以前在网络上学习golang的时候发现的，压缩率不错，而且整个的画质也很好。&lt;/p&gt;
&lt;p&gt;然后这台mac上面可能由于以前做图片剪裁的时候安装了imagemagick，然后可以直接用命令行进行批量转化了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mogrify -format webp *.tif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;等待转化完成后，删除原来的tif文件即可。&lt;/p&gt;
&lt;p&gt;原本的空间占用7.9GB,转化后的空间占用为428MB.&lt;/p&gt;
</content:encoded></item><item><title>数据类型错误导致的问题</title><link>https://dididudu998.github.io/posts/%E7%94%B1%E4%BA%8E%E8%AE%A1%E7%AE%97%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E9%94%99%E8%AF%AF%E5%AF%BC%E8%87%B4%E7%9A%84%E4%BA%8B%E6%95%85/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%B1%E4%BA%8E%E8%AE%A1%E7%AE%97%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E9%94%99%E8%AF%AF%E5%AF%BC%E8%87%B4%E7%9A%84%E4%BA%8B%E6%95%85/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 21 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;计算机在无时无刻的接收数据，并对数据进行传输和类型转化以及计算，然后再进行传输，传输到其他的IO设备，比如显示器或者到磁盘文件。&lt;/p&gt;
&lt;p&gt;在这里数据转化是非常关键的一部分，类比下就好像是协议，当协商不一致的时候，两个人之间对数据的理解是完全不对等的，会导致严重的错误。&lt;/p&gt;
&lt;p&gt;这里摘录了几个由于在代码中数据类型转化导致问题而引发的事件。&lt;/p&gt;
&lt;p&gt;一般来说都是大数转为整型，或者小数接近于0，导致溢出。&lt;/p&gt;
&lt;p&gt;还有要说明的是，为什么你写的软件赚不到钱，因为你根本没有意识到数据的准确性在真实世界是多么的珍贵。所以在给银行，证券，军事，航空航天，远洋运输，卫星，医疗，精密工业制造等用的软件才是真正的体现了人类智慧和思考精华的软件，才是可以赚钱的软件，并且应该赚钱的软件和服务。&lt;/p&gt;
&lt;p&gt;下面是几个例子：&lt;/p&gt;
&lt;h2&gt;阿丽亚娜5火箭升空爆炸&lt;/h2&gt;
&lt;p&gt;Converting large ﬂoating-point numbers to integers is a common source of programming errors. Such an error had disastrous consequences for the maiden voyage of the Ariane 5 rocket, on June 4, 1996. Just 37 seconds after liftoff, the rocket veered off its ﬂight path, broke up, and exploded. Communication satellites valued at $500 million were on board the rocket.&lt;/p&gt;
&lt;p&gt;A later investigation [73, 33] showed that the computer controlling the inertial navigation system had sent invalid data to the computer controlling the engine nozzles. Instead of sending ﬂight control information, it had sent a diagnostic bit pattern indicating that an overﬂow had occurred during the conversion of a 64-bit ﬂoating-point number to a 16-bit signed integer.&lt;/p&gt;
&lt;p&gt;The value that overﬂowed measured the horizontal velocity of the rocket, which could be more than ﬁve times higher than that achieved by the earlier Ariane 4 rocket. In the design of the Ariane 4 software, they had carefully analyzed the numeric values and determined that the horizontal velocity would never overﬂow a 16-bit number. Unfortunately, they simply reused this part of the software in the Ariane 5 without checking the assumptions on which it had been based.&lt;/p&gt;
&lt;h2&gt;爱国者拦截飞毛腿导弹失败的问题&lt;/h2&gt;
&lt;p&gt;The imprecision of ﬂoating-point arithmetic can have disastrous effects. On February 25, 1991, during the ﬁrst Gulf War, an American Patriot Missile battery in Dharan, Saudi Arabia, failed to intercept an incoming Iraqi Scud missile. The Scud struck an American Army barracks and killed 28 soldiers. The US General Accounting Ofﬁce (GAO) conducted a detailed analysis of the failure [76] and determined that the underlying cause was an imprecision in a numeric calculation.&lt;/p&gt;
&lt;p&gt;The Patriot system contains an internal clock, implemented as a counter that is incremented every 0.1 seconds. To determine the time in seconds, the program would multiply the value of this counter by a 24-bit quantity that was a fractional binary approximation to 1/10 . In particular, the binary representation 1 ... of 10 is the nonterminating sequence 0.000110011[0011]  , where the portion in brackets is repeated indeﬁnitely. The program approximated 0.1, as a value x, by considering just the ﬁrst 23 bits of the sequence to the right of the binary point: x = 0.00011001100110011001100.&lt;/p&gt;
&lt;p&gt;The problem was that the Patriot software had been upgraded to use a more accurate function for reading time, but not all of the function calls had been replaced by the new code. As a result, the tracking software used the accurate time for one reading and the inaccurate time for the other&lt;/p&gt;
&lt;h2&gt;整型数字可能溢出导致的问题&lt;/h2&gt;
&lt;p&gt;In 2002, it was discovered that code supplied by Sun Microsystems to implement the XDR library, a widely used facility for sharing data structures between programs, had a security vulnerability arising from the fact that multiplication can overﬂow without any notice being given to the program.&lt;/p&gt;
&lt;p&gt;Code similar to that containing the vulnerability is shown below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
/* Illustration of code vulnerability similar to that found in * Sun’s XDR library.

*/ 

void* copy_elements(void *ele_src[], int ele_cnt, size_t ele_size) { 
/* * Allocate buffer for ele_cnt objects, each of ele_size bytes * and copy from locations designated by ele_src */ 
	void *result = malloc(ele_cnt * ele_size); 
	if (result == NULL) /* malloc failed */ 
		return NULL; 
	void *next = result; 
	int i;

	for(i=0;i&amp;lt;ele_cnt;i++){
	
		/* Copy object i to destination */ 
		memcpy(next, ele_src[i], ele_size); /* Move pointer to next memory region */ 
		next += ele_size;
		} 
		return result;
	}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function copy_elements is designed to copy ele_cnt data structures, each consisting of ele_ size bytes into a buffer allocated by the function on line 9. The number of bytes required is computed as ele_cnt * ele_size.&lt;/p&gt;
&lt;p&gt;Imagine, however, that a malicious programmer calls this function with ele_cnt being 1,048,577 (2 20 + 1) and ele_size being 4,096 (2 12 ) with the program compiled for 32 bits. Then the multiplication on line 9 will overﬂow, causing only 4,096 bytes to be allocated, rather than the 4,294,971,392 bytes required to hold that much data. The loop starting at line 15 will attempt to copy all of those bytes, overrunning the end of the allocated buffer, and therefore corrupting other data structures. This could cause the program to crash or otherwise misbehave.&lt;/p&gt;
&lt;p&gt;The Sun code was used by almost every operating system and in such widely used programs as Internet Explorer and the Kerberos authentication system. The Computer Emergency Response Team (CERT), an organization run by the Carnegie Mellon Software Engineering Institute to track security vulnerabilities and breaches, issued advisory “CA-2002-25,” and many companies rushed to patch their code. Fortunately, there were no reported security breaches caused by this vulnerability.&lt;/p&gt;
&lt;h2&gt;GetPeerName 问题&lt;/h2&gt;
&lt;p&gt;In 2002, programmers involved in the FreeBSD open-source operating systems project realized that their implementation of the getpeername library function had a security vulnerability. A simpliﬁed version of their code went something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/*

* Illustration of code vulnerability similar to that found in * FreeBSD’s implementation of getpeername() */

/* Declaration of library function memcpy */

void *memcpy(void *dest, void *src, size_t n);
/* Kernel memory region holding user-accessible data */ 
#define KSIZE 1024 
char kbuf[KSIZE];
/* Copy at most maxlen bytes from kernel region to user buffer */
int copy_from_kernel(void *user_dest, int maxlen) {
/* Byte count len is minimum of buffer size and maxlen */
	int len = KSIZE &amp;lt; maxlen ? KSIZE : maxlen; 
	memcpy(user_dest, kbuf, len); return len; 
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this code, we show the prototype for library function memcpy on line 7, which is designed to copy a speciﬁed number of bytes n from one region of memory to another.&lt;/p&gt;
&lt;p&gt;The function copy_from_kernel, starting at line 14, is designed to copy some of the data maintained by the operating system kernel to a designated region of memory accessible to the user. Most of the data structures maintained by the kernel should not be readable by a user, since they may contain sensitive information about other users and about other jobs running on the system, but the region shown as kbuf was intended to be one that the user could read. The parameter maxlen is intended to be the length of the buffer allocated by the user and indicated by argument user_dest. The computation at line 16 then makes sure that no more bytes are copied than are available in either the source or the destination buffer.&lt;/p&gt;
&lt;p&gt;Suppose, however, that some malicious programmer writes code that calls copy_from_kernel with a negative value of maxlen. Then the minimum computation on line 16 will compute this value for len, which will then be passed as the parameter n to memcpy. Note, however, that parameter n is declared as having data type size_t. This data type is declared (via typedef) in the library ﬁle stdio.h. Typically, it is deﬁned to be unsigned for 32-bit programs and unsigned long for 64-bit programs. Since argument n is unsigned, memcpy will treat it as a very large positive number and attempt to copy that many bytes from the kernel region to the user’s buffer. Copying that many bytes (at least 231 ) will not actually work, because the program will encounter invalid addresses in the process, but the program could read regions of the kernel memory for which it is not authorized.&lt;/p&gt;
</content:encoded></item><item><title>Windows下使用ffmpeg</title><link>https://dididudu998.github.io/posts/windows%E4%B8%8B%E7%94%A8ffmpeg/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windows%E4%B8%8B%E7%94%A8ffmpeg/</guid><pubDate>Tue, 30 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;windows 下使用ffmpeg&lt;/h1&gt;
&lt;p&gt;其实是两个事情，在手机上装了termux，装了yt-dlp，然后装了ffmpeg，可以从youtube上下载完整的音乐专辑，然后有的是演唱会模式的，所以用ffmpeg转为mp3.&lt;/p&gt;
&lt;p&gt;台式机上面用的windows，有时候听youtube的时候，顺手也就可以这么干。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
1. pip install yt-dlp
2. choco install ffmpeg-full  //in administrator mode， powershell)
3. pip install tldr //it can help you to understand the command
4. tldr ffmpeg

C:\WINDOWS\system32&amp;gt;tldr ffmpeg

  ffmpeg

  Video conversion tool.
  More information: https://ffmpeg.org.

  - Extract the sound from a video and save it as MP3:
    ffmpeg -i path/to/video.mp4 -vn path/to/sound.mp3

  - Save a video as GIF, scaling the height to 1000px and setting framerate to 15:
    ffmpeg -i path/to/video.mp4 -vf &apos;scale=-1:1000&apos; -r 15 path/to/output.gif

  - Combine numbered images (`frame_1.jpg`, `frame_2.jpg`, etc) into a video or GIF:
    ffmpeg -i path/to/frame_%d.jpg -f image2 video.mpg|video.gif

  - Quickly extract a single frame from a video at time mm:ss and save it as a 128x128 resolution image:
    ffmpeg -ss mm:ss -i path/to/video.mp4 -frames 1 -s 128x128 -f image2 path/to/image.png

  - Trim a video from a given start time mm:ss to an end time mm2:ss2 (omit the -to flag to trim till the end):
    ffmpeg -ss mm:ss -to mm2:ss2 -i path/to/video.mp4 -codec copy path/to/output.mp4

  - Convert AVI video to MP4. AAC Audio @ 128kbit, h264 Video @ CRF 23:
    ffmpeg -i path/to/input_video.avi -codec:a aac -b:a 128k -codec:v libx264 -crf 23 path/to/output_video.mp4

  - Remux MKV video to MP4 without re-encoding audio or video streams:
    ffmpeg -i path/to/input_video.mkv -codec copy path/to/output_video.mp4

  - Convert MP4 video to VP9 codec. For the best quality, use a CRF value (recommended range 15-35) and -b:v MUST be 0:
    ffmpeg -i path/to/input_video.mp4 -codec:v libvpx-vp9 -crf 30 -b:v 0 -codec:a libopus -vbr on -threads number_of_threads path/to/output_video.webm

 直接从YOUTUBE链接转化为MP3的方法：

  yt-dlp --extract-audio --audio-format mp3 --audio-quality 0 &quot;https://www.youtube.com/watch?v=A96X-maQVSs&quot;

5. 这里的对于时间截取的部分非常友好，提取一个专辑中的特别的歌曲非常有用。
6. 然后windows中的话，直接自带的media player就可以满足基本的音频播放了。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最近听二手玫瑰和恰克飞鸟。&lt;/p&gt;
</content:encoded></item><item><title>Upgrade CentOS7 to RockyLinux9</title><link>https://dididudu998.github.io/posts/upgrade-centos7-to-rockylinux9/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/upgrade-centos7-to-rockylinux9/</guid><pubDate>Thu, 25 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;upgrade CentOS7 to Rocky Linux 9&lt;/h1&gt;
&lt;p&gt;CentOS7 已经EOL，为了继续使用，准备升级到Rocky Linux。&lt;/p&gt;
&lt;p&gt;升级的过程是，先升级到CentOS8，然后迁移到Rocky Linux8，这个EOL是2025年。&lt;/p&gt;
&lt;p&gt;然后从Rocky Linux8 升级到 Rocky Linux9. 这个的EOL是2029. 但是这个不是官方支持的升级。官方建议直接重新安装新系统然后对数据和服务进行重新部署。&lt;/p&gt;
&lt;p&gt;下面是升级步骤，可能出现的冲突的包和你的不同。但是概括下，就是添加repo，更新，解决包冲突问题，然后继续即可。&lt;/p&gt;
&lt;p&gt;要说明的是，这里选择了清华的CentOS的镜像，因为这个在国内维护的非常好，我也喜欢他们的这个TUNA协会。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://tuna.moe/events/&quot;&gt;TUNA Events&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;@2024-01-26 update, 删除有可能带来困扰的命令行。&lt;/p&gt;
&lt;h3&gt;补充&lt;/h3&gt;
&lt;p&gt;从Rocky Linux8升级到Rocky Linux9不是官方支持的行为。&lt;/p&gt;
&lt;p&gt;升级后，可能面临在进行“dnf update”的时候，出现大量的“conflicting requests&quot;问题提示。这个问题可能由于来自CentOS7时候安装的部分软件。对于module的问题，可以这样进行解决。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Problem 1: conflicting requests
  - nothing provides module(platform:el8) needed by module gimp:2.8:8030020210427153901:c307c522.x86_64 from @modulefailsafe
 Problem 2: conflicting requests
  - nothing provides module(platform:el8) needed by module go-toolset:rhel8:8090020231117205530:da531176.x86_64 from @modulefailsafe
 Problem 3: conflicting requests
  - nothing provides module(platform:el8) needed by module mariadb:10.3:8080020230920001707:fd72936b.x86_64 from @modulefailsafe
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用 module reset命令可以一次解决。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dnf module reset -y gimp go-toolset mariadb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再次尝试 update，发现问题提示已经没有了。&lt;/p&gt;
&lt;h2&gt;完整更新过程&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# check current version
cat /etc/os-release 
# install epel
yum -y install epel-release
# install rpmconf and yum-utils
yum -y install rpmconf yum-utils
rpmconf -a #yes for all
# install dnf
yum -y install dnf
# remove yum and yum-metadata-parser
dnf -y remove yum yum-metadata-parser
# remove current yum repo, otherwise there may some issues
rm -rf /etc/yum
# install dnf
dnf -y upgrade

# uninstall any centos- related packages
rpm -e --nodeps `rpm -qa|grep centos-`

# install centos8 repo

rpm -ivh --nodeps --force https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/centos-linux-repos-8-3.el8.noarch.rpm

rpm -ivh --nodeps --force https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/centos-linux-release-8.5-1.2111.el8.noarch.rpm

rpm -ivh --nodeps --force https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/dracut-network-049-191.git20210920.el8.x86_64.rpm

rpm -ivh --nodeps --force https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/centos-gpg-keys-8-3.el8.noarch.rpm

dnf -y upgrade https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

# here I got an issue about ius, just remove it
dnf remove ius-release-1.0-156.ius.centos7.noarch
dnf remove ius

dnf clean all

# remove kernel
rpm -e --nodeps `rpm -qa|grep -i kernel`

# install centos8
dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync

# there still some issues, so move any not native repo to bak

cd /etc/yum.repos.d
ls
mv elasticsearch.repo elasticsearch.repo.bak
mv kibana.repo kibana.repo.bak
mv vmware-tools.repo vmware-tools.repo.bak
mv filebeat.repo filebeat.repo.bak

# just create a folder, and move the current repo files into the folder, then reinstall the centos 8 repo
 
# continure install centos8
dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync

# optional, if above command is not working, try this

minorver=8.5.2111
sudo sed -e &quot;s|^mirrorlist=|#mirrorlist=|g&quot;          -e &quot;s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/$minorver|g&quot;          -i.bak          /etc/yum.repos.d/CentOS-*.repo
dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync

#今天2024-01-30在升级一台bind服务器时，提示下面错误：
```shell
导入公钥成功
运行事务检查
错误：事务检查与依赖解决错误：
(mariadb &amp;gt;= 3:10.3.27 if mariadb) 被 mariadb-connector-c-3.1.11-2.el8_3.x86_64 需要
(mariadb-connector-c-config = 3.1.11-2.el8_3 if mariadb-connector-c-config) 被 mariadb-connector-c-3.1.11-2.el8_3.x86_64 需要
rpmlib(RichDependencies) &amp;lt;= 4.12.0-1 被 mariadb-connector-c-3.1.11-2.el8_3.x86_64 需要
(flatpak-selinux = 1.8.5-5.el8_5 if selinux-policy-targeted) 被 flatpak-1.8.5-5.el8_5.x86_64 需要
rpmlib(RichDependencies) &amp;lt;= 4.12.0-1 被 flatpak-1.8.5-5.el8_5.x86_64 需要

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时，需要从package里面安装对应的包。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm -ivh --nodeps --force https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/AppStream/x86_64/os/Packages/flatpak-1.8.5-5.el8_5.x86_64.rpm

rpm -ivh --nodeps --force https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/AppStream/x86_64/os/Packages/mariadb-connector-c-3.1.11-2.el8_3.x86_64.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装完毕后，再次
dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync&lt;/p&gt;
&lt;p&gt;会提示有冲突的包。然后继续下面的操作&lt;/p&gt;
&lt;h1&gt;there some conflict, remove it&lt;/h1&gt;
&lt;p&gt;rpm -e --nodeps sysvinit-tools-2.88-14.dsf.el7.x86_64
rpm -e --nodeps python36-rpmconf-1.1.7-1.el7.1.noarch
rpm -e --nodeps python-backports-1.0-8.el7.x86_64
rpm -e --nodeps python-six-1.9.0-2.el7.noarch
rpm -e --nodeps python-backports-ssl_match_hostname-3.5.0.1-1.el7.noarch&lt;/p&gt;
&lt;h1&gt;try again&lt;/h1&gt;
&lt;p&gt;dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync&lt;/p&gt;
&lt;h1&gt;still some conflict&lt;/h1&gt;
&lt;p&gt;rpm -e --nodeps python-ipaddress-1.0.16-2.el7.noarch&lt;/p&gt;
&lt;h1&gt;try again&lt;/h1&gt;
&lt;p&gt;dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync&lt;/p&gt;
&lt;h1&gt;pass, continue (yes for all)&lt;/h1&gt;
&lt;p&gt;rpmconf -a&lt;/p&gt;
&lt;h1&gt;install kernel and kernel-core&lt;/h1&gt;
&lt;p&gt;dnf install kernel kernel-core -y
dnf -y install shim grub2-tools-extra grubby grub2-common grub2-pc
dnf -y install grub2-tools-efi grub2-tools-minimal grub2-efi grub2-pc-modules grub2-tools&lt;/p&gt;
&lt;h1&gt;remove /etc/yum to make a clean install&lt;/h1&gt;
&lt;p&gt;rm -rf /etc/yum
dnf -y groupinstall &quot;Minimal Install&quot;&lt;/p&gt;
&lt;p&gt;reboot&lt;/p&gt;
&lt;h1&gt;check current version, it should be centos8&lt;/h1&gt;
&lt;p&gt;cat /etc/os-release&lt;/p&gt;
&lt;h1&gt;download rocky linux migration tool&lt;/h1&gt;
&lt;p&gt;dnf install git
git clone https://github.com/rocky-linux/rocky-tools.git&lt;/p&gt;
&lt;p&gt;cd rocky-tools/
cd migrate2rocky/
chmod u+x migrate2rocky.sh
./migrate2rocky.sh -r&lt;/p&gt;
&lt;h1&gt;some package detected conflict. remove any conflict packages&lt;/h1&gt;
&lt;p&gt;rpm -e python3-pyyaml-3.12-12.el8.x86_64
rpm -e python36-PyYAML-3.13-1.el7.x86_64&lt;/p&gt;
&lt;h1&gt;enable any module that missing&lt;/h1&gt;
&lt;p&gt;dnf module enable perl:5.26
dnf remove python-tornado-4.2.1-5.el7.x86_64&lt;/p&gt;
&lt;p&gt;#dnf --disablerepo &apos;*&apos; --enablerepo=extras swap centos-linux-repos centos-stream-repos
dnf clean all
dnf distro-sync&lt;/p&gt;
&lt;h1&gt;try migrate again&lt;/h1&gt;
&lt;p&gt;./migrate2rocky.sh -r&lt;/p&gt;
&lt;h1&gt;pass, continue and reboot&lt;/h1&gt;
&lt;p&gt;reboot&lt;/p&gt;
&lt;h1&gt;continue upgrade to rocky linux 9, it is not official yet, but it works&lt;/h1&gt;
&lt;h1&gt;modify the default grub, to boot rocky linux kernel by default&lt;/h1&gt;
&lt;p&gt;vi /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot&lt;/p&gt;
&lt;h1&gt;install rocky linux 9 repo&lt;/h1&gt;
&lt;p&gt;dnf upgrade --refresh
REPO_URL=&quot;https://download.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/Packages/r/&quot;
RELEASE_PKG=&quot;rocky-release-9.3-1.2.el9.noarch.rpm&quot;
REPOS_PKG=&quot;rocky-repos-9.3-1.2.el9.noarch.rpm&quot;
GPG_KEYS_PKG=&quot;rocky-gpg-keys-9.3-1.2.el9.noarch.rpm&quot;
sudo dnf install $REPO_URL/$RELEASE_PKG $REPO_URL/$REPOS_PKG $REPO_URL/$GPG_KEYS_PKG -y&lt;/p&gt;
&lt;h1&gt;remove unwanted packages&lt;/h1&gt;
&lt;p&gt;sudo dnf -y remove rpmconf yum-utils epel-release
sudo rm -rf /usr/share/redhat-logos&lt;/p&gt;
&lt;h1&gt;install rocky linux 9 packages&lt;/h1&gt;
&lt;p&gt;sudo dnf -y --releasever=9 --allowerasing --setopt=deltarpm=false distro-sync&lt;/p&gt;
&lt;h1&gt;uninstall any conflict packages&lt;/h1&gt;
&lt;p&gt;rpm -e --nodeps iptables-ebtables-1.8.5-11.el8.x86_64&lt;/p&gt;
&lt;h1&gt;try again&lt;/h1&gt;
&lt;p&gt;sudo dnf -y --releasever=9 --allowerasing --setopt=deltarpm=false distro-sync&lt;/p&gt;
&lt;h1&gt;build rpm conf&lt;/h1&gt;
&lt;p&gt;rpm --rebuilddb
reboot&lt;/p&gt;
&lt;h1&gt;check grub and make it rocky&lt;/h1&gt;
&lt;p&gt;vi /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>从CentOS7 升级到RockyLinux8</title><link>https://dididudu998.github.io/posts/%E5%8D%87%E7%BA%A7centos7%E5%88%B0rockylinux8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8D%87%E7%BA%A7centos7%E5%88%B0rockylinux8/</guid><pubDate>Thu, 30 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;下面是完整的升级记录&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	192  cat /etc/os-release
  193  yum -y install epel-release
  194  yum -y upgrade
  195  reboot
  196  yum -y install rpmconf yum-utils
  197  rpmconf -a
  198  yum -y install dnf
  199  dnf -y remove yum yum-metadata-parser
  200  rpm -e --nodeps `rpm -qa|grep centos-`
  201  rpm -ivh --nodeps --force https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/Packages/r/rocky-release-8.9-1.6.el8.noarch.rpm
  202  rpm -ivh --nodeps  --force https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/Packages/r/rocky-repos-8.9-1.6.el8.noarch.rpm
  203  rpm -ivh --nodeps --force https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/Packages/r/rocky-gpg-keys-8.9-1.6.el8.noarch.rpm
  204  dnf -y upgrade https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
  205  dnf clean all
  206  rpm -e --nodeps `rpm -qa|grep -i kernel`
  207  vi /usr/lib/python2.7/site-packages/sitecustomize.py(option)
  208  dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync
  
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;错误解决&lt;/h3&gt;
&lt;p&gt;运行上面的命令后，会有错误的提示，比如kernel-core-4.18需要安装什么软件包之类的。我们可以直接在/var/cache/dnf目录下找到这个kernel的安装包进行安装。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  212  find /var/cache/dnf -name *kernel-core-4.18*
  213  rpm -ivh --nodeps --force /var/cache/dnf/baseos-3e608afeebc9a90b/packages/kernel-core-4.18.0-513.9.1.el8_9.x86_64.rpm
  214  find /var/cache/dnf -name *dracut-network-049-228.git20230802.el8.x86_64*
  215  rpm -ivh --nodeps --force /var/cache/dnf/baseos-3e608afeebc9a90b/packages/dracut-network-049-228.git20230802.el8.x86_64.rpm
  216  dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;卸载冲突的包&lt;/h3&gt;
&lt;p&gt;这个要根据实际情况检查，有的确实是包冲突，要删除，有的并不是，可能是原来的repo中加载了一些rockylinux不太支持的包，需要禁用这些repo。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;217  rpm -e --nodeps sysvinit-tools-2.88-14.dsf.el7.x86_64
218  rpm -e --nodeps python36-six-1.14.0-2.el7.noarch
219  rpm -e --nodeps ython3-six-1.11.0-8.el8.noarch
221  rpm -e --nodeps python36-PyYAML-3.13-1.el7.x86_64
222  rpm -e --nodeps python-backports-ssl_match_hostname-3.5.0.1-1.el7.noarch
223  dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync

228  dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync

235  rpm -e --nodeps python36-six-1.14.0-3.el7.noarch
236  dnf install platform-python-setuptools-39.2.0-7.el8.noarch
237  dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync
238  rpm -e --nodeps platform-python-setuptools-39.2.0-7.el8.noarch
239  rpm -e --nodeps python-six-1.3.0-4.el7.noarch 

245  dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;依然会有错误提示&lt;/p&gt;
&lt;p&gt;检查当前更新源，将里面无关的都修改掉&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; 
  258  dnf repolist
  259  cd /etc/dnf/
  260  vi dnf.conf
  261  cd /etc/yum.repos.d
  262  ls
  263  mv epel-testing-modular.repo epel-testing-modular.repo.bak
  264  mv epel-testing.repo epel-testing.repo.bak
  265  mv salt-latest.repo salt-latest.repo.bak
  266  mv salt-py3-latest.repo salt-py3-latest.repo.bak
  267  mv zabbix-non-supported.repo zabbix-non-supported.repo.bak
  268  mv zabbix.repo zabbix.repo.bak
       mv docker-ce.repo docker-ce.repo.bak
  269  dnf upgrade
  270  rpm -e --nodeps python-linux-procfs-0.4.11-4.el7.noarch
  271  rpm -e --nodeps gdbm-1.10-8.el7.x86_64
  272  dnf upgrade
  273  dnf upgrade --best --allowerasing rpm
  274  dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync
 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装内核和最小化系统&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;  278  dnf -y install kernel-core
  279  dnf -y groupupdate &quot;Core&quot; &quot;Minimal Install&quot;
  281  shutdown -r now
  282  cat /etc/os-release 
 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此，更新完成。&lt;/p&gt;
</content:encoded></item><item><title>kerberoasting攻击</title><link>https://dididudu998.github.io/posts/kerberoasting%E6%94%BB%E5%87%BB/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/kerberoasting%E6%94%BB%E5%87%BB/</guid><pubDate>Wed, 29 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;kerberoasting攻击&lt;/h1&gt;
&lt;p&gt;原文地址为：
&lt;a href=&quot;https://adsecurity.org/?p=3458&amp;amp;ref=qomplx.com&quot;&gt;Detecting Kerberoasting Activity&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;简要说明&lt;/h2&gt;
&lt;p&gt;当我们通过破解或者社工有了一个活动目录域内的正常用户的时候，我们就可以尝试这样的攻击。举个例子，在test.com域内有一个我们已经知晓的账户名为user1，密码为12345的账户。我们就可以尝试setspn的命令获取域内的服务账户的信息。&lt;/p&gt;
&lt;p&gt;假设我们获得了服务账户为service1，spn是mssqlsvc/test.com:1433，我们就可以使用下面的方式进行尝试获取TGS，然后进行线下破解。&lt;/p&gt;
&lt;p&gt;破解出来的密码，就是service1的密码。&lt;/p&gt;
&lt;p&gt;下面就可以用service1这个账户进行后续的操作。&lt;/p&gt;
&lt;p&gt;kali中已经包含了对应的攻击脚本：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;获取当前域中的SPN信息&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; GetUserSPNs.py test.com/user1:123456
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;请求TGS&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;GetUserSPNs.py test.com/user1:123456 -request
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;将输出的TGS加密信息存入info.txt文件&lt;/li&gt;
&lt;li&gt;利用hashcat 获取其中TGS-REP的信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;hashcat -h ｜grep &apos;Kerberos&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;假设获取到的TGS-REP的其实位置是13100.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; hashcat -m 13100 info.txt words.txt 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;等待破解，破解成功后会显示信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;kerberoasting用来对活动目录中的服务账户进行攻击。&lt;/p&gt;
&lt;p&gt;一般来说在不那么严谨的环境下，服务账户的密码几乎不进行修改，而且长度也和普通用户的密码长度大致一样，而且服务账户一般会永久或者长期持有，如果服务账户被攻破了，那么就相当于在活动目录域内有了个可以自由移动的特权账户。&lt;/p&gt;
&lt;h2&gt;kerberos验证过程&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/KerberosComms.png&quot; alt=&quot;d273a506688ac9e3a6763f4506b6f35b.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上面是账户在活动目录域内的验证过程。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户的密码转化为NTLM 哈希，然后将当前的时间戳加密，将这个哈希和加密的时间戳发送给KDC用于获取TGT&lt;/li&gt;
&lt;li&gt;KDC检查用户的信息，包括登录限制，组成员信息等，然后创建一个TGT（ticket-granting ticket）&lt;/li&gt;
&lt;li&gt;这个TGT是加密并进行了签名，然后发回给用户。在整个域中，只有kerveros service（krgtgt）才能打开和读取这个TGT的数据&lt;/li&gt;
&lt;li&gt;当用户需要请求一个TGS（ticket granting service）ticket的时候，他需要将这个TGT给DC进行检查。DC打开TGT并且验证其中的PAC校验和是否正确，如果可以打开，并且校验和正确，那么DC就认为这个TGT是正确无误的。然后将TGT内的数据信息拷贝到TGS ticket里面&lt;/li&gt;
&lt;li&gt;TGS通过目标机器的服务账户的NTLM 密码哈希进行加密，然后发回给用户&lt;/li&gt;
&lt;li&gt;用户连接到要访问的目标机器的对应的端口后，向目标机器展示TGS的信息，目标机器的服务利用其自身的NTLM密码的哈希打开TGS ticket&lt;/li&gt;
&lt;li&gt;服务接收所有TGS ticket的数据，不需要和DC再进行通讯&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;攻击步骤&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;对域内的服务账户进行扫描
&lt;ul&gt;
&lt;li&gt;在活动目录中，任何已经验证的用户都可以查询SPN&lt;/li&gt;
&lt;li&gt;攻击者往往对于有特权服务账户非常感兴趣，如果一个账户属性里面包含“AdminCount=1”，那就是了&lt;/li&gt;
&lt;li&gt;查询命令&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;get-aduser -filter {AdminCount -eq 1} -prop * | select name,created,passwordlastset,lastlogondate

Get-NetUser -AdminCount | Select name,whencreated,pwdlastset,lastlogon
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过上面获取到的信息，就可以确定服务账户了。&lt;/p&gt;
&lt;p&gt;还有就是可以参考下面的信息来确认服务账户的类型：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;AGPMServer： 对GPO有完全管理权限&lt;/li&gt;
&lt;li&gt;MSSQL/MSSQLSvc：对MS SQL server有管理权限&lt;/li&gt;
&lt;li&gt;FIMService：对多个活动目录森林有管理权限&lt;/li&gt;
&lt;li&gt;STS：是VMware SSO服务&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;开始攻击&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目的是获取一个针对目标服务账户的SPN的TGS即可。&lt;/p&gt;
&lt;p&gt;需要做的是，用一个当前正常可用的域用户的TGT来请求目标服务器上面的目标服务的服务票据。&lt;/p&gt;
&lt;p&gt;域控制器查询活动目录内的SPN，然后用服务账户的NTLM密码的哈希来加密这个服务票据，加密的方式是RC4_HMAC_MD5。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;获取TGS&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;$SPNName=&apos;MSSQLSvc/adsmsDB01.adsecurity.org:1433&apos;
Add-Type -AssemblyNAme System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/K-01.jpg&quot; alt=&quot;d273a506688ac9e3a6763f4506b6f35b.png&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用mimikatz从内存中获取票据&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/K-02.jpg&quot; alt=&quot;7f5cbe44ac63c0e66f0ef4ace8a4d0f8.png&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;暴力破解&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;使用john the ripper或者hash cat 或者kali里面的tgsrepcrack进行破解获取明文密码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/K-03.jpg&quot; alt=&quot;d9e8c3a0ed54e93cbfb062e6f046c766.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;防御措施&lt;/h2&gt;
&lt;p&gt;在Windows服务器的操作系统中，已经有了一些针对服务账户的保护措施。比如使用服务组账户，这个账户是默认30天会自行变更的，不会像普通的账户那样，密码长期不变，而且整个的变更过程都是活动目录系统自行完成的，不需要人的参与。&lt;/p&gt;
&lt;p&gt;还有就是要求普通客户端进行AD验证的时候不允许RC4这样的加密算法，而统一要求AES这样的加密算法，比如不允许使用SMB1这样的协议来连接文件服务。&lt;/p&gt;
</content:encoded></item><item><title>做事的过程</title><link>https://dididudu998.github.io/posts/%E5%81%9A%E4%BA%8B%E7%9A%84%E8%BF%87%E7%A8%8B/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%81%9A%E4%BA%8B%E7%9A%84%E8%BF%87%E7%A8%8B/</guid><pubDate>Tue, 28 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这是一个循环的过程，或者是一个螺旋形的向上的过程。人们在不断的用这个过程提升自己的认知，并获取各种反馈。&lt;/p&gt;
&lt;p&gt;这个过程就是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
	participant 想法idea
	participant 产品product
	participant 数据data
	
	想法idea -&amp;gt;&amp;gt; 产品product: 通过开发build
	产品product -&amp;gt;&amp;gt; 数据data: 通过测量measure
	数据data -&amp;gt;&amp;gt; 想法idea: 通过认知learn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;精益创业提出的一个非常重要的概念，最小可行产品。minimum viable product，简单说就是用最少的钱，做更多的事。&lt;/p&gt;
&lt;p&gt;当别人要求去做一件事的时候，一般我们只要做自己弄清楚为什么要做这件事的时候再动手去做，否则就尽量的弄清楚，要不然期望不匹配，做出来的东西可能只是在耗费时间，并不能产生价值。在这个时候，有效的沟通也是非常必要的，简短扼要，有重点的沟通，可以实现信息的共享，并拓宽思路。当然是在同等的能力或者更高的能力的范围内的，和一个较低技能和水平的人进行沟通的结果可能带来混乱。&lt;/p&gt;
&lt;p&gt;在进行渗透测试的时候，最重要的步骤就是信息收集，在一个技术能力相同的层级上，哪个人收集的信息越多，他获得突破口的可能性越大。&lt;/p&gt;
&lt;p&gt;在解决问题和提升自己的过程中，也是如此。要从本身岗位的获取到的信息的上面的几层进行思考，越是获得的信息越多，思考的维度越高，对于做事情来说更有效率，带来的价值更大。&lt;/p&gt;
&lt;p&gt;很多人可以完成自己本职工作的事情，但是这样规规矩矩的，很难有什么大的进步。当了解到了更多的上下文后，信息的带宽增加了，信息量也增加了，也就更容易让自己做到最好的判断和选择。&lt;/p&gt;
&lt;p&gt;大部分的人做事情都是缺乏完整的过程的。他们领到一个任务的时候，考虑到的是要尽快的干完。但是这个任务的本身到底是要干什么，为什么服务没有搞清楚。而且很多人的目标就是做完而已，没有什么做好，承上启下的这样的认知。这也是大部分的人很难获得提升的原因。认知的维度较低，就比较难看到全局，而看不到全局，就很难做出优化的方案出来。所提到的人人都是螺丝钉的这样的情况，到最后难以实现个人的价值，主要还是难以提升自己的认知。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;下面是一些行业的最佳实践&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DoD（definite of done），做好完成的定义，减少团队内部的理解不一致&lt;/li&gt;
&lt;li&gt;要有用户故事，细化出有价值的需求&lt;/li&gt;
&lt;li&gt;持续集成，通过尽早集成，减少改动量，降低合并难度&lt;/li&gt;
&lt;li&gt;迭代0，在启动项目前，做好必要的基础准备&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;一些必要的思考方式&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;现在头脑中进行创造，然后再付诸实践&lt;/li&gt;
&lt;li&gt;获取信息，获取其来自特定方向的信息的上下文，才能更好的了解最终想要做什么&lt;/li&gt;
&lt;li&gt;要边做边推演，逐渐修正最合适和高效的路径，达到期望的结果&lt;/li&gt;
&lt;li&gt;要用可度量的数字来定义期望和问题&lt;/li&gt;
&lt;li&gt;应该做到“以终为始”，这样做事比较踏实&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>给Linux进行批量部署</title><link>https://dididudu998.github.io/posts/%E7%BB%99linux%E8%BF%9B%E8%A1%8C%E6%89%B9%E9%87%8F%E9%83%A8%E7%BD%B2/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%BB%99linux%E8%BF%9B%E8%A1%8C%E6%89%B9%E9%87%8F%E9%83%A8%E7%BD%B2/</guid><pubDate>Tue, 28 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;一早上，说什么前阵子装的很多agent，没有发现连接到服务器，可能有些人安装的不对，要重新装一下。&lt;/p&gt;
&lt;p&gt;自己以前写过个shell，用于批量配置，这不刚好改改就能用了。&lt;/p&gt;
&lt;p&gt;情况是，各个linux的主机有不同的密码，账户都是root，那就需要建立一个账户文件，包含远端机器的IP地址，root，还有密码。&lt;/p&gt;
&lt;p&gt;然后逐行读取这三个信息，用来ssh连接远端机器，连接完成后，提前将要执行的动作写入一个shell文件，然后sftp到远端机器去，再进行执行，执行后将输出写入当前的目录的log.txt文件中。&lt;/p&gt;
&lt;p&gt;目录结构如下：&lt;/p&gt;
&lt;p&gt;├── account.csv&lt;br /&gt;
├── command.py&lt;br /&gt;
├── install.sh&lt;br /&gt;
└── log.txt&lt;/p&gt;
&lt;p&gt;其中install.sh是要执行的shell文件，log.txt是执行后生成的日志。&lt;/p&gt;
&lt;p&gt;account.csv的格式如下：
用空格隔开，IP地址，账户名和密码​&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10.1.2.3 root password
10.1.2.5 root newpass
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是python的代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import csv
import paramiko


def ssh_command(ip, username, password):
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    try:
        ssh_client.connect(ip, username=username, password=password)

        sftp = ssh_client.open_sftp()
        local_sh = &quot;install.sh&quot;
        remote_path = &apos;/tmp/install.sh&apos;
        sftp.put(local_sh, remote_path)
        sftp.close()

        stdin, stdout, stderr = ssh_client.exec_command(
            &apos;chmod +x {} &amp;amp;&amp;amp; {}&apos;.format(remote_path, remote_path))

        # stdin, stdout, stderr = ssh_client.exec_command(&apos;/tmp/install.sh&apos;)
        # 等待命令执行完成
        exit_status = stdout.channel.recv_exit_status()
        # 处理命令执行结果并记录到 log.txt 文件中
        with open(&apos;log.txt&apos;, &apos;a&apos;) as log_file:
            log_file.write(f&quot;=== Output for {ip} ===\n&quot;)
            log_file.write(stdout.read().decode(&quot;utf-8&quot;))
            log_file.write(f&quot;Exit status: {exit_status}\n&quot;)
    except paramiko.AuthenticationException:
        print(f&quot;Failed to log in to {ip} with provided credentials.&quot;)
    finally:
        ssh_client.close()


with open(&apos;account.csv&apos;, &apos;r&apos;) as csvfile:
    csv_reader = csv.reader(csvfile, delimiter=&apos; &apos;)
    # next(csv_reader)  # 跳过标题行
    for row in csv_reader:
        ip = row[0]
        username = row[1]
        password = row[2]
        # command_to_run = &quot;install.sh&quot;  # 替换为要执行的脚本命令
        ssh_command(ip, username, password)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过测试，可以实现效果。后面也可以用os.remove删掉上传到远端的shell文件。&lt;/p&gt;
</content:encoded></item><item><title>ntopng流量监控</title><link>https://dididudu998.github.io/posts/ntopng%E5%92%8C%E9%98%B2%E7%81%AB%E5%A2%99/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/ntopng%E5%92%8C%E9%98%B2%E7%81%AB%E5%A2%99/</guid><pubDate>Sun, 26 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;较早前在一台电脑上用docker跑了openvpn，然后其他机器连接这个vpn来进行互相连接。&lt;/p&gt;
&lt;p&gt;为了能显示更清楚的网络流量，在这台openvpn服务器上，又安装了ntop。&lt;/p&gt;
&lt;p&gt;Ubuntu上安装很简单，就是apt install ntopng就好了。&lt;/p&gt;
&lt;p&gt;然后配置/etc/ntopng.conf,在里面填上可以访问的IP地址和端口号，要不然只有local only的访问。&lt;/p&gt;
&lt;p&gt;类似这样：&lt;/p&gt;
&lt;p&gt;--https-port=10.212.130.251:3002&lt;/p&gt;
&lt;p&gt;然后访问https://10.212.130.251:3003，默认账户admin，admin。&lt;/p&gt;
&lt;p&gt;如果忘记了密码，可以用下面的方法重置为默认密码：&lt;/p&gt;
&lt;p&gt;redis-cli del ntopng.user.admin.password&lt;/p&gt;
&lt;p&gt;重置后，必须重启服务systemctl restart ntopng&lt;/p&gt;
&lt;p&gt;还有如果想要重新设置admin密码，可以这么做：&lt;/p&gt;
&lt;p&gt;echo -n &quot;newpassword&quot; | md5sum
5e9d11a14ad1c8dd77e98ef9b53fd1ba  -&lt;/p&gt;
&lt;p&gt;然后
redis-cli set ntopng.user.admin.password 5e9d11a14ad1c8dd77e98ef9b53fd1ba&lt;/p&gt;
&lt;p&gt;重启服务后，就可以用newpassword做密码登录了。&lt;/p&gt;
&lt;p&gt;我这么做的原因是，在web上面，我想要增加用户和修改密码都没有反应，不知道原因。&lt;/p&gt;
&lt;p&gt;所以才直接修改redis。&lt;/p&gt;
&lt;p&gt;还有就是为了安全，我只限定管理机器能够访问它。&lt;/p&gt;
&lt;p&gt;10.x.x.x是我的管理机器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ufw allow from 10.x.x.x 
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试用别的机器访问web，已经不可以了。&lt;/p&gt;
</content:encoded></item><item><title>技能树</title><link>https://dididudu998.github.io/posts/skilltree/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/skilltree/</guid><pubDate>Wed, 22 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://skilltreeplatform.dev&quot;&gt;skilltreeplatform&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At the heart of the platform is the SkillTree Dashboard that acts as a Learning Management System (LMS) and enables to directly embedding SkillTree&apos;s Skills Display into one more existing/new web applications. SkillTree Platform supports both of these use-cases under a single installation of a SkillTree Dashboard - an organization can author multiple training profiles where some of these trainings are taken directly in the SkillTree&apos;s Dashboard and some are embedded into home-grown applications and taken/followed within those applications.&lt;/p&gt;
</content:encoded></item><item><title>恢复docker数据</title><link>https://dididudu998.github.io/posts/%E6%81%A2%E5%A4%8Ddocker%E6%95%B0%E6%8D%AE/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%81%A2%E5%A4%8Ddocker%E6%95%B0%E6%8D%AE/</guid><pubDate>Tue, 21 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;获取原来的数据&lt;/h2&gt;
&lt;p&gt;在做从centos7到rockeylinux9的升级的时候，忘了导出原来docker里面还在跑的taiga的数据。还好做了快照，今天将数据恢复回来。&lt;/p&gt;
&lt;p&gt;恢复到旧的centos7的时候，可能是快照打的时间差了，里面的docker已经无法启动，那么docker volume也不能用了。&lt;/p&gt;
&lt;p&gt;只有直接进/var/lib/docker/volumes里面去找对应的volumes。&lt;/p&gt;
&lt;p&gt;还好里面的各个volume都在，先scp -r到外面的一台中转服务器上去。&lt;/p&gt;
&lt;p&gt;还有重要的是要拿到以前的配置文件，我当时做了邮件，证书，代理的一些配置。&lt;/p&gt;
&lt;p&gt;找到taiga-docker文件夹，拷贝里面的env和yml文件出来，同样的到中转服务器。&lt;/p&gt;
&lt;h2&gt;安装docker在rockylinux9&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl status docker
sudo systemctl enable docker
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;还原原来的数据&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;git clone https://github.com/kaleidos-ventures/taiga-docker&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;cd taiga-docker&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git checkout stable&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mv docker-compose.yml docker-compose.yml.bak&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将中转机器上面的docker-compose.yml拷贝到单签文件夹中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;docker compose up -d&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;docker compose -f docker-compose.yml -f docker-compose-inits.yml run --rm taiga-manage createsuperuser&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;检查服务是否都已经跑起来了。访问在docker-compoose里面设置的url看看能不能访问。&lt;/p&gt;
&lt;p&gt;如果可以的话，接下来就是还原数据。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;systemctl stop docker&lt;/li&gt;
&lt;li&gt;scp -r将中转服务器里面的taiga-docker_taiga-db-data文件夹复制到/var/lib/docker/volumes中&lt;/li&gt;
&lt;li&gt;systemctl start docker&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;可能的问题&lt;/h2&gt;
&lt;p&gt;如果不能访问，那么就在taiga-docker目录下，再运行一遍 docker compose up -d。&lt;/p&gt;
&lt;p&gt;有时候会提示rabbitmq服务错误，不要管他，再docker compose up -d几次，就会好的。&lt;/p&gt;
&lt;p&gt;然后访问原来的url，就能看到以前的数据了，添加新的试了下，也没问题了。&lt;/p&gt;
&lt;h2&gt;结论&lt;/h2&gt;
&lt;p&gt;升级操作系统，是比较麻烦的事情。要做好计划列表，梳理好已有的服务，然后做好备份，这样才能避免数据的损失。&lt;/p&gt;
</content:encoded></item><item><title>ELK与安全的一些配置</title><link>https://dididudu998.github.io/posts/elk%E5%92%8C%E5%AE%89%E5%85%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/elk%E5%92%8C%E5%AE%89%E5%85%A8/</guid><pubDate>Fri, 03 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;前些日子不是搞什么记录用户登录到机器后执行的命令的行为的事情吗？7月份的时候，将session记录脚本放到用户的profile里面，只要登录就调取session，然后记录用户执行的命令和输出。&lt;/p&gt;
&lt;p&gt;但是这个有点太彻底了。今天将尘封已久的ELK又拉出来，在这个上面做个测试。&lt;/p&gt;
&lt;p&gt;我的这台ELK已经运行了有3年的时间了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@detect-risky-01 ~]# rpm -qi setup
Name        : setup
Version     : 2.8.71
Release     : 11.el7
Architecture: noarch
Install Date: 2020年09月09日 星期三 21时44分52秒
Group       : System Environment/Base
Size        : 697141
License     : Public Domain
Signature   : RSA/SHA256, 2020年04月03日 星期五 17时21分58秒, Key ID 24c6a8a7f4a80eb5
Source RPM  : setup-2.8.71-11.el7.src.rpm
Build Date  : 2020年04月01日 星期三 00时29分34秒
Build Host  : x86-02.bsys.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem &amp;lt;http://bugs.centos.org&amp;gt;
Vendor      : CentOS
URL         : https://pagure.io/setup/
Summary     : A set of system configuration and setup files
Description :
The setup package contains a set of important system configuration and
setup files, such as passwd, group, and profile.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原来一直是在vcenter上做了端口映射，用于分析和记录所有不同vLAN的虚拟机的网络流量的。用的是提供的packetbeat进行流量分析。然后呈现到kibana。&lt;/p&gt;
&lt;p&gt;而ELK本身就提供了system log的显示功能，只要安装Filebeat然后简单配置就可以了。&lt;/p&gt;
&lt;p&gt;然后，在filebeat system这个看板里面就能看到一些信息，包括syslog，执行的sudo命令，ssh登录，以及新添加的用户和组信息等。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/elk-syslog.jpg&quot; alt=&quot;syslog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/elk-ssh.jpg&quot; alt=&quot;syslog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个看起来要比用邮件看到的更友好，而且ELK本身带报警功能，可以更好的防范。&lt;/p&gt;
&lt;p&gt;ELK在数据分析上面和安全上面真的很不错。配置简单，运行也简单，而且支持外部CSV，excel等文件的导入。对于中小企业真的是很友好。&lt;/p&gt;
</content:encoded></item><item><title>获取当前系统上安装的java信息</title><link>https://dididudu998.github.io/posts/%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E5%AE%89%E8%A3%85%E7%9A%84java%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E5%AE%89%E8%A3%85%E7%9A%84java%E4%BF%A1%E6%81%AF/</guid><pubDate>Sat, 28 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近在温习web安全的一些内容，就想着继续做点题动动手看看。下载了webgoat，但是运行的时候发现提示我java版本不对，我这java程序都可以跑啊，怎么就不对了，说是java的版本太低，按照webgoat的提示，去java站点下载最新的jdk，安装,删除旧的JAVA版本文件夹，更新JAVA_HOME，再次运行webgoat就可以了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/usr/libexec/java_home -V        
                                                13:36:25
Matching Java Virtual Machines (2):
    21.0.1 (x86_64) &quot;Oracle Corporation&quot; - &quot;OpenJDK 21.0.1&quot; /Library/Java/JavaVirtualMachines/jdk-21.0.1.jdk/Contents/Home
    1.8.391.13 (x86_64) &quot;Oracle Corporation&quot; - &quot;Java&quot; /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
/Library/Java/JavaVirtualMachines/jdk-21.0.1.jdk/Contents/Home
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>AdGuard Home的使用</title><link>https://dididudu998.github.io/posts/adguardhome/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/adguardhome/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 13 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;AdGuard在手机上用了大概有3年多了，最新的4.1版本装了又卸载了，没有旧的版本用起来清楚，而且带的效果太重，感觉反应也不快。&lt;/p&gt;
&lt;p&gt;然后上Adguard Home的repo上，下载了macOS和windows的，分别装在了用的机器上，这个电脑版配置起来方便很多。基本上都是傻瓜话的，唯一的区别是和安卓版本的是电脑版没有自动设定dns，以及对自身ip进行隐藏等隐私相关的设定。&lt;/p&gt;
&lt;p&gt;不过去广告的功能都是一样的。&lt;/p&gt;
&lt;p&gt;下载地址： https://github.com/AdguardTeam/AdGuardHome/releases&lt;/p&gt;
&lt;p&gt;但是对于顽固的页面内广告，Adguard的作用不大，还是得浏览器插件，例如ublock这样的。&lt;/p&gt;
</content:encoded></item><item><title>手机上的termux</title><link>https://dididudu998.github.io/posts/%E6%89%8B%E6%9C%BA%E4%B8%8A%E7%9A%84termux/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%89%8B%E6%9C%BA%E4%B8%8A%E7%9A%84termux/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 13 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在安卓手机上安装termux是一直以来的习惯，而且这个帮我解决了好几次远程支持的事情。当只有手机，没有电脑在身边的时候，利用termux这个linux环境，ssh到机器进行排错和修改，是最好的方式了。&lt;/p&gt;
&lt;p&gt;除了ssh外，当然还需要装一些开发环境，做更好玩的事情，否则手机的利用率太低了，毕竟现在手机的计算能力和存储能力已经有超越笔记本的趋势。&lt;/p&gt;
&lt;p&gt;首先就是安装python环境，如果repo不好用的话，还可以termux-change-repo.&lt;/p&gt;
&lt;p&gt;装上python环境后，可干的事情就多了。举例说明：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我爬取一些社交网站自己一直关注的人的信息，然后进行清理，就不用打开手机app去看了，手机app上面还有广告。&lt;/li&gt;
&lt;li&gt;一些美图的图片，可以爬取下载下来，慢慢看，一次下个几百张&lt;/li&gt;
&lt;li&gt;原来自己写的一些对我个人觉得有用的，也可以转到手机上来了&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;使用手机除了屏幕小以外，各种信息经过了清理，最后汇聚出来的都是精华的信息，甚至有的app都不需要装了，即不用看广告，也不需要什么实名注册，麻烦死了。&lt;/p&gt;
&lt;p&gt;举个抓Instagram的例子😄：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import subprocess
import signal 

def signal_handler(sig,frame):
    print(&quot;quit!&quot;)
    exit(0)

signal.signal(signal.SIGINT,signal_handler)
try:
    with open(&quot;account.txt&quot;,&apos;r&apos;) as f:
        for line in f:
            id=line.strip()
            if id:
                subprocess.run([&apos;instaloader&apos;,&apos;--latest-stamps&apos;,&apos;--&apos;,&apos;profile&apos;,id])
except Exception as e:
    print(e)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>使用parsehub抓取indeed.com上的工作信息</title><link>https://dididudu998.github.io/posts/%E4%BD%BF%E7%94%A8parsehub%E6%8A%93%E5%8F%96indeedcom%E4%B8%8A%E7%9A%84%E5%B7%A5%E4%BD%9C%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BD%BF%E7%94%A8parsehub%E6%8A%93%E5%8F%96indeedcom%E4%B8%8A%E7%9A%84%E5%B7%A5%E4%BD%9C%E4%BF%A1%E6%81%AF/</guid><description>获取网络上的公开信息</description><pubDate>Wed, 19 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;使用 parsehub 抓取 indeed.com 上的工作信息&lt;/h1&gt;
&lt;h2&gt;什么是 parsehub&lt;/h2&gt;
&lt;p&gt;parsehub 是一款免费的网络爬虫工具，可以用来抓取网络上的公开信息。&lt;/p&gt;
&lt;p&gt;整体的操作比较简单，在一些不需要自己写代码的情况下，利用这个工具也能获取到较好的信息。&lt;/p&gt;
&lt;h2&gt;使用过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;首先建立新的 project&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输入要抓取的 URL: &quot;https://www.indeed.com/jobs?q=cyber+security&amp;amp;l=New+York%2C+NY&amp;amp;vjk=1b266e77a688b9f8&quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;parsehub 会开启浏览页面到该 URL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后选中职位名称，对每个职位名称进行点击，点击后进入第二个页面&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第二个页面是获取岗位的具体信息的页面&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择岗位名称和岗位信息，然后选择 relatives,对岗位描述进行解析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;至此，岗位的信息拿到了。还需要对多页面的信息进行解析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;返回到主模板，增加新 page，选择翻页，循环，然后设定翻页的次数，我这里设定为 10 页。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;保存，运行。就能获取到网页的信息了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;获取信息后，要对信息中重复的行进行删除。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;def remove_duplicates(input_file, output_file):
    unique_lines = set()

    with open(input_file, &apos;r&apos;) as infile:
        for line in infile:
            # Remove leading and trailing whitespaces and newlines
            cleaned_line = line.strip()

            # Add the cleaned line to the set if it&apos;s not already present (removing duplicates)
            if cleaned_line not in unique_lines:
                unique_lines.add(cleaned_line)

    with open(output_file, &apos;w&apos;) as outfile:
        # Write the unique lines back to the output file
        for line in unique_lines:
            outfile.write(line + &apos;\n&apos;)

# Usage example
input_file_path = &apos;/Users/Mark/Downloads/run_results_SRE.csv&apos;   # Replace with the path to your input file
output_file_path = &apos;/Users/Mark/Downloads/indeed_SRE_clean.csv&apos; # Replace with the path for the output file
remove_duplicates(input_file_path, output_file_path)

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;删除后，还可以整个词云图片看看&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;import os
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from collections import Counter
from wordcloud import WordCloud
import matplotlib.pyplot as plt

# Download the stopwords (you only need to do this once)
nltk.download(&apos;stopwords&apos;)
nltk.download(&apos;punkt&apos;)

def process_text(file_path):
    with open(file_path, &apos;r&apos;) as file:
        text = file.read().lower()  # Convert to lowercase for case-insensitive word counting

    # Tokenize the text
    tokens = word_tokenize(text)

    # Remove stopwords
    stop_words = set(stopwords.words(&apos;english&apos;))
    filtered_tokens = [word for word in tokens if word.isalpha() and word not in stop_words]

    # Count word frequencies
    word_freq = Counter(filtered_tokens)

    return word_freq

def generate_wordcloud(word_freq, output_file):
    wordcloud = WordCloud(width=800, height=400, background_color=&apos;white&apos;).generate_from_frequencies(word_freq)

    plt.figure(figsize=(10, 5))
    plt.imshow(wordcloud, interpolation=&apos;bilinear&apos;)
    plt.axis(&apos;off&apos;)
    plt.savefig(output_file)
    plt.show()

# Main script
input_file_path = &apos;/Users/Mark/Downloads/indeed_SRE_clean.csv&apos;   # Replace with the path to your input text file
output_image_path = &apos;wordcloud_SRE.png&apos; # Replace with the path where you want to save the word cloud image

word_freq = process_text(input_file_path)
generate_wordcloud(word_freq, output_image_path)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是倒出来的 ParseHub 这个项目的文件,以后要用的时候可以将其存为 indeed.phj 文件，然后导入即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{&quot;title&quot;:&quot;indeed.com Project&quot;,&quot;templates_json&quot;:&quot;[{\&quot;op\&quot;:\&quot;template\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:1,\&quot;label\&quot;:\&quot;page\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;BODY\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:1,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:true,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;name\&quot;:\&quot;main_template\&quot;,\&quot;endAtDuplicate\&quot;:true,\&quot;clearSession\&quot;:false,\&quot;loadJs\&quot;:\&quot;default\&quot;,\&quot;preserveOrder\&quot;:\&quot;default\&quot;,\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:235,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:null,\&quot;classes\&quot;:[\&quot;desktop\&quot;,\&quot;css-kyg8or\&quot;],\&quot;styles\&quot;:[],\&quot;position\&quot;:0,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:true,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:244,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:null,\&quot;classes\&quot;:[\&quot;e37uo190\&quot;],\&quot;styles\&quot;:[],\&quot;position\&quot;:0,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:true,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:247,\&quot;label\&quot;:\&quot;jobtitle\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;SPAN\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:0,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:true,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:true,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:true,\&quot;persGroupPosMat\&quot;:{\&quot;selectionSpecs\&quot;:[{\&quot;chunkTree\&quot;:{\&quot;htmlChunks\&quot;:[\&quot;32cf9019e6ff298c892413bb38266620\&quot;,\&quot;c7190d67ab4cf47a0cf2551fe7fbb838\&quot;,\&quot;9b6a145dde650efd786fa65832364434\&quot;,\&quot;3be9ac284abab500e65b96f5acbfb3dd\&quot;,\&quot;918fcbfc471e400b4cb6cfb0c3224411\&quot;,\&quot;d0e2a53e8899098fdac0a0db47fc4904\&quot;,\&quot;b09b3e3a03c53685bdcf7d6bdc3a3143\&quot;,\&quot;3518728bb5c3c25662ff956dd974c89f\&quot;,\&quot;2ec3c70439c28fc2a7095c39630a84e5\&quot;,\&quot;fb8de55afab59a869a522e1efd0543c5\&quot;,\&quot;844045c8b44c43afec000bd6d761fcb9\&quot;,\&quot;8f699817bad3f09b16093288b164d433\&quot;,\&quot;d52b01c2ff91923856af961fba413140\&quot;,\&quot;8c4af3484a748cf887fd3d4283c678e1\&quot;,\&quot;05617e6fb28414d11b2e28c299234381\&quot;,\&quot;08bfc108cfebd43f8e001300d7fd147a\&quot;],\&quot;framesChunks\&quot;:[{\&quot;htmlChunks\&quot;:[\&quot;0435747e5ac37d504d88c6102e343128\&quot;],\&quot;framesChunks\&quot;:[],\&quot;uniqueArray\&quot;:[7,1]}]},\&quot;uniqueArray\&quot;:[0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,4,1,0,1,1,2,1]},{\&quot;chunkTree\&quot;:{\&quot;htmlChunks\&quot;:[\&quot;32cf9019e6ff298c892413bb38266620\&quot;,\&quot;c7190d67ab4cf47a0cf2551fe7fbb838\&quot;,\&quot;9b6a145dde650efd786fa65832364434\&quot;,\&quot;3be9ac284abab500e65b96f5acbfb3dd\&quot;,\&quot;918fcbfc471e400b4cb6cfb0c3224411\&quot;,\&quot;d0e2a53e8899098fdac0a0db47fc4904\&quot;,\&quot;b09b3e3a03c53685bdcf7d6bdc3a3143\&quot;,\&quot;3518728bb5c3c25662ff956dd974c89f\&quot;,\&quot;2ec3c70439c28fc2a7095c39630a84e5\&quot;,\&quot;fb8de55afab59a869a522e1efd0543c5\&quot;,\&quot;844045c8b44c43afec000bd6d761fcb9\&quot;,\&quot;8f699817bad3f09b16093288b164d433\&quot;,\&quot;d52b01c2ff91923856af961fba413140\&quot;,\&quot;8c4af3484a748cf887fd3d4283c678e1\&quot;,\&quot;05617e6fb28414d11b2e28c299234381\&quot;,\&quot;08bfc108cfebd43f8e001300d7fd147a\&quot;],\&quot;framesChunks\&quot;:[{\&quot;htmlChunks\&quot;:[\&quot;0435747e5ac37d504d88c6102e343128\&quot;],\&quot;framesChunks\&quot;:[],\&quot;uniqueArray\&quot;:[7,1]}]},\&quot;uniqueArray\&quot;:[0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,5,0,4,1,0,1,1,2,1]}]},\&quot;persGroupNegMat\&quot;:{\&quot;selectionSpecs\&quot;:[]},\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;list\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:248,\&quot;variable\&quot;:\&quot;jobtitle\&quot;,\&quot;hiddenList\&quot;:true,\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;click\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:274,\&quot;template\&quot;:\&quot;results_template1\&quot;,\&quot;maxDepth\&quot;:\&quot;0\&quot;,\&quot;allowExternalTemplates\&quot;:false,\&quot;externalProject\&quot;:\&quot;\&quot;,\&quot;externalTemplate\&quot;:\&quot;\&quot;,\&quot;newPage\&quot;:true,\&quot;staysOnTemplate\&quot;:false,\&quot;maxWait\&quot;:\&quot;5000\&quot;,\&quot;simulateBrowserPerfectly\&quot;:false,\&quot;ignoreDisabledElements\&quot;:true,\&quot;interceptURL\&quot;:false,\&quot;urlToIntercept\&quot;:\&quot;\&quot;,\&quot;nodes\&quot;:[]}]}]}]}]},{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:457,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;DIV\&quot;,\&quot;classes\&quot;:[\&quot;ecydgvn1\&quot;],\&quot;styles\&quot;:[],\&quot;position\&quot;:2,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:true,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:458,\&quot;label\&quot;:\&quot;selection2\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:null,\&quot;classes\&quot;:[\&quot;e8ju0x50\&quot;],\&quot;styles\&quot;:[],\&quot;position\&quot;:0,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:true,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:true,\&quot;autoListNode\&quot;:false,\&quot;persGroupPosMat\&quot;:{\&quot;selectionSpecs\&quot;:[{\&quot;chunkTree\&quot;:{\&quot;htmlChunks\&quot;:[\&quot;b9a250dcc5c8474c851645dab6e39521\&quot;,\&quot;f5c933e4069959d97f5afaa2acb998da\&quot;,\&quot;e8470f8d7aaf2a3a8d58d7f51e058263\&quot;,\&quot;fe199a37ace1b458df51ffdf6ac4ffde\&quot;,\&quot;0d04ca889b06c03f9fcb392166a9b873\&quot;,\&quot;817db81fc55c0f28d75271efc6eb5c66\&quot;,\&quot;c976442d421cd4b3f9092d5bd9cf0aa0\&quot;,\&quot;4d67519bf5f1065b4d6e47496cefb5ca\&quot;,\&quot;6c0e4ec53283036ff3b9b87f9fad2fc5\&quot;,\&quot;07fc888f10f832ec29e1c009f0fabede\&quot;,\&quot;1af2e2e4ecc8195f06fdddf5c51c686b\&quot;,\&quot;9f28eb01a90a7c25202ab7ab43920a4f\&quot;,\&quot;190c85d99d655c478c2309c8843b424e\&quot;,\&quot;a2b65a135299b9988c824469bc765d56\&quot;,\&quot;c9f4215d10d91076550ff88797234764\&quot;,\&quot;02a09f11ac8363228b8f4afd4649dd20\&quot;],\&quot;framesChunks\&quot;:[{\&quot;htmlChunks\&quot;:[\&quot;4e82691920b371ea3508cc18540d81fd\&quot;],\&quot;framesChunks\&quot;:[],\&quot;uniqueArray\&quot;:[7,1]}]},\&quot;uniqueArray\&quot;:[1,2,10,0,4,1,0,1,1,2,1]}]},\&quot;persGroupNegMat\&quot;:{\&quot;selectionSpecs\&quot;:[]},\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;click\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:472,\&quot;template\&quot;:\&quot;main_template\&quot;,\&quot;maxDepth\&quot;:\&quot;10\&quot;,\&quot;allowExternalTemplates\&quot;:false,\&quot;externalProject\&quot;:\&quot;\&quot;,\&quot;externalTemplate\&quot;:\&quot;\&quot;,\&quot;newPage\&quot;:true,\&quot;staysOnTemplate\&quot;:false,\&quot;maxWait\&quot;:\&quot;5000\&quot;,\&quot;simulateBrowserPerfectly\&quot;:false,\&quot;ignoreDisabledElements\&quot;:true,\&quot;interceptURL\&quot;:false,\&quot;urlToIntercept\&quot;:\&quot;\&quot;,\&quot;nodes\&quot;:[]}]}]}]},{\&quot;op\&quot;:\&quot;template\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:276,\&quot;label\&quot;:\&quot;page\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;BODY\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:1,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:true,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;name\&quot;:\&quot;results_template1\&quot;,\&quot;endAtDuplicate\&quot;:true,\&quot;clearSession\&quot;:false,\&quot;loadJs\&quot;:\&quot;default\&quot;,\&quot;preserveOrder\&quot;:\&quot;default\&quot;,\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;extract\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:425,\&quot;variable\&quot;:\&quot;name\&quot;,\&quot;expression\&quot;:\&quot;$e.text\&quot;,\&quot;useRegex\&quot;:false,\&quot;regexFindAll\&quot;:false,\&quot;regex\&quot;:\&quot;\&quot;,\&quot;nodes\&quot;:[]},{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:413,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;DIV\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:3,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:true,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:422,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:null,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:0,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:true,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:421,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;DIV\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:1,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:420,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;DIV\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:1,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:419,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;DIV\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:1,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:false,\&quot;nodeId\&quot;:418,\&quot;label\&quot;:\&quot;\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:\&quot;DIV\&quot;,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:1,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;select\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:417,\&quot;label\&quot;:\&quot;jobinfo\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:null,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:0,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:true,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:true,\&quot;persGroupPosMat\&quot;:{\&quot;selectionSpecs\&quot;:[{\&quot;chunkTree\&quot;:{\&quot;htmlChunks\&quot;:[\&quot;263e67ad8dc1c2d3b55dc70f5cdf2d90\&quot;,\&quot;396d9afce0bbf44248a1920e26e761f5\&quot;,\&quot;6f8b93f5ffc22928bac6ff27578f4871\&quot;,\&quot;e9e83f825319e618d4e12c14351c9af5\&quot;,\&quot;02a22814f27f5e830aec343d26c3def2\&quot;],\&quot;framesChunks\&quot;:[{\&quot;htmlChunks\&quot;:[\&quot;5cfe69422aac514fc60901e050b0558e\&quot;],\&quot;framesChunks\&quot;:[],\&quot;uniqueArray\&quot;:[25,1]}]},\&quot;uniqueArray\&quot;:[1,0,0,0,0,0,0,1,5,1,0,3,0,1,1,3,0,1,1]},{\&quot;chunkTree\&quot;:{\&quot;htmlChunks\&quot;:[\&quot;263e67ad8dc1c2d3b55dc70f5cdf2d90\&quot;,\&quot;396d9afce0bbf44248a1920e26e761f5\&quot;,\&quot;6f8b93f5ffc22928bac6ff27578f4871\&quot;,\&quot;e9e83f825319e618d4e12c14351c9af5\&quot;,\&quot;02a22814f27f5e830aec343d26c3def2\&quot;],\&quot;framesChunks\&quot;:[{\&quot;htmlChunks\&quot;:[\&quot;5cfe69422aac514fc60901e050b0558e\&quot;],\&quot;framesChunks\&quot;:[],\&quot;uniqueArray\&quot;:[25,1]}]},\&quot;uniqueArray\&quot;:[3,0,0,0,0,1,1,5,1,0,3,0,1,1,3,0,1,1]}]},\&quot;persGroupNegMat\&quot;:{\&quot;selectionSpecs\&quot;:[]},\&quot;empty\&quot;:false,\&quot;flags\&quot;:[],\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;list\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:424,\&quot;variable\&quot;:\&quot;jobinfo\&quot;,\&quot;hiddenList\&quot;:true,\&quot;nodes\&quot;:[{\&quot;op\&quot;:\&quot;relativeSelect\&quot;,\&quot;targeted\&quot;:true,\&quot;nodeId\&quot;:426,\&quot;label\&quot;:\&quot;selection1\&quot;,\&quot;id\&quot;:null,\&quot;src\&quot;:null,\&quot;tag\&quot;:null,\&quot;classes\&quot;:[],\&quot;styles\&quot;:[],\&quot;position\&quot;:0,\&quot;hasTextNodes\&quot;:false,\&quot;waitForElements\&quot;:false,\&quot;waitForTimeout\&quot;:60000,\&quot;reselectElements\&quot;:false,\&quot;allDescendants\&quot;:false,\&quot;rooted\&quot;:false,\&quot;textNodesOnly\&quot;:false,\&quot;hasText\&quot;:false,\&quot;svgSelection\&quot;:false,\&quot;hiddenExtract\&quot;:false,\&quot;autoListNode\&quot;:false,\&quot;persGroupPosMat\&quot;:{\&quot;selectionSpecs\&quot;:[]},\&quot;persGroupNegMat\&quot;:{\&quot;selectionSpecs\&quot;:[]},\&quot;relativeSpecs\&quot;:[],\&quot;empty\&quot;:true,\&quot;placeHolderForParentSelect\&quot;:false,\&quot;nodes\&quot;:[]}]}]}]}]}]}]}]}]}]}]&quot;,&quot;options_json&quot;:&quot;{\&quot;outputType\&quot;:\&quot;csv\&quot;,\&quot;loadJs\&quot;:true,\&quot;sendEmail\&quot;:\&quot;default\&quot;,\&quot;webhook\&quot;:\&quot;\&quot;,\&quot;rotateIPs\&quot;:false,\&quot;maxWorkers\&quot;:\&quot;0\&quot;,\&quot;maxPages\&quot;:\&quot;0\&quot;,\&quot;startValue\&quot;:\&quot;{}\&quot;,\&quot;startTemplate\&quot;:\&quot;main_template\&quot;,\&quot;startUrl\&quot;:\&quot;https://www.indeed.com/jobs?q=golang&amp;amp;l=New+York%2C+NY&amp;amp;vjk=9247408d6c59705bb.com/landing\&quot;,\&quot;customProxies\&quot;:\&quot;\&quot;,\&quot;proxyAllowInsecure\&quot;:false,\&quot;allowPerfectSimulation\&quot;:false,\&quot;proxyDisableAdblock\&quot;:false,\&quot;proxyCustomRotationHybrid\&quot;:false,\&quot;preserveOrder\&quot;:false,\&quot;recoveryRules\&quot;:\&quot;{}\&quot;,\&quot;allowReselection\&quot;:false,\&quot;ignoreDisabledElements\&quot;:true}&quot;,&quot;public_key&quot;:&quot;&quot;,&quot;syntax_version&quot;:9,&quot;elements&quot;:&quot;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&quot;}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Linux记录终端用户行为的一种审计方法</title><link>https://dididudu998.github.io/posts/%E8%AE%B0%E5%BD%95%E7%BB%88%E7%AB%AF%E7%94%A8%E6%88%B7%E8%A1%8C%E4%B8%BA%E7%9A%84%E6%96%B9%E6%B3%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%AE%B0%E5%BD%95%E7%BB%88%E7%AB%AF%E7%94%A8%E6%88%B7%E8%A1%8C%E4%B8%BA%E7%9A%84%E6%96%B9%E6%B3%95/</guid><pubDate>Fri, 14 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Linux 下用户行为审计的一种方法&lt;/h1&gt;
&lt;p&gt;Linux 提供了一种可以对用户的行为进行记录和重放的方法。这种方法对于比较重要的环境下的审计以及问题的处理，有比较广泛的使用。&lt;/p&gt;
&lt;h2&gt;启用行为记录&lt;/h2&gt;
&lt;p&gt;下面是一个启用该功能的 shell 脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
mkdir -p /var/log/session
# Define the block to be added to /etc/profile
block=&apos;
if [ &quot;x$SESSION_RECORD&quot; = &quot;x&quot; ]
then
timestamp=$(date +%d-%m-%Y-%T)
session_log=/var/log/session/session.$USER.$timestamp.log
SESSION_RECORD=started
export SESSION_RECORD
script -t -f -q 2&amp;gt;${session_log}.timing $session_log
exit
fi
&apos;

# Add the block to /etc/profile
echo &quot;$block&quot; | sudo tee -a /etc/profile &amp;gt; /dev/null

# Source the profile to apply the changes
source /etc/profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面脚本的目的如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以管理员账户运行该脚本，创建/var/log/session 目录。&lt;/li&gt;
&lt;li&gt;如果用户 session 记录没有启用，那么开始进行参数定义&lt;/li&gt;
&lt;li&gt;设定 timestamp 格式，这个格式可以自己进行修改，不影响功能&lt;/li&gt;
&lt;li&gt;设定 session 日志的文件位置和命名格式&lt;/li&gt;
&lt;li&gt;启动 session 记录&lt;/li&gt;
&lt;li&gt;生成带有时间的脚本&lt;/li&gt;
&lt;li&gt;将上面的这些指令放到/etc/profile 中，并进行更新。&lt;/li&gt;
&lt;li&gt;从此以后，所有终端登录到这台 Linux 机器的人，他们的所有的输入和输出都会被记录到对应的文件中，并且可以进行回放。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;发送记录&lt;/h2&gt;
&lt;p&gt;发送到审计人的邮箱或者使用 scp 进行传输到其他地方这个是可选的。只是发送到邮箱更简单一些，方便其他人更好的进行外部审计。&lt;/p&gt;
&lt;p&gt;由于 shell 发送邮件在不同的操作系统中命令的格式略有不同，所以下面以 python 代码的形式实现，方便统一。&lt;/p&gt;
&lt;p&gt;下面是使用 python 代码发送用户行为日志的脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import zipfile

def send_email(sender, password, recipients, subject, body, attachment_folder, smtp_server, smtp_port):
    # Create a multipart message
    message = MIMEMultipart()
    message[&apos;From&apos;] = sender
    message[&apos;To&apos;] = &apos;, &apos;.join(recipients)
    message[&apos;Subject&apos;] = subject

    # Add body to the email
    message.attach(MIMEText(body, &apos;plain&apos;))

    # Create a zip file
    zip_filename = &apos;attachments.zip&apos;
    with zipfile.ZipFile(zip_filename, &apos;w&apos;) as zip_file:
        # Iterate through files in the attachment folder
        for filename in os.listdir(attachment_folder):
            attachment_path = os.path.join(attachment_folder, filename)
            if os.path.isfile(attachment_path):
                # Add the file to the zip archive
                zip_file.write(attachment_path, filename)

    # Attach the zip file to the message
    with open(zip_filename, &apos;rb&apos;) as attachment:
        part = MIMEBase(&apos;application&apos;, &apos;zip&apos;)
        part.set_payload(attachment.read())
        encoders.encode_base64(part)
        part.add_header(&apos;Content-Disposition&apos;, f&apos;attachment; filename= {zip_filename}&apos;)
        message.attach(part)

    # Connect to the SMTP server
    server = smtplib.SMTP(smtp_server, smtp_port)
    # server.starttls()
    server.login(sender, password)

    # Send the email
    server.send_message(message)

    # Disconnect from the server
    server.quit()

    # Delete the zip file
    os.remove(zip_filename)

# usage
sender = &apos;&apos;user_activity@mytemp.com”
password = “password”
recipients = [&apos;mark@mark.com&apos;, &apos;abc@cde.com&apos;]
subject = &apos;user activity log&apos;
body = &apos;Please find the attachments in this email.&apos;
attachment_folder = &apos;/var/log/session&apos;
smtp_server = &apos;smtp.mytemp.com&apos;
smtp_port = 25

send_email(sender, password, recipients, subject, body, attachment_folder, smtp_server, smtp_port)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要说明的是，enterprise 的邮箱有可能会过滤掉 zip 文件，不过经过几次测试一般都是进入垃圾邮箱的。&lt;/p&gt;
&lt;h2&gt;重放（可选）&lt;/h2&gt;
&lt;p&gt;拿到日志的审计人员，可以在自己的环境进行重放，当然直接读 log 也够了。&lt;/p&gt;
&lt;p&gt;重放的指令如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scriptreplay session.root.xxx.timing session.root.xxx.log
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;p&gt;这种审计模式由于包含所有的输入输出，而且在/etc/profile 下会对所有的终端用户启用，所以需要特别注意，是否只应对个别用户启用，而且记录的 log 由于可能包含有个人的数据信息，所以也需要审计人员特别的注意。还有就是如果用户的输入输出操作比较频繁，生成的 log 可能会非常大，要定期对旧文件进行备份和删除的操作，避免存储空间的大量占用。&lt;/p&gt;
</content:encoded></item><item><title>关于chatgpt的感想</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Echatgpt%E7%9A%84%E6%84%9F%E6%83%B3/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Echatgpt%E7%9A%84%E6%84%9F%E6%83%B3/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 08 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;关于chatgpt的感想&lt;/h1&gt;
&lt;p&gt;使用chatgpt已经有一段时间了，提供的api的过期时间是在4月1日。我在这里记录一下使用的感想。&lt;/p&gt;
&lt;p&gt;对于日常的使用来说，chatgpt对于人们提交的问题的理解是非常准确的。并且可以给出一些见解和建议。&lt;/p&gt;
&lt;p&gt;但是依然要自己进行判定，不能够完全的相信chatgpt的回答。 在有些时候，它给出的时间，地点，人物等存在信息错误。&lt;/p&gt;
&lt;p&gt;对于广泛的非技术性问题，基本上可以达到80%-90%的准确率，这点超越了Google的搜索引擎。&lt;/p&gt;
&lt;p&gt;在平时的开发的时候，也能够提供必要的代码案例，但是必然的还是要自己进行一定的修改，不过依然已经超越了普通的助理的程度。尤其对于一些自己不熟悉的部分，或者希望得到提高的部分，可以看到不同和差距。&lt;/p&gt;
&lt;h2&gt;一些问题&lt;/h2&gt;
&lt;p&gt;对于一个包含有大量的后台数据，并且在前台理解人的输入，进行信息查询汇总然后又返回结果给人的系统，chatgpt的威力确实足够大。&lt;/p&gt;
&lt;p&gt;这里有个问题，只有当你知道要问他什么的时候，怎么问就成了一个问题。含糊的提问，会带来多样的反馈，导致你不知道该如何选择。而一个好的，严谨的提问，则会带来更精确的回答结果。&lt;/p&gt;
&lt;p&gt;在这里想到，就好比对方是一个博学多闻的人，但是由小学生提问和由大学生提问，对于同样的想要获取的信息，深度是不同的。深度的不同，就产生了更大的信息差，对一件事物的真实理解就不够。而这种差异会导致对于事物，事件的判断产生偏差。从而导致行为，行动的不同。&lt;/p&gt;
&lt;p&gt;也就是说，它是遇强则强的。只有自身具备比较高的水准，它才会给你相当水平的结果。&lt;/p&gt;
&lt;p&gt;那么怎么样才能提高自己问问题的水平呢？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建立自己的问题的边界，要让问题的边界尽可能的小，这样才能够得到更精确的结果。&lt;/li&gt;
&lt;li&gt;理解问题的本质，要知道自己想要的是什么，而不是什么。&lt;/li&gt;
&lt;li&gt;对于问题的内沿和外涵，所涉及到的专业的术语，要有一定的了解&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以是一个收集元数据的能力。&lt;/p&gt;
&lt;p&gt;我不需要理解方方面面，我只需要知道这个东西是什么，为什么要创建，它的基本原理是什么，可以用来做什么，以及还有什么扩展的用法，至于具体的实现，可以通过已知的知识，一步一步的问chatgpt，直到得到一个可以接受的答案。&lt;/p&gt;
&lt;p&gt;所以是chatgpt减少了对细节的需求的掌握，而是需要提高从大局，高纬度掌握的能力。&lt;/p&gt;
&lt;p&gt;它所提供的信息，也就是训练数据，不知道是全部来自公开的，还是怎么得来的。这样的一种方式，对于以后的企业来说，他们更不愿意分享自身的数据，或者就是只提供收费的接口了。所有的数据的查询都需要付费。而chatgpt成为了一个类似数据接口的大商场，各种数据接口提供的公司在后台给他提供数据，而最终的用户根据查阅的数据的多少，质量的高低进行收费。&lt;/p&gt;
&lt;p&gt;在现在，初始的阶段，chatgpt已经获得了大量的人的关注，并且释放的api也产生了大量的好玩好用的应用。而且目前的收费标准可以说非常的低廉，是我们使用的一个非常好的选择。&lt;/p&gt;
&lt;p&gt;为了能够实现数据的准确和深度，它必须和一些第三方的数据提供商，专业的行业提供者进行联合。这样才能更好的获取经济回报。&lt;/p&gt;
&lt;p&gt;这样的趋势下，作为个人，如何才能够利用这个东西，让自己的思维，知识，经验，能力得到提升呢？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建立不同的chat频道，对于自己不理解的问题，直接发问，哪怕它是有错误的几率，也能得到一些大概的信息&lt;/li&gt;
&lt;li&gt;对于自己在研究的问题，可以放手的去问，看看前人是不是已经有了解决方案，或者是有什么新的发现&lt;/li&gt;
&lt;li&gt;对于需要快速解决的问题，直接问解决方案，而不是去问为什么，或者是怎么做的&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;看看有没有可以创新的部分，我们生活就是需要根据已有的东西来创造新的东西。&lt;/p&gt;
&lt;p&gt;前人提供的知识，如果只是学来然后静置在头脑里，那实在是无聊的生存。&lt;/p&gt;
&lt;p&gt;根据一些自己的小小的需求，结合chatgpt的协助，做一些对自己有用的小创新，这样才是最好的。&lt;/p&gt;
</content:encoded></item><item><title>用winimage转化dd过来的移动硬盘</title><link>https://dididudu998.github.io/posts/%E7%94%A8winimage%E8%BD%AC%E5%8C%96dd%E8%BF%87%E6%9D%A5%E7%9A%84%E7%A7%BB%E5%8A%A8%E7%A1%AC%E7%9B%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8winimage%E8%BD%AC%E5%8C%96dd%E8%BF%87%E6%9D%A5%E7%9A%84%E7%A7%BB%E5%8A%A8%E7%A1%AC%E7%9B%98/</guid><pubDate>Fri, 24 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;有个小同事，说是要学习，他的那个学习系统很耗费资源，想要将这个系统搞到虚拟机平台里面去。&lt;/p&gt;
&lt;p&gt;目前虚拟机平台资源足够，看在他学习热情很高，就说可以的。&lt;/p&gt;
&lt;p&gt;隔天，他拿了个移动硬盘过来。说是用dd命令备份过来的。&lt;/p&gt;
&lt;h2&gt;经过&lt;/h2&gt;
&lt;p&gt;告诉他可以在本地装个虚拟机，然后把这个移动硬盘挂上去，用dd命令备份移动硬盘到虚拟机里面去。&lt;/p&gt;
&lt;p&gt;他说他试了，不行。又拿过来了。&lt;/p&gt;
&lt;p&gt;拿来一看，电脑不识别，用diskpart试了下，认识到了新磁盘。问他原来系统是什么，他说是linux。&lt;/p&gt;
&lt;p&gt;没法，我手头没有linux机器，也没有本地的虚拟机。&lt;/p&gt;
&lt;p&gt;只好用第三方工具，用winimage转化一下。&lt;/p&gt;
&lt;p&gt;winimage是挺好的一个工具，比sysinternal的disk2vhd要更好一些。&lt;/p&gt;
&lt;p&gt;下载地址：https://www.winimage.com/download.htm&lt;/p&gt;
&lt;p&gt;下载后，安装，然后打开。&lt;/p&gt;
&lt;p&gt;选择加载可移动磁盘，就能看到外接的disk1了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/winimage.jpg&quot; alt=&quot;winimage&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后选择保存为vhd文件，就可以了。&lt;/p&gt;
&lt;p&gt;输出为vhd后，还要将其转化为vmdk文件，才能在vmware虚拟机里面使用。&lt;/p&gt;
&lt;p&gt;转化为vmdk的方法，同样是在winimage里面，选择转化出来的vhd文件，然后选择转化为vmdk文件。&lt;/p&gt;
&lt;p&gt;再将vmdk传到虚拟机存储后，再引用到虚拟机里面去。就可以了。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;格式转化工具都还是挺好的。但是很多时候，会选择才是最好的。winimage是最好的选择。&lt;/p&gt;
&lt;p&gt;其他可以转化的工具，包括disk2vhd，startwind v2v converter，vmware converter等在不同的场合下，也能实现各自的功能。&lt;/p&gt;
</content:encoded></item><item><title>用coredns容器做本地dns</title><link>https://dididudu998.github.io/posts/%E7%94%A8coredns%E5%AE%B9%E5%99%A8%E5%81%9A%E6%9C%AC%E5%9C%B0dns/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8coredns%E5%AE%B9%E5%99%A8%E5%81%9A%E6%9C%AC%E5%9C%B0dns/</guid><pubDate>Thu, 09 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;用coredns容器做本地dns&lt;/h1&gt;
&lt;p&gt;前几天由于搬迁，网络不稳定，由于需要远程连接，IP地址总是找不到，于是做了个下面的发送IP地址给我的python脚本,用hmailserver做了个smtp服务器。有两台机器是windows的，我用来平时作为Mac的辅助，因为开的浏览器页面太多，Mac屏幕太小，所以阅读类的和邮件类的都在这两台windows上。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```python
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;import socket
import smtplib
#import platform&lt;/p&gt;
&lt;h1&gt;Get the current IP address&lt;/h1&gt;
&lt;p&gt;ip = socket.gethostbyname(socket.gethostname())
hostname=socket.gethostname()&lt;/p&gt;
&lt;h1&gt;Set up the email information&lt;/h1&gt;
&lt;p&gt;sender = &quot;user1@mytemp.com&quot;
receiver = &quot;mark@mark.com&quot;
password = &quot;password&quot;&lt;/p&gt;
&lt;h1&gt;Build the message&lt;/h1&gt;
&lt;p&gt;message = &quot;Subject: Current IP Address\n\nThe current IP address is: &quot; + ip +&quot;\n\n&quot;+&quot;the system running on hostname &quot;+hostname&lt;/p&gt;
&lt;h1&gt;Send the email&lt;/h1&gt;
&lt;p&gt;server = smtplib.SMTP(&quot;mytemp.com&quot;, 25)
#server.starttls()
server.login(sender, password)
server.sendmail(sender, receiver, message)
server.quit()&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
然后想要其他的机器能够通过域名使用邮件smtp服务。就又搞了个coredns容器。

还别说docker的windows desktop版还真是好用。

首先pull镜像

    docker pull coredns/coredns

然后，创建一个文件夹，我的就叫c:\myscripts

在文件夹里面创建个Corefile文件，内容如下：

```conf   
    .:53 {
    forward . 8.8.8.8 9.9.9.9
    log
    errors
}

mytemp.com:53 {
    file /root/mytemp.db
    log
    errors
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后创建一个mytemp.db文件，内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
$ORIGIN mytemp.com.  ; designates the start of this zone file in the namespace
$TTL 1h               ; default expiration time of all resource records without their own TTL value
@                 IN  SOA     ns.mytemp.com. mark.mytemp.com. (
                                  2020010510     ; Serial
                                  1d             ; Refresh
                                  2h             ; Retry
                                  4w             ; Expire
                                  1h)            ; Minimum TTL
@                 IN  A       10.212.131.101       ; Local IPv4 address for example.com.
@                 IN  NS      ns.mytemp.com.    ; Name server for example.com.
ns                IN  CNAME   @                  ; Alias for name server (points to example.com.)
mail			  IN  A       10.212.131.101
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后就开始运行docker容器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -d --name coredns -p 53:53/udp -v c:\myscripts:/root coredns/coredns -conf /root/Corefile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再下来，开nslookup，输入下面的命令，就可以看到上面的mytemp.db文件里面的内容了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nslookup mytemp.com 127.0.0.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还有desktop版本的log，可以看到coredns的运行情况。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/coredns.jpg&quot; alt=&quot;coredns&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后只要其他机器配置coredns这台机器的ip作为dns服务器，就可以在其他机器上，通过域名访问邮件服务器了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;telnet mytemp.com 25
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为以后的邮件投递减少了配置的成本。&lt;/p&gt;
&lt;h2&gt;参考&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://coredns.io/&quot;&gt;coredns&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://coredns.io/manual/toc/#configuration&quot;&gt;manual&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mac-blog.org.ua/kubernetes-coredns-wildcard-ingress&quot;&gt;custom dns with coredns&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>回忆我的看书经历</title><link>https://dididudu998.github.io/posts/%E5%9B%9E%E5%BF%86%E6%88%91%E7%9A%84%E7%9C%8B%E4%B9%A6%E7%BB%8F%E5%8E%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%9B%9E%E5%BF%86%E6%88%91%E7%9A%84%E7%9C%8B%E4%B9%A6%E7%BB%8F%E5%8E%86/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 30 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我是个所谓的80后，听家里人讲，在我出生的前几天下了很大的雨，那个时候从家里到医院的路还是泥土路，由于下雨的关系，路很难走，而且那个时候也没有汽车，用的架子车，妈妈裹着被子躺在架子车上，几个叔叔还有我叫爷爷（这个是辈分的关系）的人拉着架子车去的医院，在当天的中午出生的。&lt;/p&gt;
&lt;p&gt;听家里人讲，在我出生前的几年，那是真的非常的穷困，吃饭是最大的问题。那个时候爷爷由于抗美援朝回来，进了当地的邮政局里面车辆维修的部门，我小的时候，还去过里面玩耍。而且车辆修好后要试车，我也坐过好几次车，在那里我大概5岁的时候第一次按响了汽车喇叭，也知道了用电炉子可以烤馒头吃。&lt;/p&gt;
&lt;p&gt;还有记忆深刻的是小时候老想着去城里，有一次妈妈卖菜，是那种三轮车，我非要去，不去就哭的那种，然后刚好去了爷爷那边邮政局的门口，那个时候邮政局都有自己的食堂，而且也对外营业，我就一直坐在车上，直到吃饭的时候，爷爷过来领我去食堂吃饭，然后我们吃好了，再给妈妈端一碗过来，然后由于非常无聊，就不断的问妈妈，什么时候回去啊，什么时候回去啊这样的话，最后回去的时候我记得也到了傍晚了，而且由于太困，好像在三轮车上睡着了。&lt;/p&gt;
&lt;p&gt;邮政局的食堂里面有个姐姐挺好的，送给了我一本书，那本书我记忆非常深刻，但是名字这么多年我一直记不起来，而且自从那本书找不到以后，就再也没有寻找到和那个一样的故事书了，我曾经在网络上也找了很久，依然没有。
内容是山里的男孩在丛林里面冒险的故事，比如发现毒蘑菇，野狼等等，最好找到探险队然后一起安全回来的故事。&lt;/p&gt;
&lt;p&gt;还有就是儿童科幻小说，比如那个时候我看了魔伞，看了如何区别机器人和人类，机器人缺乏好奇心。看了很多其他的现在都应忘记了。&lt;/p&gt;
&lt;p&gt;大概80年代刚刚改革开放，而且那个时候对于儿童文学和外国的小说引进的比较多，我还看了一本书，讲的是美国的记者在泰国芭堤雅的故事，那个时候我第一次知道了人妖这样的事情，也是忘了书名，混沌世纪还是什么。&lt;/p&gt;
&lt;p&gt;那个时候我三叔应该也是刚参加工作不久，他上学时候的很多语文书都是新的，我就拿来看，在里面有印象的是，小公务员之死，别了，司徒雷登，还有个什么不为第一，不耻最后什么的，总之那个时候的语文书是真的很好看，还有什么黄钟瓦釜之类的，再下来家里有个那个时候觉得很厚的书，叫《大千世界》，里面各种新奇古怪的事情，也是看了很长时间，再大一点了，看到了温瑞安的小说，讲的都是所谓食色性也的东西，然后是真正的看完了一本书，小仲马的《茶花女》并且大哭了一阵，还有《鲁滨逊历险记》，也是忘记了译者了，觉得这个译者翻译的非常好，而且专门写了，为什么不叫漂流记，而叫历险记的原因，后来也是找不到书了。&lt;/p&gt;
&lt;p&gt;看上面的那些书的时候差不多是三四年级的时候，字有的也认不全，但是勉强是能看下去的。&lt;/p&gt;
&lt;p&gt;还有印象深刻的是，舅舅家里的大量的科学刊物，应该是舅舅给我表哥，表姐，表弟他们订的，一个大箱子里面全都是。我有一年暑假，和妈妈去探望外婆，那个时候我们都是走路去舅舅家的，我们两个村子相隔大概有5公里或者更近一些，但是当时年纪小，我，我妹妹，还有妈妈就是走路过去，路的两边都是田地，天气好的时候走起来还好，要是下了一点雨，那么走过去，鞋底就沾满了泥土，厚厚的一层。在那个暑假，我去了舅舅家后，没有回去。而是在那边过了一个暑假。当时候外婆也很精神，我喜欢吃辣椒，就专门给我炒辣椒吃，当时还和表哥，表弟偷偷的找外婆藏的好吃的，还有个很搞笑的事情，当时外婆需要去走亲戚，但是我不想去，就偷偷说自己肚子疼。后来说是买了什么好吃的，我才愿意跟着去了。唉，我小时候也做过很多幼稚的事情。&lt;/p&gt;
&lt;p&gt;就在那个暑假，我将那些科学画刊都读了下去。都是儿歌类型的，特别有印象的是小灵通漫游未来这个。后来我给儿子好像也买了一本，但是不知道是不是也是丢的找不到了。&lt;/p&gt;
&lt;p&gt;同村有个张姓的邻里，他的儿子经常来玩，带了一个丁丁历险记的画本，小时候画本非常流行，什么三国演义，秦琼敬德这样的武打故事，都是从画本里面看到的。我就借了他的丁丁历险记来看，其实现在早已忘记什么内容。但是有个印象深刻的是，我还他画本的时候，他诧异的看着我，说我竟然知道他姓张，原因是画本的首页写着他的名字，但是其实那根本不是我写的，我也并不知道他姓张还是姓我们的村的姓。我从来不会在人家的书上面写字。&lt;/p&gt;
&lt;p&gt;再大了一点了，大概5年级时候，需要写作文，我记得很深刻的就是家里人去城里回来后给买了很多的写作文的书，那个时候的范文作文看了下，都写的很好，记忆深刻的是，北京的孩子写他随着父亲去了北卡罗来那州学习的经历，还有就是一个给自己的阿拉伯国家的笔友写的回信，还有就是上海还是北京，根据声音来想象一篇作文，里面提到了机器狗，贴身衣，高速的飞船和智能的房子等等。&lt;/p&gt;
&lt;p&gt;还有印象深刻的是，我当时过年的时候和妈妈去城里，那个时候应该是嘉汇商场吧，进门的那个旁边有个小书店，我进去扫了一圈，看到最上面有一本书，叫做中国少年百科知识大全，我就说我要买那本，刚好也就只有一本了，就买给我了，后来知道这是一套书，我照着当时的书，买了一套一模一样的给儿子，也不知道他看了多少。当时我买的那个是科学技术卷，还有其他的卷。这本书当时一本要接近30块钱，在那个时候算是很贵的。不过家里对我的学习一直很支持，买书从来不会拒绝。&lt;/p&gt;
&lt;p&gt;我在一个暑假将这部科学技术卷大概翻了一遍，可能还多一些，然后等到暑假结束开学后，老师还专门在班上说，这个暑假我几乎看到了班里所有的孩子在外面玩，可是xx却一次都没见过。你们知道差距了吗？是的，我几乎整个暑假没有出门，每天早上吃了早饭，就搬个桌子在院子看书。那个时候家里的院子挺大的，我到现在也还是喜欢农村的那种大院子，家里在院子里开辟了个小路，用砖铺成的，然后两边是泥土，在小路的两边种上了花，而且一边专门开辟了种花的地方，夏天时候，很好看。&lt;/p&gt;
&lt;p&gt;再大点，喜欢看军事的书，记得应该也是四年级的时候，参加市里举办的奥林匹克数学竞赛，因为当时在乡里的奥林匹克竞赛说得了个二等奖什么的，学校还挺重视，就让老师带着去参加市里的比赛，带队的老师我现在还记得，张文斌老师，考试结束后，给我们每个人发了5块钱好像，说是可以自己拿着去买东西或者玩。我就去了书店买了一本叫做《当代战争新武器》的书，印刷的质量很一般，但是讲的还挺细致的，那个时候好像是海湾战争的时候，这本书讲了海湾战争时候各个国家的武器，也是看的很认真。&lt;/p&gt;
&lt;p&gt;再下来记忆的是看了家里一本非常厚的书，司汤达的《红与黑》，现在印象有，简单的叙述故事也可以。那个书的排版是从上到下的竖排，不是我们一直看的从左到右的横排，所以印象很深刻。那个叫于连索黑儿的小伙子和她的情人的各种。&lt;/p&gt;
&lt;p&gt;还有就是三叔结婚了，去三婶家里，三婶家里有一本1984年还是什么时候的中国小说选，里面包含有长篇和中篇小说，我如获至宝，不知道是当时送给我的还是我拿的，反正这本书我也是看了津津有味。在里面知道了鄂温克族和狼的故事，海员对于不同的海的认识，龙王爷过会的那种漫天都是旗鱼，剑鱼飞过的场景，还有各种不同的地区，不同方向的故事。让我看的很认真。几乎只要上炕，就会一直看。而且每次都看新的故事，乐此不疲。&lt;/p&gt;
&lt;p&gt;现在我给儿子也买了中国小说选，但是好像这小子连书皮都没有拆。&lt;/p&gt;
&lt;p&gt;然后家里经常会在我乱翻东西的时候会找到新的书，比如中国文学史这样的，我也是看了，那个时候其实看不懂，就是觉得可以将一个东西按照时间的变化，人的思想的变化给记录下来，是很牛的事情。而且特别看了近代的部分，里面什么百家争鸣，什么云南文学，文心雕龙之类的，我还会买下来这书，等我老了再看。&lt;/p&gt;
&lt;p&gt;在书店还买过一本专门讲世界各地发现的奇诡的事情的书，比如房子里面没有重力，比如金字塔里面发现了外星设备之类的，反正那个时候我是对各种奇怪的事情非常的感兴趣。&lt;/p&gt;
&lt;p&gt;还有个印象是大概上了初中，买了一本四十多块钱的《三国演义故事》，不是三国演义，而是三国里面的各种人物的故事，比如武将，比如女子等等，里面是带插画的。后来才知道三国演义故事买的太贵了，一本真正的三国演义也就不到10块钱。我对于钱怎么用，在那个时候根本没有概念。&lt;/p&gt;
&lt;p&gt;初中了，然后看的就是海外星云这样的，也是各种奇怪的东西，可能就是延续了以前的。&lt;/p&gt;
&lt;p&gt;好像初中看的书就少了很多。大概鲁滨逊历险记算是了，还有日本的那个星新一的侦探书，名字也早已忘记。然后就记不起来还看过什么了。到了高中，几乎就没有看过什么书了。到了大学也是一塌糊涂，那个时候舍友好像都去外面的书店一本书一天五毛还是一块的看武侠小说，我只知道黄易，寻秦记，但是那个时候并没有看过。&lt;/p&gt;
&lt;p&gt;等到大学毕业出来，反而开始看了金庸的好几本武侠小说，还有日本的那个梦枕貘的阴阳师系列，还有倪匡的卫斯理
系列。还有一些关于历史和社会的书，因为有些书国内不好看，所以就不提了。&lt;/p&gt;
&lt;p&gt;钱钟书的《围城》是觉得不错的书，先看了电视剧，就是陈道明和李媛媛主演的那个，然后再看了书，原版书。&lt;/p&gt;
</content:encoded></item><item><title>golang跨平台编译的问题</title><link>https://dididudu998.github.io/posts/golang%E8%B7%A8%E5%B9%B3%E5%8F%B0%E7%BC%96%E8%AF%91%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/golang%E8%B7%A8%E5%B9%B3%E5%8F%B0%E7%BC%96%E8%AF%91%E7%9A%84%E9%97%AE%E9%A2%98/</guid><pubDate>Fri, 09 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;golang跨平台编译问题&lt;/h1&gt;
&lt;p&gt;这好像是第好几次出现了。没法，还是得写一下记录一下。&lt;/p&gt;
&lt;p&gt;在macOS上编译linux的时候，以前都是正常的，但是可能升级到了新的macOS版本导致的问题，其中的CommandLineTools也已经更新到了新的版本，但是没用。&lt;/p&gt;
&lt;p&gt;情况就是当在macOS上编译linux可执行文件的时候：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o example example.go
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会出现下面的错误：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;linux_syscall.c:67:13: error: implicit declaration of function &apos;setresgid&apos; is invalid in C99 [-Werror,-Wimplicit-function-declaration]
linux_syscall.c:67:13: note: did you mean &apos;setregid&apos;?
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:593:6: note: &apos;setregid&apos; declared here
linux_syscall.c:73:13: error: implicit declaration of function &apos;setresuid&apos; is invalid in C99 [-Werror,-Wimplicit-function-declaration]
linux_syscall.c:73:13: note: did you mean &apos;setreuid&apos;?
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;解决办法&lt;/h1&gt;
&lt;p&gt;这个问题的解决办法是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装musl-cross&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;brew install FiloSottile/musl-cross/musl-cross
brew info musl-cross
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;重新编译&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;GOOS=linux CC=&quot;x86_64-linux-musl-gcc&quot; GOARCH=amd64 CGO_ENABLED=1 go build -o example example.go
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;上传到linux服务器后，给对应的linux服务器安装musl-tools&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;   sudo apt-get update
   sudo apt-get install musl
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;CentOS&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;    wget https://copr.fedorainfracloud.org/coprs/ngompa/musl-libc/repo/epel-7/ngompa-musl-libc-epel-7.repo -O /etc/yum.repos.d/ngompa-musl-libc-epel-7.repo
    yum install -y musl-libc-static
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;运行&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这时候，就可以在linux服务器上运行了。&lt;/p&gt;
</content:encoded></item><item><title>在vscode中使用微软雅黑</title><link>https://dididudu998.github.io/posts/%E5%9C%A8vscode%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%9C%A8vscode%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91/</guid><pubDate>Fri, 25 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;在vscode中使用微软雅黑&lt;/h1&gt;
&lt;p&gt;昨天在windows电脑里面使用notepad，发现换成微软雅黑后，明显好看了很多。&lt;/p&gt;
&lt;p&gt;今天想着给mac上面也换下。下面是步骤。&lt;/p&gt;
&lt;h2&gt;步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;从windows电脑中复制msyh.ttc文件到mac电脑的 /Library/Fonts/ 目录下&lt;/li&gt;
&lt;li&gt;编辑下权限&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo chown root:wheel &quot;/Library/Fonts/msyh.ttc&quot;
sudo chmod 644 &quot;/Library/Fonts/msyh.ttc&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在vscode中设置字体，打开vscode的设置，搜索fontFamily，添加微软雅黑到第二个即可。别忘了将个人和工作区的都改下。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; &quot;editor.fontFamily&quot;: &quot;Menlo, &apos;微软雅黑&apos;, Monaco, &apos;Courier New&apos;, &apos;Cascadia Code&apos;,monospace,&apos;Arial Unicode&apos;,&apos;Meslo LG S for Powerline&apos;&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;重启vscode，就可以看到输入的中文字体都变成微软雅黑了。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>记录</title><link>https://dididudu998.github.io/posts/dnscrypt/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/dnscrypt/</guid><pubDate>Fri, 11 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;dnscrypt的选择&lt;/h1&gt;
&lt;p&gt;由于网络的污染，有时候莫名的网站就无法访问了。以前用过yogadns这个软件，有31天的试用期。在31天之内都是全功能的。但是超过后，只能保留一个dns服务器。而且看了下这个软件，它通过记录软件的安装日期进行计算，可以通过调电脑的日期进行绕过的操作。而且有个设计问题，即是你用的过了31天，但是只要你不关闭该软件，那么还是可以一直使用这个完全的试用版。但是一旦从试用版转化为basic版本，就再也换不回来了。用regshot研究了下注册表，删除了各种键值，也没有什么用。并且不知道在哪里写了什么东西，如果安装过后，变成了basic版本，那么你删除和重新安装后，也就直接是basic版本。&lt;/p&gt;
&lt;p&gt;本想着学习下这个软件的内涵，应该是有多重时间和使用次数的记录，每次开启该软件都会读取系统时间进行判断之类的逻辑。但是感觉力不从心。还是放弃了。&lt;/p&gt;
&lt;p&gt;随之，使用其他dnscrypt的工具，发现这个simplednscrypt.org提供了现成的工具。&lt;/p&gt;
&lt;p&gt;还是使用这个算了。&lt;/p&gt;
&lt;p&gt;https://simplednscrypt.org/&lt;/p&gt;
</content:encoded></item><item><title>linux性能监控工具</title><link>https://dididudu998.github.io/posts/linux%E6%80%A7%E8%83%BD%E8%A7%82%E5%AF%9F%E5%B7%A5%E5%85%B7/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/linux%E6%80%A7%E8%83%BD%E8%A7%82%E5%AF%9F%E5%B7%A5%E5%85%B7/</guid><pubDate>Wed, 02 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/images/tupian/linux_performance.jpg&quot; alt=&quot;linux_performance&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>设定jupyter notebook可以远程访问</title><link>https://dididudu998.github.io/posts/%E9%85%8D%E7%BD%AEjupyter%E5%8F%AF%E4%BB%A5%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AE/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E9%85%8D%E7%BD%AEjupyter%E5%8F%AF%E4%BB%A5%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AE/</guid><pubDate>Fri, 28 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;关于配置远程访问jupyter-notebook的问题&lt;/h1&gt;
&lt;p&gt;好久前做过的，但是忘记了，只好记录下来了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成jupyter-notebook的web访问密码&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;jupyter notebook password
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时，会告诉你这个密码文件保存的位置，记录那个位置，并记录下password的字符串&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置jupyter-notebook的配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;jupyter notebook --generate-config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;windows的配置文件位于： C:\Users\ls3686.jupyter， 这里ls3686是我的登录账户&lt;/p&gt;
&lt;p&gt;linux的配置文件位于： ~/.jupyter&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;修改配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 这里的字符串就是开始生成的密码
c.NotebookApp.password = ’xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&apos;

## The IP address the notebook server will listen on.
#  Default: &apos;localhost&apos;
c.NotebookApp.ip = &apos;*&apos;

## The port the notebook server will listen on (env: JUPYTER_PORT).
#  Default: 8888
c.NotebookApp.port = 8888


## Allow requests where the Host header doesn&apos;t point to a local server
#  
#         By default, requests get a 403 forbidden response if the &apos;Host&apos; header
#         shows that the browser thinks it&apos;s on a non-local domain.
#         Setting this option to True disables this check.
#  
#         This protects against &apos;DNS rebinding&apos; attacks, where a remote web server
#         serves you a page and then changes its DNS to send later requests to a
#         local IP, bypassing same-origin checks.
#  
#         Local IP addresses (such as 127.0.0.1 and ::1) are allowed as local,
#         along with hostnames configured in local_hostnames.
#  Default: False
c.NotebookApp.allow_remote_access = True

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;启动jupyter-notebook&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;jupyter notebook
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就需要输入设定的密码，并且可以远程访问了。&lt;/p&gt;
</content:encoded></item><item><title>解决nagiosxi无法应用配置的问题</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3nagiosxi%E6%97%A0%E6%B3%95%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3nagiosxi%E6%97%A0%E6%B3%95%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Thu, 25 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;解决nagiosxi无法应用配置的问题&lt;/h1&gt;
&lt;p&gt;首先发现是nagiosxi提示数据库错误，进入 /usr/local/nagiosxi/scripts,利用repair_databases.sh进行修复。
修复完成后，可以正常进入nagiosxi。但是应用配置一直无法完成。&lt;/p&gt;
&lt;p&gt;这时候做两个操作，点击应用配置后检查，tail -f /var/log/message，检查 tail -f /usr/local/nagiosxi/var/cmdsubsys.log。&lt;/p&gt;
&lt;p&gt;根据提示，发现有错误。就是应用配置检查没有问题，但是就是无法完成。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/nagiosxi_scripts.png&quot; alt=&quot;nagiosxi_scripts&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再在这个脚本里面，运行reconfigure_nagios.sh,检查错误，发现https://localhost/nagiosxi/.../ccm/
提示无法访问，证书协议错误的信息。&lt;/p&gt;
&lt;p&gt;但是用正常的https://nagios.mydomain.com/nagiosxi/.../ccm/，就可以正常访问。&lt;/p&gt;
&lt;p&gt;阅读reconfigure_nagios.sh的源码，发现里面有几个调用，对这些调用进行修改，将其中的url都改成https://nagios.mydomain.com/的形式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@nagiosxi scripts]# vi reconfigure_nagios.sh 

#!/bin/bash
# Copyright (c) 2008-2015 Nagios Enterprises, LLC.  All rights reserved.
# $Id$

# exit codes:
#       1       config verification failed
#       2       nagiosql login failed
#       3       nagiosql import failed
#       4       reset_config_perms.sh failed
#       5       nagiosql_exportall.php failed (write configs failed)
#       6       /etc/init.d/nagios restart failed
#       7       db_connect failed
#


# Import data to NagiosQL
./import_nagiosql.sh
ret=$?
if [ $ret -gt 0 ]; then
        exit $ret
fi

# Restart Nagios
./restart_nagios_with_export.sh

ret=$?
if [ $ret -gt 0 ]; then
        exit $ret
fi

exit 0
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;继续对import_nagiosql.sh进行查看。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
# Copyright (c) 2008-2015 Nagios Enterprises, LLC.  All rights reserved.
# $Id$

# Login to NagiosQL
/usr/bin/php -q nagiosql_login.php

#error handling
ret=$?
if [ $ret -gt 0 ]; then
        echo &quot;NAGIOSQL LOGIN FAILED!&quot;
        exit $ret
fi

# Import all data
/usr/bin/php -q nagiosql_importall.php

ret=$?
if [ $ret -gt 0 ]; then
        echo &quot;NAGIOSQL IMPORT FAILED!&quot;
        exit $ret
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;继续对nagiosql_login.php进行查看&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;发现其中有一行&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$url.=&quot;://localhost&quot;.$port.get_component_url_base(&quot;ccm&quot;,false).&quot;/&quot;;
修改为：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;$url.=&quot;://nagios.mydomain.com&quot;.$port.get_component_url_base(&quot;ccm&quot;,false).&quot;/&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;继续对nagiosql_importall.php进行检查&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同样的，将$url.=&quot;://localhost&quot;.$port.get_component_url_base(&quot;ccm&quot;,false).&quot;/&quot;改为$url.=&quot;://nagios.mydomain.com&quot;.$port.get_component_url_base(&quot;ccm&quot;,false).&quot;/&quot;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对nagiosql_exportall.php进行同样的操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;经过上面的操作后，在进行apply configure的时候，检查tail -f /usr/local/nagiosxi/var/cmdsubsys.log。
发现配置文件检查通过，但是提示进行tar操作的时候出现错误。&lt;/p&gt;
&lt;p&gt;对提示的文件夹进行权限变更，发现当前的权限应该是正确的/usr/local/nagiosxi/etc 属于apache:nagios.&lt;/p&gt;
&lt;p&gt;对其中错误提示的一个目录权限变更为777进行应用配置的再次尝试，发现问题依旧。&lt;/p&gt;
&lt;p&gt;这个错误不解决，应用配置就不能完成，这样新添加的host/service/contact的配置就不能生效。&lt;/p&gt;
&lt;p&gt;再次回到reconfigure_nagios.sh, 对其中的restart_nagios_with_export.sh进行查看。&lt;/p&gt;
&lt;p&gt;注释下面nom开头的几句。让整个的应用配置能够实现。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Make a new NOM checkpoint
#    ./nom_create_nagioscore_checkpoint.sh &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;

# There was a problem with the config, so restore older config from last NOM checkpoint
    # Make a new NOM error checkpoint
#    ./nom_create_nagioscore_errorpoint.sh

    # Restore the last known good checkpoint
#    ./nom_restore_nagioscore_checkpoint.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注释完成后，再进行一次apply configure，这时候tail -f /usr/local/nagiosxi/var/cmdsubsys.log中发现配置文件检查通过，返回code为0，说明配置已经生效。&lt;/p&gt;
&lt;p&gt;但是apply configure的页面始终没有结束。&lt;/p&gt;
&lt;p&gt;到host里面去看，确实新添加的host已经在里面了，而且监控服务已经可以反应出来了。&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;问题不算复杂，但是需要仔细的一步一步的进行分析。最终的结果没有实现完美。只是解决了根本的问题。&lt;/p&gt;
&lt;p&gt;至于为什么apply configure的页面没有结束，还是需要继续检查。目前先到这个效果吧。&lt;/p&gt;
</content:encoded></item><item><title>vscode使用python时候出现多个python进程，导致风扇狂转的解决</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3vscode%E7%BC%96%E8%BE%91python%E6%97%B6%E5%80%99%E9%A3%8E%E6%89%87%E7%8B%82%E8%BD%AC%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3vscode%E7%BC%96%E8%BE%91python%E6%97%B6%E5%80%99%E9%A3%8E%E6%89%87%E7%8B%82%E8%BD%AC%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Thu, 16 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;vscode使用python时候出现多个python进程，导致风扇狂转的解决&lt;/h1&gt;
&lt;p&gt;这问题困扰了我很久。搜了网上的解决方案vscode的language server的问题，将pylance换成jedi，或者将pylance换成none就可以解决。&lt;/p&gt;
&lt;p&gt;我都试过了，没用。&lt;/p&gt;
&lt;p&gt;只要一开python文件，就有数10个python进程在后台起来，然后风扇就狂转了，噪音加上发热，不可忍受。不断的killall python也不是个事啊。&lt;/p&gt;
&lt;p&gt;昨天下午突发的想法，这么做了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd &quot;/Users/ls3686/Library/Application Support/Code/User/workspaceStorage/
rm -rf ./workspaceStorage
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重启vscode，再试试python文件的编辑和运行，好了。&lt;/p&gt;
&lt;p&gt;值得记录一下。困扰的问题终于解决了。&lt;/p&gt;
</content:encoded></item><item><title>简单makefile文件</title><link>https://dididudu998.github.io/posts/%E7%AE%80%E5%8D%95makefile%E6%96%87%E4%BB%B6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%AE%80%E5%8D%95makefile%E6%96%87%E4%BB%B6/</guid><pubDate>Fri, 06 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;写一个简单的makefile文件来编译c项目&lt;/h2&gt;
&lt;p&gt;一个C程序设计的时候，分成2个函数，一个是add.c,一个是multiply.c
还有一个head文件，里面声明了add和multiply这两个函数。&lt;/p&gt;
&lt;p&gt;然后就是一个主函数，sample.c, 引用head文件，然后饮用add和multiply函数，返回函数的值。&lt;/p&gt;
&lt;p&gt;基本的操作是，对各个函数源文件生成对象文件，然后再对对向文件进行编译。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
#ifndef SAMPLE
#define SAMPLE

int add(int,int);
int multiply(int,int);

#endif

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int add(int a, int b){
    return a+b;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;int multiply(int a ,int b){
    return a*b;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#include &quot;sample.h&quot;
#include &amp;lt;stdio.h&amp;gt;

int main(int argc, char **argv){
    int x=add(4,5);
    int y=multiply(9,x);
    printf(&quot;result is: %d\n&quot;,x*y);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面分别是头文件，add.c和multiply.c，然后是主函数，sample.c。&lt;/p&gt;
&lt;p&gt;过程是这样的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gcc -c add.c -o add.o
$ gcc -c multiply.c -o multiply.o
$ gcc -c sample.c -o sample.o
$ gcc -o sample sample.o add.o multiply.o
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果是用makefile文件，那么就是这样的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
CC=gcc
CFLAGS=-I.

mysample: add.o multiply.o sample.o
	$(CC) -o mysample add.o multiply.o sample.o $(CFLAGS)

.PHONY: clean
clean:
	rm -f *.o

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行 make -f makefile即可生成mysample文件.&lt;/p&gt;
&lt;p&gt;运行  make clean， 则清理该文件下生成的.o文件。&lt;/p&gt;
&lt;p&gt;使用makefile明显可以减轻手写的工作量。所以对于一般的c项目，还是创建一个makefile比较好一些，方便使用。&lt;/p&gt;
</content:encoded></item><item><title>在Bind上面配置屏蔽广告和恶意站点</title><link>https://dididudu998.github.io/posts/bind-anti-ad/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/bind-anti-ad/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Thu, 17 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;在Bind上配置屏蔽广告和恶意站点&lt;/h2&gt;
&lt;p&gt;主要是受了nextdns的启发，其实用adguard很久了，但是没有想过自己去实现这个功能。而受到nextdns的启发是因为它有个很好的个人页面，里面包含了自己想要的东西，数据的统计比较好看。&lt;/p&gt;
&lt;p&gt;但是有个问题就是nextdns在国内的性能上面有问题，有时候是无法打开页面，有时候是慢了很多。&lt;/p&gt;
&lt;p&gt;但是报表和查询功能是不错的，它的本地app做的不好，和adguard不是一个级别。所以我还是继续使用adguard。&lt;/p&gt;
&lt;p&gt;回到正题，下面是在bind里面实现屏蔽广告和恶意站点的功能的步骤。&lt;/p&gt;
&lt;h2&gt;实现过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在bind的named.conf.options里面的options里增加response-policy那行：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;tls mytls{
                key-file &quot;/etc/bind/private.pem&quot;;
                cert-file &quot;/etc/bind/cert.pem&quot;;
        };


http local-http-server {
        endpoints { &quot;/dns-query&quot;; };
        };

options {
        directory &quot;/var/cache/bind&quot;;

        response-policy {zone &quot;adblock&quot;;};

response-policy {zone &quot;adblock&quot;;};
...
    
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在bind的named.conf.options里面增加广告站点的查询日志：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;channel rpzlog {
                file &quot;/var/log/bind/rpzlog&quot; versions unlimited size 10M;
                print-time yes;
                print-category yes;
                print-severity yes;
                severity info;
        };
       
        category rpz { rpzlog; };  
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在bind的named.conf.default-zone里面添加查询的zone信息&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;zone &quot;adblock&quot; {
        type master;
        //file &quot;/etc/bind/adblock.local&quot;;
        //file &quot;/etc/bind/mark.rpz&quot;;
        file &quot;/etc/bind/urlhaus.rpz&quot;;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;添加adguard.txt中的域名信息到urlhaus.rpz中, 这里我写了个脚本，下载adguard.txt数据后再进行转化，转化后附加到urlhaus.rpz文件里，再重启named服务，完成后发邮件给我.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面是部分代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import requests
import os
import datetime
import smtplib
from email.mime.text import MIMEText
from email.header import Header

#remove old files
os.rename(&quot;urlhaus.rpz&quot;, &quot;urlhaus.rpz.old&quot;)
os.rename(&quot;adguard.txt&quot;, &quot;adguard.txt.old&quot;)
os.rename(&quot;myadguard.txt&quot;, &quot;myadguard.txt.old&quot;)


urlhause=requests.get(&quot;https://urlhaus.abuse.ch/downloads/rpz/&quot;)
with open(&quot;urlhaus.rpz&quot;,&quot;wb&quot;) as f:
    f.write(urlhause.content)

# get adguard.txt from github

file=requests.get(&quot;https://anti-ad.net/adguard.txt&quot;)
with open(&quot;adguard.txt&quot;,&quot;w&quot;) as f:
    f.write(file.text)


os.system(&quot;systemctl restart named&quot;)
# get os.system(&quot;systemctl status named&quot;) output

named_status=os.popen(&quot;systemctl status named&quot;).read()
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;经过测试，可以实现这样的功能&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;; (1 server found)
;; global options: +cmd
;; Got answer:
;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NXDOMAIN, id: 32101
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: d265f88ef4163f1501000000620dd8ce1ba22d15bde64c10 (good)
;; QUESTION SECTION:
;dl.9xu.com.			IN	A

;; ADDITIONAL SECTION:
adblock.		1	IN	SOA	rpz.urlhaus.abuse.ch. hostmaster.urlhaus.abuse.ch. 2202170343 300 1800 604800 30

;; Query time: 917 msec
;; SERVER: 10.214.23.216#53(10.214.23.216) (UDP)
;; WHEN: Thu Feb 17 13:10:37 CST 2022
;; MSG SIZE  rcvd: 141
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;在进行合并的时候，经过查询，可以直接在一个数据文本中一$INCLUDE的方式插入文件，这样就不需要做文件合并的动作。&lt;/p&gt;
&lt;p&gt;类似这样&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$TTL 30
@ SOA rpz.urlhaus.abuse.ch. hostmaster.urlhaus.abuse.ch. 2202170343 300 1800 604800 30
 NS localhost.
;
; abuse.ch URLhaus Response Policy Zones (RPZ)
; Last updated: 2022-02-17 03:43:06 (UTC)
;
; Terms Of Use: https://urlhaus.abuse.ch/api/
; For questions please contact urlhaus [at] abuse.ch
;
$INCLUDE &quot;/etc/bind/adguard-after-convert.txt&quot;
$INCLUDE &quot;/etc/bind/other-anti-ad-after-convert.txt&quot;

testentry.rpz.urlhaus.abuse.ch CNAME . ; Test entry for testing URLhaus RPZ
1008691.com CNAME . ; Malware download (2020-10-21), see https://urlhaus.abuse.ch/host/1008691.com/
123hpcom.site CNAME . ; Malware download (2021-12-30), see https://urlhaus.abuse.ch/host/123hpcom.site/
1566xueshe.com CNAME . ; Malware download (2022-01-14), see https://urlhaus.abuse.ch/host/1566xueshe.com/
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;经过测试，这样也是可以的。&lt;/p&gt;
&lt;p&gt;这样反而更简单一些。&lt;/p&gt;
&lt;p&gt;然后在查询这些广告站点的时候，可以看到rpzlog里面会有记录。nextdns是将这些客户端的查询，正常的和禁止的都列出来，然后进行标识在网页上，让人看的比较清晰一些。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;17-Feb-2022 05:34:40.468 rpz: info: client @0x7f19c4a43b70 100.200.200.50#65359 (tracker.eu.org): rpz QNAME NXDOMAIN rewrite tracker.eu.org/A/IN via tracker.eu.org.adblock
17-Feb-2022 05:34:43.212 rpz: info: client @0x7f19c4a43b70 100.200.200.50#59226 (ads.taboola.com): rpz QNAME NXDOMAIN rewrite ads.taboola.com/A/IN via ads.taboola.com.adblock
17-Feb-2022 05:35:03.369 rpz: info: client @0x7f19c4a44970 100.200.200.50#59904 (clientservices.googleapis.com): rpz QNAME NXDOMAIN rewrite clientservices.googleapis.com/A/IN via clientservices.googleapis.com.adblock
17-Feb-2022 05:35:03.369 rpz: info: client @0x7f19c4a44970 100.200.200.50#59904 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以数据的可视化部分还是比较重要的。&lt;/p&gt;
</content:encoded></item><item><title>在Ubuntu上面启用Bind的DNS-over-HTTPS</title><link>https://dididudu998.github.io/posts/configure-doh-bind/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/configure-doh-bind/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 15 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;在Ubuntu20.04上安装Bind 9.18 启用DoH&lt;/h1&gt;
&lt;p&gt;DoH的意义在于将域名解析的请求由原来的网络层直接提升到了浏览器应用层。&lt;/p&gt;
&lt;p&gt;网络层的问题是DoT使用853的端口，很容易被封锁，而DoH使用443端口，一般不会被封锁。&lt;/p&gt;
&lt;p&gt;在进行域名查询的时候，浏览器和安全域名服务提供者之间是没有第三方的，第三方无法获取浏览器想要查询的域名。只有自己和安全浏览器提供者之间知道你访问的主站是什么，至于具体访问了什么页面也是不可知的。&lt;/p&gt;
&lt;p&gt;但是DoH的速度上面并不见的比普通的UDP/TCP 53的DNS查询快。&lt;/p&gt;
&lt;p&gt;只是这种查询在浏览器的多线程的配合下，加载复杂页面的时候，可能有突然一起加载完成的情况，感觉比较快。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;sudo add-apt-repository ppa:isc/bind-dev&lt;/li&gt;
&lt;li&gt;sudo apt-get update&lt;/li&gt;
&lt;li&gt;sudo apt install bind9&lt;/li&gt;
&lt;li&gt;configure /etc/bind/named.conf.options&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;tls mytls{
                key-file &quot;/etc/bind/private.pem&quot;;
                cert-file &quot;/etc/bind/cert.pem&quot;;
        };

http local-http-server {
        endpoints { &quot;/dns-query&quot;; };
        };

options {
        directory &quot;/var/cache/bind&quot;;

        // If there is a firewall between you and nameservers you want
        // to talk to, you may need to fix the firewall to allow multiple
        // ports to talk.  See http://www.kb.cert.org/vuls/id/800113

        // If your ISP provided one or more IP addresses for stable
        // nameservers, you probably want to use them as forwarders.
        // Uncomment the following block, and insert the addresses replacing
        // the all-0&apos;s placeholder.

        // forwarders {
        //      1.1.1.1;
        //      8.8.8.8;
        //      9.9.9.9;
        // };

        //========================================================================
        // If BIND logs error messages about the root key being expired,
        // you will need to update your keys.  See https://www.isc.org/bind-keys
        //========================================================================
        recursion yes;
        allow-recursion { any; };
        listen-on { 10.214.23.216; };
        listen-on port 443 tls mytls http local-http-server { 10.214.23.216; };
        listen-on port 8899 tls none http local-http-server { 10.214.23.216; };
        //listen-on-v6 port 443 tls mytls http local-http-server { any; };
        //listen-on-v6 { any; };
        dnssec-validation auto;
};

logging {

        channel transfers {
            file &quot;/var/log/bind/transfers&quot; versions 3 size 10M;
            print-time yes;
            severity info;
        };
        channel notify {
           file &quot;/var/log/bind/notify&quot; versions 3 size 10M;
            print-time yes;
            severity info;
        };
        channel dnssec {
            file &quot;/var/log/bind/dnssec&quot; versions 3 size 10M;
            print-time yes;
            severity info;
        };
        channel query {
            file &quot;/var/log/bind/query&quot; versions 5 size 10M;
            print-time yes;
            severity info;
        };
        channel general {
            file &quot;/var/log/bind/general&quot; versions 3 size 10M;
        print-time yes;
        severity info;
        };
    channel slog {
        syslog security;
        severity info;
    };
        category xfer-out { transfers; slog; };
        category xfer-in { transfers; slog; };
        category notify { notify; };

        category lame-servers { general; };
        category config { general; };
        category default { general; };
        category security { general; slog; };
        category dnssec { dnssec; };

        category queries { query; };
};


&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;检查和启动服务&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;named-checkconf /etc/bind/named.conf
sudo systemctl restart bind9
sudo systemctl enable bind9
sudo systemctl status bind9
journalctl -xe  如果有错误信息的话，用这个检查。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;对bind log文件夹设定权限&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo mkdir -p /var/log/bind
sudo chown bind/var/log/bind
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;对apparmor进行设定&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;vi /etc/apparmor.d/usr.sbin.named
# 增加以下内容
  /etc/bind/** r,
  /var/lib/bind/** rw,
  /var/lib/bind/ rw,
  /var/cache/bind/** lrw,
  /var/cache/bind/ rw,
  /var/log/bind/** rw,
  /var/log/bind/ rw,
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;restart apparmor 服务 systemctl restart apparmor&lt;/li&gt;
&lt;li&gt;检查https查询： dig +https @dohserver.examplecn www.baidu.com A&lt;/li&gt;
&lt;li&gt;检查query log文件： cat /var/log/bind/query&lt;/li&gt;
&lt;li&gt;配置浏览器安全dns： https://dohserver.examplecn/dns-query&lt;/li&gt;
&lt;li&gt;测试是否可以正常访问网站&lt;/li&gt;
&lt;li&gt;检查query log是否正常&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;这里的证书和私钥是已有的，不需要自己生成。&lt;/p&gt;
&lt;p&gt;服务器使用的是Ubuntu20.04，安装了bind9，使用了apparmor。&lt;/p&gt;
&lt;p&gt;服务器的主机名为dohserver.examplecn，域名为examplecn。&lt;/p&gt;
&lt;p&gt;因为这个examplecn的域名由我管理，所以设定了dohserver.examplecn的A记录为10.214.23.216，内网可以解析即可。&lt;/p&gt;
&lt;p&gt;listen-on port 8899 tls none http local-http-server { 10.214.23.216; };&lt;/p&gt;
&lt;p&gt;这句的目的是在前端有一台nginx的服务器，在nginx的服务器上面做证书卸载。&lt;/p&gt;
&lt;p&gt;下面是nginx的配置文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
upstream doh {
        server 10.214.23.216:8899;
        #keepalive 8;
}


server {
        listen 443 ssl http2;
        #ssl on;
        #ssl_certificate /etc/nginx/ssl/server_1.cer;
        ssl_certificate /etc/nginx/ssl/server.cer;
        #ssl_certificate_key /etc/nginx/ssl/server_1.key;
        ssl_certificate_key /etc/nginx/ssl/server.key;
        server_name doh.examplecn;
        access_log /var/log/nginx/doh.log;

        location /dns-query {
                grpc_pass grpc://doh;
    }
 }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;浏览器在使用安全dns服务后，将请求发送给nginx服务器，nginx服务器再将请求发送给bind9服务器，bind服务器给出响应后，将响应发送给nginx服务器，nginx服务器将响应发送给浏览器。&lt;/p&gt;
&lt;p&gt;因为我的这台bind服务器是测试段，只有我和少量人可以使用，但是用nginx后，就可以发布到全体了。也就是这个事情。&lt;/p&gt;
&lt;p&gt;如果使用bind的src进行安装的话，需要的依赖必须装好，这个比较烦。但是目前centos还没有相应的package，所以先放着吧。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dohserver:/var/log/bind# named -v
BIND 9.18.0-2+ubuntu20.04.1+isc+1-Ubuntu (Stable Release) &amp;lt;id:&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>linux下面mail的一些使用方法</title><link>https://dididudu998.github.io/posts/mail%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/mail%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BD%BF%E7%94%A8/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 14 Dec 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;linux下面mail的一些使用方法&lt;/h2&gt;
&lt;p&gt;mail里面存放了系统给我的一些反馈，当然主要是一些错误信息。
时常在我写的脚本和小程序里面用mail来给我发送邮件提醒。当程序异常的时候，一般在mail里面就会有信息。&lt;/p&gt;
&lt;p&gt;今天就发现了新的问题。昨天写的小程序，比较两个sqlite的数据库，然后将比较结果发送给我，在每天的早上7点15.但是今天早上看邮箱，并没有这个邮件提醒。直接进系统，去运行这个小程序，发现结果是我想要的。但是crontab里面就没有执行成功。&lt;/p&gt;
&lt;p&gt;进mail看看，mail里面现在有几千封邮件，我该怎么查找呢？&lt;/p&gt;
&lt;p&gt;找到crontab里面我运行的指令，比如 cd /home/ubuntu/workspace/dailyrecord/ &amp;amp;&amp;amp; ./newinfo&lt;/p&gt;
&lt;p&gt;我去在mail里面这么查找：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入mail&lt;/li&gt;
&lt;li&gt;print /newinfo&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;print: Takes a message list and types out each message on the user&apos;s terminal. If the message is a MIME multipart message, all parts with a content type of &apos;text&apos; or &apos;message&apos; are shown; the others are hidden except for their headers. Messages are decrypted and converted to the terminal character set if necessary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Print: Like print but also prints out ignored header fields and all parts of MIME multipart/alternative messages. See also print, ignore, and retain.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然后上一封，下一封就用-+来查找了。&lt;/p&gt;
&lt;p&gt;更详细的mail用法见这里： https://www.computerhope.com/unix/umailx.htm#Searchheaders-Variable&lt;/p&gt;
&lt;p&gt;虽然一直在用，但是其实真正用的深度还是很浅。直到今天才知道可以这么用。真的是很强的unix操作。&lt;/p&gt;
</content:encoded></item><item><title>利用gdb来检查可执行文件的问题</title><link>https://dididudu998.github.io/posts/%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8gdb%E6%9D%A5%E6%A3%80%E6%9F%A5%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8gdb%E6%9D%A5%E6%A3%80%E6%9F%A5%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E7%9A%84%E9%97%AE%E9%A2%98/</guid><pubDate>Wed, 01 Dec 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;在最近的一次用c++编写的程序编译后，发现总是会出现segment错误的问题。摸不着头脑。&lt;/p&gt;
&lt;p&gt;总得看看是什么导致的问题吧。&lt;/p&gt;
&lt;p&gt;那就用gdb，至少可以知道大概的错误原因。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;linux系统上直接打开gdb&lt;/li&gt;
&lt;li&gt;输入file /path/to/executable&lt;/li&gt;
&lt;li&gt;输入 run&lt;/li&gt;
&lt;li&gt;输入 bt&lt;/li&gt;
&lt;li&gt;检查错误反馈，一般来说这个可以直接定位到编写的代码的错误的行&lt;/li&gt;
&lt;li&gt;输入 quit&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;结果&lt;/h2&gt;
&lt;p&gt;返回到的是一个调试信息，非常的精确。&lt;/p&gt;
&lt;p&gt;能够写代码是一回事，知道错误的原因是一回事，能够修改代码解决错误，又是另外一回事了。&lt;/p&gt;
&lt;p&gt;写编译器的是牛人，对编译后的代码进行debug的工具更是。&lt;/p&gt;
</content:encoded></item><item><title>linux下对事件进行实时email提醒</title><link>https://dididudu998.github.io/posts/linux%E4%B8%8B%E5%AE%9E%E6%97%B6email%E6%8F%90%E9%86%92/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/linux%E4%B8%8B%E5%AE%9E%E6%97%B6email%E6%8F%90%E9%86%92/</guid><pubDate>Sun, 28 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;原因是在早上对以前做的webdns进行测试修改的时候，看到dns的zone中存在一个记录，这个记录我没有印象。是2020年6月8号做的。感觉是和安全相关的。因为指向的记录是一个不存在的地址。可能是当时在query的记录中发现有大量的错误，所以做了这个zone。但是具体是什么，已经忘记了。&lt;/p&gt;
&lt;p&gt;查看了下ssh的known_hosts，发现有2个hosts为新加坡的亚马逊的记录，因为我以前分享过root密码给别人，所以目前还不能断定这个记录是不是他们添加的。&lt;/p&gt;
&lt;p&gt;为了安全起见，我需要做一个提醒给我，以免真的安全问题，自己还不清楚。&lt;/p&gt;
&lt;h1&gt;实现&lt;/h1&gt;
&lt;p&gt;以前写过将last的信息发邮件给我的。但是那个不是实时的。&lt;/p&gt;
&lt;p&gt;这次必须要做成实时的警告。&lt;/p&gt;
&lt;p&gt;解决方法是利用rsyslog的日志记录和邮件功能。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编辑/etc/rsyslog.d/alerttomark.conf文件&lt;/li&gt;
&lt;li&gt;文件内容如下：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;ModLoad ommail
$ActionMailSMTPServer localhost
$ActionMailFrom alert@example.com
$ActionMailTo mark@xxx.com
$ActionMailTo mark@yyy.com
$template mailSubject,&quot;Login Alert on %hostname%&quot;
$template mailBody,&quot;%fromhost%\r\n\r\nTime:%timereported%\r\n\r\n\n%msg%&quot;
$ActionMailSubject mailSubject
$ActionExecOnlyOnceEveryInterval 1
# the if ... then ... mailBody mus be on one line!
#if $msg contains &apos;session opened for user&apos; then :ommail:;mailBody
if $msg contains &apos;session opened&apos; then :ommail:;mailBody

$ActionMailFrom alert@example.com
$ActionMailTo mark@xxx.com
$ActionMailTo mark@yyy.com
$ActionMailSubject,&quot;Something wrong on %hostname%&quot;
## only works on newest rsyslog: make sure we receive a mail only once in half an hour
$ActionExecOnlyOnceEveryInterval 1800
if not($msg contains &apos;10.214.23.131&apos;) and($msg contains&apos;fail&apos;) then :ommail:;mailBody
$ActionExecOnlyOnceEveryInterval 0

$ActionMailFrom alert@example.com
$ActionMailTo mark@xxx.com
$ActionMailTo mark@yyy.com
$ActionMailSubject,&quot;logging information on %hostname%&quot;
## only works on newest rsyslog: make sure we receive a mail only once in half an hour
$ActionExecOnlyOnceEveryInterval 1800
if $msg contains &apos;logging in&apos; or &apos;logging out&apos; then :ommail:;mailBody
$ActionExecOnlyOnceEveryInterval 0
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;重启rsyslog服务&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart rsyslog
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试
&lt;ul&gt;
&lt;li&gt;退出所有的ssh终端&lt;/li&gt;
&lt;li&gt;重新ssh login&lt;/li&gt;
&lt;li&gt;检查是否收到邮件&lt;/li&gt;
&lt;li&gt;测试结果实现了实时的警告。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;后续&lt;/h2&gt;
&lt;p&gt;对于CentOS，由于secure日志的安全性，不能直接获得ssh登陆的信息，要想拿到，可setenforce 0.然后就可以了&lt;/p&gt;
</content:encoded></item><item><title>dump出内存，并进行简单分析</title><link>https://dididudu998.github.io/posts/dump-memory-analysis/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/dump-memory-analysis/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 23 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;主要是最近在学习c++，想要做一个内存镜像的东西，将内存中的文件夹和文件dump出来，然后将里面的文件内容给存储下来，这样可以解决的问题是，如果某个进程卡死，但是没有退出的话， 还有可能挽救文件啊，😄&lt;/p&gt;
&lt;p&gt;自己编程目前以我的技术还差的有点远。但是linux系统本身就有这样的功能，虽然没有到我想要的地步。但是做事情哪能你想的有就有，肯定是要自己再去研究一下的。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;获取想要dump的进程的pid&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ps|aux|grep -i &quot;process name&quot; | awk &apos;{print $2}&apos;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;获取内存空间&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;cat /proc/pid/maps,见下面的例子&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@flask:~# cat /proc/3678079/maps
00400000-006a4000 r-xp 00000000 08:01 2622765                            /var/www/getnyuservice
006a4000-00946000 r--p 002a4000 08:01 2622765                            /var/www/getnyuservice
00946000-0099e000 rw-p 00546000 08:01 2622765                            /var/www/getnyuservice
......
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将需要的部分内存空间dump出来&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;gdb --pid 3678079
(gdb) dump memory /tmp/memory.dump 0x00400000 0x006a4000
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;检索dump出来的文件. 如果存在service这个关键字，则显示其上下10行的内容&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;hexdump -C /tmp/memory.dump | grep -10 service
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;如果没有安装gdb，也可以使用gcore这样的，它可以直接将这个pid的所有的内存空间都dump出来。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;gcore -o /tmp/core.dump 3678079
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;工具篇&lt;/h2&gt;
&lt;p&gt;如果不是用系统自带的，那么还有这样的工具可以使用。&lt;/p&gt;
&lt;p&gt;参考这里&amp;lt;a href=&quot;https://book.hacktricks.xyz/forensics/basic-forensic-methodology/memory-dump-analysis/volatility-examples#dump-proc&quot;&amp;gt;volatility&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;这个工具的功能非常强大，可以对系统做各种的分析。不仅是内存方面的，还有sid，token等等。&lt;/p&gt;
</content:encoded></item><item><title>对windows的可疑程序进行测试</title><link>https://dididudu998.github.io/posts/%E5%AF%B9windows%E7%9A%84%E5%8F%AF%E7%96%91%E7%A8%8B%E5%BA%8F%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%AF%B9windows%E7%9A%84%E5%8F%AF%E7%96%91%E7%A8%8B%E5%BA%8F%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 23 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;有很多的程序，尤其是windows上面的，有的破解后的程序基本上都带有一些可疑的功能，要么是释放一些广告，要么是留有后门，要么是在注册表中添加一些不相干的东西。&lt;/p&gt;
&lt;p&gt;所以对一些程序的测试需要下面的工具和环境。&lt;/p&gt;
&lt;p&gt;原文见这里：&amp;lt;a href=&quot;https://whiteheart0.medium.com/?p=58304f6bc20a&quot;&amp;gt;Dynamic Analysis of Watchdog spyware&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;h2&gt;环境&lt;/h2&gt;
&lt;p&gt;一般使用vmware的fusion，对于个人来说是免费的，只要申请一个序列号就可以。当然其他的像vbox的也没问题。&lt;/p&gt;
&lt;p&gt;用虚拟机的主要目的是为了可以快速恢复，利用snapshot的功能，初现问题，可以很快的恢复到之前的状态。&lt;/p&gt;
&lt;h2&gt;必备的应用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;注册表快照&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regshot is an open-source (LGPL) registry compare utility that allows you to quickly take a snapshot of your registry and then compare it with a second one - done after doing system changes or installing a new software product.&lt;/p&gt;
&lt;p&gt;https://sourceforge.net/projects/regshot/&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Capture BAT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Capture BAT provides a powerful mechanism to exclude event noise that naturally occurs on an idle system or when using a specific application. This mechanism is fine-grained and allows an analyst to take into account the process that cause the various state changes. As a result, this mechanism even allows Capture to analyze the behavior of documents that execute within the context of an application, for example the behavior of a malicious Microsoft Word document.&lt;/p&gt;
&lt;p&gt;https://www.honeynet.org/projects/old/capture-bat/&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wireshark&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个是用来做网络抓包的。在使用虚拟机的时候，抓包，最好可以使用映射端口的形式。这样比较清晰一些。&lt;/p&gt;
</content:encoded></item><item><title>在安卓手机上彻底删除SD卡的数据</title><link>https://dididudu998.github.io/posts/%E5%9C%A8%E5%AE%89%E5%8D%93%E6%89%8B%E6%9C%BA%E4%B8%8A%E5%BD%BB%E5%BA%95%E5%88%A0%E9%99%A4sd%E5%8D%A1%E7%9A%84%E6%95%B0%E6%8D%AE/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%9C%A8%E5%AE%89%E5%8D%93%E6%89%8B%E6%9C%BA%E4%B8%8A%E5%BD%BB%E5%BA%95%E5%88%A0%E9%99%A4sd%E5%8D%A1%E7%9A%84%E6%95%B0%E6%8D%AE/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Sat, 20 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;莫名的红米Note7的手机在天快亮的时候不断的充电断开，再充电断开，这声音把我给吵醒了。。。。&lt;/p&gt;
&lt;p&gt;旁边有两个充电器，以为是充电器坏了，就换了一个，发现故障依旧啊，但是另外一个手机就没有问题。所以是note7的问题。&lt;/p&gt;
&lt;p&gt;尝试关机充电看看，关机的时候，充电是正常的。&lt;/p&gt;
&lt;p&gt;再启动下，发现充电也没有问题。但是启动后，手机提示SD卡无法加载，请格式化SD卡的提示。我x，要是这样里面下载的歌和图片都没有了。&lt;/p&gt;
&lt;p&gt;死马当活马医，把这个sd卡关机拿下来，放到另外的手机上，看看是否能够正常加载。失败，依旧是提示数据无法加载，请格式化。&lt;/p&gt;
&lt;p&gt;什么都没干，这卡怎么就废了。。。。&lt;/p&gt;
&lt;p&gt;联系京东售后，说这个卡在保修期内，可以换，那就换吧。&lt;/p&gt;
&lt;p&gt;我手头没有sd卡的卡套，没法在电脑上进行尝试修复的操作。如果卡被京东回收后，数据可以修复，我的个人信息不就全expose了。&lt;/p&gt;
&lt;p&gt;咱做技术的，不能就这么的简单。&lt;/p&gt;
&lt;h2&gt;处理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;格式化SD卡，按照手机提示，只好先格式化，可是格式化也出问题，格式化了15分钟，卡死在格式化界面了，我x，这卡看来是真彻底废了&lt;/li&gt;
&lt;li&gt;不死心，把卡拿下来换到另外一个手机上，按照提示格式化的再来一下，这次还不错，不到1分钟就格式化完成了。&lt;/li&gt;
&lt;li&gt;数据被清理了，等京东来回收。&lt;/li&gt;
&lt;li&gt;手机里面装个termux，开始做深度wipe的操作
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;lt;font color=green&amp;gt;pkg install tsu&amp;lt;/font&amp;gt; （这个是安装termux的root的，开启tsu就直接进root模式）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mount一下，看看sd卡的路径，发现是那种文件挂载的路径，这是不行的，需要找到/dev/路径的那种对象才可以&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后找到sd的设备路径为：
&amp;lt;font color=red&amp;gt;&amp;lt;b&amp;gt;/dev/block/vold/179,65&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开始用dd来复写sd卡&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/urandom of=/dev/block/vold/179,65
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;做了个测试，如果是使用0来复写的话，速度大概是每秒50MB，使用随机的话，每秒只有11MB的速度。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=/dev/block/vold/179,65 bs=2G count=1 oflag=direct

dd if=/dev/uraom of=/dev/block/vold/179,65 bs=2G count=1 oflag=direct
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;结果&lt;/h2&gt;
&lt;p&gt;就是SD卡128GB,用urandom的方式,花了有三个多小时，以每秒11.8MB的速度，复写了一遍。&lt;/p&gt;
&lt;p&gt;以后买手机就直接买存储空间大的，最少256GB起，不要再幻想用SD卡来存一些数据，这个数据的存储风险太大了。&lt;/p&gt;
&lt;p&gt;还是苹果做的彻底，根本就不会有SD卡扩展的可能。&lt;/p&gt;
</content:encoded></item><item><title>记录</title><link>https://dididudu998.github.io/posts/14-40-%E8%AE%B0%E5%BD%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/14-40-%E8%AE%B0%E5%BD%95/</guid><pubDate>Thu, 28 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;记录&lt;/h1&gt;
&lt;p&gt;people do not buy software because of what it does, they buy it for the positive change it will make in the life. if you think &quot;people should buy this because it will make them money, save them time, and get them back to their kids faster&apos;, then you probably have a viable idea;&lt;/p&gt;
&lt;p&gt;people love talking about their problems to anyone who will listen to them. often they won&apos;t have the first clue about what a solution looks like, but at the very least repeateed similar emotional reactions from many people in a market should tell you that the problem is there and real.&lt;/p&gt;
&lt;p&gt;you will likely be involved in the business until you decide to quit. markets which change quickly or where products rot.&lt;/p&gt;
&lt;p&gt;avoid events, plan for processes.&lt;/p&gt;
&lt;p&gt;document everything.&lt;/p&gt;
&lt;p&gt;solving complex technical problems is not a goal, writing bug-free code is not a goal, using sexy programming languages is not a goal, but add revenue, reduce costs that is the only goals.&lt;/p&gt;
</content:encoded></item><item><title>用C调用linux shell，用来屏蔽对shell的直接引用</title><link>https://dididudu998.github.io/posts/%E7%94%A8c%E8%B0%83%E7%94%A8linux-shell/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8c%E8%B0%83%E7%94%A8linux-shell/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Thu, 28 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;有一个sqlite的数据库，用shell的方式获取查询的结果，然后输出到html文件，再将这个文件用shell发送给我。&lt;/p&gt;
&lt;h1&gt;实现&lt;/h1&gt;
&lt;p&gt;查询sqlite数据库文件见下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
cd &quot;/usr/local/lib/python3.6/dist-package/folder&quot;

sqlite3 vlundb &quot;select * from vluninfo where severity&amp;gt;=3;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发邮件给我：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
cd &quot;/usr/local/lib/python3.6/dist-packages/folder&quot;

today=`date +%Y%m%d`
sh qs.sh &amp;gt; vluns-$today.html

mailx -r vluns-high@example.com -s &quot;vluns-high-critical&quot; mark@example.com &amp;lt;vluns-$today.html

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C程序是网上抄的,见下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
int main(){
        FILE *pipe=popen(&quot;sh /usr/local/lib/python3.6/dist-packages/folder/mailtome.sh&quot;, &quot;r&quot;);
        if(pipe){
                char buffer[128];
                while(!feof(pipe)){
                        if(fgets(buffer,128,pipe)!=NULL){}
                }
                pclose(pipe);
                buffer[strlen(buffer)-1]==&apos;\0&apos;;
        }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;结果&lt;/h1&gt;
&lt;p&gt;将编译生成后的可执行文件拷贝到其他的目录执行，发现结果如所期望的实现了。&lt;/p&gt;
&lt;p&gt;目前就这样吧。&lt;/p&gt;
</content:encoded></item><item><title>电子书集合</title><link>https://dididudu998.github.io/posts/%E7%94%B5%E5%AD%90%E4%B9%A6%E9%9B%86%E5%90%88/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%B5%E5%AD%90%E4%B9%A6%E9%9B%86%E5%90%88/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Sun, 24 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;网上电子书集合&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;https://ebook2.lorefree.com&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;https://www.kgbook.com&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;https://sobooks.cc&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;https://z-lib.org&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;https://www.jiumodiary.com&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;https://manybooks.net/   这个搜素英文书为主&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我一般用gen。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;https://zh.sa1lib.org/s/golang  这个是一个补充，搜索的时候发现的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不过这些应当是够了。如果还是找不到，而且特别喜欢，那就到各地的图书馆线上资源来查吧。&lt;/p&gt;
</content:encoded></item><item><title>Windows安装powercli并监控是否有新的虚拟机生成</title><link>https://dididudu998.github.io/posts/windows%E5%AE%89%E8%A3%85powercli%E5%B9%B6%E7%9B%91%E6%8E%A7%E6%98%AF%E5%90%A6%E6%9C%89%E6%96%B0%E7%9A%84%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%94%9F%E6%88%90/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windows%E5%AE%89%E8%A3%85powercli%E5%B9%B6%E7%9B%91%E6%8E%A7%E6%98%AF%E5%90%A6%E6%9C%89%E6%96%B0%E7%9A%84%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%94%9F%E6%88%90/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Sun, 03 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;安装powercli&lt;/h1&gt;
&lt;p&gt;这个感觉是非常简单的，在管理员模式下，进入powershell，输入 install-module vmware.powercli&lt;/p&gt;
&lt;p&gt;但是可惜报错，提示无法解析powershellgallary.microsoft.com，域名解析是没有问题的，出问题的原因在于请求的加密方式，需要在powershell下面输入下面的命令，调整安全请求的协议为TLS1.2.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后再运行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;install-module vmware.powercli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就可以正常安装了。&lt;/p&gt;
&lt;p&gt;然后一定要记得，要import才可以使用哦。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Import-Module VMware.PowerCLI
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上整个的安装过程结束。&lt;/p&gt;
&lt;h1&gt;测试监控脚本&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;$vCenterServer = &quot;myvc&quot;    #Can also be a VMware host
$Days = 1
$Mail = @{
    To = &quot;mark@example.com&quot;
    From = &quot;new-vm-created-notify@shanghai.nyu.edu&quot;
    Subject = &quot;new vm created notify&quot;
    SMTPServer = &quot;smtp.mark.com&quot;
}

$Header = @&quot;
&amp;lt;style&amp;gt;
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
&amp;lt;/style&amp;gt;
&quot;@

$pd=get-content &quot;./password.txt&quot; |convertto-SecureString
$mycre=new-object system.management.automation.PSCredential(&quot;mark@vsphere.local&quot;,$pd)
connect-viserver $vCenterServer -credential $mycre| Out-Null
$Events = Get-VIEvent -Start (Get-Date).AddDays(-$Days) -MaxSamples 100000 | Where {$_.Gettype().Name-eq &quot;VmCreatedEvent&quot; } | Sort CreatedTime -Descending | Select CreatedTime, UserName,FullformattedMessage #linux环境下，用Sort-Object替换Sort
If ($Events)
{   $Body = $Events | ConvertTo-HTML -PreContent &quot;New VM&apos;s have been created:&amp;lt;br&amp;gt;&quot; -Head $Header | Out-String
}
Else
{   $Body = &quot;No VM&apos;s have been created today: $(Get-Date) in vCenter $vCenterServer&quot;
}

Send-MailMessage @Mail -Body $Body -BodyAsHtml 
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>获取这几天看的pdf文件</title><link>https://dididudu998.github.io/posts/%E8%8E%B7%E5%8F%96%E8%BF%99%E5%87%A0%E5%A4%A9%E7%9C%8B%E7%9A%84pdf%E6%96%87%E6%A1%A3/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%8E%B7%E5%8F%96%E8%BF%99%E5%87%A0%E5%A4%A9%E7%9C%8B%E7%9A%84pdf%E6%96%87%E6%A1%A3/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Wed, 15 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;获取这几天看的pdf文件&lt;/h1&gt;
&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;由于pdf阅读器有时候会crash，有时候也是自己会不小心关掉，或者系统升级的什么原因，总之是会退出。但是退出后，不是将我以前看的文档都打开，而是打开几个最近看的文档。而且个数很少，好像只有4个还是几个。应该是应用程序的设定的问题。&lt;/p&gt;
&lt;p&gt;导致我经常要找以前打开的文档，要找很久，有时候一篇pdf文档不是一直在看的。加上pdf比较多，就有点乱了。&lt;/p&gt;
&lt;p&gt;所以需要按天整理下当天打开的pdf文件，弄个列表出来。&lt;/p&gt;
&lt;h2&gt;解决方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;获取我打开pdf文件的应用的pid&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
ps aux | grep &apos;PDF&apos; |awk &apos;{print $2}&apos; | head -1

ps aux | grep &apos;Skim&apos; |awk &apos;{print $2}&apos; |head -1

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;利用pid获取打开的文件信息&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
lsof -p 1224 |grep .pdf|awk &apos;{print substr($0,index($0,$9))}&apos; &amp;gt;2021-09-15-reading-pdf.txt

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;合起来写成script&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
#!/bin/bash

today=`date +%Y-%m-%d`

printf &quot;PDF Experf opened files below:\n &quot;

ppid=($(ps aux | grep &apos;PDF&apos; |awk &apos;{print $2}&apos; | head -1))

lsof -p $ppid |grep .pdf |awk &apos;{print substr($0,index($0,$9))}&apos;

lsof -p $ppid |grep .pdf |awk &apos;{print substr($0,index($0,$9))}&apos; &amp;gt;$today-pdf-openfiles.txt



while ((i&amp;lt;100));do
  printf &quot;-&quot;
  ((i=i+1))
done

printf &quot;\n&quot;

printf &quot;Skim opened pdf files below:\n&quot;


ppid_skim=($(ps aux | grep &apos;Skim&apos; |awk &apos;{print $2}&apos; | head -1))
lsof -p $ppid_skim | grep .pdf |awk &apos;{print substr($0,index($0,$9))}&apos;

lsof -p $ppid_skim | grep .pdf |awk &apos;{print substr($0,index($0,$10))}&apos;&amp;gt;&amp;gt;$today-pdf-openfiles.txt

cat $today-pdf-openfiles.txt|xargs echo | mail -v -s pdf-books-reading miaomiaomi@outlook.com

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;结果&lt;/h2&gt;
&lt;p&gt;就是将pdf阅读器目前打开的文件列出来，然后最后用mail发送邮件给我。&lt;/p&gt;
&lt;p&gt;这个mail要在～/.mailrc里面做个配置。outlook有个好处就是接受来自非internet注册的smtp服务器的邮件，虽然大部分会放在垃圾箱，但是还是可以收到的。&lt;/p&gt;
&lt;p&gt;至此，问题算是有个解决了。&lt;/p&gt;
</content:encoded></item><item><title>从多个pdf文件中找关键字</title><link>https://dididudu998.github.io/posts/%E4%BB%8E%E5%A4%9A%E4%B8%AApdf%E6%96%87%E4%BB%B6%E4%B8%AD%E6%89%BE%E5%85%B3%E9%94%AE%E5%AD%97/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BB%8E%E5%A4%9A%E4%B8%AApdf%E6%96%87%E4%BB%B6%E4%B8%AD%E6%89%BE%E5%85%B3%E9%94%AE%E5%AD%97/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 25 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;从多个pdf文件找到自己想要的那个文件&lt;/h1&gt;
&lt;p&gt;前几天为了提升大闹学习的兴趣，找到了个指导用python的turtle模块进行编程的pdf文件。
但是今天想要找的时候，找不到了，感觉就是那么几个pdf，但是就是找不到。&lt;/p&gt;
&lt;h2&gt;解决方法&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;打开多个pdf文件&lt;/li&gt;
&lt;li&gt;然后对多个pdf文件进行内容查找&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第二步用到的是pdf expert,我把这个作为我默认的打开pdf的应用，它里面有一个查找的功能，可以查找所有打开的标签页。&lt;/p&gt;
&lt;p&gt;那么只要第一步可以实现，问题就可以解决了。&lt;/p&gt;
&lt;p&gt;第一步本想着用python来实现。发现还是太麻烦。还是用shell吧。&lt;/p&gt;
&lt;p&gt;下面是我的shell：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/zsh
filename=&quot;pdf_latest_60.txt&quot;
#folder=&quot;/Users/ls3686/Downloads/libgen-downloads/&quot;
folder1=&quot;/Users/ls3686/Downloads/&quot;
#cd $folder &amp;amp;&amp;amp; ls -t *Algo*.pdf |head -60 &amp;gt;$filename
cd $folder1 &amp;amp;&amp;amp; ls -t *Algo*.pdf | head -60 &amp;gt;$filename
while read line;do
#  echo $line
  file=$folder$line
  echo &quot;$file&quot;
  open &quot;$file&quot;
done &amp;lt;$filename
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就打开了多个pdf文件。&lt;/p&gt;
&lt;p&gt;然后在pdf expert中，这样搜索：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/pdf%E6%9F%A5%E8%AF%A2.jpg&quot; alt=&quot;pdf-keywords&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在右边的搜索结果栏就会出现找关键字的片段，单击就可以确认是那个pdf了。&lt;/p&gt;
&lt;h2&gt;后记&lt;/h2&gt;
&lt;p&gt;解决问题有多个方法，怎么方便怎么来。&lt;/p&gt;
&lt;p&gt;在使用编程解决的时候，有利用pdf模块将pdf文件转成文本，再对文本进行搜索的方法，这个在没有任何第三方工具的时候是个办法。&lt;/p&gt;
&lt;p&gt;但是我们有现成的pdf软件，借用软件自身的功能，做起来既方便又快。&lt;/p&gt;
&lt;p&gt;顺便，自己下载的pdf文件真的比较多。&lt;/p&gt;
</content:encoded></item><item><title>ksmtuned 服务占了大量的cpu资源</title><link>https://dididudu998.github.io/posts/centos-ksmtuned-high-cpu/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/centos-ksmtuned-high-cpu/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 24 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;在检查netdata的数据的时候，发现有个进程占了大量的cpu资源。&lt;/p&gt;
&lt;p&gt;这台机器是centos8的，不知道是不是因为8里面安装了某些东西的缘故。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NAME=&quot;CentOS Linux&quot;
VERSION=&quot;8 (Core)&quot;
ID=&quot;centos&quot;
ID_LIKE=&quot;rhel fedora&quot;
VERSION_ID=&quot;8&quot;
PLATFORM_ID=&quot;platform:el8&quot;
PRETTY_NAME=&quot;CentOS Linux 8 (Core)&quot;
ANSI_COLOR=&quot;0;31&quot;
CPE_NAME=&quot;cpe:/o:centos:centos:8&quot;
HOME_URL=&quot;https://www.centos.org/&quot;
BUG_REPORT_URL=&quot;https://bugs.centos.org/&quot;

CENTOS_MANTISBT_PROJECT=&quot;CentOS-8&quot;
CENTOS_MANTISBT_PROJECT_VERSION=&quot;8&quot;
REDHAT_SUPPORT_PRODUCT=&quot;centos&quot;
REDHAT_SUPPORT_PRODUCT_VERSION=&quot;8&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/ksmtuned.jpg&quot; alt=&quot;high-cpu-process&quot; /&gt;&lt;/p&gt;
&lt;p&gt;google了下，内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Kernel same-page Merging (KSM), used by the KVM hypervisor, allows KVM guests to share identical memory pages. These shared pages are usually common libraries or other identical, high-use data. KSM allows for greater guest density of identical or similar guest operating systems by avoiding memory duplication……
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;p&gt;解决方案见&lt;a href=&quot;https://thelinuxcluster.com/2020/06/22/swap-overheads-ksm-and-tuned/&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;停止和禁用这服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
systemctl stop ksmtuned
systemctl stop ksm

systemctl disable ksmtuned
systemctl disable ksm

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When KSM is disabled, any memory pages that were shared prior to deactivating KSM are still shared. To delete all of the PageKSM in the system, use the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo 2 &amp;gt;/sys/kernel/mm/ksm/run
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>一个简单问题的溯源过程</title><link>https://dididudu998.github.io/posts/%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E9%97%AE%E9%A2%98%E6%BA%AF%E6%BA%90/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E9%97%AE%E9%A2%98%E6%BA%AF%E6%BA%90/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 24 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;这篇只是想用一个溯源的过程，让人了解，什么是系统，以及各自的人员对于系统的理解。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;p&gt;通过powercli获得在7月31日，有部分虚拟机提示nvram: write failed.错误。 这个是vmware的管理员看到的情况。&lt;/p&gt;
&lt;p&gt;这个错误在vmware的kb上是说和datastore有关系。&lt;/p&gt;
&lt;p&gt;然后存储管理员查7月31日的datastore日志。&lt;/p&gt;
&lt;p&gt;发现7月31日的netapp磁盘阵列出现了断电的事故，但是netapp是双头的，所以大部分的应用不受影响。存储管理员也没有对这个事件做出响应，因为电来了后，就自动恢复了。&lt;/p&gt;
&lt;p&gt;然后联系facility的人员，确认在7月31日确实出现了一定时间的停电故障。&lt;/p&gt;
&lt;h1&gt;结论&lt;/h1&gt;
&lt;p&gt;这里溯源的过程，各个角色看到的情况是不同的。但是都互相产生了影响。停电导致存储部分失效，而这部分和某些应用的vm有关系。&lt;/p&gt;
&lt;p&gt;所以当出现问题的时候，或者溯源的时候，一定要先了解互相的依赖关系。有时候看到的表象，并不一定是自身的问题导致的，互相依赖的情况下，紧耦合的这种情况，会导致一连串的问题发生。&lt;/p&gt;
&lt;p&gt;在更多的时候，利用流程可以做到最小化的影响。但是首先问题是确认资产，然后资产间的关系。很多做事情的人，只了解做自己的工作，忽略了自身工作和其他人工作的联系，导致了工作协作之间本应是1+1&amp;gt;2的情况，却发生了1+1&amp;lt;1的情况大量发生。&lt;/p&gt;
&lt;p&gt;流程减少人与人之间的摩擦，用规则和实例指导事情的反应和流转。越是大的公司，越需要这样的规则，否则会出比较大的问题。&lt;/p&gt;
</content:encoded></item><item><title>用概率来计算鱼塘中鱼的数量和质量</title><link>https://dididudu998.github.io/posts/%E7%94%A8%E6%A6%82%E7%8E%87%E6%9D%A5%E8%AE%A1%E7%AE%97%E6%95%B0%E9%87%8F%E5%92%8C%E8%B4%A8%E9%87%8F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8%E6%A6%82%E7%8E%87%E6%9D%A5%E8%AE%A1%E7%AE%97%E6%95%B0%E9%87%8F%E5%92%8C%E8%B4%A8%E9%87%8F/</guid><pubDate>Tue, 24 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;利用概率来计算一种未知&lt;/h1&gt;
&lt;p&gt;以下文章来自图书《程序员的数学思维修炼》。&lt;/p&gt;
&lt;p&gt;老李在农贸市场开了一个鲜鱼销售店，经常要到乡村去整塘购买渔民养的鱼，并每天从池塘中打鱼到门店中进行销售。&lt;/p&gt;
&lt;p&gt;在购买整塘的鱼时，需要根据鱼的重量与渔民签订合同，计算合同金额。可是，该怎么估算鱼塘中鱼的重量呢？&lt;/p&gt;
&lt;p&gt;在估算时，应使鱼的损失尽量小，并能尽量准确地估算出鱼的重量，并且这种方法要让买卖双方都接受。&lt;/p&gt;
&lt;p&gt;通常能想到的办法有以下几种。&lt;/p&gt;
&lt;p&gt;第一种方法：首先想到的方法就是称重。将池塘中的鱼全部打捞上来，再称重，这样可以得到比较精确的重量。可是，将鱼全部打捞上来称重后再放回池塘，会造成很大一部分鱼会死掉。&lt;/p&gt;
&lt;p&gt;第二种方法：可考虑一种将问题规模缩小的方法。即将鱼塘划分成相等的多个区域，然后将一个区域中的鱼打捞上来，进行称重。再将该区域中鱼的重量乘以划分的区域数量，即可得到总的重量。&lt;/p&gt;
&lt;p&gt;可是这种方法的缺点也是很明显的。划分的区域通常不能达到均匀相等；另一方面，对划分的区域进行打捞时，由于鱼会四处游动，并不能保证可以将所划分区域中的鱼全部打捞上来。&lt;/p&gt;
&lt;p&gt;由于这些缺点，导致最终计算出来的结果误差很大，从而使买卖双方不容易认可、接受。&lt;/p&gt;
&lt;p&gt;第三种方法：使用概率来估算。本节我们将详细介绍这种方法。&lt;/p&gt;
&lt;h2&gt;用概率来计算&lt;/h2&gt;
&lt;p&gt;用概率来估算鱼塘中鱼的重量，可以达到比较准确并能被买卖双方接受的结果。下面介绍具体的实现方法，可按以下步骤进行操作。&lt;/p&gt;
&lt;p&gt;（1）从鱼塘中捞出100条鱼进行称重。&lt;/p&gt;
&lt;p&gt;（2）将这100条鱼做上标记，然后放入池塘中。&lt;/p&gt;
&lt;p&gt;（3）等一段时间后，在池塘的不同位置随机撒网打捞，将一网打捞上来的鱼进行称重，并记录第（2）步中做好标记的鱼的数量，以及未做标记的鱼的数量。&lt;/p&gt;
&lt;p&gt;（4）多次重复第（3）步。&lt;/p&gt;
&lt;p&gt;（5）将记录的数据进行计算，计算出做了标记的100条鱼被打捞上来的概率。&lt;/p&gt;
&lt;p&gt;（6）根据得到的概率即可估算出整个池塘中鱼的数量和重量。&lt;/p&gt;
&lt;p&gt;下面以一个实际操作来看看这种通过概率估算池塘中的鱼重量的方法。&lt;/p&gt;
&lt;p&gt;（1）首先从池塘中打捞出100条鱼，称出这100条鱼的重量为216公斤。&lt;/p&gt;
&lt;p&gt;（2）在这100条鱼的鱼尾涂上红色油漆，然后将这些鱼放入池塘中。&lt;/p&gt;
&lt;p&gt;（3）一小时之后，在池塘的不同地方多次撒网打鱼，并记录每次打捞上来的鱼的数量，包括有标记和无标记的鱼的数量。10次打捞后的结果如表6-3所示。&lt;/p&gt;
&lt;p&gt;表6-3
&lt;img src=&quot;/images/tupian/%E9%B1%BC%E5%A1%98.png&quot; alt=&quot;打捞&quot; /&gt;&lt;/p&gt;
&lt;p&gt;有了以上表格中的数据，接下来就可以进行估算了。首先估算鱼塘中鱼的数量，将10次打捞的鱼中有标记的鱼的数量相加，得到：&lt;/p&gt;
&lt;p&gt;2+3+1+3+4+3+1+2+2+1=22&lt;/p&gt;
&lt;p&gt;而打捞了10次，一共捕鱼数量为：&lt;/p&gt;
&lt;p&gt;22+25+23+18+。。。+13=205&lt;/p&gt;
&lt;p&gt;那么有标记的鱼的数量与打捞上来的鱼的数量的比可以计算为一个概率：&lt;/p&gt;
&lt;p&gt;22/205=0.1073&lt;/p&gt;
&lt;p&gt;那么我们是投放了100条有标记的鱼在鱼塘的，可以估算出鱼塘中总的鱼的数量约为：&lt;/p&gt;
&lt;p&gt;100/0.1073=932&lt;/p&gt;
&lt;p&gt;计算出鱼的总数量之后，接下来再来估算鱼的重量。100条做了标记的鱼的重量为216公斤，则每条鱼的平均重量为2.16公斤。所以，池塘中鱼的重量估算为：&lt;/p&gt;
&lt;p&gt;932*2.16=2013&lt;/p&gt;
&lt;p&gt;就是说这个池塘总的鱼的重量约2013公斤。每条鱼大约重2.16公斤，大约有鱼932条。&lt;/p&gt;
&lt;h2&gt;后记&lt;/h2&gt;
&lt;p&gt;这个利用概率来解决问题的思路需要掌握，在生活中有些地方可以使用的上。&lt;/p&gt;
&lt;p&gt;概率思路也是区分对于问题的抽象和理解到了一种程度后的人与人的差距。&lt;/p&gt;
&lt;p&gt;能够将问题拆分为组合，计算组合的概率，然后得到一个比较接近实际的值，是一种非常强大的逻辑思路。&lt;/p&gt;
</content:encoded></item><item><title>从sec.org获上市公司信息</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8E%E9%98%85%E8%AF%BB%E4%B8%8A%E5%B8%82%E5%85%AC%E5%8F%B8%E5%B9%B4%E6%8A%A5/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8E%E9%98%85%E8%AF%BB%E4%B8%8A%E5%B8%82%E5%85%AC%E5%8F%B8%E5%B9%B4%E6%8A%A5/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 19 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;sec.org&lt;/h1&gt;
&lt;p&gt;首先从这里获取上市公司的CKI信息，这串代码跟着上市公司，哪怕它改名或者怎么滴，类似于上市公司的身份证。&lt;/p&gt;
&lt;p&gt;https://www.sec.gov/edgar/searchedgar/cik.htm&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/cik-search-page.png&quot; alt=&quot;cik-search-page&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在这里输入上市公司的名字，比如我知道有Amazon，那就输入Amazon，然后提交，它会返回一个列表。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/CIK.png&quot; alt=&quot;CIK&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里面是包含有Amazon这个字段的所有的上市公司，几乎是可以分辨出来的，那就是Amazon.com，号码就是1018724。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/find_cik.png&quot; alt=&quot;find_cik&quot; /&gt;&lt;/p&gt;
&lt;p&gt;单击这串数字，进入主题。&lt;/p&gt;
&lt;h1&gt;年报和季报&lt;/h1&gt;
&lt;p&gt;这个页面的信息很全面。其中8-K就是最近的财报，10-k就是年报，10-Q就是季报。&lt;/p&gt;
&lt;p&gt;点击进去，想看那个看那个，当然如果有兴趣的话。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/info.png&quot; alt=&quot;info&quot; /&gt;&lt;/p&gt;
&lt;p&gt;还有就是比较有用的是了解下怎么看这些信息。这个网站信息量比较足。&lt;/p&gt;
&lt;p&gt;https://www.investor.gov/&lt;/p&gt;
</content:encoded></item><item><title>git push到多个远程库</title><link>https://dididudu998.github.io/posts/git-push-to-multi-remote/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/git-push-to-multi-remote/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Fri, 09 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;git 一次推送到多个远程库&lt;/h1&gt;
&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;因为既有自己搭建到git服务器，也有网上提供的github和gitlab的私有库可用。&lt;/p&gt;
&lt;p&gt;为了能够一次性的提交，免得麻烦，可以用下面的方式实现。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;p&gt;以下面的为例，已经有了下面的远程库。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;remote.gitlab.url=git@gitlab.com:xxxx/my_kee.git

remote.github.url=git@github.com:yyyy/kees.git

remote.mypc.url=ssh://admin@zzzz:8400/kee.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果不做一次性的提交，那么提交到gitlab就是git push gitlab master，其他的一样的。&lt;/p&gt;
&lt;p&gt;为了可以实现一次性的提交，这么做：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote add all git@gitlab.com:xxxx/my_kee.git

git remote set-url --add --push all git@github.com:yyyy/kees.git

git remote set-url --add --push all ssh://admin@zzzz:8400/kee.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;验证下，git remote -v 就能看到all的这个项目存在。&lt;/p&gt;
&lt;p&gt;下次直接 git push all 就可以一次性的push到上面的三个远程库里面了，减少了麻烦。&lt;/p&gt;
</content:encoded></item><item><title>关于metasploit</title><link>https://dididudu998.github.io/posts/%E5%89%8D%E9%98%B5%E5%AD%90%E5%85%B3%E4%BA%8Emetasploit/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%89%8D%E9%98%B5%E5%AD%90%E5%85%B3%E4%BA%8Emetasploit/</guid><pubDate>Wed, 07 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;安装&lt;/h1&gt;
&lt;p&gt;直接在官网下载针对MacOS的pkg包安装即可。
安装后最好做个alias，这样方便操作。
我用的zsh，所以做了这个alias：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alias msf= &quot;cd /opt/metasploit-framework/bin&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样source ~/.zshrc后， 在窗口输入msf就能到对应目录。&lt;/p&gt;
&lt;h1&gt;使用&lt;/h1&gt;
&lt;p&gt;使用的话，先show -h
会有对应的帮助命令出来。&lt;/p&gt;
&lt;p&gt;-- 使用基本的portscan&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;use auxiliary/scanner/portscan/tcp&lt;/li&gt;
&lt;li&gt;show options&lt;/li&gt;
&lt;li&gt;set RHOSTS www.google.com.hk&lt;/li&gt;
&lt;li&gt;set THREADS 11&lt;/li&gt;
&lt;li&gt;set CONCURRENCY 20&lt;/li&gt;
&lt;li&gt;run
-- 使用证书扫描&lt;/li&gt;
&lt;li&gt;use auxiliary/scanner/http/ssl&lt;/li&gt;
&lt;li&gt;show options
3. set RHOSTS www.microsoft.com
4. run&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;获取详细的payload&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;有时候我想看看这个payload是怎么样子的，可以这么做。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;  ./msfvenom LPORT=4444 --payload windows/shell_bind_tcp --platform windows --arch x86 --encoder x86/shikata_ga
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里是看shell_bind_tcp这个payload在x86平台上面，使用python语言看到的payload信息。&lt;/p&gt;
&lt;p&gt;这里的语言的选项有很多种，这个platform的选项也有多种。都可以看看。&lt;/p&gt;
</content:encoded></item><item><title>AD验证的过程</title><link>https://dididudu998.github.io/posts/ad%E8%AE%A4%E8%AF%81%E8%BF%87%E7%A8%8B/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/ad%E8%AE%A4%E8%AF%81%E8%BF%87%E7%A8%8B/</guid><pubDate>Wed, 31 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AD验证的过程&lt;/h1&gt;
&lt;p&gt;看看忘忘，忘忘看看。&lt;/p&gt;
&lt;p&gt;摘录于&lt;a href=&quot;https://adsecurity.org/?p=1515&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;或者更多的信息看&lt;a href=&quot;https://www.trimarcsecurity.com/research&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;User logs on with username &amp;amp; password.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Password converted to NTLM hash, a timestamp is encrypted with the hash and sent to the KDC as an authenticator in the authentication ticket (TGT) request (AS-REQ).
1b. The Domain Controller (KDC) checks user information (logon restrictions, group membership, etc) &amp;amp; creates Ticket-Granting Ticket (TGT).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The TGT is encrypted, signed, &amp;amp; delivered to the user (AS-REP). Only the Kerberos service (KRBTGT) in the domain can open and read TGT data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The User presents the TGT to the DC when requesting a Ticket Granting Service (TGS) ticket (TGS-REQ). The DC opens the TGT &amp;amp; validates PAC checksum – If the DC can open the ticket &amp;amp; the checksum check out, TGT = valid. The data in the TGT is effectively copied to create the TGS ticket.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The TGS is encrypted using the target service accounts’ NTLM password hash and sent to the user (TGS-REP).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The user connects to the server hosting the service on the appropriate port &amp;amp; presents the TGS (AP-REQ). The service opens the TGS ticket using its NTLM password hash.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If mutual authentication is required by the client (think MS15-011: the Group Policy patch from February that added UNC hardening).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Unless PAC validation is required (rare), the service accepts all data in the TGS ticket with no communication to the DC.&lt;/p&gt;
&lt;p&gt;Active Directory Kerberos Key Points:&lt;/p&gt;
&lt;p&gt;Microsoft uses the NTLM password hash for Kerberos RC4 encryption.
Kerberos policy is only checked when the TGT is created &amp;amp; the TGT is the user authenticator to the DC.
The DC only checks the user account after the TGT is 20 minutes old to verify the account is valid or enabled. TGS PAC Validation only occurs in specific circumstances. When it does, LSASS on the server sends the PAC Validation request to the DC’s netlogon service (using NRPC)
If it runs as a service, PAC validation is optional (disabled). If a service runs as System, it performs server signature verification on the PAC (computer account long-term key).&lt;/p&gt;
&lt;p&gt;Forging Kerberos Tickets:&lt;/p&gt;
&lt;p&gt;Forging Kerberos tickets depends on the password hash available to the attacker
Golden Ticket requires the KRBTGT password hash.
Silver ticket requires the Service Account (either the computer account or user account) password hash.
Create anywhere and user anywhere on the network, without elevated rights.
Spoof access without modifying AD groups.
Once the KRBTGT account password is disclosed, the only way to prevent Golden Tickets is to change the KRBTGT password twice, since the current and previous passwords are kept for this account.&lt;/p&gt;
</content:encoded></item><item><title>ppsspp玩和平行者</title><link>https://dididudu998.github.io/posts/%E6%89%8B%E6%9C%BA%E4%B8%8A%E7%8E%A9%E5%90%88%E9%87%91%E8%A3%85%E5%A4%87%E5%92%8C%E5%B9%B3%E8%A1%8C%E8%80%85/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%89%8B%E6%9C%BA%E4%B8%8A%E7%8E%A9%E5%90%88%E9%87%91%E8%A3%85%E5%A4%87%E5%92%8C%E5%B9%B3%E8%A1%8C%E8%80%85/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 19 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;ppspp玩和平行者&lt;/h1&gt;
&lt;p&gt;小鸡模拟器上下载了和平行者，这个很早之前下载过，但是没有玩通版。后来删除了。
这前天又下载下来了美版的，发现美版的比较容易一些。&lt;/p&gt;
&lt;p&gt;为了体验游戏，就想着作弊。但是小鸡里面的作弊对于psp根本就没用。不知道怎么回事。
对于街机和别的系列的都还挺好的。&lt;/p&gt;
&lt;p&gt;没法，只好上论坛搜索。&lt;/p&gt;
&lt;p&gt;得到下面的信息：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在手机的内部存储上找到psp文件夹，下面有个cheats目录&lt;/li&gt;
&lt;li&gt;在cheats目录下创建cheat.db文件&lt;/li&gt;
&lt;li&gt;Go to PPSSPP App, enable cheats then select ur game. when the game loads,exit the app.&lt;/li&gt;
&lt;li&gt;go to PSP/CHEATS you&apos;ll see a ULUSIOxxx.ini like file there. edit that file then paste the code.&lt;/li&gt;
&lt;li&gt;编辑这个ULUSIOxxx.ini文件，里面写上秘籍。&lt;/li&gt;
&lt;li&gt;比如我玩的合金装备-和平行者的秘籍就是下面的这样的&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;_C0 All AI chip
_L 0x2010F398 0x00002812
_L 0x2010F39C 0xA0A20000

_C0 All Items Developed
_L 0x20049B98 0x00000000
_L 0x20049B9C 0x24020003
_L 0x20049BA0 0xAC820004

_C0 All Weapons Developed
_L 0x200487D4 0x00000000
_L 0x200487D8 0x24020003
_L 0x200487DC 0xAC820004

_C0 All Weapons Level 3
_L 0x20049758 0x24030003
_L 0x2004975C 0xA0830016

_C0 Camoflauge 100%
_L 0x2017E924 0x240203E8

_C0 Clearance time 00:00:00
_L 0x20019158 0xAE000034

_C0 Full Titles
_L 0x20313A48 0x24020017
_L 0x20313A4C 0xA062AD98

_C0 Heroism Stats Max
_L 0x604F5068 0x000F423F
_L 0x00020001 0x00000B30

_C0 Infinite Ammo
_L 0x20101EDC 0xFFFFFFFF

_C0 Infinite HP
_L 0x20110004 0x24050000

_C0 Infinite Items
_L 0x200FE308 0x24130000

_C0 Infinite Stun Rod
_L 0x204F7770 0x00002A10

_C0 Invincible
_L 0x201148B0 0x24050000

_C0 Soliton Radar Always ON
_L 0x20246504 0x1000028A

_C0 2x Faster
_L 0x2017C2A8 0x00C08021
_L 0x2017C2B0 0x4614003C
_L 0x2017C2B4 0x3C034000
_L 0x2017C2B8 0x44836000
_L 0x2017C314 0x46146302

_C0 Max Combat Unit (Max GMP, Max Stats)
_L 0x20030384 0x0A200800
_L 0x20030388 0x3C010001
_L 0x20002000 0x3421869F
_L 0x20002004 0xAC810038
_L 0x20002008 0x2401270F
_L 0x2000200C 0xA4810044
_L 0x20002010 0xA481004C
_L 0x20002014 0x3C0104E2
_L 0x20002018 0x342104E2
_L 0x2000201C 0xA4810052
_L 0x40002020 0x00030001
_L 0xAC810054 0x00000004
_L 0x2000202C 0xA4810060
_L 0x20002030 0x240103E7
_L 0x40002034 0x00040001
_L 0xA4810064 0x00000004
_L 0x20002044 0xA4810082
_L 0x20002048 0xA4800076
_L 0x2000204C 0xA480007A
_L 0x20002050 0xA480007C
_L 0x20002054 0xA4800080
_L 0x20002058 0x0A2120B6
_L 0x2000205C 0x8C840038
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在pps打开游戏，然后返回，开启作弊和导入金手指，就能看到所有的秘籍已经导入了&lt;/li&gt;
&lt;li&gt;选择对应的秘籍，继续游戏，就能看到效果。&lt;/li&gt;
&lt;li&gt;不同的游戏或者同一个游戏不同版本的秘籍可能都不一样，有时候不是都能生效的。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>安全站点</title><link>https://dididudu998.github.io/posts/16-21-%E5%AE%89%E5%85%A8%E7%AB%99%E7%82%B9/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/16-21-%E5%AE%89%E5%85%A8%E7%AB%99%E7%82%B9/</guid><pubDate>Thu, 11 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;安全站点&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;https://paper.seebug.org/&lt;/li&gt;
&lt;li&gt;https://www.praetorian.com/blog/&lt;/li&gt;
&lt;li&gt;https://www.anquanke.com/&lt;/li&gt;
&lt;li&gt;https://medium.com/@sebnemK&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>威廉斯托林-计算机安全原理与实践</title><link>https://dididudu998.github.io/posts/10-03-%E5%A8%81%E5%BB%89%E6%96%AF%E6%89%98%E6%9E%97-%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AE%89%E5%85%A8%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E8%B7%B5/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/10-03-%E5%A8%81%E5%BB%89%E6%96%AF%E6%89%98%E6%9E%97-%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AE%89%E5%85%A8%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E8%B7%B5/</guid><pubDate>Wed, 10 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;威廉斯托林-计算机安全原理与实践&lt;/h1&gt;
&lt;h2&gt;口令&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;先验口令&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;工具： 开源软件pam_passwdqc(openwall.com/passwdqc/)&lt;/li&gt;
&lt;li&gt;在进行口令设置时，执行各种规则，并可以由管理员进行配置&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;口令破解器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当用户在选择一个口令时候，将由破解器进行检查，确保这个口令不在破解器字典内。&lt;/li&gt;
&lt;li&gt;问题是，随着人员的增多和时间，口令字典会变得越来越大，检查时间会越来越长&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bloom过滤器&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;spafford提出的基于Bloom的过滤器，是概率统计的技术。用于生成高效的后验证口令检查。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;令牌&lt;/h2&gt;
&lt;p&gt;用户持有的，用于进行认证的一种物品。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;存储卡： 只存储数据，而不处理数据，用于单独的物理访问&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要读卡器&lt;/li&gt;
&lt;li&gt;会丢失或者被盗窃&lt;/li&gt;
&lt;li&gt;用户的满意度不高&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;智能卡：带有微处理器，可以处理一些数据，有接触式和非接触式的，带有人机接口，按钮或者液晶显示。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有静态协议，或者动态口令生成器，也有的是挑战-应答协议&lt;/li&gt;
&lt;li&gt;智能卡是完整的一套处理器，内存，输入输出部件组成的设备。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;电子身份证&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;德国的新身份证使用的是电子身份证&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;包含个人信息，文档编号，卡片接入号，机器读卡区&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用于epass，为政府部门所用，是离线功能；eid用于商业应用，既可以离线也可以在线；esign，用于生成持卡人的数字签名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;口令认证连接设施，用于确保非经过许可的情况下，任何设备不可以读取RFID这样的信息&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;生物特征&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;面部识别
&lt;ul&gt;
&lt;li&gt;常用的是对人的面部进行照相，然后基于相对位置和关键面部器官建立特征&lt;/li&gt;
&lt;li&gt;还有一种就是使用红外摄像机对人脸内部隐含的血管系统生成面部温谱图&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;指纹
&lt;ul&gt;
&lt;li&gt;被认为是独一无二的&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;手型
&lt;ul&gt;
&lt;li&gt;手掌的特征，包括形状，大小，长度，宽度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;视网膜：这个使用的比较少了&lt;/li&gt;
&lt;li&gt;虹膜： 开始应用的比较广泛&lt;/li&gt;
&lt;li&gt;签名： 银行会需要用，但是签名的比对非常复杂，因为一个人在不同的时间签名的样本也会发生很大的变化。&lt;/li&gt;
&lt;li&gt;语音：这个很多app已经在使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;远程用户认证&lt;/h2&gt;
&lt;p&gt;本地认证是最简单的。复杂一些的是通过网络或者其他通讯线路进行认证。
远程认证的方式由于跨了设备和路线，所以相对存在较多的安全隐患。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用口令协议
远程服务器存储的是口令的散列。
过程如下：&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;用户先发送自己的身份给远程主机&lt;/li&gt;
&lt;li&gt;远程主机生成一个随机数r，通常称为nonce值，并返回这个值给用户&lt;/li&gt;
&lt;li&gt;远程主机需要指定两个函数h和f，在响应过程中使用&lt;/li&gt;
&lt;li&gt;从远程主机到用户的数据传输称为质询。用户响应的是函数f(r,h(p))=r的值。其中p是用户的口令。函数h是一个散列函数。&lt;/li&gt;
&lt;li&gt;远程主机存储了每一个注册用户的口令的散列。对于用户u使用h(p(u))表示。
当收到用户应答时候，远程主机计算函数f(r,h(p(u)))的值和收到的f(r,h(p))的值进行比较。如果相等，那么用户就被许可。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用令牌协议&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用静态生物特征认证&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用动态生物特征认证&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;远程主机提供一个随机序列x和一个随机数r作为质询。这个质询序列是由数字，字符或者单词组成的序列。
用户必须通过发音，打字或者手写来产证一个生物特征序列信号bs(x).之后，客户端对生物信号和随机数加密。
远程主机收到信息后进行解密，收到的随机数必须和最初作为质询的随机数r完全匹配才可以。
并且，远程主机根据输入的生物特征信号bs(x),已经存储的用户模版bt(u)以及原始信号x生成一个比较值，如果改比较值超过了预设的阈值，那么就可以通过验证。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;潜在的安全问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;客户端攻击&lt;/li&gt;
&lt;li&gt;主机攻击&lt;/li&gt;
&lt;li&gt;窃听，盗窃和复制口令，令牌和生物特征&lt;/li&gt;
&lt;li&gt;重放&lt;/li&gt;
&lt;li&gt;特洛伊木马&lt;/li&gt;
&lt;li&gt;拒绝服务&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;实际应用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;阿联酋入境处使用虹膜生物特征认证系统。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;特点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;海量人群识别&lt;/li&gt;
&lt;li&gt;依赖于长期不变的生物特征&lt;/li&gt;
&lt;li&gt;该生物特征容易提取&lt;/li&gt;
&lt;li&gt;方便使用&lt;/li&gt;
&lt;li&gt;可以实时响应&lt;/li&gt;
&lt;li&gt;安全无伤害&lt;/li&gt;
&lt;li&gt;能够在超大范围内进行区分并且性能很好&lt;/li&gt;
&lt;li&gt;价格上面负担的起&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实现&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;阿联酋入境处&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;阿联酋17个入境处均设有虹膜扫描仪&lt;/li&gt;
&lt;li&gt;虹膜扫描仪会在距离眼球5-24英寸的地方拍摄黑白照片&lt;/li&gt;
&lt;li&gt;使用近红外照明技术，不可见并且绝对安全&lt;/li&gt;
&lt;li&gt;首先确定虹膜的内外边界以及眼睑的轮廓&lt;/li&gt;
&lt;li&gt;将虹膜的纹理转化为数字编码&lt;/li&gt;
&lt;li&gt;将编码与存在数据库中的编码进行匹配判断&lt;/li&gt;
&lt;li&gt;利用分布式网络，所有入境乘客的虹膜编码都可以实时的与中央数据库进行比对&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;漏洞：依然有被禁止入境的人，使用滴眼液扩张虹膜，而导致虹膜识别不了，进入阿联酋的案例。因此算法还需要对虹膜的状态进行判断，是常态还是扩张后的。&lt;/p&gt;
&lt;h3&gt;ATM系统安全&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;禁止明文传输&lt;/li&gt;
&lt;li&gt;分离网络&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;访问控制&lt;/h2&gt;
&lt;p&gt;概念：对于每个具体的系统资源，谁或者什么（比如应用进程）可以访问，以及每个实例允许的访问类型。&lt;/p&gt;
&lt;p&gt;包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;认证：验证用户或者其他系统实体声称的身份是有效的&lt;/li&gt;
&lt;li&gt;授权：授予系统实体访问系统的权限和许可。确定谁对于给定的目的是可信的&lt;/li&gt;
&lt;li&gt;审计：对系统记录和活动进行独立评审和检查，确保系统控制措施的充分性，既定策略和操作规程，安全违规，并推荐控制措施，策略等的优化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;访问控制策略&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;自主访问控制：基于请求者的身份和访问规则控制访问，规定请求者可以或者不可以做什么&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;强制访问控制：通过比较具有安全许可的安全标记来控制访问&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;基于角色的访问：通过用户在系统中所具有的角色来控制访问&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;基于属性控制：基于用户，被访问资源以及当前环境条件来控制访问&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实例&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UNIX文件访问控制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;unix的文件都由操作系统通过inode管理。inode是index node的缩写。是操作系统对一个文件所需的关键信息的控制结构。几个文件名可以与一个inode关联
但是一个活动inode仅和一个文件关联，一个文件也仅被一个inode控制。文件的属性以及访问许可和其他
的控制信息都存储在inode中。在磁盘上有一个inode表，包含了文件系统中所有文件的inode。打开这个文件时，
它的inode被读进内存。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ICAM是一种用来管理和实现数字身份以及相关属性，凭证，和访问控制的综合性方法。
ICAM由美国政府开发，但是并不仅适用于政府机构，还可以由寻求访问控制统一方法的企业来部署。&lt;/p&gt;
&lt;h2&gt;数据库&lt;/h2&gt;
&lt;p&gt;这里主要讲关系型数据库。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注入攻击&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;利用数据库应用（一般是查询）中存在的安全漏洞而发起的攻击。攻击者可以提取或者操纵web应用的数据。
用户的输入被当作嵌入在sql语句中的字符串转义符而被错误的过滤或者执行。&lt;/p&gt;
&lt;p&gt;-- 实现过程&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;攻击者找到web应用的弱点，然后通过向web服务器发送命令来对数据库注入sql命令。这些命令会被传送到防火墙&lt;/li&gt;
&lt;li&gt;web服务器接收到恶意代码，然后发送给web应用服务器&lt;/li&gt;
&lt;li&gt;web应用服务器将代码发送给数据库服务器&lt;/li&gt;
&lt;li&gt;数据库服务器在数据库上执行恶意代码，数据库从对应的表中返回数据&lt;/li&gt;
&lt;li&gt;web应用服务器动态的生成包含有数据的页面&lt;/li&gt;
&lt;li&gt;web服务器向攻击者提供页面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;-- 简单举例&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;参看下面的查询语句&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;var city;
city=request.from(&quot;city&quot;)
var sql=&quot;select * from ordertable where city=&apos;&quot;+city+&quot;&apos;&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个代码的意思是说从用户输入的城市中筛选出所有的订单。&lt;/p&gt;
&lt;p&gt;但是如果用户输入的城市名变成这个 beijing‘;drop table ordertable--&lt;/p&gt;
&lt;p&gt;那么查询语句就变成这样了： select * from ordertable where city =&apos;beijing&apos;;drop table ordertable--&lt;/p&gt;
&lt;p&gt;这时候的操作就变成查询北京这个城市的订单，然后删除这个订单表。&lt;/p&gt;
&lt;h3&gt;sql注入的攻击途径和类型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;用户输入：采用这一个方式的攻击者，通过精心构造用户输入来注入SQL命令。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;服务器变量：包含http头部，网络协议头部，环境变量等数据的变量集合。如果这些变量不经过处理就直接记录在数据库中，则可能会产生sql注入漏洞。因为当攻击者能够构造http和网络报头来利用这些漏洞，将数据直接安排在报头中，挡在税局哭中执行对服务器变量的查询语句时，报头中的攻击语句将会被触发。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;二阶注入：在二阶注入中，恶意用户可以利用系统或数据库中已存在的数据来触发一个sql注入攻击，因此当这种攻击出现时候，引发攻击的输入不是来自用户，而是来自系统本身。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;cookie：当用户再次访问之前已访问过的web应用程序时候，cookie被用于存储用户的状态信息。由于cookie数据是在客户端控制的，在应用服务器利用cookie构造sql查询时，攻击者可以通过更改cookie的值来实现sql查询语句的构造和进行查询功能的修改。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;物理用户输入：除了web页面请求，还有其他可以被用于sql注入的用户请求。常见的包括条形码，射频识别标签，甚至是能够利用图像识别技术扫描然后发送到数据库系统的纸质形式。
这种攻击方式大体上包含，带内，带外，和推理三种方式。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;带内攻击是使用同样的通信信道来完成注入sql代码和返回。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;比如，将代码注入一个或者多个永真的表达式中。&lt;/p&gt;
&lt;p&gt;$query=&quot;select info from user where name=&apos;$_get[&quot;name&quot;]&apos; and pwd=&apos;$_get[&quot;pwd&quot;]&apos;&quot;;&lt;/p&gt;
&lt;p&gt;假如攻击者提交 “‘or 1=1 --&apos;&quot;作为名字字段，那么查询语句就变成这样：&lt;/p&gt;
&lt;p&gt;select info from user where name=&apos; &apos; or 1=1 -- and pwd = &apos; &apos;&lt;/p&gt;
&lt;p&gt;这样就导致口令检查失效，因为--会导致后面的查询变成不可执行的注释。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;推理攻击： 没有实际的数据传输。但攻击者能够通过发送特定的请求和观察网站的数据库服务器的响应规律来重新构造信息。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;非法/逻辑错误查询&lt;/li&gt;
&lt;li&gt;盲sql注入：攻击者推测数据库系统的数据，利用错误页面的信息等获得结构&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;带外攻击： 返回数据使用不同的通信频道。比如一个带有查询结果的email生成和返回是在不同的信道进的。这一方式用于信息检索有限制但数据库服务器带外连接不严格的情况。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;sql注入的应对措施&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;手动防御性编码： 如果是数值型的输入，应该检查是否只包含数字。一般采用模式匹配进行区分&lt;/li&gt;
&lt;li&gt;参数化查询：指定sql查询结构，分离传递值参数&lt;/li&gt;
&lt;li&gt;sql dom：它将查询建立过程由使用字符串拼接的不规范过程变成为具有类型检查api的语义构建过程。&lt;/li&gt;
&lt;li&gt;基于特征的攻击&lt;/li&gt;
&lt;li&gt;基于异常的攻击&lt;/li&gt;
&lt;li&gt;代码分析&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;云安全&lt;/h2&gt;
&lt;h2&gt;恶意软件&lt;/h2&gt;
&lt;p&gt;定义： 被秘密的植入系统中，以损害受害者数据，应用程序或者操作系统的可信性，完整性或者可用性，抑或对用户实施骚扰或妨碍的程序。&lt;/p&gt;
&lt;p&gt;传染的机制包括：病毒，蠕虫和木马。&lt;/p&gt;
&lt;p&gt;有效负载包括：系统损坏，僵尸网络，网络钓鱼，间谍软件rootkit等&lt;/p&gt;
&lt;p&gt;类型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;APT：商业性或者政治性的目标，使用多种入侵技术和恶意软件并在长期持续有效的攻击目标&lt;/li&gt;
&lt;li&gt;广告软件&lt;/li&gt;
&lt;li&gt;攻击工具包&lt;/li&gt;
&lt;li&gt;auto-rooter：用于远程入侵到新的机器上的恶意攻击工具&lt;/li&gt;
&lt;li&gt;后门：能够绕过正常安全检查的机制，并允许未经授权的访问&lt;/li&gt;
&lt;li&gt;下载器：在被攻击的机器上面安装其他的内容的程序&lt;/li&gt;
&lt;li&gt;夹带式下载：利用被俘虏的网站，当该网站被访问时候，被植入的恶意代码可以利用浏览器漏洞攻击访问者的系统&lt;/li&gt;
&lt;li&gt;漏洞攻击：针对某个漏洞进行攻击的代码&lt;/li&gt;
&lt;li&gt;泛洪式攻击： 通过联网的计算机发起大量的数据包，实现拒绝服务攻击的程序&lt;/li&gt;
&lt;li&gt;键盘记录器： 捕获侵入系统的键盘输入&lt;/li&gt;
&lt;li&gt;逻辑炸弹： 潜伏在正常的软件程序中。当满足预定义的某些条件时候，逻辑炸弹触发，执行恶意操作&lt;/li&gt;
&lt;li&gt;宏病毒： 使用宏或者脚本语言写的病毒，通常植入到文档中，当浏览或编辑文档时候被触发，复制自身到其他的文档&lt;/li&gt;
&lt;li&gt;移动代码：能够不加修改的移植到不同类型的系统平台并执行&lt;/li&gt;
&lt;li&gt;rootkit：攻击者成功入侵计算机并获得root访问权限&lt;/li&gt;
&lt;li&gt;垃圾邮件&lt;/li&gt;
&lt;li&gt;间谍软件：通过监听键盘输入，显示器数据，网络流量或搜素系统文件获取敏感资源信息，并传送到其他的设备的软件&lt;/li&gt;
&lt;li&gt;木马：看上去有作用，但是还具备其他隐藏的潜在的恶意功能，并且用来避开安全机制&lt;/li&gt;
&lt;li&gt;病毒&lt;/li&gt;
&lt;li&gt;蠕虫：能够独立执行，并且可以将自己完整的复制到其他网络主机的程序&lt;/li&gt;
&lt;li&gt;僵尸： 在被感染的计算机中运行，激活后向其他的计算机发送攻击的程序&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;点击劫持：就是在一个按钮或者输入框上面或者下面蒙一层新的透明不可见的按钮或者输入框，当用户输入或者点击按钮的时候，触发隐藏的操作。&lt;/p&gt;
&lt;p&gt;bot: 最开始使用的是irc，所有受控机器加入一个irc频道，控制机在频道内进行指令发送给受控机。后来专用http协议实现隐蔽通道，避免单一控制节点的问题，再后来使用p2p的方式，也是避免控制节点单一失效的问题。&lt;/p&gt;
&lt;p&gt;由于固定ip地址很容易被找到和进行封锁。所以现在的恶意软件使用这样的技术：自动生成大量的服务器域名并令恶意软件尝试与所有的这些域名进行连接。即使其中一个服务器名称被破坏，攻击者依然可以用某个域名来重新建立服务器，获得控制。这样要想解决问题，需要技术人员逆向工程以分析其域名生成的算法，然后对所有（大量）的域名进行封锁，这个是很消耗时间和精力的。&lt;/p&gt;
&lt;p&gt;还有一种隐藏服务器的技术是使用快速变迁域名(fast-flux dns)技术。它使得与给定服务器域名相关联的ip地址频繁的变动（每隔几分钟），并在大量的服务器代理中轮转，而这些代理往往是僵尸网络的其他成员。这么做会阻止执法机构有效的对他们的威胁采取措施。&lt;/p&gt;
&lt;p&gt;键盘记录器，由于大量的使用https和TLS的方式进行数据的传输，所以黑客使用键盘记录器来降低这个收集信息的难度，这里利用软件工具包制作的Zeus网银木马是其中最有名的代表。&lt;/p&gt;
&lt;p&gt;rootkitrevealer, 这个工具是mark大神在sysinternal工具包里面包含的一个用于检测rootkit的工具，面向windows，它将使用api的系统扫描结果与不实用api的指令所获得的实际存储视图进行对比。因为rootkit通过修改系统管理员调用所能看到的视图来隐藏自己，而rootkitrevealer刚好利用这个差异来进行判断。&lt;/p&gt;
&lt;p&gt;如果检查出一个系统级别的rootkit，那么唯一可靠的方式就是彻底的重新安装新的操作系统。&lt;/p&gt;
&lt;h3&gt;边界管理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;入口扫描&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所有进入企业的流量都需要进行防火墙或入侵检测的探查。这样在入口的时候就屏蔽掉一些入侵和恶意的行为。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;出口扫描&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以部署在企业内部网络中的各个独立的局域网出口点上，也可以安装在内外网之间。&lt;/p&gt;
&lt;h2&gt;拒绝服务攻击&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;源地址欺骗&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大部分的DoS攻击中，所使用数据包的一个共同的特征是所采用伪造的源地址。这个比较容易使用许多操作系统上的原始套接字接口来实现。&lt;/p&gt;
&lt;p&gt;操作系统设计者是为了进行某些自定义的网络测试或网络协议的研究而引入原始套接字接口的，并不是用于正常的网络操作。但是由于兼容性和继承性的问题，在如今的操作系统中依然保留原始套接字接口。攻击者可以利用这个标准接口很容易的制造具有伪造属性的数据包。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SYN欺骗&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过造成服务器上用于管理TCP连接的连接表的溢出，从而攻击网络服务器响应TCP连接请求的能力。这意味着即使合法的用户TCP的请求也得不到服务器的响应。&lt;/p&gt;
&lt;p&gt;SYN欺骗是针对系统资源的DoS攻击，就是针对操作系统上网络处理程序的攻击。
大量的伪造源地址的主机向服务器申请TCP握手，正常的话，服务器会响应SYN-ACK包到正常的源地址。通讯完成后，源主机会发送RST信号给服务器，关闭连接。但是伪造的主机没有这样的源地址，也就不会有RST信号发出，服务器就会将这个信息保存在连接表中，而连接表的大小是有限度的，这个表一旦被填满，那么后来来的请求就不会得到服务器的响应。正常情况下，超时的TCP连接请求会立即被清理出TCP连接表，但是攻击者是不断的发送足量的欺骗TCP连接给服务器的，也就是这个TCP连接表会一直被填满，从而无法响应大多数合法的连接请求。&lt;/p&gt;
&lt;p&gt;SYN泛洪攻击与SYN欺骗攻击的方式类似，只是泛洪攻击的是数据包的总量，像洪水一样冲垮对方，而SYN欺骗则是用小部分的数据包消耗目标系统上的网络处理程序。&lt;/p&gt;
&lt;p&gt;泛洪攻击既使用UDP也可以使用TCP，虽然TCP会很容易被目标服务器拒绝，但是攻击者已经成功的消耗了服务器的网络链路。&lt;/p&gt;
&lt;p&gt;一些抵御SYN欺骗的方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对于TCP连接，把请求连接的关键信息加密编码存放于cookie中，然后将这个cookie作为服务器的初始序号封装在syn-ack响应包中发送给客户端。当合法用户返回ack应答包时候，要求在ack的应答包中包含序号+1的cookie，然后服务器根据这个cookie来重构那些曾经在tcp连接表中存储的相关信息。&lt;/li&gt;
&lt;li&gt;这个技术一般用于防止TCP连接表溢出。&lt;/li&gt;
&lt;li&gt;缺点是服务器要消耗一定的计算资源来计算cookie。还有就是限制了一些tcp的扩展功能。比如large window。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个技术最著名的方法的实现者是： SYN cookie。发明者是Daniel Bernstein。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;修改TCP/IP网络处理程序中所使用的参数。包括连接表的大小，当未收到响应时删除表项目的超时时间。虽然这样增加了攻击的难度，但是并不能从根本上预防攻击。&lt;/li&gt;
&lt;li&gt;最好的措施是屏蔽IP定向广播的使用。&lt;/li&gt;
&lt;li&gt;还有就是判断连接来自人还是机器，增加captcha这样的限制&lt;/li&gt;
&lt;li&gt;增加站点的镜像在多个不同的地方，也能增加稳定性和容错能力。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;多机系统的间接攻击：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;分布式拒绝服务攻击&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;分层的控制体系： 攻击者将攻击指令下发给执行者僵尸机器，执行者僵尸机器联系它所能管控的代理僵尸机器，代理僵尸机器根据执行者发过来的指令对目标机器进行攻击。这里的指令和通讯很大程度上都是加密的。而且从目标机器上反向查找攻击者变得极其困难。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;反射攻击&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;举个例子，我要攻击的对象是a,我做一些带有a的源地址的数据包给某些网络服务器，网络服务器会响应这些数据包，会将响应的数据包发给a的源地址。当攻击者发送的数量足够大，那么响应包的数据将占满目标系统的网络链路。这些网络服务器成了DDoS攻击的中间媒介，而且他们做的都是正常的反应。这也使得攻击者可以更容易的发起攻击和躲避跟踪。&lt;/p&gt;
&lt;p&gt;实现的方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;发起一个小的请求，产生较大的响应数据包的服务。通常UDP服务可以实现这样的目的。比如dns，snmp，isakmp，chargen等&lt;/li&gt;
&lt;li&gt;中间媒介有较高的网络服务器性能和较好的链接速度。&lt;/li&gt;
&lt;li&gt;还有就是可以使用tcp sync进行握手攻击。攻击者发送带有虚假源地址的syn数据包给中间媒介，中间媒介会响应一个syn-ack包给这个源地址的主机，而这个主机是真实存在的目标系统。大量的syn-ack包就能产生泛洪的效果。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;改进型的，但容易被切断的攻击方式：&lt;/p&gt;
&lt;p&gt;一般dns客户端会通过自身的一个端口利用udp协议向dns服务器的53端口发送域名解析请求。
但是攻击者会利用一个虚假的源地址A向dns发送域名解析请求，攻击者使用端口7，这个端口是echo应答协议的端口。dns服务器稍后会向该攻击的受害者A的端口7发送一个响应。如果受害者的机器提供应答服务，它就可能创建一个网络包将收到的数据返回给DNS服务器。如果DNS服务器响应了A的这个包，那么在A和DNS服务器之间就会产生循环。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;放大攻击&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;标准的dns协议，一个60字节的udp请求包会生成一个512字节的udp响应包。而ipv6以及其他扩展dns特性，则可以让这个响应包超过4000字节。&lt;/li&gt;
&lt;li&gt;攻击者构造使用源地址为攻击目标的dns请求包，然后发送给网络上大量的域名服务器，这些域名服务器就会将响应包发送给攻击目标。看起来都是合法的，但是就是这样被利用了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;国际组织希望安装过滤器在路由器或者网关旁边，以用于过滤伪造的源地址，但是ISP以这样会消耗路由器的性能为说法，不支持这样的提议。从而大量的家庭客户端的电脑被用于制造虚假的源地址。&lt;/p&gt;
&lt;h3&gt;基于应用的攻击&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SIP泛洪&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IP电话使用的是SIP协议，语法和http类似。有请求和响应两种形式。它的实现方式是这样的：&lt;/p&gt;
&lt;p&gt;A的客户端首先向自己所在的代理服务器发起invite请求，目标是B。此时A的代理服务器会经过DNS查询B的代理服务器的地址，然后A的代理服务器会将invite请求发给B的代理服务器，B的代理服务器在接受到这个请求后，将消息转发给B的客户端。B的客户端就会响铃了。&lt;/p&gt;
&lt;p&gt;攻击者利用伪造的IP地址向一个SIP代理发送大量的invite请求，或者使用僵尸网络生成大量的invite请求，就会造成DoS攻击。这种攻击第一可以让服务器的资源被无效的invite消耗，第二可以让服务器的网络容量被占用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基于HTTP的攻击&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比如当大量的http请求来自不同的bots，就可以消耗相当大的资源。
比如从目标服务器下载大文件的请求会导致web服务器从硬盘中读取文件，然后将文件存在内存中，再将其转化为网络包流，再进行传输，这个过程消耗内存，cpu，网络资源。&lt;/p&gt;
&lt;p&gt;这种攻击的变种称为递归http泛洪。bots从给定的http链接触发，通过递归的方式遍历给定的web服务器的所有的链接。也就是爬虫。&lt;/p&gt;
&lt;p&gt;Slowloris攻击，利用多线程支持多个到同一个服务器应用程序的请求进行攻击。它不断的发送不完整的http请求，试图独占服务器所有可用的请求处理线程。
Slowloris 背后的关键是它能够以很少带宽消耗引起很大麻烦。&lt;/p&gt;
&lt;p&gt;这是使用了HTTP协议规范（RFC2616）：一个空白行必须用来说明请求报头的末尾或者载荷的开始，如果有的话。一旦接收到完整的请求，web服务器便会响应。但是slowloris不发送这个信号给web服务器。&lt;/p&gt;
&lt;p&gt;Slowloris 攻击分为 4 个步骤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;攻击者首先通过发送多个部分 HTTP 请求标头来打开与目标服务器的多个连接。&lt;/li&gt;
&lt;li&gt;目标为每个传入请求打开一个线程，目的是在连接完成后关闭该线程。为提高效率，如果连接花费时间太长，服务器将使非常长的连接超时，从而为下一请求释放线程。&lt;/li&gt;
&lt;li&gt;为了防止目标使连接超时，攻击者会定期向目标发送部分请求标头，以使请求保持活动状态。本质上说：“我还在这里！我很慢，请等我。”&lt;/li&gt;
&lt;li&gt;目标服务器在等待请求终止时永远无法释放任何打开的部分连接。一旦所有可用线程都被使用，服务器将无法响应来自常规流量的其他请求，从而导致拒绝服务。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;减轻slowloris攻击的方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加服务器在任何时间允许的最大客户端数量&lt;/li&gt;
&lt;li&gt;限制传入请求的速率，限制单个ip允许建立的最大连接数，限制慢速传输速度以及限制客户端允许保持连接的最长时间&lt;/li&gt;
&lt;li&gt;使用反向负载均衡代理服务，保护源站服务器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;负载均衡会对http请求报头做完整性检查，除非http客户端发送报头的最后两个回车和换行，否则该请求是不会被送至web服务器的。要说明的是，企业级的入侵检测和入侵防护系统，对与slowloris没有什么效果，因为它走的是合法的http流量。&lt;/p&gt;
&lt;h2&gt;入侵检测&lt;/h2&gt;
&lt;p&gt;一种监控并分析系统事件的安全服务，目标是发现未经授权而访问系统资源的尝试活动，并提供实时或者近似实时的报警。&lt;/p&gt;
&lt;p&gt;包括三个组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;传感器：收集数据，包括网络数据包，日志文件和系统调用记录。收集后转发给分析器&lt;/li&gt;
&lt;li&gt;分析器：从接受的数据中进行分析，确定是否发生了入侵。如果发生入侵，则输出入侵的证据信息。分析器可以提供指导，用于判断什么活动是入侵导致的。&lt;/li&gt;
&lt;li&gt;用户接口：用户可以通过这个来查看系统输出以及控制系统的行为。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IDS可以分为下面几类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基于主机的IDS： 检测一台主机的特征和该主机发生的或参与的可疑活动的事件。例如进程识别器，系统调用等&lt;/li&gt;
&lt;li&gt;基于网络的IDS：监测特定网段或者设备的流量，传输和应用协议等进行分析。&lt;/li&gt;
&lt;li&gt;分开或混合式IDS：将主机和网路的传感器收集的信息相结合，汇总到中央分析器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;身份验证，访问控制和防火墙在阻断入侵方面都有一定的作用。但是入侵检测有下面的表现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;能够不间断的运行，较少需要人的参与&lt;/li&gt;
&lt;li&gt;具有容错功能，系统崩溃时，必须能够较快的恢复和重新初始化&lt;/li&gt;
&lt;li&gt;抵御破坏。IDS必须能够检测自身，检测是否自己被攻击者修改&lt;/li&gt;
&lt;li&gt;对于正运行的系统增加较小的开销&lt;/li&gt;
&lt;li&gt;能够根据被检测系统的安全策略进行配置&lt;/li&gt;
&lt;li&gt;能过自动适应系统和用户变化&lt;/li&gt;
&lt;li&gt;能够扩展用于监控更多的主机&lt;/li&gt;
&lt;li&gt;能够提供降级服务，如果某些组件失效，其余部分将最少受到影响&lt;/li&gt;
&lt;li&gt;允许动态配置，不需要变更后重启&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;NIDS检测网络上流向潜在的易受攻击的计算机系统的数据包流量。而HIDS是基于主机的，检测主机上用户和软件的活动。&lt;/p&gt;
&lt;p&gt;NIDS通常是企业外围安全防御架构的一部分。通常通过监控流量模式和数据包的内容来检测入侵企图。但是随着加密技术的使用，NIDS已经无法看到数据包内部的有效内容了。这也妨碍了它的作用的发挥。&lt;/p&gt;
&lt;h3&gt;蜜罐&lt;/h3&gt;
&lt;p&gt;入侵检测技术中一个特别的组件，是用来引诱潜在的攻击者远离关键系统而设计的。作用包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;转移攻击者的目标&lt;/li&gt;
&lt;li&gt;收集有关攻击者活动的信息&lt;/li&gt;
&lt;li&gt;引诱攻击者在系统中逗留足够长的时间，以便管理员对攻击做出反应&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;防火墙&lt;/h3&gt;
&lt;p&gt;针对包过滤防火墙的攻击方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IP地址欺骗： 入侵者从外部向内部发送数据包，使用的源地址包含内部主机地址。应对措施是，丢弃那些到达外部接口而源地址为标记内部主机地址的包。&lt;/li&gt;
&lt;li&gt;源路由攻击：源端指定包通过internet使用的路由，希望可以绕过对源路由信息的安全检查。&lt;/li&gt;
&lt;li&gt;细小分段攻击：入侵者利用IP分段来产生特别小的数据分段，并强制将TCP头信息装入分散的分段中。这种攻击主要是为了绕过基于TCP头信息的过滤规则。应对措施：包的第一个分段必须包含最少的预定传输头。如果第一个分段被否决，那么过滤器将记住这个包，并丢弃后继的所有分段。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;状态检测防火墙：&lt;/p&gt;
&lt;p&gt;状态检测防火墙通过建立一个出战TCP连接目录来强制执行TCP流量规则。只有当数据包符合这个目录中的某项时，才允许通过。状态检测和包检测检查相同的包信息，但是不同的是状态检测防火墙还会记录TCP连接信息。一些状态检测防火墙还跟踪TCP包的序号，以阻止基于序号的攻击。比如会话劫持。&lt;/p&gt;
&lt;p&gt;应用级网关（也叫应用代理）：用于应用级流量中继。&lt;/p&gt;
&lt;p&gt;用户使用tcp/ip应用程序连接网关，网关要求用户提供要访问的远程主机名。当用户提供了有效的身份验证后，网关会联系远程主机并在远程主机和用户计算机间中继包含应用程序数据的tcp分段。网关可以被设置为只支持某种应用程序的中继。&lt;/p&gt;
&lt;h4&gt;VPN&lt;/h4&gt;
&lt;p&gt;IPSec VPN是建立在客户端与防火墙之间的一种虚拟网络。
因为IPSec包，除了IP头和载荷数据外，还需要有IPSec头，如果放在网络内部，防火墙无法识别加密流量，也就失去了保护的意义。&lt;/p&gt;
&lt;p&gt;分布式防火墙：&lt;/p&gt;
&lt;p&gt;外部数据包经过边界路由器后，进入外部防火墙，这里有外部DMZ区。穿过外部防火墙后，进入内部DMZ，再往下有内部防火墙，保护内部的网络，然后各个内部的主机上面还有主机级别的防火墙。&lt;/p&gt;
&lt;p&gt;IPS：&lt;/p&gt;
&lt;p&gt;基于主机的IPS，用于避免对系统资源的修改，避免提权攻击和缓冲区溢出攻击，以及访问电子邮件通讯录，以及文件目录遍历。&lt;/p&gt;
&lt;p&gt;IBM数字免疫系统&lt;/p&gt;
&lt;p&gt;一体化的威胁管理产品，UTM。主要的问题是吞吐量和延迟的，现在商业设备普遍的吞吐量损失是50%，客户被建议使用高性能，大吞吐量的设备以避免性能问题。&lt;/p&gt;
&lt;h2&gt;软件安全与可信系统&lt;/h2&gt;
&lt;h3&gt;缓冲区溢出&lt;/h3&gt;
&lt;p&gt;大量的输入被放置到缓冲区或者数据存储区，超过了它所分配的存储能力，覆盖了其他的信息。攻击者利用这样的情况破坏系统或者插入特别编制的代码，以获取系统的控制权。&lt;/p&gt;
&lt;p&gt;这是编程错误的结果导致的。发生缓冲区溢出后，会导致程序使用的数据受到破坏，在程序中发生意外的控制权转移，可能的内存非法访问，以及很可能导致程序终止。&lt;/p&gt;
&lt;p&gt;当缓冲区溢出被用于攻击系统时，系统的控制权会被转移到攻击者的代码中，此时攻击者可以执行任意的代码在系统中。&lt;/p&gt;
&lt;p&gt;缓冲区溢出非常常见，越是靠近底层的语言，比如C，越要靠开发者的技能和细心来避免出现漏洞的语句。建议在可能的情况下，使用高级语言进行开发，减少考虑底层内存和指针的问题。
但是为了提高效率，比如硬件驱动的开发，C语言是不可避免使用的。&lt;/p&gt;
&lt;p&gt;linux系统由于有大量的迭代操作，C语言沉积下来的会有比较多的缓冲区溢出攻击面，后来人们使用OpenBSD这样的系统，在操作系统层面进行了加固。&lt;/p&gt;
&lt;h3&gt;防御，针对栈stack溢出&lt;/h3&gt;
&lt;p&gt;目前有2中防御方法，一种就是在程序运行时候，首先程序会申请地址，我们在对变量分配地址空间之前，在旧的桢指针下写入一个不可预知的值。当程序运行结束前，我们检查这个值是否有变化。如果有变化，我们就让这个程序异常终止。如果没有变化，我们就正常退出。
问题是，这样的程序需要用带有扩展的gcc编译器重新编译才有效果。&lt;/p&gt;
&lt;p&gt;还有一种就是在函数的入口处，将返回地址的一个副本写到内存的某个安全区。在函数的出口处，我们检查帧里的返回地址与保存的副本，如果两者有差异，那就终止程序。&lt;/p&gt;
&lt;p&gt;以上的两种防御都需要重新编译。人们开始想办法当程序运行时进行监控，也就是运行时防御。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可执行地址空间保护：在stack区禁止代码执行。可执行代码仅能在进程的地址空间找到。&lt;/li&gt;
&lt;li&gt;地址空间随机化：这样攻击者无法预测目标缓冲区的大致位置。这样即使他们的代码有问题，程序也会由于引用无效的内存而导致终止，不会产生破坏。当前提供的内存地址动态分配就是这样的防御措施。攻击者又开始转向对程序的标准库进行攻击，这个时候有一些安全扩展，随机的选择程序装载标准库的顺序，然后随机它的虚拟内存地址位置，也可以避免攻击。&lt;/li&gt;
&lt;li&gt;guard页：因为一个进程的有效虚拟内存比它通常需要的多很多。地址空间的每一个部分所使用的一系列地址之间都设置了gap。这些gap叫做guard页。它被当作非法地址进行标记。任何企图对其进行访问的进程都会导致终止。这对于全局数据溢出攻击，有效。因为它企图改写进程的地址空间的相邻区域。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;heap堆溢出&lt;/h2&gt;
&lt;p&gt;堆一般设置在程序代码和全局数据之上。堆溢出的可能目标是从堆中动态分配的内存缓冲区。使用动态数据结果的程序是从堆中请求内存的。例如记录的链表。&lt;/p&gt;
&lt;p&gt;与栈不一样，堆空间中没有容易引起控制权转移的返回地址。但是如果分配的空间包含一个指向函数的指针，而这个函数代码随后就要被调用，攻击者能够安排改变这个地址指向被改写的缓冲区的shellcode。&lt;/p&gt;
&lt;p&gt;通常，处理输入/输出或者解码一个压缩图像/视频文件时候，程序使用记录列表保存大块数据。这样的攻击就可能发生。&lt;/p&gt;
&lt;p&gt;防御堆溢出的方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使堆区的代码成为不可执行的。&lt;/li&gt;
&lt;li&gt;堆区内存分配采取随机选择，这样堆目标缓冲区地址的预测变得极其困难&lt;/li&gt;
&lt;li&gt;内存的分配和回收函数包含了堆管理数据是否是到破坏的检查，可以帮助检测和终止使一个已分配的内存发生溢出的任何企图&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;全局数据区溢出&lt;/h2&gt;
&lt;p&gt;全局数据从程序文件中被装载，并设置在程序代码区之上。如果使用不安全的缓冲区操作，数据可以溢出到一个全局数据的缓冲区，并改变相邻的内存地址，包括可能随后要调用的函数的指针。&lt;/p&gt;
&lt;p&gt;防御的方法：使全局数据区成为不可执行的。将函数指针设置在其他类型数据之下，以及在全局数据区和任何其他管理区之间使用guard页。&lt;/p&gt;
&lt;h1&gt;软件安全&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;软件安全和防御性程序设计
&lt;ul&gt;
&lt;li&gt;很多计算机安全漏洞都是由于不良的编程习惯造成的
&lt;ol&gt;
&lt;li&gt;组件之间的不安全交互&lt;/li&gt;
&lt;li&gt;高风险的资源管理&lt;/li&gt;
&lt;li&gt;脆弱的防御&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;在web安全方面有5个与代码安全有关
&lt;ol&gt;
&lt;li&gt;未经验证的输入&lt;/li&gt;
&lt;li&gt;跨站点脚本&lt;/li&gt;
&lt;li&gt;缓冲区溢出&lt;/li&gt;
&lt;li&gt;注入攻击&lt;/li&gt;
&lt;li&gt;不恰当的错误处理&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;提高软件质量通常的方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;采用结构化的设计，通过测试来识别和消除程序中的bug&lt;/li&gt;
&lt;li&gt;包括对可能输入变化和常见的错误测试&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;软件安全关心的不是程序中bug的数量，而是这些bug是如何被触发而导致程序失败的。&lt;/p&gt;
&lt;p&gt;软件安全不同与软件质量和可靠性，攻击者的目的是找到可利用的bug，造成程序失败。而这些bug需要通过一些特殊构造的方法被触发，一般的检测较难发现。&lt;/p&gt;
&lt;p&gt;无论何时，只要一个程序调用一些服务，而这个服务来自于另一个程序，服务或者函数，就可能发生注入攻击。给一个程序传递来自外部的一些不可信，没有充分检查和验证的信息时候，也可能发生注入攻击。&lt;/p&gt;
&lt;p&gt;fuzzing测试用于进行常规的，更普遍的测试。
主要就是按照模版生成大量的测试输入，然后输入到程序中，检查输出。但是这样的测试对于需要构造复杂结构而触发的漏洞，没有效果。而这样的漏洞一般而言是最重要的。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;操作系统安全&lt;/h1&gt;
&lt;p&gt;许多报告指出，使用少量的基本加固措施就能抵御大量的已知攻击。&lt;/p&gt;
&lt;p&gt;这四条策略是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;白名单许可的应用&lt;/li&gt;
&lt;li&gt;给第三方应用和操作系统漏洞打补丁&lt;/li&gt;
&lt;li&gt;限制管理员的权限&lt;/li&gt;
&lt;li&gt;创建深度防御系统&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这里也可以看看网络上著名的20 critical security control&lt;/p&gt;
&lt;p&gt;在创建和部署一个系统的时候应该有一个预案，并运行于整个系统的生命周期：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;评估风险和规划系统部署&lt;/li&gt;
&lt;li&gt;加固系统底层操作系统和关键应用程序&lt;/li&gt;
&lt;li&gt;确保任何关键内容是安全的&lt;/li&gt;
&lt;li&gt;确保使用了合适的网络保护机制&lt;/li&gt;
&lt;li&gt;确保应用了合适的流程保证系统安全&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;系统安全规划&lt;/h2&gt;
&lt;p&gt;宗旨： 以最小的代价获得最大化的安全。&lt;/p&gt;
&lt;p&gt;设计相关内容：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;系统的目的，存储信息的类型，提供的应用和服务以及安全需求&lt;/li&gt;
&lt;li&gt;系统用户的分类，以及拥有的权限，以及可以访问的信息类型&lt;/li&gt;
&lt;li&gt;用户怎样获得认证&lt;/li&gt;
&lt;li&gt;以什么方式访问系统内的信息应该被监管&lt;/li&gt;
&lt;li&gt;系统对存储在其他主机，如文件服务器或者数据库服务器上的信息可以进行访问，对这些访问怎么样进行管理&lt;/li&gt;
&lt;li&gt;谁来管理系统，以何种方式管理&lt;/li&gt;
&lt;li&gt;系统需要的其他附加安全措施，包括主机防火墙，发病毒软件或其他恶意代码防护机制以及日志&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;加固操作系统的建议&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;安装操作系统并打补丁&lt;/li&gt;
&lt;li&gt;移除不需要的服务，应用，协议&lt;/li&gt;
&lt;li&gt;配置用户，组以及权限&lt;/li&gt;
&lt;li&gt;配置资源控制&lt;/li&gt;
&lt;li&gt;安装安全工具&lt;/li&gt;
&lt;li&gt;测试基本操作系统的安全性&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;安全维护&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;监控和分析日志信息&lt;/li&gt;
&lt;li&gt;定期备份&lt;/li&gt;
&lt;li&gt;从安全损坏中恢复&lt;/li&gt;
&lt;li&gt;定期测试系统安全性&lt;/li&gt;
&lt;li&gt;使用合适的软件流程来更新关键软件和补丁，并进行监控和修改相关配置&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h1&gt;可信计算与多级安全&lt;/h1&gt;
&lt;p&gt;BLP模型，核心是保密性。关心信息的非授权泄漏。&lt;/p&gt;
&lt;p&gt;不能上读，不能下写。&lt;/p&gt;
&lt;p&gt;这两个特性规定了强制访问控制的保密性形式。并且还规定了自主访问控制。&lt;/p&gt;
&lt;p&gt;模型的三元组：主体，客体，访问方式&lt;/p&gt;
&lt;p&gt;BLP的困难：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;保密性与完整性互斥，要么追求权限，要么追求机密。&lt;/li&gt;
&lt;li&gt;出现隐蔽通道的问题，比如合谋&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Biba模型：关注完整性，关心数据的非授权修改。针对军事应用。&lt;/p&gt;
&lt;p&gt;clark-wilson：关注完整性，针对商业应用。
基础是：良形事务，和用户职责分离。&lt;/p&gt;
&lt;p&gt;chinese-wall：完整性和保密性。为了可能发生利益冲突的商业应用开发的，利用了自主和强制访问概念。是金融界和法律界的一个思想。&lt;/p&gt;
&lt;h3&gt;可信计算TC&lt;/h3&gt;
&lt;p&gt;可信计算提供三个基本服务：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;鉴别引导&lt;/li&gt;
&lt;li&gt;认证&lt;/li&gt;
&lt;li&gt;加密&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;IT安全管理和风险评估&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;哪些资产需要保护&lt;/li&gt;
&lt;li&gt;这些资产受到哪些威胁&lt;/li&gt;
&lt;li&gt;如何应对这些威胁&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;IT安全管理概念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;实现和保持适当级别的保密性，完整性，可用性，可核查性，真实性和可靠性的过程。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;职能包括：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;确定组织的IT安全目标，战略和方针&lt;/li&gt;
&lt;li&gt;确定组织的IT安全要求&lt;/li&gt;
&lt;li&gt;识别和分析组织内IT资产面临的安全威胁&lt;/li&gt;
&lt;li&gt;识别和分析的风险&lt;/li&gt;
&lt;li&gt;规定适当的安全防护措施&lt;/li&gt;
&lt;li&gt;监视必要的安全防护措施的实施和运行，以便为组织内部的信息和服务提供最经济的保护&lt;/li&gt;
&lt;li&gt;开发和实施安全意识项目&lt;/li&gt;
&lt;li&gt;检测和响应事件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;CSO信息安全官的职责：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;监督信息安全管理过程&lt;/li&gt;
&lt;li&gt;与主管信息安全的高级管理层联络&lt;/li&gt;
&lt;li&gt;维护组织的信息安全目标，战略和方针&lt;/li&gt;
&lt;li&gt;协调对信息安全事件的响应&lt;/li&gt;
&lt;li&gt;管理整个组织的信息安全意识和培训计划&lt;/li&gt;
&lt;li&gt;与IT项目安全官相互沟通&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h1&gt;IT安全控制，计划和规程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;控制措施：通过一些方法减少风险。包括消除或者预防违规的现象。将违规造成的损害减到最小。发现违规现象进而启动纠正措施。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;管理问题&lt;/h1&gt;
&lt;h2&gt;物理和基础设施安全&lt;/h2&gt;
&lt;p&gt;信息系统安全的三要素：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;逻辑安全：保护数据免受基于软件和基于通信的威胁&lt;/li&gt;
&lt;li&gt;物理安全：保护存储数据的信息系统和使用，操作，维护这些系统的人员的安全。&lt;/li&gt;
&lt;li&gt;整体安全：也叫做公司或者工厂安全。保护一个完整区域的人和财产，设施和建筑的安全。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;相对湿度 40%-60%&lt;/p&gt;
&lt;h2&gt;物理安全破坏的恢复&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;使用冗余。在理想情况下，系统中所有的重要的数据在站点外都是可以访问的。并且在成本/收益的基础上对其进行近乎实时的更新。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;人力资源管理&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;安全意识，培训和教育&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;改善员工的行为&lt;/li&gt;
&lt;li&gt;提升员工为自己的行为负责的能力&lt;/li&gt;
&lt;li&gt;减轻组织为员工的行为所负的责任&lt;/li&gt;
&lt;li&gt;遵守法规和合同的义务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;教育是为了让人知道“为什么”，培训是为了让人知道“怎么做”，而意识是让人知道“什么是”&lt;/p&gt;
&lt;p&gt;教育要求理解背景知识。培训要动手实践，意识可以通过看视频了解。&lt;/p&gt;
&lt;p&gt;人员安全的原则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;最小特权：根据员工所做的工作给予他最小的访问权限&lt;/li&gt;
&lt;li&gt;责任划分：对责任细分，减少职员对自己的权限进行不恰当的使用机会。&lt;/li&gt;
&lt;li&gt;对关键员工有限的依赖：确保在机构中没有人是不可替代的。对于系统来说，员工结构中应该建立冗余机制。专门的技能或者知识不能仅有一人掌握。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;把所有的安全和审计责任放在一个人身上是危险的。&lt;/p&gt;
&lt;p&gt;员工离职过程安全：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将其账户从授权访问列表清除&lt;/li&gt;
&lt;li&gt;明确通知保安，该人在没有内部人员陪同的情况下不许进入办公区域&lt;/li&gt;
&lt;li&gt;清除离职人员的访问pin&lt;/li&gt;
&lt;li&gt;修改必要的安全锁&lt;/li&gt;
&lt;li&gt;收回员工文档，设备，硬盘，工牌等&lt;/li&gt;
&lt;li&gt;通知该信息给适当的部门&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ISO27002&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;安全审计&lt;/h1&gt;
&lt;p&gt;目的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为与安全相关的正当的计算机操作提供一定级别的保证&lt;/li&gt;
&lt;li&gt;无论攻击是否成功，都为其生成可用于事后分析的数据&lt;/li&gt;
&lt;li&gt;提供一种可用于评估安全服务中存在的不足的工具&lt;/li&gt;
&lt;li&gt;提供能够用于定义异常行为的数据&lt;/li&gt;
&lt;li&gt;维护对计算机取证有用的记录&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;审计模型：&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;事件鉴别器&lt;/li&gt;
&lt;li&gt;审计记录器&lt;/li&gt;
&lt;li&gt;报警处理器&lt;/li&gt;
&lt;li&gt;安全审计迹：记录器将每个事件创建格式化的记录存储于此处&lt;/li&gt;
&lt;li&gt;审计分析器&lt;/li&gt;
&lt;li&gt;审计存档器&lt;/li&gt;
&lt;li&gt;存档&lt;/li&gt;
&lt;li&gt;审计提供器&lt;/li&gt;
&lt;li&gt;审计迹检查器&lt;/li&gt;
&lt;li&gt;安全报告&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SIEM&lt;/p&gt;
&lt;h1&gt;法律与道德问题&lt;/h1&gt;
&lt;h1&gt;密码编码算法&lt;/h1&gt;
&lt;p&gt;攻击类型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;唯密文攻击：需要知道加密算法和要解密的密文&lt;/li&gt;
&lt;li&gt;已知明文攻击：需要知道加密算法，要解密的密文，以及用同一个密钥加密的一个或多个明文-密文对&lt;/li&gt;
&lt;li&gt;选择明文攻击：需要知道加密算法，要解密的密文，以及分析者任意选择的明文和用同一个密钥加密的密文&lt;/li&gt;
&lt;li&gt;选择密文攻击：需要知道加密算法，要解密的密文，分析者有目的选择的一些密文和用同一个密钥解密的明文&lt;/li&gt;
&lt;li&gt;选择文本攻击：加密算法，要解密的密文，分析者任意选择的明文和用统一密钥加密的对应的明文，还需要知道分析者有目的选择的一些密文和用同一个密钥解密的对应的密文&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3DES的有效密钥长度为168位。如果令k1=k3，那么密钥长度就是112位。如果k1=k2=k3，那么3DES就和DES一样了，密钥长度为56了。&lt;/p&gt;
&lt;p&gt;在DES和3DES中，分组长度为64位。&lt;/p&gt;
&lt;p&gt;AES中，分组长度为128位。密钥长度可以被指定为128，202或者256位。&lt;/p&gt;
&lt;p&gt;AES，字节的最左边4位作为行，右边4位作为列，然后按照行列取出表中对应的值。&lt;/p&gt;
&lt;h3&gt;流密码和RC4&lt;/h3&gt;
&lt;p&gt;RC4作为SSL/TLS标准。该标准为网络浏览器和服务器间通信而制定。&lt;/p&gt;
&lt;p&gt;分组密码的工作方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ECB：用相同的密钥分别对64位明文组进行加密&lt;/li&gt;
&lt;li&gt;CBC：加密算法的输入是上一个64位密文组和下一个64位的明文组异或&lt;/li&gt;
&lt;li&gt;CFB：一次处理位。上一个分组密文作为产生一个伪随机数输出的加密算法的输入，该输出与明文异或，作为下一个分组的输入&lt;/li&gt;
&lt;li&gt;OFB：与CFB基本相同，只是加密算法的输入是上一次DES的输出&lt;/li&gt;
&lt;li&gt;CTR：每个明文组是与加密的计数器的异或。对每个后续的组，计数器是增加的&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;公钥密码和消息认证&lt;/h1&gt;
&lt;p&gt;RSA是一种分组密码，其明文和密文均是0～n-1之间的整数。&lt;/p&gt;
&lt;p&gt;RSA算法的详细解法
密钥交换的详细解法&lt;/p&gt;
&lt;h1&gt;网络安全&lt;/h1&gt;
&lt;h2&gt;internet安全协议&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;email，S/MIME&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;符合rfc822的规范，定义了一个简单报头，包括to，from，subject以及其他域。mime定义了一些内容格式，用于支持多媒体email进行标准化表示，包括文本，图像，音频，视频等。&lt;/p&gt;
&lt;p&gt;s/mime提供签名和加密消息的能力。&lt;/p&gt;
&lt;p&gt;TLS协议中的两个概念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TLS连接：对TLS来说，这样的连接是点到点的连接关系，而且这些连接是瞬态的，暂时的。每个连接都与一个会话关联。&lt;/li&gt;
&lt;li&gt;TLS会话：一个客户端与一个服务器之间的关联。由握手协议创建。会话可以用来便面每个连接需要进行的，代价高昂的新的安全参数的协商过程。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SSL记录协议支持两种服务，机密性和消息完整性。&lt;/p&gt;
&lt;p&gt;心跳的目的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;向发送者确保接收端存活，即使在底层tcp连接上已经有一段事件没有任何活动&lt;/li&gt;
&lt;li&gt;心跳生成了空闲时间段中的活动连接，以避免被不容忍空闲连接的防火墙关闭掉&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;IPsec的两种模式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;传输模式：保护扩展到IP包的载荷，针对上层协议提供保护。一般用于主机端到端的通信。该模式下会对载荷进行加密和有选择性的进行认证。但是对IP头不进行处理。&lt;/li&gt;
&lt;li&gt;隧道模式：对整个IP包提供保护。新生成的包是和原来的包不同的源地址和目标地址，增加了安全性。ESP在隧道模式下会对整个IP包，包括IP头进行加密和认证。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;Internet认证应用&lt;/h1&gt;
&lt;p&gt;主要是kerberous的方面&lt;/p&gt;
&lt;p&gt;协议的安全主要依赖于参加者对时间的松散同步和短周期的叫做Kerberos票据的认证声明。 下面是对这个协议的一个简化描述，将使用以下缩写：&lt;/p&gt;
&lt;p&gt;AS（Authentication Server）= 认证服务器
KDC（Key Distribution Center）= 密钥分发中心
TGT（Ticket Granting Ticket）= 票据授权票据，票据的票据
TGS（Ticket Granting Server）= 票据授权服务器
SS（Service Server）= 特定服务提供端
客户端用户发送自己的用户名到KDC服务器以向AS服务进行认证。KDC服务器会生成相应的TGT票据，打上时间戳，在本地数据库中查找该用户的密码，并用该密码对TGT进行加密，将结果发还给客户端用户。该操作仅在用户登录或者kinit申请的时候进行。 客户端收到该信息，并使用自己的密码进行解密之后，就能得到TGT票据了。这个TGT会在一段时间之后失效，也有一些程序(session manager)能在用户登陆期间进行自动更新。 当客户端用户需要使用一些特定服务(Kerberos术语中用&quot;principal&quot;表示)的时候，该客户端就发送TGT到KDC服务器中的TGS服务。当该用户的TGT验证通过并且其有权访问所申请的服务时，TGS服务会生成一个该服务所对应的ticket和session key，并发还给客户端。客户端将服务请求与该ticket一并发送给相应的服务端即可。具体的流程请看下面的描述。&lt;/p&gt;
&lt;p&gt;其在網路通訊協定中屬於顯示層。&lt;/p&gt;
&lt;p&gt;简单地说，用户先用共享密钥从某认证服务器得到一个身份证明。随后，用户使用这个身份证明与SS通信，而不使用共享密钥。&lt;/p&gt;
&lt;h1&gt;网络访问控制和云安全&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;NAC&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;访问请求者&lt;/li&gt;
&lt;li&gt;策略服务器&lt;/li&gt;
&lt;li&gt;网络接入服务器（媒体网关）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;网络访问实施方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IEEE802.X&lt;/li&gt;
&lt;li&gt;VLAN&lt;/li&gt;
&lt;li&gt;Firewall&lt;/li&gt;
&lt;li&gt;DHCP&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;EAP：EAP（Extensible Authentication Protocol）为可扩展身份验证协议，是一系列验证方式的集合，设计理念是满足任何链路层的身份验证需求，支持多种链路层认证方式。EAP协议是IEEE 802.1x认证机制的核心，它将实现细节交由附属的EAP Method协议完成&lt;/p&gt;
&lt;p&gt;EAPOL：EAP over LAN。比如在PC和NAS之间，EAP报文用这个格式进行封装。&lt;/p&gt;
&lt;p&gt;EAPoR：EAP over Radius。在NAS和AAA之间的封装格式。&lt;/p&gt;
&lt;p&gt;EAP的四种认证方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EAP-MD5:容易受到字典攻击，不支持密钥生成&lt;/li&gt;
&lt;li&gt;LEAP：cisco的专用认证方法，在EAP-MD5的基础上增加了动态的WEP密钥和互验证（客户端和Radius服务器之间）&lt;/li&gt;
&lt;li&gt;EAP-TLS：基于TLS的EAP，是WPA和WPA2的行业标准。优点是安全性较高。缺点是需要PKI体系，还有客户端认证时候负载较高，证书的管理有难度&lt;/li&gt;
&lt;li&gt;EAP-TTLS：基于隧道TLS的EAP.目的是解决EAP-TLS需要PKI系统的问题。这样不需要PKI，而是直接在TLS隧道内使用原有的认证方法。&lt;/li&gt;
&lt;li&gt;PEAP：将EAP封装到TLS隧道。由cisco，microsoft和RSA共同开发的。也是WPA，WPA2的标准&lt;/li&gt;
&lt;li&gt;EAP-FAST：cisco提出的，用于代替LEAP。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;传输层安全&lt;/h1&gt;
&lt;p&gt;使用HTTPs时候，下面的通信元素是加密的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;请求文档的URL&lt;/li&gt;
&lt;li&gt;文档的内容&lt;/li&gt;
&lt;li&gt;浏览器格式的内容&lt;/li&gt;
&lt;li&gt;在浏览器和服务器之间传输的cookies&lt;/li&gt;
&lt;li&gt;HTTP报头的内容&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;无线网络安全&lt;/h1&gt;
&lt;p&gt;无线网络的关键因素：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;信道：容易窃听和干扰&lt;/li&gt;
&lt;li&gt;移动性&lt;/li&gt;
&lt;li&gt;资源：手机和平板的处理能力较低，比较容易受到拒绝服务攻击和恶意软件&lt;/li&gt;
&lt;li&gt;易接近性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;包括终端，无线媒介，接入点&lt;/p&gt;
&lt;p&gt;保护措施：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;信号隐藏&lt;/li&gt;
&lt;li&gt;加密&lt;/li&gt;
&lt;li&gt;绑定mac地址的访问&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;电子邮件安全&lt;/h1&gt;
&lt;h1&gt;IP安全性&lt;/h1&gt;
</content:encoded></item><item><title>cybersecurity-books</title><link>https://dididudu998.github.io/posts/20-53-cybersecurity-books/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/20-53-cybersecurity-books/</guid><pubDate>Tue, 09 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;cybersecurity-books&lt;/h1&gt;
&lt;p&gt;Top 5 books to get started in cybersecurity: 0:28​
Book 1: The Pentest Blueprint: 1:00​
Book 2: Social Engineering - The Art fo Human Hacking: 1:58​
Real world example from Neal&apos;s experience: 3:03​
Social engineering vs technical hacking skills: 6:34​
Some people wouldn&apos;t want to lie: 10:12​
What&apos;s good in the book - defeating humans: 10:50​
Book 3: Basic Security Testing with Kali Linux: 12:22​
Teaching you tools / OSCP: 13:42​
Book 4: Metasploit Penetration Testing Cookbook: 14:27​
Cost of training: 16:05​
Book 5: The Hacker Playbook: 16:37​
How do I practice ethical hacking? 18:27​
Buying physical equipment: 20:06​
Practical Book 1: RTFM: 22:00​
Practical Book 2: BLue Team Handbook: 23:46​
Practical Book 3: Gray Hat Python: 24:51​
Practical Book 4: Malware Analysts Cookbook: 26:40​
Practical Book 5: Inside Cyber Warfare: 35:16&lt;/p&gt;
&lt;h1&gt;ISBN Numbers from Neal&apos;s bookshelf:&lt;/h1&gt;
&lt;p&gt;Inside Cyber Warfare:  978-0-596-800215-8
The Hacker Playbook:  978-1-4949-3263-3
Metasploit Penetration Testing Cookbook:  978-1-84951-742-3
Social Engineering - The Art fo Human Hacking:  978-0-470-63953-5
Basic Security Testing with Kali Linux:  9781-494861278
Malware Analysts Cookbook:  978-0-470-61303-0
Gray Hat Python: 978-1-59327-192-3
Blue Team Handbook:  9781500734756
Red Team Field Manual:  9781494295509&lt;/p&gt;
&lt;p&gt;The Pentester BluePrint: Starting a Career as an Ethical Hacker: https://amzn.to/3rzZ9Hw​&lt;/p&gt;
&lt;p&gt;Inside Cyber Warfare:  https://amzn.to/2YZUcvn​&lt;/p&gt;
&lt;p&gt;The Hacker Playbook:
1: https://amzn.to/36XrM9I​
2: https://amzn.to/36Sr2mj​
3: https://amzn.to/3rzYxSe​&lt;/p&gt;
&lt;p&gt;Metasploit Penetration Testing Cookbook:
2nd Edition: https://amzn.to/2MO2WCk​
3rd Edition: https://amzn.to/3jyZgQH​&lt;/p&gt;
&lt;p&gt;Social Engineering - The Art of Human Hacking:  https://amzn.to/3aMZsIm​&lt;/p&gt;
&lt;p&gt;Basic Security Testing with Kali Linux:  https://amzn.to/3cWLAOc​&lt;/p&gt;
&lt;p&gt;Malware Analysts Cookbook:  https://amzn.to/3cSlxb7​&lt;/p&gt;
&lt;p&gt;Gray Hat Python: https://amzn.to/2Z2wiPK​&lt;/p&gt;
&lt;p&gt;Blue Team Handbook:  https://amzn.to/3tHq6uM​&lt;/p&gt;
&lt;p&gt;Red Team Field Manual (RTFM):  https://amzn.to/2LzzSOh​&lt;/p&gt;
&lt;p&gt;INE Free training: https://bit.ly/freeinetraining​
eLearn Security: https://elearnsecurity.com/product/ej...​
OSCP: https://www.offensive-security.com/co...​
SANS: https://www.sans.org/​
Hack the box: https://www.hackthebox.eu/​
Try Hack Me: https://tryhackme.com/​
CTF Time: https://ctftime.org/ctf-wtf/​
CEH: https://www.eccouncil.org/programs/ce...​
Cyber Blue: https://securityblue.team/​
Cyber Defenders: https://cyberdefenders.org/​&lt;/p&gt;
</content:encoded></item><item><title>算法</title><link>https://dididudu998.github.io/posts/20-59-%E7%AE%97%E6%B3%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/20-59-%E7%AE%97%E6%B3%95/</guid><pubDate>Tue, 09 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;算法&lt;/h1&gt;
&lt;p&gt;Computer Science Distilled - https://amzn.to/39jYZ0S​
Grokking Algorithms - https://amzn.to/2JcBrjS​
Introduction to Algorithms - https://amzn.to/2V03JRb​
Elements of Programming Interviews (Python) - https://amzn.to/35XPQJw​
Elements of Programming Interviews (Java) - https://amzn.to/374W5KT​&lt;/p&gt;
&lt;p&gt;💻🎧 Don&apos;t like reading books? Become a better programmer with audiobooks of the #1 bestselling programming series: Clean Code, Clean Architecture, Clean Coder and Clean Agile with 4.6/5 stars and 4000+ reviews!
Visit https://www.cleancodeaudio.com/​ and use code UTSAV to get 40% off all four audio books!&lt;/p&gt;
&lt;p&gt;📕 OTHER RECOMMENDATIONS&lt;/p&gt;
&lt;p&gt;Algorithm Design Manual - https://amzn.to/35ZXx1D​
Algorithms (4th Ed.) - https://amzn.to/3m9c1kN​&lt;/p&gt;
&lt;p&gt;📺 EXCELLENT FREE RESOURCES&lt;/p&gt;
&lt;p&gt;(Watch these in order - beginner to advanced)&lt;/p&gt;
&lt;p&gt;Intro to Computer Science (by Ana Bell @ MIT) - https://bit.ly/3oHCWpq​
Programming Abstractions (by Julie Zelenski @ Stanford) - https://bit.ly/3n7WfIg​
Introduction to Algorithms (by Erik Demaine @ MIT) - https://bit.ly/2JWzd8J​&lt;/p&gt;
&lt;p&gt;——————————————————————————————————&lt;/p&gt;
</content:encoded></item><item><title>关于安卓apk的研究</title><link>https://dididudu998.github.io/posts/14-00-%E5%85%B3%E4%BA%8E%E5%AE%89apk%E7%9A%84%E7%A0%94%E7%A9%B6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/14-00-%E5%85%B3%E4%BA%8E%E5%AE%89apk%E7%9A%84%E7%A0%94%E7%A9%B6/</guid><pubDate>Fri, 05 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;关于安卓apk的研究&lt;/h1&gt;
&lt;p&gt;主要是逆向apk文件，获得应用相关的组件和运行信息。&lt;/p&gt;
&lt;p&gt;可用的工具如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;apktool&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://ibotpeaches.github.io/Apktool/&lt;/p&gt;
&lt;p&gt;这个工具用于decompile/recompile app文件和资源。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jadx-gui&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://github.com/skylot/jadx&lt;/p&gt;
&lt;p&gt;将apk载入后，可以反编译出java源码和class出来。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;smali/baksmali&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://github.com/JesusFreke/smali&lt;/p&gt;
&lt;p&gt;这个可以将java类转化成课编辑的forms，然后可以对源代码进行修改。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dex2Jar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://github.com/pxb1988/dex2jar&lt;/p&gt;
&lt;p&gt;图形界面化的显示java源代码，kali-linux中包含有这个应用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bytecode viewer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://github.com/Konloch/bytecode-viewer/&lt;/p&gt;
&lt;p&gt;java逆向工程用的，和jadx有点像。 用起来就是java -jar bytecode-viewer-version.jar&lt;/p&gt;
</content:encoded></item><item><title>最近喜欢上了油画</title><link>https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91%E5%96%9C%E6%AC%A2%E4%B8%8A%E4%BA%86%E6%B2%B9%E7%94%BB/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%9C%80%E8%BF%91%E5%96%9C%E6%AC%A2%E4%B8%8A%E4%BA%86%E6%B2%B9%E7%94%BB/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 02 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;最近喜欢上了油画&lt;/h1&gt;
&lt;p&gt;原因是看了一本书《樊文龙-世界美术全集》，对里面的一幅画干草车非常喜欢。
然后看到这幅画保存在大英博物馆，就想到去博物馆下载下看看。&lt;/p&gt;
&lt;p&gt;然后发现这里的很多的画都很喜欢，就写了个下载的小应用。&lt;/p&gt;
&lt;p&gt;这里的图片最大的分辨率差不多1920*2383这样的，貌似没有更大的分辨率。&lt;/p&gt;
&lt;p&gt;然后就下载了很多，有空的时候可以看看了。&lt;/p&gt;
&lt;p&gt;大英博物馆的地址：https://www.nationalgallery.org.uk/&lt;/p&gt;
&lt;p&gt;aelbert-cuyp-a-herdsman-with-five-cows-by-a-river&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/youhua/aelbert-cuyp-a-herdsman-with-five-cows-by-a-river.jpg&quot; alt=&quot;aelbert-cuyp-a-herdsman-with-five-cows&quot; /&gt;&lt;/p&gt;
&lt;p&gt;aelbert-cuyp-a-hilly-landscape-with-figures&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/youhua/aelbert-cuyp-a-hilly-landscape-with-figures.jpg&quot; alt=&quot;aelbert-cyu-a-hhilly-lanscape&quot; /&gt;&lt;/p&gt;
&lt;p&gt;aert-van-der-neer-a-river-landscape-with-a-village&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/youhua/aert-van-der-neer-a-river-landscape-with-a-village.jpg&quot; alt=&quot;aert-van-der-neer-a-river-landscape-with-a-village&quot; /&gt;&lt;/p&gt;
&lt;p&gt;claus-anton-kolle-a-courtyard-in-rome
&lt;img src=&quot;/images/youhua/claus-anton-kolle-a-courtyard-in-rome.jpg&quot; alt=&quot;claus-anton-kolle-a-courtyard-in-rome&quot; /&gt;&lt;/p&gt;
&lt;p&gt;john-constable-the-hay-wain&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/youhua/john-constable-the-hay-wain.jpg&quot; alt=&quot;john-constable-the-hay-wain&quot; /&gt;&lt;/p&gt;
&lt;p&gt;claude-the-mill
&lt;img src=&quot;/images/youhua/claude-the-mill.jpg&quot; alt=&quot;claude-the-mill&quot; /&gt;&lt;/p&gt;
&lt;p&gt;charles-francois-daubigny-willows
&lt;img src=&quot;/images/youhua/charles-francois-daubigny-willows.jpg&quot; alt=&quot;charles-francois-daubigny-willows&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>fish中alias的使用</title><link>https://dididudu998.github.io/posts/fish%E4%B8%ADalias%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/fish%E4%B8%ADalias%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><pubDate>Thu, 25 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;简便的shell-fish&lt;/h1&gt;
&lt;p&gt;好像是在微博上看到的有人问除了zsh还有什么shell比较好用.&lt;/p&gt;
&lt;p&gt;我现在用的是zsh，配合使用的oh-my-zsh这个。&lt;/p&gt;
&lt;p&gt;然后也跟风去安装了fish，fish和zsh的区别是有些命令没有。还有在zshrc中配置的alias都没有。但是fish的自动补全功能是很好的。而且启动新的窗口比zsh要快，可能是我的zshrc中配置的东西太多了导致的。&lt;/p&gt;
&lt;p&gt;我只是想在fish shell中使用更快捷的alias命令，所以在这里配置即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd ~/.config/fish
ls
config.fish    fish_variables functions
vi config.fish
alias updatedb=&quot;sudo /usr/libexec/locate.updatedb&quot;
....
....
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其他的alias逐行添加即可。
添加后重新打开fish shell，就可以用了。&lt;/p&gt;
</content:encoded></item><item><title>关于redhat satellite</title><link>https://dididudu998.github.io/posts/09-50-%E5%85%B3%E4%BA%8Eredhat-satellite/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/09-50-%E5%85%B3%E4%BA%8Eredhat-satellite/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 23 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;关于redhat satellite&lt;/h1&gt;
&lt;p&gt;这个是redhat用于管理其redhat linux而生产的一个产品，主要用于部署，配置，分布式补丁管理。有点类似于微软的SCCM，补丁管理类似于微软的WSUS。&lt;/p&gt;
&lt;p&gt;如果是个出售的产品，小型的规模不太合适。大型的化，可能价格太高。适合中型的，有一定的IT人员，但是又不想花太多的时间来做基础配置的。&lt;/p&gt;
&lt;p&gt;我个人感觉实用性一般。&lt;/p&gt;
&lt;p&gt;期间搜索关于satellite的资料到了这里：http://blog.emba.kr/blog/
发现这个网站不错。韩国的技术人员在多年前在我的印象里就比较严谨。
当时在微软的消息协作team做支持，韩国那边升级过来的case都写的很好，自己做了哪些测试，结果如何，清清楚楚。&lt;/p&gt;
&lt;p&gt;对于satellite的了解搁置，这个东西不值得花什么时间在上面。&lt;/p&gt;
</content:encoded></item><item><title>做个自己电脑的导航页</title><link>https://dididudu998.github.io/posts/%E5%81%9A%E4%BA%86%E4%B8%AA%E8%87%AA%E5%B7%B1%E7%94%B5%E8%84%91%E7%9A%84%E5%AF%BC%E8%88%AA/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%81%9A%E4%BA%86%E4%B8%AA%E8%87%AA%E5%B7%B1%E7%94%B5%E8%84%91%E7%9A%84%E5%AF%BC%E8%88%AA/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 22 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;做了个自己电脑的导航页&lt;/h1&gt;
&lt;p&gt;MacBook的文件夹管理，我用的是彩色标签的形式来分类哪些是常用的文件夹。还有就是用terminal的profile创建alias的方式来快速启动应用。&lt;/p&gt;
&lt;p&gt;还有一些文件夹是经常要看的书和一些数据的整理。&lt;/p&gt;
&lt;p&gt;还有一些是自己随时写的文件。时间长了总是要找几下才能找到在哪里。&lt;/p&gt;
&lt;p&gt;这次就是这个原因，导致我要做个这电脑的导航页给自己。避免总是找文件耗费时间。&lt;/p&gt;
&lt;p&gt;还有就是浏览器的收藏夹收藏的太多了，缺乏整理。后面加上自己筛选出来的放上去，归个类。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;style type=&quot;text/css&quot;&amp;gt;
    a:link
    {
        text-decoration: none;
    }
    a:visited
    {
        text-decoration: none;
    }
    a:active
    {
        text-decoration: none;
    }
    a:hover
    {
        text-decoration: underline;
    }
&amp;lt;/style&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;utf-8&quot;&amp;gt;
    &amp;lt;title&amp;gt;电脑上面的信息分布&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;经常用的文件位置&amp;lt;/h1&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=file:///Users/ls3686/myrecords&amp;gt;日常记录&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=file:///Users/ls3686/Downloads/weibocrawl/weibo-crawler/weibo&amp;gt;微博收集&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=file:///Users/ls3686/atom_dev_files&amp;gt;atom_dev_files&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=file:///Users/ls3686/程序原型与设想init&amp;gt;程序原型与设想init&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=file:///Users/ls3686/mynotes/我的笔记/读书笔记&amp;gt;读书笔记&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=file:///Users/ls3686/mynotes/我的笔记/IT&amp;gt;IT笔记&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=file:///Users/ls3686/Downloads/scz_offline/index.html&amp;gt;scz_offline&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    .....
    .....
    .....

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>登录信息定时发送到邮箱</title><link>https://dididudu998.github.io/posts/%E7%99%BB%E5%BD%95%E4%BF%A1%E6%81%AF%E5%8F%91%E9%82%AE%E4%BB%B6%E7%BB%99%E6%88%91/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%99%BB%E5%BD%95%E4%BF%A1%E6%81%AF%E5%8F%91%E9%82%AE%E4%BB%B6%E7%BB%99%E6%88%91/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 26 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;增加对登录的监控&lt;/h1&gt;
&lt;p&gt;定时将用户的登录信息发送到我邮箱。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;apt install mailutils 用于安装smtp服务器，类型选择为internet site即可&lt;/li&gt;
&lt;li&gt;如果没有设定正确的fqdn名，则会出现下面的错误提示：&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;said: 504 5.5.2 &lt;a href=&quot;mailto:root@flask&quot;&gt;root@flask&lt;/a&gt;: Sender address rejected: need fully-qualified address (in reply to RCPT TO command))&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;配置 vi /etc/postfix/main.cf， 修改append_dot_mydomain=true&lt;/li&gt;
&lt;li&gt;也可以在/etc/mailname中输入域名&lt;/li&gt;
&lt;li&gt;测试发送邮件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;hello&quot; | mail -s &quot;test message&quot; my-email-address
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;大部分公司的邮箱服务器做了反垃圾邮件的策略，所以，虽然在/var/log/mail.log中看到已经发出去了，但是是收不到的。但是outlook邮箱没问题。&lt;/li&gt;
&lt;li&gt;login的检查有两个：&lt;pre&gt;&lt;code&gt;grep Accept /var/log/auth.log|tail -10 | mail -s &quot;auth info&quot; my-email-address


/usr/bin/last | mail -s &quot;login info&quot; my-email-address
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;做两个bash文件，然后添加到crontab中即可。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;后续&lt;/h1&gt;
&lt;p&gt;其实用这个做一个类似实时检查登录的也是可以的，无非就是tail -1和任务的时间缩短到1分钟去。
也可以做个小程序，后台以服务的形式来探查，不过还没有到那个程度，就先这样了。&lt;/p&gt;
</content:encoded></item><item><title>golang模板中使用array的索引获取value</title><link>https://dididudu998.github.io/posts/golang%E6%A8%A1%E7%89%88/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/golang%E6%A8%A1%E7%89%88/</guid><pubDate>Thu, 21 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;想要搞一个session的网站，后台是ldap验证的，当用户验证后，生成cookie，记录对应的session，然后在session过期前就可以一直进行相关的操作，而不需要每次操作都要验证。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;p&gt;开始的时候很顺利，但是当修改了模版后，莫名的cookie创建后，不能写入了。
就是login后，直接退出，application中的cookie项目为空了。&lt;/p&gt;
&lt;p&gt;开始没有头绪，后来就发现肯定是模版设计的有问题。总是出不来效果。&lt;/p&gt;
&lt;p&gt;因为当从session中取简单值，然后将模版设定为简单的那种，就可以显示。&lt;/p&gt;
&lt;p&gt;搞这个模版折腾了接近一天的时间。&lt;/p&gt;
&lt;p&gt;后来数据结构就是[][]string这样了，不搞什么struct了。累了。&lt;/p&gt;
&lt;p&gt;模版中这样写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;table&amp;gt;
            &amp;lt;thead&amp;gt;
            &amp;lt;tr&amp;gt;
            &amp;lt;th scope=&quot;col&quot;&amp;gt;ID&amp;lt;/th&amp;gt;
            &amp;lt;th scope=&quot;col&quot;&amp;gt;HostName&amp;lt;/th&amp;gt;
            &amp;lt;th scope=&quot;col&quot;&amp;gt;OS&amp;lt;/th&amp;gt;
            &amp;lt;/tr&amp;gt;
          &amp;lt;/thead&amp;gt;
          &amp;lt;tfoot&amp;gt;
          &amp;lt;tr&amp;gt;
          &amp;lt;td&amp;gt;End&amp;lt;/td&amp;gt;
          &amp;lt;/tfoot&amp;gt;
    
          &amp;lt;tbody&amp;gt;
          {{ range $_,$item:=.Result }}
           &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt; {{ index $item 0 }}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt; {{ index $item 1 }}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt; {{ index $item 2 }}&amp;lt;/td&amp;gt;
          &amp;lt;/tr&amp;gt;
          {{ end }}
          &amp;lt;/tbody&amp;gt;
          &amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的Result是提交给template用于解析的类型为[][]string的数组。
如果这个Result的值是这样的[[&quot;1“,“server1”,&quot;Windows]],那么{{ index $item 0}}, 就是表示[&quot;1“,“server1”,&quot;Windows]中的index为0的值，依次类推。&lt;/p&gt;
&lt;p&gt;省的搞什么struct这样的，真的好累。&lt;/p&gt;
&lt;p&gt;还有最后发现一个问题说“securecookie: the value is too long”，
再说吧，一般人没有这么大的数据量。。&lt;/p&gt;
&lt;p&gt;后台用redis处理的方式，下面再来看了。&lt;/p&gt;
&lt;p&gt;补充：
还是看看这里的后台方案吧：
https://github.com/gorilla/sessions#store-implementations&lt;/p&gt;
</content:encoded></item><item><title>解谜</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E8%B0%9C/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E8%B0%9C/</guid><pubDate>Mon, 18 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;解谜&lt;/h1&gt;
&lt;p&gt;无意看到这个网站，http://i.hacking8.com，要想注册需要邀请码，
获得邀请码要么就是找加入过的人给一个，要么就是自己来解谜题，解谜后拿到flag，提交flag，获得邀请码。&lt;/p&gt;
&lt;p&gt;过程是这样的：&lt;/p&gt;
&lt;p&gt;运行解谜：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 -c &quot;exec(__import__(&apos;urllib.request&apos;,fromlist=[&apos;urlopen&apos;]).urlopen(&apos;http://i.hacking8.com/static/i.py&apos;).read().decode())&quot;

一个简单的编程游戏！一共有4题，全部回答完成，即挑战成功。
第一关:计算结果 1+1=？
请输入答案:2
恭喜你通过第一关！

第二关:次方求余数 (12345678910^12345678901234567890)%9999999999=?
请输入结果:6014760148
恭喜你通过第二关！

第三关：1_2_3_4_5_6_7_8_9=404,每处_填入1个运算符+-*/,使得等式成立(答案保证唯一),表达式为?
请输入表达式:1-2+3*4*5+6*7*8+9
恭喜你通过第三关，最后一关了哦！

第四关:w8ay将自己的微信用一种加密算法加密了，为此他设计了一套解密算法，但关键的key他忘记了，只知道是纯数字的组合，好在记得前10位是4201353550,帮助它寻找完整的key叭。
请输入key:&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>python的时间格式转化</title><link>https://dididudu998.github.io/posts/python-datetime%E7%9A%84%E6%97%B6%E9%97%B4%E6%A0%BC%E5%BC%8F%E8%BD%AC%E5%8C%96/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/python-datetime%E7%9A%84%E6%97%B6%E9%97%B4%E6%A0%BC%E5%BC%8F%E8%BD%AC%E5%8C%96/</guid><pubDate>Fri, 15 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;python的时间格式转化&lt;/h1&gt;
&lt;p&gt;时间格式转化需要引入下面的两个模块&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;from datetime import datetime&lt;/li&gt;
&lt;li&gt;import time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于获取当前时间：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt;datetime.now()
datetime.datetime(2021, 1, 11, 21, 52, 15, 435113)

strftime是将日期格式转化为字符串：
&amp;gt;&amp;gt;&amp;gt; datetime.strftime(datetime.now(),&quot;%a %m %d %H:%M:%S +0800 %Y&quot;)
&apos;Fri 01 11 21:23:49 +0800 2021&apos;

strptime是将字符串转化为日期：
datetime.strptime(&apos;Fri 01 11 21:23:49 +0800 2021&apos;,&quot;%a %m %d %H:%M:%S +0800 %Y&quot;)
datetime.datetime(2021, 1, 11, 21, 23, 49)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;函数中所使用的格式化形式见下表：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;两个函数都涉及日期时间的格式化字符串，列举如下：

%a 星期几的简写;如 星期三为Web 
%A 星期几的全称;如 星期三为Wednesday 
%b 月份的简写; 如4月份为Apr 
%B 月份的全称; 如4月份为April 
%c 标准的日期的时间串;（如： 04/07/10 10:43:39） 
%C 年份的后两位数字 
%d 十进制表示的每月的第几天 
%D 月/天/年 
%e 在两字符域中，十进制表示的每月的第几天 
%F 年-月-日 
%g 年份的后两位数字，使用基于周的年 
%G 年分，使用基于周的年 
%h 简写的月份名 
%H 24小时制的小时 
%I 12小时制的小时 
%j 十进制表示的每年的第几天 
%m 十进制表示的月份 
%M 十时制表示的分钟数 
%n 新行符 
%p 本地的AM或PM的等价显示 
%r 12小时的时间 
%R 显示小时和分钟：hh:mm 
%S 十进制的秒数 
%t 水平制表符 
%T 显示时分秒：hh:mm:ss 
%u 每周的第几天，星期一为第一天 （值从0到6，星期一为0） 
%U 第年的第几周，把星期日做为第一天（值从0到53） 
%V 每年的第几周，使用基于周的年 
%w 十进制表示的星期几（值从0到6，星期天为0） 
%W 每年的第几周，把星期一做为第一天（值从0到53） 
%x 标准的日期串 
%X 标准的时间串 
%y 不带世纪的十进制年份（值从0到99） 
%Y 带世纪部分的十制年份 
%z，%Z 时区名称，如果不能得到时区名称则返回空字符。 
%% 百分号
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>简单线性规划问题的求解</title><link>https://dididudu998.github.io/posts/%E7%AE%80%E5%8D%95%E7%BA%BF%E6%80%A7%E8%A7%84%E5%88%92%E9%97%AE%E9%A2%98%E4%BB%A5%E5%8F%8A%E5%BE%AE%E7%A7%AF%E5%88%86%E6%B1%82%E8%A7%A3/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%AE%80%E5%8D%95%E7%BA%BF%E6%80%A7%E8%A7%84%E5%88%92%E9%97%AE%E9%A2%98%E4%BB%A5%E5%8F%8A%E5%BE%AE%E7%A7%AF%E5%88%86%E6%B1%82%E8%A7%A3/</guid><pubDate>Mon, 11 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;简单线性规划问题的求解&lt;/h1&gt;
&lt;p&gt;在看算法设计与分析的书中，练习题里面有个线性规划的问题。&lt;/p&gt;
&lt;p&gt;利用坐标和画出线性图像，可以解决。但是这样效率不高。&lt;/p&gt;
&lt;p&gt;经过搜索，可以使用python的scipy这个库进行解决。&lt;/p&gt;
&lt;p&gt;很早前安装这个库是为了求多元多次方程的。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;p&gt;问题&lt;/p&gt;
&lt;p&gt;当x,y满足下面条件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;x+y&amp;lt;=4&lt;/li&gt;
&lt;li&gt;x+3y&amp;lt;=6&lt;/li&gt;
&lt;li&gt;x&amp;gt;=0,y&amp;gt;=0
求 3x+5y的最大值。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;解决&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要说明的是求解的时候要给各个方程乘以-1，确保左边的值&amp;gt;=右边的值，而不是小于。
故有：
-x-y&amp;gt;=-4
-1-3y&amp;gt;=-6&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import numpy as np
from scipy import optimize as op
x=(0,None)
y=(0,None)
a_ub=np.array([[-1,-1],[-1,-3]])
b_ub=np.array([-4,-6])
c=np.array([3,5])
res=op.linprog(c,a_ub,b_ub,bounds(x,y))
res
     con: array([], dtype=float64)
     fun: 13.999999999646015
 message: &apos;Optimization terminated successfully.&apos;
     nit: 4
   slack: array([-9.11426490e-11, -1.71698211e-10])
  status: 0
 success: True
       x: array([3., 1.])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的scipy求出来的是float类型的，如果想更精确，可以这么做：
res=op.linprog(c,a_ub,b_ub,bounds(x,y),method=&quot;revised simplex&quot;)&lt;/p&gt;
&lt;p&gt;即当x=3,y=1的时候，3x+5y可以拿到最大值，14.&lt;/p&gt;
&lt;h1&gt;更进一步&lt;/h1&gt;
&lt;p&gt;PuLP is an LP modeler written in python. PuLP can generate MPS or LP files and call GLPK, COIN CLP/CBC, CPLEX, and GUROBI to solve linear problems.&lt;/p&gt;
&lt;p&gt;这个库更强大一些，专门为各种优化问题提供的，最大，最小，最优等等。。。&lt;/p&gt;
&lt;p&gt;更详细的信息可以看这个： https://coin-or.github.io/pulp/main/the_optimisation_process.html&lt;/p&gt;
&lt;p&gt;case study开始：https://coin-or.github.io/pulp/CaseStudies/a_blending_problem.html&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import pulp as p
# 求最大值为LpMaximize,求最小值为LpMinimize
lp1=p.LpProblem(&apos;problem&apos;,p.LpMaximize) 
# x,y的边界3
x=p.LpVariable(&apos;x&apos;,lowBound=0)
y=p.LpVariable(&apos;y&apos;,lowBound=0)
# 输入结构方程
lp1+=3*x+5*y
lp1+=x+y&amp;lt;=4
lp1+=x+3*y&amp;lt;=6
# print(lp1)
# status=lp1.solve()
# 求解
print(p.value(x),p.value(y),p.value(lp1.objective))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出为：3.0 1.0 14.0&lt;/p&gt;
&lt;p&gt;可以看到pulp的方式比scipy的更加适合处理规划问题。简单而且不含糊。&lt;/p&gt;
&lt;h1&gt;再进一步&lt;/h1&gt;
&lt;p&gt;在进行多元多项式的处理的时候，scipy会存在只考虑正整数，忽略负数的情况，而且不能用无理数替换float的数，导致求出来的值无法在理论意义上相等。而sympy这个模块可以实现。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from sympy import *
init_printing(use_unicode=True)
sqrt(8)
&amp;gt;&amp;gt;&amp;gt; 2⋅√2

# 矩阵计算

M=Matrix([[1,-1,2],[3,4,5]])
N=Matrix([0,1,1])
M*N

⎡1⎤
⎢ ⎥
⎣9⎦
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;微分方程&lt;/h1&gt;
&lt;p&gt;我們看範例，解微分方程式  y&apos;-3y=2&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;t = symbols(&apos;t&apos;)

y = Function(&apos;y&apos;)
dsolve(Eq(Derivative(y(t), t) -3*y(t), 2), y(t))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;           3⋅t    
       C₁⋅ℯ      2
y(t) = ─────── - ─
          3      3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Derivative(y(t), t)就是微一階y&apos;(t)；若微二階 y&apos;&apos;(t) 就是Derivative(y(t), t, t).&lt;/p&gt;
&lt;h2&gt;解微分方程 y&apos;=(y+1)/(t-3)&lt;/h2&gt;
&lt;p&gt;转化为 y&apos;-(y+1)/(t-3)=0&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;t=symbols(&apos;t&apos;)
y=Function(&apos;y&apos;)
dsolve(Eq(Derivative(y(t),t)-(y(t)+1)/(t-3),0),y(t))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;y(t) = C₁⋅t - 3⋅C₁ - 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;解二阶微分方程&lt;/h2&gt;
&lt;p&gt;y‘‘+9y=1&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;t=symbols(&apos;t&apos;)
y=Function(&apos;y&apos;)
dsolve(Eq(Derivative(y(t),t,t)+9*y(t),1),y(t))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;y(t) = C₁⋅sin(3⋅t) + C₂⋅cos(3⋅t) + 1/9
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;求解不定积分&lt;/h1&gt;
&lt;p&gt;积分2x/(x*x-1)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import math
from sympy import *
x=symbols(&apos;x&apos;)
integrate(2*x/(x**2-1),x)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;求解定积分&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/%E5%AE%9A%E7%A7%AF%E5%88%86.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;更好的资料参看这里：&lt;/p&gt;
&lt;p&gt;http://web.ntnu.edu.tw/~tsungwu/Python_DevOps/Part1_Basics&amp;amp;Math/section5_integration.html&lt;/p&gt;
</content:encoded></item><item><title>揭开smartcmp的数据库为我所用</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E5%AF%86smartcmp%E6%95%B0%E6%8D%AE%E5%BA%93/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E5%AF%86smartcmp%E6%95%B0%E6%8D%AE%E5%BA%93/</guid><pubDate>Fri, 08 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;原因是某些人要求有更多的IP地址信息，而我不想要登录那个平台的web进行操作。想要直接更新数据库的方式实现这个请求。&lt;/p&gt;
&lt;h1&gt;经过&lt;/h1&gt;
&lt;p&gt;ssh到这个平台的主机，这个平台可以说完全是开源组件构建起来的，但是好像是在卖钱，个人不觉得这个产品的技术价值有多大，但是可能让一些懒惰的人觉得有用。我是不会为它付钱的。&lt;/p&gt;
&lt;p&gt;至于这个产品的结构不提了，底层用了一些python，terrform，ansible这样的自动化部署脚本，网络上用networkx这样的东西，然后通讯用celery和amq这样的，web用nginx，监控用了gafana和prometheus，dashborad是自己的java写的，部署用了tomcat。看起来整的还挺多的。。。。。。&lt;/p&gt;
&lt;p&gt;吐槽到此为止，进入正题。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入它的/opt/manager目录，读取cloudchef-rest.conf文件&lt;/li&gt;
&lt;li&gt;里面的mysql的用户名和密码是明文的，哦哦，太好了&lt;/li&gt;
&lt;li&gt;直接mysql -uaccount -p进入数据库&lt;/li&gt;
&lt;li&gt;凭经验直接打开SmartCMP数据库&lt;/li&gt;
&lt;li&gt;show tables; 里面有一个network_ip_address表；&lt;/li&gt;
&lt;li&gt;show columns in network_ip_address;
+---------------------+---------------+------+-----+---------+-------+
| Field               | Type          | Null | Key | Default | Extra |
+---------------------+---------------+------+-----+---------+-------+
| id                  | varchar(64)   | NO   | PRI | NULL    |       |
| created_by          | varchar(64)   | NO   |     | NULL    |       |
| created_at          | datetime(6)   | NO   |     | NULL    |       |
| deleted             | bit(1)        | NO   |     | NULL    |       |
| deleted_timestamp   | bigint(20)    | NO   |     | NULL    |       |
| exts                | varchar(1024) | NO   |     | NULL    |       |
| lock_version        | bigint(20)    | NO   |     | NULL    |       |
| updated_by          | varchar(64)   | NO   |     | NULL    |       |
| updated_at          | datetime(6)   | NO   |     | NULL    |       |
| tenant_id           | varchar(64)   | NO   |     | NULL    |       |
| deployment_id       | varchar(64)   | YES  |     | NULL    |       |
| vm_external_id      | varchar(512)  | YES  |     | NULL    |       |
| ip_address          | varchar(32)   | NO   |     | NULL    |       |
| port_name           | varchar(256)  | YES  |     | NULL    |       |
| status              | varchar(16)   | YES  |     | NULL    |       |
| vm_name             | varchar(512)  | YES  |     | NULL    |       |
| network_ip_range_id | varchar(64)   | YES  | MUL | NULL    |       |
| recycled_at         | datetime(6)   | YES  |     | NULL    |       |
| epg_name            | varchar(128)  | YES  |     | NULL    |       |
| network_profile_id  | varchar(128)  | YES  |     | NULL    |       |
| description         | varchar(1024) | YES  |     | NULL    |       |
| cooldown_at         | datetime(6)   | YES  |     | NULL    |       |
+---------------------+---------------+------+-----+---------+-------+&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;找一个没有使用过的ip地址select下看看，发现,
| id                                   | created_by | created_at                 | deleted | deleted_timestamp | exts | lock_version | updated_by | updated_at                 | tenant_id | deployment_id | vm_external_id | ip_address   | port_name | status    | vm_name | network_ip_range_id                  | recycled_at | epg_name | network_profile_id                   | description | cooldown_at |
| 0ec505ff-4dc2-4e6c-ba60-26bee8066e9d | sysadmin   | 2019-10-21 09:59:17.128000 |         |                 0 | {}   |            1 | sysadmin   | 2019-10-21 09:59:17.238000 | default   | NULL          | NULL           | 10.214.14.90 | NULL      | Available | NULL    | 5919ff6a-5a49-48ca-ba06-14b836885538 | NULL        | NULL     | 708b8305-aa0d-4ce9-b912-b9712d4b20b6 | NULL        | NULL        |&lt;/p&gt;
&lt;p&gt;找个没有用过的ip，select下看看，这里的updated_by: ce0858e2-14f7-4588-9150-dc13c61ab310 (这个是我的id号)。&lt;/p&gt;
&lt;p&gt;| 43be24d5-93fc-4245-b9f8-357828d68d5f | sysadmin   | 2019-10-21 09:59:17.124000 |         |                 0 | {}   |            2 | ce0858e2-14f7-4588-9150-dc13c61ab310 | 2020-11-30 16:44:18.340000 | default   | NULL          | NULL           | 10.214.14.71 | NULL      | Occupied | demo demo | 5919ff6a-5a49-48ca-ba06-14b836885538 | NULL        | NULL     | 708b8305-aa0d-4ce9-b912-b9712d4b20b6 | NULL        | NULL        |&lt;/p&gt;
&lt;p&gt;那就明显了，只要更新需要更新的，以及自己想要更新的数据段就好了。&lt;/p&gt;
&lt;p&gt;更新语句如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update network_ip_address set lock_version=2,updated_by=&quot;ce0858e2-14f7-4588-9150-dc13c61ab310&quot;,updated_at=&quot;2021-01-06 16:44:18.340000&quot;,status=&quot;Occupied&quot;,vm_name=&quot;just a test&quot; where ip_address=&quot;10.214.14.129&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;刷新下web就能看到，这个地址被标记为占用了。&lt;/p&gt;
&lt;p&gt;为了能够给出可以使用的前十个地址，可以这么查询一下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select ip_address from network_ip_address where status=&quot;Available&quot; order by created_at limit 10;

+--------------+
| ip_address   |
+--------------+
| 10.214.14.77 |
| 10.214.14.78 |
| 10.214.14.81 |
| 10.214.14.79 |
| 10.214.14.84 |
| 10.214.14.82 |
| 10.214.14.85 |
| 10.214.14.83 |
| 10.214.14.87 |
| 10.214.14.90 |
+--------------+
10 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样脱离web，直接操作数据库感觉好了点。&lt;/p&gt;
&lt;p&gt;重要的是，这样，做个前端的web，用户想要自己申请ip可以自己去做。&lt;/p&gt;
&lt;p&gt;这样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当一个虚拟机从一个vlan迁移到这个测试vlan的时候，用户自己去申请ip&lt;/li&gt;
&lt;li&gt;用govc工具，直接将这个ip绑定到对应的虚拟机&lt;/li&gt;
&lt;li&gt;开机&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就不需要用户做什么变ip地址，申请ip地址的事情了。&lt;/p&gt;
&lt;p&gt;今天早上就干了个这。。。。。&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;smartcmp这个产品能解决一些问题，但是不是我所设想的，因为它并没有给我带来什么启发的东西。我自己做的web也能实现它的功能，当然仅仅是vmware，没有它的那么全面。&lt;/p&gt;
&lt;p&gt;小型企业用不上，大型企业看不上。对于有钱的行政事业机关可能有用。&lt;/p&gt;
&lt;p&gt;很久没有用sql语句了，基本的语法都忘了。还得search。。。。&lt;/p&gt;
</content:encoded></item><item><title>vCenter 7.0u1 更新</title><link>https://dididudu998.github.io/posts/vcenter70u1/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/vcenter70u1/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 05 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;vCenter 7.0 u1 更新后的新功能&lt;/h1&gt;
&lt;p&gt;一直用的powershell脚本来进行跨vCenter的虚拟机迁移。&lt;/p&gt;
&lt;p&gt;在脚本中比较容易进行专门的设定，比如迁移前，去掉ISO的挂载，对原VM进行clone，然后移动这个clone的VM到另外vCenter的某个host，某个datastore，然后挂载某个虚拟网卡等等。&lt;/p&gt;
&lt;p&gt;这大概两年的运行，都比较好。也是效率的体现。&lt;/p&gt;
&lt;p&gt;今天更新了vCenter 7.0u1后，这个跨vCenter进行VM迁移已经集成到迁移工具中了。&lt;/p&gt;
&lt;p&gt;VMware提供的这个站点也提供了GUI工具。&lt;/p&gt;
&lt;p&gt;https://flings.vmware.com/cross-vcenter-workload-migration-utility&lt;/p&gt;
&lt;p&gt;下载下来看了下，和我当时想要提供的后台为powershell，前台为webpage的界面类似，但是我不提供更多的选项，只提供移动操作。&lt;/p&gt;
&lt;p&gt;这个java工具用起来也不错。&lt;/p&gt;
&lt;p&gt;用的时候这么干：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;java -jar -Dserver.port=8888 xvm-3.1.jar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在浏览器输入https://localhost:8888就可以了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/across.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;新的环境需要注册vCenter，注册后，就可以进行migrate的工作。&lt;/p&gt;
&lt;p&gt;因为环境的特定性，我还是觉得我的powershell的函数比较方便。&lt;/p&gt;
</content:encoded></item><item><title>跨vCenter 移动VM报“DataCenterMismatchArgument to Object”的问题</title><link>https://dididudu998.github.io/posts/%E8%B7%A8vcenter%E8%BF%81%E7%A7%BB%E7%9A%84%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%B7%A8vcenter%E8%BF%81%E7%A7%BB%E7%9A%84%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/</guid><pubDate>Thu, 17 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;跨vCenter移动vm出现“datacentermismatchargument to object&quot;的问题&lt;/h1&gt;
&lt;p&gt;应该是前天做虚拟机迁移的时候用自己以前的迁移脚本，出现了这个问题。在想，是不是因为不同vCenter的版本导致的。源vCenter是6.7，目标vCenter是7.0.感觉如果要是这个原因，那就麻烦了。&lt;/p&gt;
&lt;p&gt;又想着升级6.7的vCenter到7.0.但是问题又来了，6.7的vCenter上面乱七八糟，用VMware的迁移升级工具，报超时。也就是没法用工具迁移。&lt;/p&gt;
&lt;p&gt;昨天想了这个方案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;备份6.7的数据库&lt;/li&gt;
&lt;li&gt;建一个新的6.7的vCenter&lt;/li&gt;
&lt;li&gt;还原数据库到这个新的vCenter&lt;/li&gt;
&lt;li&gt;迁移这个新的vCenter到7.0&lt;/li&gt;
&lt;li&gt;断开连接到旧的6.7的vCenter的esxi主机&lt;/li&gt;
&lt;li&gt;在新的vCenter 7上面连接这些esxi主机&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;感觉是可以实现，但是这个月没时间来做这个操作了。明年1月再说。&lt;/p&gt;
&lt;p&gt;回到这个datacentermismatchargument的问题。&lt;/p&gt;
&lt;p&gt;网上搜了一下，各种说法都有，但是看不出有什么借鉴的，因为配置了没用。&lt;/p&gt;
&lt;p&gt;到了昨天下午，试着clone了一个VM，再用脚本迁移，成了。。。。。&lt;/p&gt;
&lt;p&gt;调查了一下问题，看到成了的VM的数据是存在标准的DATASTORE中的，而不成的是存在存储数据集群的。&lt;/p&gt;
&lt;p&gt;我当时为了管理的方便，做了几个存储数据集群。&lt;/p&gt;
&lt;p&gt;将移动报错的VM迁移到标准的数据存储后，再用脚本进行移动，成功。&lt;/p&gt;
&lt;p&gt;接着尝试了将另外存在标准数据存储的vm移动到存储数据集群中，再进行移动，也是成功的。莫名了。。。。。&lt;/p&gt;
&lt;p&gt;到底是什么原因导致的报错啊？&lt;/p&gt;
&lt;p&gt;不是因为vCenter的版本的原因。也不全是VM存储的方式的原因。也不是VM的版本的原因。。。&lt;/p&gt;
&lt;p&gt;但是可以说明的是，我只要做了几次VM在当前vCenter的存储迁移后，就可以进行跨vCenter的迁移。&lt;/p&gt;
&lt;p&gt;现在静不下来看vmware的api文档，权且这样吧。无非就是多迁移几次存储。&lt;/p&gt;
&lt;p&gt;---2020-12-17 11:29 AM 补充&lt;/p&gt;
&lt;p&gt;看了下API文档，有这样的说法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Managed Object Reference
To interact or modify an entity such as a virtual machine or ESX(i) host, a client application like the vSphere Client or one of the vSphere SDK’s needs to be able to reference a Managed Object from the server side, as you can not access the server side objects directly. This reference encapsulates the properties and operations of the Managed Object and it makes available to the client application. This reference is always guaranteed to be unique and persistent for the lifetime of the object within vSphere.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;代码中包含“datacentermismatchArgument”的部分：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type DatacenterMismatchArgument struct {
	DynamicData

	Entity          ManagedObjectReference  `xml:&quot;entity&quot;`
	InputDatacenter *ManagedObjectReference `xml:&quot;inputDatacenter,omitempty&quot;`
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到其中有这么两个参数，其中收集entity和inputdatacenter，omitempty的信息。&lt;/p&gt;
&lt;p&gt;其中inputdatacenter这个值可以为空。因为&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a field with a tag including the &quot;omitempty&quot; option is omitted
if the field value is empty. The empty values are false, 0, any
nil pointer or interface value, and any array, slice, map, or
string of length zero.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而查看代码又有：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type DynamicData struct {
}

type ManagedObjectReference struct {
	Type  string `xml:&quot;type,attr&quot;`
	Value string `xml:&quot;,chardata&quot;`
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明 ManagedObjectReference是一个类似dict的结构，包括类型和值。&lt;/p&gt;
&lt;p&gt;move-vm的工作描述见下，跨vCenter的情况下，only datastores are supported as storage destinations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alertSet      : @{alert=System.Management.Automation.PSObject[]}
description   : {@{Text=This cmdlet moves a virtual machine to the location that is specified by the Destination or the Datastore 
                parameters. The destination must be a folder, host, cluster, or a resource pool. You can move a virtual machine to 
                a DRS cluster. Moving a virtual machine to the top level of a non-DRS cluster is only possible if the virtual 
                machine is in a resource pool in that cluster. If the virtual machine is outside the non-DRS cluster, you need to 
                specify a virtual machine host in that cluster as destination. When moving virtual machines that are powered on, 
                vMotion is used. You can move storage and compute resources simultaneously. You can move virtual machines between 
                vCenter Server systems of vSphere version 6.0 and later. To specify a server different from the default one, use 
                the Server parameter. When you move a virtual machine from one vCenter Server system to another, only datastores 
                are supported as storage destinations.}}
syntax        : @{syntaxItem=System.Management.Automation.PSObject[]}
parameters    : @{parameter=System.Management.Automation.PSObject[]}
relatedLinks  : @{navigationLink=System.Management.Automation.PSObject[]}
inputTypes    : 
details       : @{verb=Move; name=Move-VM; description=System.Management.Automation.PSObject[]; noun=VM}
examples      : @{example=System.Management.Automation.PSObject[]}
returnValues  : @{returnValue=@{type=@{name=Zero or more relocated VirtualMachine objects}; 
                description=System.Management.Automation.PSObject[]}}
xmlns:maml    : http://schemas.microsoft.com/maml/2004/10
xmlns:command : http://schemas.microsoft.com/maml/dev/command/2004/10
xmlns:dev     : http://schemas.microsoft.com/maml/dev/2004/10
xmlns:MSHelp  : http://msdn.microsoft.com/mshelp
Name          : Move-VM
Category      : Cmdlet
Synopsis      : This cmdlet moves virtual machines to another location.
Component     : 
Role          : 
Functionality : 
PSSnapIn      : 
ModuleName    : VMware.VimAutomation.Core
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;错误输出信息：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;12/17/2020 10:45:40 AM Move-VM  Could not obtain the result of   task                                                  | &apos;/VIServer=vsphere.local\ls3686@10.214.16.218:443/Task=Task-task-4730/&apos;. Task name is                                | &apos;RelocateVM_Task&apos;. The following error occured: Unexpected error occured. Cannot convert type                        | &apos;DatacenterMismatchArgument&apos; to &apos;Object&apos;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;根据错误信息，其中的“RelocateVM_Task&apos;, 在powershell的检查有下面的输出：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$v=get-vm vm1&lt;/li&gt;
&lt;li&gt;$v.ExtensionData.RelocateVM_Task
&lt;blockquote&gt;
&lt;p&gt;OverloadDefinitions
VMware.Vim.ManagedObjectReference RelocateVM_Task(VMware.Vim.VirtualMachineRelocateSpec spec,
System.Nullable[VMware.Vim.VirtualMachineMovePriority] priority)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;这其中有这样的参数“VMware.Vim.VirtualMachineRelocateSpec”&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;研究这个参数&lt;/h2&gt;
&lt;p&gt;继续powershell&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$spec=New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec

Service      : 
Folder       : 
Datastore    : 
DiskMoveType : 
Pool         : 
Host         : 
Disk         : 
Transform    : 
DeviceChange : 
Profile      : 
CryptoSpec   : 
LinkedView   : 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也就是执行relocateVM这个任务需要的参数就是上面的情况。&lt;/p&gt;
&lt;p&gt;这里的每一个类型，都可以用$spec.DataStore这样类似的方式获得说明和参数。&lt;/p&gt;
&lt;p&gt;可以说，move-vm只要上面的参数值是正确的就可以执行。只要vCenter的版本在6.0以上就可以，不在于vCenter之间的版本的差别。&lt;/p&gt;
&lt;h1&gt;综述&lt;/h1&gt;
&lt;p&gt;&amp;lt;b&amp;gt;总结&amp;lt;/b&amp;gt;：最终能够移动的原因还是在于datastore的问题。&lt;/p&gt;
</content:encoded></item><item><title>自定义openvpn客户端的路由</title><link>https://dididudu998.github.io/posts/08-53-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/08-53-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 08 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;自定义openvpn客户端的路由&lt;/h1&gt;
&lt;p&gt;默认openvpn的客户端在连接服务端后，路由都是从服务器的指定接口走的。&lt;/p&gt;
&lt;p&gt;但是如果不想这么做，想要部分目的地址从自己本身的网关走呢？可以参看下面的配置：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;调整自己的客户端上面的profile&lt;/li&gt;
&lt;li&gt;增加下面的语句&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;redirect all default traffic via the VPN&lt;/h1&gt;
&lt;p&gt;redirect-gateway def1&lt;/p&gt;
&lt;h1&gt;redirect the Intranet network 192.168.1/24 via the VPN&lt;/h1&gt;
&lt;p&gt;route 192.168.1.0 255.255.255.0&lt;/p&gt;
&lt;h1&gt;redirect another network to NOT go via the VPN&lt;/h1&gt;
&lt;p&gt;route 10.10.0.0 255.255.255.0 net_gateway&lt;/p&gt;
&lt;h1&gt;redirect a host using a domainname to NOT go via the VPN&lt;/h1&gt;
&lt;p&gt;route www.google.ca 255.255.255.255 net_gateway&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;这样默认走10.10.0.0/24 和www.google.ca都是走自己本地的网关了&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>利用rancher,gitlab,drone,harbor进行集成发布</title><link>https://dididudu998.github.io/posts/%E9%9B%86%E6%88%90%E5%8F%91%E5%B8%83/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E9%9B%86%E6%88%90%E5%8F%91%E5%B8%83/</guid><pubDate>Mon, 30 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;主要是为了将零散的repo集中起来。还有就是可以好好的用下rancher。虽然rancher比起国内的kubesphere显得有点不那么的易用，但是对于基本上对于基础架构一点不懂的team来说部署和操控都是很方便。&lt;/p&gt;
&lt;h1&gt;实现过程&lt;/h1&gt;
&lt;h2&gt;gitlab&lt;/h2&gt;
&lt;p&gt;gitlab是开发人员的唯一接口，开发者将代码推送给gitlab中对应的库就好了。其余的事情由后台的运维人员进行。当然如果开发人员自己写部署的pipeline也是可以的。只是大部分的开发人员不太懂这些，也可能是比较懒。&lt;/p&gt;
&lt;p&gt;安装gitlab的过程按照gitlab的官网文档即可，唯一要注意的是，要开启本地网络的允许hook的请求，否则后面的要进行hook的动作会报错。&lt;/p&gt;
&lt;p&gt;开启的地方是：&lt;/p&gt;
&lt;p&gt;gitlab-&amp;gt;管理中心-&amp;gt;设置-&amp;gt;网络-&amp;gt;外发请求&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/%E5%A4%96%E5%8F%91%E8%AF%B7%E6%B1%82.jpg&quot; alt=&quot;waifaqingqiu&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;安装Harbor&lt;/h2&gt;
&lt;p&gt;根据官方文档安装即可。这里要说明的是可以创建一个用户，添加这个用户到对应的项目中作为项目管理员，这个用户的权利比较大，可以进行image的更新和删除的工作。该账号也可以用于下面的drone的pipeline中将生成的docker image推送到harbor。这样比较简单，但是基于安全考虑，可以做不同的设定。&lt;/p&gt;
&lt;p&gt;harbor如果没有什么特别的原因还是启用SSL的访问方式。&lt;/p&gt;
&lt;h2&gt;创建gitlab和drone的关联&lt;/h2&gt;
&lt;p&gt;我这里直接使用的是gitlab的root用户。&lt;/p&gt;
&lt;p&gt;在用户设置中，选择应用。 在名称中输入drone，在redirect URI中输入drone的访问页面。&lt;/p&gt;
&lt;p&gt;这里我用的是http的方式，回调地址为 http://drone.mydomain.cn/login&lt;/p&gt;
&lt;p&gt;对于该应用的范围，我这里除了写库，写registry外，全部勾选了。&lt;/p&gt;
&lt;p&gt;然后保存应用后，就会有app id和password两个key出来。&lt;/p&gt;
&lt;p&gt;还要再创建一个共享key: openssl rand -hex 16&lt;/p&gt;
&lt;h2&gt;安装drone 和 drone runner&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;安装drone&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根据官方文档安装即可: https://docs.drone.io/server/provider/gitlab/&lt;/p&gt;
&lt;p&gt;这里的client id就是上面生成的app id，client secret就是上面的password，rpc secret就是用openssl生成的随机字符。&lt;/p&gt;
&lt;p&gt;要说明的是这个里面的server_host要和proto对应起来，我这里都是http的，所以server protol是http，然后我的host记录是drone.mydomain.cn.&lt;/p&gt;
&lt;p&gt;我试着用https反代的方式来添入这个server host，但是在部署的时候提示错误。也没有继续研究下去。使用https的方式后面再看。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run \
  --volume=/var/lib/drone:/data \
  --env=DRONE_GITLAB_SERVER=https://gitlab.mydomain.com \
  --env=DRONE_GITLAB_CLIENT_ID={{DRONE_GITLAB_CLIENT_ID}} \
  --env=DRONE_GITLAB_CLIENT_SECRET={{DRONE_GITLAB_CLIENT_SECRET}} \
  --env=DRONE_RPC_SECRET={{DRONE_RPC_SECRET}} \
  --env=DRONE_SERVER_HOST=drone.mydomain.cn \
  --env=DRONE_SERVER_PROTO=http \
  --publish=80:80 \
  --publish=443:443 \
  --restart=always \
  --detach=true \
  --name=drone \
  drone/drone:1

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装drone runner&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;docker run -d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e DRONE_RPC_PROTO=http \
  -e DRONE_RPC_HOST=drone.mydomain.cn \
  -e DRONE_RPC_SECRET=c35215163c269b40e43dc2ded7a7e602 \
  -e DRONE_RUNNER_CAPACITY=2 \
  -e DRONE_RUNNER_NAME=${HOSTNAME} \
  -p 3000:3000 \
  --restart always \
  --name runner \
  drone/drone-runner-docker:1
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试gitlab和drone的互通性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;访问http://drone.mydomain.cn 页面会跳转到gitlab.mydomain.cn进行验证。验证通过后，会返回drone的页面。如果身份下面有对应的repo存在，则drone中会显示对应的项目。&lt;/p&gt;
&lt;p&gt;为了实现集成，要做的就是在drone中激活对应的项目即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/drone.jpg&quot; alt=&quot;drone sync&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里要说明的是，激活后，需要在项目的repo中创建.drone.yml文件，这个文件是告诉drone当repo被commit后要做什么事情的。这个文件如果没有写好，会导致集成的失败或者不连续。&lt;/p&gt;
&lt;h1&gt;看看.drone.yml的写法&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;创建test项目
&lt;ul&gt;
&lt;li&gt;server.go&lt;/li&gt;
&lt;li&gt;Dockerfile&lt;/li&gt;
&lt;li&gt;.drone.yml&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;server.go&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
    &quot;fmt&quot;
    &quot;log&quot;
    &quot;net/http&quot;
)

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, &quot;Hello World&quot;)
}

func main() {
    http.HandleFunc(&quot;/&quot;, hello)
    if err := http.ListenAndServe(&quot;:8080&quot;, nil); err != nil {
        log.Fatal(err)
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Dockerfile&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;FROM golang
WORKDIR /go
ADD server /go
CMD [&quot;./server&quot;]

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;.drone.yml&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;kind: pipeline
type: docker
name: build
steps:
- name: build-code  #对代码进行build
  image: golang:alpine # 使用的image是golang
  pull: if-not-exists # always never
  commands:
    - go build  -tags netgo server.go # 这里要特别注意，如果缺少-tags netgo的话，在进行pipeline的时候会提示找不到对应的文件或文件夹的错误
- name: build-image #如果build-code阶段没问题，进行镜像的创建
  image: plugins/docker #创建的来源
  settings:
    repo: dockhub.mydomain.cn/library/go-server # 这里是在harbor上创建的项目地址
    registry: dockhub.shnyu.edu.cn # 这里是harbor的访问地址
    use_cache: true
    username:  # 这里的两个变量需要在drone中对应的项目中进行设定，这里的username，password对应harbor中该项目的有镜像push权限的人员的用户名和密码
      from_secret: docker_username
    password:
      from_secret: docker_password
    tags: ${DRONE_BUILD_NUMBER} #这里的这个tag的意思是build的次数
    insecure: true 
trigger:
  branch:
  - master # 当repo是master库的时候
  event:
  - push  #进行push操作

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;进行pipeline&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;确认drone中对应的repo已经激活&lt;/li&gt;
&lt;li&gt;上面的test的repo中的文件都已经commit&lt;/li&gt;
&lt;li&gt;然后在drone中进行sync操作看看，等上10几秒，如果还是没有什么反应，那就在gitlab的repo中，创建个readme.md文件，commit下，激活下drone的执行&lt;/li&gt;
&lt;li&gt;执行的过程就是.drone.yml中的步骤，按照这个步骤执行&lt;/li&gt;
&lt;li&gt;同步和执行默认都是自动的，如果都ok的话，就能得到想要的结果&lt;/li&gt;
&lt;li&gt;如果不ok，设定了报警的邮件话，会收到报警&lt;/li&gt;
&lt;li&gt;下面是执行成功的样子&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/%E6%89%A7%E8%A1%8C%E6%88%90%E5%8A%9F.jpg&quot; alt=&quot;success&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;并且在gitlab中的流水线也能看到同样的结果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/gitlabpipeline.jpg&quot; alt=&quot;gitlabpipeline&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;集成harbor和rancher&lt;/h1&gt;
&lt;p&gt;这个就比较简单了。要做两件事。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;创建密文，用于harbor的登录&lt;/li&gt;
&lt;li&gt;在部署的时候，选择对应的image即可&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;实现过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;首先进入rancher中我们创建的项目，这里我是test-from-gitlab&lt;/li&gt;
&lt;li&gt;在资源选项中选择密文&lt;/li&gt;
&lt;li&gt;在镜像库凭证列表中，选择添加凭证，如下图&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/repoaccount.jpg&quot; alt=&quot;添加镜像库凭证&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;返回资源页面，选择部署服务&lt;/li&gt;
&lt;li&gt;在docker镜像选项中，就可以输入已经推送到harbor的镜像了。例如dockhub.mydomain.cn/library/go-server:9, 必须加上tag&lt;/li&gt;
&lt;li&gt;然后按照需要进行其他的设定后，启动即可。&lt;/li&gt;
&lt;li&gt;启动完成后，就可以在负载均衡页进行dns的设定，设定完成后就可以访问了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/rancher-lb.jpg&quot; alt=&quot;rahcer-lb&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/verify-webpage.jpg&quot; alt=&quot;verify&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;还没有解决的问题&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;如何自动化发布？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当gitlab和drone生成新的docker镜像后，要让rancher马上进行新的镜像的部署，这个可以在drone.yml中增加新的step来实现，我想要写个web页面来实现，这样减少访问rancher页面的问题，减少时间消耗&lt;/p&gt;
&lt;p&gt;初步的想法是读取harbor中的镜像文件信息，如果同一个项目中有新的tag的镜像文件，就进行rancher的部署服务操作，后台创建一个namespace供这个项目使用，随机写入一个新的工作负载名称，镜像选择新的镜像文件，然后启动部署服务。部署服务完成后，添加负载均衡规则，根据Dockerfile文件中的参数，进行expose端口的设定，并创建实际的dns记录。&lt;/p&gt;
&lt;p&gt;整套完成后，发送服务部署完成的提醒邮件给我，然后应该就可以访问新的这个环境页面了。&lt;/p&gt;
</content:encoded></item><item><title>彻底清理docker的信息</title><link>https://dididudu998.github.io/posts/16-04-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/16-04-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 20 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;彻底清理docker信息&lt;/h1&gt;
&lt;p&gt;在进行集群配置的时候，出现了etcd不一致导致的集群无法建立的情况。&lt;/p&gt;
&lt;p&gt;网上搜索了下，发现这个，就是彻底的清理docker信息。&lt;/p&gt;
&lt;p&gt;我自己在找到这个之前只是清理了volume信息，发现没有用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker stop $(docker ps -aq)
 docker system prune -f
 docker volume rm $(docker volume ls -q)
 docker image rm $(docker image ls -q)
 rm -rf /etc/ceph \
        /etc/cni \
        /etc/kubernetes \
        /opt/cni \
        /opt/rke \
        /run/secrets/kubernetes.io \
        /run/calico \
        /run/flannel \
        /var/lib/calico \
        /var/lib/etcd \
        /var/lib/cni \
        /var/lib/kubelet \
        /var/lib/rancher/rke/log \
        /var/log/containers \
        /var/log/pods \
        /var/run/calico
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>docker主机CPU使用爆高的问题</title><link>https://dididudu998.github.io/posts/09-07-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/09-07-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 18 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;docker主机经常的失去管理控制&lt;/h1&gt;
&lt;p&gt;发现CPU使用暴涨，而且管理端提示PLEG错误：Container runtime is down,PLEG is not healthy.&lt;/p&gt;
&lt;p&gt;pleg是pod生命周期事件生成器&quot;pod lifecycle event generator&quot;, 的缩写。pleg会记录Pod生命周期中的各种事件，如容器的启动、终止等，这些事件会写入缓存中，同时他检测到container异常退出时，他会通知kubelet，然后重启创建该container。（https://github.com/kubernetes/kubernetes/issues/45419#issuecomment-304413713）&lt;/p&gt;
&lt;p&gt;pleg在每次迭代检查中会 调用docker ps来检测容器状态的变化，并调用docker Inspect来获取这些容器的详细信息。&lt;/p&gt;
&lt;p&gt;在完成每次迭代之后，它更新一个时间戳。如果时间戳有一段时间没有更新(即3分钟)，则运行状况检查失败。&lt;/p&gt;
&lt;p&gt;搜索后，很多文章提及到是由于CentOS7中的systemd版本的问题。经过检查当前的systemctl --version显示为219.&lt;/p&gt;
&lt;p&gt;着手将一台节点进行升级。&lt;/p&gt;
&lt;p&gt;网络上已经有高人制作了对应的升级repo，参看这里：https://copr.fedorainfracloud.org/coprs/jsynacek/systemd-backports-for-centos-7/&lt;/p&gt;
&lt;p&gt;nstallation Instructions
Make sure to edit /etc/selinux/config and put SELinux to permissive before you update, otherwise your system will not boot anymore!&lt;/p&gt;
&lt;h1&gt;wget https://copr.fedorainfracloud.org/coprs/jsynacek/systemd-backports-for-centos-7/repo/epel-7/jsynacek-systemd-backports-for-centos-7-epel-7.repo -O /etc/yum.repos.d/jsynacek-systemd-centos-7.repo&lt;/h1&gt;
&lt;h1&gt;yum update systemd&lt;/h1&gt;
&lt;p&gt;Reboot.&lt;/p&gt;
&lt;p&gt;但是在update的时候提示这个：Protected multilib versions: systemd-libs-234-0.1.el7.centos.x86_64 != systemd-libs-219-62.el7_6.6.i686&lt;/p&gt;
&lt;p&gt;安装了i686的这个lib，着手删除这个。&lt;/p&gt;
&lt;p&gt;rpm -e systemd-libs-219-62.el7_6.6.i686&lt;/p&gt;
&lt;p&gt;提示有对应的依赖。
删除依赖&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@node1 ~]# rpm -e systemd-libs-219-62.el7_6.6.i686
error: Failed dependencies:
	libsystemd.so.0 is needed by (installed) rdma-core-17.2-3.el7.i686
	libsystemd.so.0(LIBSYSTEMD_209) is needed by (installed) rdma-core-17.2-3.el7.i686
	libudev.so.1 is needed by (installed) rdma-core-17.2-3.el7.i686
	libudev.so.1(LIBUDEV_183) is needed by (installed) rdma-core-17.2-3.el7.i686
[root@node1 ~]# rpm -e  rdma-core-17.2-3.el7.i686
[root@node1 ~]# rpm -e systemd-libs-219-62.el7_6.6.i686
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;继续执行yum update systemd -y，成功，然后重启。&lt;/p&gt;
&lt;p&gt;检查systemctl --version版本变为234.
观察docker运行状态一天看看是否还会存在同样的状态。&lt;/p&gt;
</content:encoded></item><item><title>手动扩容lvm的步骤</title><link>https://dididudu998.github.io/posts/14-35-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/14-35-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 16 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;增加硬盘后扩容LVM&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;
fdisk -l //获取新增硬盘的设备名称

假设新硬盘为/dev/sdb

格式化硬盘： fdisk /dev/sdb
n，创建新的磁盘
一路回车
p，打印新硬盘的信息
w，写入分区表


fdisk -l //获取新的分区后的设备名称
假设为 /dev/sdb1

创建新的pv

pvcreate /dev/sdb1

扫描pv

pvscan //这里获取到VG的名称

假设VG 名称为 cl

将新的pv加入到vg中

vgextend cl /dev/sdb1

显示加入后的vg

vgdiplay //此时获得Free PE/Size中的PE数，假设为430

显示lv的状态

lvdisplay //获取lv的名称，这里为/dev/cl/root

扩展lv

lvresize -l +430 /dev/cl/root

写入lv

当使用resize2fs 出现bad magic的错误的时候，这个是由于文件格式的问题。不是ext4
的格式，而是xfs的格式。

此时用xfs_growfs /dev/cl/root

检查最后的容量

df -h 看看/dev/cl/root所表示的/的大小是不是确实变成增加新硬盘后的容量了。

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>pyenv和新的macOS系统的问题</title><link>https://dididudu998.github.io/posts/13-27-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/13-27-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 13 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;pyenv和新的macOS系统的问题&lt;/h1&gt;
&lt;p&gt;在更新了macOS到新的big sur测试版本后，想要安装新版本的python。会提示错误。
错误1是说c编译器不支持新的python版本。当在developer.apple.com上下载了新的xcode的commandline安装后，此时更新到clang的v12版本。再进行安装的时候会提示pip文件问题。&lt;/p&gt;
&lt;p&gt;在pyenv的github上面搜到有人提供这样的脚本来进行安装，看了下，这里面的依赖我都是有的。照着做了下，确实是可以用了。厉害。&lt;/p&gt;
&lt;p&gt;脚本的内容见下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
echo &quot;Installing Dependencies&quot;
brew install zlib
brew install sqlite
brew install bzip2
brew install libiconv
brew install libzip
echo &quot;Done!&quot;
echo
echo -e &quot;Setting Environment Variables&quot;
export LDFLAGS=&quot;${LDFLAGS} -L/usr/local/opt/zlib/lib&quot;
export CPPFLAGS=&quot;${CPPFLAGS} -I/usr/local/opt/zlib/include&quot;
export LDFLAGS=&quot;${LDFLAGS} -L/usr/local/opt/sqlite/lib&quot;
export CPPFLAGS=&quot;${CPPFLAGS} -I/usr/local/opt/sqlite/include&quot;
export PKG_CONFIG_PATH=&quot;${PKG_CONFIG_PATH} /usr/local/opt/zlib/lib/pkgconfig&quot;
export PKG_CONFIG_PATH=&quot;${PKG_CONFIG_PATH} /usr/local/opt/sqlite/lib/pkgconfig&quot;
echo &quot;Done!&quot;
echo
echo &quot;Installing Python 3.8.5&quot;
pyenv install 3.8.5
echo &quot;Done!&quot;
exit 0


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我更新到了3.10-dev这个版本，然后pyenv migrate 3.8.2 3.10-dev的时候有比较多的lib还没有进行适配。&lt;/p&gt;
&lt;p&gt;没有必要尝鲜的。&lt;/p&gt;
</content:encoded></item><item><title>winscp 连接vcenter appliance复制文件</title><link>https://dididudu998.github.io/posts/winscp%E8%BF%9E%E6%8E%A5vcenter-appliance/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/winscp%E8%BF%9E%E6%8E%A5vcenter-appliance/</guid><pubDate>Mon, 09 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;winscp 连接vcenter appliance复制文件&lt;/h1&gt;
&lt;h2&gt;问题&lt;/h2&gt;
&lt;p&gt;要收集vcenter的调试日志，用connect-viserver 和get-log的方法以及在webclient下导出system log的方式都很慢。&lt;/p&gt;
&lt;p&gt;情急之下，直接ssh到vcenter以及不同的esxi主机上面去取。&lt;/p&gt;
&lt;h2&gt;步骤&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;收集esxi主机日志就登录到那台esxi主机，使用vm-support命令即可，日志会存在存储区里面&lt;/li&gt;
&lt;li&gt;收集vcenter的日志，要登录到vcenter appliance中，用root登录，执行vc-support，结束会报出存放位置
&lt;ul&gt;
&lt;li&gt;日志生成后，使用winscp用sftp的方式连接vcenter appliance的时候会报错，&quot;receive too large packet sftp...&quot;&lt;/li&gt;
&lt;li&gt;参考&amp;lt;a href=&quot;https://www.johnborhek.com/vmware/vmware-vsphere/vmware-vcenter/using-winscp-vmware-vcenter-server-appliance/&quot;&amp;gt;这里&amp;lt;/a&amp;gt;&lt;/li&gt;
&lt;li&gt;调整advance里面的sftp server这个项目为：shell /usr/libexec/sftp-server&lt;/li&gt;
&lt;li&gt;保存，重新连接就可以了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>IOPS的计算问题</title><link>https://dididudu998.github.io/posts/13-21-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/13-21-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 03 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;IOPS的计算&lt;/h1&gt;
&lt;p&gt;转帖来自&amp;lt;a href=&quot;https://www.dell.com/community/%E7%BB%BC%E5%90%88%E8%AE%A8%E8%AE%BA%E5%8C%BA/%E5%A6%82%E4%BD%95%E8%AE%A1%E7%AE%97IOPS/td-p/6824629&quot;&amp;gt;Dell Community&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;IOPS计算方法&lt;/p&gt;
&lt;p&gt;传统磁盘本质上一种机械装置，如FC, SAS, SATA磁盘，转速通常为5400/7200/10K/15K rpm不等。影响磁盘的关键因素是磁盘服务时间，即磁盘完成一个I/O请求所花费的时间，它由寻道时间、旋转延迟和数据传输时间三部分构成。&lt;/p&gt;
&lt;p&gt;寻道时间Tseek是指将读写磁头移动至正确的磁道上所需要的时间。寻道时间越短，I/O操作越快，目前磁盘的平均寻道时间一般在3－15ms。&lt;/p&gt;
&lt;p&gt;旋转延迟Trotation是指盘片旋转将请求数据所在扇区移至读写磁头下方所需要的时间。旋转延迟取决于磁盘转速，通常使用磁盘旋转一周所需时间的1/2表示。比如，7200rpm的磁盘平均旋转延迟大约为60*1000/7200/2 = 4.17ms，而转速为15000 rpm的磁盘其平均旋转延迟约为2ms。&lt;/p&gt;
&lt;p&gt;数据传输时间Ttransfer是指完成传输所请求的数据所需要的时间，它取决于数据传输率，其值等于数据大小除以数据传输率。目前IDE/ATA能达到133MB/s，SATAII可达到300MB/s的接口数据传输率，数据传输时间通常远小于前两部分时间。&lt;/p&gt;
&lt;p&gt;因此，理论上可以计算出磁盘的最大IOPS，即IOPS = 1000 ms/ (Tseek + Troatation)，忽略数据传输时间。假设磁盘平均物理寻道时间为3ms, 磁盘转速为7200,10K,15K rpm，则磁盘IOPS理论最大值分别为，&lt;/p&gt;
&lt;p&gt;IOPS = 1000 / (3 + 60000/7200/2)  = 140&lt;/p&gt;
&lt;p&gt;IOPS = 1000 / (3 + 60000/10000/2) = 167&lt;/p&gt;
&lt;p&gt;IOPS = 1000 / (3 + 60000/15000/2) = 200&lt;/p&gt;
&lt;p&gt;固态硬盘SSD是一种电子装置，避免了传统磁盘在寻道和旋转上的时间花费，存储单元寻址开销大大降低，因此IOPS可以非常高，能够达到数万甚至数十万。实际测量中，IOPS数值会受到很多因素的影响，包括I/O负载特征(读写比例，顺序和随机，工作线程数，队列深度，数据记录大小)、系统配置、操作系统、磁盘驱动等等。因此对比测量磁盘IOPS时，必须在同样的测试基准下进行，即便如何也会产生一定的随机不确定性。通常情况下，IOPS可细分为如下几个指标：&lt;/p&gt;
&lt;p&gt;Toatal IOPS，混合读写和顺序随机I/O负载情况下的磁盘IOPS，这个与实际I/O情况最为相符，大多数应用关注此指标。&lt;/p&gt;
&lt;p&gt;Random Read IOPS，100%随机读负载情况下的IOPS。&lt;/p&gt;
&lt;p&gt;Random Write IOPS，100%随机写负载情况下的IOPS。&lt;/p&gt;
&lt;p&gt;Sequential Read IOPS，100%顺序负载读情况下的IOPS。&lt;/p&gt;
&lt;p&gt;Sequential Write IOPS，100%顺序写负载情况下的IOPS。&lt;/p&gt;
&lt;p&gt;IOPS的测试benchmark工具主要有Iometer, IoZone, FIO等，可以综合用于测试磁盘在不同情形下的IOPS。对于应用系统，需要首先确定数据的负载特征，然后选择合理的IOPS指标进行测量和对比分析，据此选择合适的存储介质和软件系统。&lt;/p&gt;
&lt;p&gt;首先需要知道I/O中读操作(Read)与写操作(Write)所占的百分比。然后通过下列公式，将主机的IOPS需求转换成硬盘实际IOPS负载：
RAID类型	公式
RAID 5和3	Drive IOPS = Read IOPS + 4&lt;em&gt;Write IOPS
RAID 6	Drive IOPS = Read IOPS + 6&lt;/em&gt;Write IOPS
RAID 1和1/0	Drive IOPS = Read IOPS + 2*Write IOPS&lt;/p&gt;
&lt;p&gt;假定4500 IOPS中读/写比是2:1，则不同RAID类型Drive IOPS要求分别如下：&lt;/p&gt;
&lt;p&gt;RAID 1/0: (2/3)&lt;em&gt;4500 + 2&lt;/em&gt;(1/3)*4500 = 6000 IOPS&lt;/p&gt;
&lt;p&gt;RAID 5: (2/3)&lt;em&gt;4500 + 4&lt;/em&gt;(1/3)*4500 = 9000 IOPS&lt;/p&gt;
&lt;p&gt;RAID 6: (2/3)&lt;em&gt;4500 + 6&lt;/em&gt;(1/3)*4500 = 12000 IOPS&lt;/p&gt;
&lt;p&gt;再参照下表中不同类型硬盘单块IOPS参数，得出需要多少块硬盘：&lt;/p&gt;
&lt;p&gt;硬盘类型	IOPS
Fibre Channel 15k rpm	180
SAS 15k rpm	180
Fibre Channel 10k rpm	140
SATA 7.2k rpm	80
SATA 5.4k rpm	40
Flash drive	2500
假定选用FC 15K RPM硬盘，则：&lt;/p&gt;
&lt;p&gt;RAID 1/0: 6000/180 = 34 块&lt;/p&gt;
&lt;p&gt;RAID 5: 9000/180 = 50 块&lt;/p&gt;
&lt;p&gt;RAID 6: 12000/180 = 67 块&lt;/p&gt;
&lt;p&gt;注：实际情况下还需考虑Vault Drivers (共5块)以及Hot Spares (建议每30块硬盘一个)。&lt;/p&gt;
&lt;p&gt;raid5和raid6分别带1份和2份校验（parity）作为数据保护的手段，从而可分别应对最多坏1个盘和2个盘的情况。但是随之而来也有了写(write)性能上一定的降低。这是因为对于raid5上的每个写IO，需要分别读取数据位和校验位，计算后然后再写入数据位和校验位总共4个IO来完成。同理，对于raid6上的每次写IO，需要3+3总共6次IO来完成。这个也就是上述公式里的4&lt;em&gt;Write IOPS （对应raid5）和6&lt;/em&gt;Write IOPS （对应raid6）的意思。&lt;/p&gt;
&lt;p&gt;当然，这个只是指传统意义上的理论算法。就当今的存储系统而言，由于大量写缓存的存在以及系统的其他优化处理，raid5和raid6的写性能并没有想象中的那么差。&lt;/p&gt;
</content:encoded></item><item><title>系统方面的问题</title><link>https://dididudu998.github.io/posts/13-04-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/13-04-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 02 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;系统方面的问题&lt;/h1&gt;
&lt;p&gt;▲ 34 进程和线程之间有什么区别？&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://docs.microsoft.com/en-gb/windows/win32/procthread/about-processes-and-threads?redirectedfrom=MSDN&quot;&amp;gt;Microsoft explains&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority class, minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.&lt;/p&gt;
&lt;p&gt;A thread is the entity within a process that can be scheduled for execution. All threads of a process share its virtual address space and system resources. In addition, each thread maintains exception handlers, a scheduling priority, thread local storage, a unique thread identifier, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread&apos;s set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread&apos;s process. Threads can also have their own security context, which can be used for impersonating clients.&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://www.backblaze.com/blog/whats-the-diff-programs-processes-and-threads/&quot;&amp;gt;backblaze&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;每个进程有自己独立的内存地址，进程之间是隔离的。进程间的数据是不能直接访问的。&lt;/p&gt;
&lt;p&gt;进程之间的切换需要一些时间，包括保存和调入registers（这个是CPU的入口），内存映射，以及其他的资源。&lt;/p&gt;
&lt;p&gt;线程之间是共享内存地址和资源的，所以当某个进程里面的多个线程中的某个出现问题，会影响其他的线程。&lt;/p&gt;
&lt;p&gt;操作系统的这样的管理方式，是为了保证当一个进程出现资源问题或者安全问题导致锁死和崩溃的时候，其他的进程不会受到影响，保证整体。&lt;/p&gt;
&lt;p&gt;当一个进程启动的时候，操作系统会分配内存和其他的资源。进程中的线程会共享这些分配的内存和资源。如果单线程的进程，那么这个线程就是进程本身。&lt;/p&gt;
&lt;p&gt;▲ 29 进程间有哪些通信方式？&lt;/p&gt;
&lt;p&gt;进程通的目的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将数据从一个进程发送到另一个进程的，进行数据传输&lt;/li&gt;
&lt;li&gt;多个进程想要操作共享数据&lt;/li&gt;
&lt;li&gt;一个进程向另外一个或者一组进程发送消息，或者通知某个事件&lt;/li&gt;
&lt;li&gt;多个进程之间共享同样的资源。需要锁和同步机制&lt;/li&gt;
&lt;li&gt;进程控制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;linux可用的通信方式包括：&lt;/p&gt;
&lt;p&gt;网上这里有位仁兄给了个总结，看这里&amp;lt;a href=&quot;https://www.jianshu.com/p/c1015f5ffa74&quot;&amp;gt;TyiMan&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;管道&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;管道的实质是一个内核缓冲区，进程以先进先出的方式从缓冲区存取数据，管道一端的进程顺序的将数据写入缓冲区，另一端的进程则顺序的读出数据。
该缓冲区可以看做是一个循环队列，读和写的位置都是自动增长的，不能随意改变，一个数据只能被读一次，读出来以后在缓冲区就不复存在了。
当缓冲区读空或者写满时，有一定的规则控制相应的读进程或者写进程进入等待队列，当空的缓冲区有新数据写入或者满的缓冲区有数据读出来时，就唤醒等待队列中的进程继续读写。&lt;/p&gt;
&lt;p&gt;作者：TyiMan
链接：https://www.jianshu.com/p/c1015f5ffa74
来源：简书
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。&lt;/p&gt;
&lt;p&gt;流管道去除了半双工限制，可以双向传输。&lt;/p&gt;
&lt;p&gt;有名管道可以允许无亲缘关系的进程之间通信。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;信号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;消息队列&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消息队列是消息的链接表&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;共享内存&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;信号量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;套接字&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可用于不同的机器之间的进程的通信。&lt;/p&gt;
&lt;p&gt;各种通信方式的比较和优缺点&lt;/p&gt;
&lt;p&gt;管道：速度慢，容量有限，只有父子进程能通讯&lt;/p&gt;
&lt;p&gt;FIFO：任何进程间都能通讯，但速度慢&lt;/p&gt;
&lt;p&gt;消息队列：容量受到系统限制，且要注意第一次读的时候，要考虑上一次没有读完数据的问题&lt;/p&gt;
&lt;p&gt;信号量：不能传递复杂消息，只能用来同步&lt;/p&gt;
&lt;p&gt;共享内存区：能够很容易控制容量，速度快，但要保持同步，比如一个进程在写的时候，另一个进程要注意读写的问题，相当于线程中的线程安全，当然，共享内存区同样可以用作线程间通讯，不过没这个必要，线程间本来就已经共享了同一进程内的一块内存。&lt;/p&gt;
&lt;p&gt;▲ 27 简述 socket 中 select 与 epoll 的使用场景以及区别，epoll 中水平触发以及边缘触发有什么不同？&lt;/p&gt;
&lt;p&gt;socket的目的是设计并发的网络程序。&lt;/p&gt;
&lt;p&gt;select的设计是这样的：当有I/O事件来的时候，select通知应用程序有事件了需要去处理，而应用程序必须轮询所有的FD集合，测试每个FD是否有事件发生，并处理事件。&lt;/p&gt;
&lt;p&gt;epoll不仅会告诉应用程序有I/O需要处理，还会告诉应用程序相关的信息，这些信息是应用程序填充的，因此应用程序可以直接定位到事件，而不需要遍历FD集合。&lt;/p&gt;
&lt;p&gt;select模型是对每隔进程的文件描述符进行管理，文件描述符由FD_SETSIZE设置，默认1024/2048，虽然可以修改，让select的最大并发数变大，但是由于select每次的调用都是扫描所有的FD的集合，并发变大，导致扫描的时间就变长，最糟糕的情况就是发生拥堵和超时。&lt;/p&gt;
&lt;p&gt;select采取内存拷贝的方法，就是每次调用select，都需要把FD的集合从用户态拷贝到内核态。&lt;/p&gt;
&lt;p&gt;epoll没有最大并发连接数的限制，一般来说和系统的内存有关系，内存越大可以打开的文件的数目就越大，可以看/proc/sys/fs/file-max，1G内存的机器可以打开10万左右的连接。&lt;/p&gt;
&lt;p&gt;epoll只管理活动的连接，而不是所有的连接。&lt;/p&gt;
&lt;p&gt;epoll使用共享内存，而不需要进行内存拷贝。&lt;/p&gt;
&lt;p&gt;▲ 26 Linux 进程调度中有哪些常见算法以及策略？&lt;/p&gt;
&lt;p&gt;参看这里&amp;lt;a href=&quot;https://blog.csdn.net/gatieme/article/details/51699889&quot;&amp;gt;linux进程调度器概述&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;进程调度基本的要求：
低延迟，快速的进程反应时间
最大的系统利用，高的输出&lt;/p&gt;
&lt;p&gt;实时进程调度策略有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先进先出，实时处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A First-In, First-Out real-time process. When the scheduler assigns the CPU to the process, it leaves the process descriptor in its current position in the runqueue list. If no other higher-priority real-time process is runnable, the process will continue to use the CPU as long as it wishes, even if other real-time processes having the same priority are runnable.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;轮询实时处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A Round Robin real-time process. When the scheduler assigns the CPU to the process, it puts the process descriptor at the end of the runqueue list. This policy ensures a fair assignment of CPU time to all SCHED_RR real-time processes that have the same priority.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;其他&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A conventional, time-shared process.
The policy field also encodes a SCHED_YIELD binary flag. This flag is set when the process invokes the sched_ yield( ) system call (a way of voluntarily relinquishing the processor without the need to start an I/O operation or go to sleep. The scheduler puts the process descriptor at the bottom of the runqueue list.&lt;/p&gt;
&lt;p&gt;进程优先级
时间切片&lt;/p&gt;
&lt;p&gt;公平调度算法： 每一个process会收到1/n个处理器时间，这里的n是所有在运行的process&lt;/p&gt;
&lt;p&gt;▲ 18 操作系统如何申请以及管理内存的？
▲ 12 简单介绍进程调度的算法
▲ 11 简述 Linux 系统态与用户态，什么时候会进入系统态？
▲ 11 简述 LRU 算法及其实现方式
▲ 11 线程间有哪些通信方式？
▲ 8 简述同步与异步的区别，阻塞与非阻塞的区别
▲ 8 简述操作系统如何进行内存管理
▲ 7 简述操作系统中的缺页中断
▲ 3 简述操作系统中 malloc 的实现原理
▲ 2 BIO、NIO 有什么区别？怎么判断写文件时 Buffer 已经写满？简述 Linux 的 IO模型
▲ 1 进程空间从高位到低位都有些什么？&lt;/p&gt;
&lt;p&gt;▲ 41 简述 TCP 三次握手以及四次挥手的流程。为什么需要三次握手以及四次挥手？
▲ 32 RestFul 与 RPC 的区别是什么？RestFul 的优点在哪里？
▲ 29 HTTP 与 HTTPS 有哪些区别？
▲ 26 RestFul 是什么？RestFul 请求的 URL 有什么特点？
▲ 23 一次 HTTP 的请求过程中发生了什么？
▲ 19 TCP 与 UDP 在网络协议中的哪一层，他们之间有什么区别？
▲ 18 TCP 中常见的拥塞控制算法有哪些？
▲ 17 TCP 怎么保证可靠传输？
▲ 17 从系统层面上，UDP如何保证尽量可靠？
▲ 8 TCP 的 keepalive 了解吗？说一说它和 http 的 keepalive 的区别？
▲ 8 简述 TCP 滑动窗口以及重传机制
▲ 8 简述 HTTP 1.0，1.1，2.0 的主要区别
▲ 7 简述 TCP 的 TIME_WAIT
▲ 5 HTTP 的方法有哪些？
▲ 4 简述 TCP 协议的延迟 ACK 和累计应答
▲ 1 简述 TCP 的报文头部结构
▲ 1 简述 TCP 半连接发生场景
▲ 1 什么是 SYN flood，如何防止这类攻击？&lt;/p&gt;
</content:encoded></item><item><link>https://dididudu998.github.io/posts/13-systemquestions--record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/13-systemquestions--record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 02 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;系统方面的问题&lt;/h1&gt;
&lt;p&gt;▲ 34 进程和线程之间有什么区别？&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://docs.microsoft.com/en-gb/windows/win32/procthread/about-processes-and-threads?redirectedfrom=MSDN&quot;&amp;gt;Microsoft explains&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority class, minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.&lt;/p&gt;
&lt;p&gt;A thread is the entity within a process that can be scheduled for execution. All threads of a process share its virtual address space and system resources. In addition, each thread maintains exception handlers, a scheduling priority, thread local storage, a unique thread identifier, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread&apos;s set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread&apos;s process. Threads can also have their own security context, which can be used for impersonating clients.&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://www.backblaze.com/blog/whats-the-diff-programs-processes-and-threads/&quot;&amp;gt;backblaze&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;每个进程有自己独立的内存地址，进程之间是隔离的。进程间的数据是不能直接访问的。&lt;/p&gt;
&lt;p&gt;进程之间的切换需要一些时间，包括保存和调入registers（这个是CPU的入口），内存映射，以及其他的资源。&lt;/p&gt;
&lt;p&gt;线程之间是共享内存地址和资源的，所以当某个进程里面的多个线程中的某个出现问题，会影响其他的线程。&lt;/p&gt;
&lt;p&gt;操作系统的这样的管理方式，是为了保证当一个进程出现资源问题或者安全问题导致锁死和崩溃的时候，其他的进程不会受到影响，保证整体。&lt;/p&gt;
&lt;p&gt;当一个进程启动的时候，操作系统会分配内存和其他的资源。进程中的线程会共享这些分配的内存和资源。如果单线程的进程，那么这个线程就是进程本身。&lt;/p&gt;
&lt;p&gt;▲ 29 进程间有哪些通信方式？&lt;/p&gt;
&lt;p&gt;进程通的目的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将数据从一个进程发送到另一个进程的，进行数据传输&lt;/li&gt;
&lt;li&gt;多个进程想要操作共享数据&lt;/li&gt;
&lt;li&gt;一个进程向另外一个或者一组进程发送消息，或者通知某个事件&lt;/li&gt;
&lt;li&gt;多个进程之间共享同样的资源。需要锁和同步机制&lt;/li&gt;
&lt;li&gt;进程控制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;linux可用的通信方式包括：&lt;/p&gt;
&lt;p&gt;网上这里有位仁兄给了个总结，看这里&amp;lt;a href=&quot;https://www.jianshu.com/p/c1015f5ffa74&quot;&amp;gt;TyiMan&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;管道&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;管道的实质是一个内核缓冲区，进程以先进先出的方式从缓冲区存取数据，管道一端的进程顺序的将数据写入缓冲区，另一端的进程则顺序的读出数据。
该缓冲区可以看做是一个循环队列，读和写的位置都是自动增长的，不能随意改变，一个数据只能被读一次，读出来以后在缓冲区就不复存在了。
当缓冲区读空或者写满时，有一定的规则控制相应的读进程或者写进程进入等待队列，当空的缓冲区有新数据写入或者满的缓冲区有数据读出来时，就唤醒等待队列中的进程继续读写。&lt;/p&gt;
&lt;p&gt;作者：TyiMan
链接：https://www.jianshu.com/p/c1015f5ffa74
来源：简书
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。&lt;/p&gt;
&lt;p&gt;流管道去除了半双工限制，可以双向传输。&lt;/p&gt;
&lt;p&gt;有名管道可以允许无亲缘关系的进程之间通信。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;信号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;消息队列&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消息队列是消息的链接表&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;共享内存&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;信号量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;套接字&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可用于不同的机器之间的进程的通信。&lt;/p&gt;
&lt;p&gt;各种通信方式的比较和优缺点&lt;/p&gt;
&lt;p&gt;管道：速度慢，容量有限，只有父子进程能通讯&lt;/p&gt;
&lt;p&gt;FIFO：任何进程间都能通讯，但速度慢&lt;/p&gt;
&lt;p&gt;消息队列：容量受到系统限制，且要注意第一次读的时候，要考虑上一次没有读完数据的问题&lt;/p&gt;
&lt;p&gt;信号量：不能传递复杂消息，只能用来同步&lt;/p&gt;
&lt;p&gt;共享内存区：能够很容易控制容量，速度快，但要保持同步，比如一个进程在写的时候，另一个进程要注意读写的问题，相当于线程中的线程安全，当然，共享内存区同样可以用作线程间通讯，不过没这个必要，线程间本来就已经共享了同一进程内的一块内存。&lt;/p&gt;
&lt;p&gt;▲ 27 简述 socket 中 select 与 epoll 的使用场景以及区别，epoll 中水平触发以及边缘触发有什么不同？&lt;/p&gt;
&lt;p&gt;socket的目的是设计并发的网络程序。&lt;/p&gt;
&lt;p&gt;select的设计是这样的：当有I/O事件来的时候，select通知应用程序有事件了需要去处理，而应用程序必须轮询所有的FD集合，测试每个FD是否有事件发生，并处理事件。&lt;/p&gt;
&lt;p&gt;epoll不仅会告诉应用程序有I/O需要处理，还会告诉应用程序相关的信息，这些信息是应用程序填充的，因此应用程序可以直接定位到事件，而不需要遍历FD集合。&lt;/p&gt;
&lt;p&gt;select模型是对每隔进程的文件描述符进行管理，文件描述符由FD_SETSIZE设置，默认1024/2048，虽然可以修改，让select的最大并发数变大，但是由于select每次的调用都是扫描所有的FD的集合，并发变大，导致扫描的时间就变长，最糟糕的情况就是发生拥堵和超时。&lt;/p&gt;
&lt;p&gt;select采取内存拷贝的方法，就是每次调用select，都需要把FD的集合从用户态拷贝到内核态。&lt;/p&gt;
&lt;p&gt;epoll没有最大并发连接数的限制，一般来说和系统的内存有关系，内存越大可以打开的文件的数目就越大，可以看/proc/sys/fs/file-max，1G内存的机器可以打开10万左右的连接。&lt;/p&gt;
&lt;p&gt;epoll只管理活动的连接，而不是所有的连接。&lt;/p&gt;
&lt;p&gt;epoll使用共享内存，而不需要进行内存拷贝。&lt;/p&gt;
&lt;p&gt;▲ 26 Linux 进程调度中有哪些常见算法以及策略？&lt;/p&gt;
&lt;p&gt;参看这里&amp;lt;a href=&quot;https://blog.csdn.net/gatieme/article/details/51699889&quot;&amp;gt;linux进程调度器概述&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;进程调度基本的要求：
低延迟，快速的进程反应时间
最大的系统利用，高的输出&lt;/p&gt;
&lt;p&gt;实时进程调度策略有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先进先出，实时处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A First-In, First-Out real-time process. When the scheduler assigns the CPU to the process, it leaves the process descriptor in its current position in the runqueue list. If no other higher-priority real-time process is runnable, the process will continue to use the CPU as long as it wishes, even if other real-time processes having the same priority are runnable.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;轮询实时处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A Round Robin real-time process. When the scheduler assigns the CPU to the process, it puts the process descriptor at the end of the runqueue list. This policy ensures a fair assignment of CPU time to all SCHED_RR real-time processes that have the same priority.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;其他&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A conventional, time-shared process.
The policy field also encodes a SCHED_YIELD binary flag. This flag is set when the process invokes the sched_ yield( ) system call (a way of voluntarily relinquishing the processor without the need to start an I/O operation or go to sleep. The scheduler puts the process descriptor at the bottom of the runqueue list.&lt;/p&gt;
&lt;p&gt;进程优先级
时间切片&lt;/p&gt;
&lt;p&gt;公平调度算法： 每一个process会收到1/n个处理器时间，这里的n是所有在运行的process&lt;/p&gt;
&lt;p&gt;▲ 18 操作系统如何申请以及管理内存的？
▲ 12 简单介绍进程调度的算法
▲ 11 简述 Linux 系统态与用户态，什么时候会进入系统态？
▲ 11 简述 LRU 算法及其实现方式
▲ 11 线程间有哪些通信方式？
▲ 8 简述同步与异步的区别，阻塞与非阻塞的区别
▲ 8 简述操作系统如何进行内存管理
▲ 7 简述操作系统中的缺页中断
▲ 3 简述操作系统中 malloc 的实现原理
▲ 2 BIO、NIO 有什么区别？怎么判断写文件时 Buffer 已经写满？简述 Linux 的 IO模型
▲ 1 进程空间从高位到低位都有些什么？&lt;/p&gt;
&lt;p&gt;▲ 41 简述 TCP 三次握手以及四次挥手的流程。为什么需要三次握手以及四次挥手？
▲ 32 RestFul 与 RPC 的区别是什么？RestFul 的优点在哪里？
▲ 29 HTTP 与 HTTPS 有哪些区别？
▲ 26 RestFul 是什么？RestFul 请求的 URL 有什么特点？
▲ 23 一次 HTTP 的请求过程中发生了什么？
▲ 19 TCP 与 UDP 在网络协议中的哪一层，他们之间有什么区别？
▲ 18 TCP 中常见的拥塞控制算法有哪些？
▲ 17 TCP 怎么保证可靠传输？
▲ 17 从系统层面上，UDP如何保证尽量可靠？
▲ 8 TCP 的 keepalive 了解吗？说一说它和 http 的 keepalive 的区别？
▲ 8 简述 TCP 滑动窗口以及重传机制
▲ 8 简述 HTTP 1.0，1.1，2.0 的主要区别
▲ 7 简述 TCP 的 TIME_WAIT
▲ 5 HTTP 的方法有哪些？
▲ 4 简述 TCP 协议的延迟 ACK 和累计应答
▲ 1 简述 TCP 的报文头部结构
▲ 1 简述 TCP 半连接发生场景
▲ 1 什么是 SYN flood，如何防止这类攻击？&lt;/p&gt;
</content:encoded></item><item><title>openconnect和Duo的双重验证</title><link>https://dididudu998.github.io/posts/16-28-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/16-28-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 28 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;openconnect和Duo的双重验证&lt;/h1&gt;
&lt;p&gt;使用openconenct代替cisco anyconnect是因为它可以记录用户名和密码，不需要每次都输入。&lt;/p&gt;
&lt;p&gt;原来没有双重验证的时候是这样的,其中mmm.txt里面写了登录密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo /usr/local/bin/openconnect --user=myaccount vpnserver --passwd-on-stdin &amp;lt;./mmm.txt  --servercert pin-sha256:Hb6OUS95kA4Wtxbzv3RmA/dOPwTvbI3tjOCjheGres=
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在启用了双重验证后是这样的:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;mypassword\npush&quot; |sudo openconnect -u myaccount vpnserver --servercert pin-sha256:Hb6OUS95kA4Wtxbzv3R/mA/dOPwTvbI3tjOCjheGres=
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加证书的原因是这里的证书出现过不受信任的情况，就加上了。&lt;/p&gt;
&lt;p&gt;用push的原因是这是最方便的，用sms的想想就觉得麻烦。&lt;/p&gt;
&lt;p&gt;暂时就这样吧。&lt;/p&gt;
</content:encoded></item><item><title>扩容lvm碰到的问题</title><link>https://dididudu998.github.io/posts/16-35-record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/16-35-record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 28 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;扩容lvm碰到的问题&lt;/h1&gt;
&lt;p&gt;部署的VMware vRealize提示说DNS的服务器磁盘空间满了。&lt;/p&gt;
&lt;p&gt;感觉不可思议。这服务器是用来给学生DNS查询forward用的，虽然设定了规则，但是也不不至于会空间满啊。&lt;/p&gt;
&lt;p&gt;登录检查，还真是，主要是磁盘怎么才分了4GB，明明给的是100GB啊。&lt;/p&gt;
&lt;p&gt;问题既然出现了，就开始解决。&lt;/p&gt;
&lt;p&gt;用pvdisplay检查发现确实是100GB的空间，而且都已经划分好了。&lt;/p&gt;
&lt;p&gt;用lvdisplay确实是用了4GB。&lt;/p&gt;
&lt;p&gt;那就把没用的用起来吧。&lt;/p&gt;
&lt;p&gt;使用lvextend -L +90GB /dev/ubuntu-vg/ubuntu-lv 提示设备可用空间为0；&lt;/p&gt;
&lt;p&gt;诡异。&lt;/p&gt;
&lt;p&gt;不想那么多了，搜一下。找到这个https://blog.csdn.net/yjk13703623757/article/details/80267647&lt;/p&gt;
&lt;p&gt;照着做一下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; lvresize -A n -L +90GB /dev/ubuntu-vg/ubuntu-lv

 resize2fs -p /dev/ubuntu-vg/ubuntu-lv

 df -h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好了。&lt;/p&gt;
&lt;p&gt;这里的意思是lvresize -A（autoback）n（不需要） -L（扩展）+90GB（增加90GB空间）/dev/....（PV）&lt;/p&gt;
&lt;p&gt;这些本该是最开始就做的，不知道怎么回事变成这样了。。。。&lt;/p&gt;
</content:encoded></item><item><title>整理了下自己常用的alias任务</title><link>https://dididudu998.github.io/posts/%E6%95%B4%E7%90%86%E4%B8%8B%E8%87%AA%E5%B7%B1%E7%9A%84%E5%B8%B8%E7%94%A8alias%E4%BB%BB%E5%8A%A1/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%95%B4%E7%90%86%E4%B8%8B%E8%87%AA%E5%B7%B1%E7%9A%84%E5%B8%B8%E7%94%A8alias%E4%BB%BB%E5%8A%A1/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 21 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;自己的一些快捷任务整理&lt;/h1&gt;
&lt;p&gt;下面都是执行的shell，在crontab -e里面写定时语句即可执行，我一般写成类似这样的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;00 */4 * * * cd /Users/ls3686  &amp;amp;&amp;amp; sh sync-my-project.sh&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;同步目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;echo &quot;starting rsync to github-我自己的项目&quot;
rsync -arvh --progress --exclude=&quot;&lt;em&gt;.git&quot; --exclude=&quot;node_modules&quot; --exclude=&quot;src&quot; --      exclude=&quot;&lt;/em&gt;.jpg&quot; --exclude=&quot;&lt;em&gt;.gif&quot; /Users/ls3686/workspace/learn/自己的项目/&lt;/em&gt; &quot;/Users/ls3686/github-我自己的项目&quot;
echo &quot;rsync to github-我自己的项目 完成!&quot;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;定时更新到我的gitlab&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
 #备份桌面上的我的笔记到加密的压缩文件夹，然后在git  push到我的库去
 #目标文件夹
 backupdir=/Users/ls3686/github-station/
 #原始文件夹
 rootdir=/Users/ls3686/Desktop/我的笔记/
 workspace=/Users/ls3686/workspace/learn/
 #今天到日期
 today=`date +%Y%m%d`
 fourday=`date -v-4d +%Y%m%d`
 threeday=`date -v-3d +%Y%m%d`
 fiveday=`date -v-5d +%Y%m%d`
 twoday=`date -v-2d +%Y%m%d`
 #开始
 echo &apos;开始备份&apos;
 cd $rootdir
 zip -P mypassword &apos;mynotes&apos;-$today.zip *.*
 mv &apos;mynotes&apos;-$today.zip $backupdir
 pushd $backupdir
 rm &apos;mynotes&apos;-$twoday.zip
 rm &apos;mynotes&apos;-$threeday.zip
 rm &apos;mynotes&apos;-$fourday.zip
 rm &apos;mynotes&apos;-$fiveday.zip
 rm &apos;mylearn&apos;-$fourday.zip
 rm &apos;mylearn&apos;-$fiveday.zip
 git add .
 git commit -m $today-&apos;update&apos;
 git push mygit master -f
    ```

- 添加shell的alias
因为喜欢用文本的形式记录平时的一些事情，所以创建了一个template，当我在shell中输入trd的时候就会一个md的模版出来，供我进行记录。模版中提供当前日期，时间，分类等初始信息。并且存在一个可以和gitlab同步的文件夹下面，这样当同步gitlab的时候就会顺便同步它。不会导致混乱和遗失。

- 生成读书笔记的文件

创建了读书笔记的template，然后设定了一个dsbj的alias在profile里面。在terminal中输入dsbj就会要求输入主题，然后将主题添入模版第三行的title项中，再写入第九行的标题栏。
完成后，将这个template重名为当日-主题.md文件，并用vi打开。


```bash
#!/bin/bash
today=`date +%Y-%m-%d-%H-%M`
echo 今天读书笔记想要写什么主题？
read topic
title=&quot;title: &quot;$topic
head=&quot;# &quot;$topic
cp template_dushubiji template_dushubiji0
sed -i &apos;&apos; &quot;3s/.*/$title/&quot; template_dushubiji0
sed -i &apos;&apos; &quot;9s/.*/$head/&quot; template_dushubiji0
mv template_dushubiji0 $today-$topic.md &amp;amp;&amp;amp; vi /Users/ls3686/mynotes/我的笔记/读书笔记/$today-$topic.md
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>修复不能登录的SQL Server账户</title><link>https://dididudu998.github.io/posts/record/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/record/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 20 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;早上收到一封邮件说一直使用的好好的SQL数据库只读账户突然不能使用了。
给了截图报登录4064错误。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;登录服务器，检查该账户的状态，发现是正常的。&lt;/li&gt;
&lt;li&gt;检查SQL的日志，发现从昨晚凌晨3:40分开始，该账户从一台机器不断的登录SQL数据库，但是都是验证失败错误。&lt;/li&gt;
&lt;li&gt;告诉这台机器的使用人，关闭这台不断连接的机器对数据库服务器的连接&lt;/li&gt;
&lt;li&gt;修改该账户的密码和重新设定只读
&lt;ul&gt;
&lt;li&gt;集群模式下，在secondary的机器上修改成功&lt;/li&gt;
&lt;li&gt;但是在primiary机器上面，提示该账户已经存在，无法修改&lt;/li&gt;
&lt;li&gt;怀疑是集群在切换后，导致了这种问题&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;先解决问题&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;use [database]
exec sp_change_users_login &apos;AUTO_FIX&apos;,&apos;username&apos;
go
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的语句是用于修复孤立账户的。
正确的执行后会输出下面的语句：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The row for user  will be fixed by updating its login link to a login already in existence.
The number of orphaned users fixed by updating users was 1.
The number of orphaned users fixed by adding new logins and then updating users was 0.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>在linux中设定一次性的执行任务</title><link>https://dididudu998.github.io/posts/%E5%9C%A8linux%E4%B8%AD%E5%88%A9%E7%94%A8at%E6%89%A7%E8%A1%8C%E4%B8%80%E6%AC%A1%E6%80%A7%E4%BB%BB%E5%8A%A1/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%9C%A8linux%E4%B8%AD%E5%88%A9%E7%94%A8at%E6%89%A7%E8%A1%8C%E4%B8%80%E6%AC%A1%E6%80%A7%E4%BB%BB%E5%8A%A1/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 16 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;有部门联系人说当前的虚拟机的资源不够，要求在晚上十点以后对虚拟机的资源进行扩容。
增加CPU和内存。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;p&gt;检查了下该虚拟机，没有开通CPU和内存的热添加功能。&lt;/p&gt;
&lt;p&gt;先在控制台搞一个计划任务，在晚上10点对该机器做一个快照。&lt;/p&gt;
&lt;p&gt;开始写一个执行脚本。&lt;/p&gt;
&lt;p&gt;开启该虚拟机的CPU和内存的热添加功能，这里又牵出以前的案例，测试了下发现旧的扩展配置属性的方法不能用了。在网上找到个新的，测试通过。&lt;/p&gt;
&lt;p&gt;脚本写好了，要安排个时间执行。
因为是一次性的任务，所以就使用at命令。
我使用的是pwsh，就是linux下的vmware powershell。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pwsh -f ext1.ps1 |at 10:05pm&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;系统会产生一个job。&lt;/p&gt;
&lt;p&gt;可以用atq命令查看。&lt;/p&gt;
&lt;p&gt;对于要取消的任务，可以用atrm 任务号 进行删除。&lt;/p&gt;
</content:encoded></item><item><title>执行java文件编译为jar</title><link>https://dididudu998.github.io/posts/java%E6%96%87%E4%BB%B6%E7%BC%96%E8%AF%91%E4%B8%BAjar/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/java%E6%96%87%E4%BB%B6%E7%BC%96%E8%AF%91%E4%B8%BAjar/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;命令行下将.java文件编译为jar文件&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;创建MANIFEST.MF文件&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Manifest-Version: 1.0
Built-By: mark
Main-Class: reverse_str&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;b&amp;gt;这里的Main-Class可以自己起名&amp;lt;/b&amp;gt;

- java创建class文件

我这里的java文件名为reverse_str.java，创建class用下面的命令：

&amp;gt; javac reverse_str.java

会生成reverse_str.class文件

- 打包MANIFEST和class生成jar

&amp;gt; jar cvfm reverse_str.jar MANIFEST.MF reverse_str.class

这里的reverse_str.jar为要生成的jar文件名。

- 测试jar文件

&amp;gt; java -jar reverse_str.jar&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>golang的生成文件缩减的问题</title><link>https://dididudu998.github.io/posts/golang%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E5%A4%AA%E5%A4%A7%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/golang%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E5%A4%AA%E5%A4%A7%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 25 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;golang的文件太大了，压缩一下，但是还是大啊。。。。&lt;/h1&gt;
&lt;p&gt;golang方便的是可以生成针对不同平台的编译后的可执行文件，但是问题是它的编译后的文件确实相比其他的语言来说太大了。&lt;/p&gt;
&lt;p&gt;用了网络上的解决方法：&lt;/p&gt;
&lt;p&gt;这种比我直接go build的大概缩减了30%的大小，从5MB变成3.8MB。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;go build -ldflags “-s -w” -o test -i app.go 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;继续用upx压缩生成的可执行文件，将从3.8MB继续压缩到1.4MB&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;upx test
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>windows 程序调试</title><link>https://dididudu998.github.io/posts/windows%E7%A8%8B%E5%BA%8F%E8%B0%83%E8%AF%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windows%E7%A8%8B%E5%BA%8F%E8%B0%83%E8%AF%95/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 24 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;调试工具&lt;/h1&gt;
&lt;p&gt;除了上专家级的windbg外，微软在windows软件开发工具包中包含有应用程序验证工具。&lt;/p&gt;
&lt;p&gt;下面是微软对于该工具的介绍，可以作为比较容易使用的先用用获取对应的报告。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;应用程序验证工具 ( # A0) 是用户模式应用程序的 动态验证 工具。 此工具在应用程序运行时监视应用程序操作，使应用程序成为各种强调和测试，并生成有关应用程序执行或设计中潜在错误的报告。
应用程序验证工具可以检测所有不基于托管代码（包括用户模式驱动程序）的用户模式应用程序中的错误。 它会发现在标准应用程序测试或驱动程序测试过程中可能难以检测到的细微编程错误。
您可以单独使用应用程序验证工具或与用户模式调试器一起使用。 此工具在 Microsoft Windows XP 和更高版本的 Windows 上运行。 当前用户必须是计算机上 Administrators 组的成员。
应用程序验证工具包含在 Windows 软件开发工具包 (SDK) 中.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;基本的windbg指令&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;!cpuinfo:获得CPU信息&lt;/li&gt;
&lt;li&gt;!analyze -v:让windbg自动分析原因&lt;/li&gt;
&lt;li&gt;!pcr 0 或者!pcr 1:分别观察不同的处理器控制区，这个区是操作系统给多核CPU用来进行id和线程区分的内存空间，一般一个cpu分两个内存页8KB大小。&lt;/li&gt;
&lt;li&gt;!locks:寻找可能存在的内核死锁对象&lt;/li&gt;
&lt;li&gt;.ecxr:读取用户态的转储文件&lt;/li&gt;
&lt;li&gt;.thread 线程地址:这个可以直接观察对应的线程&lt;/li&gt;
&lt;li&gt;kn,kvn:栈回顾/详细栈回顾，这个可以获得执行的函数&lt;/li&gt;
&lt;li&gt;!drvobj 驱动名:这个可以获取对应驱动的更多信息，获得驱动的驱动对象地址，也就是这个设备的实例。&lt;/li&gt;
&lt;li&gt;!devstack 驱动对象地址:可以观察到该设备栈的信息。&lt;/li&gt;
&lt;li&gt;!devnode 0 1:显示系统中所有设备的设备树，可以在这里搜索驱动名&lt;/li&gt;
&lt;li&gt;uf 函数: 可以反汇编对应的函数&lt;/li&gt;
&lt;li&gt;dd 基地址+8 l1:这个可以获取寄存器的线性地址。一般EBP+8是第一个参数&lt;/li&gt;
&lt;li&gt;!vtop 0 线性地址: 这个可以通过线性地址找到对应的物理地址&lt;/li&gt;
&lt;li&gt;!arbiter 2:可以显示系统中物理地址的分配情况，通过物理地址就可以看到所分配的地址区间对应的硬件&lt;/li&gt;
&lt;li&gt;!error 地址:可以获取该地址所对应的错误码信息&lt;/li&gt;
&lt;li&gt;p:单步调试&lt;/li&gt;
&lt;li&gt;lm vm 模块名:用来显示详细的模块信息&lt;/li&gt;
&lt;li&gt;!cs:获取线程的所有关键帧&lt;/li&gt;
&lt;li&gt;!address:获取内存地址信息&lt;/li&gt;
&lt;li&gt;!heap -a:获取程序的堆信息，这个可以获得可执行程序的内存基地址&lt;/li&gt;
&lt;li&gt;dpu 内存地址 L800:获取内存地址内的unicode字符&lt;/li&gt;
&lt;li&gt;s -u 内存地址 L800 “string”: 搜索在内存地址的空间内是否包含有对应的string&lt;/li&gt;
&lt;li&gt;~:显示线程&lt;/li&gt;
&lt;li&gt;!do 内存地址: dumpobject 出对应的内存地址对象&lt;/li&gt;
&lt;li&gt;.writemem 内存区间 c:\dump.txt :从内存区间内dump出unicode的字符写入dump.txt文件.这个对于非英文的字符会出现乱码，需要修改头文件来进行修正。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Windows下禁止程序运行</title><link>https://dididudu998.github.io/posts/windows%E4%B8%8B%E7%A6%81%E6%AD%A2%E7%A8%8B%E5%BA%8F%E8%BF%90%E8%A1%8C/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windows%E4%B8%8B%E7%A6%81%E6%AD%A2%E7%A8%8B%E5%BA%8F%E8%BF%90%E8%A1%8C/</guid><description>像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 23 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Windows下禁止程序运行&lt;/h1&gt;
&lt;h2&gt;方法1:使用注册表的方式&lt;/h2&gt;
&lt;p&gt;参见这里：
http://scz.617.cn:8/windows/201703092204.txt&lt;/p&gt;
&lt;p&gt;原理是利用windows的image file execution options(IFEO)注册表，增加对应的键值。&lt;/p&gt;
&lt;p&gt;当操作系统尝试执行一个可执行文件的时候，首先检查该运行程序是否为可执行文件，在windows下面就是PE格式，可移植可执行格式，PE文件必须是Windows下的文件。&lt;/p&gt;
&lt;p&gt;PE是微软Win32环境下的标准文件格式，包括exe，dll，vxd，sys，vdm等。&lt;/p&gt;
&lt;p&gt;PE格式文件的文件头，最上面有DOS MZ header，下来是PE头，这里包含PE装载器需要的重要字段，包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;程序入口点&lt;/li&gt;
&lt;li&gt;文件偏移地址：数组在PE文件中的地址，是文件在磁盘上存放的相对于文件开头的偏移&lt;/li&gt;
&lt;li&gt;虚拟地址&lt;/li&gt;
&lt;li&gt;基地址&lt;/li&gt;
&lt;li&gt;相对虚拟地址&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当可执行文件执行时，操作系统会分配虚拟内存给它，操作系统负责物理内存。用户使用虚拟内存，虚拟内存和物理内存空间存在地址映射关系。&lt;/p&gt;
&lt;p&gt;这种方法不能阻止bat，cmd这样的文件运行。&lt;/p&gt;
&lt;p&gt;比如要阻止notepad.exe的运行：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;reg.exe add &quot;HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe&quot; /v &quot;Debugger&quot; /t REG_SZ /d &quot;d:\dumb.exe&quot; /f&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果是64-bits系统，可能还得多加一条:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;reg.exe add &quot;HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options&amp;lt;executable&amp;gt;&quot; /v &quot;Debugger&quot; /t REG_SZ /d &quot;x:dumb.exe&quot; /f&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;executable&amp;gt;为程序全名，含扩展名，比如calc.exe。
这里的dumb.exe是一个不存在的文件，或者不能使用的文件。&lt;/p&gt;
&lt;h2&gt;方法2:使用windows自带的组策略&lt;/h2&gt;
&lt;p&gt;组策略的方式是比较理想的解决方法。&lt;/p&gt;
&lt;p&gt;windows自带的组策略中关于软件限制的部分提供了多种的限制方式。
有证书，哈希等可以完全满足企业级的需要。&lt;/p&gt;
&lt;p&gt;根据微软的文档，software restriction policies构建是这样的：&lt;/p&gt;
&lt;p&gt;https://docs.microsoft.com/en-us/windows-server/identity/software-restriction-policies/software-restriction-policies-technical-overview&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;software restriction policies API，这个用来创建和配置规则，并且提供查询和处理规则的请求&lt;/li&gt;
&lt;li&gt;管理工具，就是我们用的组策略编辑器&lt;/li&gt;
&lt;li&gt;safer enforcement API，包含两个功能函数，一个是saferidentifylevel，一个是safercomputetokenformlevel。由这两个功能函数来返回最符合的规则和执行规则。&lt;/li&gt;
&lt;li&gt;活动目录和组策略，这个用于windows域环境&lt;/li&gt;
&lt;li&gt;认证码和微软认证的可信APIs，操作系统级别，会被safer enforcecement API实时调用，包括微软的office宏，动态链接库装载器，以及COM+，还包含两个API，ShellExecute，CreateProcess&lt;/li&gt;
&lt;li&gt;事务查看器，event viewer，用来记录软件限制策略所产生的log&lt;/li&gt;
&lt;li&gt;RSoP，用来检查客户端所执行的组策略，用于排错&lt;/li&gt;
&lt;li&gt;software restriction policies 保存在下面的位置：
&lt;ul&gt;
&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer&lt;/li&gt;
&lt;li&gt;HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;微软的文档，关于软件限制是如何工作的：
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc786941(v=ws.10)&lt;/p&gt;
&lt;p&gt;当域级别，父OU级，子OU级都存在限制策略时候，这些策略会同时作用域子OU的计算机对象，操作系统进行这些策略的合并。这些策略会物理的保存在注册表中。&lt;/p&gt;
&lt;p&gt;当用户准备运行可执行文件的时候，软件限制策略的强制API会来检测和当前执行的可执行程序所联系的已有的设定规则，如果没有，则放行。如果存在对应的规则，则不会运行。并进行提示说明。&lt;/p&gt;
&lt;p&gt;这里组策略比方法一高明的一点是，当你尝试用cmd这样的方式，而不是exe这样的方式运行的时候，shellexecute依然会调用软件限制API中的安全限定等级来进行判定，如果存在对应的规则，cmd这样的文件也是不能执行的。&lt;/p&gt;
&lt;h1&gt;关于软链接和硬链接&lt;/h1&gt;
&lt;p&gt;举例：&lt;/p&gt;
&lt;p&gt;创建file1.txt文件，写入test到其中
touch file1.txt
echo “test” &amp;gt;file1.txt&lt;/p&gt;
&lt;p&gt;创建硬链接
ln file1.txt file2.txt
此时cat file2.txt发现和file1.txt的内容是完全一样的，而且inode的位置也是一样的。&lt;/p&gt;
&lt;p&gt;创建软连接
ln -s file1.txt file3.txt&lt;/p&gt;
&lt;p&gt;对file1的权限和内容修改和file2这个硬链接的修改是同样显示的。&lt;/p&gt;
&lt;p&gt;但是如果我们对file1.txt这个开始的文件删除后，会发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;硬链接文件file2.txt依然可以打开原来的内容，保留原来的权限&lt;/li&gt;
&lt;li&gt;软连接文件file3.txt已经不能打开了，显示不存在的文件或者目录&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说硬链接是对同一个物理对象的不同命名，不同的硬链接名称对应同样的物理对象。删除一个硬链接名称并不对物理对象产生影响。
软链接依附于设定的物理对象，物理对象被删除后，软连接没有可依附的对象，会失效。&lt;/p&gt;
</content:encoded></item><item><link>https://dididudu998.github.io/posts/linux%E5%9F%BA%E6%9C%AC/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/linux%E5%9F%BA%E6%9C%AC/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Tue, 22 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;reptyr&lt;/h1&gt;
&lt;p&gt;ubuntu 可以直接利用apt进行安装。&lt;/p&gt;
&lt;p&gt;reptyr  is a utility for taking an existing running program and attaching it to a new terminal. Started a long-running process over ssh, but have to leave and don&apos;t want to  interrupt it?  Just  start  a screen, use reptyr to grab it, and then kill the ssh session and head on home.&lt;/p&gt;
&lt;p&gt;reptyr works by attaching to the target program using ptrace(2), redirecting  relevant  file
descriptors,  and  changing  the program&apos;s controlling terminal (See tty(4)) It is this last
detail that makes reptyr work much better than alternatives such as
retty(1).&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;ALIAS&lt;/h1&gt;
&lt;p&gt;今天在编辑macos的zshrc的时候忘记了``的作用。
创建了一个每天9点01分的计划任务，用来创建一个文件，文件名为: date +%Y-%m-%d&apos;-record.md,
然后在zshrc里面创建alias，
alias trd=&quot;cd /Users/ls3686/my_daily_record &amp;amp;&amp;amp; vi `date +%Y-%m-%d-record.md`&quot;,&lt;/p&gt;
&lt;p&gt;就可以每天用trd来编辑当天的文件了。&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Strace&lt;/h1&gt;
&lt;p&gt;strace -e execve ls -alhc
output:
execve(&quot;/bin/ls&quot;, [&quot;ls&quot;, &quot;-alhc&quot;], 0x7ffc848b1f78 /* 25 vars */) = 0&lt;/p&gt;
&lt;p&gt;In the simplest case strace runs the specified command until it exits.   It  intercepts  and
records the system calls which are called by a process and the signals which are received by
a process.  The name of each system call, its arguments and its return value are printed  on
standard error or to the file specified with the -o option.&lt;/p&gt;
&lt;p&gt;strace  is  a  useful diagnostic, instructional, and debugging tool.  System administrators,
diagnosticians and trouble-shooters will find it invaluable for solving problems  with  pro‐
grams  for which the source is not readily available since they do not need to be recompiled
in order to trace them.  Students, hackers and the overly-curious will  find  that  a  great
deal  can  be learned about a system and its system calls by tracing even ordinary programs.
And programmers will find that since system calls and signals are events that happen at  the
user/kernel  interface,  a  close examination of this boundary is very useful for bug isola‐
tion, sanity checking and attempting to capture race conditions.&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;windows 10 multi rdp session&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/stascorp/rdpwrap/releases&quot;&gt;rdp wrap&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;默认的windows桌面操作系统，rdp的时候只能有一个session，后面尝试登录的session会将前一个强制注销掉，或者要求前一个的批准。
这个工具可以让桌面操作系统提供多达15的远程连接session。&lt;/p&gt;
</content:encoded></item><item><title>检查和删除macOS中的用户</title><link>https://dididudu998.github.io/posts/%E6%A3%80%E6%9F%A5%E5%92%8C%E5%88%A0%E9%99%A4macos%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E5%92%8C%E7%BB%84/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%A3%80%E6%9F%A5%E5%92%8C%E5%88%A0%E9%99%A4macos%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E5%92%8C%E7%BB%84/</guid><pubDate>Sun, 20 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;没意识的，用/etc/passwd看了下当前macOS的用户，发现自己的账户没有，但是有一个cadmin的账户，感觉这个是以前给分电脑的时候做的一个隐藏的账户，用来做管理用的。&lt;/li&gt;
&lt;li&gt;不喜欢有除了我之外的另外的管理员在自己的电脑上面&lt;/li&gt;
&lt;li&gt;开始执行删除&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;列出和我的账户在同一个组的所有账户
&lt;ol&gt;
&lt;li&gt;dscacheutil -q group |grep “myaccountname”&lt;/li&gt;
&lt;li&gt;果然这个cadmin有好几个和我并列&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;检查这个账户的属性： id cadmin&lt;pre&gt;&lt;code&gt;uid=401(cadmin) gid=20(staff) groups=20(staff),702(com.apple.sharepoint.group.2),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),701(com.apple.sharepoint.group.1),703(com.apple.sharepoint.group.3),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),400(com.apple.access_remote_ae)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;删除这个账户
&lt;ol&gt;
&lt;li&gt;sudo dscl . -delete /Users/cadmin&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;检查包含有这个账户的组
&lt;ol&gt;
&lt;li&gt;dscl . -list /groups GroupMembership&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;从对应的组中删除这个账户
&lt;ol&gt;
&lt;li&gt;sudo dscl . -delete /Groups/_appserveradm GroupMembership cadmin&lt;/li&gt;
&lt;li&gt;sudo dscl . -delete /Groups/_appserverusr GroupMembership cadmin&lt;/li&gt;
&lt;li&gt;sudo dscl . -delete /Groups/admin GroupMembership cadmin&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;重新检查组的成员，发现已经没有这个cadmin账户了
&lt;ol&gt;
&lt;li&gt;dscl . -list /groups GroupMembership&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>windbg的使用</title><link>https://dididudu998.github.io/posts/windbg%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/windbg%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><pubDate>Tue, 15 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;windbg的使用&lt;/h1&gt;
&lt;p&gt;这两天在看简单的汇编，想起来很早之前用windows的时候使用的bluescreen分析工具和windbg。
在win10的电脑上安装了下，大概700Mb的样子。配好了symbol，用notepad做下测试。&lt;/p&gt;
&lt;h1&gt;读取notepad内存&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;打开notepad，在里面写上一些话。&lt;/li&gt;
&lt;li&gt;打开windbg x64，attach 到notepad这个进程&lt;/li&gt;
&lt;li&gt;可以有多种方式找到notepad所使用的内存空间
&lt;ol&gt;
&lt;li&gt;!address指令可以找到所有的，这里面有notepad的进程&lt;/li&gt;
&lt;li&gt;lm m notepad，这个指令可以找到notepad所使用的起始的内存地址&lt;/li&gt;
&lt;li&gt;!heap -a，这个指令显示notepad所使用的堆列表&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;以!heap -a为例
&lt;img src=&quot;/images/tupian/heap1.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/li&gt;
&lt;li&gt;看到index1的起始地址为：1febb0a0000&lt;/li&gt;
&lt;li&gt;增加一个偏移量1000，然后进行搜索，s -u 1febb0a0000 L0001000 “wo“
&lt;ol&gt;
&lt;li&gt;结果是这样的:000001fe`bb0a3e00  0077 006f 0020 006c 0065 0020 0067 0065  w.o. .l.e. .g.e.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;du du 000001fe`bb0a3e00
&lt;ol&gt;
&lt;li&gt;结果是这样的：000001fe`bb0a3e00  &quot;wo le ge qu ..你好..o &quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;导出文件
&lt;ol&gt;
&lt;li&gt;.writemem d:\demo2.txt 000001fe`bb0a3e00&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;查看系统崩溃的原因&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;确保windows中打开了当系统崩溃时候生成dump文件的选项，否则系统崩溃蓝屏后没有可分析的文件&lt;/li&gt;
&lt;li&gt;用windbg打开由于蓝屏而产生的dump文件，一般以dmp结尾，在系统文件夹内&lt;/li&gt;
&lt;li&gt;打开后会看到系统的运行时间&lt;/li&gt;
&lt;li&gt;利用!process 0 0，可以查看系统启动了哪些进程&lt;/li&gt;
&lt;li&gt;利用!analyze -v命令，让windbg自动帮忙分析蓝屏的原因，一般会给出停止码，unexpected_kernel_mode_trap。&lt;/li&gt;
&lt;li&gt;根据停止码的信息可以做个简单的判读
&lt;ol&gt;
&lt;li&gt;比如停止码为7f，表示double fault，双重出错，操作系统一般可以纠错或者放弃错误的指令，但是如果出现多次错误，操作系统会将这个标记为“不可解决”的异常，然后启动自我保护措施。&lt;/li&gt;
&lt;li&gt;一般连续的两次页错误会触发7f，连续两次通用保护错误也会触发。但是断点和调试这样的不会。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;根据!analyze -v还能看到可能导致异常的指令，可以根据这个指令往下推理&lt;/li&gt;
&lt;li&gt;执行heap的回溯：k，会看到原始的指令，根据这个指令需要去看程序的源码来定义程序的问题&lt;/li&gt;
&lt;li&gt;要细心的检查windbg给出的警告信息&lt;/li&gt;
&lt;li&gt;获取在蓝屏时候的进程：!process&lt;/li&gt;
&lt;li&gt;利用kvn获取详细的stack信息&lt;/li&gt;
&lt;li&gt;用!pte观察内存地址，用以判断内存地址的有效性&lt;/li&gt;
&lt;li&gt;一般如果发现push信息为导致蓝屏的原因的时候，要查看esp所指向的栈内存，是否栈指针指向了无效的内存或者正在使用的内存。&lt;/li&gt;
&lt;li&gt;因为线程信息中包含栈信息，所以用!thread来检查
&lt;ol&gt;
&lt;li&gt;例如 stack init f6560000 current f655de8c base f6560000 limit f655d000&lt;/li&gt;
&lt;li&gt;这里栈的基地址是f6560000，边界是f655d000，栈是从高地址往低地址排列的，使用的越多，栈指针越接近低地址。直到降到边界。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;使用ln 地址的方式可以找到该地址所对应的符号，也即当前函数的父函数名称。知道了函数名，就可以找到对应的源代码来进行修改。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>firewalld的一些使用场景</title><link>https://dididudu998.github.io/posts/firewall%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/firewall%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF/</guid><pubDate>Thu, 10 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;firewalld的一些使用场景（长期更新）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;开了个数据展现网站，只给自己看，自己的ip是固定的，可以这么做&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --new-zone=mark --permanent
firewall-cmd --reload
firewall-cmd --zone=mark --add-source=192.168.100.23/32 --permanent
firewall-cmd --zone=mark --add-port=5678/tcp --permanent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;检查： firewall-cmd --zone=mark --list-all&lt;/p&gt;
</content:encoded></item><item><title>rancher-k8s-kubesphere</title><link>https://dididudu998.github.io/posts/rancher-k8s-kubesphere/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/rancher-k8s-kubesphere/</guid><pubDate>Tue, 08 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;rancher,k8s,kubesphere&lt;/h1&gt;
&lt;p&gt;因为开发准备使用docker的结构来发布软件，为了满足他们的需求，需要尽快搞一套管理平台给他们用。
原始的基于kubeadm的模式构建感觉比较烦。
这次采用了rancher的方式，会比较方便一点。&lt;/p&gt;
&lt;p&gt;rancher对于我来说比较方便，但是对于使用者来说可能没有kubesphere好用。其实本质都一样，但是各花入各眼，做个kubepsher的ui对他们来说比较好一点。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;4台centos7的机器，其中3台做k8s，1台做rancher的管理机&lt;/li&gt;
&lt;li&gt;按照rancher的需求，我这里关闭了防火墙，将这台rancher的管理机器的公钥拷贝到其他的3台机器&lt;/li&gt;
&lt;li&gt;安装docker&lt;/li&gt;
&lt;li&gt;安装docker的时候最好确认下以后文件的存储位置。默认docker文件存储/var/lib/docker中。&lt;/li&gt;
&lt;li&gt;可以适当的将/var/空间扩容，或者移动docker的默认存储到较大的空间，方便以后使用&lt;/li&gt;
&lt;li&gt;配置管理机的dns&lt;/li&gt;
&lt;li&gt;sudo docker run -d -v /opt/rancher-data:/var/lib/rancher --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher&lt;/li&gt;
&lt;li&gt;rancher安装完毕后，可以直接使用https://dns名称 的方式打开访问界面，设定密码后进入管理界面&lt;/li&gt;
&lt;li&gt;选择创建集群，输入集群名&lt;/li&gt;
&lt;li&gt;选择使用已有的机器，按照需求勾选机器的职能，然后拷贝出现的命令行，在对应的主机上面运行即可。&lt;/li&gt;
&lt;li&gt;等待集群构建完成&lt;/li&gt;
&lt;li&gt;测试创建部署服务，见&lt;a href=&quot;https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/workload/&quot;&gt;这里&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;测试部署ingress和nodeport的两个方式，访问对应的服务&lt;/li&gt;
&lt;li&gt;在全局的界面，能看到kubectl的按钮，这里可以利用kubectl做很多事情&lt;/li&gt;
&lt;li&gt;创建存储类(storageclass),这里使用longhore
&lt;ol&gt;
&lt;li&gt;开始在节点安装必要组件,参见&lt;a href=&quot;https://longhorn.io/docs/1.0.2/deploy/install/#installing-open-iscsi&quot;&gt;这里&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;yum install iscsi-initiator-utils -y&lt;/li&gt;
&lt;li&gt;在k8s部署： kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml&lt;/li&gt;
&lt;li&gt;部署完成后会产生新的longhore的命名空间&lt;/li&gt;
&lt;li&gt;可以通过ingress来映射longhore的web ui访问&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;创建完成后，设定为默认存储类,设定完成后，存储类的默认会出现闪亮的五星标志。这个步骤可以直接在图像界面用鼠标确定。
&lt;ol&gt;
&lt;li&gt;kubectl get storageclass&lt;/li&gt;
&lt;li&gt;kubectl patch storageclass &amp;lt;storage-class-name&amp;gt; -p &apos;{&quot;metadata&quot;: {&quot;annotations&quot;:{&quot;storageclass.kubernetes.io/is-default-class&quot;:&quot;true&quot;}}}&apos;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;开始部署kubesphere&lt;/li&gt;
&lt;li&gt;参看&lt;a href=&quot;https://kubesphere.io/docs/quick-start/minimal-kubesphere-on-k8s/&quot;&gt;这里&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;如果没有默认的存储类，会部署失败。&lt;/li&gt;
&lt;li&gt;部署完成后，将kubesphere对应的命名空间移动到kube-system中。等待所有的pod启动完成。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;下面看图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/longhore.jpg&quot; alt=&quot;longhore&quot; /&gt;
&lt;img src=&quot;/images/tupian/longhore2.jpg&quot; alt=&quot;longhore2&quot; /&gt;
&lt;img src=&quot;/images/tupian/longhore3.jpg&quot; alt=&quot;longhore3&quot; /&gt;
&lt;img src=&quot;/images/tupian/rancher0.jpg&quot; alt=&quot;rancher0&quot; /&gt;
&lt;img src=&quot;/images/tupian/rancher1.jpg&quot; alt=&quot;rancher1&quot; /&gt;
&lt;img src=&quot;/images/tupian/rancher2.jpg&quot; alt=&quot;rancher2&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>esxcli 更新esxi主机</title><link>https://dididudu998.github.io/posts/%E7%94%A8esxcli%E5%BC%BA%E5%88%B6%E6%9B%B4%E6%96%B0vsphere/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8esxcli%E5%BC%BA%E5%88%B6%E6%9B%B4%E6%96%B0vsphere/</guid><pubDate>Tue, 11 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;利用esxcli升级esxi host&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;利用VUM升级是比较方便的，在新的VCSA的版本里面，VUM变更为lifecycle management，通过导入ISO的方式比较方便的进行新的profile和基准的设定&lt;/li&gt;
&lt;li&gt;但是有个问题，就是如果导入的ISO的镜像中不包含对应的驱动的时候，会提示所提供的镜像和硬件不兼容而导致更新失败&lt;/li&gt;
&lt;li&gt;大部分的情况下，vmware在新版本的vsphere的发布时候会削减掉对部分硬件的支持&lt;/li&gt;
&lt;li&gt;利用esxcli的强制更新profile的方式可以实现强制升级，在一定的情况下，这样的升级方式不会对系统产生问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;network firewall ruleset set -e true -r httpClient&lt;/li&gt;
&lt;li&gt;检索对应的ESXi的版本
&lt;ul&gt;
&lt;li&gt;esxcli software sources profile list -d https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml | grep ESXi-6.7.0-2020&lt;/li&gt;
&lt;li&gt;结果如下&lt;pre&gt;&lt;code&gt;ESXi-6.7.0-20200404001-no-tools   VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
ESXi-6.7.0-20200403001-no-tools   VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
ESXi-6.7.0-20200604001-standard   VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
ESXi-6.7.0-20200401001s-no-tools  VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
ESXi-6.7.0-20200403001-standard   VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
ESXi-6.7.0-20200401001s-standard  VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
ESXi-6.7.0-20200404001-standard   VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
ESXi-6.7.0-20200604001-no-tools   VMware, Inc.  PartnerSupported  2020-06-04T02:20:40  2020-06-04T02:20:40
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;选择对应的版本更新（强制更新）
&lt;ul&gt;
&lt;li&gt;加参数 -f 为强制更新。 建议先不加 -f参数，看看输出结果，判断是有那些硬件驱动不兼容&lt;/li&gt;
&lt;li&gt;esxcli software profile update -d https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml -p ESXi-6.7.0-20200604001-standard -f&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;更新完毕后，reboot机器&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>ssh简单密码的审计</title><link>https://dididudu998.github.io/posts/ssh%E5%AE%A1%E8%AE%A1%E5%B7%A5%E5%85%B7/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/ssh%E5%AE%A1%E8%AE%A1%E5%B7%A5%E5%85%B7/</guid><pubDate>Mon, 27 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;关于ssh的审计&lt;/h1&gt;
&lt;p&gt;前阵子在微信群里做了个公告，要求所有人如果在生产环境还没更换默认密码的尽快修改密码。
说是说了，但是有没有人执行是另外的一回事，所以得检查下效果怎么样。&lt;/p&gt;
&lt;p&gt;其实我这边除了要做这个外， 我还希望做端口的审计以及其他弱密码的审计。
希望是本无所谓有的，无所谓无的，先做点基本的吧。：）&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;找到ssh-auditor这个工具，因为我知道初始的密码，这些模版是我做的。&lt;/li&gt;
&lt;li&gt;go get github.com/ncsa/ssh-auditor&lt;/li&gt;
&lt;li&gt;添加访问账户和密码
&lt;ul&gt;
&lt;li&gt;ssh-auditor addcredential root pass01!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取主机段内开通22端口的主机,如果要扫描多个端口，直接再加-p 端口号
&lt;ul&gt;
&lt;li&gt;ssh-auditor discover -p 22 10.214.16.0/24&lt;/li&gt;
&lt;li&gt;ssh-auditor discover -p 22 -p 1443 10.214.16.0/24&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;用添加的账户名和密码进行尝试连接
&lt;ul&gt;
&lt;li&gt;ssh-auditor scan&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取扫描的结果的合并
&lt;ul&gt;
&lt;li&gt;ssh-auditor vule&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获得report，以json形式表示
&lt;ul&gt;
&lt;li&gt;ssh-auditor dupes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;解析&lt;/h1&gt;
&lt;p&gt;因为这个获得的信息是ip地址的，我希望再反馈为域名，因为这些机器都是有名字的。
写了个简单的powershell脚本。
其中ip地址来自于vule的输出。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $ipl=&quot;10.214.16.166&quot;,&quot;10.214.16.190&quot;,&quot;10.214.16.159&quot;,&quot;10.214.16.192&quot;,&quot;10.214.8.73&quot;,&quot;10.214.8.80&quot;,&quot;10.214.8.78&quot;,&quot;10.214.8.79&quot;,&quot;10.214.8.76&quot;,&quot;10.214.8.77&quot;,&quot;10.214.96.40&quot;,&quot;10.214.96.34&quot;
foreach($ip in $ipl){
  $dname=cmd.exe /c nslookup $ip
  foreach ($item in $dname){if ($item.Contains(&quot;Name&quot;)){write-host $ip,$item}}
  } 
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;后记&lt;/h1&gt;
&lt;p&gt;这两天在学习rust，本想着自己写一个，但是奈何几天的学习并不能达到所想即所用的状态，还是差距大大的。&lt;/p&gt;
&lt;p&gt;不好好学习是不行的。&lt;/p&gt;
</content:encoded></item><item><title>Bind下的一些防御措施</title><link>https://dididudu998.github.io/posts/bind%E4%B8%8B%E7%9A%84%E4%B8%80%E7%82%B9%E9%98%B2%E5%BE%A1%E6%8E%AA%E6%96%BD/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/bind%E4%B8%8B%E7%9A%84%E4%B8%80%E7%82%B9%E9%98%B2%E5%BE%A1%E6%8E%AA%E6%96%BD/</guid><pubDate>Thu, 16 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;前几天微软的DNS服务器暴露出说已经潜藏了17年的高安全漏洞，当进行一些字符的解析的时候，会出现内存溢出，而这样的溢出会被利用可以进行权限的提升和域名的修改。&lt;/p&gt;
&lt;p&gt;这里内部以前有windows的dns服务器用来进行IPv6的解析，但是经过我的检查，这些DNS服务器已经不再使用了。&lt;/p&gt;
&lt;p&gt;也就不需要担心。&lt;/p&gt;
&lt;p&gt;前几天做了一个利用rpc over http来进行虚拟机快照的小程序，也顺便做了一个dev的域名，用来将以后的与开发相关的都转移过去。&lt;/p&gt;
&lt;p&gt;做好域名后，在进行message检查的时候发现有大量的query到某几个域名，虽然在bind的name.conf里面已经做了rate limit的限制，但是好像不顶用啊。&lt;/p&gt;
&lt;h1&gt;实施&lt;/h1&gt;
&lt;p&gt;想着用防火墙来搞，但是好像iptables我都是用的ip地址，不知道能不能用。
嘿，原来iptables本身就带这个功能，学艺不精，只学了个皮毛。&lt;/p&gt;
&lt;p&gt;更详细的信息参看这里：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.perturb.org/display/1186_Linux_Block_DNS_queries_for_specific_zone_with_IPTables.html&quot;&gt;linux_block_dns_queries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://defragged.org/2020/05/20/tips-and-tricks-blocking-dns-requests-via-iptables/&quot;&gt;block_dns_request&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;是这么操作的，一群随机的ip地址，我查了下，有来自阿里云的，有来自美国的，有来自什么阿尔巴尼亚的还有海地的都查询几个域名，疯狂的查询。
假设他们查询的域名是：woaichifan.org. 那么woaichifan是9位，org是3位。在iptables中这么添加：&lt;/p&gt;
&lt;p&gt;对查询woaichifan.org的域名的访问直接抛弃&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;iptables -A INPUT -i ens160 -p udp --dport 53 -m string --hex-string &quot;|09|woaichifan|03|org&quot; --algo bm -j DROP&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对来自恶意的地址直接丢弃&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;iptables -A INPUT -s xx.xx.xx.x -j DROP&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;检查&lt;/h1&gt;
&lt;p&gt;发现启用后，再进行query这些域名，只会超时了。 而且对query日志进行检查，发现清爽很多了。&lt;/p&gt;
&lt;h1&gt;后记&lt;/h1&gt;
&lt;p&gt;有很多的知识，是相通的，但是要不往前走一步，就不知道它的边界在哪里，往前走，只会越走越宽广。不管是学习也好，还是做事也好，都要试着往更进一步想想。&lt;/p&gt;
</content:encoded></item><item><title>为什么flash芯片有寿命限制</title><link>https://dididudu998.github.io/posts/%E4%B8%BA%E4%BB%80%E4%B9%88flash%E8%8A%AF%E7%89%87%E6%9C%89%E5%AF%BF%E5%91%BD%E9%99%90%E5%88%B6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%BA%E4%BB%80%E4%B9%88flash%E8%8A%AF%E7%89%87%E6%9C%89%E5%AF%BF%E5%91%BD%E9%99%90%E5%88%B6/</guid><pubDate>Fri, 19 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;为什么flash芯片有寿命限制&lt;/h1&gt;
&lt;h2&gt;量子隧穿效应&lt;/h2&gt;
&lt;p&gt;在量子力學裏，量子穿隧效應（Quantum tunnelling effect）指的是，像電子等微觀粒子能夠穿入或穿越位勢壘的量子行為，儘管位勢壘的高度大於粒子的總能量。在古典力學裏，這是不可能發生的，但使用量子力學理論卻可以給出合理解釋。[1]:xix&lt;/p&gt;
&lt;p&gt;量子穿隧效應是太陽核融合所倚賴的機制。量子穿隧效應限制了太陽燃燒的速率，是太陽聚變循環的瓶頸，因此維持太陽的長久壽命。[2]:625[3]許多現代器件的運作都倚賴這效應，例如，隧道二極體、場致發射、約瑟夫森結、磁隧道結等等。掃描隧道顯微鏡、原子鐘也應用到量子穿隧效應。[2]:257, 260, 437, 454量子穿隧理論也被應用在半導體物理學、超導體物理學等其它領域。&lt;/p&gt;
&lt;h2&gt;flash芯片的原理&lt;/h2&gt;
&lt;h3&gt;结构&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/flash%E7%9A%84%E7%BB%93%E6%9E%84.jpg&quot; alt=&quot;falsh&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/%E9%97%AA%E5%AD%98%E5%8D%95%E5%85%83.jpg&quot; alt=&quot;闪存单元&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;source: 源极&lt;/li&gt;
&lt;li&gt;Drain:漏极&lt;/li&gt;
&lt;li&gt;Float gate：浮动栅&lt;/li&gt;
&lt;li&gt;control gate：控制栅&lt;/li&gt;
&lt;li&gt;insulator：二氧化硅材料 （超薄）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;浮动栅是由氮化物夹在二氧化硅中构成。&lt;/p&gt;
&lt;h4&gt;写操作&lt;/h4&gt;
&lt;p&gt;给控制栅加+电压，利用隧穿效应，将电子吸入浮动栅。由于浮动栅上下的二氧化硅材料并不导电，这些电子被囚禁在浮动栅中，不能出去。这样以后无论控制栅电压有没有，这个状态都会保持下去。所以闪存可以掉电保存数据。
写操作完成后，闪存单元存储的为0.&lt;/p&gt;
&lt;h4&gt;擦除操作&lt;/h4&gt;
&lt;p&gt;在源极加+电压，利用浮动栅和漏极之间的隧道效应，将注入到浮动栅的负电荷吸引到源极，排空浮动栅的电子。这时候读取的状态为1.&lt;/p&gt;
&lt;h4&gt;读取操作&lt;/h4&gt;
&lt;p&gt;在读取的时候，给控制栅加一个低的读取电压，
对于被写过的闪存单元来说，被囚禁的电子可以抵消该读取电压，造成源极和漏极之间是关闭的状态。
对于被擦除过的闪存则相反，源极和漏极在控制栅的低电压作用下，处于导通状态。&lt;/p&gt;
&lt;p&gt;也就是通过向控制栅加读取电压，判断源极和漏极之间是否导通就可以来读取单元的状态。如果写过，则是关闭的，为0.如果被擦除过，则是导通的，为1.&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;当写的时候，加入足够大的门极电压，就可以通过氧化层的隧穿效应，将电子打入到浮栅中完成写0的过程；
当擦除的时候，就加反向电压同样利用隧穿效应让电子从氧化层出来，就可以完成擦除写1的过程；
当读的时候，由于浮栅里面有电子，会有反向电场，读的时候就是靠这个特性，通过读取电压来分析导通电流，判断是否为0。&lt;/p&gt;
&lt;p&gt;因为flash要想要维持其能够封存电子，需要有这种超薄的绝缘薄膜（二氧化硅）的支持。
随着长期的电子的穿透，薄膜的绝缘性受到了降低，因为晶格结构被反复冲击会产生电效应和热效应。
这样当进行电压的改变进行电子的吸附的时候，就会出现电子的逃逸，产生漏电，这样的结果就是不能获取到底是读还是写的准确状态，这样就不能继续使用了。&lt;/p&gt;
</content:encoded></item><item><title>解决nutanix莫名的问题</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3nutanix%E8%8E%AB%E5%90%8D%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3nutanix%E8%8E%AB%E5%90%8D%E7%9A%84%E9%97%AE%E9%A2%98/</guid><pubDate>Tue, 16 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;莫名的nutanix主机断开的问题&lt;/h1&gt;
&lt;p&gt;昨天在进行虚拟机部署的时候，部署到90%，发现一直卡在这里不动了.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/zhujiduankai.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看的时候，发现该主机已经在vCenter上显示断开
但是用ssh 访问esxi还是可以登录，但是只能ls，其他的命令只要输入就会卡死。&lt;/p&gt;
&lt;p&gt;因为快要下班，先看到这里，明天继续。&lt;/p&gt;
&lt;h2&gt;第二天&lt;/h2&gt;
&lt;p&gt;首先这个esxi 主机是无法touch到的，想要重启，就联想到了IPMI，刚好有这个口令，重启了这台主机。&lt;/p&gt;
&lt;p&gt;重启后，检查了下存放cvm机器的存储，这个里面多了一台虚拟机，移走。&lt;/p&gt;
&lt;p&gt;至此，cvm显示正常了，但是主机显示缺少HA的存储心跳，看了下，数据存储只有本身的，没有nutanix创建出来的nfs部分。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/cunchudiushi.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;进prism，到存储，到storage container，update对应的存储到这台重启的esxi主机。&lt;/p&gt;
&lt;p&gt;发现提示这个 “a datastore based on the provided spec already exists on the node。。。”，&lt;/p&gt;
&lt;p&gt;用 ssh进esxi，发现vmfs果然有nfs存储的目录，而且都可以访问。但是vsphere中就是看不到。&lt;/p&gt;
&lt;h2&gt;解决问题&lt;/h2&gt;
&lt;p&gt;想着莫非是HA导致的问题，检查了隐藏的vsphere-ha目录下的文件，没有什么异常。&lt;/p&gt;
&lt;p&gt;想着，要不再重启一次。。。。。。，算了，一般不是这个问题，重启比较费时间。&lt;/p&gt;
&lt;p&gt;要不重启下对应的服务，&lt;/p&gt;
&lt;p&gt;/etc/init.d/hostd restart
/etc/init.d/vpxa restart&lt;/p&gt;
&lt;p&gt;确保这两个服务重启成功，一个是主机值守服务，一个是vcenter的代理服务。&lt;/p&gt;
&lt;p&gt;重启完成后，再看存储，好了，出现了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/cunchuhuifu.jpg&quot; alt=&quot;huifu&quot; /&gt;
问题解决了。&lt;/p&gt;
&lt;p&gt;耗时2个小时。&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;出现问题，明确的分析，找对方法，都是可以解决的。
要分析，分析问题是比较困难的，也是价值的体现。&lt;/p&gt;
</content:encoded></item><item><title>利用dns查询获取我的公网地址</title><link>https://dididudu998.github.io/posts/%E5%88%A9%E7%94%A8dns%E6%9F%A5%E8%AF%A2%E8%8E%B7%E5%8F%96%E6%88%91%E7%9A%84%E5%85%AC%E7%BD%91%E5%9C%B0%E5%9D%80/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%88%A9%E7%94%A8dns%E6%9F%A5%E8%AF%A2%E8%8E%B7%E5%8F%96%E6%88%91%E7%9A%84%E5%85%AC%E7%BD%91%E5%9C%B0%E5%9D%80/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一</description><pubDate>Mon, 08 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;利用dns查询获取我的公网地址&lt;/h1&gt;
&lt;p&gt;获取自己的公网地址的方法很多，我这个也是不得已而为之。&lt;/p&gt;
&lt;p&gt;目的无非就是当adsl的电脑重新拨号后，获得新的地址，这个地址我能够知道。&lt;/p&gt;
&lt;p&gt;以前的路由器有这个发送syslog的选项，就是可以定时发送syslog出来，可以在这里看，但是要配置邮箱，而且syslog的信息也不是都是我要的。&lt;/p&gt;
&lt;p&gt;还有就是用curl这样的工具，来访问提供公网地址查询的api，获取返回地址，再发送出来。但是我不想折腾smtp服务在自己的电脑上。也懒得写脚本。&lt;/p&gt;
&lt;p&gt;刚好有自己的dns服务器。那好办了。&lt;/p&gt;
&lt;p&gt;设个定时任务，让adsl的计算机，每隔4个小时，来query一个奇怪的我的不存在的子域名，然后从dns的query日志里面去tail 最后一个query这个奇怪域名的客户端的ip地址，再通过mail发给我不就好了。&lt;/p&gt;
&lt;p&gt;然后就是这样的就完成了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
cd /var/log/named/
cat named-query.log |grep dwoejaldjfla.mydomain.com |gawk &apos;{print $1,$2,$5}&apos; |tail -1 | xargs echo | mail -v -s 你的公网地址 myemailbox@mydomain1.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在crontab中加入这个script，定期运行，然后就能在我设定的邮箱收到邮件了。&lt;/p&gt;
</content:encoded></item><item><title>利用cockpit远程管理Linux主机</title><link>https://dididudu998.github.io/posts/%E5%88%A9%E7%94%A8cockpit%E8%BF%9C%E7%A8%8B%E7%AE%A1%E7%90%86linux%E4%B8%BB%E6%9C%BA/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%88%A9%E7%94%A8cockpit%E8%BF%9C%E7%A8%8B%E7%AE%A1%E7%90%86linux%E4%B8%BB%E6%9C%BA/</guid><pubDate>Tue, 02 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;起因&lt;/h1&gt;
&lt;p&gt;在使用了CentOS8.1的时候，发现开机有提示，可以enable cockpit.socket服务。&lt;br /&gt;
当时感觉可能就是类似Ubuntu的那种聚合管理的东西，就打开了。&lt;/p&gt;
&lt;p&gt;然后发现这个还真是所想的那种。&lt;/p&gt;
&lt;h1&gt;了解&lt;/h1&gt;
&lt;p&gt;参看&lt;a href=&quot;https://cockpit-project.org/&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;还有统一认证的部分以及架构&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/cockpit-transport.png&quot; alt=&quot;架构&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>powercli的一点实践</title><link>https://dididudu998.github.io/posts/powercli%E7%9A%84%E4%B8%80%E7%82%B9%E5%AE%9E%E8%B7%B5/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/powercli%E7%9A%84%E4%B8%80%E7%82%B9%E5%AE%9E%E8%B7%B5/</guid><pubDate>Fri, 29 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;密码加密&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;输入用户名和密码，这里将密码存入文件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$credential=get-credential
$credential.Password|ConvertFrom-Securestring |Set-content password.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;获取密码&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$p=get-content password.txt |convertto-securestring
$cre=new-object system.management.automation.pscredential(&quot;ls3686@ad.shanghai.nyu.edu&quot;,$p)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;使用密文密码进行连接&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;connect-viserver 10.214.24.109 -credential $cre
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;使用golang来编译powershell的脚本&lt;/h1&gt;
&lt;p&gt;引入下面两个模块&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;	ps &quot;github.com/bhendo/go-powershell&quot;
    &quot;github.com/bhendo/go-powershell/backend&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;生成漂亮的html页面&lt;/h1&gt;
&lt;p&gt;首先建立css文件，这里以下面的css为例。
保存css文件为css.html.&lt;/p&gt;
&lt;p&gt;然后通过powershell导出的文件的方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成html格式的vms对象&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$vms=get-vm|select-object name,numcpu,MemoryGB,@{n=&quot;UsedSpace&quot;;e={[math]::Round($_.UsedSpaceGB)}},@{n=&quot;ProvisionedSpace&quot;;e={[math]::Round($_.ProvisionedSpaceGB)}},@{n=&quot;HOSTNAME&quot;;e={$_.ExtensionData.guest.hostname}},@{n=&quot;IP&quot;;e={$_.ExtensionData.guest.ipaddress}},@{N=&quot;OS&quot;;e={$_.ExtensionData.guest.guestfullname}},@{N=&quot;SnapshotSize&quot;;e={[math]::Round((Get-Snapshot -VM $_ | Measure-Object -Sum SizeGB).Sum)}} |convertto-html -Fragment
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;创建html空文件对象&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$filename=$(get-date -format &quot;yyyy-MM-dd&quot;)+&quot;-Production.html&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;将vms对象写入filename这个文件，这里面的body部分因为没有使用powershell的变量引用，所以其实只引入了vms这个对象，其他的css都为空。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$report=ConvertTo-Html -title &quot;Virtual Machine detail informations&quot; -head &quot;&amp;lt;div id=&apos;title&apos;&amp;gt;Production-Env VM information reporting&amp;lt;/div&amp;gt;$br&amp;lt;div id=&apos;subtitle&apos;&amp;gt;Report generated on:$(get-date)&amp;lt;/div&amp;gt;&quot; -body &quot;$css $PageBoxOpener $BoxContentOpener $PageBoxCloser&amp;lt;/table&amp;gt; $br $BoxContentOpener $vms $PageBoxCloser&quot; |Out-File $filename
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;合并css到文件，合并css到html文件末尾，使得表格呈现出来。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;get-content css.html |add-content $filename
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;用powershell发邮件&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;write-host &quot;begin sending email&quot; -ForegroundColor &quot;blue&quot;

$msg=new-object net.mail.mailmessage
$attachment=new-object net.mail.attachment($filename) #这里的$filename是html文件的文件名，可以加上路径
$smtpserver=new-object net.mail.smtpclient(&quot;smtp.mysmtpserver.com&quot;)
$msg.from=&quot;demo@mycompany.com&quot;
$msg.to.add(&quot;mark@home.com&quot;)
$msg.subject=&quot;something may interested&quot;
# $msg.body=$htmlbody |Out-String
$msg.Attachments.add($attachment)
$msg.IsBodyHtml=$true
$smtpserver.Send($msg)

write-host &quot;message sent&quot; -foreground color &quot;blue&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;用powershell检测端口开放情况&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;起因是开始做了一个用iis发布的folder，因为iis服务器没有加入域，没发做域的认证。后来换成了go，编译了一下，还是放在了这台windows机器上。为了保证服务的可靠性，需要做一个监控端口是否开放的脚本，如果端口连接不上，那就需要重启这个exe文件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;用了两种方式，一种是打开sockets的方式，一种是test-openport的方式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;其中cmd /qn的参数是静默在后台运行的意思。实际上不需要加/qn参数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;$ipaddress=&quot;10.214.8.75&quot;
$port=8075
#$connection=new-object system.net.sockets.tcpclient($ipaddress,$port)
$connection=test-netconnection 10.214.8.75 -port 8075 
#if ($connection.Connected){
if ($connection.tcptestsucceeded){
	write-host &quot;port is open,fine!&quot;
   }
else {
	write-host &quot;port is not open!&quot;
        &quot;c:\authpublish\authpublish.exe&quot; |cmd /qn
   }
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>关于DHCP的监控</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Edhcp%E7%9B%91%E6%8E%A7/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Edhcp%E7%9B%91%E6%8E%A7/</guid><pubDate>Fri, 15 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;DHCP监控&lt;/h1&gt;
&lt;p&gt;废话不多说。&lt;/p&gt;
&lt;p&gt;早就配置过这个了，但是今天发生问题，长时间没访问给忘记了。记录下。&lt;/p&gt;
&lt;p&gt;直接上&lt;a href=&quot;https://github.com/Akkadius/glass-isc-dhcp&quot;&gt;glass-isc-dhcp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用的访问端口是3000端口，而不是8080的端口。这个要明白。&lt;/p&gt;
&lt;p&gt;整个的实现也比较简单。&lt;/p&gt;
&lt;p&gt;直接放在dhcp服务器上面即可。&lt;/p&gt;
</content:encoded></item><item><title>怎么判断程序运行在虚拟机</title><link>https://dididudu998.github.io/posts/%E5%A6%82%E4%BD%95%E5%88%A4%E6%96%AD%E6%98%AF%E5%90%A6%E4%BD%BF%E7%94%A8%E4%BA%86%E8%99%9A%E6%8B%9F%E6%9C%BA/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%A6%82%E4%BD%95%E5%88%A4%E6%96%AD%E6%98%AF%E5%90%A6%E4%BD%BF%E7%94%A8%E4%BA%86%E8%99%9A%E6%8B%9F%E6%9C%BA/</guid><pubDate>Tue, 12 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;怎么判断程序运行在虚拟机里面&lt;/h1&gt;
&lt;p&gt;参看这篇&lt;a href=&quot;https://www.cyberbit.com/blog/endpoint-security/anti-vm-and-anti-sandbox-explained/&quot;&gt;文章&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;判断CPUID
&lt;ol&gt;
&lt;li&gt;指令EAX输入为1，如果ECX返回为0，则是物理机。如果ECX返回为1，则是虚拟机&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;判断特殊的EAX值
&lt;ol&gt;
&lt;li&gt;调取CPUID 的值为EAX=40000000，返回值会提供虚拟化供应商的名称&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;判断特殊的I/O端口
&lt;ol&gt;
&lt;li&gt;在vmware，主机和虚拟机之间通讯是使用特别的I/O端口的，如果这个端口存在，那么就是虚拟机环境&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;检查MAC地址的前六位
&lt;ol&gt;
&lt;li&gt;这个很容易实现，见下面列表
&lt;ol&gt;
&lt;li&gt;VMWARE：00:05:69&lt;/li&gt;
&lt;li&gt;VMWARE：00:0C:29&lt;/li&gt;
&lt;li&gt;VMWARE: 00:1C:14&lt;/li&gt;
&lt;li&gt;VMWARE: 00:50:56&lt;/li&gt;
&lt;li&gt;VirtualBox: 08:00:27&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;检查注册表键值
&lt;ol&gt;
&lt;li&gt;针对Windows系统，可以看下面的键值
&lt;ol&gt;
&lt;li&gt;HKLM\SOFTWARE\Vmware Inc.\Vmware Tools&lt;/li&gt;
&lt;li&gt;HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SCSI PORT 2\SCSI BUS 0\Target Id 0\Logical Unit Id 0\Identifier&lt;/li&gt;
&lt;li&gt;SYSTEM\CurrentControlSet\Enum\SCSI\Disk&amp;amp;Ven_VMware_&amp;amp;Prod_VMware_Virtual_S&lt;/li&gt;
&lt;li&gt;SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\root#vmwvmcihostdev&lt;/li&gt;
&lt;li&gt;SYSTEM\CurrentControlSet\Control\VirtualDeviceDrivers&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;检查运行的进程
&lt;ol&gt;
&lt;li&gt;VMware
&lt;ol&gt;
&lt;li&gt;vmtoolsd.exe&lt;/li&gt;
&lt;li&gt;vmwaretrat.exe&lt;/li&gt;
&lt;li&gt;vmwareuser.exe&lt;/li&gt;
&lt;li&gt;vmacthlp.exe&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;VirtualBox
&lt;ol&gt;
&lt;li&gt;vboxservice.exe&lt;/li&gt;
&lt;li&gt;vboxtray.exe&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;检查存在的文件
&lt;ol&gt;
&lt;li&gt;Vmware&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\windows\System32\Drivers\VBoxMouse.sys C:\windows\System32\Drivers\VBoxGuest.sys
C:\windows\System32\Drivers\VBoxSF.sys
C:\windows\System32\Drivers\VBoxVideo.sys
C:\windows\System32\vboxdisp.dll
C:\windows\System32\vboxhook.dll
C:\windows\System32\vboxmrxnp.dll
C:\windows\System32\vboxogl.dll
C:\windows\System32\vboxoglarrayspu.dll
C:\windows\System32\vboxoglcrutil.dll
C:\windows\System32\vboxoglerrorspu.dll
C:\windows\System32\vboxoglfeedbackspu.dll
C:\windows\System32\vboxoglpackspu.dll
C:\windows\System32\vboxoglpassthroughspu.dll
C:\windows\System32\vboxservice.exe
C:\windows\System32\vboxtray.exe
C:\windows\System32\VBoxControl.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;检查运行的服务&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;VMTools&lt;/li&gt;
&lt;li&gt;Vmhgfs&lt;/li&gt;
&lt;li&gt;VMMEMCTL&lt;/li&gt;
&lt;li&gt;Vmmouse&lt;/li&gt;
&lt;li&gt;Vmrawdsk&lt;/li&gt;
&lt;li&gt;Vmusbmouse&lt;/li&gt;
&lt;li&gt;Vmvss&lt;/li&gt;
&lt;li&gt;Vmscsi&lt;/li&gt;
&lt;li&gt;Vmxnet&lt;/li&gt;
&lt;li&gt;vmx_svga&lt;/li&gt;
&lt;li&gt;Vmware Tools&lt;/li&gt;
&lt;li&gt;Vmware Physical Disk Helper Service&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>解码文件（可执行文件）</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E7%A0%81%E6%96%87%E4%BB%B6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E7%A0%81%E6%96%87%E4%BB%B6/</guid><pubDate>Mon, 11 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;解码文件&lt;/h1&gt;
&lt;h2&gt;基本的命令&lt;/h2&gt;
&lt;p&gt;看了这篇文章&lt;a href=&quot;https://class.malware.re/2020/02/04/exe-file-analysis-1.html&quot;&gt;EXE file analysis&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;就用以前写的go文件build后的可执行文件作为目标，试试看。&lt;/p&gt;
&lt;p&gt;go文件build后的文件名为op。&lt;/p&gt;
&lt;p&gt;解码看看：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用hexdump op，乱码&lt;/li&gt;
&lt;li&gt;使用hexdump -C op， 继续乱码&lt;/li&gt;
&lt;li&gt;使用objdump -f op， 一长串，没有肉眼可以分辨的信息&lt;/li&gt;
&lt;li&gt;使用objdump -x op， 没有可以分辨的信息&lt;/li&gt;
&lt;li&gt;使用objdump -d op， 出错&lt;/li&gt;
&lt;li&gt;使用strings -n 6 op， 乱码&lt;/li&gt;
&lt;li&gt;使用strings -n 8 op, 成功解析go程序引用的库。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;顺便还有exiftool，用于从照片中分离exif信息。
用file获取文件类型信息&lt;/p&gt;
&lt;h2&gt;使用酷工具&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ghidra-sre.org&quot;&gt;ghidra&lt;/a&gt;是一个使用java jdk来运行的反编译软件。&lt;br /&gt;
按照这个课程的使用指南，发现真的很强大。&lt;br /&gt;
从导入文件，自动分析，到找定义的string，然后从string找到函数，再从函数convert到命令行。可以很快的找到这个字段所对应的操作。&lt;/p&gt;
</content:encoded></item><item><title>Pro Nodejs</title><link>https://dididudu998.github.io/posts/pronodejs/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/pronodejs/</guid><pubDate>Sun, 05 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;一些扩展信息&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;获得详细的命令行信息&lt;pre&gt;&lt;code&gt;- info coreutil base64
  - printf &quot;hello | base64
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;在运行ls -alhn后，第一行的total信息，表示该目录在硬盘上所使用的块的数量&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>安卓用twrp的时候不能挂载分区的问题</title><link>https://dididudu998.github.io/posts/twrp%E4%B8%8D%E8%83%BDmount%E5%88%86%E5%8C%BA%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/twrp%E4%B8%8D%E8%83%BDmount%E5%88%86%E5%8C%BA%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 20 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;给家人买了一个新的荣耀9x手机替换用的红米note3，这个红米的电池有问题了，经常用着就自动关机了，我拿过来看了下，发现电池已经鼓包了，这个是一年前换的淘宝上面的电池，还所谓的原厂的，很垃圾啊。继续在淘宝花40块钱买一个新的电池，还能用啊。然后我又有第二张卡，所以就把这个note3拿过来，替换中国移动50块钱给的一个阿里云os的手机，这个移动的手机的系统很糟糕，各种封闭，而且自己做的还不够好。在这个移动的手机之前我的是小米3，在小米3之前是iPhone4，再下来是windows phone，就是htc的雷达。再前面是被称为神机的一个htc的，再前面是多普达的一个windows mobile。现在用的是红米note7，就是某晚上突发的买的那款，其实这个note7不是很合意。&lt;/p&gt;
&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;换过来的note3，仍然像往常一样刷aospextend的rom，但是发现这次的这个印度的小哥做的rom不是很ok啊，因为以前给小米3刷的aosp的rom的，那叫一个好，所以一有手机，就先上aosp找rom，这次看来是失败了。&lt;/p&gt;
&lt;p&gt;再下来我看miui有开发版的rom，下载下来后，发现这个开发版的rom的root不完全啊，用rootexplorer依然不能够mount根目录，而且没发修改文件的权限啊。折腾了几个小时，还下载了google的全套，到后面也是给出厂化了，浪费几个小时。&lt;/p&gt;
&lt;p&gt;想着换个魔趣的rom，没想到，现在魔趣的rom下载那叫一个慢，慢的要死，也是放弃了，累死了，何必。&lt;/p&gt;
&lt;p&gt;想着不用miui自己的root了，换magisk试试，或许这个行呢。&lt;/p&gt;
&lt;p&gt;下面是实现的步骤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;换个低版本的twrp版本，从3.3.1换到3.3.0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;twrp进去后，先选择wipe data分区，再选择高级wipe，在选择更改文件系统格式到ext2，应用，然后再选择修改文件格式为ext4，应用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;参考的是另外一篇，但是忘记哪里了，就搜到下面的这篇&lt;a href=&quot;https://appuals.com/how-to-fix-twrp-unable-to-mount-storage-internal-storage-0mb/&quot;&gt;修复不能mount的问题&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
How to Fix TWRP Unable to Mount Storage

  The first thing to try is if somehow your internal storage became encrypted when using a legacy screen lock method.
  - Go to your Android device’s Settings &amp;gt; Security &amp;gt; Screen Lock, and change your screen lock method to either Pass or Pin. Create a new one.
  - Reboot into TWRP, and it should ask for a password – enter the pass or pin you just created.
  TWRP will attempt to decrypt your device’s internal storage, and if it succeeds, you should not have further issues. However, if this does not solve your issue of “unable to mount data, internal storage 0mb”, continue with the rest of this guide.
  - Reboot your device into TWRP again.
  Navigate to Wipe &amp;gt; Advance Wipe &amp;gt; Data, and choose Repair or Change File System.
  Press Repair File System to see if this fixes the issue. If not, continue.
  Press Change File System, choose Ext2, and swipe to confirm.
  Now switch back to Ext4 and swipe to confirm.
  Go back to TWRP main menu, then the Mount menu, and check if your partitions can be mounted now.
  If you are still unable to mount your partitions, you need to repair Internal partition, which will most likely wipe your internal storage.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修复后，可以挂载data分区了，这下应该是好了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下载magisk的zip包，下载note3的开发者rom&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在twrp下面刷进去&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;twrp直接在bootloader的情况下，用fastboot flash recovery twrp.img刷入&lt;/li&gt;
&lt;li&gt;用adb push note3rom.zip /sdcard的方式传rom到手机&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;刷完后，安装下rootexplore来检验magisk的root完整性，发现完美。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装adaway，也可以更新host文件了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;小米这个经常搞不完全root，很糟糕，就像现在的note7一样，也是得第三方的root才成。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;后记&lt;/h1&gt;
&lt;p&gt;note3 虽然已经是5年前的东西了，但是接电话，刷刷微博还是没问题的，电子产品现在这样的不让换电池的设置真的不喜欢啊，现在的一些安卓pad就是因为这个，电池坏了基本上就废了。&lt;/p&gt;
&lt;p&gt;现在无力最早的ipad一代，还能用，就在旁边，装上老版本的adobe reader就能看pdf，装上我的文档就能狗无线上传文件，还有老版本的网易新闻等，我放到百度网盘里面了。&lt;/p&gt;
&lt;p&gt;ipad1代看pdf大文件，nook看文字小说，合起来用挺好的。&lt;/p&gt;
&lt;p&gt;我不喜欢将能用的东西扔掉，总想着挖掘下，直到没有法了再说。&lt;/p&gt;
</content:encoded></item><item><title>trojan的部署和使用</title><link>https://dididudu998.github.io/posts/trojan%E7%9A%84%E9%83%A8%E7%BD%B2%E5%92%8C%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/trojan%E7%9A%84%E9%83%A8%E7%BD%B2%E5%92%8C%E4%BD%BF%E7%94%A8/</guid><pubDate>Tue, 11 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;前序&lt;/h1&gt;
&lt;p&gt;总是怀着可能沦陷的忐忑的心情，也就多了一份忧虑，也就多了一些想法，也就有了一些行动。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;在gcp上开启新的虚拟机，使用centos7，最小化部署，我选择的是东京的，每天的消耗大概在5个多港币&lt;/li&gt;
&lt;li&gt;生成虚拟机后，看看得到的临时public ip地址，确保是可以ping通的，有时候不能，那就换地址&lt;/li&gt;
&lt;li&gt;确定地址可用后，要申请一个公网域名和这个IP地址绑定，我有一个公网的dns，所以就可以直接上一个，没有的话，搜索下就有方法&lt;/li&gt;
&lt;li&gt;ssh到该虚拟机后，执行下面的操作
&lt;ol&gt;
&lt;li&gt;wget --no-check-certificate https://raw.githubusercontent.com/cx9208/Linux-NetSpeed/master/tcp.sh &amp;amp;&amp;amp; chmod +x tcp.sh &amp;amp;&amp;amp; ./tcp.sh&lt;/li&gt;
&lt;li&gt;安装加速（此时可以不用重启）&lt;/li&gt;
&lt;li&gt;安装trojan
&lt;ol&gt;
&lt;li&gt;curl -O https://raw.githubusercontent.com/atrandys/trojan/master/trojan_centos7.sh &amp;amp;&amp;amp;  chmod +x ./trojan_centos7.sh &amp;amp;&amp;amp; ./trojan_centos7.sh&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;按照需求填入公网的dns名称，直到运行结束，告诉你客户端的下载链接&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;利用告知的客户端下载链接，下载压缩包并解压&lt;/li&gt;
&lt;li&gt;解压出来的里面，查看config.json文件，里面有需要的远程地址，端口，密码信息&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;└── src
    └── trojan-cli
        ├── CONTRIBUTORS.md
        ├── LICENSE
        ├── README.md
        ├── VC_redist.x64.exe
        ├── config.json
        ├── examples
        │   ├── client.json-example
        │   ├── forward.json-example
        │   └── server.json-example
        ├── fullchain.cer
        ├── libcrypto-1_1.dll
        ├── libmariadb.dll
        ├── libssl-1_1.dll
        ├── msvcp140.dll
        ├── msvcp140_1.dll
        ├── msvcp140_2.dll
        ├── start.bat
        ├── stop.bat
        ├── trojan.exe
        ├── vcruntime140.dll
        └── vcruntime140_1.dll
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;如果是安卓的用户，需要下载下面的这个工具
&lt;ol&gt;
&lt;li&gt;https://github.com/trojan-gfw/igniter/releases&lt;/li&gt;
&lt;li&gt;安装后，利用config.json的信息填入，start即可&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;经测试，确实比shadow和v2ray还要快一些&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;结论&lt;/h1&gt;
&lt;p&gt;永远得保持一颗谨慎，警醒的头脑和乐观的心态。&lt;/p&gt;
</content:encoded></item><item><title>新冠状病毒肺炎假期</title><link>https://dididudu998.github.io/posts/%E6%96%B0%E5%86%A0%E7%8A%B6%E7%97%85%E6%AF%92%E8%82%BA%E7%82%8E%E5%81%87%E6%9C%9F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%96%B0%E5%86%A0%E7%8A%B6%E7%97%85%E6%AF%92%E8%82%BA%E7%82%8E%E5%81%87%E6%9C%9F/</guid><description>2020年的这个春节假期</description><pubDate>Mon, 03 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2020年的春节&lt;/h1&gt;
&lt;p&gt;2020年这个春节在放假前就没有什么年味。从后半年很多的新闻报道上听闻有大量的工厂停工和解散的消息。城市里面的人的数量就少了一些。
但是春运的票依然是比较难买，因为没有想要的票的缘故，只买到了凌晨的高铁回家。&lt;/p&gt;
&lt;p&gt;到了高铁站，也没有往常春运时候的那种人潮的涌动。这个时候已经有了肺炎的消息，但是消息很零散，并没有太多的人重视。我自始至终带着口罩，这个口罩真的带了时间长了令人感觉很憋闷。在车上，周围的人并没有戴口罩的意识，因为凌晨的缘故，没有人说话，比较安静的就回来了。&lt;/p&gt;
&lt;p&gt;春晚的当天，基本上没有看，用手机刷着微博以及其他的app来收集这些信息，看到的信息有点可怕。&lt;/p&gt;
&lt;p&gt;接着回来后的几天，新闻上开始了各种的说法，有市长说可防可控，有专家说不存在人感染人的情况，直到一周左右的时间，开始说武汉要封锁城市了，人感染人了，一些国家开始要撤侨了，还有口罩和酒精已经成为战略物资，买不到了。我开始准备延迟返工了，退了本来1月底返程的火车票。&lt;/p&gt;
&lt;p&gt;再后来国务院发了延迟返工的文件，但是文件的本身有点赌博的意思，因为没有人能肯定在2月3日就能够有方法来解决这个感染的问题。感染的人数，死亡的人数，确诊的人数在每日每日的上升，最近几天是连续的每天2000多人确诊。网上的消息是感染的人数应该在10万人左右，死亡的人数远远超过新闻报道的记录。&lt;/p&gt;
&lt;p&gt;现在提到说病毒的感染除了通过上呼吸道外，还存在接触性感染，以及粪便的感染，不知道水和血液传播，动物的传播会不会，因为随着温度的升高，水汽的蒸发，蚊虫的叮咬的几率会大大的增加，如果病毒对温度不敏感，这些传播方式将增加更多的人感染，以及更大范围的感染区。&lt;/p&gt;
&lt;p&gt;目前所有的省市都已经存在感染者，只是多少的问题。&lt;/p&gt;
&lt;p&gt;又接到消息说返工的时间延迟到2月9日。查了下火车票，已经没有了，而且提到2月1日后购买火车票必须留电话号码，而且地铁以及市内的公交需要出示身份证并且戴口罩才能乘坐。&lt;/p&gt;
&lt;p&gt;期间还有各个的村子，封堵入村的路口的新闻报道。后来又国家发文要求取消这种操作。&lt;/p&gt;
&lt;p&gt;京东的快递还没有停，基本上仓库内的物品还是隔日达，其他的物品都是说因为交通管制的问题，最早都要到2月10日后开始发货。&lt;/p&gt;
&lt;p&gt;又有新闻说深圳的外卖小哥在潜伏期内送了几百份外卖，最终确诊了。而在潜伏期内是可以感染其他人的。这个悲剧的消息。&lt;/p&gt;
&lt;p&gt;网上还有说因为没有病床，很多人在家里等死，连殡仪馆都要24小时工作了。&lt;/p&gt;
&lt;h2&gt;未来&lt;/h2&gt;
&lt;p&gt;日子还是得继续过。有专家说面临三个可能性，一个就是在短时间内控制了，这个的可能性微乎其微。因为并没有什么所谓的特效药，那些新闻报道说出院的，治愈的是依赖自身的抵抗力抗过去的，而且说即使扛过去，也不代表将来不能再次受到感染的可能。 还有一个就是长期的战役了，要过半年甚至更长的时间才能收尾这个疾病。另外一个就是无法控制了，收不了场的，全面爆发，引起全国乃至全世界的问题。&lt;/p&gt;
&lt;p&gt;现在由于有一些国外的案例，所以WHO的出面，应该会引起全球的医疗机构的注意进行解药的研发。但是从研发到实现全员的接种，这个时间不知道要多久。
如果像瘟疫战争游戏那样的，感染的速度远远超过研发的速度的话，这个问题就很麻烦了。因为肺炎的死亡率很高，直接导致呼吸的困难。年纪大有一点的人基本上很难扛过去。&lt;/p&gt;
&lt;p&gt;口罩，酒精等已经买不到了，开始了配额制。超市里面的蔬菜加个也是飞涨，一把韭菜5块多，一把芹菜7.5，菠菜8.8，都是一斤的价格。
幸好是过年期间，人们提前储备了一些食物。&lt;/p&gt;
&lt;p&gt;贪官污吏，以及尸位素餐的官员曝光了一些，与官员有关系的人们可以在网上售卖捐助物资，黑心的作坊制作假的口罩出售等等各种的消息满天飞。
医院的医生护士等一线的人员没有足够的防护措施导致大量一线人员的感染等等，这些新闻开始沸腾。&lt;/p&gt;
&lt;p&gt;然后又有官员被免职，黑心作坊被查封，医院说缺乏物资是假消息等的各种操作。&lt;/p&gt;
&lt;p&gt;国外撤侨的国家越来越多，大部分来撤侨的飞机都带有援助品，将援助品放下，然后将自己国家的人接走，但是又听说不允许有中国国籍的妻子随某个国籍的丈夫和孩子回国，导致这个家庭只能留在国内的消息。&lt;/p&gt;
&lt;p&gt;股市开盘就是个跌停。经济的下行的情况会超过大部分人的悲观想象。人心要是散了，很多事情会失去行动的意义，没有了行动，基本上就是混吃等死了。&lt;/p&gt;
</content:encoded></item><item><title>重置mariadb/mysql的root账户密码</title><link>https://dididudu998.github.io/posts/%E9%87%8D%E7%BD%AEmariadb%E7%9A%84root%E5%AF%86%E7%A0%81/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E9%87%8D%E7%BD%AEmariadb%E7%9A%84root%E5%AF%86%E7%A0%81/</guid><description>mysql/mariadb root forgot password</description><pubDate>Tue, 28 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;有一台fedora装了mariadb的数据库想要知道数据库的信息，但是没有人知道密码。&lt;/p&gt;
&lt;p&gt;用mysql -uroot -p的形式，提示root没有权限访问。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;systemctl stop mariadb&lt;/li&gt;
&lt;li&gt;mysqld_safe --skip-grant-table --skip-networking &amp;amp;&lt;/li&gt;
&lt;li&gt;此时mariadb即可直接登陆，不需要用户名和密码&lt;/li&gt;
&lt;li&gt;连接mysql,mysql -uroot&lt;/li&gt;
&lt;li&gt;执行下面的步骤&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;use mysql;
update user set password=&quot;abcdef&quot; where user=&apos;root&apos;;
flush privileges;
quit
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;然后ps aux|grep mysql*&lt;/li&gt;
&lt;li&gt;kill -9 掉那些mysql的进程&lt;/li&gt;
&lt;li&gt;尝试 systemctl start mariadb&lt;/li&gt;
&lt;li&gt;然后用新的密码登陆试试&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;tips&lt;/h1&gt;
&lt;p&gt;如果没有kill掉mysql的进程的话，修改密码会失败。而且start服务会卡住。
建议在修改密码，quit后，有条件也可以直接重启机器。&lt;/p&gt;
</content:encoded></item><item><title>vCenter 6.7的postgresql数据库</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Evmware%E7%9A%84postgresql%E6%95%B0%E6%8D%AE%E5%BA%93/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Evmware%E7%9A%84postgresql%E6%95%B0%E6%8D%AE%E5%BA%93/</guid><pubDate>Fri, 17 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;设想&lt;/h1&gt;
&lt;p&gt;原始的设想是想要做一个可视化的关于虚拟机数量的dashboard。
如果用遍历的方式，感觉有点low，就想着直接从vmware的数据库上面找找，希望能更直接的获得点信息。&lt;/p&gt;
&lt;p&gt;但是现在的vcenter不是以前的用mssql的了，用的PostgreSQL，我想要搞出数据来，需要两个工具。&lt;/p&gt;
&lt;p&gt;一个就是notepad++,还有一个就是pgadmin。&lt;/p&gt;
&lt;p&gt;安装这两个软件后，进入直接的操作部分。&lt;/p&gt;
&lt;h1&gt;操作&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;用notepad++打开这个文件 c:\programdata\vmware\vcenterserver\cfg\vmware-vpx\vcdb.properties&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;获得pgadmin连接数据库需要的条目&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;database name: VCDB&lt;/li&gt;
&lt;li&gt;username: vc&lt;/li&gt;
&lt;li&gt;password: ......&lt;/li&gt;
&lt;li&gt;url: jdbc:postgresql://server:5432/VCDB&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第一次打开pgadmin的时候，要求输入一个master密码用于保护以后建立的连接信息&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个密码仅仅是为了保护以后的数据，和连接服务器的信息无关&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;连接成功后，就可以看到VCDB的数据库信息
&lt;img src=&quot;/images/tupian/pgadmin.jpg&quot; alt=&quot;pgadmin.jpg&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查询数据库table的语句和sql的一样&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tables&lt;/th&gt;
&lt;th&gt;Comment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_entity&lt;/td&gt;
&lt;td&gt;（用于query所有的对象）&amp;lt;br&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_entity where type_id=0&lt;/td&gt;
&lt;td&gt;（这个用于query所有的虚拟机）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_event_33&lt;/td&gt;
&lt;td&gt;(查询所有的事件日志，从第33表开始)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_event_arg_33&lt;/td&gt;
&lt;td&gt;(查询event对应的参数信息，应该是vmware api的接口模式，我这里用了pyvmomi和golang的http)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_ext&lt;/td&gt;
&lt;td&gt;(查询vmware vcenter注册的其他vmware服务，包括vcops，nsx等的版本好，和指纹信息，以及心跳时间)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_ext_client&lt;/td&gt;
&lt;td&gt;(查询扩展服务的url地址，版本号，以及厂商信息等)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_host&lt;/td&gt;
&lt;td&gt;(查询所有的物理主机信息)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_host_cpu&lt;/td&gt;
&lt;td&gt;(查询host的cpu数量以及cpu信息)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_host_cpu_thread&lt;/td&gt;
&lt;td&gt;(查询主机所有的cpu的线程数)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_ip_address&lt;/td&gt;
&lt;td&gt;(查询所有的IP地址记录，包括ipv4和ipv6)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_network&lt;/td&gt;
&lt;td&gt;(查询所有的网络名称，包括动态和静态的VLAN名称)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_snapshot&lt;/td&gt;
&lt;td&gt;(查询所有做过的snapshot的信息)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_uptime&lt;/td&gt;
&lt;td&gt;查询vcenter机器的开机和重启记录，非常的详细&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;select * from vpx_vm&lt;/td&gt;
&lt;td&gt;查询vm的一些信息，包括dns名称和ip地址以及存储位置等&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&amp;lt;font color=red&amp;gt;&amp;lt;b&amp;gt;关联查询&amp;lt;/font&amp;gt;&amp;lt;/b&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;查询时间戳之前哪些虚拟机做了snapshot，用于清理这些snapshot
&lt;img src=&quot;/images/tupian/sqljoin.jpg&quot; alt=&quot;sql-join-select&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;select * from vpx_entity join vpx_snapshot
on vpx_snapshot.vm_id=vpx_entity.id 
and vpx_snapshot.create_time &amp;lt; timestamp &apos;2018-01-01 00:00:00&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;利用pgadmin图形界面的download按钮可以将output直接下载为csv文件。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>怎么样在macOS下解码dump文件</title><link>https://dididudu998.github.io/posts/%E6%80%8E%E4%B9%88%E6%A0%B7%E8%A7%A3%E7%A0%81dump%E6%96%87%E4%BB%B6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%80%8E%E4%B9%88%E6%A0%B7%E8%A7%A3%E7%A0%81dump%E6%96%87%E4%BB%B6/</guid><pubDate>Thu, 12 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;收到个电话说发现几个人的Chrome浏览器和Symantec Endprotection客户端出现冲突，导致浏览器崩溃，只能用其他的浏览器的问题。&lt;/p&gt;
&lt;p&gt;这个现象在不久前的时候官方有个kb，&lt;a href=&quot;%22https://support.symantec.com/us/en/article.tech256047.html%22&quot;&gt;这里&lt;/a&gt;
还有这样的更新包提供下载&lt;a href=&quot;%22https://support.symantec.com/us/en/article.info5196.html%22&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但是今天这个不是说这个问题，而是说如果拿到了chrome的crash的dmp文件，怎么解码的问题&lt;/p&gt;
&lt;p&gt;在widows的时候有软件用来解码蓝屏的时候的dmp文件，而且也有微软提供的方法，很早之前用过，等会儿搜索下再回顾下。&lt;/p&gt;
&lt;h1&gt;dmp文件在哪里&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;option1
&lt;ul&gt;
&lt;li&gt;chrome://crashes&lt;/li&gt;
&lt;li&gt;开启 &quot;自动发送使用状态信息和崩溃报告给google&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;option2
&lt;ul&gt;
&lt;li&gt;直接进目录找
&lt;ul&gt;
&lt;li&gt;macOS：~/Library/Application Support/Google/Chrome/Crashpad/completed/&lt;/li&gt;
&lt;li&gt;Windows：%HOMEPATH%\AppData\Local\Google\Chrome\User Data\Crashpad\reports&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;MacOS&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;访问这里 https://chromium.googlesource.com/breakpad/breakpad&lt;/li&gt;
&lt;li&gt;git clone https://chromium.googlesource.com/breakpad/breakpad&lt;/li&gt;
&lt;li&gt;直接进入目录&lt;/li&gt;
&lt;li&gt;./configure&lt;/li&gt;
&lt;li&gt;make&lt;/li&gt;
&lt;li&gt;make install&lt;/li&gt;
&lt;li&gt;src目录下的process中有minidump_dump可执行文件&lt;/li&gt;
&lt;li&gt;src目录下的tools目录中有各种工具，但是需要编译，我这边没有xcode工具，放弃&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里是用minidump_dump打开的chrome崩溃的dmp文件的截图：
&lt;img src=&quot;/images/tupian/minidump.jpg&quot; alt=&quot;chrome-crash&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里的这篇文章可以参考：&lt;a href=&quot;%22https://cloud.tencent.com/developer/article/1084368%22&quot;&gt;mac下利用breakpad的dump文件进行调试&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Windows&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;WinDbg Preview &lt;a href=&quot;%22https://www.microsoft.com/zh-tw/p/windbg-preview/9pgjgd53tn86?rtc=1&amp;amp;activetab=pivot:overviewtab#%22&quot;&gt;这里&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;下载关联的库 这里https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/microsoft-public-symbols&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>马上2019年结束了</title><link>https://dididudu998.github.io/posts/%E9%A9%AC%E4%B8%8A%E4%B8%80%E5%B9%B4%E7%BB%93%E6%9D%9F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E9%A9%AC%E4%B8%8A%E4%B8%80%E5%B9%B4%E7%BB%93%E6%9D%9F/</guid><description>近来的一些感悟</description><pubDate>Tue, 10 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2019年&lt;/h1&gt;
&lt;p&gt;2019年马上就要结束了，还有20天就要到2020年了。&lt;/p&gt;
&lt;p&gt;今年过的很平静。&lt;/p&gt;
&lt;p&gt;前年看名侦探柯南，去年看蜡笔小新，最近在看龙珠。&lt;/p&gt;
&lt;p&gt;很多东西看着看着就没有以往那么大的劲头了。&lt;/p&gt;
&lt;p&gt;不知道是成熟了，还是变的麻木了。&lt;/p&gt;
&lt;p&gt;看着以前收集的一些个人博客，他们的生活倒是很丰富多彩。&lt;/p&gt;
&lt;p&gt;我没有像别人那样的给每一年设定一个计划，比如学个什么东西，考个什么证之类的。&lt;/p&gt;
&lt;p&gt;随着时间的逝去，越发的觉得宝贵了。&lt;/p&gt;
&lt;p&gt;有时候回顾一下，发现好像什么都没有进步。但是一遇到问题，又发现，好像变的比以前强了许多。&lt;/p&gt;
&lt;p&gt;总结是个好东西，应该是自己总结的太少了。有些随性，不深刻。&lt;/p&gt;
&lt;p&gt;2020年，又是新的一年了。&lt;/p&gt;
&lt;p&gt;整体的经济方面不一定会比2019好，要做好各种的准备。&lt;/p&gt;
&lt;p&gt;热情的生活。&lt;/p&gt;
</content:encoded></item><item><title>存储技术</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8E%E5%AD%98%E5%82%A8%E6%8A%80%E6%9C%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8E%E5%AD%98%E5%82%A8%E6%8A%80%E6%9C%AF/</guid><description>低延迟的存储技术</description><pubDate>Mon, 09 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;在进行大量的计算和存储的交互的时候，人们发现存储的延迟会大大的降低整个系统的性能。而现在的基于大数据以及大型计算的环境越来越多。所以在物理级别和软件层面都发力，用来突破短延时的情况下传输大量的数据。&lt;/p&gt;
&lt;h1&gt;技术层面&lt;/h1&gt;
&lt;p&gt;采用从内存到内存的RDMA方式来传递数据。
它需要的网卡共有三种技术格式。
分别是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iWARP
&lt;ul&gt;
&lt;li&gt;使用TCP/IP以及以太网链路层来实现&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;InfiniBand
&lt;ul&gt;
&lt;li&gt;全套自有的硬件，包括IB的传输协议/网络层/链路层&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RoCE1/RoCE2
&lt;ul&gt;
&lt;li&gt;使用IB的传输协议，但是跑在以太网链路层，尤其是RoCE2，使用udp进行包的封装和IP进行路由。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当前的网络带宽，以10Gpbs，25Gbps，40Gbps，50Gbps，100Gbps的比较普遍。一般都是使用叠加的方式。比如25Gbps，用3个10Gbps来实现，用1个25Gbps的网卡接受数据，然后后台用NVMe的存储卡来实现存储。&lt;/p&gt;
&lt;p&gt;传输线材方面，有直连的双心铜线，但是缺点是距离比较短，3-7m，优点是成本低，延迟低。然后就是光纤线，一般传输距离100-200m之间。&lt;/p&gt;
&lt;p&gt;铜线一般用于在同一个机柜内进行互联。光纤用于跨机柜和在数据中心内进行连接。&lt;/p&gt;
&lt;p&gt;RoCE1在数据链路层上实现，缺点是只能在同一个广播域进行传输，不能路由。
RoCE2将global routing header封装在ip包头中，然后将UDP包头封装在
传输层进行转发。&lt;/p&gt;
&lt;p&gt;有的网卡上内建一个eSwitch PCI-Express交换器，当几台要互联的时候，就直接使用端对端的互联即可。&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&quot;red&quot;&amp;gt;iWARP与RoCE的差别&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;iWARP&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接运行在以太网的网络层&lt;/li&gt;
&lt;li&gt;网络交换机不需要支持数据中心桥接功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Infiniband&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主要用在HPC环境中，支持到200GbE的频宽&lt;/li&gt;
&lt;li&gt;它也可以跑在以太网的网络层，但是必须使用infiniband自己的网络交换机，而不能是其他的类型的交换机&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;b&amp;gt;RoCE的网卡供应商有mellanox，Qlogic，Emulex等&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;iWARP的网卡供应商有chelsio，intel等&amp;lt;/b&amp;gt;&lt;/p&gt;
&lt;h1&gt;存储模式&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;single parity
&lt;ul&gt;
&lt;li&gt;当S2D群集中有3台主机的时候，建议使用三项镜像的模式&lt;/li&gt;
&lt;li&gt;当只有2个主机的时候，那可以使用写一个副本的方式&lt;/li&gt;
&lt;li&gt;存储效率在66.7%-87.5%之间&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;dual parity
&lt;ul&gt;
&lt;li&gt;当群集中有4个主机的时候，可以建立，也就是写两份副本&lt;/li&gt;
&lt;li&gt;存储效率在50%-80%之间，随主机数量的增多而增多&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;微软的内存计算方式&lt;/h1&gt;
&lt;p&gt;假设每个微软的软件定义存储群集的主机配置了4个800GB的SSD存储，那么整体的存储为3.2TB，此时需要给该主机配置4*3.2=12.8GB的内存，用于提供元数据的存储和交换。&lt;/p&gt;
&lt;p&gt;也就是说每1TB的存储，需要有4GB的内存来搭配。&lt;/p&gt;
&lt;p&gt;同时采用NUMA架构的服务器更好，也就是每个cpu对应不同的存储，也就是平均分配存储给cpu，而不需要cpu跨NUMA节点获取存储，提高效率。&lt;/p&gt;
&lt;h1&gt;挑选SSD&lt;/h1&gt;
&lt;p&gt;SSD有资料读取寿命，即使简单的读也会影响。SSD固态盘在运行中还有个读取干扰的现象。随着存储密度不断增加，维持资料的可用性会降低。目前是通过缓冲区技术来保证可用性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在消费领域，使用暂时性快取和电池来保证资料不会被遗失&lt;/li&gt;
&lt;li&gt;在企业中，通过使用电容来保证不会因为失去电源而发生资料遗失&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消费领域的规格：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1TB&lt;/li&gt;
&lt;li&gt;读取一般在95000 IOPS&lt;/li&gt;
&lt;li&gt;写入一般在90000 IOPS&lt;/li&gt;
&lt;li&gt;资料可以读写185TB，保证5年&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每日磁盘写入量（device writes per day，dwpd）&lt;/p&gt;
&lt;p&gt;185TB /（365*5=1825 days）= 100GB 每天&lt;/p&gt;
&lt;p&gt;也就是说如果每天写如100GB，那5年的寿命就结束。&lt;/p&gt;
</content:encoded></item><item><title>建立centos7 的rsyslog服务器</title><link>https://dididudu998.github.io/posts/%E6%94%B6%E9%9B%86symantec%E6%97%A5%E5%BF%97%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%94%B6%E9%9B%86symantec%E6%97%A5%E5%BF%97%E4%BF%A1%E6%81%AF/</guid><description>收集symantec的日志信息</description><pubDate>Fri, 06 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;大概几年前做过这个东西，但是只是给我用的，后来那个elsatic的服务器我也把它干掉了。
这个现在又要做，这里几乎每年都要做一些重复的活动，比如建立新的domain，比如迁移客户端，比如将域控放在这里哪里的数据中心等等。。。。。。。，😓&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;先搞一台rsyslog服务器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS：CentOS7&lt;/li&gt;
&lt;li&gt;yum install rsyslog -y&lt;/li&gt;
&lt;li&gt;vi /etc/rsyslog.conf
&lt;ul&gt;
&lt;li&gt;modify，uncomment like below:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# Provides UDP syslog reception
 $ModLoad imudp
 $UDPServerRun 514

 # Provides TCP syslog reception
 $ModLoad imtcp
 $InputTCPServerRun 514
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;firewall-cmd --add-port=514/tcp&lt;/li&gt;
&lt;li&gt;firewall-cmd --add-port=514/udp&lt;/li&gt;
&lt;li&gt;firewall-cmd --reload&lt;/li&gt;
&lt;li&gt;firewall-cmd --list-all //确认端口是不是开通了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置sysmantec management server&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;login SEPM&lt;/li&gt;
&lt;li&gt;admin-&amp;gt;Server-&amp;gt;local Site-&amp;gt;add external logging&lt;/li&gt;
&lt;li&gt;注意看看loglevel的设定，我这里填0&lt;/li&gt;
&lt;li&gt;filter里面也可以按照需要做一些修改&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过检查 tail -f /var/log/message,就能发现log信息push过来了&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实搞这个东西我觉得没什么意义。因为已经做了SEPM的报警服务。
而且这种集成要想和网络的互动起来，并没有什么特别的意义。&lt;/p&gt;
</content:encoded></item><item><title>学习的不踏实，又忘的差不多了</title><link>https://dididudu998.github.io/posts/%E5%8F%88%E5%BF%98%E7%9A%84%E5%B7%AE%E4%B8%8D%E5%A4%9A%E4%BA%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8F%88%E5%BF%98%E7%9A%84%E5%B7%AE%E4%B8%8D%E5%A4%9A%E4%BA%86/</guid><pubDate>Mon, 02 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;又忘了差不多了&lt;/h1&gt;
&lt;p&gt;昨天用golang做了一个能对MS SQL进行包括连接，备份，列数据库，查询等基本操作的脚本。今天想着搬到web上面来，但是发现又网的差不多了。看了一会儿web的基本操作才晃过神来。&lt;/p&gt;
&lt;p&gt;还想着用vue.js做个漂亮的前端页面，折腾了早上，还是放弃了。
头脑不清晰，做事情是是事半功倍。
刚才又想着还是换基本的命令行算了。反正能用就可以。&lt;/p&gt;
&lt;p&gt;这真的是三天不练手生。我决定放弃学习vue.js了。这个混合形式的html把我搞得很晕，浪费了很多时间。&lt;/p&gt;
&lt;p&gt;总结：学习如逆水行舟，不进则退！&lt;/p&gt;
&lt;p&gt;今天的事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;朗科的64GB优盘收到了&lt;/li&gt;
&lt;li&gt;开始备份先前的项目到U盘，做三保险
&lt;ul&gt;
&lt;li&gt;同步用rsync&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;rsync -avh source --filter=&apos;- .git&apos; --filter=&apos;- node_modules&apos; --filter=&apos;- pkg&apos; --filter=&apos;- src&apos; ./
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果发现了不想要的目录，用下面的进行删除&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;find . -maxdepth 3 -name node_modules -type d -exec rm -rf {} +
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>一些感悟</title><link>https://dididudu998.github.io/posts/%E4%B8%80%E4%BA%9B%E6%84%9F%E6%82%9F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%80%E4%BA%9B%E6%84%9F%E6%82%9F/</guid><description>近来的一些感悟</description><pubDate>Tue, 26 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;一些感悟&lt;/h1&gt;
&lt;p&gt;今天看到了Knight Capital的故事，参看&lt;a href=&quot;%22https://www.kitchensoap.com/2013/10/29/counterfactuals-knight-capital/%22&quot;&gt;这里&lt;/a&gt;,还有&lt;a href=&quot;%22https://dougseven.com/2014/04/17/knightmare-a-devops-cautionary-tale/%22&quot;&gt;这里&lt;/a&gt;,还有&lt;a href=&quot;%22https://money.cnn.com/2012/08/09/technology/knight-expensive-computer-bug/index.html%22&quot;&gt;这里&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;顺便最近这里也发生了一些类似的事件。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某周五下班前，突然某管理平台将几十台虚拟服务器poweroff&lt;/li&gt;
&lt;li&gt;某天下班前，突然SEP客户端导致计算机断网&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很明显的，不仅仅是技术问题。当然技术问题很突出。这样的情况在我所能管辖的范围内是不会出现的。&lt;/p&gt;
&lt;p&gt;这表明，组织内不仅在技术层面存在眼高手低的问题，而且缺乏风险和管控机制，这样的组织在没有吃过大亏的时候估计很少思考自己存活的风险。&lt;/p&gt;
&lt;p&gt;我发现，现在的年轻人，他们对于自己所谈到的东西，掌握的并不是能达到可以进行放手操作的程度。这样的人不是少数。&lt;/p&gt;
&lt;p&gt;我不知道是因为他们急于表现，还是过于自信。但是在企业里面，这样的行为如果多次出现，表明了一些危机。&lt;/p&gt;
&lt;p&gt;一个没有风险意识的人/组织，会吃大亏的。对于人来说，可能损失一些时间。但是对于企业内的组织，可能就得换掉了。&lt;/p&gt;
&lt;p&gt;从我个人的工作经历来看，出现这样的情况的，九成是人的管理的问题，技术再次。事件的结果变现了混乱的表象。&lt;/p&gt;
&lt;p&gt;这样的企业还能继续存活下去，我觉的是应该烧香的，这样的组织还能存活，我觉得是侥幸的。&lt;/p&gt;
&lt;p&gt;我个人觉得未来的一段时间，就是组织和企业回归到真实的状态的时间，不踏实，不脚踏实地，夸夸其谈以及总是出现返工现象的人，是需要淘汰掉的。&lt;/p&gt;
</content:encoded></item><item><title>domain account 没有了文件访问权限了</title><link>https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3netapp%E6%97%A0%E6%B3%95%E7%94%A8%E5%9F%9F%E8%B4%A6%E6%88%B7%E7%99%BB%E5%BD%95%E7%9A%84%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A7%A3%E5%86%B3netapp%E6%97%A0%E6%B3%95%E7%94%A8%E5%9F%9F%E8%B4%A6%E6%88%B7%E7%99%BB%E5%BD%95%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>解决存储问题</description><pubDate>Fri, 08 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题描述&lt;/h1&gt;
&lt;p&gt;这周刚开始，大概在周二的时候早上，有人过来说他放在netapp存储上的文件不能访问了，弹框要验证，说没权限。&lt;br /&gt;
而这些人都是以前配置的好的，用域账户进行验证的，本身的域账户并没有存在过期或者锁定的问题。&lt;br /&gt;
经过检查，本地账户是ok的，为了解决他们访问的问题，先临时开了几个本地账户用。顺便为解决问题争取下时间。&lt;br /&gt;
但是最终还是要解决这个问题啊，要不然，权限设定要烦啊。&lt;/p&gt;
&lt;h1&gt;诊断过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;首先登录netapp存储console里面去，看下安全日志，发现存在很多“None LSA server”的信息&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
event log show -messagename secd.*
event log show -severity DEBUG

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;检查到域控的网络，以及时间服务是否正常&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#从lif是否能够ping通域控    

network ping -lif lif-cifs-01 -vserver svm-netapp01-cifs -destination ip_of_domain_controller 

#显示ntp服务器

cluster time-service ntp server show 

#显示当前时间
date 

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;当前的cifs都是使用的活动目录进行验证的，cifs的本体是加入到domain的。经过dsquery，dsget的检查，这个计算机对象的本体是好的，没有被disable，也没有过期。&lt;/li&gt;
&lt;li&gt;那下来就是检查验证方式是不是出错了。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;cifs security show -vserver vservername 

结果如下：
Vserver: svm-netapp01-cifs

                    Kerberos Clock Skew:                   5 minutes
                    Kerberos Ticket Age:                  10 hours
                   Kerberos Renewal Age:                   7 days
                   Kerberos KDC Timeout:                   3 seconds
                    Is Signing Required:               false
        Is Password Complexity Required:                true
   Use start_tls for AD LDAP connection:               false
              Is AES Encryption Enabled:               false
                 LM Compatibility Level:  lm-ntlm-ntlmv2-krb
             Is SMB Encryption Required:               false
                Client Session Security:                none
        SMB1 Enabled for DC Connections:                true
        SMB2 Enabled for DC Connections:                true
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;怀疑是域控的安全策略进行了更新或者进行了升级，SMB1的连接方式被撤销了。所以先将SMB1的这个连接方式在netapp上面禁用掉，让其只能使用SMB2的方式与预控进行通讯，试试看，是否会解决问题&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;cifs security modify -vserver vservername -smb1-enabled-for-dc-connections false -smb2-enabled-for-dc-connections true

结果如下：
Vserver: svm-netapp01-cifs

                    Kerberos Clock Skew:                   5 minutes
                    Kerberos Ticket Age:                  10 hours
                   Kerberos Renewal Age:                   7 days
                   Kerberos KDC Timeout:                   3 seconds
                    Is Signing Required:               false
        Is Password Complexity Required:                true
   Use start_tls for AD LDAP connection:               false
              Is AES Encryption Enabled:               false
                 LM Compatibility Level:  lm-ntlm-ntlmv2-krb
             Is SMB Encryption Required:               false
                Client Session Security:                none
        SMB1 Enabled for DC Connections:               false
        SMB2 Enabled for DC Connections:                true

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;到netapp的web管理控制台，到cifs的共享文件夹下面，去添加个域的账户到访问权限列表中，如果可以添加，那么问题已经解决了。因为在添加账户的时候就需要进行sid的验证了，验证通过就说明与域的通讯已经恢复正常。&lt;/li&gt;
&lt;li&gt;至此问题解决。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总结：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;解决问题的前提是能够根据已有的情况，先尽量的缩小问题的爆发面积，争取解决问题的时间。&lt;/li&gt;
&lt;li&gt;利用已知的情况，去分析与该问题相关联的对象，以及属性，还有就是收集确切的信息，事件日志&lt;/li&gt;
&lt;li&gt;通过确切的日志信息来缩小与问题相关联的对象的范围，然后修改对应的条目来进行测试&lt;/li&gt;
&lt;li&gt;比如这个问题，netapp上cifs唯一和域通讯相关的除了dns，ntp外，就只有smb1/smb2这两个属性了，那么在不影响功能的前提下，禁用一个，使用高版本看看，就是解决问题的方法了&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>图像识别初学</title><link>https://dididudu998.github.io/posts/%E5%9B%BE%E5%83%8F%E8%AF%86%E5%88%AB%E5%88%9D%E5%AD%A6/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%9B%BE%E5%83%8F%E8%AF%86%E5%88%AB%E5%88%9D%E5%AD%A6/</guid><description>图像识别</description><pubDate>Tue, 29 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;图像识别初学&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;想要将每年的工作日历中的非工作日或者增加的工作日通过图像识别转化为文本信息，并链接到日历中生成提醒&lt;/li&gt;
&lt;li&gt;工作日历中的放假日期用绿色表示，公司特别增加的非工作日用蓝色表示，而增加的上班日期用红色表示&lt;/li&gt;
&lt;li&gt;这样用RGB进行每个月份的过滤是最简单的。但是问题是每一个月份都需要进行3次过滤，并进行文字的汇总。&lt;/li&gt;
&lt;li&gt;文字的汇总本来是想要用tesseract来进行的，但是发现识别不出来，莫名的。可能是参数设定的不对导致的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;首先是将原始的工作日历按照月份进行切割，这样可以比较小块的进行识别，并且识别出来的信息对应到该月份，避免了以后识别时日期对应的错误哦&lt;/li&gt;
&lt;li&gt;切割(有手动版的和自动版的，自动版就是用opencv获得图片的长，宽，然后按照数据运算，切分成长多少，宽多少的块。但是有个问题就是图片中有除了想要的内容外的其他的文字，这些区域需要割掉。下面的是手动版的，精确一些)&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import itertools
x0=&quot;a:b&quot;
x1=&quot;c:d&quot;
x2=&quot;e:f&quot;
x3=&quot;g:h&quot;
y0=&quot;i:j&quot;
y1=&quot;k:l&quot;
y2=&quot;m:n&quot;
listx=[x0,x1,x2,x3]
listy=[y0,y1,y2]
listxy=itertools.product(listx,listy)
print(listxy)

(&apos;a:b&apos;, &apos;i:j&apos;)
(&apos;a:b&apos;, &apos;k:l&apos;)
(&apos;a:b&apos;, &apos;m:n&apos;)
(&apos;c:d&apos;, &apos;i:j&apos;)
(&apos;c:d&apos;, &apos;k:l&apos;)
(&apos;c:d&apos;, &apos;m:n&apos;)
(&apos;e:f&apos;, &apos;i:j&apos;)
(&apos;e:f&apos;, &apos;k:l&apos;)
(&apos;e:f&apos;, &apos;m:n&apos;)
(&apos;g:h&apos;, &apos;i:j&apos;)
(&apos;g:h&apos;, &apos;k:l&apos;)
(&apos;g:h&apos;, &apos;m:n&apos;)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;RGB过滤&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/rgb2hsv.jpg&quot; alt=&quot;rgb表&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import cv2
import numpy as np

img = cv2.imread(&quot;cropped1.jpg&quot;)

lower_green = np.array([35, 43, 46]) #这些值来自于上面的图表
high_green = np.array([77, 255, 255])

hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) #将rgb值转为hsv值

mask = cv2.inRange(hsv, lower_green, high_green) #设定蒙层
cv2.imshow(&apos;mask&apos;, mask)
cv2.imwrite(&quot;green.jpg&quot;, mask) #应用蒙层，保存图片

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;识别&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>go的文件引用</title><link>https://dididudu998.github.io/posts/go%E7%9A%84%E6%96%87%E4%BB%B6%E5%BC%95%E7%94%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/go%E7%9A%84%E6%96%87%E4%BB%B6%E5%BC%95%E7%94%A8/</guid><description>GOLANG的文件引用，可以这么简单</description><pubDate>Fri, 18 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;让go的文件引用变的和python一样简单&lt;/h1&gt;
&lt;p&gt;go因为有gopath的存在，导致在进行文件引用的时候需要在src下面进行，但是这样限制了随便编程的自由，我不喜欢。&lt;/p&gt;
&lt;p&gt;在前段时间的小项目中，找到了这样的方式，而且多次使用都没有问题。这里记录一下。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;比如我们创建了一个主程序名为mainrun.go&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们创建了一个子包，名为subrun.go,并且在subrun.go里面有个子函数client()&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们需要在mainrun.go里面引用这个client()函数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们可以这么干&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在mainrun.go的同目录下创建一个目录命名为example（这个名字随意）&lt;/li&gt;
&lt;li&gt;将subrun.go移动到example目录下&lt;/li&gt;
&lt;li&gt;在mainrun.go里面引用的时候可以这么写&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import (
	...
  subrun &quot;./example&quot;
  ...
)

func main() {
	...
  subrun.client()
  ...
}
	
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这样就和将subrun.go安装到src下面一样调用了。而且在进行go build的时候也是直接附带生成的，很方便。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;温故而知新，可以为师矣。&lt;/p&gt;
</content:encoded></item><item><title>备份git库到手机</title><link>https://dididudu998.github.io/posts/%E5%A4%87%E4%BB%BDgit%E5%BA%93%E5%88%B0%E6%89%8B%E6%9C%BA/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%A4%87%E4%BB%BDgit%E5%BA%93%E5%88%B0%E6%89%8B%E6%9C%BA/</guid><description>折腾</description><pubDate>Mon, 07 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;备份git库到安卓手机&lt;/h1&gt;
&lt;p&gt;本来想买一个移动硬盘的，但是觉得不是很有必要，主要是移动硬盘二手的风险比较大，但是一手的存这点代码实在是有点大材小用。&lt;/p&gt;
&lt;p&gt;刚好手机上面有外置的SD卡，将就先用这个吧。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;h3&gt;安装termux和openssh服务&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;手机下载termux，并安装&lt;/li&gt;
&lt;li&gt;安装完成后，apt-get update 一下&lt;/li&gt;
&lt;li&gt;安装apt install openssh并且运行sshd，启动sshd服务&lt;/li&gt;
&lt;li&gt;用数据线连接手机到电脑，然后adb push ~/.ssh/id_rsa.pub /sdcard/id_rsa_computer1.pub&lt;/li&gt;
&lt;li&gt;然后在手机上打开这个/sdcard/id_rsa_computer1.pub文件，复制里面的内容。&lt;/li&gt;
&lt;li&gt;在termux中vi ~/.ssh/authorized_keys,粘贴到里面，esc，:wq保存退出。&lt;/li&gt;
&lt;li&gt;ifconfig找到手机的ip地址&lt;/li&gt;
&lt;li&gt;在电脑上面 ssh 手机的ip地址 -p 8022，看看能不能访问&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;安装git和termux-tools&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;由于默认termux只能保存文件到手机的内置存储上，我们想要保存文件到外置的SD卡，需要安装个工具&lt;/li&gt;
&lt;li&gt;apt install termux-tools&lt;/li&gt;
&lt;li&gt;apt install git&lt;/li&gt;
&lt;li&gt;再安装个tree工具，pkg install tree&lt;/li&gt;
&lt;li&gt;安装完成后运行下tree storage&lt;/li&gt;
&lt;li&gt;会发现有几个链接，dcim/downloads/external-1/...&lt;/li&gt;
&lt;li&gt;我们要的是这个external-1，这个是链接到外置的SD卡的&lt;/li&gt;
&lt;li&gt;cd storage/external-1&lt;/li&gt;
&lt;li&gt;找到我们已有的库，在github或者其他的ssh/https的地址&lt;/li&gt;
&lt;li&gt;在external-1文件夹下，开始 git clone repo_url&lt;/li&gt;
&lt;li&gt;如果碰到权限问题，说什么readonly，就装个tsu吧&lt;/li&gt;
&lt;li&gt;直接 cd /sdcard/，在sd卡根目录建立文件夹，到里面去git clone就好了&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>macOS导出提醒信息</title><link>https://dididudu998.github.io/posts/macos%E5%AF%BC%E5%87%BA%E6%8F%90%E9%86%92%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/macos%E5%AF%BC%E5%87%BA%E6%8F%90%E9%86%92%E4%BF%A1%E6%81%AF/</guid><description>怀旧</description><pubDate>Wed, 25 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;导出macOS上面的提醒事件&lt;/h1&gt;
&lt;p&gt;很早很早之前，大概是刚拿到苹果笔记本的时候，做了很多的事情，都记录在了提醒事项里面。然后想要将这些信息导出来，看了apple官网的解释，但是操作不了。&lt;/p&gt;
&lt;p&gt;后来不知道是在哪里看到的，可以用下面的方式来导出信息，导出都是文字信息，我主要是为了看，所以就用这个方法。&lt;/p&gt;
&lt;h1&gt;方法&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;找到macOS上面的自动操作&lt;/li&gt;
&lt;li&gt;选择工作流程&lt;/li&gt;
&lt;li&gt;选择日历&lt;/li&gt;
&lt;li&gt;选择查找日历项目&lt;/li&gt;
&lt;li&gt;在查找里面选择提醒日历&lt;/li&gt;
&lt;li&gt;添加过滤器&lt;/li&gt;
&lt;li&gt;运行查找&lt;/li&gt;
&lt;li&gt;将结果拷贝出来即可&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>又搞一次elasticsearch</title><link>https://dididudu998.github.io/posts/%E5%8F%88%E6%9D%A5elasticsearch/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8F%88%E6%9D%A5elasticsearch/</guid><description>闲的</description><pubDate>Fri, 20 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;又搞一次elasticsearch&lt;/h1&gt;
&lt;p&gt;发现这周又搞一次的事情还真是多，先是搞了一次对DHCP的监控，搞了一阵发现原来在一个月前搞过了，后来因为并不实用就放弃了，这是彻底的晕头了。浪费时间。&lt;/p&gt;
&lt;p&gt;再下来，就是大概五六年前搞了elasticsearch+kibana+logstash+syslog的用于监控所有服务器事件日志的东西，这套系统其实觉得最有用的一次是有几个人的账户，莫名的总是会被锁定，最后到我这里来，我就用这个给搜索了下，发现他们都是把自己的账户绑定到服务了，但是在自己的电脑上改了密码，这个绑定的服务上面没有更新，导致不断的重试，最后被锁。还有就是审计的时候比较有用，查查谁的密码过期了，谁的账户乱登机器之类的小事情。&lt;/p&gt;
&lt;p&gt;过了这么些年，这边搞splunk，确实是有钱了就可以整。这个没话说。&lt;/p&gt;
&lt;p&gt;但是实际上真的大型企业用这个的还是比较铺张，毕竟这个东西不自由啊。&lt;/p&gt;
&lt;p&gt;又想起了elasticsearch这套玩意儿。不过我不再想去监控这些日志了。&lt;/p&gt;
&lt;p&gt;我监控下网络情况。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;先是开通一台CentOS7的虚拟机，双网卡，一个用来配置管理，一个用来接收mirror过来的数据包用于分析&lt;/li&gt;
&lt;li&gt;接着配置mirror，在vCenter里面将一个vSwitch的一个VLAN引入刚才开的虚拟机的对应的网卡的PortID&lt;/li&gt;
&lt;li&gt;看文档，来安装下packetbeat这个，还要记得安装一些依赖&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;packetbeat部分&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;默认安装后packetbeat在/usr/share/packetbeat这个文件夹&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置文件在 /etc/packetbeat/packetbeat.yml这里&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改的部分包括 要监听那块网卡，我的有明确的，所以就是那块mirror的，如果没有特别的就保持原样即可，什么都不需要改&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;但是要记得是在ELK都实现后，默认的kibana中是没有dashboard的，为了有个现成的dashboard，只需要运行下packetbeat setup，它就自动的下载对应的dashboard json文件了，省事。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动服务的时候这样&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;packetbeat -e -c /etc/packetbeat/packetbeat.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后应该能看到一些翻滚过来的数据&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;配置java环境&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;我不得不说我很烦JAVA环境，但是配置还是有必要记一下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alternatives --config java 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用这个获取java的路径，前提是你装过了yum install java。&lt;/p&gt;
&lt;p&gt;或者按照下面的方式，获得最终的路径&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;which java
ls -lrt $(which java)
ls -lrt $(上一步的结果)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;找到路径后就可以往配置文件(~/.bashrc)里面写了&lt;/p&gt;
&lt;p&gt;比如找到了这个/usr/lib/jvm/java-1.8.x-openjdk-1.8.x/jre/bin/java&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export JAVA_HOME=/usr/lib/jvm/java-1.8.x-openjdk-1.8.x
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;写完后保存，然后source一下更新即可。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;ELK部分&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;按照步骤来，整个的结构式，packetbeat分析数据包，然后将数据包的情况发送给logstash，logstash经过筛选，再发送给elasticsearch，然后kibana用来进行展示。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;建议ELK这三个都用tgz的方式下载解压来安装，用yum的安装到时候会发现路径很烦。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;因为elasticicsearch不让用root账户，所以还得创建一个普通账户&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建完后，还需要chown -R 普通账户 elasticsearch文件夹 赋权一下。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我碰到的问题是，elasticsearch的启动怎么都不认java环境。后来直接修改elasticsearch的env运行文件才好，因为它默认里面少了那个jre的子目录路径，真是折腾&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;elasticsearch没啥好弄的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;到logstash了，这个主要是配置一下logstash.conf文件,其实什么都没配置。就是说我接受5044端口发过来的东西，然后我将这些东西发送给elasticsearch，而elasticsearch是本地机的9200端口&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;input {
  beats {
    port =&amp;gt; 5044
  }
}

output {
  if [source_ip] not in [&apos;10.200.100.100&apos;,&apos;127.0.0.1&apos;] {
        elasticsearch {
                hosts =&amp;gt; [&quot;http://localhost:9200&quot;]
                index =&amp;gt; &quot;%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}&quot;
    #user =&amp;gt; &quot;elastic&quot;
    #password =&amp;gt; &quot;changeme&quot;
  }
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;现在试着启动packetbeat，logstash，elasticsearch&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;logstash启动的时候 ./bin/logstash -f ./config/logstash&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;elasticsearch要用普通用户 ./bin/elasticsearch&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果没事，继续kibana&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kibana有个/etc/kibana/kibana.yml的配置文件，我主要是修改下里面的server.host为0.0.0.0，这样外面也好访问&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动kibana，如果用root的话，会提示，照着加参数就好了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用netstat -nltp看看端口是不是都ok了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果什么9200,5601,5044,9300,9600都有了，那么就开始去开通防火墙，让外面能访问kibana的5601端口即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;因为本身就有nginx的机器，就做了个反向代理。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/kibana.jpg&quot; alt=&quot;kibana&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>获取github上的信息</title><link>https://dididudu998.github.io/posts/%E8%8E%B7%E5%8F%96github%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%8E%B7%E5%8F%96github%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BF%A1%E6%81%AF/</guid><description>闲的</description><pubDate>Tue, 17 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;不是问题，就是想要看看GitHub上一些Nb的项目，看看别的人都是怎么玩的。&lt;/p&gt;
&lt;p&gt;然后GitHub自带search和api，刚好复习下怎么抓信息下来。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;首先确定能够提供搜索的页面URL&lt;/p&gt;
&lt;p&gt;https://api.github.com/search/repositories?q=language:python&amp;amp;sort=stars&amp;amp;per_page=100&lt;/p&gt;
&lt;p&gt;这里q=后面的都是提供的搜索的参数，这些参数在github的develop API文档里面有写，需要看看的。&lt;/p&gt;
&lt;p&gt;但是要注意&amp;lt;font color=&quot;red&quot;&amp;gt;per_page=100&amp;lt;/font&amp;gt;,这个如果不带，那么仅返回30个item出来，这个是默认的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我用自己的github账号申请了token，但是发现也并不是有什么用，用匿名的也可以获得自己想要的信息&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;提供headers是必须的&lt;/p&gt;
&lt;p&gt;headers={&apos;Accept&apos;:&apos;application/vnd.github.v3+json&apos;}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下面是一些编码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;r=requests.get(url,headers)
resp=r.json()
#打印下resp会发现是一个字典
#解析这个字典，提取list
respd=resp[&apos;items&apos;]
for e in respd:
	print(f&quot;\nName: {e[&apos;name&apos;]}&quot;)
	print(f&quot;\nURL: {repo_dict[&apos;html_url&apos;]}&quot;)
  print(f&quot;\nDescription: {repo_dict[&apos;description&apos;]}&quot;)

&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据query的不同，可以解析获得不同的结果，比如star数量，用的语言，是否带有某些关键字等等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我列出来一些上万颗星的库，python的库，go的库，以及一些fork很多的电子书的库等&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>用powershell导出ova</title><link>https://dididudu998.github.io/posts/%E7%94%A8powershell%E5%AF%BC%E5%87%BAova/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8powershell%E5%AF%BC%E5%87%BAova/</guid><description>闲的</description><pubDate>Tue, 10 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;这垃圾的VMware现在全部搞web来访问，垃圾的flash总是要用，反应慢的要死。&lt;/p&gt;
&lt;p&gt;今天早上想要导出个虚拟机，简直是耗费了要一个小时，折腾死了。&lt;/p&gt;
&lt;p&gt;我就想问搞VMware Vcenter客户端管理的项目经理是吃屎了吗，非要用web来访问和控制，而且每一个版本的升级总会有bug出现。&lt;/p&gt;
&lt;p&gt;垃圾的要死。&lt;/p&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;p&gt;骂归骂，还是要解决问题的。&lt;/p&gt;
&lt;p&gt;想着搞ssh直接从存储库里面拉出来好了。但是那个出来得直接是vmdk文件。我想要一个ovf的，以后可以从控制台导入的。这个方法放弃。&lt;/p&gt;
&lt;p&gt;后来搜到还是搞vmware的powershell。&lt;/p&gt;
&lt;p&gt;最终还是要感谢微软，现在win10的powershell集合了vmware 的powercli的部分命令。&lt;/p&gt;
&lt;p&gt;废话不说，干就是了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;connect-viserver -server vcenter_ip -user username -pass password 

get-vm vm_name | Export-VApp -Destination &quot;f:\&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;等待结束。&lt;/p&gt;
&lt;p&gt;我只能说vmware如果以后还是web的客户端管理模式，我以后就只用接口了，这垃圾的web console。&lt;/p&gt;
</content:encoded></item><item><title>升级nginx</title><link>https://dididudu998.github.io/posts/%E5%8D%87%E7%BA%A7nginx/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8D%87%E7%BA%A7nginx/</guid><pubDate>Mon, 26 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;Nessus上周报nginx由于http2的漏洞，可能导致ddos的攻击，并且将安全级别设定为high。&lt;/p&gt;
&lt;p&gt;用yum update做了个升级，但是没仔细看，这样升级后的版本还是受到影响的。&lt;/p&gt;
&lt;p&gt;没法只好从根上进行解决，就是按照Nessus的报告说明，升级到最新版的nginx。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;到nginx.org下载最新的tar.gz文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解压备用，这里假设解压到/root/nginx1.17.x/这个目录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;确定当前运行的nginx的信息&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nginx -v  //用于确定当前的nginx版本&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;nginx -V //用于确定当前nginx使用的配置项，拷贝输出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;进入/root/nginx1.17.x目录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;运行./configure 加上当前nginx的配置项（就是b的输出），如果出现报错，酌情进行一些项目的修改&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我这里因为以前是yum安装的，有些依赖没有及时更新，在进行./configure的时候出现多个依赖的问题，这边用这个来解决的&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;yum install openssl-devel zlib zlib-devel libxslt-devel gd gd-devel geoip-devel gperftools perl-devel perl-ExtUtils-Embed -y&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;上面的依赖安装完毕后，再进行./configure 加配置参数的事情就顺利完成了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再下来对当前的nginx的运行文件进行备份，这个过程不影响当前运行的nginx进程&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mv /usr/sbin/nginx /usr/sbin/nginx.bak&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;还是在/root/nginx1.17.x目录下，运行make命令，进行编译&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;编译顺利完成后会进行提示，并且在objs目录下会有nginx的文件出现&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;复制该文件到原位置&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cp ./objs/nginx /usr/sbin/nginx&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;复制完成后，nginx -t来检测下nginx.conf的配置文件是否没有错误&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果提示有错误，出现模块的版本替换问题，最好就是直接到module文件夹下，对这些个module的配置文件用#号进行注释掉&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;还有就是原来我的那些conf.d目录下的conf文件都是开了ssl的，但是这个新版本里面的ssl on这个指令已经被废除了，所以在conf文件里面也要将这行ssl on注释掉&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再进行nginx -t的测试，没有错误了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;依然在 /root/nginx1.17.x目录下运行 make upgrade进行热升级&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以后使用service nginx restart 或者service nginx reload 都成&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;访问下页面，看看没有问题，nginx -v也显示为高版本了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;结论&lt;/h1&gt;
&lt;p&gt;nginx是非常成熟稳定的应用程序了。在linux的世界中，所有基于文本配置的程序都是很稳定，很有年头的事物，这种稳定，帮助后来者节约大量的时间来部署和修复错误。类似BIND的这种，超级易用，超级稳定，这也是我们都喜欢linux的原因。让有想法的人做更多有效果/结果的事情，而不是大量修复性的事务。&lt;/p&gt;
&lt;h1&gt;补充&lt;/h1&gt;
&lt;p&gt;2025年10月28日，从1.20.1更新到1.29.2的最新版本了，基本上按照对应的步骤进行，但是有个问题是关于perl的，出现了perl的模块和1.29.2的不兼容，因为当前没有要用perl的部分，直接dnf remove perl perl-base后，nginx -t就通过了。问题解决。
顺便增加了server_tokens off选项，展示错误页后不在显示nginx版本了。&lt;/p&gt;
</content:encoded></item><item><title>Win10下设定OpenVPN服务器</title><link>https://dididudu998.github.io/posts/window10-opendns%E6%9C%8D%E5%8A%A1%E5%99%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/window10-opendns%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid><pubDate>Wed, 21 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;大概上周的时候在公司，为了避开跨网管理的问题，部署了基于Docker的openvpn服务器。运行起来还是很好的。&lt;/p&gt;
&lt;p&gt;但是在屋里的旧电脑奔腾双核4GB内存Windows10上面跑docker感觉很不方便，主要还是现在的Docker for Windows和Windows内置的defender有点冲突，安装的时候如果不把defender关闭，则会安装失败。&lt;/p&gt;
&lt;p&gt;想了下，既然openVPN有原生的for Windows的版本，为什么不用这个呢。&lt;/p&gt;
&lt;p&gt;说干就干。至于怎么在家用路由器上面开端口映射，以及怎么在Windows上面允许inbound连接就不提了，自己做一下，很快的。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;p&gt;主要的参考文档是这个，可以说写的超级详细，国内也有。不过比较下来，还是这个好很多。&lt;/p&gt;
&lt;p&gt;链接这里：&lt;a href=&quot;https://wiki.teltonika.lt/view/OpenVPN_server_on_Windows&quot;&gt;Wiki Knowledge OpenVPN on Windows&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我还是简单提一下比较好，以免到时候这个页面因为某些原因不可访问了。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;下载openVPN for Windows的安装包，安装的时候将easy-rsa给勾上，用于下面生成证书私钥之类的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;命令行下进入easy-rsa目录，运行下面的指令&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;init-config&lt;/p&gt;
&lt;p&gt;vars&lt;/p&gt;
&lt;p&gt;clean-all&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下面就是申请证书&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;//创建ca，里面的commonName需要填好自己从外面访问过来的FQDN，我是申请的DDNS域名，所以填这个域名就好&lt;/p&gt;
&lt;p&gt;build-ca&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;//创建服务器证书，输入个比较好记的comon Name&lt;/p&gt;
&lt;p&gt;build-key-server server&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;//创建客户端证书&lt;/p&gt;
&lt;p&gt;build-key user1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt; &amp;gt; //创建tls加密用的密码
 &amp;gt;
 &amp;gt; build-dh
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后将ca.crt,server.crt,server.key从easy-ras的key文件夹下拷贝到config目录下&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从sample-config中拷贝server.ovpn也到config这个目录下，做些调整。为了增加安全性，我还用上了HMAC firewall，所以需要加上那个ta.key，ta.key这么创建：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;openvpn —genkey —secret ta.key&lt;/p&gt;
&lt;p&gt;//创建完成后，也一样的拷贝到config目录下，并在server.ovpn中添加一下&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;ca &quot;C:\\Program Files\\OpenVPN\\config\\ca.crt&quot;
cert &quot;C:\\Program Files\\OpenVPN\\config\\server.crt&quot;
key &quot;C:\\Program Files\\OpenVPN\\config\\server.key&quot;
dh &quot;C:\\Program Files\\OpenVPN\\config\\dh2048.pem&quot;
tls-auth &quot;C:\\Program Files\\OpenVPN\\config\\ta.key&quot; 0 # This file is secret
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;剩下的依次类推&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;测试下，服务端用gui工具能不能连接成功，如果连接成功了，就开始做客户端的ovpn文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;想要对服务端的OpenVPN实现开机自动启动，就到service里面去将OpenVPN这个服务设定为自动，然后开启即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;客户端的ovpn文件，模版如下所示：&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;client
nobind
dev tun
remote-cert-tls server
remote myddns.domain.com 8294 udp4
resolv-retry infinite
keepalive 5 10
persist-key
persist-tun
verb 3
&amp;lt;ca&amp;gt;
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
&amp;lt;/ca&amp;gt;

&amp;lt;cert&amp;gt;
-----BEGIN CERTIFICATE-----
《这里是user1.
-----END CERTIFICATE-----
&amp;lt;/cert&amp;gt;

&amp;lt;key&amp;gt;
-----BEGIN PRIVATE KEY-----
《这里是user1.key》
-----END PRIVATE KEY-----
&amp;lt;/key&amp;gt;

key-direction 1
154 &amp;lt;tls-auth&amp;gt;
155 #
156 # 2048 bit OpenVPN static key
157 #
158 -----BEGIN OpenVPN Static key V1-----
  《这里加上ta.key的内容》
175 -----END OpenVPN Static key V1-----
176 &amp;lt;/tls-auth&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;重头戏&lt;/h1&gt;
&lt;p&gt;会发现，当你的客户端的配置文件和服务器端的文件都好的，而且能互相连接上，日志也没有问题的时候，你的客户端却无法访问internet。&lt;/p&gt;
&lt;p&gt;原理就不说了，现在说怎么做：参看这里&lt;a href=&quot;https://forums.openvpn.net/viewtopic.php?t=20765&quot;&gt;fix internet connect&lt;/a&gt;, 我直接摘抄在下面了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Using this settings on Windows 10 :
&lt;em&gt;Start -&amp;gt; Right-click My Computer -&amp;gt; Manage&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Services&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Right-click Routing and Remote Access -&amp;gt; Properties -&amp;gt; AutomaticRight-click Routing and Remote Access -&amp;gt; Start&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Next:Control Panel&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Network and Sharing Center&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;*Local Area Connection *&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Properties&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sharing&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Tick the box &quot;Allow other network users to connect through this computer&apos;s Internet connection&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;From the drop-down list select &quot;Local Area Connection 2&quot;, or whatever is the connection name of your TAP server connection.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;regedit&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Value: IPEnableRouter&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Type: REG_DWORD&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Data: 0x00000001 (1)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It Works !!!!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然后就可以愉快的上网了，做个tracerout发现，客户端先走到服务端的网关，然后再出去。说明整个的VPN实现了。&lt;/p&gt;
&lt;p&gt;补充：&lt;/p&gt;
&lt;p&gt;当你启用internet共享到TAP网卡的时候，要将TAP网卡的IP地址和DNS设定为自动获得。
如果TAP网卡的地址不是默认的10.8.0.x的时候，客户端可以连接OpenVPN网络，但是会无法访问其他internet网络。&lt;/p&gt;
</content:encoded></item><item><title>Bind-Dhcpd-DDNS</title><link>https://dididudu998.github.io/posts/bind-dhcpd-ddns/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/bind-dhcpd-ddns/</guid><pubDate>Wed, 14 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;前阵子做了个webdns的东西，用来给生产和测试环境的机器注册dns的。&lt;/p&gt;
&lt;p&gt;但是测试环境的dns我觉得还是自动的来比较好，毕竟我在做测试机器部署的时候已经可以定义机器名了，部署完成后，直接就可以机器名+测试域名的方式进行访问，岂不方便。&lt;/p&gt;
&lt;p&gt;当然还是有人需要手动注册的，所以这个webdns的页面还是要留着，前几天就有人要做类似load balance的需求，一个ip对应多个域名的。&lt;/p&gt;
&lt;p&gt;最终结果两种，一种就是保持原样，注册用webdns实现。还有就是webdns不用了，所有注册都自动。因为我没解决webdns实现的时候会修改dns文件，但是修改后，（即使做了改进，不会出现语法错误的提示而导致dns服务中断）slave dns服务器不能同步。。。。，找了大半天也没有解决方案，放弃了。&lt;/p&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;p&gt;看了下DDNS的部分，刚好Bind和DHCP服务器都在我的控制下，说干就干。&lt;/p&gt;
&lt;p&gt;要修改的包括两个服务器的配置，一个是Bind，也就是DNS服务器，这里是/etc/named.conf 文件；一个是DHCP服务器，这里/etc/dhcp/dhcpd.conf&lt;/p&gt;
&lt;p&gt;下面贴出配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DNS部分&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;其中的rndc.key是可以生成的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rndc-confgen
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;named.conf文件部分&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;        zone &quot;test.example.com&quot; IN {
        type master;
        file &quot;test.example.com.zone&quot;;
//      allow-update { none; };
        allow-update { key rndc-key; };
        allow-transfer {10.214.8.24; 10.214.8.25;};
        };

include &quot;/etc/named.root.key&quot;;
include &quot;/etc/named.rfc1912.zones&quot;;
include &quot;/etc/rndc.key&quot;;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DHCP部分&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;option domain-name &quot;test.example.com&quot;;
ddns-update-style interim;
update-static-leases on;
one-lease-per-client on;
 
 //这里的rndc-key要和dns服务器上使用的一样，否则通讯失败
key rndc-key {  
        algorithm hmac-md5;
        secret &quot;qASUM2NKt7udawe10021==&quot;;
}

zone test.example.com. {
        primary 10.214.x.x;
        key rndc-key;   
}

subnet 10.214.x.0 netmask 255.255.254.0 {
	range .....;
	option routers 10.214.x.1;
	
	allow client-updates;
	update-optimization off;
	update-conflict-detection on;
	
	group {
	 ....... //这些是绑定mac地址的机器，固定IP
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;弄好了上面两个，重启dhcp服务和named服务就可以了。slave DNS的配置和其他的slave zone的相似。&lt;/p&gt;
&lt;p&gt;需要说明的是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;当*.jnl文件不能创建的时候，是权限问题，用chmod 775 /var/named后重启下named服务一般就好了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;服务都启动后，要等待一会儿，只要jnl生成成功，zone文件就会及时更新的。不放心可以看看/var/log/message&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dhcpd.conf文件中的domain-name必须写对&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;检查zone文件，就会有A记录和TXT记录以及$ORIGIN TTL值的新机器进来&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;update-optimization 解释如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-static-leases flag;

	    The	update-static-leases flag, if enabled, causes the DHCP	server
	    to	do  DNS	 updates  for  clients even if those clients are being
	    assigned their IP address using a fixed-address statement  -  that
	    is,	the client is being given a static assignment.	 This can only
	    work with the interim DNS update scheme.   It is  not  recommended
	    because  the  DHCP	server	has no way to tell that	the update has
	    been done, and therefore will not delete the record	when it	is not
	    in	use.	Also, the server must attempt the update each time the
	    client renews its lease, which could have  a  significant  perfor-
	    mance  impact in environments that place heavy demands on the DHCP
	    server.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;bind系统自生成的文件，如果手动做了修改，很容易导致dns服务出错，提示zone文件语法错误，无法loaded。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;折腾了半天，用python对文件进行内容的替换，不影响结构，也不影响dns服务的情况下，却导致slave dns的zone文件不能更新，提示“ refresh: unexpected rcode (SERVFAIL) from master ”。Bind对于少量的DNS管理是比较OK的，但是大型的DNS的话，还是建议使用后台有数据库做数据管理的比较好一些。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;准备有时间的话，将bind换成powerdns之类的dns服务器&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Docker openVPN跨网实践</title><link>https://dididudu998.github.io/posts/docker-openvpn-%E8%B7%A8%E7%BD%91%E5%AE%9E%E8%B7%B5/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/docker-openvpn-%E8%B7%A8%E7%BD%91%E5%AE%9E%E8%B7%B5/</guid><pubDate>Mon, 12 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;由于企业安全的限制，访问数据中心以及关键基础架构的时候只能在指定的网络进行，普通的网段无法进行访问的操作。&lt;/p&gt;
&lt;p&gt;以前试着用反向代理的方式来解决，但是反向代理存在稳定性问题，而且不是所有的情况下都可以正常的使用。&lt;/p&gt;
&lt;p&gt;为此，想着用做vpn的方式来实现，当我在普通的网络的时候可以远程接入专用网络做一些操作。&lt;/p&gt;
&lt;h1&gt;步骤&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;目前我的环境是由一台windows 台式电脑，接在核心网络，但是日常使用的时候是macOS，macos是接入普通网络的，这个普通网络涵盖了整个的楼宇，但是核心网络我只有用Windows电脑才可以。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;为此想着在Windows电脑上搭建VPN服务，在选择VPN服务的时候，想到使用开放的openVPN，然后选择使用docker的模式来实现，既不会影响我现在Windows电脑上面的应用，也不妨碍有需要的时候可以用macOS拨入，毕竟拨入的流量非常的小，对于整体的稳定性来说影响要做到比较小，就是小动静，解决问题即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装docker for windows，参看这里&lt;a href=&quot;https://nickjanetakis.com/blog/setting-up-docker-for-windows-and-wsl-to-work-flawlessly&quot;&gt;docker on windows wsl&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重要的就是暴露出0.0.0.0:2375这个步骤，并且服务自动启动&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后就是给Windows电脑部署开发人员工具，Ubuntu18.04LTS服务器&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;直接在Windows10的Microsot Store里面搜索即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后安装，启动&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动后，就是安装docker服务&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/ubuntu_in_win.jpg&quot; alt=&quot;ubuntu18.04&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;检验下docker服务是否正常运行，我在部署的时候发现docker服务会存在无法获得链接点的错误，后来怎么弄好的也忘记了，应该可以搜索的到解决方案&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后就是重头戏了，首先感谢大神已经做好的文档和工具，我是先搜索到这里&lt;a href=&quot;https://medium.com/@gurayy/set-up-a-vpn-server-with-docker-in-5-minutes-a66184882c45&quot;&gt;Set Up a VPN Server With Docker In 5 Minutes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据这里，在我的一个独立网段的ubuntu系统里创建好了一个openVPN服务，并且在我的macOS上连接正常。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后去了github的源，也就是这里&lt;a href=&quot;https://github.com/kylemanna/docker-openvpn&quot;&gt;kylemanna&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;摘抄具体步骤如下，以免github上不去了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; OVPN_DATA=&quot;ovpn-data-example&quot;
 docker volume create --name $OVPN_DATA

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM
这里的vpn.servername.com需要替换为自己真正的服务器地址或者域名

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn ovpn_initpki    

开启openvpn服务
docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn

创建证书
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass

导出客户端配置文件
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_getclient CLIENTNAME &amp;gt; CLIENTNAME.ovpn```


&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在已经运转正常的Windows10里面的Ubuntu18里面gitclone这个库，按照操作文档执行即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;为了可以让这个容器可以在Ubuntu启动后自动重启，可以使用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker update --restart=always container_name
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我这里因为专网前面还有一个路由器，所以做了个一个防火墙规则和端口转发的规则才可以。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;也就是普通的网络要访问UDP 3000端口，我先得设定允许inbound的访问到我的路由器所谓的公网的IP的UDP3000端口，然后还要将这个公网的UDP 3000端口转发给我现在的Windows电脑的IP的UDP 3000上面，这样才是一条完整的通路。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;openVPN的客户端用的是TunnelBlick这个，上面的文档有提到。忘了在哪里下载的，搜索一些也就是了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;总之是实现了。速度还是不错的，而且还是挺稳定的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/tunnelblick.jpg&quot; alt=&quot;tunnelblick&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&amp;lt;b&amp;gt;补充&amp;lt;/b&amp;gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当将生成的profile文件，也就是.ovpn文件，是同一个用户的时候，导入openVPN客户端，在这里同时为user1账户时，发现当手机的VPN连接后，电脑的VPN就会中断。&lt;/li&gt;
&lt;li&gt;为此，创建另外一个账户user2来生成新的配置文件，给到不同的设备。&lt;/li&gt;
&lt;li&gt;配置方法和文档中提到的相同&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;docker run -v $vpndata:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full user2 nopass


docker run -v $vpndata:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient user2 &amp;gt;user2.ovpn
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这样给除了macOS设备的其他设备使用user2这个配置就可以互相不影响了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>MacOS的性能诊断</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Emacos%E7%9A%84%E6%80%A7%E8%83%BD%E8%AF%8A%E6%96%AD/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Emacos%E7%9A%84%E6%80%A7%E8%83%BD%E8%AF%8A%E6%96%AD/</guid><pubDate>Thu, 25 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;MacOS 的性能诊断&lt;/h1&gt;
&lt;h2&gt;Apple 的开发者网站提供的信息&lt;/h2&gt;
&lt;p&gt;包含有性能工具，监控工具等一些基本的信息&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/library/archive/documentation/Performance/Conceptual/PerformanceOverview/PerformanceTools/PerformanceTools.html&quot;&gt;developer  of Apple.com&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;sc_usuage&lt;/li&gt;
&lt;li&gt;fs_usage&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;方法1&lt;/h2&gt;
&lt;p&gt;这个是延续下来的方法，就是使用Dtrace，不过现在的MacOS系统对于安全方面进行了增强，系统的完整性检测导致Dtrace无法正常运行。如果只是一个可以运行的二进制文件，看论坛上面的可以将它拷贝到/tmp目录后运行，然后执行Dtrace，就能绕过系统完整性检测，获得结果。&lt;/p&gt;
&lt;p&gt;至于如何关闭系统完整性检测，可以到网上搜搜，不过我没有这样的操作。&lt;/p&gt;
&lt;p&gt;对于应用程序的性能检查，这个是最好的方式。因为只有这些的指令可以从底层来观察和介入应用程序，从而获得最真实的信息。&lt;/p&gt;
&lt;h2&gt;方法2&lt;/h2&gt;
&lt;p&gt;有一本书，叫做《MacOS X internal》，我可能下来会读读，说可以使用这个命令看看&amp;lt;font color=red&amp;gt;vmmap&amp;lt;/font&amp;gt;. 可以看到这个命令仅仅是对于进程调用虚拟内存的展现，但是可以作为性能判断的一个要素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NAME
     vmmap -- Display the virtual memory regions allocated in a process

SYNOPSIS
     vmmap [-w] [-v] [-pages] [-interleaved] [-submap] [-allSplitLibs] [-noCoalesce] [-summary] pid |
           partial-executable-name | memory-graph-file [address]

DESCRIPTION
     vmmap displays the virtual memory regions allocated in a specified process, helping a programmer under-
     stand how memory is being used, and what the purposes of memory at a given address may be.

     vmmap requires one argument -- either the process ID or the full or partial executable name of the
     process to examine, or the pathname of a memory graph file generated by leaks or the Xcode Memory Graph
     Debugger.

     If the optional address is given, information is only shown for the VM region containing that address
     (if any) and the regions around it.

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还有就是看看文件的实时读取情况,利用&amp;lt;font color=red&amp;gt;fs_usage&amp;lt;/font&amp;gt;.参见下面的说明，它可以获得文件系统的活动状态。也是一个可以参考的要素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NAME
     fs_usage -- report system calls and page faults related to filesystem activity in real-time

SYNOPSIS
     fs_usage [-e] [-w] [-f mode] [-b] [-t seconds] [-R rawfile [-S start_time] [-E end_time]] [pid | cmd
              [pid | cmd] ...]

DESCRIPTION
     The fs_usage utility presents an ongoing display of system call usage information pertaining to
     filesystem activity.  It requires root privileges due to the kernel tracing facility it uses to oper-
     ate.  By default, the activity monitored includes all system processes except the running fs_usage
     process, Terminal, telnetd, telnet, sshd, rlogind, tcsh, csh, sh, and zsh.  These defaults can be over-
     ridden such that output is limited to include or exclude a list of processes specified by the user.

     The output presented by fs_usage is formatted according to the size of your window.  A narrow window
     will display fewer columns of data.  Use a wide window for maximum data display.  You may override the
     window formatting restrictions by forcing a wide display with the -w option.  In this case, the data
     displayed will wrap when the window is not wide enough.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还有就是最常用的&amp;lt;font color=red&amp;gt;lsof&amp;lt;/font&amp;gt;,用于检查打开的文件以及网络连接状态。&lt;/p&gt;
&lt;p&gt;​	比较常用的是 ：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;				1. lsof -p PID
				2. lsof /usr/sbin/httpd
				3. lsof -c httpd  # 包含httpd
				4. lsof -i udp
				5. lsof -i tcp
				6. lsof -i tcp:80
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt; An  open  file  may be a regular file, a directory, a block special file, a character special file, an executing text reference, a library, a stream or a network
       file (Internet socket, NFS file or UNIX domain socket.)  A specific file or all the files in a file system may be selected by path.

       Instead of a formatted display, lsof will produce output that can be parsed by other programs.  See the -F, option description, and the OUTPUT FOR OTHER PROGRAMS
       section for more information.

       In  addition  to  producing  a  single output list, lsof will run in repeat mode.  In repeat mode it will produce output, delay, then repeat the output operation
       until stopped with an interrupt or quit signal.  See the +|-r [t[m&amp;lt;fmt&amp;gt;]] option description for more information.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>人们为什么会生病4</title><link>https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%854/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%854/</guid><pubDate>Tue, 16 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;第一推动系列之人们为什么会生病4&lt;/h1&gt;
&lt;h2&gt;接上篇&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;人类早期由于食物的缺乏，导致婴儿出生率极低，而且生存的时间也很短。并且由于卫生条件的匮乏，寄生虫以及初级的病毒就导致了大量的死亡现象。所以初期人口的增长率比较低&lt;/li&gt;
&lt;li&gt;随着人类社会的进步，当食物开始变得不那么匮乏的时候，增长率变得非常快。早期人类的战争很多时候是由于食物的短缺产生的。&lt;/li&gt;
&lt;li&gt;人类本性中好的一面主要表现在：群体内友善，群体间敌视。&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>人们为什么会生病2</title><link>https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%852/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%852/</guid><pubDate>Fri, 12 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;第一推动系列之人们为什么会生病(2)&lt;/h1&gt;
&lt;h2&gt;接上篇&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;太阳光伤害皮肤细胞的原因不在于热力学，而在于光化学反应引起的物质变化。光化学反应所产生的不正常化合物和死细胞会招致免疫系统的攻击。&lt;/li&gt;
&lt;li&gt;表皮中负责将异物呈递给免疫系统的事郎格罕细胞。它对于波长在290-320纳米的短波紫外线（UV-B）有复杂的反应。该细胞分泌的一种激素能阻断神经活动。UV-B紫外线能抑制皮肤郎格罕细胞，从而阻断它对抗原作出反应。皮肤癌的病人缺乏这样的敏感性。&lt;/li&gt;
&lt;li&gt;某些防晒霜可以阻断UV-B，防止日光灼伤，但是允许波长320-400纳米（UV-A）通过。UV-A也会伤害皮肤中的免疫细胞。超量的UV-A，事情反而更糟。&lt;/li&gt;
&lt;li&gt;番茄和马铃薯的叶片受伤后，全身都会产生毒素（蛋白质酶抑制剂）。植物没有神经系统，但是它有电信号和激素系统。，能够把某个局部发生的事故广而告之。有些白杨树的信息交流系统更加惊人，甚至可以通知附近其他的白杨树&lt;/li&gt;
&lt;li&gt;一片叶子受伤后，一种挥发性化合物“甲基茉莉酸”从伤处挥发，可以“告知”附近的叶片分泌蛋白酶抑制剂，临近的树上的叶片也会发生这种反应。它可以让昆虫吃后不舒服。&lt;/li&gt;
&lt;li&gt;内行的困出，在进食之前会首先切段供应叶片的主脉，使得植物不能释放更多的毒素，影响它进食。&lt;/li&gt;
&lt;li&gt;人体会对与霉坏的气味产生排斥的反应。吞下去的毒素可以被胃酸和消化酶分解。胃黏膜上覆盖着一层黏液，可以保护胃免受毒素和胃酸的伤害。如果某些细胞受了侵害，损伤的效应也很短暂，因为胃壁和肠壁细胞会定期脱落更新。&lt;/li&gt;
&lt;li&gt;如果毒素被胃和肠吸收，它们将被血液带到肝脏，在肝脏，酶可以改造某些分子使得它们变得无害，或者与某些分子结合再从胆汁排入肠道。毒素分子比较少的时候，将很快被肝细胞的受体所摄取，并迅速被肝脏的各种解毒酶处理掉。&lt;/li&gt;
&lt;li&gt;草酸是另外一种植物防御毒素。在大黄叶中的浓度非常高。它会结合金属离子，特别是钙离子，形成难溶于水的草酸钙。绝大多数的尿路结石都是由草酸钙组成的。&lt;/li&gt;
&lt;li&gt;但是结果表明，摄取低钙饮食的人反而是尿路结石的高位人群。因为食物中的钙在肠道中与草酸结合变成不溶的盐，不能被吸收。如果食物中钙的含量太少，过量的草酸就会被人体吸收。&lt;/li&gt;
&lt;li&gt;毛地黄和马利筋属于植物制造糖苷，可以干扰维持心率的电脉冲信号的传导。&lt;/li&gt;
&lt;li&gt;如果体内的毒素太多，肝脏处理不过来，那么这些毒素就会进入人体的循环系统，引起全身的伤害。&lt;/li&gt;
&lt;li&gt;通俗的讲，我们遵循我们的当地的文化习俗是十分明智的，就是不去接触和吃喝我们不了解的食物。这样避免了我们的身体的伤害。&lt;/li&gt;
&lt;li&gt;实验证据表明，代谢活跃的组织比处于休眠状态的组织更易受伤害，快速分裂的细胞比休止期细胞更易受伤害，有待分化的细胞比已分化的细胞更易受伤害。&lt;/li&gt;
&lt;li&gt;妊娠反应，晨吐的目的在于使的胎儿接触的毒素的机会减到最小。早起的胚胎对于母亲来说是一个很小的营养的消费者，正常的母亲即使少量的饮食也足以提供胚胎的营养需求，但是如果此时，吃到有毒素或者霉菌的食物，将很容易导致胚胎的流产或着死亡。医学表明，容易晨吐的妇女更容易出生健康的宝宝。&lt;/li&gt;
&lt;li&gt;此时厌恶食物，是为了保护胎儿。即使痛苦，也是为了一个健康的家庭的利益所需要付出的代价。&lt;/li&gt;
&lt;li&gt;当婴儿长大到儿童的时候，往往他们厌恶蔬菜。特别是气味强烈的蔬菜，例如洋葱和西兰花，因为它们含有更多的植物毒素。但是当儿童慢慢的成长到少年的时候，他们会改变这种现象。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>人们为什么会生病3</title><link>https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%853/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%853/</guid><pubDate>Fri, 12 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;第一推动系列之人们为什么会生病(3)&lt;/h1&gt;
&lt;h2&gt;接上篇&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;近视是由于眼球过度生长导致的，但是根本原因是由于基因导致的。&lt;/li&gt;
&lt;li&gt;人体的每一个细胞中的DNA都含有一串120亿个ACTG这样的碱基分子。&lt;/li&gt;
&lt;li&gt;一个DNA分子就像是一架螺旋的梯子，两边由交替变换的磷酸和脱氧核糖的单元组成。信息就放在梯子的横杠上，这些横杠由成对的碱基分子组成，包括A，C，G，T。&lt;/li&gt;
&lt;li&gt;人类大约有95%的DNA不编辑蛋白质，只有约5%的DNA可以分成大约十万个功能单位，这些被称为基因。&lt;/li&gt;
&lt;li&gt;苯丙酮尿症，其纯合子不能处理正常食物中所含有的常量苯丙氨酸，表现为智力发育停滞。对于这样的群体，只要控制后天的食物中不含有苯丙氨酸就可以预防智力发育障碍。&lt;/li&gt;
&lt;li&gt;1%的人带有苯丙酮尿症的基因，因此很多国家要求婴儿出生后要进行普查。该基因得以延续的主要原因是它可以降低胎儿的流产率。所以母亲的子宫会选择性的将这样的基因保留下来。&lt;/li&gt;
&lt;li&gt;如果某种疾病是遗传决定的，我们便有可能用最好的环境办法干预它。&lt;/li&gt;
&lt;li&gt;我们总归是难逃一死。到80岁，有一半的人已经死去。到100岁，99%的人已经死去，到115岁，每个人都会死去。&lt;/li&gt;
&lt;li&gt;衰老和死亡是不可避免的。衰老表现为对多种疾病的易感性逐渐增加，以及修复损伤的能力全面的下降。&lt;/li&gt;
&lt;li&gt;人类的身体有很强的维护能力，比如牙齿，皮肤，以及血细胞。但是我们不能像大象一样，可以换6次牙，而且肝组织也可以很快自行修复，骨折了，皮肤破裂了都可以很快的修复。因为我们的身体的修复能力有限。人们一直想要了解这些差异，从而获得不老的传说。&lt;/li&gt;
&lt;li&gt;青年时代吸收大量的铁，可以避免发生缺铁性贫血，但是早期吸取的铁在肝脏内堆积，将毁坏肝脏，并且导致中年的猝死的风险。女性需要铁来弥补由于月经时候失血的损失。但是中年男子，则不要增加任何铁的补充。&lt;/li&gt;
&lt;li&gt;有学者研究阿兹海默症，认为少年时代的才智较高的，以及大脑容量较大的人群，更容易患上阿兹海默症。该症状在65岁的人群中发病率为5%。80岁的人群中发病率为20%。该疾病受遗传因素影响。呈现 家族性特征。&lt;/li&gt;
&lt;li&gt;哈佛的生物学家经过一些研究，发现，食物不足的大鼠可以活的更久一些，但是它们不进行交配。限制进食导致长寿的生物学机制仍然在研究中。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>人们为什么会生病1</title><link>https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%851/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BA%BA%E4%BB%AC%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E7%94%9F%E7%97%851/</guid><pubDate>Thu, 11 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;第一推动系列之人们为什么会生病(1)&lt;/h1&gt;
&lt;p&gt;断断续续的看了这本书，第一推动系列这套关于人的书很多年前出版的，前段时间找到了。&lt;/p&gt;
&lt;p&gt;其中有这么几点比较好玩。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自然选择只利于“基因”，而不是族群&lt;/li&gt;
&lt;li&gt;自然选择是偶然的，没有目的也没有方向，无法预测&lt;/li&gt;
&lt;li&gt;生物个体的随机变异导致了个体间适应性的微小差异，而这些差异将导致其个体比另外的个体留下更多的后代，那么这种变异就会在后代中更加的表现出来&lt;/li&gt;
&lt;li&gt;身体是各种机能调和妥协的产物。不会出现过度设计的组织。&lt;/li&gt;
&lt;li&gt;任何过度设计的产生都违背了自然选择偶然性的前提&lt;/li&gt;
&lt;li&gt;对鸟类进行了50年研究的鸟类学家得出的结论：鸟类调整其产蛋的数量，使得其个体繁殖后代的成功率最大。如果产蛋数量太少，那么后代的自然存活数量就会变少。但是如果产蛋很多，那么就需要更多的食物来满足后代的哺育，而这个将耗尽本身的能量，或者带来后代的食物不足的危险。&lt;/li&gt;
&lt;li&gt;对于性别的自然选择。如果父母哺育子女时付出的代价相当，那么性别将维持在稳定的比例上。&lt;/li&gt;
&lt;li&gt;咳嗽，发热等等其实是自然选择塑造出来的对抗感染的一种适应性防御机制。因此不要特意的用药物进行阻止。但是发热或者咳嗽严重的情况下，必须进行药物治疗。&lt;/li&gt;
&lt;li&gt;20世纪初，治疗梅毒的最佳手段是让梅毒患者感染疟疾。这样的疗法让梅毒患者的自然痊愈率从1%上升到30%，发明者因此获得了1972年诺贝尔医学奖。&lt;/li&gt;
&lt;li&gt;在抗生素大规模使用前，鸡蛋清曾被用于治疗感染。因为蛋清的蛋白质中含有12%的半清蛋白，这种蛋白可以隔离细菌和铁元素，从而可以让鸡蛋能保持的长久。&lt;/li&gt;
&lt;li&gt;当人体细菌感染而生病的时候，不要去吃含铁成分较多的食物，比如鸡蛋和火腿，而应该多喝水，绿茶和吃面包。这样可以降低细菌对铁的获取。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>将原来的GitHub page重新做了下</title><link>https://dididudu998.github.io/posts/%E5%88%87%E6%8D%A2%E4%BA%86github-page/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%88%87%E6%8D%A2%E4%BA%86github-page/</guid><pubDate>Thu, 11 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;重新建立github page&lt;/h1&gt;
&lt;p&gt;原来的github page是直接从jeklly那边fork过来用的，主题不是很好看。&lt;/p&gt;
&lt;p&gt;昨天下午在网上搜了下，觉得还是有好看的主题的，就想着重新做下。&lt;/p&gt;
&lt;p&gt;毕竟自己看了也会比较养眼一点。&lt;/p&gt;
&lt;p&gt;虽然内容还是那么些内容。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;选个新的主题
&lt;ul&gt;
&lt;li&gt;这个主题来自这里&lt;a href=&quot;https://github.com/suyan/suyan.github.io&quot;&gt;SUNYAN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;配置的过程
&lt;ul&gt;
&lt;li&gt;参看这里&lt;a href=&quot;https://www.jianshu.com/p/e68fba58f75c&quot;&gt;byqiu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;其中在进行disqus的shortname的时候耗费了一点时间。
&lt;ul&gt;
&lt;li&gt;这个shortname要在站点信息页里面看，仔细点即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;新主题在进行切换的时候，要对以前的文章进行yaml的注释，否则会出现文章不显示的问题。这个是比较烦的，我记得有可以自动进行分类的，难道又要写个小玩意。算了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;结果&lt;/h2&gt;
&lt;p&gt;结果就是现在看到的样子，其中里面的main.js中存在http的链接，会在浏览器浏览的时候提示不安全，而且disqus的引用也是http的，会导致无法加载回复，这些都要在对应的js和html文件中对http替换为https。&lt;/p&gt;
&lt;p&gt;总的来说还是可以的。&lt;/p&gt;
</content:encoded></item><item><title>还是做了个扩容的小应用</title><link>https://dididudu998.github.io/posts/%E8%BF%98%E6%98%AF%E5%81%9A%E4%BA%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%BF%98%E6%98%AF%E5%81%9A%E4%BA%86/</guid><description>不喜欢重复的活动</description><pubDate>Thu, 11 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;还是做了个自动进行lvm扩容的小应用&lt;/h1&gt;
&lt;p&gt;前面说了做虚拟磁盘扩容比较烦，想着做个脚本扩容的，但是发现不是和现在的环境贴切，而且也觉得脚本的方式也不是很好。&lt;/p&gt;
&lt;p&gt;所以就用golang自己根据虚拟机的模版做了一个可执行文件，用来扩容centos7的xfrs的虚拟卷。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;p&gt;其实内部就是将linux的命令行进行了包装。&lt;/p&gt;
&lt;p&gt;还有就是利用partprobe减少了一次重启的次数。&lt;/p&gt;
&lt;p&gt;虚拟机在磁盘容量增加后，必须重启才可以让虚拟机认到。这个重启无法避免。&lt;/p&gt;
&lt;p&gt;在进行扩容的时候，首先，对新增加的磁盘容量建立新的分区，然后更新分区表，然后将新增加的分区添加到虚拟卷中，对虚拟卷进行扩容，然后获得虚拟卷的空闲空间大小，为了安全起见，在进行lvextend的时候，只增加空闲空间的99.9%，剩余0.1%做为buffer。&lt;/p&gt;
&lt;p&gt;lvextend后，进行分区的格式化，我这里的使用xfrs_grows的命令行，比较老的还是可以用resize2fs的方式。&lt;/p&gt;
&lt;p&gt;执行前面的所有步骤后，倒数5秒重启机器。然后在这5秒内，发邮件给我，告诉我那台机器进行了磁盘扩容的操作，扩容了多少，这样的信息。&lt;/p&gt;
&lt;p&gt;偷懒在发邮件的时候没有用邮件模版，就直接text/html发了，看起来不好看，不过也就只发给我，所以意思到了就可以了。&lt;/p&gt;
</content:encoded></item><item><title>又要换租房了</title><link>https://dididudu998.github.io/posts/%E5%8F%88%E8%A6%81%E7%A7%9F%E6%88%BF%E4%BA%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8F%88%E8%A6%81%E7%A7%9F%E6%88%BF%E4%BA%86/</guid><description>无聊</description><pubDate>Wed, 10 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;租房&lt;/h1&gt;
&lt;p&gt;这眼看着这边的租期到了，说实话，这边住的真是很垃圾。&lt;/p&gt;
&lt;p&gt;这最后三个月了，楼上搬来一家人，带了2个小孩，这老房子的楼板又薄，到了晚上这两小孩玩的不亦乐乎，有时候直到晚上11点半还在闹腾，声音大的都让我快要得上心脏病，尤其是当正睡觉的时候，突然一声巨响。&lt;/p&gt;
&lt;p&gt;去了楼上拍了2次门，第一次毛用没有。隔了3个星期，晚上九点多，实在是忍无可忍，怒的无法言语，里面的人说会管教管教。好了这才两周，妈的又开始了。&lt;/p&gt;
&lt;p&gt;我实在是觉得有些人是无法教育的。就好比说猪就是猪，你跟它提什么艰苦奋斗，为他人着想，完全是自取其辱。&lt;/p&gt;
&lt;p&gt;这是其一。&lt;/p&gt;
&lt;p&gt;其二，这个房东这次狮子大张口，从4000直接调价到4800，我擦，想钱想疯了吧。我对他说，这房子位置好，交通方便，很容易会有下个人接手的，他问我，多少钱你还续租呢？我说，我不续了。😄。&lt;/p&gt;
&lt;p&gt;在58同城，安居客（这个app被google play认为是恶意软件），豆瓣上面都扫了下，还加了2个中介，说到月中的时候再联系，现在还太早了。&lt;/p&gt;
&lt;p&gt;我自己这次也没有什么紧迫感，好像觉得没什么大不了的，无非就是钱的问题。&lt;/p&gt;
&lt;p&gt;上海这个地方，我觉得如果再不继续搞什么公租房，平价租房这样的话，未来几乎就没有什么发展劲头了。&lt;/p&gt;
&lt;p&gt;年轻人，即使是高薪的年轻人，月薪2，3万的，买房也得狠狠心才行。&lt;/p&gt;
&lt;p&gt;年轻人减少了，那么养老负担就重了，明显的，上海的老年人就依赖着来上海这里打工的年轻人交的社保和医保来做他们的承载。一个少了，另外一个就显得多了，显得多了，上海本地财政就要有考虑了，要么提前做好放水养鱼的想法，要么就是恶性循环，加税，人更少，本地公司，本地人。来打工的人变少了。各个地方都变成只有本地人才能生存的地方，人口的流动就缓和了，人口不流动了，这后面一系列的东西就要发生变化，运输，生活用品，医药，教育，零售等等都会随着改变。大家都开始搞虚的经济，股票，期货可能会大行其道。&lt;/p&gt;
&lt;p&gt;这样的场景，想想就比较可怕。&lt;/p&gt;
&lt;p&gt;作为一个普通的穷人，沪漂，打工者，能做的只是想想退路在哪里。&lt;/p&gt;
&lt;p&gt;减少一些由于大趋势的变化带来的损害。&lt;/p&gt;
</content:encoded></item><item><title>升级OpenSSH</title><link>https://dididudu998.github.io/posts/%E5%8D%87%E7%BA%A7openssh/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8D%87%E7%BA%A7openssh/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 25 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;扫描器提示OpenSSH的版本太低，存在多个安全漏洞，而且漏洞级别是high。&lt;/p&gt;
&lt;p&gt;所以就开始升级OpenSSH。&lt;/p&gt;
&lt;p&gt;为此还专门先升级了OpenSSL组件。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;首先CentOS的库里面没有提供最新的OpenSSH的包，也就是不能从yum直接升级，而且也米有对应的可以下载的RPM包&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;只好从源码安装&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从这里下载   wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.0p1.tar.gz&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装编译工具，以及依赖&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yum groupinstall &quot;Development Tools&quot; -y
yum install openssl-devel zlib-devel -y
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解压openssh文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar -zvxf openssh-8.0p1.tar.gz
cd openssh0-8.0p1
./configure --with-ssl-dir=/usr/local/lib64
make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新的ssh安装到了/usr/local/bin/ssh。将原来的/usr/bin/ssh 移动到/tmp，然后建立连接&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ln -s /usr/local/bin/ssh /usr/bin/ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(2019-07-24补充)修改SSHD服务&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vi /etc/init.d/sshd&lt;/li&gt;
&lt;li&gt;SSHD=/usr/sbin/sshd —&amp;gt; SSHD=/usr/local/sbin/sshd&lt;/li&gt;
&lt;li&gt;KEYGEN=/usr/sbin/ssh-keygen —&amp;gt;KEYGEN=/usr/local/bin/ssh-keygen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;禁用CipherBlockChaining（CBC）和weak MAC Algorithms&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在/etc/ssh/sshd_config中添加下面的两行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128
MACs hmac-sha1,umac-64@openssh.com,hmac-ripemd160
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重启SSHD服务&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;service sshd restart&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;测试 ssh -V(有时候发现还是旧的版本，只要重启下就好了)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再次用扫描器Nessus扫描后，发现OpenSSH的漏洞已经不再报了&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>怪了，升级系统</title><link>https://dididudu998.github.io/posts/%E6%80%AA%E4%BA%86%E5%8D%87%E7%BA%A7%E7%B3%BB%E7%BB%9F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%80%AA%E4%BA%86%E5%8D%87%E7%BA%A7%E7%B3%BB%E7%BB%9F/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 20 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;微软的Windows 7 和Windows 2008系列要退出历史舞台了，明年一月份停止更新。现在就开始要着手进行更新了。&lt;/p&gt;
&lt;p&gt;下午更新了数据库服务器，还有一台管理服务器。&lt;/p&gt;
&lt;p&gt;还降级了一台domain controller，但是在升级另外2台domain controller的时候，总是在最后出现：&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Setup cannot continue. Your computer will now restart, and your previous version of Windows will be restored.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;百思不解。&lt;/p&gt;
&lt;h1&gt;处理过程&lt;/h1&gt;
&lt;p&gt;我做了下面的操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;卸载Symantec系列的软件，包括防病毒软件和backup Exec agent&lt;/li&gt;
&lt;li&gt;卸载salt-minion&lt;/li&gt;
&lt;li&gt;卸载snare&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是结果是鸟用不顶。错误依旧。&lt;/p&gt;
&lt;p&gt;后来发现这个页面&amp;lt;a herf=&quot;https://blogs.technet.microsoft.com/askcore/2012/10/31/upgrading-to-windows-server-2012-part-3/&quot;&amp;gt;Known Issues during an upgrade&amp;lt;/a&amp;gt;。&lt;/p&gt;
&lt;p&gt;用了方法二，参考这里&amp;lt;a herf=&quot;http://jacobackerman.blogspot.com/2012/12/how-to-remove-system-reserved-partition.html&quot;&amp;gt;删除system reserved分区&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The procedure below has been validated on the following OS:

Windows 7 Professional
Windows 7 Enterprise
Windows 7 Ultimate
Windows Server 2008 R2 (all editions)



Run command prompt as administrator
Type: bcdboot c:\windows /s c:
You should get a message that states: Boot files successfully created.
Open Disk Management, right-click on your C: drive and select Mark Partition as Active.
Reboot
Open Disk Management, delete the system reserved partition.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发现依然没用。&lt;/p&gt;
&lt;p&gt;下载方法一的hotfix，好大，要接近600MB，更新下，明天再看。应该就好了吧。&lt;/p&gt;
&lt;p&gt;今天在更新Domain Controller的时候，依然还是得要adprep /forestprep，adprep/domainperp。 现在adprep文件在安装光盘的support目录里面。&lt;/p&gt;
&lt;p&gt;好久没有进行这样的操作了。记录一下。&lt;/p&gt;
&lt;p&gt;=====补充====&lt;/p&gt;
&lt;p&gt;试了几次，直到今天，6月25日，问题依旧没有解决。&lt;/p&gt;
&lt;p&gt;=====补充====&lt;/p&gt;
&lt;p&gt;放弃了，无法正常升级！！！&lt;/p&gt;
</content:encoded></item><item><title>虚拟磁盘扩容</title><link>https://dididudu998.github.io/posts/%E5%8F%88%E4%B8%80%E6%AC%A1%E7%9A%84%E8%99%9A%E6%8B%9F%E7%A3%81%E7%9B%98%E6%89%A9%E5%AE%B9/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8F%88%E4%B8%80%E6%AC%A1%E7%9A%84%E8%99%9A%E6%8B%9F%E7%A3%81%E7%9B%98%E6%89%A9%E5%AE%B9/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 30 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;这样的情况发生的次数实在是太多次了，很烦，但是也没有办法。&lt;/p&gt;
&lt;p&gt;再记录一次。&lt;/p&gt;
&lt;p&gt;虚拟机原本分配了100GB的空间，做了LVM，但是后来数据膨胀，发现100GB不够了，要加到350GB才行。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;先对虚拟机的虚拟磁盘第一个从100GB扩展到350GB，这个在虚拟机的配置里面做&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重启虚拟机，让虚拟机系统认识到硬件已经改变了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;进入虚拟机，fdisk -l一下，会显示当前的磁盘列表，/dev/sda，/dev/sda1，/dev/sda2&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;由于做的第一个盘的扩容，那么这里就会看到/dev/sda的容量为350GB&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;接下来就要将我们扩展的这250GB变成逻辑磁盘出来&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fdisk /dev/sda
n （创建新的分区）
p  （分区类行为primary）
&amp;lt;选择起始扇区&amp;gt;回车
&amp;lt;选择last扇区&amp;gt;回车
w (写入分区表)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此，新的逻辑主分区/dev/sda3就创建出来了。&lt;/p&gt;
&lt;p&gt;重启电脑，让分区被系统所认识。&lt;/p&gt;
&lt;p&gt;下面要将这个分区加入到我们的虚拟卷中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;lvdisplay一下，看看逻辑卷的情况，记录下LV Path以及VG Name逻辑卷的名字，下面要用，这里VG Name的名字是cl，LV Path是/dev/cl/root&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开始扩容卷组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vgextend cl /dev/sda3
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再来vgdisplay一下，就能看到VG Size已经变了，接下来要记录下Free PE /Size 这个值，这里就是250GB&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;扩容逻辑卷啦&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lvextend -L+250GB /dev/cl/root
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;扩容完成后，要扩容文件系统，让系统知道&lt;/p&gt;
&lt;p&gt;老的文件系统使用 resize2fs /dev/cl/root&lt;/p&gt;
&lt;p&gt;新的系统使用的是xfs的格式，要用xfs_growfs /dev/cl/root&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后 df -h一下看看就发现卷的大小改变了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;结束&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;这样的事情发生的很多，怎么样才能自动化一下就好了。&lt;/p&gt;
&lt;p&gt;感觉这样的情况是可以自动化的，无非就是要重启两次电脑。&lt;/p&gt;
&lt;p&gt;等会儿搜搜看，是不是有人写了脚本了执行这个事情。&lt;/p&gt;
</content:encoded></item><item><title>关于数据获取</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8E%E6%95%B0%E6%8D%AE%E8%8E%B7%E5%8F%96/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8E%E6%95%B0%E6%8D%AE%E8%8E%B7%E5%8F%96/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 28 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;以前一直用urllib库的方式来获取webpage的信息，也就是爬网，主要是不想看新闻，只想看内容，用这个可以get到内容，而且整理起来也方便。&lt;/p&gt;
&lt;p&gt;然后用网上的库来收集一些别的地方的信息。&lt;/p&gt;
&lt;p&gt;但是很多时候，这些地方都有针对爬网或者API的限制。怎么越过这个限制就是个问题，自己比较懒，其实也不聪明，想着为了越过这个东西要耗费不少时间，还不一定行，就放弃了。&lt;/p&gt;
&lt;p&gt;但是人的想法有时候由于热情或者埋在心里的那种冲动会发生改变，为了看一些人发出来的信息，还是去做了。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;p&gt;这个是针对短的信息的应用。利用API Key转为Application Key的方式来一次性获取更多的信息的方法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;获得access_token&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;先获得API的custom key和custom secure key,到developer页面取注册id后，就可以获得了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后base64出来值，base64的格式是： customer key：custom secure key（这步现在可以省略了，postman的新版本支持了自动的变换，如果不能自动变化，那么post的headers里面就要写入Authorization的value为bearer base64_value）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo -n &quot;customer key:custom secure key&quot; |base64
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后用到postman这个工具，将获得的base64编码的信息用这样的方式进行提交&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;POST的地址为：https://api.tw.com/oauth2/token&lt;/li&gt;
&lt;li&gt;Authorization里面输入username为custom key，password为secure key&lt;/li&gt;
&lt;li&gt;在headers里面输入对应的值
&lt;ul&gt;
&lt;li&gt;User-Agent：my app v1.0&lt;/li&gt;
&lt;li&gt;Content-Type：application/x-www-form-urlencoded&lt;/li&gt;
&lt;li&gt;Accept-Encoding: application/gzip&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;在body里面输入：grant_type=client_credentials&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后send，如果都正确的话，会返回一个json的片段，里面包含有access_token。这个是我们想要获得的&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;获得想要关注的id的信息&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;接下来还是用Postman，这个工具用起来真的很顺手。如果是小事情的话，比自己去用http的urlib这样的方式自己写要方便很多。但是如果是希望将来少动手，或者不动手的话，还是自己写比较好一点。我比较懒。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这时候我们已经有了access_token，下来我们用get方法来获得信息&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Get的地址为：https://api.tw.com/1.1/statuses/user_timeline.json?count=3000&amp;amp;screen_name=xinhuashe&amp;amp;page=9&amp;amp;User-Agent=my app v1.&amp;amp;Accept-Encoding=gzip&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这里要说明的是，问号后面的值都是在Params里面输入的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;count：3000，其实最多200&lt;/li&gt;
&lt;li&gt;User-Agent：my app v1.&lt;/li&gt;
&lt;li&gt;Accept-Encoding：gzip&lt;/li&gt;
&lt;li&gt;screen_name: 这里要注意了，这个就是你要关注的人的账户名，不需要做任何的转换操作&lt;/li&gt;
&lt;li&gt;page：9。 同样的，这个page是你可以修改的，如果他只有不到200个发文，那么page=1即可，如果他发文很多，那就page=2，3，4，5，就可以不断的获得他的发文信息。每一页200条。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再下来就是Authorization部分了，在这里选择认证类型为Bearer Token，在token的文本框中输入我们获得的Access_token.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后单击send。如果网络都ok的话，那么很快就获得关注人的信息出现在Body的栏目里了。不过都是json格式的，包含有很多。类似下面这样的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[
    {
        &quot;created_at&quot;: &quot;Mon May 12 16:37:55 +0000 2017&quot;,
        &quot;id&quot;: 11330497057,
        &quot;id_str&quot;: &quot;1133041467648&quot;,
        &quot;text&quot;: &quot;如今https://t.co/bt5HNGg7xB&quot;,
        &quot;truncated&quot;: false,
        &quot;entities&quot;: {
            &quot;hashtags&quot;: [],
            &quot;symbols&quot;: [],
            &quot;user_mentions&quot;: [],
            &quot;urls&quot;: [],
            &quot;media&quot;: [
                {
                    &quot;id&quot;: 11328,
                    &quot;id_str&quot;: &quot;11486528&quot;,
                    &quot;indices&quot;: [
                        26,
                        49
                    ],
                    &quot;media_url&quot;: &quot;http://pbs./D7lmr_ZVU.jpg&quot;,
                    &quot;media_url_https&quot;: &quot;https://pbs./D7lmr_ZVU.jpg&quot;,
                    &quot;url&quot;: &quot;https://t.co/bt7xB&quot;,
                    &quot;display_url&quot;: &quot;pic.com/bt7xB&quot;,
                    &quot;expanded_url&quot;: &quot;https://tPow/status/1133467648/photo/1&quot;,
                    &quot;type&quot;: &quot;photo&quot;,
                    &quot;sizes&quot;: {
                        &quot;thumb&quot;: {
                            &quot;w&quot;: 150,
                            &quot;h&quot;: 150,
                            &quot;resize&quot;: &quot;crop&quot;
                        },
                        &quot;small&quot;: {
                            &quot;w&quot;: 680,
                            &quot;h&quot;: 626,
                            &quot;resize&quot;: &quot;fit&quot;
                        },
                        &quot;large&quot;: {
                            &quot;w&quot;: 1370,
                            &quot;h&quot;: 1262,
                            &quot;resize&quot;: &quot;fit&quot;
                        },
                        &quot;medium&quot;: {
                            &quot;w&quot;: 1200,
                            &quot;h&quot;: 1105,
                            &quot;resize&quot;: &quot;fit&quot;
                        }
                    }
                }
            ]
        },
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;前面说过了，这个限定了一次只能取200条，那么就要对这获得的json文件进行清洗，我只想获得json文本中的text属性的值。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;清洗json文件，获得最终的信息&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开始想要golang来写的，但是发现格式转化老是为空，想着自己的能力还是太差。转而还是用python吧，直接点。&lt;/li&gt;
&lt;li&gt;我总共手动拷贝复制了16次，也就是获得了16个json文件。&lt;/li&gt;
&lt;li&gt;下面是python代码，反正就是粗暴直接：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;import json
tmp = []
filename = []
for num in range(1, 16):
    filename.append(&quot;file&quot;+str(num)+&quot;.txt&quot;)
for file in filename:
    with open(file) as f:
        data = json.load(f)
        for content in data:
            tmp.append(content[&apos;text&apos;])
with open(&quot;chunjing-pad.txt&quot;, &quot;w&quot;) as f1:
    for line in tmp:
        f1.write(str(line)+&quot;\n&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;获得了chunjing-pad.txt这个文本，里面就几千行吧，可以慢慢看了。不过网上也有很多直接获得图片和video的，目前还没这一个想法，就放弃了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个比直接用python的好的一点是，不会出现402这样的错误，402错误表示链接受限，可能是网络问题，SSL的问题，更大的可能是服务器端不允许链接了。而且速度很快，普通的发文人，顶多半小时就把他几年的发文给收下来了。&lt;/p&gt;
&lt;p&gt;当然如果你想要持续的关注这个人，那么接下来就可以用stream的方式，实时进行监控。这里就不往下继续了。&lt;/p&gt;
</content:encoded></item><item><title>一些powershell的命令</title><link>https://dididudu998.github.io/posts/%E4%B8%80%E4%BA%9B%E5%85%B3%E4%BA%8Epowershell%E7%9A%84%E5%91%BD%E4%BB%A4/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%80%E4%BA%9B%E5%85%B3%E4%BA%8Epowershell%E7%9A%84%E5%91%BD%E4%BB%A4/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Sun, 05 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;刚才在搞一个对DNS分析的数据。&lt;/p&gt;
&lt;p&gt;用正则筛选出来了一天的所有的dns查询信息，现在想要做个数据总结和分析。&lt;/p&gt;
&lt;p&gt;但是一没有excel，二也不想搞什么编程，咋整&lt;/p&gt;
&lt;p&gt;直接用powershell开干&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;正则出来的dns数据类似下面的形式,过滤掉了日期，更细分的那就上其他工具吧，这边只想筛选出来解析最多的和最少的域名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cambrian-images.cdn.bcebos.com
cambrian-images.cdn.bcebos.com
cello.client-channel.google.com
cello.client-channel.google.com
cello.client-channel.google.com
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;powershell直接排序&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;get-content C:\dns-201905.txt |Group-Object -NoElement |Sort-Object Count
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出的样子是这样的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   ...
   24 clients4.google.com
   30 chat-pa.clients6.googl...
   36 mail.google.com
   61 vortex.data.microsoft.com
   64 play.google.com
   66 ssl.gstatic.com
   ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将就能看了。更好看的方式那就上excel或者用程序来画图吧，我这边目前没有这样的需求。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;顺便其他&lt;/h1&gt;
&lt;p&gt;powershell越来越类似于linux的shell，而且对于windows来说比cmdline有更加的功能性。&lt;/p&gt;
&lt;p&gt;顺便摘抄一个foreach的loop项。&lt;/p&gt;
&lt;p&gt;参见&amp;lt;a href=&quot;https://ss64.com/ps/foreach.html&quot;&amp;gt;Powershell Loop&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Examples

Loop through an array of strings:

 $trees = @(&quot;Alder&quot;,&quot;Ash&quot;,&quot;Birch&quot;,&quot;Cedar&quot;,&quot;Chestnut&quot;,&quot;Elm&quot;)

 foreach ($tree in $trees) {
   &quot;$tree = &quot; + $tree.length
 }

Loop through a collection of the numbers, echo each number unless the number is 2:

 foreach ($num in 1,2,3,4,5) {
  if ($num -eq 2) { continue } ; $num
 }

Loop through a collection of .txt files:

  foreach ($file in get-ChildItem *.txt) {
    Echo $file.name
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;是有必要好好再温习下基本的powershell语法了。现在就是想用的时候就直接上网google。&lt;/p&gt;
</content:encoded></item><item><title>做了个申请iscsi存储的页面</title><link>https://dididudu998.github.io/posts/%E5%81%9A%E4%BA%86%E4%B8%AA%E7%94%B3%E8%AF%B7iscsi%E5%AD%98%E5%82%A8%E7%9A%84%E9%A1%B5%E9%9D%A2/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%81%9A%E4%BA%86%E4%B8%AA%E7%94%B3%E8%AF%B7iscsi%E5%AD%98%E5%82%A8%E7%9A%84%E9%A1%B5%E9%9D%A2/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 25 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;有了新的存储了，这里使用存储的大概有这么几个部分，一部分是对服务器的磁盘进行添加，一部分是有人希望他的个人或者他的部门的存储能够增加，目前还没有人有备份的需求希望有额外的磁盘（可见所有人还处于个人电脑的时代）。&lt;/p&gt;
&lt;p&gt;以前分配存储是需要我来参与的，但是我现在不想了。为了省事，就做个页面，自己去申请，自己去挂载好了。&lt;/p&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;其实就是将iscsi的创建targetportal，创建磁盘，创建映射给封装了下，然后从web中获得一些相关参数，然后服务器端制作完后，发送邮件给申请者，申请者根据邮件的内容，下载用于激活的客户端小程序，运行下，然后到磁盘里面去初始化新的盘就可以了。&lt;/li&gt;
&lt;li&gt;整个的代码在github我的私有库里面&lt;/li&gt;
&lt;li&gt;需要提到的是这个小项目里面用到了gomail的邮件模版功能。这个功能是比较实用的，特别是发邮件的时候，可以做的比较好看一些。&lt;/li&gt;
&lt;li&gt;还有就是用到了golang在做需要管理员权限的命令行程序的时候，需要用到rsrc，等一会我贴下怎么用的。&lt;/li&gt;
&lt;li&gt;还有就是怎么在批处理里面来判定和执行自己想要的程序&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;netstat -an |findstr &quot;8888&quot; | find &quot;LISTENING&quot;
if errorlevel 1 (d:\goweb.exe)
if errorlevel 0 (....)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;​	上面就是golang的web的页面侦听8888端口，如果这个端口是listening状态的话，说明golang的这个web本地服务是ok的，如果不ok那就执行goweb.exe(我将小程序build成了windows的可执行程序，&amp;lt;font color=&quot;red&quot;&amp;gt;只需要创建对应的template和templates文件夹即可&amp;lt;/font&amp;gt;）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;还有就是更深刻的回顾了下iscsi target和initinator在windows下的使用。&lt;/li&gt;
&lt;li&gt;&amp;lt;font color=&quot;blue&quot;&amp;gt;还有就是使用了golang引用本地的其他的golang的文件中的函数的用法&amp;lt;/font&amp;gt;&lt;/li&gt;
&lt;li&gt;还有就是golang在web开发方面我个人的skill还很差，虽然在页面里面做到了输入的判定，以及反馈等等，但是整个的测试还是历经很多次，比如忘记了return，导致即使错误的输入还是走到了下一步这样的低级错误。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;小记&lt;/h1&gt;
&lt;p&gt;由于在客户端电脑上添加逻辑磁盘的动作需要管理员权限，而普通的可执行文件，不会直接要求用户的权限，所以当执行需要特殊权限的时候，会出错，或者直接退出，导致执行失败。&lt;/p&gt;
&lt;p&gt;golang中有一个run as admin的类似的东西。参见下面的页面:&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://github.com/mozey/run-as-admin&quot;&amp;gt;run-as-admin&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;还有更重要的是需要一个manifest文件来声明我们需要管理权限才能执行。&lt;/p&gt;
&lt;p&gt;我下面贴出个例子，这里假设我们最后要生成的程序位addspace.exe，这个xml文件名为addspace.txt.(习惯了，一般以manifest结尾比较好认）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&amp;gt;
&amp;lt;assembly xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot; manifestVersion=&quot;1.0&quot;&amp;gt;
&amp;lt;assemblyIdentity
    version=&quot;9.0.0.0&quot;
    processorArchitecture=&quot;amd64&quot;
    name=&quot;addspace.exe&quot;
    type=&quot;win32&quot;
/&amp;gt;
&amp;lt;description&amp;gt;My App&amp;lt;/description&amp;gt;
&amp;lt;trustInfo xmlns=&quot;urn:schemas-microsoft-com:asm.v3&quot;&amp;gt;
    &amp;lt;security&amp;gt;
        &amp;lt;requestedPrivileges&amp;gt;
            &amp;lt;requestedExecutionLevel level=&quot;requireAdministrator&quot; uiAccess=&quot;false&quot;/&amp;gt;
        &amp;lt;/requestedPrivileges&amp;gt;
    &amp;lt;/security&amp;gt;
&amp;lt;/trustInfo&amp;gt;
&amp;lt;/assembly&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我还为这个exe增加了一个ico，这个需要将ico文件，golang文件都放在一个目录下，这样便于操作。&lt;/p&gt;
&lt;p&gt;golang的文件名为addspace.go&lt;/p&gt;
&lt;p&gt;manifest的文件名为addspace.txt&lt;/p&gt;
&lt;p&gt;ico的文件名为002.ico&lt;/p&gt;
&lt;p&gt;准备就绪，开始：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;生成syso文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rsrc -manifest addspace.txt -ico 002.ico -o addspace.syso
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至于rsrc是什么，自己去查下就好了，我的测试电脑上面因为python的原因早已经安装了。可以看看我以前写的关于python生成exe的那条。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;利用syso文件生成需要admin权限的exe文件&lt;/p&gt;
&lt;p&gt;（我这个是在windows下执行的，如果在其他系统下，注意GOOS，GOARCH的设定）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;go build -o addspace.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后就有了啊。&lt;/p&gt;
&lt;p&gt;然后申请在webpage上操作完成后，收到邮件，邮件里面包含有这个exe的下载链接，然后下载后执行即可了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>一步闲棋</title><link>https://dididudu998.github.io/posts/%E5%B0%8F%E8%AE%B0%E4%B8%80%E4%B8%AA%E9%97%B2%E6%A3%8B%E7%9A%84%E5%A5%BD%E5%A4%84/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%B0%8F%E8%AE%B0%E4%B8%80%E4%B8%AA%E9%97%B2%E6%A3%8B%E7%9A%84%E5%A5%BD%E5%A4%84/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 18 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;有时候看起来没有什么用的劳动，但是只要是有了结果的，都很有可能在你没有预见的时候起到很大的作用。&lt;/p&gt;
&lt;h1&gt;情况描述&lt;/h1&gt;
&lt;p&gt;这个大概是一个月前的事情了。有人问，想看到分配给某些人的存储的使用情况怎么样，他们又没有这些存储的使用权限，怎么搞？&lt;/p&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;p&gt;想起来更早前，部署了一台NetApp API service服务器。这个问题，可以刚好用API来调取，用web来展现。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;建立READONLY的NETAPP服务账户&lt;/li&gt;
&lt;li&gt;建立用于Query的API Service账户&lt;/li&gt;
&lt;li&gt;调取所有的CIFS对象信息中的存储空间状态属性&lt;/li&gt;
&lt;li&gt;用HTML图表的形式进行展现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;依然是用python和flask的结合，依然是房子自己的总的backend的服务站点。&lt;/p&gt;
&lt;p&gt;做出来的样子是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/storage.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;将就就这样吧。&lt;/p&gt;
</content:encoded></item><item><title>利用API添加虚拟机到备份组</title><link>https://dididudu998.github.io/posts/%E5%88%A9%E7%94%A8api%E6%B7%BB%E5%8A%A0%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%88%B0%E5%A4%87%E4%BB%BD%E7%BB%84/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%88%A9%E7%94%A8api%E6%B7%BB%E5%8A%A0%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%88%B0%E5%A4%87%E4%BB%BD%E7%BB%84/</guid><description>比较早做的东西</description><pubDate>Thu, 11 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;这边开始用rubrik来替换vdp做虚拟机备份。&lt;/p&gt;
&lt;p&gt;其实我个人觉得vdp也挺好用的，但是场景就是vdp的备份限于本地存储，而rubrik可以备份到Azure和GCP上面去。相当于跨到云上去了，增加了一点可靠性。&lt;/p&gt;
&lt;p&gt;介于rubrik在选择虚拟机到时候比较的麻烦，所以利用它提供的API调用后，直接将要备份的虚拟机加入到指定的备份组里面去，应用备份策略。&lt;/p&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;这里用了rubrik提供的go语言接口&lt;/li&gt;
&lt;li&gt;可以在这里看看 &quot;github.com/rubrikinc/rubrik-sdk-for-go/rubrikcdm&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我的代码结构：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/rubrik-jiegou.jpg&quot; alt=&quot;rubrik的代码结构&quot; /&gt;&lt;/p&gt;
&lt;p&gt;其中rubrik-functions.go是一些功能函数包，包括写的添加vm到SLA策略的函数，列出受保护的虚拟机的函数，检查虚拟机名是否正确的函数。&lt;/p&gt;
&lt;p&gt;template是为了提供web界面，做的rubrik.html的页面。&lt;/p&gt;
&lt;p&gt;main.go就是主文件了。下面给出比较结构性的部分。&lt;/p&gt;
&lt;p&gt;就是验证，验证完了就是操作，操作好了，给个提示。&lt;/p&gt;
&lt;p&gt;就是这样，打完收工。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;html/template&quot;
	&quot;log&quot;
	&quot;net/http&quot; 

	Md &quot;./rubrikmd&quot;  //这样的结构便于引用
	&quot;gopkg.in/gomail.v2&quot; //发邮件的模块，用于提醒加入成功
	auth &quot;gopkg.in/korylprince/go-ad-auth.v2&quot; //验证模块，用于验证操作人是否有权限
)

const (
	host = &quot;0.0.0.0&quot;
	port = &quot;8084&quot;
)


// Webshow 用于增加vm到受保护的策略中
func Webshow(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	if r.Method == &quot;GET&quot; {
		t, _ := template.ParseFiles(&quot;./templates/rubik.html&quot;)
		t.Execute(w, nil)
	} else if r.Method == &quot;POST&quot; {
		vmname := r.Form.Get(&quot;vmname&quot;)
		netid := r.Form.Get(&quot;account&quot;)
		password := r.Form.Get(&quot;password&quot;)
		if len(netid) == 0 {
			fmt.Fprintf(w, &quot;You must fill your netid correctly!&quot;)
		}
		if len(password) == 0 {
			fmt.Fprint(w, &quot;Check your password,please!&quot;)
		}

		config := &amp;amp;auth.Config{
			Server:   &quot;dc01.test.local&quot;,
			Port:     389,
			BaseDN:   &quot;OU=example,OU=USERS,OU=ACCTS,dc=test,dc=local&quot;,
			Security: auth.SecurityNone,
		}

		status, err := auth.Authenticate(config, netid, password)
		if err != nil {
			fmt.Fprint(w, &quot;login failed! You should check your network first!&quot;)
		} else {
			if !status {
				fmt.Fprintf(w, &quot;login failed! please double check your account and password!&quot;)
			} else {
				if Md.Detect(vmname) != nil {
					fmt.Fprintf(w, &quot;the VM cannot found! please double check and try again!&quot;)
				} else {
					Md.AddVMintoProtect(vmname, &quot;ProtectPolies30days&quot;)
					fmt.Fprint(w, &quot;Your request is accepted!&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;​&lt;/p&gt;
</content:encoded></item><item><title>正则表达式小记</title><link>https://dididudu998.github.io/posts/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%B0%8F%E8%AE%B0%E5%BD%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%B0%8F%E8%AE%B0%E5%BD%95/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 10 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;正则表达式好像永远都用不熟的。（应该是用的频率不够高，所以总是碰到了就需要找网上的资料，要是没有就得看正则表达式的帮助）&lt;/p&gt;
&lt;p&gt;其实是一个经常用的场景，就是删除带有特定关键字的行。&lt;/p&gt;
&lt;p&gt;前天做了个记录本机DNS查询和应答的小程序，运行结束后会写文本文件，记录这些信息。&lt;/p&gt;
&lt;p&gt;现在我需要删除所有应答的条目，我只想看电脑在这段时间内query了什么.&lt;/p&gt;
&lt;p&gt;程序获得的记录如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;query dns name: go.microsoft.com
query dns name: go.microsoft.com
answer ip address is CNAME go.microsoft.com.edgekey.net
answer ip address is CNAME e11290.dspg.akamaiedge.net
answer ip address is 23.219.16.121
query dns name: sbsdomains.blob.core.windows.net
query dns name: sbsdomains.blob.core.windows.net
answer ip address is CNAME blob.chi21prdstr03a.store.core.windows.net
answer ip address is 52.239.186.132
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我想要将所有带IP地址的都给取掉。&lt;/p&gt;
&lt;h1&gt;方法&lt;/h1&gt;
&lt;p&gt;使用替换的方式，用正则表达式进行筛选，然后替换为空行&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;最简单的就是将带有“ip address”的行给取掉&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^.*ip address.*\r?\n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接将带有ip address的行给替换为空行，然后清理掉，这个会将answer为CNAME的也给干掉&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;过滤带有实际的IP地址的行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^.*((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))).){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))).*\r?\n
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;等会儿将输出的时候用log的形式，加上时间戳&lt;/p&gt;
</content:encoded></item><item><title>nodejs做了个证书申请的页面</title><link>https://dididudu998.github.io/posts/%E8%A1%A5%E4%B8%8A%E4%B8%BA%E4%BA%86%E5%88%86%E4%BA%AB%E5%81%9A%E7%9A%84%E8%AF%81%E4%B9%A6%E7%94%B3%E8%AF%B7%E5%92%8C%E5%8F%91%E9%80%81%E7%9A%84%E9%A1%B5%E9%9D%A2/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A1%A5%E4%B8%8A%E4%B8%BA%E4%BA%86%E5%88%86%E4%BA%AB%E5%81%9A%E7%9A%84%E8%AF%81%E4%B9%A6%E7%94%B3%E8%AF%B7%E5%92%8C%E5%8F%91%E9%80%81%E7%9A%84%E9%A1%B5%E9%9D%A2/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 10 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;为了一次所谓的技术分享，做的个页面&lt;/h1&gt;
&lt;p&gt;网站使用证书已经是标配了。（我有个很特殊的网页，嵌在HTTPS的主页中，一般人进去默认是https，跳转到其他的地方，但是一个很重要的功能，必须使用http才能用😄，只有我知道）&lt;/p&gt;
&lt;p&gt;但是申请证书这样的事情，太基本了，最好做成傻瓜式的，不要浪费时间。&lt;/p&gt;
&lt;p&gt;成品如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/certificate_request.jpg&quot; alt=&quot;申请页面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个是使用nodejs做的，原因是练手，然后就是比较简单，而且这个不是我flask里面的东西，还有就是nodemon用起来也比较顺利，加上监控脚本，轻快又稳定。&lt;/p&gt;
&lt;p&gt;流程就是只需要输入申请人的电子邮件地址和FQDN，这边就生成公钥，刷新到当前页面，然后将CSR和私钥一并以附件的形式发送到电子邮件地址去。&lt;/p&gt;
&lt;p&gt;在真正的证书申请页面里面只要输入CSR即可了。&lt;/p&gt;
&lt;p&gt;我觉得挺好的。整个做起来加上测试大概就是下午三个小时吧。&lt;/p&gt;
</content:encoded></item><item><title>golang打包windows可执行程序</title><link>https://dididudu998.github.io/posts/%E8%A1%A5%E4%B8%8A%E6%89%93%E5%8C%85%E5%B8%A6%E6%9C%89icon%E7%9A%84go%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%A8%8B%E5%BA%8F/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%A1%A5%E4%B8%8A%E6%89%93%E5%8C%85%E5%B8%A6%E6%9C%89icon%E7%9A%84go%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%A8%8B%E5%BA%8F/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 10 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;golang下给windows的可执行文件进行打包&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;下载&lt;a href=&quot;http://www.mingw.org/&quot;&gt;MinGW&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MinGW is a compiler system uses GCC to produce Windows programs. Win32 ports of GCC, GDB, binutils to build native Win32 programs that rely on no 3rd party DLLs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装完成后，下载gcc的包&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Install GCC&lt;/p&gt;
&lt;p&gt;Install GCC (GNU C Compiler) from MinGW, select mingw32-gcc package from All Packages → MinGW → MinGW Based System in left sidebar, and click Apply change in Installation menu.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;检验gcc是否可以用，在命令行下运行gcc -v看看有没有输出&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装完成后，将MinGW的路径和MinGW\bind的路径加入系统的Path中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建一个文件夹出来，将main.go以及对应的go文件放在一起&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下载一个icon文件，起名为main.ico也放在一起&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建main.rc文件&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;IDI_ICON1 ICON &quot;main.ico&quot;
1 24 &quot;main.exe.manifest&quot;

1 VERSIONINFO
FILEVERSION     1,0,0,0
PRODUCTVERSION  1,0,0,0
FILEFLAGS       0x0L
FILEFLAGSMASK   0x3fL
FILESUBTYPE     0
BEGIN
    BLOCK &quot;StringFileInfo&quot;
    BEGIN
        BLOCK &quot;040904B0&quot;
        BEGIN
            VALUE &quot;FileDescription&quot;, &quot;阿弥陀佛&quot;
            VALUE &quot;FileVersion&quot;, &quot;1.0&quot;
            VALUE &quot;LegalCopyright&quot;, &quot;Mark&quot;
            VALUE &quot;InternalName&quot;, &quot;去试试吧&quot;
            VALUE &quot;OriginalFilename&quot;, &quot;amituofo&quot;
            VALUE &quot;ProductName&quot;, &quot;念经吧&quot;
            VALUE &quot;ProductVersion&quot;, &quot;1.0&quot;
        END
    END
    BLOCK &quot;VarFileInfo&quot;
    BEGIN
            VALUE &quot;Translation&quot;, 0x0409, 0x04B0
    END
END
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;创建main.exe.manifest文件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&amp;gt;
&amp;lt;assembly xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot; manifestVersion=&quot;1.0&quot;&amp;gt;
&amp;lt;assemblyIdentity
    version=&quot;1.0.0.0&quot;
    processorArchitecture=&quot;x86&quot;
    name=&quot;controls&quot;
    type=&quot;win32&quot;
/&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;dependentAssembly&amp;gt;
        &amp;lt;assemblyIdentity
            type=&quot;win32&quot;
            name=&quot;Microsoft.Windows.Common-Controls&quot;
            version=&quot;6.0.0.0&quot;
            processorArchitecture=&quot;*&quot;
            publicKeyToken=&quot;6595b64144ccf1df&quot;
            language=&quot;*&quot;
        /&amp;gt;
    &amp;lt;/dependentAssembly&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;/assembly&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;在该文件夹下运行下面的命令&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;windres -o main-res.syso main.rc &amp;amp;&amp;amp; go build -i
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就会生成一个以该文件夹名为命名的exe文件，带有对应的icon和编辑的属性信息&lt;/p&gt;
</content:encoded></item><item><title>golang挂载网盘</title><link>https://dididudu998.github.io/posts/%E5%B0%8F%E8%AE%B0golang%E4%B8%8B%E8%BF%90%E8%A1%8Cwindows%E5%91%BD%E4%BB%A4/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%B0%8F%E8%AE%B0golang%E4%B8%8B%E8%BF%90%E8%A1%8Cwindows%E5%91%BD%E4%BB%A4/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 27 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;前段时间用的python和nodejs做了一些web的事情，主要用于显示和封装后端的一些指令。最近在学习golang，所以，看到有需求了，就想用golang来实现。&lt;/p&gt;
&lt;p&gt;问题是golang的轮子不是很多，找起来比较麻烦，所以尽可能用系统内置的一些指令来执行最好。&lt;/p&gt;
&lt;p&gt;下面用挂载网络盘这个最简单的需求来说，怎么样用golang的os.exec模块来实现。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;第一步是对用户进行身份验证，确保他的账户和密码输入是正确的
&lt;ul&gt;
&lt;li&gt;此时需要调用身份验证的模块，这里有两个选择，第一个是用ldap的方式进行验证，一个是使用smb的方式进行验证&lt;/li&gt;
&lt;li&gt;因为这个挂载的是smb的，所以就选择smb的方式进行验证了，当然这两个选择哪个都是没有任何问题的，这里以smb为例了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;调用windows的内置挂在网络盘的命令
&lt;ul&gt;
&lt;li&gt;这里同样有两种方式，一种就是net use的，这个最简单，还有就是使用powershell的方式&lt;/li&gt;
&lt;li&gt;powershell的方式在这个例子里面也包括，所以怎么用powershell的方式来进行挂载你也可以自己试试，这里以net use的方式来说明&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;给出成功/失败/错误的信息给管理者
&lt;ul&gt;
&lt;li&gt;这个是个可选的，不过我还是做了。通过邮件的方式来实现。将输出信息发送邮件给管理者，确定谁在什么时候是否访问了他的网络盘&lt;/li&gt;
&lt;li&gt;最近喜欢搞一些监控类的小东西，所以很多时候都写了邮件通告的部分，可以直接拿来就用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;好了，前面的思考部分结束，开始代码部分：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;log&quot;
	&quot;os/exec&quot;
	&quot;syscall&quot;
	&quot;time&quot; //发送邮件的时候用来确定时间的

	&quot;github.com/stacktitan/smb/smb&quot; //这个就是说的用来做smb验证的
	&quot;golang.org/x/crypto/ssh/terminal&quot; //这个是用来确保在console输入的密码安全的

	ps &quot;github.com/bhendo/go-powershell&quot; //这个是调用powershell的指令的
	&quot;github.com/bhendo/go-powershell/backend&quot;

	&quot;gopkg.in/gomail.v2&quot; //这个是用来发送邮件的
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;验证部分：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
func createsession(username, password string) {
	host := &quot;fileserver.domain.com&quot;
	options := smb.Options{
		Host:        host,
		Port:        445,
		User:        username,
		Domain:      &quot;domain&quot;,
		Workstation: &quot;&quot;,
		Password:    password,
	}
	debug := false
	session, err := smb.NewSession(options, debug)
	if err != nil {
		log.Fatalln(&quot;[!]&quot;, err)
	}
	//defer session.Close() //这里我将这条给注释掉了，其实是不应该的。我们的目的仅仅是验证用户名和密码，并不需要做其他的事情。

	if session.IsAuthenticated {
		log.Println(&quot;[+] Login successful&quot;)
	} else {
		log.Println(&quot;[-] Login failed&quot;)
	}

	if err != nil {
		log.Fatalln(&quot;[!]&quot;, err)
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;挂载部分：&lt;/p&gt;
&lt;p&gt;这段才是我要说的重点，虽然做了后觉得没什么大不了的，可是当第一次做的时候，还是有点不对劲，我当时用引号的方式，以及``的方式总是得出错误的结果，后来换成和python一样的用arrary的方式，就是ok了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;func mountfolder(username,password string){
    //net use 挂载
    cmd:=`net`
    args:=[]string{`use`,&quot;P:&quot;,`\\fileserver.domain.com\`+username,`/User:`+`domain\`+username,password}
    mount:=exec.Command(cmd,args...)
    if err:=mount.Run();err!=nil{
        log.Fatal(err)
    }
    
    //利用powershell修改挂载的名字，让好看点
    back:=&amp;amp;backend.Local{}
    shell,err:=ps.New(back)
    defer shell.Exit()
    stdout, _, err := shell.Execute(`(New-Object -com shell.application).namespace(&apos;P:&apos;).self.name=&apos;Personal&apos;`)
	if err != nil {
		log.Fatal(err)
	}
    
    //调取exploer直接打开这个P盘
    cmd0:=exec.Command(`explorer`,`P:`)
    cmd0.Run()  //这里不在设定err返回的东西
    
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据返回的code值发送通告：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;func alertmail(username, code string) {
	etime := time.Now().Format(time.RFC850)
	//send email to owner about new file created and write
	m := gomail.NewMessage()
	m.SetHeader(&quot;From&quot;, &quot;Personal_folder_access@domain.com&quot;)
	m.SetHeader(&quot;To&quot;, &quot;xxx@domain.com&quot;)
	m.SetAddressHeader(&quot;Bcc&quot;, &quot;YYY@domain.com&quot;, &quot;Mark&quot;)
	m.SetHeader(&quot;Subject&quot;, &quot;Personal Folder Access alert&quot;)

	switch code {
	case &quot;not exist&quot;:
		m.SetBody(&quot;text/html&quot;, &quot;&amp;lt;b&amp;gt;Alert&amp;lt;/b&amp;gt;\n&quot;+etime+&quot;----&quot;+username+&quot;---&quot;+&quot;Personal Folder does not exist!&quot;)
	case &quot;success&quot;:
		m.SetBody(&quot;text/html&quot;, &quot;&amp;lt;b&amp;gt;Alert&amp;lt;/b&amp;gt;\n&quot;+etime+&quot;----&quot;+username+&quot;---&quot;+&quot;Access the Personal Folder&quot;)
	default:
		m.SetBody(&quot;text/html&quot;, &quot;&amp;lt;b&amp;gt;Alert&amp;lt;/b&amp;gt;\n&quot;+etime+&quot;----&quot;+username+&quot;---&quot;+&quot;try to access the personl folder&quot;)
	}
	d := gomail.NewDialer(&quot;smtp.domain.com&quot;, 25, &quot;&quot;, &quot;&quot;)
	if err := d.DialAndSend(m); err != nil {
		log.Fatal(err)
	}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;收尾部分&lt;/h1&gt;
&lt;p&gt;基本的主要程序部分就是这样的，其实在windows里面就那么一句话而已，但是既然是做programmer，还是用程序的思维来的比较顺一些。最后用go build生成exe，试了下，没问题。为了美观，可以借鉴下面的这个链接来实现添加icon以及添加版本信息，作者等的属性给到exe程序。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://xuri.me/2016/06/15/embedded-icon-in-go-windows-application.html&quot;&gt;embedded-icon-in-go-windows-application&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;这段时间对于golang的使用算是婴儿期，知道了一些语法，使用上面还没有很熟练，但是总的来说golang更多的在后端系统层面是很优秀的，尤其对于信号通告以及多进程的使用上面。这个要比其他的预言好很多，系统的阻塞基本上都可以排除了。nodejs在web层面的nonblock也很棒，但是nodejs在系统编程方面不是很合适，python的主要问题是如果你做了个小程序，发出去后基本上是明文的。而且python的自身要依靠系统的，或者第三方的应用才能发挥出来。&lt;/p&gt;
&lt;p&gt;每种语言都有比较合适的用于处理问题的方式，不同的问题，用不同的语言来搞定会更明智一些。这个只是一个例子，并不应该是真正的处理问题的方式。&lt;/p&gt;
&lt;p&gt;加油！！！&lt;/p&gt;
</content:encoded></item><item><title>面试</title><link>https://dididudu998.github.io/posts/%E8%BD%AC%E5%B8%96java%E9%9D%A2%E8%AF%95/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%BD%AC%E5%B8%96java%E9%9D%A2%E8%AF%95/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 06 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;面试&lt;/h1&gt;
&lt;p&gt;互联网Java开发面试总结&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://xinsheng.huawei.com/cn/index.php?app=forum&amp;amp;mod=Detail&amp;amp;act=index&amp;amp;id=3885437&quot;&gt;原版在这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;1.一面主要问基础，包括几方面:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;collection接口下面有哪些集合，hashmap的实现原理，要把1.7和1.8的区别(红黑树)讲出来，map有哪些实现类以及使用场景，hashmap, hashtable, linkedhashmap,weakHashMap, treemap, concurrentmap，你要是讲的好这里可以说十几分钟，linkedhashmap和treemap排序的区别，concurrenthashmap如何实现线程安全，这里也要把1.7和1.8实现差异说出来(分段加锁和cas技术)，说到这里以后就会问你cas实现原理( CPU Lock前缀指令),它是如何保证其他cpu core的cache失效的，然后会问你volatile的实现原理，要结合java内存模型来讲，可见性是如何实现的(内存屏障)，synchronized锁和reentrantlock的区别以及内部怎么实现的:常用的gc算法及优缺点，如何判断对象的存活性&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mysql有哪些索引，底层数据结构是什么，画一下b+树的结构以及数据的插入过程，聚集索引的特点，如何做索引优化，给你一个sql语句select a,b,c from t where a&amp;lt;某个值 and  b&amp;gt;某个值 and c = 1,如何建索引(可以是c,a,b或者c,b, a的联合索引，但要分析什么场景下分别用哪个);结合Innodb的实现说下数据库的隔离级别，分别是怎么解决脏读、不可重复读和幻读取的;对mysql最新版本的同步机制有没有了解,比如一个主节点和多个备份节点,mysql怎么保证可用性和性能；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;redis有哪些数据结构，分别用在哪些场景,对redis的pipeline有没有了解，解决什么问题,redis采用了什么方式来节省内存&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring IOC的理解以及IOC容器的初始化过程,Spring里的Bean是保存在哪里的,BeanFactory和FactoryBean的区别,Spring AOP怎么实现的(需要讲出来JDK动态代理和CGLib动态代理优缺点),头条还问了如果一个类的某个方法没有在接口里定义,这两种动态代理方式是怎么实现的；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;线程池有哪些实现类，ThreadPoolExecutor有哪些参数，讲下它的工作原理，在使用过程中有哪些经验(比如工作队列大小的设置,ThreadFactory和ExjectExcutionHandler)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;线程有哪些状态以及怎么转换的&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;\2. 二面主要结合项目来问&lt;/p&gt;
&lt;p&gt;1). GC的常用算法以及优缺点，项目中用的什么垃圾回收算法,怎么做GC调优,对G1收集器有没有了解(要说出G1的出现主要解决了什么问题,为什么CMS算法会有内存碎片)&lt;/p&gt;
&lt;p&gt;在介绍GC算法的时候可能会提到GC Roots，面试官会问你哪些对象可以作为GC Roots，栈里面的局部变量表里有基本数据类型和引用类型，怎么找到引用类型;有个对象引用比如Hello,hello.sayHello()调用的时候怎么找到类里的sayHello()这个方法&lt;/p&gt;
&lt;p&gt;2). 项目里有用到限流，具体怎么做的&lt;/p&gt;
&lt;p&gt;3). 看你对Netty有了解，能不能讲下它的工作原理,netty里ChannelInBoundHandler和ChannelOutBoundHandler的区别，netty在读写数据的时候是先调用head还是tail handler,既然你知道NIO，有没有听说&lt;/p&gt;
&lt;p&gt;JDK epoll的BUG，Netty是怎么解决的,如何解决TCP粘包和拆包的问题,为什么会出现粘包和拆包&lt;/p&gt;
&lt;p&gt;4). 讲下你项目里做的数据库索引优化,如何去分析一条语句的执行性能,explain语句你会关注哪些字段&lt;/p&gt;
&lt;p&gt;5). 分别在什么场景使用synchronized和Lock，ReentrantLock内部怎么实现的，多线程通信有哪些方式(要把JUC包下的常用实现类说出来,比如CountDownLantch,信号量,栅栏)&lt;/p&gt;
&lt;p&gt;6). 如何实现分布式锁,一开始说了redis的实现,redis可能在锁超时后还没执行完任务,这个时候要怎么做，有没有更好的方式,后面说了用zookeeper的实现&lt;/p&gt;
&lt;p&gt;7). 项目里有用到ElasticSearch，能介绍ES的工作原理吗,什么是正向索引和反向索引，如何对ES进行优化&lt;/p&gt;
&lt;p&gt;8). 为什么会出现大量CLOSE_WAIT连接，能不能画一下TCP挥手的流程图介绍下,后面是怎么解决句柄泄露的问题&lt;/p&gt;
&lt;p&gt;9). 写代码实现一个EnumSet(阿里),用数组或者链表实现一个阻塞队列(美团)&lt;/p&gt;
&lt;p&gt;10). 哪些场景下会出现内存泄露(可以讲下HashMap,ThreadLocal,WeakHashMap,finalize),会问你ThreadLocal的原理以及为什么会有内存泄露&lt;/p&gt;
&lt;p&gt;11). 如何获取Redis里所有的keys(可以先说下keys *命令,然后再介绍可能导致系统阻塞无法对外响应,再介绍更好的scan命令)&lt;/p&gt;
&lt;p&gt;12). Java类加载机制，为什么要双亲委派&lt;/p&gt;
&lt;p&gt;13). Spring Bean的作用域有哪些，单例是线程安全的吗，怎么保证线程安全&lt;/p&gt;
&lt;p&gt;14). java里的Exception信息是怎么保存的,有没有用到java8的一些特性,Lambda表达式是语法糖吗，怎么实现的，和匿名内部类有什么区别;&lt;/p&gt;
&lt;p&gt;\3. 三面,一般是技术总监或者某个部门的主管面&lt;/p&gt;
&lt;p&gt;1). 简历里有提到有定位系统响应慢的经验，具体怎么做的&lt;/p&gt;
&lt;p&gt;2). 如果有个节点一直在做FullGC，你要怎么快速定位并恢复环境&lt;/p&gt;
&lt;p&gt;3). 如果要做一个秒杀系统，你会怎么设计，把能想到的点都说出来&lt;/p&gt;
&lt;p&gt;4). 假设数据库里有100W条数据，要把他们全部加载到Redis里，你会怎么设计这个系统(这里可能是个坑,缓存一般保存的热点数据,要讲下分布式缓存、缓存击穿、雪崩、并发更新等问题)&lt;/p&gt;
&lt;p&gt;5). ElasticSearch的分片机制,ES搜索过程是如何工作的,如果有很多网卡信息怎么做分片，如果一个Document有2个网卡呢&lt;/p&gt;
&lt;p&gt;6). 用过哪些消息中间件,能不能说下Kafka的工作原理，如果保证分布式系统的数据的一致性,给Kafka发消息如何保证消息的幂等性&lt;/p&gt;
&lt;p&gt;7). 如何对数据库做分库分表&lt;/p&gt;
&lt;p&gt;\4. 四面,基本上也是结合项目来问一些知识点,面试官一般会比较强势,会经常打断你说话,给你压力,这个时候千万不要慌,问的问题和上面差不多&lt;/p&gt;
&lt;p&gt;你在项目中遇到的最难的一个问题是什么，自己对未来3-5年的一个规划&lt;/p&gt;
&lt;p&gt;\5. 五面,HR面，随便聊聊&lt;/p&gt;
</content:encoded></item><item><title>去私立医院</title><link>https://dididudu998.github.io/posts/%E5%8E%BB%E7%A7%81%E7%AB%8B%E5%8C%BB%E9%99%A2/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%8E%BB%E7%A7%81%E7%AB%8B%E5%8C%BB%E9%99%A2/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Sat, 02 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;咽喉疼了一周了，一直没有请假，等到周六了去医院看看。预约到了下午两点。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;p&gt;下午一点十分出发坐地铁，到医院已经两点过一分钟，去了还是老规矩，量体温，量血压，血压偏高，这次没有跟我说心率。估计心率也是偏高。&lt;/p&gt;
&lt;p&gt;等了不到3分钟，前面的人看好了，毕竟我迟到了，不可能让医生等着。然后到我了，问讯加上听诊器听呼吸➕和我商量着开药（因为她给我开的一款含片，我说没用），总共时间不超过5分钟，绝对不超过5分钟。然后去缴费，因为过了一年，原来的保险卡期限过期了，这次她们又拍照了新的保险卡。然后签字确认。这次我看了下缴费单，挂号费60，诊断费500，药费合集385.4，合计945.4元。不错不错。&lt;/p&gt;
&lt;p&gt;然后去取药，这取药每次都是很垃圾要等，这次是真的厉害了，有的人非要问这个那个的在取药的时候，这个单子上面写的很明白，什么一日几次，一次几颗，餐前还是餐后，她还非要让那个拿药的给她再说一遍，还要拿个笔写在药盒上，真的烦。取药花了我大概15分钟的样子，等的有点不耐烦。&lt;/p&gt;
&lt;p&gt;无聊的时候拿医院的宣传单看看，现在医院也是牛，看病可以办套餐，还分五个等级，什么温馨，珍爱，和睦等等，办卡的一年有2000的额度可以免费，然后诊断费可以打折，哈哈，但是一个人的话一万，两个人的话8千，三口之家的话，小孩子只要6000，很会算啊。毕竟小孩子的保险的需求远远大于成人的需求。&lt;/p&gt;
&lt;p&gt;然后返程。&lt;/p&gt;
&lt;h1&gt;感想&lt;/h1&gt;
&lt;p&gt;医生的好与不好，除了医生本身的经验和技能以外，其实更重要的是她可以给你开的药是不是比较有效的。&lt;/p&gt;
&lt;p&gt;即使她可以诊断出你的病，但是没有对应的有效的药，其实也没有什么用处。&lt;/p&gt;
&lt;p&gt;看病的主要是为了拿到有用的药。&lt;/p&gt;
&lt;p&gt;现在医院电脑里面你输入咽喉炎，它自己就会列出一些症状和对应的药品出来的。&lt;/p&gt;
&lt;p&gt;不过私立医院的好处就是不用等待，仪器比较好一些，医生都比较温柔一点，但是并不代表她们真的医术高超啊。&lt;/p&gt;
&lt;p&gt;同样的诊断在公立医院也完全做的出来，但是公立医院开的药就比较的不是那么有效，可能要吃好几盒才能有效果，而且要排队，而且医生都比较烦躁，但是优势是比较便宜。&lt;/p&gt;
&lt;p&gt;私立医院的医生也是有KPI考核的，她们也会想要留下比较容易看，愿意花钱的病人，建立比较好的关系，拓展她们的营业范围，吸引更多的人来就诊，所以才有看到的家庭年卡计划。&lt;/p&gt;
&lt;p&gt;公立医院的KPI那也是一样的，可是公立医院就诊的人并不那么的希望花费很多，比如一个感冒诊断就要500块，所以公立医院依靠普通消费人群的大基数来实现盈利，所以公立医院的医生和护士都比较的烦躁，因为就诊的人数和她们的工作强度成比的上升。越是有名的公立医院，越是这样，就诊量很大，人们的满意度比较低。&lt;/p&gt;
&lt;p&gt;好像是比较难有一个平衡的手段。我觉得鼓励民营医院的时候，也鼓励下民营的药房，要求每个药房都需要有执业医师的存在，这样很多的普通病痛可能只需要自己买买药就好了，不需要去医院。现在老年人去医院的频率和频次都很巨大，对于有医疗保障的老人和家庭来说，可能没什么，就和有的老人有了免费的老人公交卡，夏天去蹭空调车一样的。但是对于还有众多的自费去就诊的人来说，这个就比较糟，排队，挂号，检查，开药，然后还有复诊等等，非常的耗时，还有耗钱。&lt;/p&gt;
&lt;p&gt;国内的药厂还是得需要更有毅力努力研发更有效的药品出来才行。否则就像前面说的，看病诊断是第一步，看准了，你没有办法解决，也就是没有药品或者没有对应的医疗器械，那也是无力啊。&lt;/p&gt;
&lt;p&gt;现在的CT，彩超，以及更先进的计算机辅助手术台等都是需要进口的，还有一些特效的药也是需要进口的，任重而道远啊。&lt;/p&gt;
</content:encoded></item><item><title>gitblit和被动ftp服务器</title><link>https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Egitblit%E5%92%8C%E8%A2%AB%E5%8A%A8ftp%E6%9C%8D%E5%8A%A1%E5%99%A8/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%85%B3%E4%BA%8Egitblit%E5%92%8C%E8%A2%AB%E5%8A%A8ftp%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 12 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;由于已经设定过办公地方的gitblit服务器，这次将家用电脑配置为ftp服务器，可以从公司直接往家里传文件，省的还要通过网盘或者电脑来回对拷。&lt;/p&gt;
&lt;h1&gt;过程&lt;/h1&gt;
&lt;h2&gt;gitblit 部分&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;首先安装java，这个gitblit需要。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后下载gitblit的安装压缩包并解压&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;打开解压目录中data\defaults.properties,编辑&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;pre&gt;&lt;code&gt;git.repositoriesFolder=I:\mylab
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个就是我以后gitblit创建仓库的实际文件夹所处位置。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;然后修改解压缩文件根目录下的installservice.cmd文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SET ARCH=amd64
SET CD=H:\gitblit-1.8.0 #这个是我解压缩的文件夹
#去掉--StartParams的参数
--StartParams=&quot;&quot; ^
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然后开始运行下这个文件，用于注册下gitlbit这个服务&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;为了让这个可以自启动，也可以使用windows的startup快捷方式&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建gitblit.bat文件为下面的形式，可以避免出现java的运行命令行窗口&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@echo off
cd H:\gitblit-1.8.0
start java -jar gitblit.jar --baseFolder data %*
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建gitblit.bat的快捷方式，并放置到win10的startup文件夹即可&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Win10的startup文件夹位于：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;c:\programdata\microsoft\windows\start menu\programs\startup
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ftp部分&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;安装filezilla服务器&lt;/li&gt;
&lt;li&gt;创建ftp的目录&lt;/li&gt;
&lt;li&gt;打开filezilla控制台对该目录进行用户授权&lt;/li&gt;
&lt;li&gt;创建自签名的证书，要求TLS加密&lt;/li&gt;
&lt;li&gt;本地测试上传和下载，确认成功&lt;/li&gt;
&lt;li&gt;打开被动访问，确定端口，这里以7000-7050为例&lt;/li&gt;
&lt;li&gt;确定默认的ftp over tls使用的990端口&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;防火墙部分&lt;/h2&gt;
&lt;p&gt;这里是重头戏了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在路由器上进行端口转发的设定，gitblit需要有ssh，https以及git的端口的映射，按照需要进行即可&lt;/li&gt;
&lt;li&gt;对于ftp部分
&lt;ul&gt;
&lt;li&gt;首先要有一个ftp的21端口的映射，这里我映射外部7021到内部的21端口&lt;/li&gt;
&lt;li&gt;还需要有个990端口的映射，用于ftp over tls&lt;/li&gt;
&lt;li&gt;然后还需要被动端口集7000-7050的允许入站连接，这个内部的端口映射留空即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;测试&lt;/h2&gt;
&lt;p&gt;拨入个外部的vpn，填入申请的家里的ddns域名，然后试着git push，ftp upload，以及https的接入，都没有什么问题了。&lt;/p&gt;
</content:encoded></item><item><title>2018年最后一个工作日</title><link>https://dididudu998.github.io/posts/%E5%B9%B4%E5%89%8D%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E5%B7%A5%E4%BD%9C%E6%97%A5/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%B9%B4%E5%89%8D%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E5%B7%A5%E4%BD%9C%E6%97%A5/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 01 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;随笔&lt;/h2&gt;
&lt;p&gt;&amp;lt;hr&amp;gt;&lt;/p&gt;
&lt;p&gt;现在是2019年2月1日，最后一个工作日。&lt;/p&gt;
&lt;p&gt;下午这个时候基本上大家都已经离开了。&lt;/p&gt;
&lt;p&gt;有半个月的时间没有记录什么，主要是也没有什么可记录的。&lt;/p&gt;
&lt;h3&gt;事件记录&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;公平和权力的最终决定来自于实力&lt;/li&gt;
&lt;li&gt;没有实力的愤怒是没有意义的，只能自取其辱&lt;/li&gt;
&lt;li&gt;尽可能的远离没有真实的水平的家伙&lt;/li&gt;
&lt;li&gt;要有个比较明确的长期目标&lt;/li&gt;
&lt;li&gt;记住，人生是按照几十年的时间来记录的，而不是下周或者下个月&lt;/li&gt;
&lt;li&gt;要专注，要有计划的专注，建立长期的事件提醒是个好主意，我一直用ticktick和macOS的提醒&lt;/li&gt;
&lt;li&gt;多管齐下的前提是要知道自己要什么，一旦发现不合适，就放弃，时间是宝贵的&lt;/li&gt;
&lt;li&gt;尽量去干一些能够带来长期价值的事情，当然偶尔做些小玩意儿也没问题，主要是不要浪费时间&lt;/li&gt;
&lt;li&gt;看书是要思考的，看起来很努力的进行学习，其实都没有什么意义，主要是要能够真正的获得思想，我见识过很多看书的人，其实他只是在阅读，而且只是读字，并没有形成完整的思路和意识，这个是浪费时间，不如直接出去喝两杯&lt;/li&gt;
&lt;li&gt;格局是需要锻炼的，人的性格在长时期形成后，基本上看待问题的角度和做事的方式就固化了，但是通过学习，是有效的，获得有开了眼界般的学习，然后自身形成智慧，才能升入更高的格局。&lt;/li&gt;
&lt;li&gt;基础学习是非常必要的，不要搞一些所谓的奇技淫巧，这些对于某些小问题可能有效，但是对于长期的思维形成有障碍，做事情会总想着走捷径。我不赞成小孩子去搞什么高深的，困难的数学竞赛&lt;/li&gt;
&lt;li&gt;人与人之间的友谊，一种是通过交换，一种是通过语言，还有一种是通过行为。交换得来的是社会朋友，因为利益在一起，普通人比较难有这样的经历。通过语言在一起的要通过行动来进行验证，单单的依靠语言来判断一个人的品行是愚蠢的。行为是最能说明问题的，但是行为很多时候你并不能关注的很细致。认识人是一辈子的学问，当然有很多人，在比较年轻的时候就可以能够做到一定的程度。&lt;/li&gt;
&lt;li&gt;在思考现象的时候，要能看到任何行为的背后都有经济利益作为背景，不管是人也好，还是国家也好。因为阶级的不同，掌控的资源的不同，互相之间总是有各自的期望，这种期望通过对事件的发生过程的控制上都各自给力来实现，最终还是返回上面的话，看实力。一般来说有更多资源的阶级最终会获得胜利，而不是什么正义的一方&lt;/li&gt;
&lt;li&gt;学习的速度和学习的深度之间没有矛盾，主要在于你学习的目的。当前的教育最后实现的是缺乏思考能力的学生，他们通过刷题来进行所谓的知识的学习，离开了题目，知识就没有了用武之力。这个对现实生活是没有意义的，人们学习的目的是为了能够认识世界，认识事物，掌握一些事物的发展规律，从而为己所用&lt;/li&gt;
&lt;li&gt;在可能的前提下，最好使用linux或者macOS系统，因为这个让你能少份点心，研究什么系统的问题，而更多的关注于你想要干什么的问题&lt;/li&gt;
&lt;li&gt;多看书，多看看能够长见识的书，很多人是可以通过一些现象来预测未来的，当看书看到一定的程度，你看人的水准也好，预测事件的能力也好，都会有相当的提高&lt;/li&gt;
&lt;li&gt;在自身的能力得到自己的认可的时候，进行行动是检验的最好途径。不要期望重复的做一件事就可以获得能力上的提升，要想提升，先考虑价值，再考虑时效，再考虑工具。&lt;/li&gt;
&lt;li&gt;重复的做同样的事情，然后期望获得不同的结果，在对单一的系统来说，无异于神经病。一个最简单的我的个人的做事的方式就是如果重复了三次还没有结果，换思路，换方法，换工具，换人&lt;/li&gt;
&lt;li&gt;不要生气，特别是不要生一些SB的气，SB是不懂得反省的，你的生气和指责并不会对他们产生任何的正反馈，反而可能遭到不好的结果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;hr&amp;gt;&lt;/p&gt;
&lt;p&gt;乱的写了一通，就是因为没有什么值得记录的事情。&lt;/p&gt;
&lt;p&gt;总之2018年过的还是有点快的，储备能力，储备精神，储备资源来迎接2019了。&lt;/p&gt;
&lt;p&gt;昨天晚上吃了一盒草莓，挺好吃的，要不是发送的礼盒，我是不会自己去买的。&lt;/p&gt;
&lt;p&gt;1月份买了一个荣耀的magicbook，买了200袋速溶咖啡，买了个威戈的行李箱，买了个一等高铁座，买了个软卧，买了个红米note7等等&lt;/p&gt;
</content:encoded></item><item><title>vscode抽了</title><link>https://dididudu998.github.io/posts/vscode_python%E6%8A%BD%E4%BA%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/vscode_python%E6%8A%BD%E4%BA%86/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 18 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;可能是因为升级的问题，具体我还没查出来。反正就是动不动这个python的进程后台就出来很多个，然后就听到风扇呜呜的转起来。这个这两天特别严重啊。&lt;/p&gt;
&lt;h1&gt;搜索&lt;/h1&gt;
&lt;p&gt;Google了下，说是jedi的问题，可是我没有开启这个，然后还有说是pylint的问题，这个要禁用吗？还是换另外一个flake8？还是啥别的pep8&lt;/p&gt;
&lt;p&gt;换了个pep8，竟然多了更多的问题，warning个没完&lt;/p&gt;
&lt;p&gt;算了，直接disable这些pylint了再说&lt;/p&gt;
&lt;p&gt;为这个问题，还装了了个glances，Mac自带的那个任务管理器用起来不是很好。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip3 install glances
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行的效果是挺漂亮的，用1，2，3，4就可以有效的看到情况了。&lt;/p&gt;
&lt;p&gt;而且这个tasks的信息更明了。&lt;/p&gt;
&lt;p&gt;问题重现的时候，看到：&lt;/p&gt;
&lt;p&gt;此时的task中进行着很多个python的进程，进行pytest 测试。导致CPU被吃完了。&lt;/p&gt;
&lt;p&gt;但是前段时间是没有这样的情况的。&lt;/p&gt;
&lt;h1&gt;结论&lt;/h1&gt;
&lt;p&gt;目前先disable pylint这些先，等到vscode再升级的时候打开下看看，希望不会再有这样的问题发生。&lt;/p&gt;
&lt;p&gt;bug是无处不在的，就好像美，你不看它的时候，它是不存在的，你看它的时候，它就在看你，😄&lt;/p&gt;
</content:encoded></item><item><title>python不能返回上一个命令的问题</title><link>https://dididudu998.github.io/posts/python%E4%B8%AD%E4%B8%8D%E8%83%BD%E8%BF%94%E5%9B%9E%E4%B8%8A%E4%B8%80%E4%B8%AA%E5%91%BD%E4%BB%A4%E4%BA%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/python%E4%B8%AD%E4%B8%8D%E8%83%BD%E8%BF%94%E5%9B%9E%E4%B8%8A%E4%B8%80%E4%B8%AA%E5%91%BD%E4%BB%A4%E4%BA%86/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Thu, 17 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;装了个bash-git-prompt在Mac后，今天才发现在iterm里面进入python控制台的时候，没法使用up arrow返回上一个命令了。&lt;/p&gt;
&lt;p&gt;此时如果按向上的箭头，出现^[[A&lt;/p&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;p&gt;基本上干活的时候都在vscode里面，所以发现的晚了。&lt;/p&gt;
&lt;p&gt;感觉是和安装了这个有关，不过又不想刚装上又卸载。就搜了下。&lt;/p&gt;
&lt;p&gt;pip3 install gnureadline&lt;/p&gt;
&lt;p&gt;然后进入python控制台后，先import gnureadline&lt;/p&gt;
&lt;p&gt;这下就可以用上箭头来返回上个命令行了。&lt;/p&gt;
</content:encoded></item><item><title>排除node_modules文件夹</title><link>https://dididudu998.github.io/posts/%E6%8E%92%E9%99%A4node_modules%E6%96%87%E4%BB%B6%E5%A4%B9/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%8E%92%E9%99%A4node_modules%E6%96%87%E4%BB%B6%E5%A4%B9/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Sat, 12 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;问题&lt;/h1&gt;
&lt;p&gt;其实这个问题在git的时候不算是个什么事。&lt;/p&gt;
&lt;p&gt;在git的目录添加个.gitignore文件，写上node_modules就解决的.&lt;/p&gt;
&lt;p&gt;但是我有个习惯就是经常会将自己的所谓的project的文件夹zip一下保存。&lt;/p&gt;
&lt;p&gt;为此我写了个小shell，每天定时zip我的project文件夹，然后git到我的私有存储里，git完成后，删除3天前的文件。因为是自己的存储，所以一直懒得也没有去做什么过滤或者节省空间这样的事情。&lt;/p&gt;
&lt;h1&gt;解决&lt;/h1&gt;
&lt;p&gt;现在不是github私有库可以免费用了么，就想着不如也git一份到github的私有库里面去，只要不大于100MB就好了啊。&lt;/p&gt;
&lt;p&gt;同样的只要在原来的shell里面修改下，滤掉所有的node_modules文件夹，然后再添加下git 到我的github私有库就好。&lt;/p&gt;
&lt;p&gt;过滤：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zip -r -P mypassword &apos;myproject&apos;-$today.zip myproject_folder -x **\node_modules\* *.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;font color=&quot;blue&quot;&amp;gt;使用**的目的是可以&amp;lt;b&amp;gt;recursive&amp;lt;/b&amp;gt;b，我的目录搞的比较乱，找不到完全靠搜索。&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;这里的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;today=`date +%Y%m%d`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pushd myzipfile_folder
git add .
git commit -m $today-&apos;update&apos;
git push myprivate_github master -f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;做了个测试，没问题。&lt;/p&gt;
</content:encoded></item><item><title>预约了红米note7</title><link>https://dididudu998.github.io/posts/%E9%A2%84%E7%BA%A6%E4%BA%86%E7%BA%A2%E7%B1%B3note7/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E9%A2%84%E7%BA%A6%E4%BA%86%E7%BA%A2%E7%B1%B3note7/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Fri, 11 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;完全是意外&lt;/h1&gt;
&lt;p&gt;昨天晚上可能喝了豆浆喝多了，半夜起来上厕所。&lt;/p&gt;
&lt;p&gt;去了后，再就睡不着了。&lt;/p&gt;
&lt;p&gt;然后看到说小米的雷军有个新的直播，有新产品发布了。&lt;/p&gt;
&lt;p&gt;然后看了看，考虑了很久到底是在京东买呢还是在小米商城买。&lt;/p&gt;
&lt;p&gt;后来还是决定在&lt;a href=&quot;https://www.mi.com/redminote7/&quot;&gt;小米商城&lt;/a&gt;了，因为+10元会有个一个18W的快充头。&lt;/p&gt;
&lt;p&gt;我用东西是比较爱惜的，个性使然。&lt;/p&gt;
&lt;p&gt;现在还在跑的一台台式机推算应该用了有接近7-8年了，基本上这四年来都是24小时开机，兼作ftp服务器和git服务器。&lt;/p&gt;
&lt;p&gt;一台手机，再过四个月也就用了有5年了。期间自己换过一次电池，然后到网店去升级过一次emmc内存，从32GB到64GB，一直用到现在。当然是刷过ROM了。&lt;/p&gt;
&lt;p&gt;要到一月十五号支付尾款，还不知道什么时候可以到手，我比较烦这种没有实物的首发或者预约，因为你付了钱，商家并没有肯定的告诉你什么时候可以发货给你，只说尽快。&lt;/p&gt;
&lt;p&gt;但是新的一年，总是要有点希望吧，希望可以在1月底前能到我手。&lt;/p&gt;
</content:encoded></item><item><title>还是做了个webpage</title><link>https://dididudu998.github.io/posts/%E8%BF%98%E6%98%AF%E5%81%9A%E4%BA%86%E4%B8%AAwebpage/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E8%BF%98%E6%98%AF%E5%81%9A%E4%BA%86%E4%B8%AAwebpage/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Wed, 26 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;接上篇，管理infoblox&lt;/h1&gt;
&lt;p&gt;今天还是做了一个webpage用来管理infoblox了。&lt;/p&gt;
&lt;p&gt;主要是在这个webpage做了DNS的变更后，我可以收到邮件提醒。&lt;/p&gt;
&lt;p&gt;这样我就可以对数据进行回溯。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/tupian/infobloxoption.jpg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>今天和infoblox卯上了</title><link>https://dididudu998.github.io/posts/%E4%BB%8A%E5%A4%A9%E5%92%8Cinfoblox%E5%8D%AF%E4%B8%8A%E4%BA%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BB%8A%E5%A4%A9%E5%92%8Cinfoblox%E5%8D%AF%E4%B8%8A%E4%BA%86/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 24 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;大概有一年半的时间，从ipmanager转为infoblox，对于系统层面来说，对DNS的管理一直处于手动的状态，主要还是变更的不多，有时候想要做自动化，但是又觉得没必要，反正变化不是很多。&lt;/p&gt;
&lt;p&gt;在上周的这件事情，成了要做自动化的最后一次提醒。就是pre-stage的阶段，几乎全平台都是自动化的，但是从pre-stage转到stage的生成环境的时候，由于IP需要变更，IP不设定，生产环境就无法联网，但是这个infoblox在生产环境一直都是手动的。&lt;/p&gt;
&lt;p&gt;经过和总部的IT的人员邮件说明，过了2天，给我开通了API。&lt;/p&gt;
&lt;h1&gt;开始&lt;/h1&gt;
&lt;h2&gt;添加主机记录&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;curl -k -u account:password -H &apos;content-type: application/json&apos; -X POST &quot;https://infoblox/wapi/v2.9/record:host?_return_fields%2B=name,ipv4addrs&amp;amp;_return_as_object=1 &quot; -d &apos;{&quot;name&quot;: &quot;apitest06.example.com&quot;,&quot;ipv4addrs&quot;:[{&quot;ipv4addr&quot;:&quot;func:nextavailableip:10.200.10.0/23&quot;,&quot;mac&quot;:&quot;00:50:56:12:23:34&quot;}],&quot;extattrs&quot;:{&quot;location&quot;:{&quot;value&quot;:&quot;NEW YORK&quot;}}}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个是在IP区间10.200.10.0/23中，取出一个可用的IP绑定到MAC地址为0:50:56:12:23:34，注册主机名为“apitest06.example.com”，并且提供扩展属性地区为NEW YORK。&lt;/p&gt;
&lt;h2&gt;获得域名扩展属性&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;curl -k -u user:password -X GET &quot;https://infoblox/wapi/v2.9/extensibleattributedef?_return_as_object=1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获得Network信息&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;curl -k -u user:password -X GET &quot;https://infoblox/wapi/v2.9/network?_return_as_object=1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获得Zone信息&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;curl -k -u user:password -c cookies.txt -X GET &quot;https://infoblox/wapi/v2.9/zone_auth?_return_as_object=1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获得Schema信息&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;curl -k -u user:password -X GET &quot;https://infoblox/wapi/v1.0/?_schema&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;还有一些开发人员编写了使用powershell或者python的模块，我也尝试用request甚至直接写个subprocess来跑curl，但是想了想又放弃了。&lt;/p&gt;
&lt;p&gt;主要是用的次数不多，而且也就只有我用。直接跑curl好了。&lt;/p&gt;
&lt;p&gt;等到还有其他人需要的时候，再做个webpage吧。&lt;/p&gt;
&lt;p&gt;可能过两天改变主意了再说。&lt;/p&gt;
</content:encoded></item><item><title>上周做了个webdns</title><link>https://dididudu998.github.io/posts/%E4%B8%8A%E5%91%A8%E5%81%9A%E4%BA%86%E4%B8%AAwebdns/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%8A%E5%91%A8%E5%81%9A%E4%BA%86%E4%B8%AAwebdns/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 11 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;问题&lt;/h2&gt;
&lt;p&gt;由于变更DNS是工作中的一部分，虽然很少量，但是还是基于想让申请人self-service的理念，既减少他们的时间（需要写邮件，走流程，等待反馈），也减少了事件到我这里后，需要抽时间来做，还要从原来的事情中抽身的转化的时间的耗费。你知道从一个事情转换到另外一个事情，然后再转化回去的话，中间是会损耗一部分有效时间的，可能要十几分钟或者更长。&lt;/p&gt;
&lt;p&gt;自动化是一种基本的思路，主要是可以延长生命啊。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;p&gt;分为两个路径，开始的一天用nodejs做了个雏形，已经实现了功能。但是对于nodejs下的express这个web服务看了几个小时，发现没有flask上手。虽然express肯定也可以做，但是为了节省时间，还是用flask来实现比较方便一些。&lt;/p&gt;
&lt;p&gt;随后放弃nodejs，换python，上flask。&lt;/p&gt;
&lt;p&gt;加上ldap3的认证模块，比较快的实现了在web页面添加和变更DNS的操作。&lt;/p&gt;
&lt;h2&gt;结果&lt;/h2&gt;
&lt;p&gt;nodejs的语法比较好玩，相比于python。nodejs更加的活波一些，里面的事件概念比较贴近真实的应用环境。但是nodejs的web模块方面，我只是看了下express，觉得没有python下面的flask便捷，虽然从操作上面来讲差别不算很大，但是还是有先入为主的趋势。先用了flask，然后就比较认同了。可能以后会发现express的好吧。&lt;/p&gt;
&lt;p&gt;后台部分的web应用从活动目录，到虚拟机，到DNS部分算是初步结束了，剩下就是告警部分和一键的应用了。&lt;/p&gt;
</content:encoded></item><item><title>把ecplise给删除了</title><link>https://dididudu998.github.io/posts/%E4%BB%8A%E5%A4%A9%E4%B8%80%E6%80%92%E6%8A%8Aecplise%E7%BB%99%E5%88%A0%E4%BA%86/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%BB%8A%E5%A4%A9%E4%B8%80%E6%80%92%E6%8A%8Aecplise%E7%BB%99%E5%88%A0%E4%BA%86/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Sun, 02 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;本来是想要搞一个类似VSC那样的open command here的东西，但是装了下插件发现不是那么回事，然后就莫名的总是鼠标悬停的时候出现黑色的边框，还有就是nodejs的代码被格式化成不同的颜色了&lt;/p&gt;
&lt;p&gt;看着就不舒服。&lt;/p&gt;
&lt;p&gt;折腾了下，什么重设，发现没用。&lt;/p&gt;
&lt;p&gt;算了算了，因为这半年也是一直用VSC，罢了，不要Ecplise了。&lt;/p&gt;
&lt;p&gt;感觉Ecplise是真的要完了。装了2年了，都好好的。唉&lt;/p&gt;
</content:encoded></item><item><title>各linux平台安装nodejs</title><link>https://dididudu998.github.io/posts/%E5%90%84linux%E5%B9%B3%E5%8F%B0%E5%AE%89%E8%A3%85nodejs/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E5%90%84linux%E5%B9%B3%E5%8F%B0%E5%AE%89%E8%A3%85nodejs/</guid><pubDate>Thu, 29 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;问题&lt;/h2&gt;
&lt;p&gt;我只能说搞毛，要做个小项目，发现CentOS7 上面安装nodejs用源码安装要用gcc进行编译，也可能是电脑慢（不可思议），编译起来感觉慢，中途给ctrl+Z了。受不了，什么年代了，装个这东西还要编译。&lt;/p&gt;
&lt;p&gt;搜索别的解决办法。&lt;/p&gt;
&lt;p&gt;先是yum install epel-release，然后安装nodejs，但是宪法版本是旧的，而且旧的不是一点，目前的版本是11，这个装起来是6.&lt;/p&gt;
&lt;p&gt;继续找。。。，找到下面的这个。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/nodesource/distributions#rpminstall&quot;&gt;nodesource&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个是真的不错啊。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -sL https://rpm.nodesource.com/setup_11.x | bash -
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;装好了nodejs，还有npm。&lt;/p&gt;
&lt;p&gt;很好很好很好！&lt;/p&gt;
</content:encoded></item><item><title>YunOS删除软件包</title><link>https://dididudu998.github.io/posts/yunos%E7%94%A8%E6%88%B7%E7%BA%A7%E5%88%AB%E5%88%A0%E9%99%A4%E8%BD%AF%E4%BB%B6%E5%8C%85/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/yunos%E7%94%A8%E6%88%B7%E7%BA%A7%E5%88%AB%E5%88%A0%E9%99%A4%E8%BD%AF%E4%BB%B6%E5%8C%85/</guid><pubDate>Tue, 27 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;问题&lt;/h2&gt;
&lt;p&gt;移动送了一个2GB内存，16GB存储的，CPU 1.3Ghz的双核的4G手机，系统是阿里的YunOS 5.3.&lt;/p&gt;
&lt;p&gt;出于对里面广告以及内置软件的厌恶，想要root，删除自带软件。&lt;/p&gt;
&lt;p&gt;但是先搜索了下，发现说YunOS不可能被root。&lt;/p&gt;
&lt;p&gt;也出于对一些root软件的不信任，放弃root的想法。&lt;/p&gt;
&lt;p&gt;转向使用adb的方式来处理看看。&lt;/p&gt;
&lt;h2&gt;过程&lt;/h2&gt;
&lt;p&gt;YunOS的手机使用USB调试模式，音量键+，然后开机键一起，插上电脑USB口，用adb device发现。&lt;/p&gt;
&lt;p&gt;就这个过程，折腾了几次，原因就是这YunOS根本在手机里面的更多设置里没有启用开发者这个选项，什么按系统版本几次开启的方法也没有，死马当活马医，用上面的方式算是能够使用adb 发现这台手机了。&lt;/p&gt;
&lt;p&gt;此时USB调试模式能看到，但是是灰色的。即使连接上了，也没法像root那样的随意的删除安装包，只能在用户级进行删除。&lt;/p&gt;
&lt;p&gt;下面是整个的命令流程：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;adb devices
## 此时可以发现已经授权的设备
adb shell
## 进入shell模式，发现依然是$引导符号，而不是#引导符号
pm list packages 
## 显示所有的已经存在的包
pm uninstall {包名} //这个无效，提示无法删除
## 用户级别删除包
pm uninstall -k --user 0 {包名}
## 此时，手机上面还要提醒授权，点确定后，这边会返回success。


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;逐个的删除即可。
有些是系统级别的包，即使提示说success了，也是没有用的，重启后，依然存在，就是那个负一屏的垃圾广告页面，没有办法
删除完了重启就可以了。&lt;/p&gt;
&lt;h2&gt;综述&lt;/h2&gt;
&lt;p&gt;可能手机上面安装的app比较少，也可能YunOS对于app的后台控制的不错，手机的电量消耗比较少，待机时间比较长。&lt;/p&gt;
&lt;p&gt;但是总的来说，YunOS不值得折腾。&lt;/p&gt;
</content:encoded></item><item><title>pyenv下的升级</title><link>https://dididudu998.github.io/posts/pyenv%E4%B8%8B%E7%9A%84%E5%8D%87%E7%BA%A7/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/pyenv%E4%B8%8B%E7%9A%84%E5%8D%87%E7%BA%A7/</guid><pubDate>Thu, 15 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;下午想个异步的问题，一直没有搞明白。有点烦躁。看了下pyenv的环境，有了新的python版本了，升级一下。&lt;/p&gt;
&lt;h2&gt;升级步骤&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;将已经安装的包导出个列表出来&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip freeze &amp;gt;requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要说明的是，这个pip其实是pip3，因为在bash_profile里面做了alias，指向的是python3.6.4的路径。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在pyenv环境下安装3.7.0版本的python&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pyenv install 3.7.0
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后将requirements.txt中包含的包名和版本号进行分离，我只要最新的包&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;导出的requirements.txt是这样的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bleach==2.1.2
bs4==0.0.1
ccy==0.7.0
certifi==2018.1.18
cffi==1.11.4
chardet==3.0.4
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;做个简单的过滤，只要包名，然后生成新文件new.txt&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后在新的python3.7的bin下面运行下面的命令进行包的安装&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ./pip3 install -r  ~/new.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装完毕后设定global为3.7.0&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pyenv global 3.7.0
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在bash_profile里面做个修改，将原来的3.6.4的路径注释掉，然后将3.7.0的添上去&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alias python=&quot;python3.7&quot;
export PATH=&quot;/Users/dahunhun/.pyenv/versions/3.7.0/bin:$PATH&quot;
export PATH=&quot;/Users/dahunhun/.pyenv/versions/3.7.0/lib:$PATH&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再source ~/.bash_profile一下，让其生效&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开一个新的终端窗口，运行下python，看看是不是这样的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Python 3.7.0 (default, Nov 15 2018, 17:21:37)
[Clang 10.0.0 (clang-1000.10.44.4)] on darwin
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;跑一下原来写的代码，发现都ok，3.6.4先留着，过一段时间再删除&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>我的git设定</title><link>https://dididudu998.github.io/posts/%E6%88%91%E7%9A%84git%E8%AE%BE%E5%AE%9A/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E6%88%91%E7%9A%84git%E8%AE%BE%E5%AE%9A/</guid><pubDate>Thu, 15 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;用了时间比较长的git了，但是基本上都是git clone，git push，用checkout的都比较少，做文件还原倒还有几次。&lt;/p&gt;
&lt;p&gt;贴下当前的git config --list内容，做个摘要&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MACBOOKPRO:learn hunhun$ git config --list
credential.helper=osxkeychain
user.name=admin
user.email=xxx@xyz.com
alias.lg=log --color --graph --pretty=format:&apos;%Cred%H%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&amp;lt;%an&amp;gt;%Creset&apos; --abbrev-commit --
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是.gitconfig的内容&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[user]
        name = admin
        email = xxx@xyz.com
[http]
[alias]
        lg = log --color --graph --pretty=format:&apos;%Cred%H%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&amp;lt;%an&amp;gt;%Creset&apos; --abbrev-commit
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>用root来执行计划任务</title><link>https://dididudu998.github.io/posts/%E7%94%A8root%E6%9D%A5%E6%89%A7%E8%A1%8C%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E7%94%A8root%E6%9D%A5%E6%89%A7%E8%A1%8C%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1/</guid><pubDate>Wed, 14 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;问题&lt;/h2&gt;
&lt;p&gt;这两天发现部署在cloud上面的容器服务有连不上的现象，检查了下docker logs,也没查出个所以然。索性就设个比较粗暴的计划，如果连不上了，就重启容器。&lt;/p&gt;
&lt;h2&gt;操作&lt;/h2&gt;
&lt;p&gt;创建一个shell，起个名字叫做restart_app.sh&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash
if lsof -Pi:2222 -sTCP:LISTEN -t&amp;gt;/dev/null ;then
	echo &quot;service is running on port 2222&quot;
else
	/usr/bin/docker restart container1
	/usr/bin/docker restart container2
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后，由于lsof如果不用root来运行的话，会出现错误。那就用root的角色来设定计划任务，这样shell就可以以root的权限来执行了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo crontab -e
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开计划任务添加下面的条目，我希望是每5分钟检查一次。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*/5 * * * * /bin/sh /home/mark/restart_app.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为了确定计划任务可以运行，手动stop容器，然后过会儿再docker ps一下看看，发现已经在运行了。&lt;/p&gt;
</content:encoded></item><item><title>Flask中使用celery执行异步操作</title><link>https://dididudu998.github.io/posts/flask%E4%B8%AD%E4%BD%BF%E7%94%A8celery%E6%89%A7%E8%A1%8C%E5%BC%82%E6%AD%A5%E6%93%8D%E4%BD%9C/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/flask%E4%B8%AD%E4%BD%BF%E7%94%A8celery%E6%89%A7%E8%A1%8C%E5%BC%82%E6%AD%A5%E6%93%8D%E4%BD%9C/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Tue, 13 Nov 2018 00:00:00 GMT</pubDate><content:encoded/></item><item><title>Ubuntu18的floopy问题</title><link>https://dididudu998.github.io/posts/ubuntu18%E7%9A%84floopy%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/ubuntu18%E7%9A%84floopy%E9%97%AE%E9%A2%98/</guid><pubDate>Tue, 13 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;问题描述&lt;/h2&gt;
&lt;p&gt;在使用了Ubuntu18.04 LTS的虚拟机后，开机也好，运行一段时间也好，总会出现I/O error，fd0出错的问题。&lt;/p&gt;
&lt;p&gt;这样的提示不影响应用，但是看着比较烦。&lt;/p&gt;
&lt;p&gt;经过Google，发现这个&lt;a href=&quot;https://askubuntu.com/questions/719058/blk-update-request-i-o-error-dev-fd0-sector-0/884026&quot;&gt;这里&lt;/a&gt;有解决方案了。照猫画虎执行后，问题解决了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo rmmod floppy
echo &quot;blacklist floppy&quot; | sudo tee /etc/modprobe.d/blacklist-floppy.conf
sudo dpkg-reconfigure initramfs-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发现Ubuntu18中有比较多的东西和以前的版本差别比较大。&lt;/p&gt;
&lt;p&gt;有影响的是本来16的时候，做的批处理部署ubuntu模版的时候，在vmware中挂载vds网卡都是可以开机就挂载的，但是18就不行，因为vmware还没有制作针对18的开机挂载功能。现在最新的是16的。这个只有等。&lt;/p&gt;
&lt;p&gt;还有就是18的网络配置使用netplan了，也谈不上这个和以前的相比有多好，只是ubuntu这是越来越向cloud端发展的苗头，不是很ok。&lt;/p&gt;
&lt;p&gt;CentOS就一直的比较稳定和坚持。&lt;/p&gt;
</content:encoded></item><item><title>不伤害数据怎么刷回miui</title><link>https://dididudu998.github.io/posts/%E4%B8%8D%E4%BC%A4%E5%AE%B3%E6%95%B0%E6%8D%AE%E6%80%8E%E4%B9%88%E5%88%B7%E5%9B%9Emiui/</link><guid isPermaLink="true">https://dididudu998.github.io/posts/%E4%B8%8D%E4%BC%A4%E5%AE%B3%E6%95%B0%E6%8D%AE%E6%80%8E%E4%B9%88%E5%88%B7%E5%9B%9Emiui/</guid><description>如果你也像我一样经常工作于Windows和Linux，那么这篇文章值得一看</description><pubDate>Mon, 12 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;几个月之前，因为miui的更新，导致使用的小米3电信版经常的出现google服务崩溃，而且这种崩溃导致只能重启，否则会不停的提示，让所有的应用都不能正常的运行。&lt;/p&gt;
&lt;p&gt;为此，刷成了lineageos 14.1版本。&lt;/p&gt;
&lt;p&gt;总的来说lineageos是一个不错的系统，但是国内的很多apps，如果不加限制，那么手机会卡的不能自理，用起来想要摔碎的想法。而且在出现这种情况的时候，多点击几下，手机就会重启。&lt;/p&gt;
&lt;p&gt;虽然lineageos的重启时间比miui要快的多，但是这种重启令人不快。算了还是刷回miui，听说现在miui可以比较顺利的安装google服务了。&lt;/p&gt;
&lt;h2&gt;进行&lt;/h2&gt;
&lt;p&gt;刷lineageos的时候刷入了twrp，这个大家都知道的，很有用，比miui的recovery要强大多了。&lt;/p&gt;
&lt;p&gt;下载了miui给小米3电信版提供的卡刷rom，传输到手机的sdcard目录下，用twrp开始刷回，发现报错，提示没有对应的分区。看了下网上的说法，都要下载线刷包重新刷机，但是&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;&amp;lt;b&amp;gt;线刷，会抹掉所有的数据！！！&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;我勒个去，要备份所有的数据，这个感觉好累啊，我就是想要好好用个手机而已。&lt;/p&gt;
&lt;h2&gt;解决&lt;/h2&gt;
&lt;p&gt;因为前段时间在小小的研究什么导致miui出现google服务crash的问题，因此比较熟悉adb，就想着，能不能不线刷，用adb的方式返回MIUI。&lt;/p&gt;
&lt;p&gt;下面是解决的步骤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下载小米3电信版的对应的&lt;a href=&quot;http://bigota.d.miui.com/7.11.16/cancro_images_7.11.16_20171116.0000.00_6.0_cn_34170842a7.tgz&quot;&gt;线刷包&lt;/a&gt;;具体的线刷包地址可以参看&lt;a href=&quot;https://www.miui.com/shuaji-393.html&quot;&gt;这里&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;下载完成后，是个tgz的文件，解压它，在解压文件夹中会出现下面的文件&lt;img src=&quot;/images/tupian/%E7%BA%BF%E5%88%B7%E5%8C%85%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8.jpg&quot; alt=&quot;线刷包解压文件&quot; /&gt;&lt;/li&gt;
&lt;li&gt;接着就twrp里面wipe了，记着，你不要把自己的数据给抹了，就是&amp;lt;font color=&apos;red&apos;&amp;gt;&amp;lt;b&amp;gt;internal storage打死都不能wipe&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;/li&gt;
&lt;li&gt;下面要用到adb了，adb在Mac里面应该是自带的，或者不是，我忘记了，windows的话，要去下载下，我给出执行的顺序，这里面不是所有的img都需要刷入的，而且有的刷入会带有&amp;lt;b&amp;gt;破坏性&amp;lt;/b&amp;gt;&lt;/li&gt;
&lt;li&gt;下面是执行的顺序：
&lt;ul&gt;
&lt;li&gt;首先向system分区刷入system.img&lt;/li&gt;
&lt;li&gt;再向boot分区刷入boot.img&lt;/li&gt;
&lt;li&gt;再刷入cache分区&lt;/li&gt;
&lt;li&gt;然后重启&lt;/li&gt;
&lt;li&gt;等待完成后，就能看到久违的miui了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;/images/tupian/%E6%89%A7%E8%A1%8C%E6%AD%A5%E9%AA%A4.jpg&quot; alt=&quot;执行步骤&quot; /&gt;&lt;/li&gt;
&lt;li&gt;我就是这样的从其他的rom刷入miui的。&lt;/li&gt;
&lt;li&gt;为了保留twrp，没有刷入小米自己的recovery，个人感觉还是不要刷入小米的好。毕竟twrp的功能比小米的好很多。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item></channel></rss>