修复env 引起的codex sandbox helper启动失败

不知不觉 Codex 辅助编程已经成了不可或缺部分。对话多了以后难免卡顿,近期归档功能一直时好时坏,干脆删除全部配置,重新安装。

按照往常习惯,删除 .codex 下所有文件,以及 AppData 下和 openai,chatgpt,codex 相关的全部目录,重新下载官方安装包进行安装。

再次运行时却发现执行 apply_patch 时无法启动 codex sandbox helper,提示如下:

其他命令都正常,此时 codex 靠 powershell 来兜底执行。为了一探究竟,各方搜索后,其实很滑稽,原来是留在 .codex 目录下的 .env 引起的故障,这个文件对于中国用户一定不陌生,用于配置代理,否则就得等 timeout 5次,很浪费时间,所以在重装后还没启动的时候,这个文件就被我放进去了,此时启动 codex 初始化 sandbox 时候会读取并带到 sandbox 配置中,且仅仅带了个端口号,就因为这个配置,会引起 sandbox 启动失败。查看配置文件 .codex\.sandbox\setup_marker.json 如下:

“proxy_ports”: [
6789
],

修复也很简单,删除6789,置为空数组,回到 codex中让他自己检查一遍:

vibe的东西,有时候别太较真。

https://github.com/openai/codex/issues/29072

Linux 下临时给 Docker daemon 配代理

因为访问镜像仓库的是 Docker daemon,不是你当前 shell,所以仅仅在命令前加,通常没用,需要临时给 dockerd 配代理。

新建临时代理配置

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1"
EOF

重新加载并重启 Docker

sudo systemctl daemon-reload
sudo systemctl restart docker

验证

systemctl show --property=Environment docker
docker pull nginx

用完后取消代理

sudo rm -f /etc/systemd/system/docker.service.d/http-proxy.conf
sudo systemctl daemon-reload
sudo systemctl restart docker

密钥安全那些事

借着此次上海公安数据库疑似泄密事件,好好梳理下项目中是如何确保密钥安全。密钥大多指 Key-Value 键值对、公私钥、Token 等,从早期的代码中硬编码,到配置文件硬编码,再到各种的配置中心的诞生,例如:携程 Apollo 或者 HashiCorp Vault。不断的演变进化中,安全性与灵活性也极大的提高。

硬编码时代:密钥控制权将完全由开发者决定,一旦代码泄露则密钥也一并泄露,即便泄露不是源代码,而是编译后的 Class 文件,Jar、War 包等也是可以轻松反编译得到源码,所以是最不可靠的方案,实际项目中应绝对禁止,且应在 CI 流程中加入 Checkmarx SAST 检测告警,以避免疏忽大意而导致泄露。配置文件只可存放用于测试的配置,例如连接本地数据库的用户密码,在 CI 流程中进行动态替换,这样一来,密钥则可交由运维人员来管理,与开发者完全隔离。

微服务时代:随着配置项的增多,管理职权分离后,密钥如何存储,更新,授权,管理等一些列问题也孕育而生。携程 Apollo 则是一个较好的解决方案,目前也是国内项目大多数的选择。自身的稳定性,灵活性都还做的不错,有着不错的 Web UI,与 Spring Boot 集成也非常简单。

云原生时代:随着 Kubernetes 的加入,DevOps 发生了较大的变化,对容器而言,推荐使用 Secret 和 ConfigMap 来存放密钥和键值对。同时众多角色的加入,如何安全存放密钥、安全使用密钥以及更好的与基础平台整合,对密钥管理又提出了更高要求。HashiCorp Vault 则是不二之选,通过一套复杂的加密机制可以确保在公有云上能够安全的存储机密信息,且支持密钥轮转,在 CD 流程中拉取密钥挂载到容器中使用,对服务来说可以做到完全透明,缺点是无法实时更改。

当然除了密钥需要正确保管外,环境有效隔离才是最后一道屏障,面对层出不穷的数据泄密事件,无论是有意还是无意,黑客行为,或许应该思考本身是否有必要收集和存储?去中心化的互联网架构或许是未来的出路?

docs:

https://www.vaultproject.io/docs/what-is-vault

API网关那些事

一个典型的Web架构中,网关是一个很容易被忽略的东西,或者透明般存在,而在云原生的微服务架构中,网关被赋予了更多职责,也变得更为重要。

1、反向代理时代
说到反向代理,不得不提Nginx,开源版的Nginx也仅起到反向代理的作用,常用来根据Host,Path来路由到不同的服务,做Stream负载均衡,SSL终结等,流量基本是透传,所以在后端看来几乎透明。且通过配置文件进行管理,一旦服务多了,难以维护。优势也就占用资源少,性能强悍。

