V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
scoutteemo
V2EX  ›  Python

寻求 Python 代码管控方案

  •  
  •   scoutteemo · 2021-01-22 15:33:53 +08:00 · 4239 次点击
    这是一个创建于 1390 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题引入

    公司需要对代码进行管控,以前的代码都是 C 写的,编译工作在远程的服务器上,用 RDP 远程连接到服务器上进行开发,编译后的固件传下来。
    现在引入了 python 语言来做的自动化测试方案,需要运行在 本地的 Linux 系统 上,还要 开放 root 权限 。现在同样需要对 python 的代码进行管控。所以在思考有没有什么方式,可以指定 python 这个程序才可以访问到特定的文件和目录, 其他的进程无法访问
    代码可以是一个整体的加密文件,运行时解密,但解密后的内容要保证不会被轻易取走。或者通过远程服务器实时下发内容运行。最好是能保留调试功能,可以逐行执行代码什么的。由于程序需要依赖硬件,所以代码只能在本地的 Linux 系统上运行才可以。

    想到的可能方案

    我们在 Windows 平台的软件有类似的设计,会生成一个虚拟的文件系统,具体方式我也不清楚,然后把实际运行的 exe 文件存放在其中,再运行。
    这样的话就需要实现一个FUSE,并且要保证这个文件系统是只有指定的进程才可以访问到的。 可以修改cpython的代码,里面融合类似于encfs这样的 FUSE,读的接口只暴露给 cpython 这个程序。然后再加上网络验证,从服务器上获取代码,运行完之后整个销毁掉。
    但是这样的方式工程量比较巨大,还是需要先考虑其他可行方式。

    第 1 条附言  ·  2021-01-22 16:26:36 +08:00
    管控就是说这个代码只允许存放到公司内部的服务器上,通过 RDP 这样的远程方式去访问编辑,不允许把代码下载到本地电脑
    第 2 条附言  ·  2021-01-22 22:43:38 +08:00
    Python 代码运行时需要访问 pci 总线上的设备,所以代码只能在本地的机器上跑才行,在本地机器的 pcie 接口上连接设备。并且需要 root 的权限,用来操作 Linux 内核的一些功能。除此之外,连接的设备也可能会经常更换之类的。所以代码在远程服务器上运行的方案基本上是不行了。
    51 条回复    2021-01-25 10:16:51 +08:00
    foxyier
        1
    foxyier  
       2021-01-22 15:46:39 +08:00
    没太理解, 到底是要管控「 python 代码」, 还是要管控「特定的文件和目录」?
    scoutteemo
        2
    scoutteemo  
    OP
       2021-01-22 15:53:34 +08:00
    @foxyier 是要管控代码,在我的认识中代码需要存放到某个目录才可以被 python 程序调用到,特别是我们还有一个用 C 接口的.so 文件,需要 import 进去使用
    scoutteemo
        3
    scoutteemo  
    OP
       2021-01-22 15:55:56 +08:00
    还有自己写的模块,都放在一起运行,需要 import 进去,所以应该是要整个目录都要有限制,才能达到目标这样。刚深入接触 python 不久,如果有什么理解不对的地方,还望大家指出
    zeroDev
        4
    zeroDev  
       2021-01-22 16:12:56 +08:00 via Android
    完全看不懂,只知道自己看得懂字
    这个“管控”,实在无法理解
    superrichman
        5
    superrichman  
       2021-01-22 16:17:45 +08:00 via iPhone
    没看懂,不过我想把东西都扔 docker 里应该能解决问题
    scoutteemo
        6
    scoutteemo  
    OP
       2021-01-22 16:19:26 +08:00
    @zeroDev 好吧,我重新描述开个新帖子
    scoutteemo
        7
    scoutteemo  
    OP
       2021-01-22 16:19:57 +08:00
    @superrichman docker 不行诶,文件系统没有完全隔离的,还是可以直接找到 docker 里面的文件的
    scoutteemo
        8
    scoutteemo  
    OP
       2021-01-22 16:22:16 +08:00
    @zeroDev 还是就先解释一下吧,管控就是说这个代码只允许存放到公司内部的服务器上,通过 RDP 这样的远程方式去访问编辑,不允许把代码下载到本地服务器
    scoutteemo
        9
    scoutteemo  
    OP
       2021-01-22 16:24:26 +08:00
    scoutteemo
        10
    scoutteemo  
    OP
       2021-01-22 16:24:57 +08:00
    cassyfar
        11
    cassyfar  
       2021-01-22 16:25:17 +08:00
    要完全管控,为啥不在服务器上跑 python 的自动化测试方案呢?
    xchaoinfo
        12
    xchaoinfo  
       2021-01-22 16:26:05 +08:00
    Cython 把 Python 代码编译为 C, 然后按照 C 的规矩操作。
    scoutteemo
        13
    scoutteemo  
    OP
       2021-01-22 16:27:05 +08:00
    @cassyfar 这个测试需要硬件的支持,服务器上跑不了
    scoutteemo
        14
    scoutteemo  
    OP
       2021-01-22 16:29:15 +08:00
    @xchaoinfo 对诶,这确实是一个办法,但是这样就没办法调试代码了,多谢你的方案
    cassyfar
        15
    cassyfar  
       2021-01-22 16:34:32 +08:00
    @scoutteemo 我大概理解了你的问题,你这是源码不能外漏,以前用 C,你可以在服务器编译成 binary,下载到自己电脑,连上设备,测。感觉这种做法本来就不规范,正确的是单独有个测试机,连上你的设备,设好权限,远程上去测。要不然你就遇到 python 这个问题。
    youngce
        16
    youngce  
       2021-01-22 16:38:56 +08:00
    python 工作在远程的服务器上,用 RDP 远程连接到服务器上进行开发,pyinstaller 打包编译后的可执行 EXE 传下来(别和我提 pyinstaller 安全性问题:)
    zeroDev
        17
    zeroDev  
       2021-01-22 16:39:47 +08:00 via Android
    @scoutteemo 用 grpc 或者其他 rpc 方案
    keakon
        18
    keakon  
       2021-01-22 16:49:20 +08:00
    这样管控,多个人怎么并行开发?
    scoutteemo
        19
    scoutteemo  
    OP
       2021-01-22 16:51:50 +08:00
    @cassyfar 我们做的是嵌入式设备,C 编译出来的二进制是嵌入式设备的固件,现在要用 python 来做个自动化测试,测试我们写的固件。这个自动化测试方案后续估计要大规模部署,而且设备频繁插拔也是常有的事,所以单独设测试机远程过去估计不太可行
    zjsxwc
        20
    zjsxwc  
       2021-01-22 16:54:27 +08:00
    python 代码混淆不就好了,反正混淆解密后的也是乱码
    scoutteemo
        21
    scoutteemo  
    OP
       2021-01-22 17:02:30 +08:00
    @keakon 没什么问题的呀,多人一起 RDP 连同一台服务器,用 SVN 做代码管理,验证代码只需要编译后的二进制文件
    scoutteemo
        22
    scoutteemo  
    OP
       2021-01-22 17:05:41 +08:00
    @zeroDev 好的,先去了解一下,多谢啦
    scoutteemo
        23
    scoutteemo  
    OP
       2021-01-22 17:06:43 +08:00
    @youngce 好像是可以,但是这样也没办法进行调试了,在服务器上是没办法运行测试的
    scoutteemo
        24
    scoutteemo  
    OP
       2021-01-22 17:08:05 +08:00
    @zjsxwc 意思是在远程服务器上编辑好代码,下载到本地的是混淆后的代码,然后再在本地运行这样吗?
    zjsxwc
        25
    zjsxwc  
       2021-01-22 17:12:30 +08:00 via Android
    @scoutteemo 对呀,商业化脚本语言代码不都是这么干吗
    scoutteemo
        26
    scoutteemo  
    OP
       2021-01-22 17:19:12 +08:00
    @zjsxwc 喔喔,才接触 python 还不是很了解。混淆之后的代码逆向起来成本会很高的吗?我知道有商业的代码会用 Cython 编译一次,再用 pyinstaller 打包,这样逆向起来就很麻烦了
    makdon
        27
    makdon  
       2021-01-22 20:31:43 +08:00
    把设备和代码都部署在远端呗,然后开放用有限权限的用户帐号登上去操作,那个帐号限定只能执行限定的命令
    scoutteemo
        28
    scoutteemo  
    OP
       2021-01-22 20:48:39 +08:00 via Android
    @makdon 不行的,设备一定要在本地才可以,而且需要系统的 root 权限。我们做的设备是在 pcie 总线上用的,一台服务器就这么些 pcie 通道,因为要控制 pci 的配置空间什么的,所以需要 root 权限
    sampeng
        29
    sampeng  
       2021-01-22 21:42:07 +08:00 via iPhone
    1.所有人签订保密协议.2,电脑不允许插 u 盘。3,所有内网机器没有外网。
    也就是参考华为那套,这样你的代码安全了。
    sampeng
        30
    sampeng  
       2021-01-22 21:43:36 +08:00 via iPhone
    兄 dei,防君子不防小人。签订协议即可。代码真没那么重要。
    ArJun
        31
    ArJun  
       2021-01-22 21:46:12 +08:00
    你这是多少个亿的大项目,当年 B 站都没你这样管控代码,你有牛逼的方案别人盗不走的
    DoctorCat
        32
    DoctorCat  
       2021-01-22 22:03:50 +08:00
    就是云桌面呗,查查云桌面的安全方案,一般都是限制远程网络、有限程序、单向剪贴板。
    scoutteemo
        33
    scoutteemo  
    OP
       2021-01-22 22:30:53 +08:00 via Android
    @DoctorCat 对,现在我们的方案就是这样,一个带限制功能的 RDP 远程桌面。不能使用剪切板,网络也有限制,编译出来的结果通过一个自己研发的软件,审核之后下传到本地。但是这样的方式在这样一个依赖硬件的 Python 程序环境中用不起来,程序需要访问本地的硬件,服务器上运行是不行的,而且硬件还可能需要频繁更换之类的。
    scoutteemo
        34
    scoutteemo  
    OP
       2021-01-22 22:33:58 +08:00 via Android
    @ArJun 那倒也不是什么大项目,因为现在的代码是有这样的管控限制的,看新的 python 代码能不能也加上一样的限制,如果不行或者太麻烦,那当然也不会强行限制断自己手足
    scoutteemo
        35
    scoutteemo  
    OP
       2021-01-22 22:36:35 +08:00 via Android
    @sampeng 😂这就是从另一个角度解决问题了,看看从技术上有没有什么好解决的办法先,不行也不是非得这样
    neoblackcap
        36
    neoblackcap  
       2021-01-23 00:25:59 +08:00
    Python 的源代码混淆约定于没有。C 那些也应该是靠强壳才比较安全
    说回 Python 吧,我估计你们现在是实际执行的时候会用到 Python 写的脚本吧。对于这个问题,网易的阴阳师就是一个例子,他们是用 Python 写业务逻辑,然后生成 pyc 字节码文件,部署就只部署字节码文件。关键他们已经魔改过 Python 解析器了,但是一样被人逆向了。
    所以我觉得你们如果对代码保密程度很高的,那么你们还是继续上 C 什么的吧。Python 要保密,怕是要大改虚拟机
    scoutteemo
        37
    scoutteemo  
    OP
       2021-01-23 07:45:55 +08:00 via Android
    @neoblackcap 好吧,看来这还真是个棘手的问题。像帖子内容上面提到的修改 python 解释器的方案,应该也能起到一定作用吧
    chiu
        38
    chiu  
       2021-01-23 08:38:07 +08:00
    我有一点其他疑问:
    >> 在本地机器的 pcie 接口上连接设备...连接的设备也可能会经常更换之类的。所以代码在远程服务器上运行的方案基本上是不行了.
    我理解中,PCIE 总线上可以挂接多个设备,真的设备类型很多的话,我觉得 5 台以内的 server 数量应该是足够的。如果都能挂接上独立访问,应该就不会有设备需要经常更换的问题。
    scoutteemo
        39
    scoutteemo  
    OP
       2021-01-23 09:24:38 +08:00 via Android
    @chiu PCIE 的通道是 PCIE 设备独占的,例如一个 16 通道的 PCIE 口,就只能连接 4 个 4 通道的设备,不能无限制地挂接设备。
    现在还处于初步开发阶段,有时候会把自己的设备跑死,需要重新上断电,但 pcie 不支持热插拔,这时又只能重启服务器来进行解决,甚至需要短接设备引脚,重新烧录程序这样。
    设备还存在寿命的问题,不可能一直插在服务器上就不取下来。
    有时单个设备存在问题,我们会有替换法替换其他设备来做交叉验证找问题。设备类型倒是很单一,但我们同一个设备(产品)有很多个实现方案,验证完一个方案会需要更换其他方案验证。
    同一个方案我们也会使用多个设备来做验证。最后的部署规模估计会到 100 个设备的样子。
    另外 PCIE 口可以连接存储设备,这样可以很容易地把代码拷贝走。禁止 PCIE 口的插拔不太现实,因为替换设备的需求还是存在的。
    在后期部署成熟后,这个方法说不定可行。不同的实现方案可以固定对应不同的机器,再加上插拔限制,应该是能实现这个方式
    kaneg
        40
    kaneg  
       2021-01-23 09:54:06 +08:00 via iPhone
    要保密就不要选 Python 这种解释型的语言。之前看到过类似的,比如加密 php,js,java 等。这些解释型的语言只要你把发布的产品给别人,真要防黑客是不可能的。在上面做的各类混淆,加密都只是增加一点难度,属于掩耳盗铃的做法。你的代码如果价值不大,做这些就是白白浪费人力。如果你的代码价值真的很大,是业内的核心资产,你用力保护,人家也会不遗余力的破解,而且比你更容易。你以为自己的方案是固若金汤,实质上会变成马其诺防线。
    安全与方便是不可兼得的,二者都想得到的方案再复杂都是空中楼阁。
    scoutteemo
        41
    scoutteemo  
    OP
       2021-01-23 10:08:35 +08:00 via Android
    @kaneg 啊,好吧,看来在 Python 上做保密还是挺费劲的,要进行取舍才行了。
    AoEiuV020
        42
    AoEiuV020  
       2021-01-23 12:30:45 +08:00
    我就不明白搞这些保密真有啥用吗,再怎么保密也要允许 python 进程读取,那写个 python 脚本把所有代码打包带走不也拦不住?
    scoutteemo
        43
    scoutteemo  
    OP
       2021-01-23 14:00:06 +08:00
    @AoEiuV020 我去,还真是,这是没考虑到的点
    jr981008
        44
    jr981008  
       2021-01-23 15:43:29 +08:00
    直接上 docker 一个容器一个任务
    DoctorCat
        45
    DoctorCat  
       2021-01-23 19:24:58 +08:00
    @kaneg 更正你关于 Py 是“解释型”语言的概念 。什么是解释型语言? - 李广胜的回答 - 知乎
    https://www.zhihu.com/question/268303059/answer/336730398
    DoctorCat
        46
    DoctorCat  
       2021-01-23 19:28:06 +08:00
    @neoblackcap 大改虚拟机这事儿,去年我干过,还是有一定复杂度的,就像做手术。兼容性完全没保证了,尤其是在优化了 co_code 和 exec 后,某些第三方库(改字节码操作的)崩溃。


    @scoutteemo 需要访问本地硬件这事儿,可以物理隔离了。某些外包大厂给人做设备灌固件进去的适合就是在物理隔离的工作区域
    sampeng
        47
    sampeng  
       2021-01-24 00:13:21 +08:00 via iPhone
    @scoutteemo 技术本身是无解的,如果我能写代码。你无论如何拦不住我,代码里我可以加任何逻辑,自己把自己打包传出去不要太简单。变异型的好那么一点点。

    还一个办法,这是技术方案,没啥高级的,做职能分离。一个功能拆成 n 份。每一份只知道自己的工作。要有全部才能 work 。泄露了谁都没意义…
    leir
        48
    leir  
       2021-01-24 16:23:01 +08:00
    @scoutteemo 这个需求靠单个点基本没用

    我的理解是:
    1. 需求来源:你现在至少有,产品代码-c,测试代码-python,本来是只想对 C 保密,但是由于 python 有访问 C 的权限,所以想对 python 也一起做“管控”
    2. 应用场景:python 在测试环境中运行,并需要访问 PCI 设备

    建议:
    **狗头** 如果成本可接受
    支持贵司嵌入式平台的 CI/CD 或者自建 CI/CD

    **如果**这个成本都无法接受,那么考虑代码管控技术方案的意义可能不大,直接对人员进行管控就行了……
    scoutteemo
        49
    scoutteemo  
    OP
       2021-01-24 20:04:25 +08:00 via Android
    @leir 需求理解得很透彻😂,自建 CI/CD 的成本应该还是可以接受的,如果能支持的话,是能有什么办法吗?

    @sampeng 看来是没有完美解决方案了。放弃调试功能的话,倒是可以在服务器上把代码用 Cython 编译成 so,再在本地调用这样。拆分功能的话,现在初步阶段内容也不多,不好分。可能会选择放弃代码管控吧

    @DoctorCat 物理隔离确实是很顶级的办法,估计我们目前是实现不了
    scoutteemo
        50
    scoutteemo  
    OP
       2021-01-24 20:07:17 +08:00 via Android
    感谢各位的回复,这事看来不是很好办,等明天开会讨论一下,看到底要不要进行管控,方案具体怎么做。再次多谢大家的热心指导。
    qinyusen
        51
    qinyusen  
       2021-01-25 10:16:51 +08:00
    提 2 个个人见解:
    1. 嵌入式部分 ci-cd 做好,然后自动化测试拿到的是 c 代码编译后的二进制,二进制里面自己做加密就行。
    做好访问渠道的单项访问防护,也就是永远只有编译服务器->自动化测试服务器,由 C 代码服务器推送(或者某种 hook)启动,不要用自动化测试的服务器主动启动。
    C 代码里做 mac 地址绑定,硬盘 UUID 绑定,时间失效(编译时间戳+2 小时自动化测试时间)等一系列乱七八糟的防御,保证这部分自动化测试的代码的生命周期和生存环境

    2.安全领域里有 2 个点,第一个点是主动防御,类似于 1 。 第二个叫做入侵检测, 就是泄露了就泄露了,但是我能发现他被入侵和泄露了。
    那么在加密的二进制里可以检查一个什么你们特有的 eeprom 或者 flash 或者什么东西,做一个校验,如果没有发现这玩意,检查网络发送 HTTP 请求,将当前 IP 和 mac 地址等信息发到你服务器上。前提是你们的嵌入式是比较强的那种,这部分 lib 比较大。也就是泄露了之后能发现它泄露了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1034 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:18 · PVG 04:18 · LAX 12:18 · JFK 15:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.