2、边缘网关时代
在云原生时代,微服务众多,接入设备复杂多样化,一些重复度高的动作就必须抽取出来,而这些琐碎放到网关在合适不过了,以Apigee Edge为例,支持公有云、混合云、私有云部署,不仅做到API管理,还支持客户端管理,顶级层级为APP(Mobile or Web),可配置访问凭证,第二层级为Products,可配置环境(SIT or PROD),授权给APP访问,第三层级为API Proxies,即下面详解的API管理,绑定到Products,三层按顺序均为一对多关系,可参考OAuth2授权模式之密码模式。

API Proxy主要抽象出几个概念:

1、代理端点(Proxy Endpoints)
2、目标端点(Target Endpoints)
3、策略(Policies)
4、资源(Resources)

代理端点用来定义一个API,并对外暴露,主要与客户端打交道,目标端点则可以是后端微服务,也可以是公网上的另一个API,API支持环境区分部署,版本管理。

策略则是Apigee精华所在,策略是对请求做处理的最小单元,例如定义一个策略对参数进行校验、再定义一个对user&app token校验等,甚至执行js&java lib进行加解密等更为复杂的逻辑。策略通过Flow(处理流)来规定执行条件和执行顺序,一旦命中则跳过后续Flow。多个Flow又可以组成Shared Flows,以便复用。同样Flow也支持环境区分部署,版本管理。

资源则是放置js脚本或者java lib的地方,供策略调用。策略支持分环境来部署,支持版本切换,而这一切都是动态实时的,无需重启reload。

这样一来,到达backend的请求就已经是符合要求的了,可以省去很多的判断。

这里继续介绍一下策略,策略实质上是通过xml来定义,可分以下几种:
1、流量管理,例如Quota、Spike Arrest等,内置了数十种对流量进行管理的策略。
2、安全管理,例如Basic Authentication、OAuth、LDAP、JWT、HMAC等,同样内置了十分丰富,涵盖大部分场景。
3、协调与扩展,例如内置的XML&JSON格式互转。其中用的比较多的主要以下三个,可以非常灵活的将多个backend请求组合成一个API。
3.1、AssignMessage 请求管理
3.2、ServiceCallout 外部服务调用
3.3、ExtractVariables 解析响应

Apigee使用几个月来,初期学习成本比较高,但很多配置都是复用的,后续维护并不算太难。当然有了如此强大的功能,还有配套的trace工具,可视化的看到每一个请求的执行情况、入参和出参、请求头、策略命中与结果等,非常人性化,Apigee简单介绍到此,更详细请查阅官方文档,后续再对比一些开源方案。

文档地址:https://docs.apigee.com/api-platform/get-started/get-started

Apache Guacamole – All in WEB

1. Ubuntu 20.04 下安装 Docker,添加当前用户到 docker 组
curl -fsSL https://get.docker.com | bash -s docker –mirror Aliyun
sudo usermod -aG docker $USER

2. 拉取镜像
docker pull guacamole/guacamole
docker pull guacamole/guacd
docker pull mysql/mysql-server:5.7

3. 导出 guacamole 中的数据库初始脚本,启动 MySQL 数据库
docker run –rm guacamole/guacamole /opt/guacamole/bin/initdb.sh –mysql > initdb.sql
docker run –name mysql –restart=always -e MYSQL_ROOT_PASSWORD=123456 -d mysql/mysql-server:5.7

4. 复制到容器中,进入容器 MySQL Client
docker cp initdb.sql mysql:/initdb.sql
docker exec -it mysql mysql -uroot -p123456

5. 创建数据库、用户密码,导入初始脚本
CREATE DATABASE guacamole;
CREATE USER ‘guacamole’@’%’ IDENTIFIED BY ‘guacamole’;
GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole.* TO ‘guacamole’@’%’;
FLUSH PRIVILEGES;
USE guacamole;
SOURCE initdb.sql;

6. 启动 guacamole
docker run –name guacd –restart=always -d guacamole/guacd
docker run –name guacamole –restart=always –link guacd:guacd –link mysql:mysql -e MYSQL_DATABASE=’guacamole’ -e MYSQL_USER=’guacamole’ -e MYSQL_PASSWORD=’guacamole’ -d -p 8080:8080 guacamole/guacamole

浏览器打开 http://localhost:8080/guacamole 默认用户名密码 guacadmin。配置好SSH,RDP,VNC,主机可以是内网中任何一台能访问的机器,RDP 注意关闭认证和选上网络级别身份验证(NLA)。配合御花园(https://ifport.com)将 8080 端口映射到公网,随时在浏览器中访问(注意安全)。

自此 All in WEB,Docker 大法好。